Give the two pattern pages dedicated CSS instead of inline styles
Loop and Archive are meant to model real usage of this system — what an
actual project would write, not a documentation-only shortcut — so they
should look like it. Both were previously ~100% inline-styled: every
div's layout, spacing, and color set by hand on the element instead of
in a stylesheet (108 inline style= attributes combined).

Added _sass/site/patterns.css: real classes for the page-specific shapes
neither page shares with an actual component (a dashboard shell, a phone
frame, a status-strip day, a capture dock) — composed from the same
var(--ad-*) tokens every component reads. Also added .field-stack to
field.css itself (a genuinely reusable vertical-fields composition,
alongside the existing .form-row for side-by-side fields), since that
one belongs with the component, not the pages.

Loop: 70 inline styles -> 3 (a one-off danger-tone label and the dialog
demo's own width/min-height, consistent with how every other component
page leaves demo-specific sizing inline).
Archive: 38 -> 4 (one-off spacing/sizing choices, same standard).

Left card-row.md's own remaining inline styles alone — consolidating its
row-content pattern with Loop/Archive's would mean deciding CardRow's
real content-composition API, which is a component design decision, not
an obvious inline-to-class extraction.

Verified: rake build succeeds, screenshots of both patterns are visually
identical to before (compared against the pre-refactor renders).
change
commit 5ff895e12710e790afa20fbd030f3bf36414c0e6
author Claude <noreply@anthropic.com>
date
parent 1a4f938a
diff --git a/_patterns/archive.md b/_patterns/archive.md
index db5d2d6..27b71dd 100644
--- a/_patterns/archive.md
+++ b/_patterns/archive.md
@@ -14,56 +14,56 @@ Three screens, abbreviated to what each one adds.
 <figure class="example">
 <figcaption>Home — recent captures</figcaption>
 <div>
-<div style="width: 300px; height: 560px; background: var(--ad-color-surface-page); border-radius: var(--ad-radius-lg); box-shadow: var(--ad-shadow-float); overflow:hidden; display:flex; flex-direction:column; position:relative;">
-  <header style="padding: 16px var(--ad-space-m) var(--ad-space-2xs);">
-    <span style="font-weight:600; font-size: var(--ad-step-1); letter-spacing:-0.01em;">Archive</span>
+<div class="pattern-phone">
+  <header class="pattern-phone__header">
+    <span class="pattern-phone__brand">Archive</span>
   </header>
-  <div style="flex:1; overflow:hidden; padding: 0 var(--ad-space-m);">
-    <div style="display:flex; align-items:baseline; gap:8px; margin: var(--ad-space-s) 0 var(--ad-space-xs);">
-      <span style="font-weight:700; font-size: var(--ad-step-0);">Recent</span>
-      <span class="type-label" style="margin-left:auto;">3 tracked</span>
+  <div class="pattern-phone__body pattern-phone__body--dock">
+    <div class="pattern-list-heading">
+      <span class="pattern-list-heading__title">Recent</span>
+      <span class="type-label">3 tracked</span>
     </div>
     <ul class="card">
       <li>
         <span class="avatar" data-square><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
-        <div style="flex:1; min-width:0;">
-          <div style="font-weight:550; font-size: var(--ad-step--1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">Dishwasher manual</div>
-          <div class="type-label" style="margin-top:2px;">PDF · 2.1MB</div>
+        <div class="pattern-row">
+          <div class="pattern-file-title pattern-file-title--truncate">Dishwasher manual</div>
+          <div class="type-label pattern-file-meta">PDF · 2.1MB</div>
         </div>
-        <span class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">2h</span>
+        <span class="type-mono pattern-row__meta">2h</span>
       </li>
       <li>
         <span class="avatar" data-square><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
-        <div style="flex:1; min-width:0;">
-          <div style="font-weight:550; font-size: var(--ad-step--1);">Sofa receipt</div>
-          <div class="type-label" style="margin-top:2px;">JPG · 640KB</div>
+        <div class="pattern-row">
+          <div class="pattern-file-title">Sofa receipt</div>
+          <div class="type-label pattern-file-meta">JPG · 640KB</div>
         </div>
-        <span class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">1d</span>
+        <span class="type-mono pattern-row__meta">1d</span>
       </li>
       <li>
         <span class="avatar" data-square><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
