cta.dot-signal-tile · Signal tile

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

Rule
One red tile: the title in the dot face at step 6, a line and an inline email form in 1–8; a round halftone widget in 10–12.
Slots
title, body, newsletter, image
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)

Pattern notes

  • One red widget (padding 48 × 40 px): the title in the dot face at step 6 (≤14 ch), a line and an inline email form with a white pill submit in 1–8, all in `onAccent`; a round halftone picture in 10–12, hidden on phones. The only red tile on the page bottom.

Have a hard thing to explain?

Each engagement starts with a two-week audit: interviews with customers, sales and the people who build the product. The brief writes itself after that.

you@example.com
Subscribe
Layout tree (as in design/layout.json)
{
  "pattern": "cta.dot-signal-tile",
  "kind": "cta",
  "slots": [
    "title",
    "body",
    "newsletter",
    "image"
  ],
  "tree": {
    "el": "box",
    "bg": "accent",
    "pad": [
      12,
      10
    ],
    "justify": "between",
    "radius": "md",
    "children": [
      {
        "el": "grid",
        "gap": 6,
        "align": "center",
        "children": [
          {
            "el": "box",
            "span": "1-8",
            "gap": 6,
            "justify": "center",
            "children": [
              {
                "el": "text",
                "color": "onAccent",
                "slot": "title",
                "role": "h2",
                "step": 6,
                "weight": 700,
                "leading": "tight",
                "maxCh": 14
              },
              {
                "el": "text",
                "color": "onAccent",
                "slot": "body",
                "role": "body",
                "maxCh": 40
              },
              {
                "el": "form",
                "slot": "newsletter",
                "fields": [
                  "email"
                ],
                "inline": true
              }
            ]
          },
          {
            "el": "media",
            "span": "10-12",
            "mobile": "hide",
            "alignSelf": "center",
            "slot": "image",
            "treatment": "dot-matrix",
            "frame": "circle"
          }
        ]
      }
    ]
  }
}
Component example: reference/cta.dot-signal-tile.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>cta.dot-signal-tile — Dot Matrix</title>
<link rel="stylesheet" href="base.css">
<style>
  section { padding: var(--section) 0; }
  .widget.signal { padding: 48px 40px; display: grid; grid-template-columns: repeat(12, 1fr); gap: 24px; align-items: center; }
  .copy { grid-column: 1 / 9; display: grid; gap: 24px; }
  .copy h2 { font-size: var(--step-6); max-width: 14ch; }
  form { display: flex; gap: 8px; max-width: 520px; }
  input { flex: 1; min-width: 0; height: 52px; padding: 0 20px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--on-accent) 55%, transparent);
          background: color-mix(in srgb, #000 12%, var(--accent)); color: var(--on-accent); font: inherit; }
  input::placeholder { color: color-mix(in srgb, var(--on-accent) 80%, transparent); }
  .btn.white { background: var(--on-accent); color: var(--accent); }
  .pic { grid-column: 10 / 13; }
  @media (max-width: 640px) { .widget.signal { padding: 32px 20px; } .copy h2 { font-size: 44px; } form { flex-direction: column; } }
</style>
</head>
<body>
<section class="wrap">
  <div class="widget signal">
    <div class="copy">
      <h2>Be first in the queue</h2>
      <p>One email when the next drop opens. Nothing else.</p>
      <form><label class="mono" for="e" hidden>Email</label><input id="e" type="email" placeholder="you@example.com"><button class="btn white" type="submit">Notify me</button></form>
    </div>
    <div class="pic hide-phone"><svg class="halftone round" viewBox="0 0 280 280" role="img" aria-label="Halftone of the phone"></svg></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