Skip to content

Layout pattern · Inset panel · Rounded frame · Product · Calm

Framed page

The whole page sits in one rounded panel on a tinted ground, with the footer outside the frame.

Download .md

Rendered from the same HTML and CSS as the code below. Scroll inside the stage to see the whole page.1280 px

Anatomy. Every region, numbered.

Instead of letting content run to the screen edges, the page is a single rounded panel set into a slightly darker ground. The frame gives the site the feel of a native app window and makes every edge deliberate. Inside, sections are separated by space alone, and the only filled surfaces are nested panels with a smaller radius.

  1. 1. Ground

    A tinted page background, a few percent darker than the frame, with a 12px inset on every side. It is visible on all edges and below the page.

  2. 2. Frame

    The whole page lives in one rounded panel with a 1px border and a 16px radius. Nav, sections and panels sit inside it.

  3. 3. Nav bar

    The nav is the frame's top bar. It uses the same wrapper as the sections, so the logo aligns with the headline.

  4. 4. Inset panel

    Wells, stat strips and the closing call to action are nested panels with a 12px radius on a slightly tinted fill. They are the only filled surfaces.

  5. 5. Footer strip

    The footer sits on the ground, outside the frame, so the frame reads as a finished object.

Rules. The numbers to copy.

Container
Tinted ground with a 12px inset, one rounded frame inside
Max width
1040px content inside the frame
Columns
3 equal columns for items, 1 column for hero and quote
Gutter
32px between items
Rules
1px solid frame border at 16% ink, 1px hairline under the nav only
Section padding
64px top and bottom, 48px below 800px
Breakpoints
Below 800px the inset shrinks to 6px, radii step down and every grid becomes one column
Sticky behavior
None. The nav may be sticky inside the frame
Accessibility
The frame is a plain div. Landmarks (header, main, footer) are unchanged, and the footer outside the frame stays in reading order

When to use it. And when to skip it.

Use it when

  • Product marketing that should feel like a native app window.
  • Sites with a calm tone, few rules and generous whitespace.
  • Pages that mix a tinted ground with one clean white surface.
  • Launch pages and waitlists where the page is short and every edge shows.

Avoid it when

  • Content-heavy pages, because the inset steals width on small screens.
  • Full-bleed imagery or video heroes, which want to reach the edges.
  • Sites that already have a strong background pattern, since the ground would compete with it.

Code. The exact markup in the stage.

