<Press theme> + press/<slug>/theme/
テーマ (Themes)
OpenPress themes には二つの層があります:typed theme object は Press metadata と CSS variables を提供し、Press-local theme directory は active CSS と font loading を持ちます。
OpenPress の theme には二つの層があります。
Typed theme object は press/<slug>/press.tsx に置き、<Press theme={...}> に渡します。Engine はこれを使って Press profile(document、slide、bare)を知り、measurement と runtime に --op-theme-* CSS variables を注入します。
Folder-local theme directory、press/<slug>/theme/、は active CSS source のままです。Font loading、prose rules、slide template classes、project-specific selectors をここに置きます。Generic page shell、measurement CSS、print reset、default MDX prose surface は framework が所有します。
なぜ theme は Press ごとに置くのか?
ひとつの workspace に A4 report と 16:9 slide deck が同居することがあります。これらの形式が意図せずグローバルな視覚状態を共有してはいけません。Theme object と theme directory を owning Press に置くことで、それぞれの output に明確な styling boundary を与えます。
Theme object は次の用途に使います:
- Profile selection: page-based document には
defineDocumentTheme()、slide deck にはdefineSlideTheme()。 - Portable color、font、typography tokens。
- Workbench と reader の theme metadata。
- Pagination measurement が必要とする CSS variables。
Theme files は次の用途に使います:
tokens.css: 色、書体、余白、artifact-level design decisions の CSS variables。fonts.css: portable な@font-faceloading。--op-theme-*variables を読む prose / slide-template selectors。
Theme ファイルで page shell を再実装しないでください。新しい work では base/page-contract.css、base/print.css、base/typography.css を含めません。これらの契約は framework-owned です。
Basic workflow
Page-based document:
import { Press } from "@open-press/core";
import { defineDocumentTheme } from "@open-press/core/theme";
const documentTheme = defineDocumentTheme({
name: "Report Theme",
colors: {
paper: "#ffffff",
ink: "#16161d",
accent: "#0d5f89",
},
typography: {
heading: { font: "serif", size: "28pt", lineHeight: 1.18, color: "ink" },
body: { font: "body", size: "10.5pt", lineHeight: 1.7, color: "ink" },
},
});
export default function ReportPress() {
return <Press slug="report" title="Report" page="a4" theme={documentTheme}>{/* pages */}</Press>;
}
Slide deck:
import { Press, Slide } from "@open-press/core";
import { defineSlideTheme } from "@open-press/core/theme";
const slideTheme = defineSlideTheme({
name: "Deck Theme",
colors: {
bg: "#fcf7e9",
ink: "#16161d",
accent: "#d42a20",
},
typography: {
display: { font: "serif", size: 138, lineHeight: 1.05, color: "ink" },
body: { font: "sans", size: 36, lineHeight: 1.48, color: "muted" },
},
});
export default function DeckPress() {
return (
<Press slug="deck" title="Deck" type="slides" page="slide-16-9" theme={slideTheme}>
<Slide id="cover" />
</Press>
);
}
Profile must match the Press type. Slide Press uses defineSlideTheme(). Page-based Press uses defineDocumentTheme().
Page geometry
ページサイズは CSS ではなく <Press page> に置きます。generic format には built-in preset を使います:
<Press page="a4" />
<Press page="slide-16-9" />
プロジェクト固有の format には custom object を使います:
<Press
page={{ id: "field-guide-card", label: "Field Guide Card", width: "148mm", height: "210mm" }}
/>
Exporter は resolved geometry を document theme metadata に書き込み、--openpress-page-width や --openpress-page-height などの runtime CSS variables を注入します。Theme object は typography と color を定義できますが、<Press page> を置き換えません。
Tailwind v4 and prose
新しい UI は Tailwind-first です。Page chrome、cover、TOC、slide layout、prose variants は React components に置き、Tailwind classes で表現します。MDX body content は framework の prose surface を使い、component classes または prose preset で調整します。shared typography CSS に戻さないでください。
複数の Press が Tailwind token name を共有する場合、Tailwind v4 @theme entries は generic または variable-backed にします。Artifact-specific values は owning Press wrapper または component に置き、ある Press が別の Press を汚染しないようにします。