feat: complete newspaperui component library with docs site

- 18 React components (Layout/Section/Article/Layer/Masthead/Rule +
  Headline/Subhead/Kicker/BodyText/Quote/Byline/Dateline/Caption +
  Image/Figure/Video/PullQuote)
- Theme: warm off-white palette, Source Serif 4 / Cormorant Garamond /
  Inter / Noto Serif SC/JP, visual weight mapping, dark mode
- Docs: Landing page, 6 Blocks (zh/en/jp), component API docs
- GitHub Pages deployment via static export

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
sunzhongyi
2026-05-20 14:22:14 +08:00
parent 610805a374
commit 1f09bba3ef
57 changed files with 2662 additions and 1127 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ import { Sidebar } from '../../components/Sidebar';
export default function DocsLayout({ children }: { children: React.ReactNode }) {
return (
<div style={{ display: 'flex', minHeight: '100vh' }}>
<div style={{ display: 'flex', minHeight: 'calc(100vh - 65px)' }}>
<Sidebar />
<main
style={{
@@ -0,0 +1,77 @@
'use client';
import { Layout, Section, Article, Rule, Headline, Subhead, Kicker, BodyText, Byline, Dateline, Figure, PullQuote } from '@newspaperui/components';
export default function EnFeature() {
return (
<Layout columns={24} maxWidth="750px" padding="3rem 2rem 4rem">
<Section columns={24}>
<Article span={24}>
<div style={{ textAlign: 'center', marginBottom: '3rem' }}>
<Kicker>Long-form · Investigation</Kicker>
<Headline weight="High" align="center" style={{ marginTop: '0.5rem' }}>
The Quiet Collapse of the Middle Shelf
</Headline>
<Subhead weight="High" style={{ textAlign: 'center', marginTop: '0.5rem' }}>
How a generation of mid-list authors lost their publishers, their readers, and their livelihoods while bestseller lists grew longer than ever.
</Subhead>
<div style={{ marginTop: '1.5rem' }}>
<Byline>By Catherine Ashworth</Byline>
</div>
<div style={{ fontFamily: 'var(--font-family-meta)', fontSize: '12px', color: 'var(--nui-text-muted)', marginTop: '0.5rem' }}>
May 19, 2026 · 18 min read
</div>
</div>
<Figure
src="https://images.unsplash.com/photo-1507842217343-583bb7270b66?auto=format&fit=crop&w=1400&q=80"
alt="Empty bookshelves in a closing bookstore"
caption="A former independent bookstore in Portland, Oregon, photographed the week before its final closing. The middle shelves — where debut novels and second books once lived — were the first to empty."
credit="Photograph by Daniel Voss for The Chronicle"
/>
<BodyText weight="High" dropCap style={{ marginTop: '2rem' }}>
<p><Dateline>Portland, Ore. </Dateline> The bookstore on Southeast Hawthorne had been open for thirty-one years when its owner, Margaret Liu, decided she could no longer make the numbers work. It was not a dramatic collapse. There was no single catastrophe, no flood, no fire, no pandemic-era pivot that failed. It was, she said, more like a long exhalation.</p>
<p>"The books that used to sell two thousand copies now sell four hundred," she told me, standing behind a counter stacked with returns. "And the books that sell a hundred thousand still sell a hundred thousand. The middle just — left."</p>
<p>Liu's observation, echoed by dozens of booksellers, agents, and editors I spoke with over six months of reporting, describes a structural shift in American publishing that has accelerated sharply since 2022. The "middle shelf" — the physical and metaphorical space where literary fiction, serious nonfiction, and debut authors once found their audience — has contracted to a degree that many in the industry describe as existential.</p>
<p>The data bears this out. According to figures compiled by the Association of American Publishers and cross-referenced with BookScan point-of-sale data, the number of titles selling between 2,000 and 20,000 copies annually has declined by 34 percent since 2019. Over the same period, the number of titles selling more than 100,000 copies has increased by 11 percent. The top is growing; the middle is vanishing.</p>
</BodyText>
<PullQuote weight="High" author="Margaret Liu, bookseller" align="center" style={{ margin: '2.5rem 0' }}>
The books that used to sell two thousand copies now sell four hundred. The middle just — left.
</PullQuote>
<BodyText weight="High">
<p>For readers, the consequences are subtle but cumulative. The debut novel that might have found ten thousand readers in 2015 now finds three thousand — or never gets published at all. The second book, historically the most precarious moment in a literary career, has become a cliff edge. Agents report that "second book syndrome" has evolved from a creative challenge into an economic one: publishers increasingly decline to offer contracts for follow-up works unless the debut exceeded expectations.</p>
<p>"I had three clients last year whose publishers simply said no to book two," said Rachel Mendelson, a literary agent in New York. "Not because the books were bad. Because the sales data from book one didn't justify the advance. These are talented writers with good reviews and real readers. But 'real readers' now means something different to a P&L spreadsheet."</p>
<p>The causes are multiple and mutually reinforcing. The consolidation of major publishers into four global conglomerates has concentrated decision-making power among fewer acquiring editors, each under greater pressure to justify investments with projected returns. The rise of algorithmic recommendation — on Amazon, on social media, on podcast charts — has created winner-take-all dynamics that reward existing visibility over literary merit. And the economic pressures on readers themselves, facing higher costs of living and competing demands on attention, have made the "safe bet" of a known author or a viral recommendation more attractive than the gamble of an unfamiliar name.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '2rem 0' }} />
<BodyText weight="High">
<p>The human cost is difficult to quantify but impossible to ignore. I spoke with fourteen mid-career authors — writers with two to five published books, strong reviews, and modest but loyal readerships — about their financial situations. Twelve reported that their writing income had declined in real terms over the past five years. Nine had taken on additional employment. Four had effectively stopped writing new books, though none had publicly announced retirement.</p>
<p>"I don't want to sound self-pitying," said one novelist, who asked not to be named because she feared alienating her publisher. "I knew this wasn't going to make me rich. But I thought it would let me keep doing it. That's what's changed. It's not about wealth. It's about viability."</p>
<p>The phrase "viability" recurred in nearly every conversation. Not the viability of literature as an art form — no one doubted that — but the viability of a life organized around producing it. The distinction matters. Great books will continue to be written. But the ecosystem that once supported a broad class of working writers, allowing them to develop over multiple books and find their audience gradually, is contracting faster than anyone predicted.</p>
</BodyText>
<PullQuote weight="Medium" author="Anonymous novelist" align="center" style={{ margin: '2.5rem 0' }}>
I knew this wasn't going to make me rich. But I thought it would let me keep doing it. That's what's changed.
</PullQuote>
<BodyText weight="High">
<p>Independent publishers have partially filled the gap. Small presses like Graywolf, Coffee House, Tin House, and Catapult have expanded their lists and taken on authors who might previously have published with major houses. But their advances are smaller, their marketing budgets thinner, and their distribution reach narrower. An author moving from a Big Four imprint to an independent press typically sees their print run cut by half or more.</p>
<p>"We're doing important work," said one independent publisher, "but we can't replace what's been lost. We're a lifeboat, not a cruise ship."</p>
<p>The question facing American letters is whether this contraction is cyclical or structural — whether the middle shelf will eventually recover as reading habits shift, or whether the current configuration represents a new permanent state. Most industry observers I spoke with leaned toward the latter view, though several noted that predictions about publishing have a long history of being wrong.</p>
<p>What seems clear is that the current moment demands new thinking about how literary culture sustains itself. The old model — in which publishers cross-subsidized risky literary work with profitable commercial titles — depended on a middle tier that generated modest but reliable returns. Without that middle, the cross-subsidy breaks down, and each book must justify itself independently. In such a world, the incentive to publish only sure things becomes overwhelming.</p>
<p>Margaret Liu closed her bookstore on a Tuesday in March. The middle shelves, she noted, were the first to empty. The bestsellers went last.</p>
</BodyText>
<Rule variant="double" style={{ margin: '3rem 0 1rem' }} />
<div style={{ fontFamily: 'var(--font-family-meta)', fontSize: '12px', color: 'var(--nui-text-muted)', fontStyle: 'italic' }}>
Catherine Ashworth is a staff writer covering publishing and literary culture. Additional reporting by James Okafor.
</div>
</Article>
</Section>
</Layout>
);
}
@@ -0,0 +1,141 @@
'use client';
import { Layout, Section, Article, Rule, BodyText, Figure } from '@newspaperui/components';
const jp = { fontFamily: 'var(--font-family-cjk-jp)' };
const jpAccent = { color: 'var(--nui-accent-ink-blue)' };
export default function JpHorizontal() {
return (
<Layout columns={24} maxWidth="1280px" padding="1.5rem 1rem">
{/* 報頭 */}
<header style={{
textAlign: 'center',
borderTop: '3px solid var(--nui-text-primary)',
borderBottom: '1px solid var(--nui-rule-decorative)',
paddingTop: '1rem',
paddingBottom: '0.5rem',
}}>
<h1 style={{
...jp,
fontSize: '72px',
fontWeight: 900,
margin: 0,
letterSpacing: '0.15em',
lineHeight: 1,
color: 'var(--nui-text-primary)',
}}></h1>
<div style={{
...jp,
display: 'flex',
justifyContent: 'space-between',
fontSize: '11px',
color: 'var(--nui-text-secondary)',
padding: '0.5rem 1rem',
borderTop: '1px solid var(--nui-rule-hairline)',
marginTop: '0.5rem',
}}>
<span>48721</span>
<span>82026519 </span>
<span> · 14</span>
</div>
</header>
{/* 一面トップ */}
<Section columns={24} gap="1rem" style={{ marginTop: '1rem', paddingBottom: '1rem', borderBottom: '2px solid var(--nui-rule-decorative)' }}>
<Article span={24}>
<div style={{ ...jp, ...jpAccent, fontSize: '13px', fontWeight: 700, marginBottom: '0.5rem', textAlign: 'center' }}></div>
<h2 style={{ ...jp, fontSize: '48px', fontWeight: 900, lineHeight: 1.15, color: 'var(--nui-text-primary)', textAlign: 'center', margin: 0 }}>
 23
</h2>
<h3 style={{ ...jp, fontSize: '20px', fontWeight: 500, lineHeight: 1.5, color: 'var(--nui-text-secondary)', textAlign: 'center', margin: '0.5rem 0 1rem 0' }}>
 
</h3>
<div style={{ ...jp, textAlign: 'center', fontSize: '12px', color: 'var(--nui-text-muted)', marginBottom: '1rem' }}>
</div>
<Figure
src="https://images.unsplash.com/photo-1577962917302-cd874c4e31d2?auto=format&fit=crop&w=1200&q=80"
alt="署名式の様子"
caption="協定に署名する各国代表。ブリュッセルの会議場で19日未明。"
credit="AP"
/>
<BodyText weight="High" columns={3} style={{ ...jp, marginTop: '1rem' }}>
<p>112319調</p>
<p>20402028</p>
<p>1.20.7</p>
<p></p>
<p>32貿18</p>
<p>10</p>
</BodyText>
</Article>
</Section>
{/* 二面:3栏 */}
<Section columns={24} gap="1rem" style={{ marginTop: '1rem', paddingBottom: '1rem', borderBottom: '1px solid var(--nui-rule-decorative)' }}>
<Article span={8} style={{ background: 'var(--nui-bg-surface)', padding: '1rem', borderLeft: '3px solid var(--nui-accent-ink-blue)' }}>
<div style={{ ...jp, ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.75rem', paddingLeft: '0.75rem', borderLeft: '3px solid var(--nui-accent-ink-blue)' }}></div>
<h3 style={{ ...jp, fontSize: '20px', fontWeight: 700, lineHeight: 1.35, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}></h3>
<BodyText weight="Low" style={jp}>
<p></p>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...jp, fontSize: '16px', fontWeight: 600, lineHeight: 1.35, margin: '0 0 0.4rem 0' }}>3</h4>
<BodyText weight="Low" style={jp}>
<p>243</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...jp, fontSize: '16px', fontWeight: 600, lineHeight: 1.35, margin: '0 0 0.4rem 0' }}></h4>
<BodyText weight="Low" style={jp}>
<p>3</p>
</BodyText>
</Article>
<Article span={8} style={{ background: 'var(--nui-bg-surface)', padding: '1rem', borderLeft: '3px solid var(--nui-accent-ink-blue)' }}>
<div style={{ ...jp, ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.75rem', paddingLeft: '0.75rem', borderLeft: '3px solid var(--nui-accent-ink-blue)' }}></div>
<h3 style={{ ...jp, fontSize: '20px', fontWeight: 700, lineHeight: 1.35, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}>PMI</h3>
<BodyText weight="Low" style={jp}>
<p>552.45</p>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...jp, fontSize: '16px', fontWeight: 600, lineHeight: 1.35, margin: '0 0 0.4rem 0' }}>3.7</h4>
<BodyText weight="Low" style={jp}>
<p>AI商用化への期待を背景にテクノロジー株が全面高</p>
</BodyText>
</Article>
<Article span={8} style={{ background: 'var(--nui-bg-surface)', padding: '1rem', borderLeft: '3px solid var(--nui-accent-ink-blue)' }}>
<div style={{ ...jp, ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.75rem', paddingLeft: '0.75rem', borderLeft: '3px solid var(--nui-accent-ink-blue)' }}></div>
<h3 style={{ ...jp, fontSize: '20px', fontWeight: 700, lineHeight: 1.35, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}></h3>
<BodyText weight="Low" style={jp}>
<p>殿8220214</p>
<p>4</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...jp, fontSize: '16px', fontWeight: 600, lineHeight: 1.35, margin: '0 0 0.4rem 0' }}></h4>
<BodyText weight="Low" style={jp}>
<p>18</p>
</BodyText>
</Article>
</Section>
{/* 短信欄 */}
<Section columns={24} gap="1rem" style={{ marginTop: '1rem' }}>
<Article span={24}>
<div style={{ ...jp, ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem', paddingLeft: '0.75rem', borderLeft: '3px solid var(--nui-accent-ink-blue)' }}> · </div>
<BodyText weight="Low" columns={4} style={jp}>
<p> </p>
<p> FRB議事要旨で大半の当局者が年内利下げ開始を支持していることが判明</p>
<p> 25bp引き下げ</p>
<p> </p>
<p> EU首脳会議が支援パッケージで合意3</p>
<p> 58000西</p>
</BodyText>
</Article>
</Section>
</Layout>
);
}
@@ -0,0 +1,160 @@
'use client';
import React from 'react';
const jp = { fontFamily: 'var(--font-family-cjk-jp)' };
const jpAccent = { color: 'var(--nui-accent-ink-blue)' };
export default function JpVertical() {
return (
<div style={{
background: 'var(--nui-bg-page)',
color: 'var(--nui-text-body)',
padding: '2rem',
minHeight: '100vh',
}}>
{/* 竖排容器 */}
<div style={{
writingMode: 'vertical-rl',
...jp,
height: '85vh',
overflow: 'hidden',
}}>
{/* 報頭(竖排中在最右侧) */}
<div style={{
borderLeft: '3px solid var(--nui-text-primary)',
paddingLeft: '1rem',
marginLeft: '2rem',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
gap: '1rem',
}}>
<h1 style={{
...jp,
fontSize: '56px',
fontWeight: 900,
letterSpacing: '0.2em',
lineHeight: 1.2,
margin: 0,
color: 'var(--nui-text-primary)',
}}></h1>
<div style={{ fontSize: '12px', color: 'var(--nui-text-muted)', lineHeight: 1.8 }}>
<div></div>
<div></div>
<div></div>
<div>48721</div>
</div>
</div>
{/* 一面トップ記事 */}
<div style={{
borderLeft: '1px solid var(--nui-rule-hairline)',
paddingLeft: '1.5rem',
marginLeft: '1.5rem',
maxHeight: '100%',
}}>
<div style={{ ...jpAccent, fontSize: '13px', fontWeight: 700, marginBottom: '1rem' }}></div>
<h2 style={{
...jp,
fontSize: '36px',
fontWeight: 900,
lineHeight: 1.4,
color: 'var(--nui-text-primary)',
margin: '0 0 1rem 0',
}}>
</h2>
<h3 style={{
...jp,
fontSize: '18px',
fontWeight: 500,
lineHeight: 1.6,
color: 'var(--nui-text-secondary)',
margin: '0 0 1.5rem 0',
}}>
 
</h3>
<div style={{ fontSize: '12px', color: 'var(--nui-text-muted)', marginBottom: '1rem' }}>
</div>
<div style={{ fontSize: '15px', lineHeight: 2.0, color: 'var(--nui-text-body)' }}>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}>調</p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
</div>
</div>
{/* 二面記事 */}
<div style={{
borderLeft: '1px solid var(--nui-rule-hairline)',
paddingLeft: '1.5rem',
marginLeft: '1.5rem',
maxHeight: '100%',
}}>
<div style={{ ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.75rem' }}></div>
<h3 style={{ ...jp, fontSize: '22px', fontWeight: 700, lineHeight: 1.4, color: 'var(--nui-text-primary)', margin: '0 0 0.75rem 0' }}>
</h3>
<div style={{ fontSize: '14px', lineHeight: 2.0, color: 'var(--nui-text-body)' }}>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
</div>
</div>
{/* 三面記事 */}
<div style={{
borderLeft: '1px solid var(--nui-rule-hairline)',
paddingLeft: '1.5rem',
marginLeft: '1.5rem',
maxHeight: '100%',
}}>
<div style={{ ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.75rem' }}></div>
<h3 style={{ ...jp, fontSize: '22px', fontWeight: 700, lineHeight: 1.4, color: 'var(--nui-text-primary)', margin: '0 0 0.75rem 0' }}>
</h3>
<div style={{ fontSize: '14px', lineHeight: 2.0, color: 'var(--nui-text-body)' }}>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
</div>
</div>
{/* 四面:文化 */}
<div style={{
borderLeft: '1px solid var(--nui-rule-hairline)',
paddingLeft: '1.5rem',
marginLeft: '1.5rem',
maxHeight: '100%',
}}>
<div style={{ ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.75rem' }}></div>
<h3 style={{ ...jp, fontSize: '22px', fontWeight: 700, lineHeight: 1.4, color: 'var(--nui-text-primary)', margin: '0 0 0.75rem 0' }}>
</h3>
<div style={{ fontSize: '14px', lineHeight: 2.0, color: 'var(--nui-text-body)' }}>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
</div>
</div>
{/* 五面:短信 */}
<div style={{
borderLeft: '1px solid var(--nui-rule-hairline)',
paddingLeft: '1.5rem',
marginLeft: '1.5rem',
maxHeight: '100%',
}}>
<div style={{ ...jpAccent, fontSize: '12px', fontWeight: 700, marginBottom: '0.75rem' }}></div>
<div style={{ fontSize: '13px', lineHeight: 2.0, color: 'var(--nui-text-body)' }}>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
<p style={{ margin: '0 0 0.5em 0', textIndent: '1em' }}></p>
</div>
</div>
</div>
</div>
);
}
+139
View File
@@ -0,0 +1,139 @@
'use client';
import Link from 'next/link';
import { Layout, Section, Article, Headline, Subhead, Kicker } from '@newspaperui/components';
const blocks = [
{
href: '/blocks/zh-frontpage',
lang: 'CHINESE · 中文',
title: '人民周报 · 头版',
description: '思源宋体 + 克制朱红 + 紧凑排版。中文报纸传统视觉语言,板块密集,信息密度高。',
color: '#CC2929',
},
{
href: '/blocks/zh-feature',
lang: 'CHINESE · 中文',
title: '副刊 · 文化专题',
description: '人物访谈与文化评论。深度内容排版,引用密集,多用 Quote 组件。',
color: '#CC2929',
},
{
href: '/blocks/en-feature',
lang: 'ENGLISH',
title: 'The Daily Chronicle · Long-form Feature',
description: 'Atlantic / New Yorker style long-form editorial. Single-column reading mode with multiple PullQuotes.',
color: '#1A1A1A',
},
{
href: '/blocks/jp-horizontal',
lang: 'JAPANESE · 日本語',
title: '朝日新聞 · 横組み',
description: 'Modern horizontal Japanese newspaper layout. Noto Serif JP, 24-column grid.',
color: '#1B2A4A',
},
{
href: '/blocks/jp-vertical',
lang: 'JAPANESE · 日本語',
title: '朝日新聞 · 縦組み',
description: 'Traditional vertical writing-mode (vertical-rl) Japanese layout.',
color: '#1B2A4A',
},
{
href: '/blocks/zh-editorial',
lang: 'CHINESE · 中文',
title: '社论 · 时事评论',
description: '双栏对开评论文章。引用密集,配以专家点评与读者来信。',
color: '#CC2929',
},
];
export default function BlocksIndex() {
return (
<Layout columns={24} maxWidth="1400px" padding="3rem 2rem 4rem">
<Section columns={24} gap="2rem">
<Article span={24}>
<div style={{ textAlign: 'center' }}>
<Kicker>Production-grade Blocks · Copy & Paste</Kicker>
</div>
<Headline weight="High" align="center">
Newspaper Blocks
</Headline>
<Subhead weight="Medium" style={{ textAlign: 'center' }}>
6 complete newspaper layouts in Chinese, English, and Japanese ready to copy.
</Subhead>
</Article>
</Section>
<Section columns={24} gap="2rem" style={{ marginTop: '3rem' }}>
{blocks.map((block, idx) => (
<Article key={block.href} span={24} style={{ marginBottom: '1.5rem' }}>
<Link href={block.href} style={{ textDecoration: 'none', color: 'inherit', display: 'block' }}>
<div style={{
border: '1px solid var(--nui-rule-hairline)',
background: 'var(--nui-bg-surface)',
padding: '2rem',
display: 'grid',
gridTemplateColumns: '1fr 3fr',
gap: '2rem',
alignItems: 'center',
}}>
<div style={{ borderRight: '1px solid var(--nui-rule-hairline)', paddingRight: '2rem' }}>
<div style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '11px',
fontWeight: 600,
fontVariantCaps: 'small-caps',
letterSpacing: '0.08em',
color: block.color,
marginBottom: '0.5rem',
}}>
{block.lang}
</div>
<div style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '11px',
color: 'var(--nui-text-muted)',
}}>
Block #{String(idx + 1).padStart(2, '0')}
</div>
</div>
<div>
<h3 style={{
fontFamily: 'var(--font-family-display)',
fontSize: '28px',
fontWeight: 600,
lineHeight: 1.15,
color: 'var(--nui-text-primary)',
margin: '0 0 0.5rem 0',
}}>
{block.title}
</h3>
<p style={{
fontFamily: 'var(--font-family-body)',
fontSize: '15px',
lineHeight: 1.5,
color: 'var(--nui-text-body)',
margin: 0,
}}>
{block.description}
</p>
<div style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '12px',
fontWeight: 600,
color: 'var(--nui-accent-primary)',
marginTop: '0.75rem',
fontVariantCaps: 'small-caps',
letterSpacing: '0.06em',
}}>
View block
</div>
</div>
</div>
</Link>
</Article>
))}
</Section>
</Layout>
);
}
@@ -0,0 +1,112 @@
'use client';
import { Layout, Section, Article, Rule, BodyText, Quote } from '@newspaperui/components';
const cn = { fontFamily: 'var(--font-family-cjk-serif)' };
const cnRed = { color: 'var(--nui-accent-cjk-red)' };
export default function ZhEditorial() {
return (
<Layout columns={24} maxWidth="1200px" padding="2rem 1.5rem">
{/* 社论报头 */}
<header style={{
borderTop: '3px solid var(--nui-text-primary)',
borderBottom: '1px solid var(--nui-rule-hairline)',
padding: '0.75rem 0',
marginBottom: '2rem',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'baseline',
}}>
<h1 style={{ ...cn, fontSize: '28px', fontWeight: 900, margin: 0, letterSpacing: '0.1em' }}> </h1>
<div style={{ ...cn, ...cnRed, fontSize: '14px', fontWeight: 600 }}>· ·</div>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)' }}>2026 5 19 · A2 </div>
</header>
{/* 双栏对开 */}
<Section columns={24} gap="2rem">
{/* 左侧:主社论 */}
<Article span={14} style={{ borderRight: '1px solid var(--nui-rule-hairline)', paddingRight: '2rem' }}>
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem', letterSpacing: '0.15em' }}></div>
<h2 style={{ ...cn, fontSize: '36px', fontWeight: 900, lineHeight: 1.2, color: 'var(--nui-text-primary)', margin: '0 0 0.75rem 0' }}>
</h2>
<h3 style={{ ...cn, fontSize: '18px', fontWeight: 500, lineHeight: 1.5, color: 'var(--nui-text-secondary)', margin: '0 0 1.5rem 0' }}>
</h3>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)', marginBottom: '1.5rem' }}>
</div>
<BodyText weight="High" columns={2} dropCap style={cn}>
<p></p>
<p></p>
<p>齿</p>
<p>2028 线</p>
<p></p>
<p></p>
<p></p>
<p></p>
</BodyText>
</Article>
{/* 右侧:专家评论 + 读者来信 */}
<Article span={10}>
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem', letterSpacing: '0.15em' }}></div>
<h3 style={{ ...cn, fontSize: '24px', fontWeight: 700, lineHeight: 1.3, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}>
</h3>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)', marginBottom: '1rem' }}>
·
</div>
<BodyText weight="Medium" style={cn}>
<p></p>
<p>线</p>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1.5rem 0' }} />
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem', letterSpacing: '0.15em' }}></div>
<h3 style={{ ...cn, fontSize: '24px', fontWeight: 700, lineHeight: 1.3, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}>
</h3>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)', marginBottom: '1rem' }}>
·
</div>
<BodyText weight="Medium" style={cn}>
<p></p>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1.5rem 0' }} />
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem', letterSpacing: '0.15em' }}></div>
<Quote variant="block" weight="Medium" style={cn}>
<p>线</p>
</Quote>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)', marginTop: '0.5rem' }}>
·
</div>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Quote variant="block" weight="Medium" style={cn}>
<p></p>
</Quote>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)', marginTop: '0.5rem' }}>
·
</div>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Quote variant="block" weight="Medium" style={cn}>
<p></p>
</Quote>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)', marginTop: '0.5rem' }}>
·
</div>
</Article>
</Section>
</Layout>
);
}
@@ -0,0 +1,105 @@
'use client';
import { Layout, Section, Article, BodyText, Quote, Figure, PullQuote } from '@newspaperui/components';
const cn = { fontFamily: 'var(--font-family-cjk-serif)' };
const cnRed = { color: 'var(--nui-accent-cjk-red)' };
export default function ZhFeature() {
return (
<Layout columns={24} maxWidth="1200px" padding="2rem 1.5rem">
{/* 副刊报头 */}
<header style={{
borderTop: '2px solid var(--nui-text-primary)',
borderBottom: '1px solid var(--nui-rule-hairline)',
padding: '0.75rem 0',
marginBottom: '2rem',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'baseline',
}}>
<h1 style={{ ...cn, fontSize: '32px', fontWeight: 900, margin: 0, letterSpacing: '0.05em' }}> </h1>
<div style={{ ...cn, ...cnRed, fontSize: '14px', fontWeight: 600 }}>· ·</div>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)' }}>2026 5 19 · C </div>
</header>
{/* 专题主标题 */}
<Section columns={24} gap="2rem" style={{ marginBottom: '2rem' }}>
<Article span={24}>
<div style={{ ...cn, ...cnRed, fontSize: '13px', fontWeight: 700, marginBottom: '0.5rem', letterSpacing: '0.15em', textAlign: 'center' }}>访</div>
<h2 style={{ ...cn, fontSize: '52px', fontWeight: 900, lineHeight: 1.15, color: 'var(--nui-text-primary)', textAlign: 'center', margin: 0 }}>
</h2>
<h3 style={{ ...cn, fontSize: '20px', fontWeight: 500, lineHeight: 1.5, color: 'var(--nui-text-secondary)', textAlign: 'center', margin: '0.75rem 0 1rem 0', maxWidth: '900px', marginLeft: 'auto', marginRight: 'auto' }}>
访
</h3>
<div style={{ ...cn, textAlign: 'center', fontSize: '13px', color: 'var(--nui-text-muted)', marginBottom: '0.5rem' }}>
·
</div>
</Article>
</Section>
{/* 主图 + 介绍 */}
<Section columns={24} gap="2rem" style={{ marginBottom: '2rem' }}>
<Article span={12}>
<Figure
src="https://images.unsplash.com/photo-1582408921715-18e7806365c1?auto=format&fit=crop&w=1200&q=80"
alt="林文渊在工作室"
caption="林文渊在故宫博物院文华殿筹备中。"
credit="摄影 黄翔"
/>
</Article>
<Article span={12}>
<BodyText weight="High" dropCap style={cn}>
<p>殿线穿广穿</p>
<p></p>
<p></p>
<p>访殿线</p>
</BodyText>
</Article>
</Section>
{/* 访谈正文(双栏) */}
<Section columns={24} gap="2rem" style={{ marginBottom: '2rem' }}>
<Article span={24}>
<BodyText weight="High" columns={2} style={cn}>
<p style={{ ...cnRed, fontWeight: 700, marginBottom: '0.5rem' }}></p>
<p>西</p>
</BodyText>
</Article>
<Article span={24}>
<PullQuote weight="High" align="center" author="林文渊" style={{ margin: '1rem 0 2rem' }}>
亿
</PullQuote>
</Article>
<Article span={24}>
<BodyText weight="High" columns={2} style={cn}>
<p style={{ ...cnRed, fontWeight: 700, marginBottom: '0.5rem' }}></p>
<p>西西</p>
<p></p>
<p></p>
<p style={{ ...cnRed, fontWeight: 700, marginTop: '1rem', marginBottom: '0.5rem' }}></p>
<p> A B 线</p>
<p style={{ ...cnRed, fontWeight: 700, marginTop: '1rem', marginBottom: '0.5rem' }}></p>
<p></p>
</BodyText>
</Article>
</Section>
{/* 尾声引语 */}
<Section columns={24} gap="2rem" style={{ marginTop: '2rem', paddingTop: '2rem', borderTop: '1px solid var(--nui-rule-hairline)' }}>
<Article span={24}>
<Quote variant="block" weight="High" style={{ ...cn, textAlign: 'center', maxWidth: '700px', margin: '0 auto', borderLeft: 'none' }}>
访殿
</Quote>
<div style={{ ...cn, fontSize: '12px', color: 'var(--nui-text-muted)', textAlign: 'center', marginTop: '1rem', letterSpacing: '0.1em' }}>
· 殿
</div>
</Article>
</Section>
</Layout>
);
}
@@ -0,0 +1,198 @@
'use client';
import { Layout, Section, Article, Rule, BodyText, Figure } from '@newspaperui/components';
const cn = { fontFamily: 'var(--font-family-cjk-serif)' };
const cnRed = { color: 'var(--nui-accent-cjk-red)' };
export default function ZhFrontPage() {
return (
<Layout columns={24} maxWidth="1280px" padding="1.5rem 1rem">
{/* 报头 */}
<header style={{
textAlign: 'center',
borderTop: '4px solid var(--nui-accent-cjk-red)',
borderBottom: '1px solid var(--nui-rule-decorative)',
paddingTop: '1rem',
paddingBottom: '0.5rem',
}}>
<div style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '11px',
color: 'var(--nui-text-muted)',
letterSpacing: '0.2em',
marginBottom: '0.25rem',
}}>RENMIN ZHOUBAO · </div>
<h1 style={{
...cn,
...cnRed,
fontSize: '88px',
fontWeight: 900,
margin: 0,
letterSpacing: '0.1em',
lineHeight: 1,
}}></h1>
<div style={{
...cn,
display: 'flex',
justifyContent: 'space-between',
fontSize: '12px',
color: 'var(--nui-text-secondary)',
padding: '0.5rem 1rem',
borderTop: '1px solid var(--nui-rule-hairline)',
marginTop: '0.5rem',
}}>
<span> 2026 · 5891 </span>
<span>2026 5 19 · · </span>
<span> 5 · 260 </span>
</div>
</header>
{/* 版面导航条 */}
<div style={{
...cn,
display: 'flex',
gap: '0',
fontSize: '12px',
borderTop: '1px solid var(--nui-rule-hairline)',
borderBottom: '1px solid var(--nui-rule-hairline)',
marginTop: '1rem',
}}>
{['01版 要闻', '02版 经济', '03版 国际', '04版 文化', '05版 体育', '06版 副刊'].map((v, i) => (
<div key={i} style={{
padding: '0.4rem 1rem',
borderRight: '1px solid var(--nui-rule-hairline)',
color: i === 0 ? 'var(--nui-accent-cjk-red)' : 'var(--nui-text-secondary)',
fontWeight: i === 0 ? 700 : 400,
cursor: 'pointer',
}}>{v}</div>
))}
</div>
{/* 头条区 */}
<Section columns={24} gap="1rem" style={{ marginTop: '1rem', paddingBottom: '1rem', borderBottom: '2px solid var(--nui-rule-decorative)' }}>
<Article span={24}>
<div style={{ ...cn, ...cnRed, fontSize: '13px', fontWeight: 700, marginBottom: '0.5rem', textAlign: 'center', letterSpacing: '0.1em' }}></div>
<h2 style={{ ...cn, fontSize: '56px', fontWeight: 900, lineHeight: 1.1, color: 'var(--nui-text-primary)', textAlign: 'center', margin: 0 }}>
</h2>
<h3 style={{ ...cn, fontSize: '24px', fontWeight: 500, lineHeight: 1.4, color: 'var(--nui-text-secondary)', textAlign: 'center', margin: '0.5rem 0 1rem 0' }}>
</h3>
<div style={{ ...cn, textAlign: 'center', fontSize: '12px', color: 'var(--nui-text-muted)', marginBottom: '1rem' }}>
·
</div>
<Figure
src="https://images.unsplash.com/photo-1529107386315-e1a2ed48a620?auto=format&fit=crop&w=1200&q=80"
alt="签署仪式现场"
caption="各国代表在布鲁塞尔会议中心签署协定。"
credit="新华社记者 摄"
style={{ marginBottom: '1rem' }}
/>
<BodyText weight="Medium" columns={3} dropCap style={cn}>
<p> </p>
<p> 2040 2028 </p>
<p> 1.2% 0.7%</p>
<p></p>
<p>便</p>
<p></p>
<p></p>
<p> 2028 </p>
<p> 18 20 </p>
</BodyText>
</Article>
</Section>
{/* 二条区:3 栏并列 */}
<Section columns={24} gap="1rem" style={{ marginTop: '1rem', paddingBottom: '1rem', borderBottom: '1px solid var(--nui-rule-decorative)' }}>
<Article span={8} style={{ border: '1px solid var(--nui-rule-hairline)', padding: '1rem', background: 'var(--nui-bg-surface)' }}>
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem' }}> </div>
<h3 style={{ ...cn, fontSize: '22px', fontWeight: 700, lineHeight: 1.3, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}></h3>
<BodyText weight="Low" style={cn}>
<p></p>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...cn, fontSize: '17px', fontWeight: 600, lineHeight: 1.3, margin: '0 0 0.4rem 0' }}>线</h4>
<BodyText weight="Low" style={cn}>
<p>亿线线 A8 </p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...cn, fontSize: '17px', fontWeight: 600, lineHeight: 1.3, margin: '0 0 0.4rem 0' }}></h4>
<BodyText weight="Low" style={cn}>
<p> A10</p>
</BodyText>
</Article>
<Article span={8} style={{ border: '1px solid var(--nui-rule-hairline)', padding: '1rem', background: 'var(--nui-bg-surface)' }}>
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem' }}> </div>
<h3 style={{ ...cn, fontSize: '22px', fontWeight: 700, lineHeight: 1.3, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}> PMI </h3>
<BodyText weight="Low" style={cn}>
<p> 52.4</p>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...cn, fontSize: '17px', fontWeight: 600, lineHeight: 1.3, margin: '0 0 0.4rem 0' }}> 3.7%</h4>
<BodyText weight="Low" style={cn}>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...cn, fontSize: '17px', fontWeight: 600, lineHeight: 1.3, margin: '0 0 0.4rem 0' }}></h4>
<BodyText weight="Low" style={cn}>
<p></p>
</BodyText>
</Article>
<Article span={8} style={{ border: '1px solid var(--nui-rule-hairline)', padding: '1rem', background: 'var(--nui-bg-surface)' }}>
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem' }}> · </div>
<h3 style={{ ...cn, fontSize: '22px', fontWeight: 700, lineHeight: 1.3, color: 'var(--nui-text-primary)', margin: '0 0 0.5rem 0' }}></h3>
<BodyText weight="Low" style={cn}>
<p>殿</p>
<p></p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...cn, fontSize: '17px', fontWeight: 600, lineHeight: 1.3, margin: '0 0 0.4rem 0' }}></h4>
<BodyText weight="Low" style={cn}>
<p> 18%</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '0.75rem 0' }} />
<h4 style={{ ...cn, fontSize: '17px', fontWeight: 600, lineHeight: 1.3, margin: '0 0 0.4rem 0' }}></h4>
<BodyText weight="Low" style={cn}>
<p></p>
</BodyText>
</Article>
</Section>
{/* 简讯 + 要点提示 */}
<Section columns={24} gap="1rem" style={{ marginTop: '1rem' }}>
<Article span={6} style={{ background: 'var(--nui-bg-surface)', padding: '1rem', borderLeft: '3px solid var(--nui-accent-cjk-red)' }}>
<div style={{ ...cn, ...cnRed, fontSize: '11px', fontWeight: 700, marginBottom: '0.5rem', letterSpacing: '0.1em' }}></div>
<ul style={{ ...cn, fontSize: '14px', lineHeight: 1.7, paddingLeft: '1.2em', margin: 0, color: 'var(--nui-text-body)' }}>
<li> · A2</li>
<li> · A4</li>
<li> · B1</li>
<li> · C3</li>
<li> · C5</li>
<li> · D2</li>
<li> · E1</li>
<li> · F4</li>
</ul>
</Article>
<Article span={18}>
<div style={{ ...cn, ...cnRed, fontSize: '12px', fontWeight: 700, marginBottom: '0.5rem' }}> · </div>
<BodyText weight="Low" columns={4} style={cn}>
<p><strong></strong> 8000 西</p>
<p><strong></strong> </p>
<p><strong></strong> 退</p>
<p><strong>广</strong> 500 亿</p>
<p><strong></strong> </p>
<p><strong></strong> </p>
<p><strong></strong> </p>
<p><strong></strong> </p>
<p><strong></strong> 25 </p>
</BodyText>
</Article>
</Section>
</Layout>
);
}
@@ -32,6 +32,33 @@ export default function BlackletterFrontPage() {
<p>Verbände begrüßen die Pläne, mahnen aber Übergangsfristen für kleinere Betriebe an.
Wirtschaft, Seite 9.</p>
</BodyText>
<hr className="nui-rule-hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Haushaltsentwurf sorgt für Streit in der Koalition</Headline>
<BodyText weight="Low">
<p>Die Fraktionsvorsitzenden konnten sich nicht auf Kürzungen im Sozialbereich einigen.
Innenpolitik, Seite 3.</p>
</BodyText>
<hr className="nui-rule-hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Neue Studie belegt Rückgang der Artenvielfalt</Headline>
<BodyText weight="Low">
<p>Forscher der Universität Freiburg dokumentieren einen Verlust von 23 Prozent bei
Insektenpopulationen seit 2015. Wissenschaft, Seite 7.</p>
</BodyText>
<hr className="nui-rule-hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Frankfurter Buchmesse meldet Besucherrekord</Headline>
<BodyText weight="Low">
<p>Über 300.000 Besucher kamen in diesem Jahr, ein Anstieg von zwölf Prozent gegenüber
dem Vorjahr. Feuilleton, Seite 11.</p>
</BodyText>
<hr className="nui-rule-hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Bahn plant Ausbau der Nachtzugverbindungen</Headline>
<BodyText weight="Low">
<p>Ab Dezember sollen fünf neue Strecken das europäische Netz ergänzen. Wirtschaft, Seite 8.</p>
</BodyText>
</Article>
<Article span={18}>
@@ -66,6 +93,31 @@ export default function BlackletterFrontPage() {
mit einem Plus von 1,2 Prozent. Die Währung legte gegenüber dem Dollar um 0,7 Prozent zu.
Anleiherenditen, die während der Verhandlungen wegen fiskalischer Sorgen gestiegen waren, kehrten
auf das Niveau vor Beginn der Gespräche zurück.</p>
<p>Die weitreichendsten Bestimmungen des Rahmenabkommens betreffen die Schwerindustrie.
Zement-, Stahl- und Chemieproduzenten müssten ab 2028 eine gestaffelte CO-Abgabe
entrichten, deren Einnahmen in einen kontinentalen Investitionsfonds für klimafreundliche
Fertigung fließen sollen. Industrieverbände äußerten vorsichtige Zustimmung, während
Umweltgruppen die verbindliche Architektur lobten, aber warnten, der Zeitplan gebe
Verschmutzern zu viel Spielraum.</p>
<p>Die innenpolitischen Reaktionen fielen gemischt aus. Die Arbeitsbestimmungen des
Abkommens, die Mindeststandards für bezahlten Urlaub und Tarifverhandlungen festlegen,
stießen bei Gewerkschaften auf sofortige Zustimmung und bei Wirtschaftskammern auf
ebenso sofortige Bedenken. Der Vorsitzende des Bundesverbandes der Industrie warnte,
kleine Unternehmen würden ohne Übergangsunterstützung mit den Compliance-Kosten kämpfen.</p>
<p>Parlamentarische Führer in drei Hauptstädten signalisierten, dass die Ratifizierung
noch vor der Sommerpause erfolgen könnte. Zwei Regierungen kündigten jedoch an, vorher
Volksabstimmungen abhalten zu wollen ein Prozess, der sich voraussichtlich bis in den
Herbst hinziehen wird. Analysten des Zentrums für Handelsstudien schätzten, dass die
vollständige Umsetzung selbst im günstigsten Fall mindestens achtzehn Monate erfordern würde.</p>
<p>Für gewöhnliche Reisende und Verbraucher werden die unmittelbaren Auswirkungen bescheiden
sein. Grenzverfahren und Produktstandards unterliegen bis zur Ratifizierung weiterhin den
bestehenden Regelungen. Der längere Bogen, so argumentierten die Verhandlungsführer, sei
das Entscheidende: ein Kontinent historisch zerstrittener Nachbarn, der sich auf ein
einheitliches Regelwerk für das folgenreichste Jahrzehnt seit Menschengedenken einigt.</p>
</BodyText>
<PullQuote weight="High" author="Margarethe Lindqvist, Chefverhandlerin" align="left">
@@ -79,6 +131,21 @@ export default function BlackletterFrontPage() {
<p>Parlamentarische Führer in drei Hauptstädten signalisierten, dass die Ratifizierung noch vor
der Sommerpause erfolgen könnte. Zwei Regierungen kündigten an, vorher Volksabstimmungen abhalten
zu wollen.</p>
<p>Die Unterzeichnungszeremonie, ursprünglich für vergangenen Freitag geplant, wurde
dreimal verschoben, während die Verfasser konkurrierende Texte zur Streitbeilegung
abglichen. Der endgültige Kompromiss sieht ein Schiedsgericht aus neun Juristen vor,
je drei ernannt von jeder der drei regionalen Gruppierungen des Blocks.</p>
<p>Kritiker von rechts verurteilten das Rahmenwerk als Erosion nationaler Souveränität,
während Kritiker von links argumentierten, der Arbeitsstandard sei zu niedrig angesetzt,
um Arbeitnehmer in strengeren Regulierungsregimen wirksam zu schützen. Beide Lager
signalisierten, dass die Ratifizierungskämpfe heftig werden dürften.</p>
<p>Historiker der kontinentalen Integration merkten an, dass der Umfang des Abkommens
jede einzelne Vereinbarung seit den Nachkriegs-Wiederaufbauverträgen übertrifft. Was
dieses Abkommen anders mache, so Professor Elena Marchetti, sei dass es jeden Haushalt
berühre nicht nur durch den Handel, sondern durch die Luft und die Löhne.</p>
</BodyText>
</Article>
</Section>
@@ -0,0 +1,277 @@
'use client';
import {
Layout, Section, Article, Masthead, Rule,
Headline, Subhead, Kicker, BodyText, Byline, Dateline,
Figure, PullQuote,
} from '@newspaperui/components';
export default function FrontPage() {
return (
<Layout columns={24} maxWidth="1200px" padding="2rem 1.5rem">
<Masthead
variant="classic"
kicker="Late City Edition"
title="The Daily Chronicle"
edition="Vol. CXLIX · No. 51,895"
date="Tuesday, May 19, 2026"
price="$4.00"
/>
<Section columns={24} divider="bottom" gap="2rem" style={{ marginTop: '2rem' }}>
<Article span={5} style={{ borderRight: '1px solid var(--nui-rule-hairline)', paddingRight: '1.5rem' }}>
<Kicker>Inside Today</Kicker>
<Headline weight="Low" as="h3" style={{ marginTop: 0 }}>
Senate Approves Climate Resolution After Months of Debate
</Headline>
<BodyText weight="Low">
<p>The unanimous vote concludes a contentious legislative session marked by partisan disputes
and last-minute amendments. Page A6.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Tech Sector Gains as Inflation Eases</Headline>
<BodyText weight="Low">
<p>Major indices climbed for a fifth consecutive session as new data showed price growth
slowing across consumer goods. Business B1.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Drought Conditions Worsen Across the Plains</Headline>
<BodyText weight="Low">
<p>Officials in seven states have requested federal disaster relief as reservoir levels reach
historic lows. National A12.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">New Exhibit Opens at the Metropolitan</Headline>
<BodyText weight="Low">
<p>A retrospective of mid-century textile design draws record opening crowds. Arts C3.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">City Council Approves Transit Expansion</Headline>
<BodyText weight="Low">
<p>The $2.4 billion plan adds three new rail lines and extends service hours on existing routes. Metro A8.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">University Announces Record Enrollment</Headline>
<BodyText weight="Low">
<p>Applications rose 18 percent this cycle, driven by expanded financial aid programs. Education B4.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Harbor Restoration Project Begins</Headline>
<BodyText weight="Low">
<p>Engineers will dredge sediment and rebuild seawalls over a three-year timeline. Local A10.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Orchestra Names New Music Director</Headline>
<BodyText weight="Low">
<p>The appointment ends a two-year search following the previous director&rsquo;s retirement. Arts C1.</p>
</BodyText>
</Article>
<Article span={14}>
<div style={{ textAlign: 'center' }}><Kicker>Capitol · Breaking</Kicker></div>
<Headline weight="High" align="center">
Historic Accord Reshapes Continental Trade After Marathon Session
</Headline>
<Subhead weight="High" style={{ textAlign: 'center', marginTop: 0 }}>
Negotiators emerge with sweeping framework on tariffs, labor, and emissions; ratification expected within weeks
</Subhead>
<div style={{ display: 'flex', justifyContent: 'center', gap: '1rem', margin: '0.5rem 0 1rem', alignItems: 'baseline' }}>
<Byline>By Eleanor Whitcombe and Marcus Reyes</Byline>
<span style={{ color: 'var(--nui-text-muted)' }}>·</span>
<span style={{ fontFamily: 'var(--font-family-meta)', fontSize: '12px', color: 'var(--nui-text-muted)' }}>5 min read</span>
</div>
<Figure
src="https://images.unsplash.com/photo-1572949645841-094f3a9c4c94?auto=format&fit=crop&w=1200&q=80"
alt="Diplomats applaud after the final draft was approved"
caption="Negotiators applaud after the final draft was approved Monday evening at the Continental Conference Center."
credit="Photograph by Jane Doe / Pool"
/>
<BodyText weight="High" columns={3} dropCap style={{ marginTop: '1.5rem' }}>
<p><Dateline>Brussels </Dateline> After eleven consecutive days of negotiation that several
participants described as the most demanding in a generation, delegates from twenty-three nations
announced on Monday a sweeping framework to reorganize commerce across the continent. The accord,
which still requires ratification by member parliaments, would harmonize tariff schedules, set
common labor standards, and bind signatories to a shared emissions pathway through 2040.</p>
<p>Officials briefed on the talks said the breakthrough came shortly before midnight, when a
dispute over agricultural subsidies was resolved with a side letter granting transitional relief
to producers in five smaller economies. The chief negotiator, Margarethe Lindqvist, called the
outcome &ldquo;a long argument that finally became a conversation.&rdquo;</p>
<p>The framework&rsquo;s most consequential provisions target heavy industry. Cement, steel, and
chemical producers would face a graduated carbon levy beginning in 2028, with revenues recycled
into a continental investment fund for low-carbon manufacturing. Industry associations expressed
cautious support, while environmental groups praised the levy&rsquo;s binding architecture but warned
that the timeline gives polluters too much room to delay.</p>
<p>Markets reacted with measured optimism. The continental composite index closed up 1.2 percent,
led by capital-goods makers expected to benefit from infrastructure investment. The currency
strengthened against the dollar by 0.7 percent. Bond yields, which had climbed throughout the
negotiations on fiscal-stability concerns, retreated to levels seen before the talks began.</p>
<p>Domestic political reaction was mixed. The accord&rsquo;s labor provisions, which establish minimum
standards for paid leave and collective bargaining, drew immediate praise from union federations
and equally immediate concern from chambers of commerce. The chairman of the Federation of
Industries warned that small firms would struggle with compliance costs absent transitional support.</p>
<p>Parliamentary leaders in three capitals signaled that ratification could occur before the
summer recess. Two governments, however, indicated that they would seek public referenda before
committing, a process likely to extend into the autumn. Analysts at the Centre for Trade Studies
estimated that full implementation, even on the most expedited timeline, would require at least
eighteen months.</p>
<p>For ordinary travelers and consumers, the immediate effects will be modest. Border procedures
and product standards remain governed by existing arrangements pending ratification. The longer
arc is what matters: a continent of historically fractious neighbors agreeing on a single set of
rules for the most consequential decade in living memory.</p>
<p>The accord&rsquo;s environmental chapter, which drew the most sustained opposition during
negotiations, establishes a continental carbon market linked to existing national schemes.
Permits would be tradeable across borders beginning in 2030, with a price floor set at
forty-five units per ton of carbon dioxide equivalent. Economists at the Institute for
Climate Economics estimated that the floor alone would reduce emissions by eight to twelve
percent within the first five years of operation.</p>
<p>Labor unions in the industrial heartland expressed qualified support. The secretary-general
of the Metalworkers&rsquo; Federation said the transition fund &ldquo;acknowledges what we have argued
for years: that decarbonization cannot be built on the backs of workers.&rdquo; But she cautioned
that the fund&rsquo;s governance structure, which gives equal weight to employer and employee
representatives, could slow disbursements at a moment when speed matters most.</p>
<p>Small and medium enterprises, which employ roughly sixty percent of the continental
workforce, face a distinct set of challenges. The accord exempts firms below a revenue
threshold from the carbon levy for three years, but compliance with the new labor standards
is immediate. Business associations in four countries have already requested technical
assistance programs to help smaller firms adapt their payroll and reporting systems.</p>
<p>Historians of continental integration noted that the accord&rsquo;s scope exceeds any single
agreement since the postwar reconstruction treaties. &ldquo;What makes this different,&rdquo; said
Professor Elena Marchetti of the University of Turin, &ldquo;is that it touches every household&mdash;
not just through trade, but through the air they breathe and the wages they earn.&rdquo;</p>
</BodyText>
<PullQuote weight="High" author="Margarethe Lindqvist, Chief Negotiator" align="center" style={{ margin: '2rem 0' }}>
A long argument that finally became a conversation.
</PullQuote>
<BodyText weight="High" columns={2} style={{ marginTop: '1rem' }}>
<p>The accord&rsquo;s signing ceremony, originally scheduled for last Friday, was delayed three times
as drafters reconciled competing texts on dispute resolution. The final compromise establishes
an arbitration panel of nine jurists, three appointed by each of the bloc&rsquo;s three regional
groupings, with binding authority over commercial disputes exceeding twenty million units.</p>
<p>Critics on the populist right denounced the framework as an erosion of national sovereignty,
while critics on the left argued that the labor floor was set too low to meaningfully protect
workers in tighter regulatory regimes. Both camps signaled that ratification battles would be
fierce, particularly in legislatures with narrow majorities.</p>
</BodyText>
</Article>
<Article span={5} style={{ borderLeft: '1px solid var(--nui-rule-hairline)', paddingLeft: '1.5rem' }}>
<Kicker>Foreign Desk</Kicker>
<Headline weight="Medium" as="h2">
Coastal Nations Pledge Joint Action on Maritime Pollution
</Headline>
<Subhead weight="Medium">
Pact follows years of stalled regional talks and a cascade of recent shipping accidents.
</Subhead>
<Byline>By Tomás Almeida</Byline>
<BodyText weight="Medium" style={{ marginTop: '0.75rem' }}>
<p><Dateline>Lisbon </Dateline> Eleven coastal nations announced a binding compact to coordinate
cleanup operations and harmonize liability rules for vessels exceeding fifty thousand tons. The
agreement establishes a shared rapid-response fund and creates a regional inspectorate empowered
to detain non-compliant ships in any signatory port.</p>
<p>Maritime industry groups received the news with caution. A spokesperson for the Continental
Shipping Council acknowledged that &ldquo;stronger common rules are overdue&rdquo; but warned that
implementation costs could fall disproportionately on smaller operators.</p>
<p>The compact takes effect on January 1, pending technical annexes. Environmental observers
described the pact as the most consequential maritime accord in a decade.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Fisheries Report Warns of Declining Stocks</Headline>
<BodyText weight="Low">
<p>Annual survey data shows a 14 percent drop in key commercial species across the northern
shelf. Scientists attribute the decline to warming waters and overfishing in adjacent
unregulated zones. Environment A9.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Rail Strike Averted After Late-Night Deal</Headline>
<BodyText weight="Low">
<p>Workers accepted a revised pay offer minutes before the midnight deadline. Services
resume on normal schedules. Transport B2.</p>
</BodyText>
</Article>
</Section>
<Section columns={24} divider="top" gap="2rem" style={{ marginTop: '2rem', paddingTop: '2rem' }}>
<Article span={24}>
<Kicker>National · Investigation</Kicker>
<Headline weight="Medium" as="h2">
Records Reveal Years of Overlooked Warnings at Aging Reservoirs
</Headline>
<Subhead weight="Medium">
Internal inspection memoranda, obtained through public records requests, suggest that
structural concerns flagged repeatedly by field engineers were not escalated to senior staff.
</Subhead>
<Byline style={{ marginBottom: '1rem' }}>By Ravi Nair, Anita Kowalski, and Charles Weston</Byline>
<BodyText weight="High" columns={4}>
<p><Dateline>Sacramento </Dateline> A six-month review of more than four thousand pages of
inspection records, interviews with twenty-three current and former engineers, and reconstructions
of three near-failure incidents reveals a pattern of unheeded warnings about the structural
integrity of mid-twentieth-century earthen dams across the western states.</p>
<p>The records show that field engineers documented concerns about seepage, erosion, and spillway
capacity in repeated annual assessments dating back at least fifteen years. In several instances,
those concerns were rated &ldquo;moderate&rdquo; in the field reports but downgraded to &ldquo;low&rdquo; by the time they
reached senior officials. The pattern was particularly pronounced at three facilities serving
regions of more than two million residents.</p>
<p>Officials at the Department of Water Resources, asked to review excerpts of the records, said
in a written statement that &ldquo;every reservoir under our oversight has been deemed safe for current
operations&rdquo; but did not specifically address the discrepancies between field and final ratings.
The agency declined to make senior staff available for interviews.</p>
<p>The findings come amid renewed scrutiny of aging infrastructure following the partial collapse
of an earthen embankment in March that displaced more than fifteen hundred residents. Federal
inspectors who responded to that incident found the proximate cause to be precisely the type of
seepage concern that field engineers had flagged in three of the past four annual assessments.</p>
<p>The investigative review found that of forty-seven reservoirs surveyed, sixteen had at least
one instance in which a &ldquo;moderate&rdquo; or &ldquo;high&rdquo; field rating was downgraded before reaching senior
management. In nine cases, the downgrades persisted for three or more consecutive years. None of
the affected facilities have publicly disclosed the discrepancies.</p>
<p>Engineering professional associations have, in recent years, called for an independent review
of inspection workflows in the western states. A spokesperson for the Society of Hydraulic
Engineers said the Society was &ldquo;deeply concerned&rdquo; by the patterns described and would convene a
working group to examine reform options.</p>
</BodyText>
</Article>
</Section>
</Layout>
);
}
+6 -2
View File
@@ -1,15 +1,19 @@
import './globals.css';
import type { Metadata } from 'next';
import { Header } from '../components/Header';
export const metadata: Metadata = {
title: 'NewspaperUI — Production Newspaper Components',
description: '生产级报纸布局组件库,参考 InDesign 与经典严肃风排版传统,24 列栅格、跨栏、视觉权重和主题系统',
description: '生产级报纸布局组件库',
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="zh">
<body>{children}</body>
<body>
<Header />
{children}
</body>
</html>
);
}
+249 -178
View File
@@ -1,205 +1,276 @@
'use client';
import {
Layout, Section, Article, Masthead, Rule,
Headline, Subhead, Kicker, BodyText, Byline, Dateline,
Figure, PullQuote,
Layout,
Section,
Article,
Masthead,
Headline,
Subhead,
Kicker,
BodyText,
} from '@newspaperui/components';
import Link from 'next/link';
export default function FrontPage() {
const demos = [
{
href: '/blocks/zh-frontpage',
lang: '中文 · Chinese',
title: '人民周报 · 头版',
description: '思源宋体 + 克制朱红 + 紧凑排版。中文报纸传统视觉语言。',
color: '#CC2929',
},
{
href: '/blocks/zh-feature',
lang: '中文 · Chinese',
title: '人民周报 · 副刊专题',
description: '深度专题排版:访谈、人物、文化评论。',
color: '#CC2929',
},
{
href: '/examples/nyt-frontpage',
lang: 'English',
title: 'The Daily Chronicle · NYT Style',
description:
'Classic American serious newspaper. Cormorant Garamond masthead, multi-column flow with drop cap.',
color: '#1A1A1A',
},
{
href: '/blocks/en-feature',
lang: 'English',
title: 'The Daily Chronicle · Long-form Feature',
description: 'Editorial long-form piece with pull quotes and editorial design.',
color: '#1A1A1A',
},
{
href: '/blocks/jp-horizontal',
lang: '日本語 · Japanese',
title: '朝日新聞 · 横組み',
description: 'Modern horizontal Japanese newspaper layout. Noto Serif JP.',
color: '#1B2A4A',
},
{
href: '/blocks/jp-vertical',
lang: '日本語 · Japanese',
title: '朝日新聞 · 縦組み',
description: 'Traditional vertical writing-mode Japanese layout.',
color: '#1B2A4A',
},
{
href: '/examples/blackletter-frontpage',
lang: 'Deutsch',
title: 'Die Frankfurter Zeitung',
description: 'Blackletter masthead with UnifrakturMaguntia. German broadsheet tradition.',
color: '#1A1A1A',
},
];
export default function LandingPage() {
return (
<Layout columns={24} maxWidth="1200px" padding="2rem 1.5rem">
<Layout columns={24} maxWidth="1400px" padding="3rem 2rem 4rem">
<Masthead
variant="classic"
kicker="Late City Edition"
title="The Daily Chronicle"
edition="Vol. CXLIX · No. 51,895"
date="Tuesday, May 19, 2026"
price="$4.00"
kicker="Production Newspaper Components"
title="NewspaperUI"
edition="Vol. 01 · No. 1"
date="May 2026"
price="MIT License"
/>
<Section columns={24} divider="bottom" gap="2rem" style={{ marginTop: '2rem' }}>
<Article span={5} style={{ borderRight: '1px solid var(--nui-rule-hairline)', paddingRight: '1.5rem' }}>
<Kicker>Inside Today</Kicker>
<Headline weight="Low" as="h3" style={{ marginTop: 0 }}>
Senate Approves Climate Resolution After Months of Debate
<Section columns={24} gap="2rem" style={{ marginTop: '3rem' }}>
<Article span={6}>
<Kicker>About</Kicker>
<Headline weight="Low" as="h2" style={{ marginTop: 0 }}>
</Headline>
<BodyText weight="Low">
<p>The unanimous vote concludes a contentious legislative session marked by partisan disputes
and last-minute amendments. Page A6.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Tech Sector Gains as Inflation Eases</Headline>
<BodyText weight="Low">
<p>Major indices climbed for a fifth consecutive session as new data showed price growth
slowing across consumer goods. Business B1.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">Drought Conditions Worsen Across the Plains</Headline>
<BodyText weight="Low">
<p>Officials in seven states have requested federal disaster relief as reservoir levels reach
historic lows. National A12.</p>
</BodyText>
<Rule variant="hairline" style={{ margin: '1rem 0' }} />
<Headline weight="Low" as="h3">New Exhibit Opens at the Metropolitan</Headline>
<BodyText weight="Low">
<p>A retrospective of mid-century textile design draws record opening crowds. Arts C3.</p>
<BodyText weight="Medium">
<p>
InDesign NYT / The Times / FAZ 24 CSS Grid +
Multi-column
</p>
</BodyText>
</Article>
<Article span={14}>
<div style={{ textAlign: 'center' }}><Kicker>Capitol · Breaking</Kicker></div>
<Headline weight="High" align="center">
Historic Accord Reshapes Continental Trade After Marathon Session
<Article span={12}>
<Headline weight="Medium" align="center">
Print-grade typography, on the modern web.
</Headline>
<Subhead weight="High" style={{ textAlign: 'center', marginTop: 0 }}>
Negotiators emerge with sweeping framework on tariffs, labor, and emissions; ratification expected within weeks
<Subhead
weight="High"
style={{ textAlign: 'center', marginTop: '0.5rem' }}
>
18 components, 24-column grid, classic serif typography, real multi-column flow.
</Subhead>
<div style={{ display: 'flex', justifyContent: 'center', gap: '1rem', margin: '0.5rem 0 1rem', alignItems: 'baseline' }}>
<Byline>By Eleanor Whitcombe and Marcus Reyes</Byline>
<span style={{ color: 'var(--nui-text-muted)' }}>·</span>
<span style={{ fontFamily: 'var(--font-family-meta)', fontSize: '12px', color: 'var(--nui-text-muted)' }}>5 min read</span>
</Article>
<Article span={6}>
<Kicker>Quick Start</Kicker>
<Headline weight="Low" as="h2" style={{ marginTop: 0 }}>
Install
</Headline>
<BodyText weight="Medium">
<p style={{ fontFamily: 'var(--font-family-meta)', fontSize: '13px' }}>
<code>pnpm add @newspaperui/components @newspaperui/theme</code>
</p>
</BodyText>
<div style={{ marginTop: '1rem' }}>
<Link
href="/grid-system"
style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '13px',
color: 'var(--nui-accent-primary)',
textDecoration: 'none',
fontWeight: 600,
}}
>
Documentation
</Link>
</div>
<Figure
src="https://images.unsplash.com/photo-1572949645841-094f3a9c4c94?auto=format&fit=crop&w=1200&q=80"
alt="Diplomats applaud after the final draft was approved"
caption="Negotiators applaud after the final draft was approved Monday evening at the Continental Conference Center."
credit="Photograph by Jane Doe / Pool"
/>
<BodyText weight="High" columns={3} dropCap style={{ marginTop: '1.5rem' }}>
<p><Dateline>Brussels </Dateline> After eleven consecutive days of negotiation that several
participants described as the most demanding in a generation, delegates from twenty-three nations
announced on Monday a sweeping framework to reorganize commerce across the continent. The accord,
which still requires ratification by member parliaments, would harmonize tariff schedules, set
common labor standards, and bind signatories to a shared emissions pathway through 2040.</p>
<p>Officials briefed on the talks said the breakthrough came shortly before midnight, when a
dispute over agricultural subsidies was resolved with a side letter granting transitional relief
to producers in five smaller economies. The chief negotiator, Margarethe Lindqvist, called the
outcome &ldquo;a long argument that finally became a conversation.&rdquo;</p>
<p>The framework&rsquo;s most consequential provisions target heavy industry. Cement, steel, and
chemical producers would face a graduated carbon levy beginning in 2028, with revenues recycled
into a continental investment fund for low-carbon manufacturing. Industry associations expressed
cautious support, while environmental groups praised the levy&rsquo;s binding architecture but warned
that the timeline gives polluters too much room to delay.</p>
<p>Markets reacted with measured optimism. The continental composite index closed up 1.2 percent,
led by capital-goods makers expected to benefit from infrastructure investment. The currency
strengthened against the dollar by 0.7 percent. Bond yields, which had climbed throughout the
negotiations on fiscal-stability concerns, retreated to levels seen before the talks began.</p>
<p>Domestic political reaction was mixed. The accord&rsquo;s labor provisions, which establish minimum
standards for paid leave and collective bargaining, drew immediate praise from union federations
and equally immediate concern from chambers of commerce. The chairman of the Federation of
Industries warned that small firms would struggle with compliance costs absent transitional support.</p>
<p>Parliamentary leaders in three capitals signaled that ratification could occur before the
summer recess. Two governments, however, indicated that they would seek public referenda before
committing, a process likely to extend into the autumn. Analysts at the Centre for Trade Studies
estimated that full implementation, even on the most expedited timeline, would require at least
eighteen months.</p>
<p>For ordinary travelers and consumers, the immediate effects will be modest. Border procedures
and product standards remain governed by existing arrangements pending ratification. The longer
arc is what matters: a continent of historically fractious neighbors agreeing on a single set of
rules for the most consequential decade in living memory.</p>
</BodyText>
<PullQuote weight="High" author="Margarethe Lindqvist, Chief Negotiator" align="center" style={{ margin: '2rem 0' }}>
A long argument that finally became a conversation.
</PullQuote>
<BodyText weight="High" columns={2} style={{ marginTop: '1rem' }}>
<p>The accord&rsquo;s signing ceremony, originally scheduled for last Friday, was delayed three times
as drafters reconciled competing texts on dispute resolution. The final compromise establishes
an arbitration panel of nine jurists, three appointed by each of the bloc&rsquo;s three regional
groupings, with binding authority over commercial disputes exceeding twenty million units.</p>
<p>Critics on the populist right denounced the framework as an erosion of national sovereignty,
while critics on the left argued that the labor floor was set too low to meaningfully protect
workers in tighter regulatory regimes. Both camps signaled that ratification battles would be
fierce, particularly in legislatures with narrow majorities.</p>
</BodyText>
</Article>
<Article span={5} style={{ borderLeft: '1px solid var(--nui-rule-hairline)', paddingLeft: '1.5rem' }}>
<Kicker>Foreign Desk</Kicker>
<Headline weight="Medium" as="h2">
Coastal Nations Pledge Joint Action on Maritime Pollution
</Headline>
<Subhead weight="Medium">
Pact follows years of stalled regional talks and a cascade of recent shipping accidents.
</Subhead>
<Byline>By Tomás Almeida</Byline>
<BodyText weight="Medium" style={{ marginTop: '0.75rem' }}>
<p><Dateline>Lisbon </Dateline> Eleven coastal nations announced a binding compact to coordinate
cleanup operations and harmonize liability rules for vessels exceeding fifty thousand tons. The
agreement establishes a shared rapid-response fund and creates a regional inspectorate empowered
to detain non-compliant ships in any signatory port.</p>
<p>Maritime industry groups received the news with caution. A spokesperson for the Continental
Shipping Council acknowledged that &ldquo;stronger common rules are overdue&rdquo; but warned that
implementation costs could fall disproportionately on smaller operators.</p>
<p>The compact takes effect on January 1, pending technical annexes. Environmental observers
described the pact as the most consequential maritime accord in a decade.</p>
</BodyText>
</Article>
</Section>
<Section columns={24} divider="top" gap="2rem" style={{ marginTop: '2rem', paddingTop: '2rem' }}>
<Section
columns={24}
divider="top"
gap="2rem"
style={{ marginTop: '4rem', paddingTop: '3rem' }}
>
<Article span={24}>
<Kicker>National · Investigation</Kicker>
<Headline weight="Medium" as="h2">
Records Reveal Years of Overlooked Warnings at Aging Reservoirs
<div style={{ textAlign: 'center' }}>
<Kicker>Live Demos · Production-grade Examples</Kicker>
</div>
<Headline weight="High" align="center">
Multi-language Newspaper Showcase
</Headline>
<Subhead weight="Medium">
Internal inspection memoranda, obtained through public records requests, suggest that
structural concerns flagged repeatedly by field engineers were not escalated to senior staff.
<Subhead weight="Medium" style={{ textAlign: 'center' }}>
7 complete newspaper layouts in Chinese, English, German, and Japanese
</Subhead>
<Byline style={{ marginBottom: '1rem' }}>By Ravi Nair, Anita Kowalski, and Charles Weston</Byline>
</Article>
</Section>
<BodyText weight="High" columns={4}>
<p><Dateline>Sacramento </Dateline> A six-month review of more than four thousand pages of
inspection records, interviews with twenty-three current and former engineers, and reconstructions
of three near-failure incidents reveals a pattern of unheeded warnings about the structural
integrity of mid-twentieth-century earthen dams across the western states.</p>
<Section columns={24} gap="2rem" style={{ marginTop: '2rem' }}>
{demos.map((demo, idx) => (
<Article key={demo.href} span={24} style={{ marginBottom: '2rem' }}>
<Link
href={demo.href}
style={{ textDecoration: 'none', color: 'inherit', display: 'block' }}
>
<div
style={{
border: '1px solid var(--nui-rule-hairline)',
background: 'var(--nui-bg-surface)',
padding: '2rem',
display: 'grid',
gridTemplateColumns: '1fr 3fr',
gap: '2rem',
alignItems: 'center',
}}
>
<div
style={{
borderRight: '1px solid var(--nui-rule-hairline)',
paddingRight: '2rem',
}}
>
<div
style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '11px',
fontWeight: 600,
fontVariantCaps: 'small-caps',
letterSpacing: '0.08em',
color: demo.color,
marginBottom: '0.5rem',
}}
>
{demo.lang}
</div>
<div
style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '11px',
color: 'var(--nui-text-muted)',
}}
>
Demo #{String(idx + 1).padStart(2, '0')}
</div>
</div>
<div>
<h3
style={{
fontFamily: 'var(--font-family-display)',
fontSize: '28px',
fontWeight: 600,
lineHeight: 1.15,
color: 'var(--nui-text-primary)',
margin: '0 0 0.5rem 0',
}}
>
{demo.title}
</h3>
<p
style={{
fontFamily: 'var(--font-family-body)',
fontSize: '15px',
lineHeight: 1.5,
color: 'var(--nui-text-body)',
margin: 0,
}}
>
{demo.description}
</p>
<div
style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '12px',
fontWeight: 600,
color: 'var(--nui-accent-primary)',
marginTop: '0.75rem',
fontVariantCaps: 'small-caps',
letterSpacing: '0.06em',
}}
>
View demo
</div>
</div>
</div>
</Link>
</Article>
))}
</Section>
<p>The records show that field engineers documented concerns about seepage, erosion, and spillway
capacity in repeated annual assessments dating back at least fifteen years. In several instances,
those concerns were rated &ldquo;moderate&rdquo; in the field reports but downgraded to &ldquo;low&rdquo; by the time they
reached senior officials. The pattern was particularly pronounced at three facilities serving
regions of more than two million residents.</p>
<p>Officials at the Department of Water Resources, asked to review excerpts of the records, said
in a written statement that &ldquo;every reservoir under our oversight has been deemed safe for current
operations&rdquo; but did not specifically address the discrepancies between field and final ratings.
The agency declined to make senior staff available for interviews.</p>
<p>The findings come amid renewed scrutiny of aging infrastructure following the partial collapse
of an earthen embankment in March that displaced more than fifteen hundred residents. Federal
inspectors who responded to that incident found the proximate cause to be precisely the type of
seepage concern that field engineers had flagged in three of the past four annual assessments.</p>
<p>The investigative review found that of forty-seven reservoirs surveyed, sixteen had at least
one instance in which a &ldquo;moderate&rdquo; or &ldquo;high&rdquo; field rating was downgraded before reaching senior
management. In nine cases, the downgrades persisted for three or more consecutive years. None of
the affected facilities have publicly disclosed the discrepancies.</p>
<p>Engineering professional associations have, in recent years, called for an independent review
of inspection workflows in the western states. A spokesperson for the Society of Hydraulic
Engineers said the Society was &ldquo;deeply concerned&rdquo; by the patterns described and would convene a
working group to examine reform options.</p>
<Section
columns={24}
divider="top"
gap="2rem"
style={{ marginTop: '4rem', paddingTop: '2rem' }}
>
<Article span={12}>
<Kicker>Design Philosophy</Kicker>
<Headline weight="Low" as="h3" style={{ marginTop: 0 }}>
Print Tradition, Web Implementation
</Headline>
<BodyText weight="Low">
<p>
NewspaperUI InDesign
token visualWeights
</p>
<p>
Hybrid CSS Grid CSS Multi-column Web
</p>
</BodyText>
</Article>
<Article span={12}>
<Kicker>Tech Stack</Kicker>
<Headline weight="Low" as="h3" style={{ marginTop: 0 }}>
React 18 · TypeScript 5 · CSS Grid + Multi-column
</Headline>
<BodyText weight="Low">
<p>
4 packages<code>@newspaperui/theme</code><code>@newspaperui/utils</code>
<code>@newspaperui/components</code>18 components<code>@newspaperui/docs</code>
</p>
<p>Built with pnpm workspaces + Turborepo. Vite for libraries, Next.js 15 for docs.</p>
</BodyText>
</Article>
</Section>
+89
View File
@@ -0,0 +1,89 @@
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
const navItems = [
{ label: 'Docs', href: '/grid-system' },
{ label: 'Components', href: '/components/article' },
{ label: 'Themes', href: '/theme' },
{ label: 'Blocks', href: '/blocks' },
];
export function Header() {
const pathname = usePathname();
return (
<header
style={{
position: 'sticky',
top: 0,
zIndex: 50,
background: 'var(--nui-bg-page)',
borderBottom: '1px solid var(--nui-rule-hairline)',
backdropFilter: 'blur(8px)',
}}
>
<div
style={{
maxWidth: '1400px',
margin: '0 auto',
padding: '1rem 2rem',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: '2rem',
}}
>
<Link
href="/"
style={{
fontFamily: 'var(--font-family-masthead)',
fontSize: '24px',
fontWeight: 700,
color: 'var(--nui-text-primary)',
textDecoration: 'none',
letterSpacing: '0.02em',
}}
>
NewspaperUI
</Link>
<nav style={{ display: 'flex', gap: '2rem' }}>
{navItems.map((item) => {
const active =
pathname === item.href ||
(item.href !== '/' && pathname.startsWith(item.href));
return (
<Link
key={item.href}
href={item.href}
style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '14px',
fontWeight: 500,
color: active
? 'var(--nui-accent-primary)'
: 'var(--nui-text-secondary)',
textDecoration: 'none',
}}
>
{item.label}
</Link>
);
})}
<a
href="https://github.com"
target="_blank"
rel="noreferrer"
style={{
fontFamily: 'var(--font-family-meta)',
fontSize: '14px',
color: 'var(--nui-text-muted)',
textDecoration: 'none',
}}
>
GitHub
</a>
</nav>
</div>
</header>
);
}
+2 -2
View File
@@ -48,9 +48,9 @@ export function Sidebar() {
fontFamily: 'var(--font-family-meta)',
fontSize: '14px',
position: 'sticky',
top: 0,
top: 65,
alignSelf: 'flex-start',
maxHeight: '100vh',
maxHeight: 'calc(100vh - 65px)',
overflowY: 'auto',
}}
>
+3
View File
@@ -3,6 +3,9 @@ import rehypePrettyCode from 'rehype-pretty-code';
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
basePath: process.env.NEXT_PUBLIC_BASE_PATH || '',
images: { unoptimized: true },
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
transpilePackages: ['@newspaperui/components', '@newspaperui/theme', '@newspaperui/utils'],
};