---
name: "Ruled sections"
description: "Full-width hairlines separate every section, with a narrow label gutter on the left and the content beside it."
type: pattern
tags: ["Rules", "Label gutter", "Marketing", "Docs"]
container: "Full-bleed sections, centered content wrapper"
max_width: "1200px"
columns: "2: 200px label gutter and one fluid content column"
gutter: "32px between label and content"
rules: "1px solid, full-bleed, ink at 9% opacity, one per section"
section_padding: "72px top and bottom, 48px below 800px"
breakpoints: "Below 800px the label stacks above the content and inner columns collapse to one"
sticky: "None. The label may become position: sticky if sections are tall"
---

# Ruled sections

Full-width hairlines separate every section, with a narrow label gutter on the left and the content beside it.

## AI build instructions

> Read this section before writing any code. It describes page structure only.
> Colors, type, radii and shadows come from the project's DESIGN.md, never from this file.

### 1. Your role

Build the page layout as **Ruled sections**. Use the HTML and CSS under Reference implementation as the
structural source of truth. Keep the project's own copy, components and styling, and place them into the
regions listed below. If the project has a DESIGN.md, map its tokens onto the base variables
(`--paper`, `--paper-2`, `--ink`, `--ink-2`, `--ink-3`, `--line`, `--accent`) and leave the structure CSS unchanged.

### 2. Structure contract

| Token | Value |
|-------|-------|
| container | Full-bleed sections, centered content wrapper |
| max width | 1200px |
| columns | 2: 200px label gutter and one fluid content column |
| gutter | 32px between label and content |
| rules | 1px solid, full-bleed, ink at 9% opacity, one per section |
| section padding | 72px top and bottom, 48px below 800px |
| breakpoints | Below 800px the label stacks above the content and inner columns collapse to one |
| sticky | None. The label may become position: sticky if sections are tall |
| accessibility | Each section is a section element with a visible heading. Rules are borders, so they stay out of the accessibility tree |

### 3. Regions

The markup marks each region with `data-region`. These attributes only drive the Blueprint view on
freedesignmd.com and can be removed in production.

1. **Nav bar.** A 56px bar with a hairline underneath. It shares the content wrapper, so the logo lines up with every label below.
2. **Section.** A full-width band that ends in a 1px hairline running edge to edge. The rule is the only separator between sections.
3. **Label gutter.** A fixed 200px column on the left holding the mono section label and, below it, one short caption.
4. **Content column.** Everything else sits to the right of the gutter: heading, then the section's blocks, left aligned to one edge.
5. **Footer strip.** The last rule closes the page. The strip reuses the wrapper, so links align with the nav.

### 4. Rules

- Draw one full-bleed 1px hairline at the bottom of every section and the nav. Never use cards or shadows to separate sections.
- Keep the label gutter at 200px and align the section label to the first line of the heading.
- Use the same content wrapper (max 1200px) for nav, every section and the footer.
- Keep section padding identical across sections, 72px on desktop.
- Collapse to one column below 800px and stack the label above the content.

### 5. Hard constraints

Never do any of the following without an explicit instruction from the user:

- Change the structure tokens above, add a column, or add dividers the pattern does not define.
- Replace the structure with cards, shadows or colored backgrounds to separate sections.
- Use gradients, glows or emoji to decorate the layout.
- Put page content inside a region that is meant for another kind of content.

### 6. Before you finish, verify

- [ ] Every region listed above exists and is in the same order as in the reference markup.
- [ ] Container width, columns, gutter, rule weight and section padding match the contract.
- [ ] The layout collapses as described at the stated breakpoints, with no horizontal scroll at 390px.
- [ ] Sticky elements behave as stated and never cover focused content.
- [ ] Colors, type and radii were taken from DESIGN.md, not invented.

---

## Overview

