Move repeated inline CSS into the Card and callout component styles
Every card-grid across the site (rationale.md, index.md, and several
foundation pages) repeated the identical inline style on every h3
("margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);") and
every p in a .card-body — that's not a demo-specific value, it's
Card's own default heading/body typography, so it belongs in
_sass/components/card.css as .card-body h3 / .card-body p, alongside
the sanctioned .card-body/.card-footer classes already documented
there. Same for .ad-callout's two-paragraph pattern (a type-label line
plus a body line), repeated identically 10 times across five files —
now .ad-callout p / .ad-callout .type-label in tokens-docs.css.

Also found and fixed input.md's focus-state demo, which hand-duplicated
the exact values already in field.css's real input:focus rule.

Left alone: the ~95 inline styles on color.md's swatches and space.md's
ruler bars, which show a literal per-item value (a hex, a clamp() width)
that IS the content being demonstrated, not a decoration standing in for
a missing class.

Verified: rake build succeeds, screenshots of Card, CardRow, Space,
Elevation, and Rationale (the heaviest card-grid/callout users) show no
visual change.
change
commit b4bdcedfc59389e4ca9e2e1d3075fd6044eccb80
author Claude <noreply@anthropic.com>
date
parent 7f312754
diff --git a/_components/button.md b/_components/button.md
index 4dd42c6..0cd2840 100644
--- a/_components/button.md
+++ b/_components/button.md
@@ -68,8 +68,8 @@ disabled primary still reads as the primary.
 </figure>
 
 <div class="ad-callout">
-  <p class="type-label" style="margin-bottom: var(--ad-space-2xs); display:block;">disabled vs. aria-disabled</p>
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p class="type-label">disabled vs. aria-disabled</p>
+  <p>
     A <code>disabled</code> button is removed from the tab order, so a reader
     navigating by keyboard never learns it is there. When a button is
     temporarily unavailable and the reason matters, use
diff --git a/_components/card.md b/_components/card.md
index 52ca02a..e568eb6 100644
--- a/_components/card.md
+++ b/_components/card.md
@@ -35,8 +35,8 @@ it that has no element of its own to hang a selector on.
 <article class="card" style="max-width: 18rem;">
   <div class="card-body">
     <p class="type-label" style="margin:0;">Recommended</p>
-    <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);">Rename the caution color</h3>
-    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">Three people have called it "yellow" in review this month.</p>
+    <h3>Rename the caution color</h3>
+    <p>Three people have called it "yellow" in review this month.</p>
   </div>
   <div class="card-footer">
     <button data-variant="primary" data-size="sm">Approve</button>
@@ -48,8 +48,8 @@ it that has no element of its own to hang a selector on.
 <pre><code>&lt;article class=&quot;card&quot; style=&quot;max-width: 18rem;&quot;&gt;
   &lt;div class=&quot;card-body&quot;&gt;
     &lt;p class=&quot;type-label&quot; style=&quot;margin:0;&quot;&gt;Recommended&lt;/p&gt;
-    &lt;h3 style=&quot;margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);&quot;&gt;Rename the caution color&lt;/h3&gt;
-    &lt;p style=&quot;margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);&quot;&gt;Three people have called it &quot;yellow&quot; in review this month.&lt;/p&gt;
+    &lt;h3&gt;Rename the caution color&lt;/h3&gt;
+    &lt;p&gt;Three people have called it &quot;yellow&quot; in review this month.&lt;/p&gt;
   &lt;/div&gt;
   &lt;div class=&quot;card-footer&quot;&gt;
     &lt;button data-variant=&quot;primary&quot; data-size=&quot;sm&quot;&gt;Approve&lt;/button&gt;
diff --git a/_components/select.md b/_components/select.md
index dc76c73..84ef5a7 100644
--- a/_components/select.md
+++ b/_components/select.md
@@ -40,7 +40,7 @@ summary: Native select, styled to match Input exactly.
 </figure>
 
 <div class="ad-callout">
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p>
     The chevron is the one place in this component set that cannot reach a
     <code>var(--ad-*)</code> token — a data-URI <code>background-image</code>
     cannot reference a custom property, so its stroke is a literal hex, kept
diff --git a/_foundations/color.md b/_foundations/color.md
index 5c6e35b..f35d6e1 100644
--- a/_foundations/color.md
+++ b/_foundations/color.md
@@ -19,7 +19,7 @@ reads from these. Retheming, or switching to dark, means repointing aliases
 at different values — which is exactly what the dark block does.
 
 <div class="ad-callout">
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p>
     The neutral ramps were authored in <code>oklch()</code>. Every value
     below is that same color converted to flat sRGB hex — not re-picked,
     not rounded. The contrast figures on this page are computed from those
@@ -215,7 +215,7 @@ the default; the other four are the sanctioned menu a project can switch to.
 </ul>
 
 <div class="ad-callout">
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p>
     All five clear AA (4.5:1) for white text at their own value, but Ochre is
     the tightest of the five at roughly 4.6:1 — closer to the floor than the
     others (Ink Blue and Plum both clear 8.5:1). That is a real property of a