pattern.html
1<!-- data-region and data-dim only drive the Blueprint view. Remove them in production. -->
2<div class="ground" data-region="Ground" data-n="1" data-at="ir">
3 <div class="frame" data-region="Frame" data-n="2" data-at="in">
4 <header class="bar" data-region="Nav bar" data-n="3" data-at="bl">
5 <div class="wrap">
6 <nav class="nav" aria-label="Primary">
7 <a class="brand" href="#"><span class="mark"></span>Meridian</a>
8 <ul class="links">
9 <li><a href="#">Product</a></li>
10 <li><a href="#">Pricing</a></li>
11 <li><a href="#">Docs</a></li>
12 <li><a href="#">Changelog</a></li>
13 </ul>
14 <div class="actions">
15 <a class="btn btn-ghost" href="#">Sign in</a>
16 <a class="btn btn-primary" href="#">Start free</a>
17 </div>
18 </nav>
19 </div>
20 </header>
21 <main>
22 <section class="sec" data-dim="64" data-dim-axis="pad">
23 <div class="wrap" data-dim="max 1040">
24 <p class="eyebrow">Release 2.4</p>
25 <h1>Ship changes your customers actually read</h1>
26 <p class="lead">Meridian turns merged pull requests into clear release notes, changelogs and update emails.</p>
27 <div class="actions">
28 <a class="btn btn-primary" href="#">Start free</a>
29 <a class="btn btn-ghost" href="#">Read the docs</a>
30 </div>
31 <div class="well" data-region="Inset panel" data-n="4" data-at="in" data-dim="radius 12" data-dim-axis="tag" data-dim-at="tr">
32 <figure class="mock" aria-label="Release notes preview">
33 <div class="mock-bar"><span>Release 2.4</span><span>Mar 12</span></div>
34 <ul>
35 <li><b class="new">New</b>Draft notes from merged pull requests</li>
36 <li><b>Improved</b>Changelog search across all releases</li>
37 <li><b>Fixed</b>Email previews on narrow screens</li>
38 </ul>
39 </figure>
40 </div>
41 </div>
42 </section>
43 <section class="sec" id="features">
44 <div class="wrap">
45 <div class="head">
46 <div>
47 <p class="eyebrow">01 Features</p>
48 <h2>Everything between merge and inbox</h2>
49 </div>
50 <p class="sub">Drafts group by product area, not by commit.</p>
51 </div>
52 <div class="cols">
53 <article class="feature">
54 <span class="n">01</span>
55 <h3>Draft from pull requests</h3>
56 <p>Group merged work by product area and get a first draft in seconds.</p>
57 </article>
58 <article class="feature">
59 <span class="n">02</span>
60 <h3>Edit in one place</h3>
61 <p>Rewrite, reorder and approve notes with your team before anything ships.</p>
62 </article>
63 <article class="feature">
64 <span class="n">03</span>
65 <h3>Publish everywhere</h3>
66 <p>Send the same note to your changelog, email list and in-app feed.</p>
67 </article>
68 </div>
69 </div>
70 </section>
71 <section class="sec" id="numbers">
72 <div class="wrap">
73 <div class="head">
74 <div>
75 <p class="eyebrow">02 Numbers</p>
76 <h2>Quiet, fast and always on</h2>
77 </div>
78 <p class="sub">Rolling twelve month medians across all workspaces.</p>
79 </div>
80 <div class="strip" data-region="Inset panel">
81 <div class="stat"><strong>2.4M</strong><span>Notes published</span></div>
82 <div class="stat"><strong>99.98%</strong><span>Uptime, last 12 months</span></div>
83 <div class="stat"><strong>140 ms</strong><span>Median render time</span></div>
84 </div>
85 </div>
86 </section>
87 <section class="sec" id="customers">
88 <div class="wrap">
89 <div class="head">
90 <div>
91 <p class="eyebrow">03 Customers</p>
92 <h2>In their words</h2>
93 </div>
94 <p class="sub">Halden, a 40 person team, publishes every week.</p>
95 </div>
96 <figure class="quote">
97 <blockquote>“Our changelog went from a Friday chore to the page customers open first.”</blockquote>
98 <figcaption><b>Sana Okafor</b> Head of Product, Halden</figcaption>
99 </figure>
100 </div>
101 </section>
102 <section class="sec" id="pricing">
103 <div class="wrap">
104 <div class="panel" data-region="Inset panel">
105 <div>
106 <p class="eyebrow">04 Pricing</p>
107 <h2>Free for small teams</h2>
108 <p class="sub">Up to five people and one changelog, no card needed.</p>
109 </div>
110 <div class="actions">
111 <a class="btn btn-primary" href="#">Start free</a>
112 </div>
113 </div>
114 </div>
115 </section>
116 </main>
117 </div>
118 <footer data-region="Footer strip" data-n="5" data-at="bl">
119 <div class="wrap">
120 <div class="foot">
121 <span>© 2026 Meridian</span>
122 <ul>
123 <li><a href="#">Privacy</a></li>
124 <li><a href="#">Terms</a></li>
125 <li><a href="#">Status</a></li>
126 </ul>
127 </div>
128 </div>
129 </footer>
130</div>

The stage renders this HTML and CSS inside the base skin. The data-region and data-dim attributes drive the Blueprint view and are safe to keep or strip. Replace the base variables with your own tokens.

The file. PATTERN.md for your agent.

