26 examples Responsive beginner

26 CSS Accordions — Vertical & Horizontal

26 free CSS accordions — 17 vertical and 9 horizontal layouts. Each demo has a live preview and copy-paste HTML + CSS.

26 unique accordions 17 Vertical 9 Horizontal 26 Pure CSS WCAG-friendly MIT licensed
01 / 26
Underline Reveal
Pure CSS
What is CodeFronts?

A library of hand-crafted CSS components, generators and tools for developers who care about craft.

Is everything free?

Yes — MIT licensed for personal and commercial projects, no attribution required.

Does it use any frameworks?

No frameworks, no dependencies. Vanilla HTML, CSS and a tiny bit of JS where needed.

Vertical accordion with a left-anchored underline that grows across the open trigger.
.acc-uline { border-bottom: 1px solid rgba(156,123,214,0.18); }
.acc-uline summary {
  position: relative; cursor: pointer; list-style: none;
  padding: 14px 0; font: 600 13px/1.4 system-ui, sans-serif;
  color: rgba(240,238,255,0.62); transition: color .25s;
}
.acc-uline summary::-webkit-details-marker { display: none; }
.acc-uline summary::after {
  content: ''; position: absolute; left: 0; bottom: -1px;
  height: 2px; width: 0;
  background: linear-gradient(90deg, #9c7bd6, #d49a5c);
  transition: width .4s cubic-bezier(.2,.9,.3,1);
}
.acc-uline[open] summary { color: #f0eeff; }
.acc-uline[open] summary::after { width: 100%; }
.acc-uline p {
  margin: 0; padding: 10px 0 16px;
  font: 12px/1.6 system-ui, sans-serif; color: rgba(240,238,255,0.55);
}
<details class="acc-uline" name="acc-uline" open>
  <summary>What is CodeFronts?</summary>
  <p>A library of hand-crafted CSS components, generators and tools for developers who care about craft.</p>
</details>
<details class="acc-uline" name="acc-uline">
  <summary>Is everything free?</summary>
  <p>Yes — MIT licensed for personal and commercial projects, no attribution required.</p>
</details>
<details class="acc-uline" name="acc-uline">
  <summary>Does it use any frameworks?</summary>
  <p>No frameworks, no dependencies. Vanilla HTML, CSS and a tiny bit of JS where needed.</p>
</details>
02 / 26
Numbered Steps
Pure CSS
1 Install the package

Add the library to your project with one command — no build step required.

2 Import a component

Pull in only the components you need. Tree-shakable and zero runtime overhead.

3 Customize with tokens

Override CSS custom properties to match your brand colors and spacing scale.

Each row is a numbered step with a circular badge that fills amethyst when expanded.
.acc-step { margin-bottom: 8px; }
.acc-step summary {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer; list-style: none;
  padding: 12px 14px; border-radius: 10px;
  background: rgba(156,123,214,0.06);
  font: 600 13px/1.3 system-ui, sans-serif; color: rgba(240,238,255,0.75);
  transition: background .2s;
}
.acc-step summary::-webkit-details-marker { display: none; }
.acc-step__n {
  display: grid; place-items: center;
  width: 22px; height: 22px; border-radius: 50%;
  border: 1.5px solid rgba(156,123,214,0.5);
  font: 700 11px monospace; color: rgba(240,238,255,0.7);
  transition: all .25s;
}
.acc-step[open] > summary { background: rgba(156,123,214,0.16); color: #f0eeff; }
.acc-step[open] .acc-step__n { background: #9c7bd6; color: #fff; border-color: #9c7bd6; }
.acc-step p {
  margin: 8px 0 0; padding: 0 14px 12px 48px;
  font: 12px/1.6 system-ui, sans-serif; color: rgba(240,238,255,0.55);
}
<details class="acc-step" name="acc-step" open>
  <summary><span class="acc-step__n">1</span> Install the package</summary>
  <p>Add the library to your project with one command — no build step required.</p>
</details>
<details class="acc-step" name="acc-step">
  <summary><span class="acc-step__n">2</span> Import a component</summary>
  <p>Pull in only the components you need. Tree-shakable and zero runtime overhead.</p>
</details>
<details class="acc-step" name="acc-step">
  <summary><span class="acc-step__n">3</span> Customize with tokens</summary>
  <p>Override CSS custom properties to match your brand colors and spacing scale.</p>
</details>
03 / 26
Plus / Minus Morph
Pure CSS
Project setup

Drop the snippet into any HTML page — works with any framework or none at all.

Browser support

Modern evergreen browsers. Native <details> has shipped everywhere since 2020.

Theming

Override --acc-pm-accent on the parent to recolor the entire group instantly.

A pure-CSS plus icon that morphs into a minus when the row opens — both bars are pseudo-elements.
.acc-pm { --acc-pm-accent: #d49a5c;
  border: 1px solid rgba(212,154,92,0.18); border-radius: 10px;
  margin-bottom: 6px; overflow: hidden;
}
.acc-pm summary {
  display: flex; align-items: center; justify-content: space-between;
  cursor: pointer; list-style: none; padding: 13px 16px;
  font: 600 13px/1.3 system-ui, sans-serif; color: rgba(240,238,255,0.78);
}
.acc-pm summary::-webkit-details-marker { display: none; }
.acc-pm__ico {
  position: relative; width: 14px; height: 14px; flex-shrink: 0;
}
.acc-pm__ico::before, .acc-pm__ico::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  background: var(--acc-pm-accent); border-radius: 1px;
  transition: transform .35s cubic-bezier(.5,1.5,.5,1);
}
.acc-pm__ico::before { width: 100%; height: 2px; }
.acc-pm__ico::after  { width: 2px;  height: 100%; }
.acc-pm[open] .acc-pm__ico::after  { transform: rotate(90deg); }
.acc-pm[open] .acc-pm__ico::before { transform: rotate(180deg); }
.acc-pm[open] { background: rgba(212,154,92,0.05); }
.acc-pm p {
  margin: 0; padding: 0 16px 14px;
  font: 12px/1.6 system-ui, sans-serif; color: rgba(240,238,255,0.55);
}
<details class="acc-pm" name="acc-pm">
  <summary>Project setup<span class="acc-pm__ico" aria-hidden="true"></span></summary>
  <p>Drop the snippet into any HTML page — works with any framework or none at all.</p>
</details>
<details class="acc-pm" name="acc-pm" open>
  <summary>Browser support<span class="acc-pm__ico" aria-hidden="true"></span></summary>
  <p>Modern evergreen browsers. Native &lt;details&gt; has shipped everywhere since 2020.</p>
</details>
<details class="acc-pm" name="acc-pm">
  <summary>Theming<span class="acc-pm__ico" aria-hidden="true"></span></summary>
  <p>Override --acc-pm-accent on the parent to recolor the entire group instantly.</p>
</details>
04 / 26
Chevron Rotate
Pure CSS
How long does setup take?

Under five minutes. Copy the markup, paste the styles, you're done.

Can I use this commercially?

Yes — MIT licensed. Use it in client work, products, anywhere.

Is there a Figma version?

Not yet. Designs live in code as the source of truth.

A pure-CSS chevron arrow rotates 180° on open — built from a single bordered square.
.acc-chv {
  border-bottom: 1px solid rgba(143,179,163,0.18); padding: 4px 0;
}
.acc-chv summary {
  display: flex; align-items: center; justify-content: space-between;
  cursor: pointer; list-style: none; padding: 14px 4px;
  font: 600 13px/1.3 system-ui, sans-serif; color: rgba(240,238,255,0.7);
  transition: color .2s;
}
.acc-chv summary::-webkit-details-marker { display: none; }
.acc-chv summary:hover { color: #f0eeff; }
.acc-chv__ico {
  width: 9px; height: 9px;
  border-right: 2px solid #8fb3a3;
  border-bottom: 2px solid #8fb3a3;
  transform: rotate(45deg) translate(-2px,-2px);
  transition: transform .35s cubic-bezier(.4,1.4,.5,1);
  flex-shrink: 0;
}
.acc-chv[open] > summary { color: #f0eeff; }
.acc-chv[open] .acc-chv__ico {
  transform: rotate(225deg) translate(-2px,-2px);
}
.acc-chv p {
  margin: 0 0 12px; padding: 0 4px;
  font: 12px/1.6 system-ui, sans-serif; color: rgba(240,238,255,0.55);
}
<details class="acc-chv" name="acc-chv">
  <summary>How long does setup take?<span class="acc-chv__ico" aria-hidden="true"></span></summary>
  <p>Under five minutes. Copy the markup, paste the styles, you're done.</p>
</details>
<details class="acc-chv" name="acc-chv" open>
  <summary>Can I use this commercially?<span class="acc-chv__ico" aria-hidden="true"></span></summary>
  <p>Yes — MIT licensed. Use it in client work, products, anywhere.</p>
</details>
<details class="acc-chv" name="acc-chv">
  <summary>Is there a Figma version?<span class="acc-chv__ico" aria-hidden="true"></span></summary>
  <p>Not yet. Designs live in code as the source of truth.</p>
</details>
05 / 26
Brutalist Stamp
Pure CSS
RAW PRINCIPLES

No gradients. No shadows blurred soft. Just hard rectangles, two colors, and intent.

NO COMPROMISE

Function leads form. Form documents function. Decoration earns its keep or it leaves.

BUILT TO LAST

Heavy structure ages well. Trends fade. A clear typographic system stays useful.

Heavy-bordered, rectangular accordion with a hard offset shadow that flips on open.
.acc-brut {
  background: #f0eeff; color: #15151d;
  border: 2px solid #15151d;
  box-shadow: 4px 4px 0 #9c7bd6;
  margin-bottom: 12px;
  transition: box-shadow .15s, transform .15s;
}
.acc-brut summary {
  cursor: pointer; list-style: none; padding: 13px 16px;
  font: 800 12px/1 system-ui, sans-serif; letter-spacing: 0.12em;
  border-bottom: 2px solid transparent;
}
.acc-brut summary::-webkit-details-marker { display: none; }
.acc-brut[open] {
  box-shadow: 2px 2px 0 #9c7bd6;
  transform: translate(2px,2px);
}
.acc-brut[open] summary { border-bottom-color: #15151d; }
.acc-brut p {
  margin: 0; padding: 14px 16px;
  font: 12px/1.6 system-ui, sans-serif;
}
<details class="acc-brut" name="acc-brut" open>
  <summary>RAW PRINCIPLES</summary>
  <p>No gradients. No shadows blurred soft. Just hard rectangles, two colors, and intent.</p>
</details>
<details class="acc-brut" name="acc-brut">
  <summary>NO COMPROMISE</summary>
  <p>Function leads form. Form documents function. Decoration earns its keep or it leaves.</p>
</details>
<details class="acc-brut" name="acc-brut">
  <summary>BUILT TO LAST</summary>
  <p>Heavy structure ages well. Trends fade. A clear typographic system stays useful.</p>
</details>
06 / 26
Glass Frosted
Pure CSS
What's inside?

A frosted surface with a subtle border that catches light when the row expands.

Does blur cost performance?

backdrop-filter is GPU-accelerated. Use it on small islands rather than wide swaths.

Browser fallback?

The semi-transparent background still reads gracefully without the blur effect.

Frosted-glass card accordion with backdrop-blur and a luminous rim that brightens on open.
.acc-glass {
  background: linear-gradient(135deg, rgba(156,123,214,0.07), rgba(143,179,163,0.05));
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border: 1px solid rgba(240,238,255,0.08);
  border-radius: 14px; margin-bottom: 8px;
  transition: border-color .3s, background .3s;
}
.acc-glass summary {
  display: flex; align-items: center; justify-content: space-between;
  cursor: pointer; list-style: none; padding: 14px 18px;
  font: 600 13px/1.3 system-ui, sans-serif; color: rgba(240,238,255,0.82);
}
.acc-glass summary::-webkit-details-marker { display: none; }
.acc-glass__caret {
  width: 6px; height: 6px;
  border-right: 1.5px solid rgba(240,238,255,0.5);
  border-bottom: 1.5px solid rgba(240,238,255,0.5);
  transform: rotate(45deg); transition: transform .3s;
}
.acc-glass[open] {
  border-color: rgba(156,123,214,0.45);
  background: linear-gradient(135deg, rgba(156,123,214,0.14), rgba(143,179,163,0.08));
}
.acc-glass[open] .acc-glass__caret { transform: rotate(225deg); }
.acc-glass p {
  margin: 0; padding: 0 18px 16px;
  font: 12px/1.6 system-ui, sans-serif; color: rgba(240,238,255,0.6);
}
<details class="acc-glass" name="acc-glass" open>
  <summary>What's inside?<span class="acc-glass__caret"></span></summary>
  <p>A frosted surface with a subtle border that catches light when the row expands.</p>
</details>
<details class="acc-glass" name="acc-glass">
  <summary>Does blur cost performance?<span class="acc-glass__caret"></span></summary>
  <p>backdrop-filter is GPU-accelerated. Use it on small islands rather than wide swaths.</p>
</details>
<details class="acc-glass" name="acc-glass">
  <summary>Browser fallback?<span class="acc-glass__caret"></span></summary>
  <p>The semi-transparent background still reads gracefully without the blur effect.</p>
</details>
07 / 26
Minimal Rail
Pure CSS
Typography

One sans family, three weights, two sizes. That's the whole system.

Spacing

Built on an 8-point base with optional 4-point quarter-step for fine control.

Color

Three brand tokens, four neutral steps. Override via CSS custom properties.

A thin colored rail on the left highlights the active row — no other decoration.
.acc-rail {
  position: relative; padding: 0 0 0 16px; margin-bottom: 4px;
}
.acc-rail::before {
  content: ''; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 2px; background: rgba(240,238,255,0.06); border-radius: 2px;
  transition: background .25s;
}
.acc-rail summary {
  cursor: pointer; list-style: none; padding: 11px 0;
  font: 600 13px/1.3 system-ui, sans-serif; color: rgba(240,238,255,0.6);
  transition: color .2s;
}
.acc-rail summary::-webkit-details-marker { display: none; }
.acc-rail[open]::before { background: linear-gradient(180deg, #9c7bd6, #d49a5c); }
.acc-rail[open] > summary { color: #f0eeff; }
.acc-rail p {
  margin: 0 0 12px; padding: 0;
  font: 12px/1.6 system-ui, sans-serif; color: rgba(240,238,255,0.5);
}
<details class="acc-rail" name="acc-rail" open>
  <summary>Typography</summary>
  <p>One sans family, three weights, two sizes. That's the whole system.</p>
</details>
<details class="acc-rail" name="acc-rail">
  <summary>Spacing</summary>
  <p>Built on an 8-point base with optional 4-point quarter-step for fine control.</p>
</details>
<details class="acc-rail" name="acc-rail">
  <summary>Color</summary>
  <p>Three brand tokens, four neutral steps. Override via CSS custom properties.</p>
</details>
08 / 26
Card Lift
Pure CSS
Mountain View

Wake to clear sightlines and warm light. The view is the room.

Garden Suite

A private terrace facing south, framed by old growth and stone.

Loft Studio

Open plan with full-height windows and a quiet corner for work.

Floating cards that lift with a soft shadow when expanded — accent color shifts subtly.
.acc-lift {
  background: #1a1a24; border: 1px solid rgba(240,238,255,0.05);
  border-radius: 12px; margin-bottom: 8px;
  transition: transform .3s cubic-bezier(.3,1.4,.5,1), box-shadow .3s, border-color .3s;
}
.acc-lift summary {
  cursor: pointer; list-style: none; padding: 14px 16px;
  font: 600 13px/1.3 system-ui, sans-serif; color: rgba(240,238,255,0.75);
}
.acc-lift summary::-webkit-details-marker { display: none; }
.acc-lift[open] {
  transform: translateY(-2px);
  box-shadow: 0 10px 28px -10px rgba(156,123,214,0.4);
  border-color: rgba(156,123,214,0.3);
}
.acc-lift[open] > summary { color: #f0eeff; }
.acc-lift p {
  margin: 0; padding: 0 16px 14px;
  font: 12px/1.6 system-ui, sans-serif; color: rgba(240,238,255,0.55);
}
<details class="acc-lift" name="acc-lift" open>
  <summary>Mountain View</summary>
  <p>Wake to clear sightlines and warm light. The view is the room.</p>
</details>
<details class="acc-lift" name="acc-lift">
  <summary>Garden Suite</summary>
  <p>A private terrace facing south, framed by old growth and stone.</p>
</details>
<details class="acc-lift" name="acc-lift">
  <summary>Loft Studio</summary>
  <p>Open plan with full-height windows and a quiet corner for work.</p>
</details>
09 / 26
Strip Tabs
Pure CSS
Horizontal column accordion — each strip widens when activated, others compress to a label.
.acc-strip {
  display: flex; gap: 4px; height: 220px; width: 100%;
  border-radius: 12px; overflow: hidden;
}
.acc-strip > input { display: none; }
.acc-strip__col {
  flex: 1 1 0; cursor: pointer; padding: 16px 14px;
  display: flex; flex-direction: column; justify-content: flex-end;
  position: relative; overflow: hidden;
  background: #1a1a24; color: rgba(240,238,255,0.7);
  transition: flex .55s cubic-bezier(.3,1,.3,1), background .4s;
}
.acc-strip__col[data-c="0"] { background: linear-gradient(160deg,#3a2a55,#1a1a24); }
.acc-strip__col[data-c="1"] { background: linear-gradient(160deg,#553a2a,#1a1a24); }
.acc-strip__col[data-c="2"] { background: linear-gradient(160deg,#2a553a,#1a1a24); }
.acc-strip__col[data-c="3"] { background: linear-gradient(160deg,#553a55,#1a1a24); }
.acc-strip__title {
  font: 800 11px/1 system-ui; letter-spacing: 0.18em;
  writing-mode: vertical-rl; transform: rotate(180deg);
  align-self: flex-start; transition: all .35s;
}
.acc-strip__body {
  font: 12px/1.55 system-ui; color: rgba(240,238,255,0.78);
  opacity: 0; max-height: 0; transition: opacity .3s .15s, max-height .35s;
}
#strip-1:checked ~ [for="strip-1"],
#strip-2:checked ~ [for="strip-2"],
#strip-3:checked ~ [for="strip-3"],
#strip-4:checked ~ [for="strip-4"] {
  flex: 5 1 0; color: #f0eeff;
}
#strip-1:checked ~ [for="strip-1"] .acc-strip__title,
#strip-2:checked ~ [for="strip-2"] .acc-strip__title,
#strip-3:checked ~ [for="strip-3"] .acc-strip__title,
#strip-4:checked ~ [for="strip-4"] .acc-strip__title {
  writing-mode: horizontal-tb; transform: none; font-size: 14px;
  align-self: stretch;
}
#strip-1:checked ~ [for="strip-1"] .acc-strip__body,
#strip-2:checked ~ [for="strip-2"] .acc-strip__body,
#strip-3:checked ~ [for="strip-3"] .acc-strip__body,
#strip-4:checked ~ [for="strip-4"] .acc-strip__body {
  opacity: 1; max-height: 100px; margin-top: 8px;
}
<div class="acc-strip">
  <input type="radio" name="strip" id="strip-1" checked>
  <input type="radio" name="strip" id="strip-2">
  <input type="radio" name="strip" id="strip-3">
  <input type="radio" name="strip" id="strip-4">
  <label for="strip-1" class="acc-strip__col" data-c="0">
    <span class="acc-strip__title">DESIGN</span>
    <span class="acc-strip__body">Compose from atomic tokens. Stay consistent across surfaces and scale.</span>
  </label>
  <label for="strip-2" class="acc-strip__col" data-c="1">
    <span class="acc-strip__title">BUILD</span>
    <span class="acc-strip__body">Hand-coded HTML and CSS, no framework lock-in. Ship faster.</span>
  </label>
  <label for="strip-3" class="acc-strip__col" data-c="2">
    <span class="acc-strip__title">SHIP</span>
    <span class="acc-strip__body">Static output, edge-cached, instant on every connection.</span>
  </label>
  <label for="strip-4" class="acc-strip__col" data-c="3">
    <span class="acc-strip__title">REPEAT</span>
    <span class="acc-strip__body">Iterate without rewriting. Components compose cleanly.</span>
  </label>
</div>
10 / 26
Image Reveal
Pure CSS
Aurora
Copper
Sage
Slate
Berry
Hover or focus to widen a column; the image inside zooms to fit while siblings collapse.
.acc-img {
  display: flex; gap: 3px; height: 220px;
  border-radius: 12px; overflow: hidden;
}
.acc-img__col {
  flex: 1; cursor: pointer; outline: none;
  background: radial-gradient(circle at 30% 20%, color-mix(in srgb, var(--bg), white 25%), var(--bg));
  display: flex; align-items: flex-end; padding: 14px;
  transition: flex .5s cubic-bezier(.3,1,.3,1), filter .3s;
  filter: saturate(0.7) brightness(0.85);
}
.acc-img__col:hover, .acc-img__col:focus {
  flex: 4; filter: saturate(1.2) brightness(1);
}
.acc-img__lbl {
  font: 700 12px/1 system-ui; letter-spacing: 0.14em;
  text-transform: uppercase; color: #f0eeff;
  text-shadow: 0 1px 8px rgba(0,0,0,0.4);
}
<div class="acc-img">
  <div class="acc-img__col" tabindex="0" style="--bg:#3a2a55">
    <span class="acc-img__lbl">Aurora</span>
  </div>
  <div class="acc-img__col" tabindex="0" style="--bg:#553a2a">
    <span class="acc-img__lbl">Copper</span>
  </div>
  <div class="acc-img__col" tabindex="0" style="--bg:#2a553a">
    <span class="acc-img__lbl">Sage</span>
  </div>
  <div class="acc-img__col" tabindex="0" style="--bg:#2a3a55">
    <span class="acc-img__lbl">Slate</span>
  </div>
  <div class="acc-img__col" tabindex="0" style="--bg:#552a3a">
    <span class="acc-img__lbl">Berry</span>
  </div>
</div>
11 / 26
Color Block
Pure CSS
Solid color blocks switch via radio inputs; the active block expands and reveals body copy.
.acc-cblk { display: flex; height: 220px; border-radius: 12px; overflow: hidden; }
.acc-cblk > input { display: none; }
.acc-cblk__b {
  flex: 1; cursor: pointer; padding: 16px;
  display: flex; flex-direction: column; justify-content: space-between;
  background: var(--bg); color: #15151d;
  transition: flex .5s cubic-bezier(.3,1,.3,1);
}
.acc-cblk__t {
  font: 800 13px/1 system-ui; letter-spacing: 0.1em;
  text-transform: uppercase;
}
.acc-cblk__d {
  font: 12px/1.55 system-ui; opacity: 0;
  transform: translateY(8px); transition: all .3s .12s;
}
#cblk-1:checked ~ [for="cblk-1"],
#cblk-2:checked ~ [for="cblk-2"],
#cblk-3:checked ~ [for="cblk-3"] { flex: 4; }
#cblk-1:checked ~ [for="cblk-1"] .acc-cblk__d,
#cblk-2:checked ~ [for="cblk-2"] .acc-cblk__d,
#cblk-3:checked ~ [for="cblk-3"] .acc-cblk__d {
  opacity: 1; transform: none;
}
<div class="acc-cblk">
  <input type="radio" name="cblk" id="cblk-1" checked>
  <input type="radio" name="cblk" id="cblk-2">
  <input type="radio" name="cblk" id="cblk-3">
  <label for="cblk-1" class="acc-cblk__b" style="--bg:#9c7bd6">
    <span class="acc-cblk__t">Amethyst</span>
    <span class="acc-cblk__d">Royal violet anchor of the system. Use for primary actions.</span>
  </label>
  <label for="cblk-2" class="acc-cblk__b" style="--bg:#d49a5c">
    <span class="acc-cblk__t">Copper</span>
    <span class="acc-cblk__d">Warm metallic accent. Use sparingly for highlights and badges.</span>
  </label>
  <label for="cblk-3" class="acc-cblk__b" style="--bg:#8fb3a3">
    <span class="acc-cblk__t">Sage</span>
    <span class="acc-cblk__d">Cool restorative neutral. Use for success and secondary chrome.</span>
  </label>
</div>
12 / 26
Numbered Spine
Pure CSS
Vertical numbered labels rotate to horizontal when their column expands.
.acc-spine {
  display: flex; gap: 2px; height: 220px;
  border-radius: 12px; overflow: hidden; background: rgba(240,238,255,0.04);
}
.acc-spine > input { display: none; }
.acc-spine__c {
  flex: 1; cursor: pointer; padding: 14px;
  background: #1a1a24; position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 10px;
  transition: flex .5s cubic-bezier(.3,1,.3,1), background .3s;
}
.acc-spine__n {
  font: 800 18px monospace; color: rgba(212,154,92,0.8);
}
.acc-spine__t {
  font: 700 12px/1 system-ui; letter-spacing: 0.12em;
  text-transform: uppercase; color: rgba(240,238,255,0.55);
  writing-mode: vertical-rl; transform: rotate(180deg);
  transition: all .35s;
}
.acc-spine__b {
  font: 12px/1.55 system-ui; color: rgba(240,238,255,0.65);
  opacity: 0; max-height: 0; transition: opacity .3s .15s, max-height .35s;
}
#sp-1:checked ~ [for="sp-1"],
#sp-2:checked ~ [for="sp-2"],
#sp-3:checked ~ [for="sp-3"] {
  flex: 4; background: linear-gradient(180deg,#1a1a24,#2a2438);
}
#sp-1:checked ~ [for="sp-1"] .acc-spine__t,
#sp-2:checked ~ [for="sp-2"] .acc-spine__t,
#sp-3:checked ~ [for="sp-3"] .acc-spine__t {
  writing-mode: horizontal-tb; transform: none; color: #f0eeff; font-size: 14px;
}
#sp-1:checked ~ [for="sp-1"] .acc-spine__b,
#sp-2:checked ~ [for="sp-2"] .acc-spine__b,
#sp-3:checked ~ [for="sp-3"] .acc-spine__b {
  opacity: 1; max-height: 120px;
}
<div class="acc-spine">
  <input type="radio" name="spine" id="sp-1" checked>
  <input type="radio" name="spine" id="sp-2">
  <input type="radio" name="spine" id="sp-3">
  <label for="sp-1" class="acc-spine__c">
    <span class="acc-spine__n">01</span>
    <span class="acc-spine__t">Discover</span>
    <span class="acc-spine__b">Map the problem space. Talk to users. Sketch hypotheses.</span>
  </label>
  <label for="sp-2" class="acc-spine__c">
    <span class="acc-spine__n">02</span>
    <span class="acc-spine__t">Define</span>
    <span class="acc-spine__b">Pick one bet. Frame it crisply. Write what success looks like.</span>
  </label>
  <label for="sp-3" class="acc-spine__c">
    <span class="acc-spine__n">03</span>
    <span class="acc-spine__t">Deliver</span>
    <span class="acc-spine__b">Ship a thin slice. Measure. Decide what's next.</span>
  </label>
</div>
13 / 26
Curtain Slide
Pure CSS

First Act

The curtain rises slowly. Light spills across the boards.

Second Act

Tension builds. The rhythm tightens. We lean forward.

Third Act

Resolution arrives. The audience exhales. Lights dim.

Active panel slides in from the right while the previous one collapses left — like a stage curtain.
.acc-curt {
  display: flex; flex-direction: column; height: 220px;
  border-radius: 12px; overflow: hidden;
  background: #1a1a24; border: 1px solid rgba(240,238,255,0.06);
}
.acc-curt > input { display: none; }
.acc-curt__tabs {
  display: flex; background: #15151d;
  border-bottom: 1px solid rgba(240,238,255,0.06);
}
.acc-curt__tabs label {
  flex: 1; padding: 11px; cursor: pointer;
  font: 700 11px/1 system-ui; letter-spacing: 0.14em; text-align: center;
  color: rgba(240,238,255,0.5); transition: color .2s, background .2s;
}
.acc-curt__tabs label:hover { color: #f0eeff; }
.acc-curt__stage { position: relative; flex: 1; overflow: hidden; }
.acc-curt__p {
  position: absolute; inset: 0; padding: 18px;
  transform: translateX(100%); opacity: 0;
  transition: transform .5s cubic-bezier(.3,1,.3,1), opacity .35s;
}
.acc-curt__p h4 { margin: 0 0 8px; font: 700 14px/1.2 system-ui; color: #d49a5c; }
.acc-curt__p p { margin: 0; font: 12px/1.55 system-ui; color: rgba(240,238,255,0.7); }
#curt-1:checked ~ .acc-curt__tabs label[for="curt-1"],
#curt-2:checked ~ .acc-curt__tabs label[for="curt-2"],
#curt-3:checked ~ .acc-curt__tabs label[for="curt-3"] {
  color: #f0eeff; background: rgba(156,123,214,0.18);
}
#curt-1:checked ~ .acc-curt__stage [data-i="0"],
#curt-2:checked ~ .acc-curt__stage [data-i="1"],
#curt-3:checked ~ .acc-curt__stage [data-i="2"] {
  transform: translateX(0); opacity: 1;
}
<div class="acc-curt">
  <input type="radio" name="curt" id="curt-1" checked>
  <input type="radio" name="curt" id="curt-2">
  <input type="radio" name="curt" id="curt-3">
  <div class="acc-curt__tabs">
    <label for="curt-1">ONE</label>
    <label for="curt-2">TWO</label>
    <label for="curt-3">THREE</label>
  </div>
  <div class="acc-curt__stage">
    <div class="acc-curt__p" data-i="0"><h4>First Act</h4><p>The curtain rises slowly. Light spills across the boards.</p></div>
    <div class="acc-curt__p" data-i="1"><h4>Second Act</h4><p>Tension builds. The rhythm tightens. We lean forward.</p></div>
    <div class="acc-curt__p" data-i="2"><h4>Third Act</h4><p>Resolution arrives. The audience exhales. Lights dim.</p></div>
  </div>
</div>
14 / 26
Vinyl Spine
Pure CSS
Records on a shelf — click a spine to slide it out and reveal its label.
.acc-vyl {
  display: flex; gap: 5px; padding: 16px;
  height: 220px; align-items: stretch;
  background: linear-gradient(180deg,#15151d,#1a1a24);
  border-radius: 12px;
}
.acc-vyl > input { display: none; }
.acc-vyl__r {
  flex: 0 0 22px; cursor: pointer; position: relative;
  background: linear-gradient(90deg, color-mix(in srgb, var(--c), black 35%), var(--c) 50%, color-mix(in srgb, var(--c), black 35%));
  border-radius: 3px; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.3);
  transition: flex .45s cubic-bezier(.3,1,.3,1);
  display: flex; align-items: center; justify-content: center;
}
.acc-vyl__r span {
  font: 700 10px/1 system-ui; letter-spacing: 0.14em;
  color: rgba(0,0,0,0.7); white-space: nowrap;
  writing-mode: vertical-rl; transform: rotate(180deg);
}
#vyl-1:checked ~ [for="vyl-1"],
#vyl-2:checked ~ [for="vyl-2"],
#vyl-3:checked ~ [for="vyl-3"],
#vyl-4:checked ~ [for="vyl-4"] { flex: 1 1 0; }
#vyl-1:checked ~ [for="vyl-1"] span,
#vyl-2:checked ~ [for="vyl-2"] span,
#vyl-3:checked ~ [for="vyl-3"] span,
#vyl-4:checked ~ [for="vyl-4"] span {
  writing-mode: horizontal-tb; transform: none; font-size: 13px;
  color: rgba(0,0,0,0.85);
}
<div class="acc-vyl">
  <input type="radio" name="vyl" id="vyl-1">
  <input type="radio" name="vyl" id="vyl-2" checked>
  <input type="radio" name="vyl" id="vyl-3">
  <input type="radio" name="vyl" id="vyl-4">
  <label for="vyl-1" class="acc-vyl__r" style="--c:#9c7bd6"><span>SIDE A · Echoes</span></label>
  <label for="vyl-2" class="acc-vyl__r" style="--c:#d49a5c"><span>SIDE B · Static</span></label>
  <label for="vyl-3" class="acc-vyl__r" style="--c:#8fb3a3"><span>SIDE C · Drift</span></label>
  <label for="vyl-4" class="acc-vyl__r" style="--c:#c8a2c8"><span>SIDE D · Hum</span></label>
</div>
15 / 26
Cinema Reel
Pure CSS
Film-strip style horizontal accordion — sprocket holes top and bottom, frame brightens on focus.
.acc-reel {
  background: #15151d; padding: 12px 0; border-radius: 8px;
  height: 220px; display: flex; align-items: center;
}
.acc-reel__strip {
  display: flex; gap: 4px; width: 100%; padding: 18px 12px;
  background:
    linear-gradient(#0a0a10,#0a0a10) center/100% calc(100% - 24px) no-repeat,
    repeating-linear-gradient(90deg, transparent 0 8px, rgba(240,238,255,0.12) 8px 14px) top/100% 12px no-repeat,
    repeating-linear-gradient(90deg, transparent 0 8px, rgba(240,238,255,0.12) 8px 14px) bottom/100% 12px no-repeat;
}
.acc-reel__strip > input { display: none; }
.acc-reel__f {
  flex: 1; cursor: pointer; min-height: 130px;
  background: linear-gradient(135deg,#3a2a55,#2a1a45);
  border-radius: 4px; display: flex; align-items: center; justify-content: center;
  font: 700 11px/1 system-ui; letter-spacing: 0.1em; color: rgba(240,238,255,0.4);
  filter: brightness(0.65) contrast(0.85);
  transition: flex .5s cubic-bezier(.3,1,.3,1), filter .3s, color .3s;
}
.acc-reel__f:nth-of-type(2) { background: linear-gradient(135deg,#553a2a,#451a1a); }
.acc-reel__f:nth-of-type(3) { background: linear-gradient(135deg,#2a553a,#1a4530); }
#reel-1:checked ~ [for="reel-1"],
#reel-2:checked ~ [for="reel-2"],
#reel-3:checked ~ [for="reel-3"] {
  flex: 4; filter: brightness(1.1) contrast(1.05);
  color: #f0eeff; font-size: 13px;
}
<div class="acc-reel">
  <div class="acc-reel__strip">
    <input type="radio" name="reel" id="reel-1" checked>
    <input type="radio" name="reel" id="reel-2">
    <input type="radio" name="reel" id="reel-3">
    <label for="reel-1" class="acc-reel__f"><span>SCENE 01 · Daybreak</span></label>
    <label for="reel-2" class="acc-reel__f"><span>SCENE 02 · Pursuit</span></label>
    <label for="reel-3" class="acc-reel__f"><span>SCENE 03 · Resolve</span></label>
  </div>
</div>
16 / 26
Aurora Strip
Pure CSS
Each panel hides a drifting aurora gradient — pop into view by widening the active strip.
.acc-aur {
  display: flex; gap: 4px; height: 220px;
  border-radius: 12px; overflow: hidden;
}
.acc-aur > input { display: none; }
.acc-aur__c {
  flex: 1; cursor: pointer; padding: 16px; position: relative;
  background:
    radial-gradient(ellipse at 30% 20%, rgba(156,123,214,0.5), transparent 60%),
    radial-gradient(ellipse at 70% 80%, rgba(212,154,92,0.4), transparent 60%),
    #15151d;
  background-size: 220% 220%, 240% 240%, 100% 100%;
  background-position: 0% 0%, 100% 100%, 0 0;
  display: flex; flex-direction: column; justify-content: flex-end;
  filter: brightness(0.55) saturate(0.8);
  transition: flex .5s cubic-bezier(.3,1,.3,1), filter .35s, background-position 6s linear;
}
.acc-aur__c:nth-of-type(2) {
  background:
    radial-gradient(ellipse at 50% 40%, rgba(212,154,92,0.55), transparent 60%),
    radial-gradient(ellipse at 80% 70%, rgba(143,179,163,0.4), transparent 60%),
    #15151d;
}
.acc-aur__c:nth-of-type(3) {
  background:
    radial-gradient(ellipse at 20% 80%, rgba(143,179,163,0.55), transparent 60%),
    radial-gradient(ellipse at 70% 30%, rgba(156,123,214,0.4), transparent 60%),
    #15151d;
}
.acc-aur__l { font: 800 12px/1 system-ui; letter-spacing: 0.16em; color: rgba(240,238,255,0.85); }
.acc-aur__d { font: 11px/1.55 system-ui; color: rgba(240,238,255,0.55); margin-top: 6px;
  opacity: 0; transition: opacity .3s .15s; }
#aur-1:checked ~ [for="aur-1"],
#aur-2:checked ~ [for="aur-2"],
#aur-3:checked ~ [for="aur-3"] {
  flex: 4; filter: brightness(1.05) saturate(1.1);
  background-position: 100% 100%, 0% 0%, 0 0;
}
#aur-1:checked ~ [for="aur-1"] .acc-aur__d,
#aur-2:checked ~ [for="aur-2"] .acc-aur__d,
#aur-3:checked ~ [for="aur-3"] .acc-aur__d { opacity: 1; }
<div class="acc-aur">
  <input type="radio" name="aur" id="aur-1" checked>
  <input type="radio" name="aur" id="aur-2">
  <input type="radio" name="aur" id="aur-3">
  <label for="aur-1" class="acc-aur__c">
    <span class="acc-aur__l">North</span>
    <span class="acc-aur__d">Cold violet ribbon, 22:00 local</span>
  </label>
  <label for="aur-2" class="acc-aur__c">
    <span class="acc-aur__l">East</span>
    <span class="acc-aur__d">Warm copper veil, 23:30 local</span>
  </label>
  <label for="aur-3" class="acc-aur__c">
    <span class="acc-aur__l">West</span>
    <span class="acc-aur__d">Soft sage glow, 01:00 local</span>
  </label>
</div>
17 / 26
Diagonal Slant
Pure CSS
Architecture

Static-first, edge-cached, no SSR runtime. Fast on every connection.

Data layer

Content lives in flat files. Authoring is git-tracked and reviewable.

Deployment

Build once, push to CDN. No servers to manage, no scaling concerns.

Vertical accordion where each row slants — open row straightens to a clean rectangle.
.acc-slant {
  background: rgba(156,123,214,0.08);
  border: 1px solid rgba(156,123,214,0.2);
  margin-bottom: 6px;
  clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
  transition: clip-path .35s cubic-bezier(.3,1.4,.5,1), background .25s;
}
.acc-slant summary {
  cursor: pointer; list-style: none; padding: 13px 22px;
  font: 700 12px/1 system-ui; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgba(240,238,255,0.7);
}
.acc-slant summary::-webkit-details-marker { display: none; }
.acc-slant[open] {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  background: rgba(156,123,214,0.18);
}
.acc-slant[open] > summary { color: #f0eeff; }
.acc-slant p {
  margin: 0; padding: 0 22px 14px;
  font: 12px/1.6 system-ui; color: rgba(240,238,255,0.6);
}
<details class="acc-slant" name="acc-slant" open>
  <summary>Architecture</summary>
  <p>Static-first, edge-cached, no SSR runtime. Fast on every connection.</p>
</details>
<details class="acc-slant" name="acc-slant">
  <summary>Data layer</summary>
  <p>Content lives in flat files. Authoring is git-tracked and reviewable.</p>
</details>
<details class="acc-slant" name="acc-slant">
  <summary>Deployment</summary>
  <p>Build once, push to CDN. No servers to manage, no scaling concerns.</p>
</details>
18 / 26
Stepped Stair
Pure CSS
Step one

Begin where you stand. The first move matters more than the plan.

Step two

Ship the rough version. Real feedback beats imagined feedback.

Step three

Refine. Cut what didn't earn its place. Keep the load light.

Step four

Repeat the loop. Compounding shows up after the tenth turn, not the first.

Each row indents progressively, creating a staircase — open row pulls back to flush left.
.acc-stair {
  margin-bottom: 4px;
  margin-left: calc(var(--i,0) * 16px);
  background: rgba(143,179,163,0.07);
  border-left: 3px solid #8fb3a3;
  border-radius: 0 8px 8px 0;
  transition: margin-left .35s cubic-bezier(.3,1.3,.5,1), background .25s;
}
.acc-stair summary {
  cursor: pointer; list-style: none; padding: 11px 14px;
  font: 600 13px/1.3 system-ui; color: rgba(240,238,255,0.7);
}
.acc-stair summary::-webkit-details-marker { display: none; }
.acc-stair[open] {
  margin-left: 0; background: rgba(143,179,163,0.15);
}
.acc-stair[open] > summary { color: #f0eeff; }
.acc-stair p {
  margin: 0; padding: 0 14px 12px;
  font: 12px/1.55 system-ui; color: rgba(240,238,255,0.6);
}
<details class="acc-stair" name="acc-stair" style="--i:0" open>
  <summary>Step one</summary>
  <p>Begin where you stand. The first move matters more than the plan.</p>
</details>
<details class="acc-stair" name="acc-stair" style="--i:1">
  <summary>Step two</summary>
  <p>Ship the rough version. Real feedback beats imagined feedback.</p>
</details>
<details class="acc-stair" name="acc-stair" style="--i:2">
  <summary>Step three</summary>
  <p>Refine. Cut what didn't earn its place. Keep the load light.</p>
</details>
<details class="acc-stair" name="acc-stair" style="--i:3">
  <summary>Step four</summary>
  <p>Repeat the loop. Compounding shows up after the tenth turn, not the first.</p>
</details>
19 / 26
Circular Arc
Pure CSS
01 02 03 04

Discover

Map the problem space. Talk to users. Sketch hypotheses before committing to a build.

Define

Pick one bet. Frame it crisply. Write down what success actually looks like.

Deliver

Ship a thin slice end-to-end. Measure real usage. Decide what comes next from data.

Refine

Iterate on real signal, not imagined feedback. Compound the wins, drop what didn't earn its place.

A four-segment ring menu — labels follow each arc via SVG textPath. Selected arc lights up with its theme color, the hub shows the active step number, and the body reveals a matching description.
.acc-arc {
  display: grid; grid-template-columns: 150px 1fr; gap: 18px;
  height: 220px; align-items: center; padding: 6px 4px;
}
.acc-arc > input { position: absolute; opacity: 0; pointer-events: none; }
.acc-arc__wheel {
  position: relative; width: 150px; height: 150px; flex-shrink: 0;
}
.acc-arc__svg { width: 100%; height: 100%; display: block; }
.acc-arc__seg {
  fill: rgba(240,238,255,0.05);
  stroke: rgba(240,238,255,0.1); stroke-width: 1;
  transition: fill .3s, stroke .3s, stroke-width .3s;
}
.acc-arc__seg[data-i="0"] { fill: rgba(156,123,214,0.2); }
.acc-arc__seg[data-i="1"] { fill: rgba(212,154,92,0.2); }
.acc-arc__seg[data-i="2"] { fill: rgba(143,179,163,0.2); }
.acc-arc__seg[data-i="3"] { fill: rgba(200,162,200,0.2); }
.acc-arc__lbl {
  font: 700 9px/1 system-ui, sans-serif;
  letter-spacing: 0.18em; fill: rgba(240,238,255,0.6);
  transition: fill .25s;
}
/* Click hit targets — 4 explicit triangular wedges from center to outer edge.
   Each polygon: center (50%,50%), outer corner A, outer corner B */
.acc-arc__hit { position: absolute; inset: 0; cursor: pointer; }
.acc-arc__hit--n { clip-path: polygon(50% 50%, 100% 0,   0    0); }
.acc-arc__hit--e { clip-path: polygon(50% 50%, 100% 100%, 100% 0); }
.acc-arc__hit--s { clip-path: polygon(50% 50%, 0    100%, 100% 100%); }
.acc-arc__hit--w { clip-path: polygon(50% 50%, 0    0,    0    100%); }
.acc-arc__hub {
  position: absolute; left: 50%; top: 50%;
  width: 60px; height: 60px; border-radius: 50%;
  background: #1a1a24;
  box-shadow: 0 0 0 1px rgba(240,238,255,0.1), 0 6px 16px rgba(0,0,0,0.4);
  transform: translate(-50%, -50%);
  display: grid; place-items: center;
  pointer-events: none;
}
.acc-arc__hub span {
  grid-area: 1/1; font: 800 18px ui-monospace, monospace;
  color: #f0eeff; opacity: 0;
  transition: opacity .25s, color .25s;
}
.acc-arc__body { position: relative; height: 150px; }
.acc-arc__body article {
  position: absolute; inset: 0; margin: 0;
  padding: 0 0 0 14px;
  border-left: 2px solid rgba(240,238,255,0.08);
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
  opacity: 0; transform: translateX(6px);
  transition: opacity .3s, transform .3s, border-color .3s;
}
.acc-arc__body h4 {
  margin: 0; font: 700 14px/1.2 system-ui, sans-serif;
  letter-spacing: 0.02em; color: #f0eeff;
}
.acc-arc__body p {
  margin: 0; font: 12px/1.6 system-ui, sans-serif;
  color: rgba(240,238,255,0.7);
}
/* Active states — explicit per-arc */
#arc-1:checked ~ .acc-arc__wheel .acc-arc__seg[data-i="0"] { fill: #9c7bd6; stroke: rgba(255,255,255,0.4); stroke-width: 1.5; }
#arc-2:checked ~ .acc-arc__wheel .acc-arc__seg[data-i="1"] { fill: #d49a5c; stroke: rgba(255,255,255,0.4); stroke-width: 1.5; }
#arc-3:checked ~ .acc-arc__wheel .acc-arc__seg[data-i="2"] { fill: #8fb3a3; stroke: rgba(255,255,255,0.4); stroke-width: 1.5; }
#arc-4:checked ~ .acc-arc__wheel .acc-arc__seg[data-i="3"] { fill: #c8a2c8; stroke: rgba(255,255,255,0.4); stroke-width: 1.5; }
#arc-1:checked ~ .acc-arc__wheel .acc-arc__lbl[data-i="0"],
#arc-2:checked ~ .acc-arc__wheel .acc-arc__lbl[data-i="1"],
#arc-3:checked ~ .acc-arc__wheel .acc-arc__lbl[data-i="2"],
#arc-4:checked ~ .acc-arc__wheel .acc-arc__lbl[data-i="3"] { fill: #15151d; }
#arc-1:checked ~ .acc-arc__wheel .acc-arc__hub span[data-i="0"] { opacity: 1; color: #b896e8; }
#arc-2:checked ~ .acc-arc__wheel .acc-arc__hub span[data-i="1"] { opacity: 1; color: #d49a5c; }
#arc-3:checked ~ .acc-arc__wheel .acc-arc__hub span[data-i="2"] { opacity: 1; color: #8fb3a3; }
#arc-4:checked ~ .acc-arc__wheel .acc-arc__hub span[data-i="3"] { opacity: 1; color: #c8a2c8; }
#arc-1:checked ~ .acc-arc__body article[data-i="0"],
#arc-2:checked ~ .acc-arc__body article[data-i="1"],
#arc-3:checked ~ .acc-arc__body article[data-i="2"],
#arc-4:checked ~ .acc-arc__body article[data-i="3"] {
  opacity: 1; transform: translateX(0);
}
#arc-1:checked ~ .acc-arc__body article[data-i="0"] { border-left-color: #9c7bd6; }
#arc-2:checked ~ .acc-arc__body article[data-i="1"] { border-left-color: #d49a5c; }
#arc-3:checked ~ .acc-arc__body article[data-i="2"] { border-left-color: #8fb3a3; }
#arc-4:checked ~ .acc-arc__body article[data-i="3"] { border-left-color: #c8a2c8; }
<div class="acc-arc">
  <input type="radio" name="arc" id="arc-1" checked>
  <input type="radio" name="arc" id="arc-2">
  <input type="radio" name="arc" id="arc-3">
  <input type="radio" name="arc" id="arc-4">
  <div class="acc-arc__wheel">
    <svg viewBox="0 0 140 140" class="acc-arc__svg" aria-hidden="true">
      <!-- Annular wedges aligned to cardinals: each spans ±45° around N/E/S/W.
           Outer r=66, inner r=42, center (70,70). -->
      <path class="acc-arc__seg" data-i="0" d="M 23.33 23.33 A 66 66 0 0 1 116.67 23.33 L 99.7 40.3  A 42 42 0 0 0 40.3 40.3   Z"/>
      <path class="acc-arc__seg" data-i="1" d="M 116.67 23.33 A 66 66 0 0 1 116.67 116.67 L 99.7 99.7  A 42 42 0 0 0 99.7 40.3  Z"/>
      <path class="acc-arc__seg" data-i="2" d="M 116.67 116.67 A 66 66 0 0 1 23.33 116.67 L 40.3 99.7  A 42 42 0 0 0 99.7 99.7  Z"/>
      <path class="acc-arc__seg" data-i="3" d="M 23.33 116.67 A 66 66 0 0 1 23.33 23.33 L 40.3 40.3   A 42 42 0 0 0 40.3 99.7  Z"/>
      <!-- Wedge centroid labels at radius 54 from center -->
      <text class="acc-arc__lbl" data-i="0" x="70"  y="22"  text-anchor="middle">DISCOVER</text>
      <text class="acc-arc__lbl" data-i="1" x="121" y="73"  text-anchor="middle" transform="rotate(90 121 70)">DEFINE</text>
      <text class="acc-arc__lbl" data-i="2" x="70"  y="123" text-anchor="middle">DELIVER</text>
      <text class="acc-arc__lbl" data-i="3" x="19"  y="73"  text-anchor="middle" transform="rotate(-90 19 70)">REFINE</text>
    </svg>
    <!-- Click targets: 4 wedge polygons matching the 4 SVG arcs (top, right, bottom, left) -->
    <label for="arc-1" class="acc-arc__hit acc-arc__hit--n" aria-label="Discover"></label>
    <label for="arc-2" class="acc-arc__hit acc-arc__hit--e" aria-label="Define"></label>
    <label for="arc-3" class="acc-arc__hit acc-arc__hit--s" aria-label="Deliver"></label>
    <label for="arc-4" class="acc-arc__hit acc-arc__hit--w" aria-label="Refine"></label>
    <div class="acc-arc__hub">
      <span data-i="0">01</span>
      <span data-i="1">02</span>
      <span data-i="2">03</span>
      <span data-i="3">04</span>
    </div>
  </div>
  <div class="acc-arc__body">
    <article data-i="0">
      <h4>Discover</h4>
      <p>Map the problem space. Talk to users. Sketch hypotheses before committing to a build.</p>
    </article>
    <article data-i="1">
      <h4>Define</h4>
      <p>Pick one bet. Frame it crisply. Write down what success actually looks like.</p>
    </article>
    <article data-i="2">
      <h4>Deliver</h4>
      <p>Ship a thin slice end-to-end. Measure real usage. Decide what comes next from data.</p>
    </article>
    <article data-i="3">
      <h4>Refine</h4>
      <p>Iterate on real signal, not imagined feedback. Compound the wins, drop what didn't earn its place.</p>
    </article>
  </div>
</div>
20 / 26
Marquee Header
Pure CSS
A long-running show that scrolls until you click · A long-running show that scrolls until you click · 

Stop the marquee. The title settles. The body opens. Calm restored.

Now open · The motion holds still · Now open · The motion holds still · 

The opened panel doesn't animate its title. Use marquee for "more here than fits."

Tap to open · Hover anywhere to slow down · Tap to open · Hover anywhere · 

Marquee speed pairs nicely with hover-to-pause for accessibility on long titles.

Closed rows scroll their title as a slow marquee; opening pauses the marquee and reveals body.
.acc-marq {
  margin-bottom: 6px; background: rgba(212,154,92,0.06);
  border: 1px solid rgba(212,154,92,0.16); border-radius: 8px;
  overflow: hidden;
}
.acc-marq summary {
  cursor: pointer; list-style: none;
  padding: 12px 0; overflow: hidden; position: relative;
}
.acc-marq summary::-webkit-details-marker { display: none; }
.acc-marq__t {
  display: inline-block; white-space: nowrap;
  font: 600 13px/1 system-ui; color: rgba(240,238,255,0.78);
  padding-left: 100%;
  animation: acc-marq-roll 14s linear infinite;
}
.acc-marq:hover .acc-marq__t { animation-play-state: paused; }
.acc-marq[open] .acc-marq__t {
  animation: none; padding-left: 16px; color: #f0eeff;
}
@keyframes acc-marq-roll {
  to { transform: translateX(-100%); }
}
.acc-marq p {
  margin: 0; padding: 0 16px 14px;
  font: 12px/1.55 system-ui; color: rgba(240,238,255,0.6);
}
@media (prefers-reduced-motion: reduce) {
  .acc-marq__t { animation: none; padding-left: 16px; }
}
<details class="acc-marq" name="acc-marq">
  <summary><span class="acc-marq__t">A long-running show that scrolls until you click · A long-running show that scrolls until you click ·&nbsp;</span></summary>
  <p>Stop the marquee. The title settles. The body opens. Calm restored.</p>
</details>
<details class="acc-marq" name="acc-marq" open>
  <summary><span class="acc-marq__t">Now open · The motion holds still · Now open · The motion holds still ·&nbsp;</span></summary>
  <p>The opened panel doesn't animate its title. Use marquee for "more here than fits."</p>
</details>
<details class="acc-marq" name="acc-marq">
  <summary><span class="acc-marq__t">Tap to open · Hover anywhere to slow down · Tap to open · Hover anywhere ·&nbsp;</span></summary>
  <p>Marquee speed pairs nicely with hover-to-pause for accessibility on long titles.</p>
</details>
21 / 26
Code Comment
Pure CSS
const installCommand = "npm i";

Installs the package and resolves all peer dependencies. Adds an entry to package.json.

const importStatement = "import x from 'lib';";

ES module import. Tree-shakable so unused exports won't bloat the bundle.

const renderHook = "useEffect";

Side-effects after paint. Cleanup runs on unmount or before the next effect fires.

Accordion styled as a multi-line code comment — "//" prefix on closed rows, full block on open.
.acc-cc {
  font-family: ui-monospace, "JetBrains Mono", monospace;
  background: #0e0e16; border-left: 3px solid #8fb3a3;
  margin-bottom: 4px; padding: 4px 0;
}
.acc-cc summary {
  cursor: pointer; list-style: none;
  padding: 8px 14px; font-size: 12.5px;
  color: rgba(143,179,163,0.85); position: relative;
}
.acc-cc summary::-webkit-details-marker { display: none; }
.acc-cc summary::before {
  content: '// '; color: rgba(143,179,163,0.45);
}
.acc-cc[open] summary { color: #f0eeff; background: rgba(143,179,163,0.06); }
.acc-cc[open] summary::before { content: '/* '; color: #d49a5c; }
.acc-cc[open] summary::after { content: ' */'; color: #d49a5c; }
.acc-cc p {
  margin: 0; padding: 8px 14px 12px 28px;
  font: 11.5px/1.7 ui-monospace, monospace;
  color: rgba(240,238,255,0.6);
}
.acc-cc p::before {
  content: '→ '; color: #d49a5c;
}
<details class="acc-cc" name="acc-cc">
  <summary>const installCommand = "npm i";</summary>
  <p>Installs the package and resolves all peer dependencies. Adds an entry to package.json.</p>
</details>
<details class="acc-cc" name="acc-cc" open>
  <summary>const importStatement = "import x from 'lib';";</summary>
  <p>ES module import. Tree-shakable so unused exports won't bloat the bundle.</p>
</details>
<details class="acc-cc" name="acc-cc">
  <summary>const renderHook = "useEffect";</summary>
  <p>Side-effects after paint. Cleanup runs on unmount or before the next effect fires.</p>
</details>
22 / 26
Paper Folded
Pure CSS
Origami

The art of folding paper into expressive form. Single sheet, no cuts, no glue.

Letterpress

Type pressed into thick cotton stock leaves a tactile bite that catches light.

Saddle Stitch

Two staples through the fold of a folio. Quick, cheap, beautiful for short runs.

Each row looks like a folded paper card; opening unfolds it with a 3D rotateX flip.
.acc-fold {
  background: linear-gradient(180deg, #f0eeff, #e6e2f5);
  color: #15151d; margin-bottom: 8px;
  border: 1px solid rgba(21,21,29,0.12);
  perspective: 800px; transform-style: preserve-3d;
}
.acc-fold summary {
  cursor: pointer; list-style: none; padding: 13px 16px;
  font: 700 13px/1 system-ui; position: relative;
  border-bottom: 1px solid transparent;
  transform-origin: bottom; transition: border-color .25s;
}
.acc-fold summary::-webkit-details-marker { display: none; }
.acc-fold summary::after {
  content: '▾'; position: absolute; right: 16px; top: 50%;
  transform: translateY(-50%); color: #9c7bd6;
  transition: transform .35s;
}
.acc-fold p {
  margin: 0; padding: 14px 16px;
  font: 12px/1.6 system-ui;
  background: linear-gradient(180deg, #faf8ff, #ece8f5);
  transform-origin: top; transform: rotateX(-90deg);
  transition: transform .45s cubic-bezier(.3,1,.3,1);
  box-shadow: inset 0 1px 0 rgba(21,21,29,0.08);
}
.acc-fold[open] summary { border-bottom-color: rgba(21,21,29,0.12); }
.acc-fold[open] summary::after { transform: translateY(-50%) rotate(180deg); }
.acc-fold[open] p { transform: rotateX(0); }
<details class="acc-fold" name="acc-fold" open>
  <summary>Origami</summary>
  <p>The art of folding paper into expressive form. Single sheet, no cuts, no glue.</p>
</details>
<details class="acc-fold" name="acc-fold">
  <summary>Letterpress</summary>
  <p>Type pressed into thick cotton stock leaves a tactile bite that catches light.</p>
</details>
<details class="acc-fold" name="acc-fold">
  <summary>Saddle Stitch</summary>
  <p>Two staples through the fold of a folio. Quick, cheap, beautiful for short runs.</p>
</details>
23 / 26
Equalizer
Pure CSS
Bass

Low-end response. Felt more than heard. Anchors the mix.

Mids

The conversation register. Where vocals and lead instruments live.

Treble

Air and detail. Cymbals, breath, the sparkle of acoustic plucks.

Audio-EQ inspired — vertical bars rise to indicate the open row. Pure CSS, no JS.
.acc-eq {
  background: #15151d; border: 1px solid rgba(240,238,255,0.06);
  border-radius: 8px; margin-bottom: 6px;
}
.acc-eq summary {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer; list-style: none; padding: 12px 16px;
  font: 600 13px/1 system-ui; color: rgba(240,238,255,0.72);
}
.acc-eq summary::-webkit-details-marker { display: none; }
.acc-eq__bars {
  display: inline-flex; align-items: flex-end; gap: 2px;
  height: 14px; width: 22px;
}
.acc-eq__bars i {
  display: block; width: 3px; background: rgba(212,154,92,0.4);
  border-radius: 1px; height: 30%; transition: height .3s;
}
.acc-eq[open] > summary { color: #f0eeff; }
.acc-eq[open] .acc-eq__bars i {
  background: #d49a5c;
  animation: acc-eq-pulse 1.1s ease-in-out infinite alternate;
}
.acc-eq[open] .acc-eq__bars i:nth-child(1) { animation-delay: .0s; }
.acc-eq[open] .acc-eq__bars i:nth-child(2) { animation-delay: .15s; }
.acc-eq[open] .acc-eq__bars i:nth-child(3) { animation-delay: .3s; }
.acc-eq[open] .acc-eq__bars i:nth-child(4) { animation-delay: .45s; }
@keyframes acc-eq-pulse {
  from { height: 25%; } to { height: 100%; }
}
.acc-eq p {
  margin: 0; padding: 0 16px 14px 50px;
  font: 12px/1.6 system-ui; color: rgba(240,238,255,0.55);
}
@media (prefers-reduced-motion: reduce) {
  .acc-eq[open] .acc-eq__bars i { animation: none; height: 70%; }
}
<details class="acc-eq" name="acc-eq">
  <summary><span class="acc-eq__bars" aria-hidden="true"><i></i><i></i><i></i><i></i></span>Bass</summary>
  <p>Low-end response. Felt more than heard. Anchors the mix.</p>
</details>
<details class="acc-eq" name="acc-eq" open>
  <summary><span class="acc-eq__bars" aria-hidden="true"><i></i><i></i><i></i><i></i></span>Mids</summary>
  <p>The conversation register. Where vocals and lead instruments live.</p>
</details>
<details class="acc-eq" name="acc-eq">
  <summary><span class="acc-eq__bars" aria-hidden="true"><i></i><i></i><i></i><i></i></span>Treble</summary>
  <p>Air and detail. Cymbals, breath, the sparkle of acoustic plucks.</p>
</details>
24 / 26
Stacked Cards
Pure CSS
Top of pile

The first card sits flush. Behind it the others fan back in scale.

Second card

Slightly smaller and pulled up. Click to bring it to the front of the stack.

Third card

The deepest in the deck. Smaller still, but always reachable.

Closed rows stack with a slight scale-down and translucent overlap; opened row pops to top.
.acc-stk {
  margin-top: -10px; margin-bottom: 0;
  background: linear-gradient(135deg, #2a2438, #1a1a24);
  border: 1px solid rgba(156,123,214,0.25);
  border-radius: 12px;
  transform: scale(calc(1 - var(--i) * 0.04)) translateY(calc(var(--i) * -2px));
  transform-origin: center top;
  transition: transform .3s, margin .3s, opacity .3s;
  opacity: calc(1 - var(--i) * 0.18);
}
.acc-stk:first-of-type { margin-top: 0; }
.acc-stk summary {
  cursor: pointer; list-style: none; padding: 13px 16px;
  font: 700 13px/1 system-ui; color: #f0eeff;
}
.acc-stk summary::-webkit-details-marker { display: none; }
.acc-stk[open] {
  transform: scale(1) translateY(0);
  opacity: 1; margin-top: 8px; margin-bottom: 8px;
  border-color: rgba(212,154,92,0.5);
  box-shadow: 0 12px 30px -10px rgba(156,123,214,0.5);
}
.acc-stk:first-of-type[open] { margin-top: 0; }
.acc-stk p {
  margin: 0; padding: 0 16px 14px;
  font: 12px/1.55 system-ui; color: rgba(240,238,255,0.65);
}
<details class="acc-stk" name="acc-stk" style="--i:0" open>
  <summary>Top of pile</summary>
  <p>The first card sits flush. Behind it the others fan back in scale.</p>
</details>
<details class="acc-stk" name="acc-stk" style="--i:1">
  <summary>Second card</summary>
  <p>Slightly smaller and pulled up. Click to bring it to the front of the stack.</p>
</details>
<details class="acc-stk" name="acc-stk" style="--i:2">
  <summary>Third card</summary>
  <p>The deepest in the deck. Smaller still, but always reachable.</p>
</details>
25 / 26
Holographic Slot
Pure CSS
Foil A · Aurora

Cool ribbon of violet to cyan, sweeping at 20 degrees. Catches light at any angle.

Foil B · Copper

Warm metallic with a soft inner glow. Reads premium without going gold.

Foil C · Mint

Cooler than gold, less corporate than silver. Quiet and confident.

Open row shows a holographic gradient sweep — like a foil sticker catching light.
.acc-holo {
  background: #15151d; border: 1px solid rgba(240,238,255,0.06);
  border-radius: 10px; margin-bottom: 6px; overflow: hidden;
  position: relative;
}
.acc-holo summary {
  cursor: pointer; list-style: none; padding: 13px 16px;
  font: 700 13px/1 system-ui; color: rgba(240,238,255,0.7);
  position: relative; z-index: 2;
}
.acc-holo summary::-webkit-details-marker { display: none; }
.acc-holo::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(110deg,
    transparent 30%, rgba(156,123,214,0.4) 45%,
    rgba(212,154,92,0.4) 55%, rgba(143,179,163,0.4) 65%,
    transparent 80%);
  background-size: 250% 100%; background-position: 100% 0;
  opacity: 0; transition: opacity .35s, background-position 1.6s ease-out;
}
.acc-holo[open] { border-color: rgba(212,154,92,0.4); }
.acc-holo[open]::before { opacity: 1; background-position: 0% 0; }
.acc-holo[open] > summary { color: #f0eeff; }
.acc-holo p {
  margin: 0; padding: 0 16px 14px; position: relative; z-index: 2;
  font: 12px/1.55 system-ui; color: rgba(240,238,255,0.65);
}
<details class="acc-holo" name="acc-holo" open>
  <summary>Foil A · Aurora</summary>
  <p>Cool ribbon of violet to cyan, sweeping at 20 degrees. Catches light at any angle.</p>
</details>
<details class="acc-holo" name="acc-holo">
  <summary>Foil B · Copper</summary>
  <p>Warm metallic with a soft inner glow. Reads premium without going gold.</p>
</details>
<details class="acc-holo" name="acc-holo">
  <summary>Foil C · Mint</summary>
  <p>Cooler than gold, less corporate than silver. Quiet and confident.</p>
</details>
26 / 26
Aurora Drift
Pure CSS
Northern Lights

Charged particles meet the upper atmosphere. The sky turns to ribbon.

Solar Wind

A constant stream from the sun. Some nights it sings louder than others.

Geomagnetic Storm

When the wind hits hard, the auroral oval expands south. Rare gift for lower latitudes.

Closed rows show a faint hue at the edge; open rows bloom into a slow-drifting aurora.
.acc-drift {
  position: relative; margin-bottom: 6px;
  background: #15151d; border-radius: 12px;
  border: 1px solid rgba(240,238,255,0.06);
  overflow: hidden;
}
.acc-drift::before {
  content: ''; position: absolute; inset: -50%;
  background:
    radial-gradient(ellipse at 20% 30%, rgba(156,123,214,0.5), transparent 55%),
    radial-gradient(ellipse at 80% 70%, rgba(143,179,163,0.4), transparent 55%),
    radial-gradient(ellipse at 50% 50%, rgba(212,154,92,0.35), transparent 60%);
  filter: blur(20px); opacity: 0;
  animation: acc-drift-roll 18s linear infinite;
  transition: opacity .4s;
  pointer-events: none;
}
.acc-drift summary {
  cursor: pointer; list-style: none; padding: 13px 16px;
  font: 700 13px/1 system-ui; color: rgba(240,238,255,0.7);
  position: relative; z-index: 2;
}
.acc-drift summary::-webkit-details-marker { display: none; }
.acc-drift[open]::before { opacity: 0.7; }
.acc-drift[open] > summary { color: #f0eeff; }
.acc-drift p {
  margin: 0; padding: 0 16px 14px; position: relative; z-index: 2;
  font: 12px/1.55 system-ui; color: rgba(240,238,255,0.7);
}
@keyframes acc-drift-roll {
  0%   { transform: translate(0,0) rotate(0); }
  100% { transform: translate(8%,-6%) rotate(15deg); }
}
@media (prefers-reduced-motion: reduce) {
  .acc-drift::before { animation: none; }
}
<details class="acc-drift" name="acc-drift" open>
  <summary>Northern Lights</summary>
  <p>Charged particles meet the upper atmosphere. The sky turns to ribbon.</p>
</details>
<details class="acc-drift" name="acc-drift">
  <summary>Solar Wind</summary>
  <p>A constant stream from the sun. Some nights it sings louder than others.</p>
</details>
<details class="acc-drift" name="acc-drift">
  <summary>Geomagnetic Storm</summary>
  <p>When the wind hits hard, the auroral oval expands south. Rare gift for lower latitudes.</p>
</details>

Related collections