Ruled sections build the page from horizontal bands that each end in a hairline running the full width of the viewport. A fixed label gutter on the left names the section, and the content sits in one column beside it. The rules do the separating, so there are no cards, backgrounds or shadows. It is the quiet, ledger-like structure behind many developer-tool and fintech sites.

## When to use it

- Marketing sites for developer tools, APIs and fintech where a calm, precise tone is the point.
- Pages made of many short sections that each need a clear name.
- Pricing, changelog and about pages that read like a document.
- Sites that want structure without cards, shadows or tinted backgrounds.

## When to avoid it

- Image-led or editorial pages, where hairlines compete with the pictures.
- Narrow screens only, since the label gutter has nothing to do below 800px.
- Pages with only two or three sections, which do not need this much scaffolding.

---

## Reference implementation

Plain HTML and CSS. The preview on freedesignmd.com renders exactly these three blocks, so what you see
is what you get. The pattern CSS decides structure. The base CSS is the neutral skin shared by every
pattern: replace its variables with your DESIGN.md tokens and keep the names.

### HTML

```html
<!-- data-region and data-dim only drive the Blueprint view. Remove them in production. -->
<div class="page">
  <header class="bar" data-region="Nav bar" data-n="1" data-at="bl">
    <div class="wrap">
      <nav class="nav" aria-label="Primary">
        <a class="brand" href="#"><span class="mark"></span>Meridian</a>
        <ul class="links">
          <li><a href="#">Product</a></li>
          <li><a href="#">Pricing</a></li>
          <li><a href="#">Docs</a></li>
          <li><a href="#">Changelog</a></li>
        </ul>
        <div class="actions">
          <a class="btn btn-ghost" href="#">Sign in</a>
          <a class="btn btn-primary" href="#">Start free</a>
        </div>
      </nav>
    </div>
  </header>
  <main>
    <section class="sec" data-region="Section" data-n="2" data-dim="72" data-dim-axis="pad">
      <div class="wrap grid" data-dim="max 1200">
        <div class="label" data-region="Label gutter" data-n="3">
          <p class="eyebrow">Release 2.4</p>
        </div>
        <div class="body" data-region="Content column" data-n="4">
          <h1>Ship changes your customers actually read</h1>
          <p class="lead">Meridian turns merged pull requests into clear release notes, changelogs and update emails.</p>
          <div class="actions">
            <a class="btn btn-primary" href="#">Start free</a>
            <a class="btn btn-ghost" href="#">Read the docs</a>
          </div>
        </div>
      </div>
    </section>
    <section class="sec" data-region="Section" data-dim="1px rule" data-dim-axis="tag" id="features">
      <div class="wrap grid">
        <div class="label" data-region="Label gutter">
          <p class="eyebrow">01 Features</p>
          <p class="sub">Drafts group by product area, not by commit.</p>
        </div>
        <div class="body" data-region="Content column">
          <h2>Everything between merge and inbox</h2>
          <div class="cols">
            <article class="feature">
              <span class="n">01</span>
              <h3>Draft from pull requests</h3>
              <p>Group merged work by product area and get a first draft in seconds.</p>
            </article>
            <article class="feature">
              <span class="n">02</span>
              <h3>Edit in one place</h3>
              <p>Rewrite, reorder and approve notes with your team before anything ships.</p>
            </article>
            <article class="feature">
              <span class="n">03</span>
              <h3>Publish everywhere</h3>
              <p>Send the same note to your changelog, email list and in-app feed.</p>
            </article>
          </div>
        </div>
      </div>
    </section>
    <section class="sec" data-region="Section" id="numbers">
      <div class="wrap grid">
        <div class="label" data-region="Label gutter">
          <p class="eyebrow">02 Numbers</p>
          <p class="sub">Rolling twelve month medians across all workspaces.</p>
        </div>
        <div class="body" data-region="Content column">
          <h2>Quiet, fast and always on</h2>
          <div class="cols">
            <div class="stat"><strong>2.4M</strong><span>Notes published</span></div>
            <div class="stat"><strong>99.98%</strong><span>Uptime, last 12 months</span></div>
            <div class="stat"><strong>140 ms</strong><span>Median render time</span></div>
          </div>
        </div>
      </div>
    </section>
    <section class="sec" data-region="Section" id="customers">
      <div class="wrap grid">
        <div class="label" data-region="Label gutter">
          <p class="eyebrow">03 Customers</p>
          <p class="sub">Halden, a 40 person team, publishes every week.</p>
        </div>
        <div class="body" data-region="Content column">
          <h2>In their words</h2>
          <figure class="quote">
            <blockquote>“Our changelog went from a Friday chore to the page customers open first.”</blockquote>
            <figcaption><b>Sana Okafor</b> Head of Product, Halden</figcaption>
          </figure>
        </div>
      </div>
    </section>
    <section class="sec" data-region="Section" id="pricing">
      <div class="wrap grid">
        <div class="label" data-region="Label gutter">
          <p class="eyebrow">04 Pricing</p>
          <p class="sub">Up to five people and one changelog, no card needed.</p>
        </div>
        <div class="body" data-region="Content column">
          <h2>Free for small teams</h2>
          <div class="actions">
            <a class="btn btn-primary" href="#">Start free</a>
          </div>
        </div>
      </div>
    </section>
  </main>
  <footer data-region="Footer strip" data-n="5">
    <div class="wrap">
      <div class="foot">
        <span>© 2026 Meridian</span>
        <ul>
          <li><a href="#">Privacy</a></li>
          <li><a href="#">Terms</a></li>
          <li><a href="#">Status</a></li>
        </ul>
      </div>
    </div>
  </footer>
</div>
```

