hero.dot-glyph-display · Glyph display

A hero pattern from Dot Matrix, drawn alone below with this design's tokens and sample copy. Used in this design on: home page, section 1. Give the section root data-pattern="hero.dot-glyph-display". A guide only: DESIGN.md and tokens.json are the source of truth.

Rule
Dot-matrix display headline at step 8 on the dotted page in 1–8, a round halftone widget and a dot-matrix date widget stacked in 9–12, and a numbered spec row of four readings under both.
Slots
eyebrow, headline, subhead, cta, cta2, caption, heroImage, label, date, meta, stats[4..4]
Grid areas
message 1-8 · dial 9-12 · reading 9-12 · specs 1-12 (12-column grid, 1-based inclusive spans)
Notes
The page shows the dot grid; widgets are solid tiles over it (radius 24 px, 1 px hairline). Red appears only in the dot beside the eyebrow and the primary pill. Numbers are the dot-matrix face; labels tiny uppercase mono.
Tokens
bg #000000 · text #E6E6E6 · heading #FFFFFF · accent #D71921 · accent2 #FFFFFF · Doto / Space Grotesk · radius 24px · space unit 4px (full list in design/tokens.json)
Section
vertical padding step 3

Pattern notes

  • The signature hero, at least 86 vh. Columns 1–8 over two rows on the dotted ground: the red signal dot beside the mono eyebrow at the top, the display headline at step 8 (≤14 ch, tight leading) and, at the bottom, the muted lead (≤40 ch) above the red primary pill and an outlined secondary pill. Columns 9–12, row 1: a surface widget with a mono caption over a round halftone picture. Row 2: a surfaceAlt clock widget with a mono label, the date in the dot face at step 6 and a muted note. Row 3 across 1–12: four numbered readings, each a hairline above a mono label and a number at step 5. Phone: message, then the two widgets, then the readings two per row.

Brand & product studio

We make complicated companies simple to choose

Northfold is a 14-person studio helping manufacturers, labs and B2B teams explain what they do — and look like they mean it.

Start a projectRead case studies

Corvid Robotics — identity

Introducing

Apr 3, 2026

Booking projects from June 2026

launches shipped

140+

years independent

12

clients return

9 of 10

average lift in demo requests

31%

