Warm Editorial — surfaces
The workhorse surface of this language. 28px corners, a hairline border, near-invisible shadow, and an image that keeps a margin from the card edge rather than bleeding to it.
Paste this into Claude, Cursor or Copilot — or point the agent at
https://ui-deploy.com/r/warm-editorial/card/prompt.md
# Editorial Card — Warm Editorial
Paste this whole file into Claude, Cursor or Copilot.
---
## What to build
The workhorse surface of this language. A raised warm panel with **28px corners**,
a hairline border, and a shadow so soft it reads as depth rather than as a shadow.
Order inside the card: image, eyebrow, title, body, link. The link sits at the
bottom on `margin-top:auto` so cards of unequal text still align their footers.
Cards sit in an auto-fit grid with a 24px gap.
---
## Tokens
```css
:root{
--bg2:#F6F3ED; --bg3:#E4DED2; --border:#DAD3C6;
--text:#22201D; --text2:#5C574F;
--accent:#A38A6A; --accent-text:#7D6644; --accent-b:rgba(163,138,106,.30);
--radius:28px; --radius-md:16px;
--shadow-sm:0 1px 2px rgba(34,32,29,.05);
--shadow-md:0 18px 48px -24px rgba(34,32,29,.22);
--font-display:'Inter Tight',system-ui,sans-serif;
--font-body:'Inter',system-ui,sans-serif;
--ease:cubic-bezier(.22,.61,.36,1);
}
[data-theme="dark"]{
--bg2:#1E1A17; --bg3:#262119; --border:#2E2822;
--text:#EDE7DD; --text2:#A79E92;
--accent:#B39B7C; --accent-text:#C0A888; --accent-b:rgba(179,155,124,.28);
--shadow-sm:0 1px 2px rgba(0,0,0,.4);
--shadow-md:0 18px 48px -24px rgba(0,0,0,.7);
}
```
---
## Rules — these are not preferences
1. **The image stays inside the padding.** It takes `--radius-md` (16px) and keeps
a margin from the card edge. Bleeding an image to the card border belongs to a
harder design language, not this one.
2. **Card corners are 28px.** Not 8, not 12. Large and soft is the whole point.
3. **No hard drop shadow.** `--shadow-sm` at rest, `--shadow-md` on hover — both
wide and nearly invisible. A crisp shadow makes this palette look cheap.
4. **Hover is: border to `--accent-b`, shadow to `--shadow-md`, `translateY(-2px)`.**
All three, or none.
5. **The eyebrow is `--accent-text`, never `--accent`.** At 11.5px the fill bronze
does not clear AA.
6. **Body text stops at ~60ch.** Longer measures break the editorial rhythm.
7. Make the whole card clickable with `::after{inset:0}` on the link rather than
wrapping the heading in an anchor — it keeps the heading in the outline for
screen readers.
8. Give every image real `alt` text, `loading="lazy"` and explicit dimensions.
---
## Reference implementation
See `code.html` in this component folder. Swap the Unsplash URLs for your own
images; keep the `aspect-ratio` so the grid stays even.
Paste this whole file into Claude, Cursor or Copilot.
The workhorse surface of this language. A raised warm panel with 28px corners, a hairline border, and a shadow so soft it reads as depth rather than as a shadow.
Order inside the card: image, eyebrow, title, body, link. The link sits at the bottom on margin-top:auto so cards of unequal text still align their footers.
Cards sit in an auto-fit grid with a 24px gap.
:root{
--bg2:#F6F3ED; --bg3:#E4DED2; --border:#DAD3C6;
--text:#22201D; --text2:#5C574F;
--accent:#A38A6A; --accent-text:#7D6644; --accent-b:rgba(163,138,106,.30);
--radius:28px; --radius-md:16px;
--shadow-sm:0 1px 2px rgba(34,32,29,.05);
--shadow-md:0 18px 48px -24px rgba(34,32,29,.22);
--font-display:'Inter Tight',system-ui,sans-serif;
--font-body:'Inter',system-ui,sans-serif;
--ease:cubic-bezier(.22,.61,.36,1);
}
[data-theme="dark"]{
--bg2:#1E1A17; --bg3:#262119; --border:#2E2822;
--text:#EDE7DD; --text2:#A79E92;
--accent:#B39B7C; --accent-text:#C0A888; --accent-b:rgba(179,155,124,.28);
--shadow-sm:0 1px 2px rgba(0,0,0,.4);
--shadow-md:0 18px 48px -24px rgba(0,0,0,.7);
}
--radius-md (16px) and keeps a margin from the card edge. Bleeding an image to the card border belongs to a harder design language, not this one.--shadow-sm at rest, --shadow-md on hover — both wide and nearly invisible. A crisp shadow makes this palette look cheap.--accent-b, shadow to --shadow-md, translateY(-2px). All three, or none.--accent-text, never --accent. At 11.5px the fill bronze does not clear AA.::after{inset:0} on the link rather than wrapping the heading in an anchor — it keeps the heading in the outline for screen readers.alt text, loading="lazy" and explicit dimensions.See code.html in this component folder. Swap the Unsplash URLs for your own images; keep the aspect-ratio so the grid stays even.
<!-- Warm Editorial — Editorial card
Requires tokens.css. Corners are large and soft; the image sits inside
the card's padding rather than bleeding to its edge. -->
<div class="we-card-grid">
<article class="we-card">
<div class="we-card-media">
<img src="https://images.unsplash.com/photo-1540555700478-4be289fbecef?w=800&q=70"
alt="A quiet treatment room in warm daylight" loading="lazy" width="800" height="600">
</div>
<p class="we-card-eyebrow"><span aria-hidden="true"></span>Recovery</p>
<h3 class="we-card-title">Contrast therapy</h3>
<p class="we-card-body">
Alternating heat and cold, structured into a protocol your nervous system
can actually adapt to.
</p>
<a class="we-card-link" href="#contrast">
Read the protocol
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M5 12h14"/><path d="M13 6l6 6-6 6"/>
</svg>
</a>
</article>
<article class="we-card">
<div class="we-card-media">
<img src="https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=800&q=70"
alt="Hands resting during a breathing session" loading="lazy" width="800" height="600">
</div>
<p class="we-card-eyebrow"><span aria-hidden="true"></span>Nervous system</p>
<h3 class="we-card-title">Breath downshift</h3>
<p class="we-card-body">
Twenty minutes of guided work that moves you out of a sympathetic state and
keeps you there.
</p>
<a class="we-card-link" href="#breath">
Read the protocol
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M5 12h14"/><path d="M13 6l6 6-6 6"/>
</svg>
</a>
</article>
</div>
<style>
.we-card-grid{
display:grid;gap:24px;
grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));
max-width:76rem;margin:0 auto;padding:0 20px;
}
.we-card{
position:relative;display:flex;flex-direction:column;
background:var(--bg2);
border:1px solid var(--border);
border-radius:var(--radius);
padding:28px;
box-shadow:var(--shadow-sm);
transition:border-color .2s var(--ease), box-shadow .2s var(--ease),
transform .2s var(--ease);
}
.we-card:hover{
border-color:var(--accent-b);
box-shadow:var(--shadow-md);
transform:translateY(-2px);
}
/* The image keeps its own smaller radius and stays inside the card padding.
Bleeding it to the card edge belongs to a different, harder design language. */
.we-card-media{
border-radius:var(--radius-md);
overflow:hidden;
margin-bottom:22px;
background:var(--bg3);
aspect-ratio:4/3;
}
.we-card-media img{display:block;width:100%;height:100%;object-fit:cover}
.we-card-eyebrow{
display:flex;align-items:center;gap:7px;margin:0 0 10px;
font-family:var(--font-display);font-size:11.5px;font-weight:600;
letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);
}
.we-card-eyebrow span{
width:5px;height:5px;border-radius:50%;background:var(--accent);flex:0 0 5px;
}
.we-card-title{
font-family:var(--font-display);font-size:21px;font-weight:600;
letter-spacing:-.015em;line-height:1.2;color:var(--text);margin:0 0 10px;
}
.we-card-body{
margin:0 0 20px;font-size:14.5px;line-height:1.75;color:var(--text2);
max-width:60ch;
}
.we-card-link{
display:inline-flex;align-items:center;gap:7px;margin-top:auto;
font-size:14px;font-weight:500;color:var(--accent-text);text-decoration:none;
}
.we-card-link svg{width:15px;height:15px;transition:transform .2s var(--ease)}
.we-card:hover .we-card-link svg{transform:translateX(3px)}
/* Whole card is the click target, without nesting the heading inside a link. */
.we-card-link::after{content:'';position:absolute;inset:0;border-radius:var(--radius)}
.we-card-link:focus-visible{outline:none}
.we-card:has(.we-card-link:focus-visible){outline:2px solid var(--accent);outline-offset:3px}
@media (prefers-reduced-motion:reduce){
.we-card,.we-card-link svg{transition:none}
.we-card:hover{transform:none}
}
</style>
Needs tokens.css on the page.