PATTERN.md
1---
2name: "Framed page"
3description: "The whole page sits in one rounded panel on a tinted ground, with the footer outside the frame."
4type: pattern
5tags: ["Inset panel", "Rounded frame", "Product", "Calm"]
6container: "Tinted ground with a 12px inset, one rounded frame inside"
7max_width: "1040px content inside the frame"
8columns: "3 equal columns for items, 1 column for hero and quote"
9gutter: "32px between items"
10rules: "1px solid frame border at 16% ink, 1px hairline under the nav only"
11section_padding: "64px top and bottom, 48px below 800px"
12breakpoints: "Below 800px the inset shrinks to 6px, radii step down and every grid becomes one column"
13sticky: "None. The nav may be sticky inside the frame"
14---
15
16# Framed page
17
18The whole page sits in one rounded panel on a tinted ground, with the footer outside the frame.
19
20## AI build instructions
21
22> Read this section before writing any code. It describes page structure only.
23> Colors, type, radii and shadows come from the project's DESIGN.md, never from this file.
24
25### 1. Your role
26
27Build the page layout as **Framed page**. Use the HTML and CSS under Reference implementation as the
28structural source of truth. Keep the project's own copy, components and styling, and place them into the
29regions listed below. If the project has a DESIGN.md, map its tokens onto the base variables
30(`--paper`, `--paper-2`, `--ink`, `--ink-2`, `--ink-3`, `--line`, `--accent`) and leave the structure CSS unchanged.
31
32### 2. Structure contract
33
34| Token | Value |
35|-------|-------|
36| container | Tinted ground with a 12px inset, one rounded frame inside |
37| max width | 1040px content inside the frame |
38| columns | 3 equal columns for items, 1 column for hero and quote |
39| gutter | 32px between items |
40| rules | 1px solid frame border at 16% ink, 1px hairline under the nav only |
41| section padding | 64px top and bottom, 48px below 800px |
42| breakpoints | Below 800px the inset shrinks to 6px, radii step down and every grid becomes one column |
43| sticky | None. The nav may be sticky inside the frame |
44| accessibility | The frame is a plain div. Landmarks (header, main, footer) are unchanged, and the footer outside the frame stays in reading order |
45
46### 3. Regions
47
48The markup marks each region with `data-region`. These attributes only drive the Blueprint view on
49freedesignmd.com and can be removed in production.
50
511. **Ground.** A tinted page background, a few percent darker than the frame, with a 12px inset on every side. It is visible on all edges and below the page.
522. **Frame.** The whole page lives in one rounded panel with a 1px border and a 16px radius. Nav, sections and panels sit inside it.
533. **Nav bar.** The nav is the frame's top bar. It uses the same wrapper as the sections, so the logo aligns with the headline.
544. **Inset panel.** Wells, stat strips and the closing call to action are nested panels with a 12px radius on a slightly tinted fill. They are the only filled surfaces.
555. **Footer strip.** The footer sits on the ground, outside the frame, so the frame reads as a finished object.
56
57### 4. Rules
58
59- Wrap the entire page in one rounded frame with a 1px border. Never add a second frame.
60- Keep the ground inset at 12px and the frame radius at 16px. Nested panels use 12px.
61- Tint the ground from the ink color at about 6 percent. Do not use a hue or gradient.
62- Separate sections with space only. Fill nested panels, never whole sections.
63- Put the footer on the ground, below the frame.
64
65### 5. Hard constraints
66
67Never do any of the following without an explicit instruction from the user:
68
69- Change the structure tokens above, add a column, or add dividers the pattern does not define.
70- Replace the structure with cards, shadows or colored backgrounds to separate sections.
71- Use gradients, glows or emoji to decorate the layout.
72- Put page content inside a region that is meant for another kind of content.
73
74### 6. Before you finish, verify
75
76- [ ] Every region listed above exists and is in the same order as in the reference markup.
77- [ ] Container width, columns, gutter, rule weight and section padding match the contract.
78- [ ] The layout collapses as described at the stated breakpoints, with no horizontal scroll at 390px.
79- [ ] Sticky elements behave as stated and never cover focused content.
80- [ ] Colors, type and radii were taken from DESIGN.md, not invented.
81
82---
83
84## Overview
85
86Instead of letting content run to the screen edges, the page is a single rounded panel set into a slightly darker ground. The frame gives the site the feel of a native app window and makes every edge deliberate. Inside, sections are separated by space alone, and the only filled surfaces are nested panels with a smaller radius.
87
88## When to use it
89
90- Product marketing that should feel like a native app window.
91- Sites with a calm tone, few rules and generous whitespace.
92- Pages that mix a tinted ground with one clean white surface.
93- Launch pages and waitlists where the page is short and every edge shows.
94
95## When to avoid it
96
97- Content-heavy pages, because the inset steals width on small screens.
98- Full-bleed imagery or video heroes, which want to reach the edges.
99- Sites that already have a strong background pattern, since the ground would compete with it.
100
101---
102
103## Reference implementation
104
105Plain HTML and CSS. The preview on freedesignmd.com renders exactly these three blocks, so what you see
106is what you get. The pattern CSS decides structure. The base CSS is the neutral skin shared by every
107pattern: replace its variables with your DESIGN.md tokens and keep the names.
108
109### HTML
110
111```html
112<!-- data-region and data-dim only drive the Blueprint view. Remove them in production. -->
113<div class="ground" data-region="Ground" data-n="1" data-at="ir">
114 <div class="frame" data-region="Frame" data-n="2" data-at="in">
115 <header class="bar" data-region="Nav bar" data-n="3" data-at="bl">
116 <div class="wrap">
117 <nav class="nav" aria-label="Primary">
118 <a class="brand" href="#"><span class="mark"></span>Meridian</a>
119 <ul class="links">
120 <li><a href="#">Product</a></li>
121 <li><a href="#">Pricing</a></li>
122 <li><a href="#">Docs</a></li>
123 <li><a href="#">Changelog</a></li>
124 </ul>
125 <div class="actions">
126 <a class="btn btn-ghost" href="#">Sign in</a>
127 <a class="btn btn-primary" href="#">Start free</a>
128 </div>
129 </nav>
130 </div>
131 </header>
132 <main>
133 <section class="sec" data-dim="64" data-dim-axis="pad">
134 <div class="wrap" data-dim="max 1040">
135 <p class="eyebrow">Release 2.4</p>
136 <h1>Ship changes your customers actually read</h1>
137 <p class="lead">Meridian turns merged pull requests into clear release notes, changelogs and update emails.</p>
138 <div class="actions">
139 <a class="btn btn-primary" href="#">Start free</a>
140 <a class="btn btn-ghost" href="#">Read the docs</a>
141 </div>
142 <div class="well" data-region="Inset panel" data-n="4" data-at="in" data-dim="radius 12" data-dim-axis="tag" data-dim-at="tr">
143 <figure class="mock" aria-label="Release notes preview">
144 <div class="mock-bar"><span>Release 2.4</span><span>Mar 12</span></div>
145 <ul>
146 <li><b class="new">New</b>Draft notes from merged pull requests</li>
147 <li><b>Improved</b>Changelog search across all releases</li>
148 <li><b>Fixed</b>Email previews on narrow screens</li>
149 </ul>
150 </figure>
151 </div>
152 </div>
153 </section>
154 <section class="sec" id="features">
155 <div class="wrap">
156 <div class="head">
157 <div>
158 <p class="eyebrow">01 Features</p>
159 <h2>Everything between merge and inbox</h2>
160 </div>
161 <p class="sub">Drafts group by product area, not by commit.</p>
162 </div>
163 <div class="cols">
164 <article class="feature">
165 <span class="n">01</span>
166 <h3>Draft from pull requests</h3>
167 <p>Group merged work by product area and get a first draft in seconds.</p>
168 </article>
169 <article class="feature">
170 <span class="n">02</span>
171 <h3>Edit in one place</h3>
172 <p>Rewrite, reorder and approve notes with your team before anything ships.</p>
173 </article>
174 <article class="feature">
175 <span class="n">03</span>
176 <h3>Publish everywhere</h3>
177 <p>Send the same note to your changelog, email list and in-app feed.</p>
178 </article>
179 </div>
180 </div>
181 </section>
182 <section class="sec" id="numbers">
183 <div class="wrap">
184 <div class="head">
185 <div>
186 <p class="eyebrow">02 Numbers</p>
187 <h2>Quiet, fast and always on</h2>
188 </div>
189 <p class="sub">Rolling twelve month medians across all workspaces.</p>
190 </div>
191 <div class="strip" data-region="Inset panel">
192 <div class="stat"><strong>2.4M</strong><span>Notes published</span></div>
193 <div class="stat"><strong>99.98%</strong><span>Uptime, last 12 months</span></div>
194 <div class="stat"><strong>140 ms</strong><span>Median render time</span></div>
195 </div>
196 </div>
197 </section>
198 <section class="sec" id="customers">
199 <div class="wrap">
200 <div class="head">
201 <div>
202 <p class="eyebrow">03 Customers</p>
203 <h2>In their words</h2>
204 </div>
205 <p class="sub">Halden, a 40 person team, publishes every week.</p>
206 </div>
207 <figure class="quote">
208 <blockquote>“Our changelog went from a Friday chore to the page customers open first.”</blockquote>
209 <figcaption><b>Sana Okafor</b> Head of Product, Halden</figcaption>
210 </figure>
211 </div>
212 </section>
213 <section class="sec" id="pricing">
214 <div class="wrap">
215 <div class="panel" data-region="Inset panel">
216 <div>
217 <p class="eyebrow">04 Pricing</p>
218 <h2>Free for small teams</h2>
219 <p class="sub">Up to five people and one changelog, no card needed.</p>
220 </div>
221 <div class="actions">
222 <a class="btn btn-primary" href="#">Start free</a>
223 </div>
224 </div>
225 </div>
226 </section>
227 </main>
228 </div>
229 <footer data-region="Footer strip" data-n="5" data-at="bl">
230 <div class="wrap">
231 <div class="foot">
232 <span>© 2026 Meridian</span>
233 <ul>
234 <li><a href="#">Privacy</a></li>
235 <li><a href="#">Terms</a></li>
236 <li><a href="#">Status</a></li>
237 </ul>
238 </div>
239 </div>
240 </footer>
241</div>
242```
243
244### CSS (pattern)
245
246```css
247:root {
248 --max: 1040px; /* content width inside the frame */
249 --inset: 12px; /* ground visible around the frame */
250 --radius: 16px; /* frame radius */
251 --radius-in: 12px; /* nested panels: frame radius minus the 4px optical step */
252 --pad: 64px; /* section padding, top and bottom */
253 --ground: color-mix(in srgb, var(--ink) 6%, var(--paper));
254}
255
256body { background: var(--ground); }
257.ground { min-height: 100svh; padding: var(--inset); }
258
259/* One rounded panel carries the whole page. */
260.frame { background: var(--paper); border: 1px solid var(--line-strong); border-radius: var(--radius); }
261.wrap { width: min(100% - 64px, var(--max)); margin-inline: auto; }
262.bar { border-bottom: 1px solid var(--line); }
263
264/* Sections are separated by space only. Fills are reserved for inset panels. */
265.sec { padding-block: var(--pad); }
266.sec h1 { margin-top: 16px; }
267.sec h1 + .lead { margin-top: 20px; }
268.sec .lead + .actions { margin-top: 28px; }
269
270.well { margin-top: 48px; padding: 32px; border-radius: var(--radius-in); background: var(--paper-2); }
271.well .mock { max-width: 560px; margin-inline: auto; }
272
273.head { display: flex; align-items: flex-end; justify-content: space-between; gap: 32px; margin-bottom: 40px; }
274.head > div > * + * { margin-top: 8px; }
275.head .sub { text-align: right; }
276.cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
277.strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; padding: 32px; border-radius: var(--radius-in); background: var(--paper-2); }
278.panel { display: flex; align-items: flex-end; justify-content: space-between; gap: 32px; padding: 40px; border-radius: var(--radius-in); background: var(--paper-2); }
279.panel > div > * + * { margin-top: 8px; }
280
281.ground > footer { padding-inline: 0; }
282
283@media (max-width: 800px) {
284 :root { --inset: 6px; --radius: 12px; --radius-in: 8px; --pad: 48px; }
285 .wrap { width: min(100% - 40px, var(--max)); }
286 .head, .panel { flex-direction: column; align-items: flex-start; gap: 12px; }
287 .head .sub { text-align: left; }
288 .cols, .strip { grid-template-columns: 1fr; gap: 24px; }
289 .well, .strip, .panel { padding: 20px; }
290}
291```
292
293### CSS (base, shared by every pattern)
294
295```css
296/* Base: tokens and content blocks shared by every pattern. Structure lives in the pattern CSS. */
297:root {
298 color-scheme: light;
299 --paper: #ffffff;
300 --paper-2: #f5f5f6;
301 --ink: #0e0e10;
302 --ink-2: #55555c;
303 --ink-3: #767680;
304 --line: rgba(14, 14, 16, 0.09);
305 --line-strong: rgba(14, 14, 16, 0.16);
306 --accent: #c8421a;
307 --inv-paper: #0b0b0d;
308 --inv-ink: #f3f3f5;
309 --inv-ink-2: #a4a4ab;
310 --inv-line: rgba(255, 255, 255, 0.12);
311 --font: "Inter Variable", Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
312 --mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
313}
314:root[data-theme="dark"] {
315 color-scheme: dark;
316 --paper: #0b0b0d;
317 --paper-2: #131316;
318 --ink: #f3f3f5;
319 --ink-2: #a4a4ab;
320 --ink-3: #74747c;
321 --line: rgba(255, 255, 255, 0.09);
322 --line-strong: rgba(255, 255, 255, 0.16);
323 --accent: #ff8a5c;
324 --inv-paper: #f6f6f7;
325 --inv-ink: #0e0e10;
326 --inv-ink-2: #55555c;
327 --inv-line: rgba(14, 14, 16, 0.1);
328}
329
330*, *::before, *::after { box-sizing: border-box; }
331html { -webkit-text-size-adjust: 100%; }
332body {
333 margin: 0;
334 background: var(--paper);
335 color: var(--ink);
336 font: 400 15px/1.55 var(--font);
337 -webkit-font-smoothing: antialiased;
338}
339h1, h2, h3, p, ul, ol, figure, blockquote, dl, dd { margin: 0; }
340ul, ol { padding: 0; list-style: none; }
341a { color: inherit; text-decoration: none; }
342
343/* Type scale: 12 / 13 / 15 / 17 / 22 / 28 / 44 */
344h1, .t-h1 { font-size: 44px; line-height: 1.05; letter-spacing: -0.03em; font-weight: 500; text-wrap: balance; }
345h2, .t-h2 { font-size: 28px; line-height: 1.15; letter-spacing: -0.02em; font-weight: 500; text-wrap: balance; }
346h3 { font-size: 15px; line-height: 1.4; font-weight: 500; }
347.lead { font-size: 17px; line-height: 1.55; color: var(--ink-2); max-width: 46ch; text-wrap: pretty; }
348.sub { font-size: 14px; line-height: 1.55; color: var(--ink-2); max-width: 40ch; text-wrap: pretty; }
349.eyebrow { font: 400 12px/16px var(--mono); color: var(--ink-3); letter-spacing: 0.02em; }
350
351/* Buttons: one primary per view */
352.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
353.btn {
354 display: inline-flex; align-items: center; height: 36px; padding: 0 14px;
355 border: 1px solid transparent; border-radius: 8px;
356 font: 500 14px/1 var(--font); white-space: nowrap;
357}
358.btn-primary { background: var(--ink); color: var(--paper); }
359.btn-ghost { border-color: var(--line-strong); color: var(--ink); }
360
361/* Nav */
362.nav { display: flex; align-items: center; gap: 32px; height: 56px; }
363.brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; letter-spacing: -0.01em; }
364.mark { width: 16px; height: 16px; border: 4px solid var(--ink); border-radius: 50%; }
365.links { display: flex; gap: 24px; font-size: 14px; color: var(--ink-2); }
366.nav .actions { margin-left: auto; }
367
368/* Feature */
369.feature { display: flex; flex-direction: column; gap: 8px; }
370.feature .n { font: 400 12px/16px var(--mono); color: var(--accent); }
371.feature p { font-size: 14px; line-height: 1.55; color: var(--ink-2); }
372
373/* Stat */
374.stat strong {
375 display: block; font: 500 36px/1.1 var(--font); letter-spacing: -0.03em;
376 font-variant-numeric: tabular-nums;
377}
378.stat span { display: block; margin-top: 4px; font-size: 13px; color: var(--ink-2); }
379
380/* Quote */
381.quote blockquote { font-size: 22px; line-height: 1.35; letter-spacing: -0.015em; text-wrap: balance; }
382.quote figcaption { margin-top: 16px; font-size: 13px; color: var(--ink-2); }
383.quote figcaption b { color: var(--ink); font-weight: 500; }
384
385/* Release card: the one visual used when a pattern has a media slot */
386.mock { border: 1px solid var(--line-strong); border-radius: 12px; background: var(--paper); overflow: hidden; }
387.mock-bar { display: flex; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--line); font: 400 12px/16px var(--mono); color: var(--ink-3); }
388.mock li { display: flex; gap: 12px; align-items: baseline; padding: 12px 16px; border-bottom: 1px solid var(--line); font-size: 14px; }
389.mock li:last-child { border-bottom: 0; }
390.mock li b { flex: none; width: 64px; font: 400 12px/16px var(--mono); color: var(--ink-3); }
391.mock li b.new { color: var(--accent); }
392
393/* Footer strip */
394.foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; height: 56px; font-size: 13px; color: var(--ink-3); }
395.foot ul { display: flex; gap: 20px; }
396
397/* Inverted band: swaps the tokens, so every block inside adapts */
398.inv {
399 --paper: var(--inv-paper); --ink: var(--inv-ink); --ink-2: var(--inv-ink-2);
400 --ink-3: var(--inv-ink-2); --line: var(--inv-line); --line-strong: var(--inv-line);
401 background: var(--paper); color: var(--ink);
402}
403
404@media (max-width: 640px) {
405 h1, .t-h1 { font-size: 34px; }
406 h2, .t-h2 { font-size: 24px; }
407 .links, .nav .btn-ghost { display: none; }
408 .nav { gap: 16px; }
409 .foot ul { gap: 14px; }
410}
411
412```