-        <div style="flex:1; min-width:0;">
-          <div style="font-weight:550; font-size: var(--ad-step--1);">Passport scan</div>
-          <div class="type-label" style="margin-top:2px;">PDF · 890KB</div>
+        <div class="pattern-row">
+          <div class="pattern-file-title">Passport scan</div>
+          <div class="type-label pattern-file-meta">PDF · 890KB</div>
         </div>
-        <span class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">4d</span>
+        <span class="type-mono pattern-row__meta">4d</span>
       </li>
     </ul>
   </div>
-  <div style="position:absolute; left:0; right:0; bottom:0; display:flex; justify-content:center; padding: 14px 20px 22px; background: linear-gradient(to top, var(--ad-color-surface-page) 65%, transparent);">
+  <div class="pattern-dock">
     <button data-variant="primary" data-size="lg" data-block>
       <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 8a2 2 0 0 1 2-2h1.5l1-1.5h9l1 1.5H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8Z" /><circle cx="12" cy="13" r="3.5" /></svg>
       Take a photo
     </button>
   </div>
 </div>
-<div style="width: 300px; height: 560px; background: var(--ad-color-surface-page); border-radius: var(--ad-radius-lg); box-shadow: var(--ad-shadow-float); overflow:hidden; display:flex; flex-direction:column;">
-  <header style="display:flex; align-items:center; gap:8px; padding: 16px var(--ad-space-m) var(--ad-space-2xs);">
+<div class="pattern-phone">
+  <header class="pattern-phone__header">
     <button class="icon-button" data-size="sm" aria-label="Back"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
-    <span style="font-weight:600; font-size: var(--ad-step-0);">Save</span>
+    <span class="pattern-phone__title">Save</span>
   </header>
-  <div style="flex:1; padding: 0 var(--ad-space-m);">
-    <div style="height: 180px; border-radius: var(--ad-radius-lg); border: 1px solid var(--ad-color-border-default); background: repeating-linear-gradient(45deg, transparent 0 8px, var(--ad-color-surface-fill-2) 8px 9px), var(--ad-color-surface-fill); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px; margin-top: var(--ad-space-s);">
+  <div class="pattern-phone__body">
+    <div class="pattern-photo-slot">
       <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg>
       <span class="type-label">Photo preview</span>
     </div>
@@ -72,27 +72,27 @@ Three screens, abbreviated to what each one adds.
       <input placeholder="Dishwasher manual" />
     </label>
   </div>
-  <div style="padding: var(--ad-space-m); display:flex; gap: var(--ad-space-2xs);">
-    <button style="flex:1;">Retake</button>
-    <button data-variant="primary" style="flex:1;">Save</button>
+  <div class="pattern-phone__footer">
+    <button>Retake</button>
+    <button data-variant="primary">Save</button>
   </div>
 </div>
-<div style="width: 300px; height: 560px; background: var(--ad-color-surface-page); border-radius: var(--ad-radius-lg); box-shadow: var(--ad-shadow-float); overflow:hidden; display:flex; flex-direction:column;">
-  <header style="display:flex; align-items:center; gap:8px; padding: 16px var(--ad-space-m) var(--ad-space-2xs);">
+<div class="pattern-phone">
+  <header class="pattern-phone__header">
     <button class="icon-button" data-size="sm" aria-label="Back"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
     <span class="type-label">Archive</span>
   </header>
-  <div style="flex:1; overflow:hidden; padding: 0 var(--ad-space-m) var(--ad-space-l);">
-    <h1 style="font-weight:700; font-size: var(--ad-step-2); letter-spacing:-0.01em; margin: var(--ad-space-xs) 0 var(--ad-space-2xs);">Dishwasher manual</h1>
-    <div style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom: var(--ad-space-m);">
+  <div class="pattern-phone__body">
+    <h1 class="pattern-detail-title">Dishwasher manual</h1>
+    <div class="pattern-tag-row">
       <span class="tag">location:kitchen</span>
       <span class="tag" data-dashed>+ add tag</span>
     </div>
-    <div class="type-label" style="margin-bottom: var(--ad-space-2xs);">File</div>
+    <div class="type-label pattern-aside__label--tight">File</div>
     <ul class="card">
       <li>
         <span class="avatar" data-square><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
-        <div style="flex:1; font-size: var(--ad-step--1);">PDF · 2.1MB</div>
+        <div class="pattern-row" style="font-size: var(--ad-step--1);">PDF · 2.1MB</div>
       </li>
     </ul>
     <div class="type-label" style="margin: var(--ad-space-m) 0 var(--ad-space-2xs);">Notes</div>
