Files
hyperframes/skills/hyperframes-creative/frame-presets/editorial-forest/frame-showcase.html
T
WaterrrForeverandClaude Opus 4.8 d0f0ec29e7 feat(skills): frame-preset library + shared audio engine (foundation) (#1632)
* feat(hyperframes-creative): add frame-preset library

Add a library of ready-made visual frame presets (claude, biennale-yellow,
blockframe, blue-professional, bold-poster, broadside, capsule, cartesian,
cobalt-grid, coral, creative-mode, daisy-days, editorial-forest, …), each with
a FRAME.md spec, a frame-showcase.html, and a per-preset caption-skin.html.
Registered in the creative design-spec so workflows can remix a preset onto
brand tokens.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(hyperframes-media): shared TTS/BGM/SFX audio engine

Add a shared audio engine under hyperframes-media (scripts/audio.mjs + lib/
tts.mjs, bgm.mjs, sfx.mjs, heygen.mjs) plus a bundled SFX pack and manifest.
Workflows resolve this engine by path (../../hyperframes-media/scripts/
audio.mjs) for text-to-speech, background music, and sound effects, so audio
is authored once and reused across skills instead of duplicated per workflow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(skills): gate render on user review; refresh router, core, general-video

- hyperframes-cli: render is now user-gated — preview opens Studio (the timeline
  editor where the user can hand-edit anything, not just watch); never
  auto-render once checks pass, pause at preview and render only after approval.
- hyperframes (router): tighten the entry SKILL.md description + routing.
- hyperframes-core: rewrite SKILL.md and add script-format.md + storyboard-format.md
  references for the script-driven authoring architecture.
- general-video: tidy the fallback-workflow description and routing table.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* style(hyperframes-creative): reformat frame-preset showcase HTML

Run the HTML formatter over the frame-showcase.html files (indentation,
self-closing void tags, one CSS declaration per line). Formatting only — no
content or markup changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(hyperframes-media): correct wait-bgm field mapping and guard credential parse

Two correctness fixes from review (#1632):

- wait-bgm.mjs read audioMeta.bgm_path / audioMeta.bgm_enabled, but audio.mjs
  writes the path nested as bgm.path and the flag as bgm_pending. The detached
  generate path (Lyria/MusicGen) therefore always saw an empty path and exited
  status: disabled, silently dropping the music track even while generation was
  running. Read audioMeta.bgm?.path and gate on bgm_pending.
- heygenCredential() had an unguarded JSON.parse despite documenting that it
  never throws — a malformed ~/.heygen credentials file crashed the engine at
  startup instead of degrading to no-credential. Wrap the parse and return null.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(hyperframes): add router tag to entry skill metadata

Fold the router metadata tag into the foundation rewrite of the entry SKILL.md.
This file is owned by this PR (the full router rewrite); keeping the tag tweak
here — instead of a separate edit on the pre-rewrite version in another PR —
avoids a guaranteed merge conflict between the two.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 22:49:10 +08:00

1274 lines
36 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Editorial Forest</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=Source+Serif+4:opsz,wght@8..60,400;8..60,500;8..60,600&family=JetBrains+Mono:wght@400;500&display=swap"
rel="stylesheet"
/>
<style id="ds-tokens">
:root {
--green: #2e4a2a;
--green-deep: #243a21;
--green-lite: #3a5a36;
--pink: #e89cb1;
--pink-deep: #d27e96;
--cream: #efe7d4;
--cream-2: #e6dcc4;
--ink: #1a1a17;
--serif: "Source Serif 4", "Source Serif Pro", Georgia, serif;
--mono: "JetBrains Mono", ui-monospace, monospace;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
background: #14140f;
}
body {
background: var(--cream);
color: var(--ink);
font-family: var(--serif);
-webkit-font-smoothing: antialiased;
}
.serif {
font-family: var(--serif);
font-weight: 500;
letter-spacing: -0.02em;
line-height: 0.96;
}
.mono {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.16em;
}
section {
padding: 110px 120px;
position: relative;
}
.topbar {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid var(--green);
padding-bottom: 18px;
margin-bottom: 56px;
}
.topbar .lbl {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.18em;
font-size: 15px;
color: var(--green);
}
.topbar h2 {
font-family: var(--serif);
font-weight: 500;
font-size: 48px;
letter-spacing: -0.02em;
line-height: 1;
}
/* COVER */
.cover {
min-height: 100vh;
background: var(--green);
color: var(--cream);
padding: 100px 140px;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.cover .top {
position: absolute;
top: 64px;
left: 140px;
right: 140px;
display: flex;
justify-content: space-between;
align-items: center;
}
.cover .top .lbl {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.18em;
font-size: 15px;
color: var(--pink);
}
.cover .mono-circle {
width: 120px;
height: 120px;
border-radius: 50%;
border: 2px solid var(--pink);
display: grid;
place-items: center;
font-family: var(--mono);
font-weight: 500;
letter-spacing: 0.1em;
font-size: 24px;
color: var(--pink);
}
.cover h1 {
font-family: var(--serif);
font-weight: 500;
font-size: clamp(96px, 15vw, 210px);
line-height: 0.92;
letter-spacing: -0.02em;
color: var(--pink);
}
.cover h1 .cr {
color: var(--cream);
}
.cover .lede {
font-family: var(--serif);
font-weight: 400;
font-size: 28px;
line-height: 1.4;
color: var(--cream);
max-width: 760px;
margin-top: 36px;
}
.cover .footline {
position: absolute;
bottom: 64px;
left: 140px;
right: 140px;
display: flex;
justify-content: space-between;
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.14em;
font-size: 14px;
color: var(--pink);
}
/* PALETTE */
.swatches {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0;
border: 2px solid var(--green);
}
.sw {
border-right: 2px solid var(--green);
border-bottom: 2px solid var(--green);
}
.sw:nth-child(4n) {
border-right: 0;
}
.sw:nth-child(n + 5) {
border-bottom: 0;
}
.sw .chip {
height: 130px;
border-bottom: 2px solid var(--green);
}
.sw .meta {
padding: 18px 20px;
background: var(--cream);
}
.sw .name {
font-family: var(--serif);
font-weight: 500;
font-size: 24px;
}
.sw .hex {
font-family: var(--mono);
font-size: 12px;
letter-spacing: 0.04em;
color: var(--ink);
opacity: 0.65;
margin-top: 6px;
}
.sw .role {
font-family: var(--serif);
font-weight: 400;
font-size: 14px;
line-height: 1.4;
color: var(--ink);
margin-top: 10px;
}
/* TYPE */
.type-row {
display: grid;
grid-template-columns: 240px 1fr;
align-items: center;
padding: 26px 0;
border-bottom: 2px solid rgba(46, 74, 42, 0.25);
}
.type-row .tok {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.14em;
font-size: 13px;
color: var(--green);
}
.type-row .m {
font-family: var(--mono);
font-size: 11px;
color: var(--ink);
opacity: 0.6;
margin-top: 8px;
line-height: 1.5;
letter-spacing: 0.02em;
}
.type-row .spec {
overflow: hidden;
}
/* COMPONENTS */
.cnote {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: 12px;
color: var(--green);
margin-bottom: 22px;
}
.cgrid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 28px;
margin-bottom: 52px;
}
.s3 {
grid-column: span 3;
}
.s4 {
grid-column: span 4;
}
.s5 {
grid-column: span 5;
}
.s6 {
grid-column: span 6;
}
.s7 {
grid-column: span 7;
}
.s8 {
grid-column: span 8;
}
.tile {
border-radius: 6px;
padding: 34px 32px;
min-height: 240px;
display: flex;
flex-direction: column;
}
.tile .ord {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.12em;
font-size: 14px;
}
.tile .ti {
font-family: var(--serif);
font-weight: 500;
font-size: 40px;
line-height: 0.98;
letter-spacing: -0.01em;
margin-top: auto;
}
.tile .ft {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.12em;
font-size: 12px;
margin-top: 14px;
}
.tile.green {
background: var(--green);
color: var(--cream);
}
.tile.green .ord,
.tile.green .ft {
color: var(--pink);
}
.tile.pink {
background: var(--pink);
color: var(--green-deep);
}
.tile.pink .ord,
.tile.pink .ft {
color: var(--green-deep);
}
.tile.lite {
background: var(--green-lite);
color: var(--pink);
}
.tile.lite .ti {
color: var(--cream);
}
.tile.cream2 {
background: var(--cream-2);
border: 2px solid var(--green);
color: var(--green);
}
.tile.cream2 .ord,
.tile.cream2 .ft {
color: var(--green);
}
.kpi {
border-top: 2px solid var(--green);
padding-top: 22px;
}
.kpi .tag {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.14em;
font-size: 13px;
color: var(--green);
}
.kpi .fig {
font-family: var(--serif);
font-weight: 500;
font-size: 128px;
line-height: 0.92;
letter-spacing: -0.03em;
color: var(--ink);
}
.kpi .fig .u {
font-size: 64px;
}
.kpi .d {
font-family: var(--serif);
font-weight: 400;
font-size: 18px;
line-height: 1.35;
color: var(--ink);
margin-top: 10px;
max-width: 280px;
}
.monobig {
width: 130px;
height: 130px;
border-radius: 50%;
border: 2px solid var(--pink);
display: grid;
place-items: center;
font-family: var(--mono);
font-weight: 500;
letter-spacing: 0.1em;
font-size: 26px;
color: var(--green);
}
.bars {
display: flex;
align-items: flex-end;
gap: 24px;
height: 200px;
border-bottom: 2px solid var(--green);
border-left: 2px solid var(--green);
padding: 0 8px;
}
.bars .bar {
width: 56px;
border-radius: 3px 3px 0 0;
position: relative;
}
.bars .bar .v {
position: absolute;
top: -30px;
left: 50%;
transform: translateX(-50%);
font-family: var(--mono);
font-weight: 500;
font-size: 14px;
color: var(--ink);
}
/* COMPOSITIONS */
.gallery {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
}
.fw .flabel {
display: flex;
gap: 14px;
align-items: baseline;
margin-bottom: 16px;
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.14em;
font-size: 12px;
color: var(--ink);
opacity: 0.55;
}
.fw .flabel b {
color: var(--green);
opacity: 1;
}
.frame {
aspect-ratio: 16/9;
container-type: size;
position: relative;
overflow: hidden;
background: var(--cream);
box-shadow: 0 0 0 1px rgba(46, 74, 42, 0.2);
}
.frame > .body {
position: absolute;
inset: 0;
z-index: 3;
}
.frame .tb {
position: absolute;
left: 5cqw;
right: 5cqw;
top: 3cqw;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 4;
}
.frame .tb .l {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: 0.95cqw;
}
.frame .fl {
position: absolute;
left: 5cqw;
right: 5cqw;
bottom: 2.8cqw;
display: flex;
justify-content: space-between;
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.14em;
font-size: 0.85cqw;
z-index: 4;
}
/* f1 cover green */
.ef1 {
background: var(--green);
}
.ef1 .tb .l {
color: var(--pink);
}
.ef1 .mc {
width: 7cqw;
height: 7cqw;
border-radius: 50%;
border: 0.13cqw solid var(--pink);
display: grid;
place-items: center;
font-family: var(--mono);
font-weight: 500;
letter-spacing: 0.1em;
font-size: 1.3cqw;
color: var(--pink);
}
.ef1 .body {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 5cqw;
}
.ef1 h3 {
font-family: var(--serif);
font-weight: 500;
font-size: 13cqw;
line-height: 0.9;
letter-spacing: -0.02em;
color: var(--pink);
}
.ef1 h3 .cr {
color: var(--cream);
}
.ef1 .fl .l {
color: var(--pink);
}
/* f2 topic tiles */
.ef2 .body {
padding: 7cqw 5cqw 6cqw;
display: flex;
flex-direction: column;
}
.ef2 h3 {
font-family: var(--serif);
font-weight: 500;
font-size: 5cqw;
line-height: 0.96;
letter-spacing: -0.02em;
color: var(--green);
margin-bottom: 2.4cqw;
}
.ef2 .row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5cqw;
flex: 1;
}
.ef2 .t {
border-radius: 0.6cqw;
padding: 1.8cqw;
display: flex;
flex-direction: column;
}
.ef2 .t .o {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.12em;
font-size: 0.85cqw;
}
.ef2 .t .ti {
font-family: var(--serif);
font-weight: 500;
font-size: 2.6cqw;
line-height: 0.98;
letter-spacing: -0.01em;
margin-top: auto;
}
.ef2 .green {
background: var(--green);
color: var(--cream);
}
.ef2 .green .o {
color: var(--pink);
}
.ef2 .pink {
background: var(--pink);
color: var(--green-deep);
}
.ef2 .pink .o {
color: var(--green-deep);
}
.ef2 .cream2 {
background: var(--cream-2);
border: 0.13cqw solid var(--green);
color: var(--green);
}
.ef2 .cream2 .o {
color: var(--green);
}
/* f3 KPI green */
.ef3 {
background: var(--green);
}
.ef3 .tb .l {
color: var(--pink);
}
.ef3 .body {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 5cqw;
}
.ef3 .tag {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: 1cqw;
color: var(--pink);
border-top: 0.12cqw solid var(--pink);
padding-top: 1.2cqw;
display: inline-block;
}
.ef3 .fig {
font-family: var(--serif);
font-weight: 500;
font-size: 18cqw;
line-height: 0.9;
letter-spacing: -0.03em;
color: var(--pink);
}
.ef3 .fig .u {
font-size: 9cqw;
}
.ef3 .d {
font-family: var(--serif);
font-weight: 400;
font-size: 1.7cqw;
line-height: 1.35;
color: var(--cream);
max-width: 40cqw;
margin-top: 1cqw;
}
.ef3 .fl .l {
color: var(--pink);
}
/* f4 statement quote */
.ef4 .body {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 8cqw;
}
.ef4 h3 {
font-family: var(--serif);
font-weight: 500;
font-size: 6.4cqw;
line-height: 1.02;
letter-spacing: -0.02em;
color: var(--green);
}
.ef4 .at {
font-family: var(--serif);
font-weight: 600;
font-size: 1.9cqw;
color: var(--ink);
margin-top: 2cqw;
}
.ef4 .ro {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: 0.95cqw;
color: var(--green);
margin-top: 0.5cqw;
}
/* PRINCIPLES */
.dos {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
}
.do-card h4 {
font-family: var(--serif);
font-weight: 500;
font-size: 34px;
color: var(--green);
margin-bottom: 6px;
letter-spacing: -0.02em;
}
.do-card .rule {
height: 2px;
background: var(--green);
margin-bottom: 22px;
}
.do-card ul {
list-style: none;
}
.do-card li {
font-family: var(--serif);
font-weight: 400;
font-size: 17px;
line-height: 1.5;
padding-left: 24px;
position: relative;
margin-bottom: 13px;
}
.do-card li::before {
position: absolute;
left: 0;
font-family: var(--mono);
}
.do-card.do li::before {
content: "+";
color: var(--green);
}
.do-card.dont li::before {
content: "\00d7";
color: var(--pink-deep);
}
.foot {
padding: 60px 120px;
border-top: 2px solid var(--green);
display: flex;
justify-content: space-between;
align-items: center;
}
.foot .l {
font-family: var(--serif);
font-weight: 500;
font-size: 30px;
color: var(--green);
}
.foot .r {
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: 11px;
color: var(--ink);
opacity: 0.55;
}
@media (max-width: 1100px) {
.gallery {
grid-template-columns: 1fr;
}
.swatches {
grid-template-columns: 1fr 1fr;
}
}
</style>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Source+Serif+4:opsz,wght@8..60,400;8..60,500;8..60,600&display=swap"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap"
/>
<style id="ft-override">
:root {
--primary: #efe7d4 !important;
--secondary: #2e4a2a !important;
--tertiary: #e6dcc4 !important;
--accent: #e89cb1 !important;
--f-disp: "Source Serif 4", sans-serif !important;
--f-body: "JetBrains Mono", sans-serif !important;
--green: #2e4a2a !important;
--pink: #e89cb1 !important;
--cream: #efe7d4 !important;
--cream-2: #e6dcc4 !important;
--serif: "Source Serif 4", sans-serif !important;
--mono: "JetBrains Mono", sans-serif !important;
--green-deep: #243a21 !important;
--green-lite: #3a5a36 !important;
--pink-deep: #d27e96 !important;
--ink: #1a1a17 !important;
}
</style>
</head>
<body>
<!-- COVER -->
<section class="cover">
<div class="top">
<span class="lbl">Frame System · Vol. 01</span>
<div class="mono-circle">EF</div>
</div>
<h1>Paper,<br />ink &amp; <span class="cr">leaf.</span></h1>
<div class="lede">
A serif-led editorial frame system — Source Serif 4 at weight 500, a forest-green /
dusty-rose / oat-cream triad, and JetBrains Mono as the editorial chrome.
</div>
<div class="footline">
<span>Source Serif 4 · JetBrains Mono</span><span>1920 × 1080</span>
</div>
</section>
<!-- PALETTE -->
<section>
<div class="topbar">
<span class="lbl">01 — Palette</span>
<h2>Three Surfaces</h2>
</div>
<div class="swatches">
<div class="sw">
<div class="chip" style="background: var(--green)"></div>
<div class="meta">
<div class="name">Green</div>
<div class="hex">#2e4a2a</div>
<div class="role">Forest primary — surface, fill, rule.</div>
</div>
</div>
<div class="sw">
<div class="chip" style="background: var(--pink)"></div>
<div class="meta">
<div class="name">Pink</div>
<div class="hex">#e89cb1</div>
<div class="role">Dusty rose — the accent + on-green text.</div>
</div>
</div>
<div class="sw">
<div class="chip" style="background: var(--cream)"></div>
<div class="meta">
<div class="name">Cream</div>
<div class="hex">#efe7d4</div>
<div class="role">Oat paper — the default ground.</div>
</div>
</div>
<div class="sw">
<div class="chip" style="background: var(--ink)"></div>
<div class="meta">
<div class="name">Ink</div>
<div class="hex">#1a1a17</div>
<div class="role">Warm near-black body on cream.</div>
</div>
</div>
<div class="sw">
<div class="chip" style="background: var(--green-deep)"></div>
<div class="meta">
<div class="name">Green Deep</div>
<div class="hex">#243a21</div>
<div class="role">Text on pink surfaces.</div>
</div>
</div>
<div class="sw">
<div class="chip" style="background: var(--green-lite)"></div>
<div class="meta">
<div class="name">Green Lite</div>
<div class="hex">#3a5a36</div>
<div class="role">Second green for tile pairs.</div>
</div>
</div>
<div class="sw">
<div class="chip" style="background: var(--pink-deep)"></div>
<div class="meta">
<div class="name">Pink Deep</div>
<div class="hex">#d27e96</div>
<div class="role">Pink-on-pink borders.</div>
</div>
</div>
<div class="sw">
<div class="chip" style="background: var(--cream-2)"></div>
<div class="meta">
<div class="name">Cream 2</div>
<div class="hex">#e6dcc4</div>
<div class="role">Tiles on the cream ground.</div>
</div>
</div>
</div>
</section>
<!-- TYPOGRAPHY -->
<section>
<div class="topbar">
<span class="lbl">02 — Typography</span>
<h2>Serif 500 · Mono Chrome</h2>
</div>
<div class="type-row">
<div>
<div class="tok">display-hero</div>
<div class="m">Source Serif 4 · 500 · 220px · 0.02em · opsz</div>
</div>
<div class="spec">
<span class="serif" style="font-size: 120px; line-height: 0.92">Quarterly</span>
</div>
</div>
<div class="type-row">
<div>
<div class="tok">headline-xl</div>
<div class="m">Source Serif 4 · 500 · 96px</div>
</div>
<div class="spec"><span class="serif" style="font-size: 76px">A Quiet Annual</span></div>
</div>
<div class="type-row">
<div>
<div class="tok">stat-figure</div>
<div class="m">Source Serif 4 · 500 · 220px · 0.03em</div>
</div>
<div class="spec">
<span class="serif" style="font-size: 108px; color: var(--green)"
>94<span style="font-size: 54px">%</span></span
>
</div>
</div>
<div class="type-row">
<div>
<div class="tok">body</div>
<div class="m">Source Serif 4 · 400 · line 1.38</div>
</div>
<div class="spec">
<p
style="
font-family: var(--serif);
font-weight: 400;
font-size: 24px;
line-height: 1.38;
max-width: 680px;
"
>
Body runs the serif at weight 400 — the drop from 500 display to 400 body is the
system's reading rhythm.
</p>
</div>
</div>
<div class="type-row" style="border-bottom: 0">
<div>
<div class="tok">label</div>
<div class="m">JetBrains Mono · 500 · uppercase · 0.18em</div>
</div>
<div class="spec">
<span class="mono" style="font-size: 16px; color: var(--green)"
>Editorial Chrome · Section</span
>
</div>
</div>
</section>
<!-- COMPONENTS -->
<section>
<div class="topbar">
<span class="lbl">03 — Components</span>
<h2>Flat · Paper-Based</h2>
</div>
<div class="cgrid">
<div class="s8">
<div class="cnote">Topic tiles — fills rotate green / pink / green-lite / cream-2</div>
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px">
<div class="tile green">
<span class="ord">01</span>
<div class="ti">Paper</div>
<span class="ft">Ground</span>
</div>
<div class="tile pink">
<span class="ord">02</span>
<div class="ti">Ink</div>
<span class="ft">Type</span>
</div>
<div class="tile lite">
<span class="ord">03</span>
<div class="ti">Leaf</div>
<span class="ft">Surface</span>
</div>
<div class="tile cream2">
<span class="ord">04</span>
<div class="ti">Rose</div>
<span class="ft">Accent</span>
</div>
</div>
</div>
<div class="s4">
<div class="cnote">Monogram circle + KPI</div>
<div class="monobig">EF</div>
<div class="kpi" style="margin-top: 28px">
<div class="tag">Retention</div>
<div class="fig">94<span class="u">%</span></div>
<div class="d">Net revenue, trailing twelve months.</div>
</div>
</div>
</div>
<div class="cgrid" style="margin-bottom: 0">
<div class="s6">
<div class="cnote">Bar chart — pink / cream / green, mono ticks</div>
<div class="bars">
<div class="bar" style="height: 55%; background: var(--pink)">
<span class="v">55</span>
</div>
<div class="bar" style="height: 72%; background: var(--cream-2)">
<span class="v">72</span>
</div>
<div class="bar" style="height: 90%; background: var(--green)">
<span class="v">90</span>
</div>
<div class="bar" style="height: 64%; background: var(--pink)">
<span class="v">64</span>
</div>
</div>
</div>
<div class="s6">
<div class="cnote">Meta definition list — 2px green top rule</div>
<div
style="
border-top: 2px solid var(--green);
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 36px;
padding-top: 20px;
"
>
<div>
<div class="mono" style="font-size: 13px; color: var(--green)">Editor</div>
<div class="serif" style="font-weight: 500; font-size: 30px; margin-top: 8px">
A. Wren
</div>
</div>
<div>
<div class="mono" style="font-size: 13px; color: var(--green)">Issue</div>
<div class="serif" style="font-weight: 500; font-size: 30px; margin-top: 8px">
No. 12
</div>
</div>
<div>
<div class="mono" style="font-size: 13px; color: var(--green)">Season</div>
<div class="serif" style="font-weight: 500; font-size: 30px; margin-top: 8px">
Spring
</div>
</div>
</div>
</div>
</div>
</section>
<!-- COMPOSITIONS -->
<section style="background: var(--cream-2)">
<div class="topbar">
<span class="lbl">04 — Frames</span>
<h2>Frame Compositions</h2>
</div>
<div class="gallery">
<div class="fw">
<div class="flabel">
<b>Cover</b><span>· identity · green · monogram · centered-left</span>
</div>
<div class="frame ef1">
<div class="tb">
<span class="l">Frame System · Vol. 01</span>
<div class="mc">EF</div>
</div>
<div class="body">
<h3>Paper, ink<br />&amp; <span class="cr">leaf.</span></h3>
</div>
<div class="fl">
<span class="l">Source Serif 4 · Mono</span><span class="l">01 / 06</span>
</div>
</div>
</div>
<div class="fw">
<div class="flabel">
<b>Topic Tiles</b><span>· catalog · rotating fills · the dense frame</span>
</div>
<div class="frame ef2">
<div class="tb">
<span class="l" style="color: var(--green)">Contents</span
><span class="l" style="color: var(--green)">02 / 06</span>
</div>
<div class="body">
<h3>Four Strands</h3>
<div class="row">
<div class="t green">
<span class="o">01</span>
<div class="ti">On Paper</div>
</div>
<div class="t pink">
<span class="o">02</span>
<div class="ti">On Ink</div>
</div>
<div class="t cream2">
<span class="o">03</span>
<div class="ti">On Measure</div>
</div>
</div>
</div>
</div>
</div>
<div class="fw">
<div class="flabel"><b>KPI Stat</b><span>· data · green · oversized figure</span></div>
<div class="frame ef3">
<div class="tb">
<span class="l">By The Numbers</span><span class="l">03 / 06</span>
</div>
<div class="body">
<span class="tag">Retention</span>
<div class="fig">94<span class="u">%</span></div>
<div class="d">
Net revenue retention across the year — the figure carries the frame.
</div>
</div>
<div class="fl"><span class="l">Annual Report</span><span class="l">03 / 06</span></div>
</div>
</div>
<div class="fw">
<div class="flabel"><b>Statement</b><span>· quote · cream · centered-left</span></div>
<div class="frame ef4">
<div class="tb">
<span class="l" style="color: var(--green)">In Their Words</span
><span class="l" style="color: var(--green)">04 / 06</span>
</div>
<div class="body">
<h3>Set it slowly,<br />and let it breathe.</h3>
<div class="at">Avery Wren</div>
<div class="ro">Editor-in-Chief</div>
</div>
</div>
</div>
</div>
</section>
<!-- PRINCIPLES -->
<section>
<div class="topbar">
<span class="lbl">05 — Rules</span>
<h2>Frame Rules</h2>
</div>
<div class="dos">
<div class="do-card do">
<h4>Do</h4>
<div class="rule"></div>
<ul>
<li>
Run every display in Source Serif 4 weight 500, negative-tracked, tight line-height.
</li>
<li>Set every label/caption in JetBrains Mono 500 uppercase, 0.140.18em.</li>
<li>Give every frame a topbar (mono label + monogram or counter).</li>
<li>Pick one dominant surface per frame; rotate tile fills, don't repeat one.</li>
<li>Separate sections with 2px hairlines in the region's accent.</li>
</ul>
</div>
<div class="do-card dont">
<h4>Don't</h4>
<div class="rule"></div>
<ul>
<li>No drop shadows, gradients, or glows — flat, paper-based depth only.</li>
<li>No third typeface; no italic or underline; no serif body at 500.</li>
<li>No fourth color family; no 1px or 4px rules (2px / 2.5px only).</li>
<li>No two competing content blocks — one subject per frame.</li>
<li>Don't blow a headline edge-to-edge — fit to measure.</li>
</ul>
</div>
</div>
</section>
<!-- CAPTIONS — preview of caption-skin.html (the preset's lower-third karaoke look) -->
<style>
/* mirrors caption-skin.html; the skin's --cap-* vocab mapped to this preset's tokens */
.capdemo {
--cap-ink: var(--ink);
--cap-canvas: var(--cream);
--cap-accent: var(--pink-deep);
--cap-accent-2: var(--pink);
}
.capdemo .stage {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 16.67cqh;
display: flex;
align-items: center;
justify-content: center;
z-index: 4;
}
.capdemo .pill {
max-width: 80cqw;
padding: 1.4cqw 3cqw 1.7cqw;
background: var(--cap-canvas);
border: 0.21cqw solid var(--cap-accent);
border-radius: 0.6cqw;
}
.capdemo .line {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.1em 0.34em;
font-family: var(--serif);
font-weight: 500;
font-size: 3.4cqw;
line-height: 1.16;
letter-spacing: -0.02em;
}
.capdemo .w {
display: inline-block;
padding: 0 0.06em;
color: color-mix(in srgb, var(--cap-ink) 42%, var(--cap-canvas));
}
.capdemo .w.spoken {
color: var(--cap-ink);
}
.capdemo .w.active {
color: var(--cap-ink);
background: var(--cap-accent);
box-shadow: 0 0 0 0.05em var(--cap-accent);
border-radius: 0.6cqw;
}
.capdemo .bandline {
position: absolute;
left: 0;
right: 0;
bottom: 16.67cqh;
border-top: 2px dashed rgba(46, 74, 42, 0.32);
z-index: 3;
}
.capdemo .bandtag {
position: absolute;
right: 5cqw;
bottom: calc(16.67cqh + 0.7cqw);
font-family: var(--mono);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.12em;
font-size: 0.85cqw;
color: var(--green);
opacity: 0.6;
z-index: 4;
}
</style>
<section style="background: var(--cream-2)">
<div class="topbar">
<span class="lbl">06 — Captions</span>
<h2>Lower-Third Karaoke</h2>
</div>
<div class="gallery">
<div class="fw">
<div class="flabel"><b>Active line</b><span>· spoken · current · upcoming</span></div>
<div class="frame capdemo">
<div class="tb">
<span class="l" style="color: var(--green)">Captions</span
><span class="l" style="color: var(--green)">05 / 06</span>
</div>
<div class="bandline"></div>
<div class="bandtag">caption band · 16.7%</div>
<div class="stage">
<div class="pill">
<div class="line">
<span class="w spoken">Built</span>
<span class="w spoken">for</span>
<span class="w active">teams</span>
<span class="w">who</span>
<span class="w">ship.</span>
</div>
</div>
</div>
</div>
</div>
<div class="fw">
<div class="flabel"><b>Settled line</b><span>· all spoken · panel cleared</span></div>
<div class="frame capdemo">
<div class="tb">
<span class="l" style="color: var(--green)">Captions</span
><span class="l" style="color: var(--green)">06 / 06</span>
</div>
<div class="stage">
<div class="pill">
<div class="line">
<span class="w spoken">Ship</span>
<span class="w spoken">faster</span>
<span class="w spoken">today.</span>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<div class="foot">
<span class="l">Editorial Forest</span>
<span class="r">Frame Showcase · Atoms Sacred · Composition Free</span>
</div>
<template id="__bundler_thumbnail">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100" fill="#2e4a2a" />
<text x="12" y="46" font-family="Georgia" font-weight="500" font-size="30" fill="#e89cb1">
Aa
</text>
<circle cx="80" cy="26" r="13" fill="none" stroke="#e89cb1" stroke-width="2" />
<rect x="12" y="60" width="60" height="2" fill="#e89cb1" />
</svg>
</template>
</body>
</html>