Figma / Public website reference / Build with the reference.
Build with the reference.
Copyable local CSS, exact run instructions, and explicit integration boundaries.
A small, inspectable implementation.
Native HTML, one authored stylesheet, and a small behavior script. No build step, server API, framework, tracking, or account integration.
Start locally
cd designs/figma/site
python3 -m http.server 4173
# Open http://localhost:4173/Retrieve the contracts
Extend a component
Use a native element. Give it an accessible name and a stable data-component ID. Reuse spacing and action classes. Document a new variant as a local addition, add realistic long content, then validate 390px and 1440px plus keyboard operation. Never imply that new reference behavior was observed in Figma.
<a class="button secondary" href="surfaces.html">
Explore surfaces <span aria-hidden="true">↗</span>
</a>Integration boundaries
| Concern | Local contract | Production handoff |
|---|---|---|
| Routing | Relative .html pages and native hash anchors | Keep stable route IDs and browser back behavior |
| State | Ephemeral local filters, disclosures, tabs | Do not add persistence without documenting data retention |
| Forms | Client-only validation; no transmission | Connect approved API only with error/retry/consent contracts |
| Analytics | None | Name event purpose, avoid raw user input, obtain appropriate consent |
| Security | textContent for user-provided strings; no HTML evaluation | Validate data and destinations; never embed credentials |
| Assets | Local evidence crops, licensed SDS, and bundled SIL-OFL font fallback | Replace research assets or obtain the required rights |
| Failure | Native navigation and static document remain usable | Keep local text if media fails; avoid blank loading surfaces |
Budgets and ownership
Reference owner: this research package. Review source freshness before release, and refresh after a Figma visual change. Target authored CSS + JS below 80KB uncompressed, no runtime dependencies, and no main-page horizontal overflow at 390px. Static images use lazy loading outside the hero. Browser validation output records actual failures; these budgets are local recommendations.
Contribution and migration
Change tokens centrally, keep older contract IDs stable, explain the evidence or local need, and add a capture/test for changed states. Deprecate a token only after all usages migrate. A new source capture must carry its date and must not silently overwrite a frozen measurement. Publication is a versioned private research reference, not a Figma-supported component package.
Extension contracts, version 1
Original local additions · adopted after an independent handoff exposed missing decisions
Loading action
Use a native button with a stable visible label and accessible name. Reserve an 18px progress slot in every state. Click, Enter, or Space starts one operation. While busy, set aria-busy=true and aria-disabled=true; keep the element focused and in the tab order, and guard the handler against duplicate activation. A polite adjacent status announces progress once. Completion clears both attributes and leaves the label unchanged. The deterministic fixture completes after 900ms; production duration comes from the actual operation. Reduced motion uses a static progress mark. Never represent this timing as observed Figma behavior.
Dismissible inline notification
Require a stable root ID, heading referenced by aria-labelledby, a native dismissal button with a specific accessible name, and data-focus-return pointing to a surviving enabled control. Dismissal sets hidden, preserves the content and surrounding query, returns focus to that target, and emits a bubbling notification:dismiss event. The consumer announces dismissal once. Essential notices have no expiry timer. An explicit restore control may reveal the same instance. Use the local informational lavender token; error messages instead require the named error role and recovery copy.
Combined offline and empty collection
Local static resources remain searchable offline. Read navigator.onLine and listen for online/offline events, treating that signal only as browser connectivity. Preserve query and category across transitions. Show offline context and filtered-empty guidance together; neither replaces the other. One atomic polite live region announces the count and connectivity context. Retry checks the current browser signal without making an unapproved remote request and must not claim endpoint recovery. Only explicit Reset clears filters and returns focus to the search input. Long translated text wraps; DOM and keyboard order stay unchanged.
Runnable implementations
Open the four extension examples → · Exact added APIs → · Extension CSS → · Extension JavaScript →
Acceptance: loading width drift ≤0.1px, one activation during busy, no lost focus or query, no page overflow at 390/768/1440px, explicit recovery, no transmitted data. Test scripts and captures remain in evidence/handoff/.