Product showcase
A headphone launch page with a distinct visual identity. Explore the product, choose a package and add it to the local bag. The price and included items update with your choice. Changes stay in this example and reset when you reload.
<style>
.example-stack { display:grid; grid-template-columns:minmax(0,1fr); gap:var(--ds-unit); min-width:0; align-content:start; }
.example-tight { display:grid; grid-template-columns:minmax(0,1fr); gap:calc(var(--ds-unit) / 2); min-width:0; align-content:start; }
.example-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--ds-unit); }
.example-two { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:calc(2 * var(--ds-unit)); align-items:start; }
.example-actions { display:flex; flex-wrap:wrap; align-items:flex-end; gap:calc(var(--ds-unit) / 2); }
.example-between { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:flex-end; gap:var(--ds-unit); }
.example-grow { flex:1; min-width:0; }
.example-section { padding-block:var(--ds-unit); }
.example-between > ds-input { width:calc(10 * var(--ds-unit)); max-width:100%; }
.example-overflow { overflow-x:auto; }
.example-rule { border-top:1px solid var(--ds-border-color); padding-top:var(--ds-unit); }
.example-caption { display:flex; justify-content:space-between; gap:var(--ds-unit); }
.example-caption > * { min-width:0; }
.example-nav { display:flex; justify-content:space-between; align-items:flex-end; gap:var(--ds-unit); }
.example-brand { flex:none; }
.example-footer { padding-top:var(--ds-unit); }
.example-stack [hidden], .example-grid [hidden], .example-two [hidden], .example-tight [hidden] { display:none!important; }
.example-status:empty { display:none; }
.example-title { --ds-sf:calc(2 * var(--sf, 1)); --ds-display-text-size:40px; --ds-typeface-regular:var(--typeface-compressed); }
.example-copy { max-width:calc(24 * var(--ds-unit)); }
.example-shop-hero { display:grid; grid-template-columns:2fr 3fr; gap:var(--ds-unit); align-items:stretch; }
.example-shop-intro { display:flex; flex-direction:column; justify-content:space-between; gap:calc(2 * var(--ds-unit)); padding-block:var(--ds-unit); }
.example-shop-hero ds-image { align-self:start; }
.example-story { display:grid; grid-template-columns:1fr 2fr; gap:calc(2 * var(--ds-unit)); padding-block:calc(2 * var(--ds-unit)); }
.example-product { display:grid; gap:calc(var(--ds-unit) / 2); min-width:0; }
.example-bag { padding-block:var(--ds-unit); border-block:1px solid var(--ds-border-color); }
.example-workspace { --ds-page-nav:calc(8 * var(--ds-unit)); --ds-page-gap:calc(2 * var(--ds-unit)); }
.example-workspace-nav { display:grid; gap:calc(2 * var(--ds-unit)); }
.example-week { display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:calc(var(--ds-unit) / 2); }
.example-day { display:grid; gap:calc(var(--ds-unit) / 2); min-height:calc(4 * var(--ds-unit)); padding-block:calc(var(--ds-unit) / 2); border-top:1px solid var(--ds-border-color); }
.example-day[aria-current] { border-top-color:var(--ds-text-color); }
.example-work { display:grid; grid-template-columns:minmax(0,3fr) minmax(0,2fr); gap:calc(2 * var(--ds-unit)); }
.example-brief { display:grid; gap:calc(var(--ds-unit) / 2); }
.example-contact-sheet { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:calc(var(--ds-unit) / 2); }
.example-contact-sheet > :first-child { grid-column:1 / -1; }
.example-item { box-sizing:border-box; display:grid; grid-template-columns:minmax(0,1fr) auto; gap:calc(var(--ds-unit) / 2); min-height:var(--ds-unit); align-items:end; border-bottom:1px solid var(--ds-border-color); }
.example-item label { display:flex; align-items:flex-end; gap:calc(var(--ds-unit) / 2); min-width:0; }
.example-item label ds-text { flex:1; }
.example-item-meta { display:flex; align-items:flex-end; gap:calc(var(--ds-unit) / 2); }
#balance-stat { --ds-stat-size:40px; --ds-stat-lines:3; --ds-stat-typeface:var(--typeface-compressed); }
.example-stats { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--ds-unit); }
.example-cash { display:grid; grid-template-columns:minmax(0,3fr) minmax(0,1fr); gap:calc(2 * var(--ds-unit)); }
.example-goal { display:grid; grid-template-columns:calc(6 * var(--ds-unit)) minmax(0,1fr); gap:var(--ds-unit); align-items:center; }
.example-audio-hero { display:grid; grid-template-columns:1fr 1fr; gap:var(--ds-unit); }
.example-audio-copy { display:flex; flex-direction:column; justify-content:space-between; gap:var(--ds-unit); padding:var(--ds-unit); background:var(--one-pink-pastel); }
.example-audio-copy .example-title { --ds-typeface-regular:var(--typeface-regular); }
.example-audio-strip { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--ds-unit); padding-block:var(--ds-unit); }
.example-audio-detail { display:grid; grid-template-columns:1fr 1fr; gap:calc(2 * var(--ds-unit)); align-items:center; }
.example-package { display:grid; grid-template-columns:1fr 1fr; gap:calc(2 * var(--ds-unit)); padding-block:calc(2 * var(--ds-unit)); }
.example-specs { display:grid; gap:0; }
.example-specs > div { display:flex; justify-content:space-between; gap:var(--ds-unit); border-bottom:1px solid var(--ds-border-color); padding-block:calc(var(--ds-unit) / 2); }
@media(max-width:900px) { .example-title { --ds-sf:var(--sf, 1); } .example-work { grid-template-columns:1fr; } .example-brief { grid-template-columns:1fr 1fr; gap:var(--ds-unit); } .example-cash { grid-template-columns:minmax(0,1fr); } }
@media(max-width:600px) {
.example-title { --ds-sf:var(--sf, 1); --ds-display-text-size:30px; }
.example-shop-hero,.example-audio-hero,.example-audio-detail,.example-package,.example-two,.example-story,.example-brief { grid-template-columns:1fr; gap:var(--ds-unit); }
.example-shop-intro { padding-block:0; gap:var(--ds-unit); }
.example-shop-hero { --hero-ratio:4 / 3; }
.example-grid { grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--ds-unit) calc(var(--ds-unit) / 2); }
.example-grid > :first-child { grid-column:1 / -1; }
.example-stats { grid-template-columns:repeat(2,minmax(0,1fr)); }
.example-stats > :first-child { grid-column:1 / -1; }
.example-audio-strip { grid-template-columns:1fr; }
.example-week { gap:calc(var(--ds-unit) / 2); }
.example-day { min-height:calc(3 * var(--ds-unit)); }
.example-day ds-text[size=small] { display:none; }
.example-nav .example-nav-secondary { display:none; }
.example-goal { grid-template-columns:calc(4 * var(--ds-unit)) minmax(0,1fr); }
.example-item { grid-template-columns:1fr; }
.example-item-meta { padding-inline-start:calc(1.5 * var(--ds-unit)); }
.example-package { padding-block:var(--ds-unit); }
}
</style><ds-page layout="column" measure="52" data-ds-surface>
<div slot="header" class="example-nav"><ds-text literal strong class="example-brand">Sound / 01</ds-text><div class="example-actions"><ds-button href="#details" class="example-nav-secondary">A closer look</ds-button><ds-button href="#configure" secondary>Choose yours</ds-button></div></div>
<div class="example-stack">
<section class="example-audio-hero"><div class="example-audio-copy"><div class="example-tight"><ds-text literal size="small">For the love of listening.</ds-text><ds-text literal size="display" class="example-title" wrap role="heading" aria-level="1">Press play.<br>Stay a while.</ds-text></div><div class="example-stack"><div data-ds-prose><p>One good pair. Your whole record collection. Meet Sound / 01.</p></div><div><ds-button primary href="#configure">Make it yours · €249 <ds-icon type="right" aria-hidden="true"></ds-icon></ds-button></div></div></div><ds-image src="/examples/images/headphones.jpg" alt="Mint headphones resting across pink and blue paper" ratio="1" loading="eager" position="50% 50%"></ds-image></section>
<div class="example-audio-strip"><ds-stat figure="Wired" label="Just plug in" caption="No pairing. No battery." literal></ds-stat><ds-stat figure="Over-ear" label="Settle into the sound" caption="Soft, full-size cushions" literal></ds-stat><ds-stat figure="Ice blue" label="A little colour" caption="An everyday favourite" literal></ds-stat></div>
<section id="details" class="example-audio-detail example-rule"><ds-image src="/examples/images/headphones.jpg" alt="A closer view of the headphone cushions and cable" ratio="1" position="50% 60%"></ds-image><div class="example-stack"><ds-text literal size="display" strong wrap role="heading" aria-level="2">Nothing between you and the next track.</ds-text><div data-ds-prose><p>Albums deserve more than background noise. Put the phone down, find the comfortable chair and listen all the way through.</p></div><div class="example-specs"><div><ds-text literal tone="muted">Connection</ds-text><ds-text literal >3.5 mm cable</ds-text></div><div><ds-text literal tone="muted">Fit</ds-text><ds-text literal >Over-ear</ds-text></div><div><ds-text literal tone="muted">Finish</ds-text><ds-text literal >Ice blue</ds-text></div></div></div></section>
<section id="configure" class="example-package example-rule"><div class="example-stack"><ds-text literal size="display" strong wrap role="heading" aria-level="2">Your next favourite pair.</ds-text><div data-ds-prose><p>Keep it simple, or take a little extra protection for the journey.</p></div><ds-text literal size="small" tone="muted" wrap>This is a fictional product. No purchase is made.</ds-text></div><div class="example-stack"><div class="example-between"><ds-stat value="249" format="money" currency="EUR" whole label="Your selection" literal></ds-stat><ds-tag>Ice blue</ds-tag></div><div class="example-actions" role="group" aria-label="Choose package"><ds-button control="host" active data-package="Headphones" aria-pressed="true">Headphones</ds-button><ds-button control="host" data-package="Headphones + travel case" aria-pressed="false">With travel case</ds-button></div><ds-text literal id="package-description" wrap tone="muted">Headphones, cable and the next album on your list.</ds-text><div><ds-button primary id="configure-add"><ds-icon type="plus" aria-hidden="true"></ds-icon> Add to bag</ds-button></div><ds-text literal id="product-status" class="example-status" role="status" wrap></ds-text></div></section>
</div><div slot="footer" class="example-footer"><ds-text literal size="small" tone="muted" wrap>Fictional demo. Your changes stay here.</ds-text></div></ds-page> let selection='Headphones';
document.querySelectorAll('[data-package]').forEach(button=>button.addEventListener('click',()=>{selection=button.dataset.package;document.querySelectorAll('[data-package]').forEach(item=>{item.toggleAttribute('active',item===button);item.setAttribute('aria-pressed',String(item===button));});document.querySelector('#configure ds-stat').value=selection==='Headphones'?249:279;document.querySelector('#package-description').textContent=selection==='Headphones'?'Headphones, cable and the next album on your list.':'Headphones, cable and a protective travel case.';document.querySelector('#product-status').textContent='';}));
document.querySelector('#configure-add').addEventListener('click',()=>{document.querySelector('#product-status').textContent=selection+' added to this example bag. No payment is taken.';}); The page uses the current DS1 components and tokens. The example only supplies content, layout composition and local interactions, so shared component updates carry through. Use Code to copy the example, Phone to check the narrow layout, or Show layers to inspect the pieces.