diff --git a/_patterns/loop.md b/_patterns/loop.md
index fac98fa..8bb5b24 100644
--- a/_patterns/loop.md
+++ b/_patterns/loop.md
@@ -9,115 +9,116 @@ summary: >-
 Loop is not a real product — it is the system's own reference layout for a
 dense, table-ish list screen: the shape a recurring-task tracker would take
 if it were rebuilt on this token set. Every visible value below is a
-component from this system; nothing here is page-specific CSS beyond a
-couple of inline widths.
+component from this system, composed with real page-specific CSS
+(`_sass/site/patterns.css`) rather than inline styles — the same thing an
+actual project built on this system would write.
 
 <figure class="example">
 <figcaption>Loop</figcaption>
 <div data-layout="stack">
-<div style="border: 1px solid var(--ad-color-border-hairline); border-radius: var(--ad-radius-lg); overflow: hidden; background: var(--ad-color-surface-page);">
-  <header style="display:flex; align-items:center; gap: var(--ad-space-s); padding: var(--ad-space-s) var(--ad-space-l); border-bottom: 1px solid var(--ad-color-border-hairline);">
-    <span style="font-family: var(--ad-font-mono); font-weight:600; letter-spacing:0.02em; font-size: var(--ad-step-0);">Loop</span>
-    <div style="flex:1;"></div>
+<div class="pattern-dashboard">
+  <header class="pattern-dashboard__header">
+    <span class="pattern-dashboard__title">Loop</span>
+    <div class="pattern-spacer"></div>
     <button data-variant="primary" data-size="sm">
       <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
       New
     </button>
     <span class="avatar">km</span>
   </header>
-  <div style="display:flex;">
-    <div style="flex:1; min-width:0; max-width: 34rem; padding: var(--ad-space-l);">
-      <section style="margin-bottom: var(--ad-space-l);">
-        <div style="display:flex; align-items:baseline; gap: var(--ad-space-2xs); margin-bottom: var(--ad-space-s);">
+  <div class="pattern-dashboard__body">
+    <div class="pattern-dashboard__main">
+      <section class="pattern-section">
+        <div class="pattern-section__heading">
           <span class="type-label" style="color: var(--ad-color-danger);">Overdue</span>
           <span class="badge" data-tone="danger">2</span>
         </div>
-        <ul class="card" style="border:none; border-radius:0; background:none;">
-          <li style="border-top: 1px solid var(--ad-color-border-hairline);">
-            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-danger);"></button>
-            <div style="flex:1; min-width:0;">
-              <div style="font-weight:500; color: var(--ad-color-danger);">Call Mom</div>
-              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 2 weeks</div>
+        <ul class="card pattern-list">
+          <li>
+            <button class="pattern-complete" data-tone="danger" aria-label="Complete"></button>
+            <div class="pattern-row">
+              <div class="pattern-row__title" data-tone="danger">Call Mom</div>
+              <div class="type-mono pattern-row__meta">every 2 weeks</div>
             </div>
-            <span class="type-mono" style="color: var(--ad-color-danger); font-size: var(--ad-step--2); white-space:nowrap;">3d overdue</span>
+            <span class="type-mono pattern-row__trailing" data-tone="danger">3d overdue</span>
           </li>
           <li>
-            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-danger);"></button>
-            <div style="flex:1; min-width:0;">
-              <div style="font-weight:500; color: var(--ad-color-danger);">Water the ferns</div>
-              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 5 days</div>
+            <button class="pattern-complete" data-tone="danger" aria-label="Complete"></button>
+            <div class="pattern-row">
+              <div class="pattern-row__title" data-tone="danger">Water the ferns</div>
+              <div class="type-mono pattern-row__meta">every 5 days</div>
             </div>
-            <span class="type-mono" style="color: var(--ad-color-danger); font-size: var(--ad-step--2); white-space:nowrap;">1d overdue</span>
+            <span class="type-mono pattern-row__trailing" data-tone="danger">1d overdue</span>
           </li>
         </ul>
       </section>
-      <section>
-        <div class="type-label" style="margin-bottom: var(--ad-space-s);">Upcoming</div>
-        <ul class="card" style="border:none; border-radius:0; background:none;">
-          <li style="border-top: 1px solid var(--ad-color-border-hairline);">
-            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-text-secondary);"></button>
-            <div style="flex:1; min-width:0;">
-              <div style="font-weight:500;">Renew passport</div>
-              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 10 years</div>
+      <section class="pattern-section">
+        <div class="type-label pattern-aside__label">Upcoming</div>
+        <ul class="card pattern-list">
+          <li>
+            <button class="pattern-complete" aria-label="Complete"></button>
+            <div class="pattern-row">
+              <div class="pattern-row__title">Renew passport</div>
+              <div class="type-mono pattern-row__meta">every 10 years</div>
             </div>