Layout tree (as in design/layout.json)
{
  "pattern": "hero.dot-glyph-display",
  "kind": "hero",
  "grid": {
    "message": "1-8",
    "dial": "9-12",
    "reading": "9-12",
    "specs": "1-12"
  },
  "slots": [
    "eyebrow",
    "headline",
    "subhead",
    "cta",
    "cta2",
    "caption",
    "heroImage",
    "label",
    "date",
    "meta",
    "stats[4..4]"
  ],
  "notes": "The page shows the dot grid; widgets are solid tiles over it (radius 24 px, 1 px hairline). Red appears only in the dot beside the eyebrow and the primary pill. Numbers are the dot-matrix face; labels tiny uppercase mono.",
  "tree": {
    "el": "grid",
    "gap": 3,
    "rowGap": 3,
    "align": "stretch",
    "minVh": 0.86,
    "children": [
      {
        "el": "box",
        "span": "1-8",
        "rowSpan": "1-2",
        "gap": 6,
        "pad": [
          2,
          0
        ],
        "justify": "between",
        "children": [
          {
            "el": "box",
            "mobile": "keep",
            "dir": "row",
            "gap": 3,
            "align": "center",
            "children": [
              {
                "el": "shape",
                "kind": "circle",
                "size": "sm",
                "fill": "accent"
              },
              {
                "el": "text",
                "color": "text",
                "slot": "eyebrow",
                "role": "label",
                "font": "mono"
              }
            ]
          },
          {
            "el": "text",
            "slot": "headline",
            "role": "display",
            "step": 8,
            "weight": 700,
            "leading": "tight",
            "maxCh": 14
          },
          {
            "el": "box",
            "gap": 6,
            "children": [
              {
                "el": "text",
                "color": "textMuted",
                "slot": "subhead",
                "role": "lead",
                "maxCh": 40
              },
              {
                "el": "box",
                "dir": "row",
                "gap": 3,
                "wrap": true,
                "children": [
                  {
                    "el": "button",
                    "slot": "cta",
                    "variant": "primary",
                    "size": "lg"
                  },
                  {
                    "el": "button",
                    "slot": "cta2",
                    "variant": "secondary",
                    "size": "lg",
                    "arrow": true
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "el": "box",
        "span": "9-12",
        "rowSpan": "1-1",
        "bg": "surface",
        "gap": 4,
        "pad": [
          5,
          5
        ],
        "justify": "between",
        "radius": "md",
        "children": [
          {
            "el": "text",
            "color": "textMuted",
            "slot": "caption",
            "role": "label",
            "font": "mono"
          },
          {
            "el": "media",
            "slot": "heroImage",
            "treatment": "dot-matrix",
            "frame": "circle"
          }
        ]
      },
      {
        "el": "box",
        "span": "9-12",
        "rowSpan": "2-2",
        "bg": "surfaceAlt",
        "gap": 4,
        "pad": [
          5,
          5
        ],
        "justify": "between",
        "radius": "md",
        "children": [
          {
            "el": "text",
            "color": "textMuted",
            "slot": "label",
            "role": "label",
            "font": "mono"
          },
          {
            "el": "text",
            "slot": "date",
            "role": "number",
            "step": 6,
            "weight": 700,
            "leading": "tight",
            "maxCh": 10
          },
          {
            "el": "text",
            "color": "textMuted",
            "slot": "meta",
            "role": "small"
          }
        ]
      },
      {
        "el": "repeat",
        "span": "1-12",
        "slot": "stats",
        "min": 4,
        "max": 4,
        "layout": "grid",
        "cols": 4,
        "phoneCols": 2,
        "gap": 6,
        "of": {
          "el": "box",
          "gap": 2,
          "pad": [
            4,
            0
          ],
          "border": "top",
          "children": [
            {
              "el": "text",
              "color": "textMuted",
              "slot": "title",
              "role": "label",
              "font": "mono"
            },
            {
              "el": "text",
              "slot": "number",
              "role": "number",
              "step": 5,
              "weight": 700,
              "leading": "tight"
            }
          ]
        }
      }
    ]
  }
}
Component example: reference/hero.dot-glyph-display.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>hero.dot-glyph-display — Dot Matrix</title>
<link rel="stylesheet" href="base.css">
<style>
  .hero { padding: 40px 0 56px; min-height: 86vh; align-items: stretch; }
  .msg { grid-column: 1 / 9; grid-row: 1 / 3; display: flex; flex-direction: column; justify-content: space-between; gap: 32px; padding: 16px 0; }
  .eyebrow { display: flex; align-items: center; gap: 12px; color: var(--text); }
  h1 { font-size: clamp(56px, 10vw, var(--step-8)); max-width: 14ch; }
  .lead { font-size: var(--step-1); line-height: 1.45; max-width: 40ch; color: var(--muted); margin-bottom: 24px; }
  .row { display: flex; gap: 12px; flex-wrap: wrap; }
  .dial { grid-column: 9 / 13; grid-row: 1 / 2; }
  .clock { grid-column: 9 / 13; grid-row: 2 / 3; }
  .clock .dot { font-size: var(--step-6); }
  .specs { grid-column: 1 / 13; display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
  .specs div { border-top: 1px solid var(--border); padding-top: 16px; display: grid; gap: 8px; }
  .specs .dot { font-size: var(--step-5); }
  @media (max-width: 640px) { .specs { grid-template-columns: 1fr 1fr; } h1 { font-size: 54px; } }
</style>
</head>
<body>
<section class="wrap grid hero">
  <div class="msg">
    <span class="mono eyebrow"><span class="rec"></span>Ear (3) — now shipping</span>
    <h1>Sound you can see through</h1>
    <div>
      <p class="lead">Transparent buds with a dot-matrix case display. Forty hours, one press.</p>
      <div class="row"><a class="btn" href="#">Buy now</a><a class="btn secondary" href="#">See the specs →</a></div>
    </div>
  </div>
  <div class="widget dial">
    <span class="mono">Ear (3) — case</span>
    <svg class="halftone round" viewBox="0 0 280 280" role="img" aria-label="Halftone of the charging case"></svg>
  </div>
  <div class="widget alt clock">
    <span class="mono">Ships</span>
    <span class="dot">Oct 30</span>
    <span class="small muted">Free returns for 30 days</span>
  </div>
  <div class="specs">
    <div><span class="mono">Battery</span><span class="dot">40h</span></div>
    <div><span class="mono">Noise cancel</span><span class="dot">-45dB</span></div>
    <div><span class="mono">Weight</span><span class="dot">4.6g</span></div>
    <div><span class="mono">Charge</span><span class="dot">10m</span></div>
  </div>
</section>
<script>
/* Halftone: a 28-dot square grid; each dot radius follows the tone of a lit sphere; a small moon in the signal red. */
for (const svg of document.querySelectorAll("svg.halftone")) {
  const n = 28, c = 10, out = [];
  for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) {
    const x = (i + .5) * c, y = (j + .5) * c, dx = (x - 130) / 95, dy = (y - 150) / 95, d2 = dx * dx + dy * dy;
    let tone = d2 <= 1 ? .18 + .82 * (1 - Math.max(0, -.55 * dx - .6 * dy + .58 * Math.sqrt(1 - d2))) : .06;
    const mx = (x - 225) / 26, my = (y - 70) / 26, sig = mx * mx + my * my <= 1; if (sig) tone = .85;
    const r = Math.min(.48, tone * .5) * c; if (r < c * .05) continue;
    out.push(`<circle class="${sig ? "sig" : "ink"}" cx="${x}" cy="${y}" r="${r.toFixed(2)}"/>`);
  }
  svg.innerHTML = out.join("");
}
</script>
</body>
</html>

Other patterns in this design

Whole design · Spec bundle (JSON) · On the style page