Save it next to your DESIGN.md and tell your agent: build every page with PATTERN.md for structure and DESIGN.md for look.

Pairs well with. Combine structures.

Centered column layout pattern: One 680px column, centered, with a centered hero and short hairlines between left-aligned sections

Centered column

One 680px column, centered, with a centered hero and short hairlines between left-aligned sections.

  • Single column
  • Long form
  • Newsletter
Bordered cell grid layout pattern: A 12-column bento where every cell shares a 1px border with its neighbours and nothing has a gap, radius or shadow

Bordered cell grid

A 12-column bento where every cell shares a 1px border with its neighbours and nothing has a gap, radius or shadow.

  • Bento
  • Cell grid
  • Features
App shell layout pattern: A fixed sidebar and top bar around one scrolling content area, with bordered panels on a 12-column grid

App shell

A fixed sidebar and top bar around one scrolling content area, with bordered panels on a 12-column grid.

  • Sidebar
  • Dashboard
  • Product UI

Questions. Short answers.

It is a layout where the page content sits inside one rounded panel set into a tinted background, so the page has visible margins and a defined edge, like an app window.

Give the page wrapper 12px of padding and a ground color, then put a child with a 16px border radius, a 1px border and the page background inside it. Nested panels use a slightly smaller radius.

Inner radius should be the outer radius minus the gap between them. With a 16px frame, use 12px for panels that sit close to its edge.