-            <span class="type-mono" style="color: var(--ad-color-text-secondary); font-size: var(--ad-step--2); white-space:nowrap;">in 3 months</span>
+            <span class="type-mono pattern-row__trailing" data-tone="secondary">in 3 months</span>
           </li>
           <li>
-            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-text-secondary);"></button>
-            <div style="flex:1; min-width:0;">
-              <div style="font-weight:500;">Dentist checkup</div>
-              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 6 months</div>
+            <button class="pattern-complete" aria-label="Complete"></button>
+            <div class="pattern-row">
+              <div class="pattern-row__title">Dentist checkup</div>
+              <div class="type-mono pattern-row__meta">every 6 months</div>
             </div>
-            <span class="type-mono" style="color: var(--ad-color-text-secondary); font-size: var(--ad-step--2); white-space:nowrap;">in 2 weeks</span>
+            <span class="type-mono pattern-row__trailing" data-tone="secondary">in 2 weeks</span>
           </li>
           <li>
-            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-text-secondary);"></button>
-            <div style="flex:1; min-width:0;">
-              <div style="font-weight:500;">Rotate mattress</div>
-              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 6 months</div>
+            <button class="pattern-complete" aria-label="Complete"></button>
+            <div class="pattern-row">
+              <div class="pattern-row__title">Rotate mattress</div>
+              <div class="type-mono pattern-row__meta">every 6 months</div>
             </div>
-            <span class="type-mono" style="color: var(--ad-color-text-secondary); font-size: var(--ad-step--2); white-space:nowrap;">in 5 weeks</span>
+            <span class="type-mono pattern-row__trailing" data-tone="secondary">in 5 weeks</span>
           </li>
         </ul>
       </section>
     </div>
-    <aside style="width: 15rem; flex-shrink:0; background: var(--ad-color-surface-fill); border-left: 1px solid var(--ad-color-border-hairline); padding: var(--ad-space-l);">
-      <div class="type-label" style="margin-bottom: var(--ad-space-s);">This week</div>
-      <div style="display:flex; background: var(--ad-color-surface-card); border: 1px solid var(--ad-color-border-hairline); border-radius: var(--ad-radius-md); overflow:hidden; margin-bottom: var(--ad-space-l);">
-                                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
-          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">S</span>
-          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+    <aside class="pattern-dashboard__aside">
+      <div class="type-label pattern-aside__label">This week</div>
+      <div class="pattern-week">
+        <div class="pattern-week__day">
+          <span class="type-mono pattern-week__label">S</span>
+          <span class="pattern-week__value">0</span>
         </div>
-                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
-          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">M</span>
-          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">1</span>
+        <div class="pattern-week__day">
+          <span class="type-mono pattern-week__label">M</span>
+          <span class="pattern-week__value">1</span>
         </div>
-                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
-          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">T</span>
-          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+        <div class="pattern-week__day">
+          <span class="type-mono pattern-week__label">T</span>
+          <span class="pattern-week__value">0</span>
         </div>
-                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0; background: var(--ad-color-accent-soft); border-right: 1px solid var(--ad-color-border-hairline);">
-          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">W</span>
-          <span style="font-size:13px; font-weight:600; color: var(--ad-color-accent-ink);">2</span>
+        <div class="pattern-week__day" data-active>
+          <span class="type-mono pattern-week__label">W</span>
+          <span class="pattern-week__value">2</span>
         </div>
-                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
-          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">T</span>
-          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+        <div class="pattern-week__day">
+          <span class="type-mono pattern-week__label">T</span>
+          <span class="pattern-week__value">0</span>
         </div>
-                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
-          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">F</span>
-          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">1</span>
+        <div class="pattern-week__day">
+          <span class="type-mono pattern-week__label">F</span>
+          <span class="pattern-week__value">1</span>
         </div>
-                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  ">
-          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">S</span>
-          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+        <div class="pattern-week__day">
+          <span class="type-mono pattern-week__label">S</span>
+          <span class="pattern-week__value">0</span>
         </div>
-              </div>
-      <div class="type-label" style="margin-bottom: var(--ad-space-2xs);">Series</div>
+      </div>
+      <div class="type-label pattern-aside__label--tight">Series</div>
       <div>