@@ -623,7 +623,7 @@ and checked by hand rather than by a build-time test.
   </table>
 
 <div class="ad-callout">
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p>
     Two things this contract deliberately does not assert.
     <strong>Text tertiary</strong> — <code>--ad-color-text-tertiary</code>
     (neutral.500) is roughly 3.46:1 against the page in light mode, under the
diff --git a/_foundations/elevation.md b/_foundations/elevation.md
index d64904e..960744c 100644
--- a/_foundations/elevation.md
+++ b/_foundations/elevation.md
@@ -31,14 +31,14 @@ is the default everywhere. Shadow is the exception, not the baseline.
 <div data-layout="grid" data-surface="sunken">
 <article class="card">
   <div class="card-body">
-    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Flat</h3>
-    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">The default. A hairline border, no shadow.</p>
+    <h3 style="font-size: var(--ad-step--1);">Flat</h3>
+    <p>The default. A hairline border, no shadow.</p>
   </div>
 </article>
 <article class="card" data-elevated>
   <div class="card-body">
-    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Elevated</h3>
-    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">shadow-float. Reserved for one element per view — a Dialog, a Toast.</p>
+    <h3 style="font-size: var(--ad-step--1);">Elevated</h3>
+    <p>shadow-float. Reserved for one element per view — a Dialog, a Toast.</p>
   </div>
 </article>
 </div>
diff --git a/_foundations/space.md b/_foundations/space.md
index 24eba63..71d51f9 100644
--- a/_foundations/space.md
+++ b/_foundations/space.md
@@ -73,20 +73,20 @@ summary: >-
 <div data-layout="grid">
 <article class="card">
   <div class="card-body" style="gap: var(--ad-space-3xs); padding: var(--ad-space-xs);">
-    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Compact</h3>
-    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">space-xs padding, space-3xs gap. For dense lists.</p>
+    <h3 style="font-size: var(--ad-step--1);">Compact</h3>
+    <p>space-xs padding, space-3xs gap. For dense lists.</p>
   </div>
 </article>
 <article class="card">
   <div class="card-body">
-    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Default</h3>
-    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">space-m padding, space-2xs gap. What Card ships with.</p>
+    <h3 style="font-size: var(--ad-step--1);">Default</h3>
+    <p>space-m padding, space-2xs gap. What Card ships with.</p>
   </div>
 </article>
 <article class="card">
   <div class="card-body" style="gap: var(--ad-space-s); padding: var(--ad-space-l);">
-    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Roomy</h3>
-    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">space-l padding, space-s gap. For a card that is the whole screen.</p>
+    <h3 style="font-size: var(--ad-step--1);">Roomy</h3>
+    <p>space-l padding, space-s gap. For a card that is the whole screen.</p>
   </div>
 </article>
 </div>
diff --git a/_sass/components/card.css b/_sass/components/card.css
index e82eac9..c5c7ff9 100644
--- a/_sass/components/card.css
+++ b/_sass/components/card.css
@@ -77,6 +77,8 @@
   gap: var(--ad-space-2xs);
   padding: var(--ad-space-m);
 }
+.card-body h3 { margin: 0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+.card-body p { margin: 0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1); }
 .card-footer {
   display: flex;
   flex-wrap: wrap;
diff --git a/_sass/site/tokens-docs.css b/_sass/site/tokens-docs.css
index dd9d962..4388f8a 100644
--- a/_sass/site/tokens-docs.css
+++ b/_sass/site/tokens-docs.css
@@ -162,6 +162,8 @@
   border-radius: var(--ad-radius-md);
   background: var(--ad-color-surface-fill);
 }