### CSS (pattern)

```css
:root {
  --max: 1200px;     /* content width */
  --label: 200px;    /* label gutter */
  --gap: 32px;       /* gutter between label and content */
  --pad: 72px;       /* section padding, top and bottom */
  --rule: 1px solid var(--line);
}

.wrap { width: min(100% - 48px, var(--max)); margin-inline: auto; }
.bar { border-bottom: var(--rule); }

/* Every section ends in a full-bleed hairline. The rule is the separator. */
.sec { padding-block: var(--pad); border-bottom: var(--rule); }
.grid { display: grid; grid-template-columns: var(--label) minmax(0, 1fr); gap: var(--gap); }

.label { display: flex; flex-direction: column; gap: 12px; padding-top: 6px; }
.body > * + * { margin-top: 24px; }
.body > h2 + * { margin-top: 40px; }
.body > .lead { margin-top: 20px; }
.cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }

footer { border-top: 0; }

@media (max-width: 800px) {
  :root { --pad: 48px; }
  .grid { grid-template-columns: 1fr; gap: 16px; }
  .label { padding-top: 0; }
  .cols { grid-template-columns: 1fr; gap: 24px; }
}
```

### CSS (base, shared by every pattern)

```css
/* Base: tokens and content blocks shared by every pattern. Structure lives in the pattern CSS. */
:root {
  color-scheme: light;
  --paper: #ffffff;
  --paper-2: #f5f5f6;
  --ink: #0e0e10;
  --ink-2: #55555c;
  --ink-3: #767680;
  --line: rgba(14, 14, 16, 0.09);
  --line-strong: rgba(14, 14, 16, 0.16);
  --accent: #c8421a;
  --inv-paper: #0b0b0d;
  --inv-ink: #f3f3f5;
  --inv-ink-2: #a4a4ab;
  --inv-line: rgba(255, 255, 255, 0.12);
  --font: "Inter Variable", Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #0b0b0d;
  --paper-2: #131316;
  --ink: #f3f3f5;
  --ink-2: #a4a4ab;
  --ink-3: #74747c;
  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.16);
  --accent: #ff8a5c;
  --inv-paper: #f6f6f7;
  --inv-ink: #0e0e10;
  --inv-ink-2: #55555c;
  --inv-line: rgba(14, 14, 16, 0.1);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 15px/1.55 var(--font);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p, ul, ol, figure, blockquote, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

/* Type scale: 12 / 13 / 15 / 17 / 22 / 28 / 44 */
h1, .t-h1 { font-size: 44px; line-height: 1.05; letter-spacing: -0.03em; font-weight: 500; text-wrap: balance; }
h2, .t-h2 { font-size: 28px; line-height: 1.15; letter-spacing: -0.02em; font-weight: 500; text-wrap: balance; }
h3 { font-size: 15px; line-height: 1.4; font-weight: 500; }
.lead { font-size: 17px; line-height: 1.55; color: var(--ink-2); max-width: 46ch; text-wrap: pretty; }
.sub { font-size: 14px; line-height: 1.55; color: var(--ink-2); max-width: 40ch; text-wrap: pretty; }
.eyebrow { font: 400 12px/16px var(--mono); color: var(--ink-3); letter-spacing: 0.02em; }

/* Buttons: one primary per view */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.btn {
  display: inline-flex; align-items: center; height: 36px; padding: 0 14px;
  border: 1px solid transparent; border-radius: 8px;
  font: 500 14px/1 var(--font); white-space: nowrap;
}
.btn-primary { background: var(--ink); color: var(--paper); }
.btn-ghost { border-color: var(--line-strong); color: var(--ink); }

/* Nav */
.nav { display: flex; align-items: center; gap: 32px; height: 56px; }
.brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; letter-spacing: -0.01em; }
.mark { width: 16px; height: 16px; border: 4px solid var(--ink); border-radius: 50%; }
.links { display: flex; gap: 24px; font-size: 14px; color: var(--ink-2); }
.nav .actions { margin-left: auto; }

/* Feature */
.feature { display: flex; flex-direction: column; gap: 8px; }
.feature .n { font: 400 12px/16px var(--mono); color: var(--accent); }
.feature p { font-size: 14px; line-height: 1.55; color: var(--ink-2); }

/* Stat */
.stat strong {
  display: block; font: 500 36px/1.1 var(--font); letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.stat span { display: block; margin-top: 4px; font-size: 13px; color: var(--ink-2); }

/* Quote */
.quote blockquote { font-size: 22px; line-height: 1.35; letter-spacing: -0.015em; text-wrap: balance; }
.quote figcaption { margin-top: 16px; font-size: 13px; color: var(--ink-2); }
.quote figcaption b { color: var(--ink); font-weight: 500; }

/* Release card: the one visual used when a pattern has a media slot */
.mock { border: 1px solid var(--line-strong); border-radius: 12px; background: var(--paper); overflow: hidden; }
.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); }
.mock li { display: flex; gap: 12px; align-items: baseline; padding: 12px 16px; border-bottom: 1px solid var(--line); font-size: 14px; }
.mock li:last-child { border-bottom: 0; }
.mock li b { flex: none; width: 64px; font: 400 12px/16px var(--mono); color: var(--ink-3); }
.mock li b.new { color: var(--accent); }

/* Footer strip */
.foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; height: 56px; font-size: 13px; color: var(--ink-3); }
.foot ul { display: flex; gap: 20px; }

/* Inverted band: swaps the tokens, so every block inside adapts */
.inv {
  --paper: var(--inv-paper); --ink: var(--inv-ink); --ink-2: var(--inv-ink-2);
  --ink-3: var(--inv-ink-2); --line: var(--inv-line); --line-strong: var(--inv-line);
  background: var(--paper); color: var(--ink);
}

@media (max-width: 640px) {
  h1, .t-h1 { font-size: 34px; }
  h2, .t-h2 { font-size: 24px; }
  .links, .nav .btn-ghost { display: none; }
  .nav { gap: 16px; }
  .foot ul { gap: 14px; }
}

```