-        <div style="padding: var(--ad-space-2xs) 0; font-size: var(--ad-step--1); color: var(--ad-color-text-secondary);">Call Mom</div>
-        <div style="padding: var(--ad-space-2xs) 0; border-top: 1px solid var(--ad-color-border-hairline); font-size: var(--ad-step--1); color: var(--ad-color-text-secondary);">Water the ferns</div>
-        <div style="padding: var(--ad-space-2xs) 0; border-top: 1px solid var(--ad-color-border-hairline); font-size: var(--ad-step--1); color: var(--ad-color-text-secondary);">Renew passport</div>
+        <div class="pattern-series-item">Call Mom</div>
+        <div class="pattern-series-item">Water the ferns</div>
+        <div class="pattern-series-item">Renew passport</div>
       </div>
     </aside>
   </div>
@@ -134,7 +135,7 @@ couple of inline widths.
   <dialog open style="width: 22rem;">
     <header>New series</header>
     <div>
-      <div style="display:flex; flex-direction:column; gap: var(--ad-space-s);">
+      <div class="field-stack">
         <label class="field">
           Note
           <input placeholder="Call Mom" />
diff --git a/_sass/components/field.css b/_sass/components/field.css
index b92908b..e3aa192 100644
--- a/_sass/components/field.css
+++ b/_sass/components/field.css
@@ -184,6 +184,9 @@ form {
   grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
   gap: var(--ad-space-xs);
 }