+.ad-callout p { margin: 0; font-size: var(--ad-step--1); }
+.ad-callout .type-label { display: block; margin-bottom: var(--ad-space-2xs); }
 /* Generic reference tables (component APIs, alias tables, the contrast
    contract). `<table>` IS a table — no class needed to say so. Every table
    on this site uses the one compact density, so there is no separate
diff --git a/index.md b/index.md
index 8eb420a..8b60c97 100644
--- a/index.md
+++ b/index.md
@@ -52,8 +52,8 @@ same afternoon.
 <div class="card-grid">
   <article class="card" data-link>
     <div class="card-body">
-      <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);"><a href="<%= relative_url('/foundations/color/') %>">Foundations</a></h3>
-      <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+      <h3><a href="<%= relative_url('/foundations/color/') %>">Foundations</a></h3>
+      <p>
         Color, type, space, elevation, and motion — with contrast ratios
         computed from the tokens and checked by hand, not typed by guess.
       </p>
@@ -61,8 +61,8 @@ same afternoon.
   </article>
   <article class="card" data-link>
     <div class="card-body">
-      <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);"><a href="<%= relative_url('/components/button/') %>">Components</a></h3>
-      <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+      <h3><a href="<%= relative_url('/components/button/') %>">Components</a></h3>
+      <p>
         Sixteen components across core, forms, feedback, and navigation, each
         rendered live next to the exact markup that produced it.
       </p>
@@ -70,8 +70,8 @@ same afternoon.
   </article>
   <article class="card" data-link>
     <div class="card-body">
-      <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);"><a href="<%= relative_url('/patterns/loop/') %>">Patterns</a></h3>
-      <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+      <h3><a href="<%= relative_url('/patterns/loop/') %>">Patterns</a></h3>
+      <p>
         Loop and Archive — a task dashboard and a capture app — put every
         component family in one screen at once.
       </p>
@@ -90,8 +90,8 @@ same afternoon.
       <span class="badge" data-tone="accent">Recommended</span>
       <span class="badge">Unassigned</span>
     </div>
-    <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);">Rename the caution color</h3>
-    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+    <h3>Rename the caution color</h3>
+    <p>
       Three people have called it "yellow" in review this month. There is no
       caution token in this system — only <code>--ad-color-success</code> and
       <code>--ad-color-danger</code>, fixed across every project.
diff --git a/install.md b/install.md
index a7798f8..4264953 100644
--- a/install.md
+++ b/install.md
@@ -71,7 +71,7 @@ a handful of custom properties after the token file loads — most of all,
 ```
 
 <div class="ad-callout">
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p>
     Re-check contrast after retheming. The system's contrast guarantees on
     the <a href="<%= relative_url('/foundations/color/') %>">Color page</a>
     are about the system's own values — swap the accent and you own the
diff --git a/rationale.md b/rationale.md
index 8162af1..08faf71 100644
--- a/rationale.md
+++ b/rationale.md
@@ -25,8 +25,8 @@ Not the quality of the individual choices. The properties below:
 <div class="card-grid">
   <article class="card">
     <div class="card-body">
-      <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);">It is written down once</h3>
-      <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+      <h3>It is written down once</h3>
+      <p>
         One hand-maintained stylesheet of custom properties. Not a Figma
         library that disagrees with the CSS, and not a spreadsheet somebody
         exports by hand.
@@ -35,8 +35,8 @@ Not the quality of the individual choices. The properties below:
   </article>
   <article class="card">
     <div class="card-body">
-      <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);">It has names</h3>
-      <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+      <h3>It has names</h3>
+      <p>
         <code>--ad-color-danger</code> survives a change of mind about which
         red. <code>#ad3a2c</code> does not.
       </p>
@@ -44,8 +44,8 @@ Not the quality of the individual choices. The properties below:
   </article>
   <article class="card">
     <div class="card-body">
-      <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);">It is actually used</h3>
-      <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+      <h3>It is actually used</h3>
+      <p>
         Every color, type, spacing, radius, elevation, and motion value in
         the components is a <code>var(--ad-*)</code>. Not one is a literal.
       </p>
@@ -53,8 +53,8 @@ Not the quality of the individual choices. The properties below:
   </article>
   <article class="card">
     <div class="card-body">
-      <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);">It can be changed</h3>
-      <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">
+      <h3>It can be changed</h3>
+      <p>
         Because of the three above, swapping the accent for Clay, Ochre, Ink
         Blue, or Plum is a one-line diff.
       </p>
@@ -88,8 +88,8 @@ borders do the elevation work, not high contrast, so it does not invent a
 ## The four rules
 
 <div class="ad-callout">
-  <p class="type-label" style="margin-bottom: var(--ad-space-2xs); display:block;">1. No color and no duration outside tokens.css</p>
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p class="type-label">1. No color and no duration outside tokens.css</p>
+  <p>
     A hex or a duration in a component stylesheet is a decision made in the
     dark, and it is the kind that breaks the moment somebody adds a theme. No
     component stylesheet in this repository contains either; the one flagged
@@ -99,8 +99,8 @@ borders do the elevation work, not high contrast, so it does not invent a
 </div>
 
 <div class="ad-callout">
-  <p class="type-label" style="margin-bottom: var(--ad-space-2xs); display:block;">2. Components read aliases, never ramps</p>
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p class="type-label">2. Components read aliases, never ramps</p>
+  <p>
     <code>--ad-color-text-primary</code>, not <code>--ad-neutral-900</code>.
     The ramp is raw material; the alias is the decision. This is the whole
     reason the dark theme is a block of repointed aliases rather than a
@@ -109,8 +109,8 @@ borders do the elevation work, not high contrast, so it does not invent a
 </div>
 
 <div class="ad-callout">
-  <p class="type-label" style="margin-bottom: var(--ad-space-2xs); display:block;">3. Every token says what it is for</p>
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p class="type-label">3. Every token says what it is for</p>
+  <p>
     Every semantic alias on the <a href="<%= relative_url('/foundations/color/') %>">Color page</a>
     carries a usage note. A token nobody can describe is a token nobody will
     use correctly.
@@ -118,8 +118,8 @@ borders do the elevation work, not high contrast, so it does not invent a
 </div>
 
 <div class="ad-callout">
-  <p class="type-label" style="margin-bottom: var(--ad-space-2xs); display:block;">4. One accent, one dark-mode convention</p>
-  <p style="margin:0; font-size: var(--ad-step--1);">
+  <p class="type-label">4. One accent, one dark-mode convention</p>
+  <p>
     Never two accents in one view. Dark mode is opt-in — a
     <code>data-theme</code> toggle plus <code>prefers-color-scheme</code>,
     never inherited silently from the OS alone.