Add or duplicate blocks in the customizer to line up any combination. Every specimen is live: click a chip's X (the loading cycle is real, ~800ms) or tab to it, and click a close control to flash the action bound to it. Only the X is clickable on a chip, and it is the chip's only tab stop, though hover and the focus ring cover the whole chip. Each is wired in one line, on every .design-guide__chip-action and every .design-guide__header-action: run(fn) on a chip, run(fn) on a close control. The footer's checkout CTA is wired the same way, on every .design-guide__footer-action: run(fn) again, because the CTA is a button and the footer holds no JS of its own.
Drawer header
Every specimen here is capped at 500px, the width of the slide-cart panel a drawer header actually renders in. Full-bleed across this page is a width the component never has, and at it even the long title fits on one line, so nothing clips. Resize the browser to compare 390 with 1200 and up; the bar stays 63 until 1199 and 65 from 1200.
3 items
3 items
3 items
3 items
Chip
Slide cart footer
Pinned to the real slide-cart panel width the footer renders in: 390px below 768, where the drawer is full-bleed, and 500px from 768 up, the panel's own max-width (Figma 13960:273733). Each cell adds its own padding and border around that panel, so at 390 the specimens are wider than this page. They stay in one column, and the whole stack scrolls sideways (drag or swipe it) rather than the panel being squeezed. The total is a finished string the caller passes in: the footer reads nothing from cart and applies no money filter. The progress-tab slot on the dedicated specimen renders the live cart-progress-tab component; with the slot empty the footer renders no box at all.
Cart progress tab
Figma counts goals (`options`), this component counts badges in `checkpoint_amounts`. Mapping: options=1 is an empty list — dot · line · end-dot, no badge, 31 tall; put the amount in the label. options=2 is two entries (51 tall), options=3 is three. A one-goal live cart must pass the list empty, not a single amount. One badge and four badges are reachable states of the N-ary contract but match no Figma option count — they sit below as Off-design. Badge 1 defaults to the box icon and every later badge to gift, unless checkpoint_icons overrides a slot by index.
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
Free shipping progress
You're this close to unlocking free shipping and a bonus gift with your order
Free shipping progress
Slide cart card
Pinned to the real 500px panel width the card renders inside (Figma 13960:273733), 390 below 768 where the drawer is full-bleed. Each card sits in the panel's own cards list, so it takes that list's inset: 16 up to 1199, 24 from 1200. The message slot renders the real message component, info or warning as each block sets it, with an optional title line above its text: a bundle item is this same default card with an info message whose title names the bundle and whose text names the pack discount. Where a specimen carries a caption, it either names a known conflict rather than a silent workaround or spells out how the specimen is composed.
Slide cart
Pinned to the real panel width, 500 from 768 (Figma 13960:273733) and full-bleed 390 below, the same rule the card and footer groups use. One specimen renders presentation='drawer', closed behind an 'Open the slide cart' trigger — the one specimen on this page that exercises Escape, the Tab trap, focus restore and the scrim, since this guide page is the only place AC-3 can be demonstrated without a theme session. Its trigger does not call the drawer: it publishes slide-cart:active with the panel id, and the drawer opens because it reacts to that topic, as it would for any other sender. The remaining five render presentation='inline', the same panel flat in the page flow with none of that dialog behaviour. Every stub card here is a fixed generic product, not driven by a setting. The all-slots specimen fills the messages slot with a real dismissible warning; dismissing it hides the message and moves focus to that specimen cell. The carousel slot holds the real upsell-carousel: the products picked in the block's Carousel products setting, or four stub product cards when none are picked, titled Bestsellers on the Empty state. The summary slot holds the real order-summary with fixed demo totals. Quick add and Apply run a ~800ms demo action; Apply always succeeds here. Quick add succeeds on the inline specimens and fails inside the drawer, so its error shows in the panel's message area under the drawer header: newest on top, up to three, 4 seconds each.
Add or duplicate blocks in the customizer to line up any combination. Every specimen except Live cart runs a fake ~800ms action bound through the component's own run(fn), and its Demo outcome setting picks what that action returns: quick add succeeds or fails, and Apply succeeds, answers that the code does not apply, or fails as if the network dropped. Failed outcomes log a console.error on purpose, the same one a real failure logs. Hover and Focus states are forced with a class so they can be reviewed without a pointer.
Product card
Pinned to the 164px card width the slide-cart carousel uses. A picked product fills the title, price, both photos and the quick-add variant; the Title, Price and image settings override it one by one. Quick add on Auto sends a product with several variants to its page instead of adding it.
High-Waisted Sculpt Capri Leggings
Upsell carousel
Pinned to the real panel width, 390 below 768 and 500 from 768. Slides come from the picked products, then the picked collection, then generic stub cards. Arrows show from 1200; with four slides or more that overflow the width the carousel loops, below that the arrows disable at either end.
Discount field
Pinned to the real panel width with the order summary's own inline padding. Typing keeps only letters and digits and upper-cases them; Enter or Apply runs the demo action. Applied codes are chips, and the field locks once the code limit is reached. Chips here are static: removing one runs the demo action but the chip stays, since no cart re-renders it.
Order summary
Pinned to the real panel width. Amounts are in cents, the way the cart reports them; Total left empty is Subtotal minus Discount, and a Discount of 0 or empty drops its row. Taxes on Auto follows the store setting that lists the countries with a Taxes row, and every other country shows VAT included under Total.
VAT included
Live cart
Not a demo: this specimen reads and writes the real cart of this session. Quick add on a carousel card adds that product; Apply and a chip's X apply and remove real discount codes. After every change the carousel, the chips and the totals re-render from the server. With an empty cart the carousel falls back to Bestsellers.
The store header row on both surfaces, full width. Resize the window to see the three breakpoints.
Interactive states