+/* Vertically stacked fields — the other half of form layout alongside
+   .form-row's side-by-side pair. */
+.field-stack { display: flex; flex-direction: column; gap: var(--ad-space-s); }
 fieldset {
   display: flex;
   flex-direction: column;
diff --git a/_sass/site/patterns.css b/_sass/site/patterns.css
new file mode 100644
index 0000000..99c5567
--- /dev/null
+++ b/_sass/site/patterns.css
@@ -0,0 +1,193 @@
+/* Dedicated CSS for the two reference patterns (Loop, Archive) — this is
+   what an actual project built on this system would write: real classes for
+   the page-specific shapes (an app shell, a phone frame, a status-strip
+   day), composed from the same var(--ad-*) tokens every component reads,
+   rather than hand-styling every element inline. Nothing here is a system
+   component — see _sass/components/ for those — this is what sits between
+   them on a real screen. */
+
+/* -- Loop (dashboard) ----------------------------------------------------- */
+
+.pattern-dashboard {
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  overflow: hidden;
+  background: var(--ad-color-surface-page);
+}
+.pattern-dashboard__header {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-s);
+  padding: var(--ad-space-s) var(--ad-space-l);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.pattern-dashboard__title {
+  font-family: var(--ad-font-mono);
+  font-weight: 600;
+  letter-spacing: 0.02em;
+  font-size: var(--ad-step-0);
+}
+.pattern-dashboard__body { display: flex; }
+.pattern-dashboard__main {
+  flex: 1;
+  min-width: 0;
+  max-width: 34rem;
+  padding: var(--ad-space-l);
+}
+.pattern-dashboard__aside {
+  width: 15rem;
+  flex-shrink: 0;
+  background: var(--ad-color-surface-fill);
+  border-left: 1px solid var(--ad-color-border-hairline);
+  padding: var(--ad-space-l);
+}
+.pattern-spacer { flex: 1; }
+
+.pattern-section { margin-bottom: var(--ad-space-l); }
+.pattern-section:last-child { margin-bottom: 0; }
+.pattern-section__heading {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  margin-bottom: var(--ad-space-s);
+}
+
+/* A section list without Card's own border/background — the divider
+   between rows still comes from `.card > li`; only the outer frame is
+   suppressed, since the dashboard's own border already contains it. */
+.pattern-list { border: none; border-radius: 0; background: none; }
+.pattern-list li:first-child { border-top: 1px solid var(--ad-color-border-hairline); }
+
+.pattern-complete {
+  all: unset;
+  width: 18px;
+  height: 18px;
+  border-radius: 4px;
+  flex-shrink: 0;
+  cursor: pointer;
+  border: 1.5px solid var(--ad-color-text-secondary);
+}
+.pattern-complete[data-tone="danger"] { border-color: var(--ad-color-danger); }
+
+.pattern-row { flex: 1; min-width: 0; }
+.pattern-row__title { font-weight: 500; }
+.pattern-row__title[data-tone="danger"] { color: var(--ad-color-danger); }
+.pattern-row__meta { color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2); }
+.pattern-row__trailing { font-size: var(--ad-step--2); white-space: nowrap; }
+.pattern-row__trailing[data-tone="danger"] { color: var(--ad-color-danger); }
+.pattern-row__trailing[data-tone="secondary"] { color: var(--ad-color-text-secondary); }
+
+.pattern-week {
+  display: flex;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  overflow: hidden;
+  margin-bottom: var(--ad-space-l);
+}
+.pattern-week__day {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 4px;
+  padding: 8px 0;
+  border-right: 1px solid var(--ad-color-border-hairline);
+}
+.pattern-week__day:last-child { border-right: none; }
+.pattern-week__day[data-active] { background: var(--ad-color-accent-soft); }
+.pattern-week__label {
+  font-size: 9px;
+  color: var(--ad-color-text-tertiary);
+  text-transform: uppercase;
+}
+.pattern-week__value { font-size: 13px; font-weight: 600; color: var(--ad-color-text-primary); }
+.pattern-week__day[data-active] .pattern-week__value { color: var(--ad-color-accent-ink); }
+
+.pattern-aside__label { margin-bottom: var(--ad-space-s); }
+.pattern-aside__label--tight { margin-bottom: var(--ad-space-2xs); }
+
+.pattern-series-item {
+  padding: var(--ad-space-2xs) 0;
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-secondary);
+}
+.pattern-series-item:not(:first-child) { border-top: 1px solid var(--ad-color-border-hairline); }
+
+/* -- Archive (mobile) ------------------------------------------------------ */
+
+.pattern-phone {
+  width: 300px;
+  height: 560px;
+  background: var(--ad-color-surface-page);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  position: relative;
+}
+.pattern-phone__header {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  padding: 16px var(--ad-space-m) var(--ad-space-2xs);
+}
+/* The home screen's app-level wordmark — one step larger than a page's own
+   contextual title next to a back button. */
+.pattern-phone__brand { font-weight: 600; font-size: var(--ad-step-1); letter-spacing: -0.01em; }
+.pattern-phone__title { font-weight: 600; font-size: var(--ad-step-0); }
+.pattern-phone__body {
+  flex: 1;
+  overflow: hidden;
+  padding: 0 var(--ad-space-m) var(--ad-space-l);
+}
+/* The home screen's list runs under a floating capture dock instead of
+   ending in its own bottom padding. */
+.pattern-phone__body--dock { padding-bottom: 0; }
+
+.pattern-list-heading {
+  display: flex;
+  align-items: baseline;
+  gap: 8px;
+  margin: var(--ad-space-s) 0 var(--ad-space-xs);
+}
+.pattern-list-heading__title { font-weight: 700; font-size: var(--ad-step-0); }
+.pattern-list-heading .type-label { margin-left: auto; }
+
+.pattern-dock {
+  position: absolute;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  display: flex;
+  justify-content: center;
+  padding: 14px 20px 22px;
+  background: linear-gradient(to top, var(--ad-color-surface-page) 65%, transparent);
+}
+
+/* The one patterned background this system permits, and only here: an
+   empty photo slot. */
+.pattern-photo-slot {
+  height: 180px;
+  border-radius: var(--ad-radius-lg);
+  border: 1px solid var(--ad-color-border-default);
+  background: repeating-linear-gradient(45deg, transparent 0 8px, var(--ad-color-surface-fill-2) 8px 9px),
+              var(--ad-color-surface-fill);
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  gap: 6px;
+  margin-top: var(--ad-space-s);
+}
+
+.pattern-detail-title { font-weight: 700; font-size: var(--ad-step-2); letter-spacing: -0.01em; margin: var(--ad-space-xs) 0 var(--ad-space-2xs); }
+.pattern-tag-row { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: var(--ad-space-m); }
+
+.pattern-file-title { font-weight: 550; font-size: var(--ad-step--1); }
+.pattern-file-title--truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+.pattern-file-meta { margin-top: 2px; }
+
+.pattern-phone__footer { padding: var(--ad-space-m); display: flex; gap: var(--ad-space-2xs); }
+.pattern-phone__footer button { flex: 1; }
diff --git a/lib/build.rb b/lib/build.rb
index 5a56bb7..2a7bee1 100644
--- a/lib/build.rb
+++ b/lib/build.rb
@@ -54,6 +54,7 @@ CSS_FILES = %w[
   site/shell.css
   site/example.css
   site/tokens-docs.css
+  site/patterns.css
 ].freeze
 
 # [source file (absolute or relative to ROOT), url, section label for the