Appearance
Component inventory
Part of the design-brief package (issue #263). The reusable pieces a generated design must define, each with the behavioral requirements the visual design has to satisfy. Components reference only
--ns-*theme tokens (see brand-tokens.md) so every one restyles with a theme switch.
Implementation registries
Two shared component kits implement this inventory — import from a kit rather than re-declaring .btn/.card/.tier-badge styles per page:
- Public kit —
$lib/public/ui(issue #824):Button(primary/secondary/quiet,big, ≥44px targets),Card(default/accent/muted tones),TierChip(equal-weight by construction — see Badges & tier markers),Tabs+tabs.ts(WAI-ARIA tablist,?tab=URL-sync — logic shared with the admin kit),NudgeCard(the right-sizing nudge's success-trio shell),SectionHeading,FieldGroup(reset fieldset+legend). Consumed by home,/select(stepper + results), and/compare. - Admin kit —
$lib/admin/ui(issue #308): the admin register — denser metrics, danger/ghost variants, tables, forms. See itsindex.tsheader for conventions.
Buttons
- Variants: primary (one per screen — the forward action), secondary (Previous, Start fresh), tertiary/link (dismiss, "skip to compare"), and destructive (admin only).
- Behavior: visible hover, active, focus-visible (use
--ns-color-focusas a ring — never remove outlines), and disabled states. Hit target ≥ 44px on touch. Primary usesaccent/on-accent; hover usesaccent-hover. - Hand-off buttons (configurator/resources deep links) are styled as primary-family actions, not external-link afterthoughts — they continue the journey (principle 4).
Cards
- Persona track cards (home): title + one-line buyer-facing description; entire card clickable with a single focus outline; equal heights in a row of 1–4; must survive long track names and 2-sentence descriptions.
- System cards (results shortlist): photo (card rendition), name, tier badge, one-line fit summary, actions. Must render acceptably with no photo (no gray placeholder box — collapse the media slot).
- Education callout (stepper): reading-typography block visually distinct from controls; supports 1–3 short paragraphs; never collapsible.
Stepper & progress
The signature component (see the screen inventory).
- Progress indicator: "Step N of M" text plus a visual track/fill; must scale from 5 to 20 steps without layout change; announces progress to screen readers (
ariacurrent/total). - Step transitions: advancing feels immediate (< 100ms perceived); optional subtle motion must respect
prefers-reduced-motion. - Option group: radio semantics, one column; label + optional "what this means" line; selected state obvious at a glance (not just a dot — fill/border shift); re-clicking the selection clears it, so the selected state must also read as a toggle.
- Boundaries: no Previous on step 1; final forward action reads See results.
- Numbered step marker (home how-it-works, #977): the 1-2-3 markers match the nanawall.com/resources treatment — a large outlined ring (transparent fill, brand-colored ring + numeral), fluid
clamp(2.75rem, 8vw, 3.5rem). Ring and numeral are--ns-color-accent, so each theme renders its own accent (nanawall teal · graphite amber · linen terracotta · pressroom vermillion) with no raw blue; the markup is identical across themes, only tokens differ. Numeral-on-circle is AA in every theme (accent≥ 4.5:1 on the section background), enforced by theaccent-on-surfacepair in the #845 token gate.
Forms (admin register)
- Text/number/select/textarea/toggle with persistent labels (no placeholder-as-label), inline validation on blur, error text tied via
aria-describedbyusing thedangertrio, save success/failure feedback, and dirty-state protection cues. Dense vertical rhythm — admin is a working tool.
Comparison table
- Sticky header (system names + photos) and sticky first column (attribute names); row hover; difference highlighting (rows where values differ); right-sizing nudge attachable to a column; "??"/missing cells as em-dash, visually quieter than real values; groups of ~60 attributes by category with collapsible group headers; horizontal scroll pattern on mobile with the first column pinned. Numeric/technical values may use
--ns-font-mono.
Media gallery & responsive image
Existing primitives (MediaGallery.svelte, ResponsiveImage.svelte, VideoEmbed.svelte) the design skins, not reinvents.
- Renditions: thumb 160w · card 480w · hero 1200w · full 2000w (AVIF/WebP/ JPEG). Design to these widths; art direction in art-direction.md.
- Gallery: primary image + thumbnail strip, keyboard navigable, captions optional; video embeds get a poster frame, never autoplay with sound.
Slideshow+slideshow.ts(#976): one framed image visible at a time — the deliberate replacement for a vertical image pile. WAI-ARIA carousel (role=group+aria-roledescription, per-slide labels, polite live region for user-driven changes only); prev/next buttons + a dot position indicator;ArrowLeft/Right/Home/Endcycle. Auto-advance is gated onprefers-reduced-motionand pauses on hover/focus. Graceful degradation (H5): the controls render only after hydration, so with JS or images absent the section is a single static framed image (MediaFrametheme tokens) — never dead buttons or a pile. Pure index logic lives inslideshow.ts.
Right-sizing nudge
The product's hero element (principle 2 — first-class, affirmative).
- A card-level call-out: "recommended X, but Y satisfies your requirements for less" with the cheaper system's name, what it still satisfies, and its own action (view/compare). Uses the
successtrio (soft fill + border) — never warning yellow or muted gray. Must work inside the results page and attached to a comparison-table column. - Shipped as
NudgeCard(#824/#825):variant="card"(default) is the standalone results form, rendered directly under the lead recommendation with the compare-pair pre-filled action;variant="column"is the compact comparison-column attachment (same success semantics, tighter rhythm) — consumed by the compare column crown.
Coverage warning
- Calm honesty for partial data or an unmet requirement:
warningtrio, icon + short text + "verify with an advisor" action. Distinct from both the nudge (positive) and errors (danger). Never blocks interaction.
Resume banner / welcome-back card
- Non-modal card above hero (home) or stepper (
/select): state line ("3 of 14 answered" / "You completed a selection"), primary resume action, secondary start-fresh, dismiss. Must not push the hero below the fold on mobile.
Badges & tier markers
- Tier labels (Budget / Mid / Premium / Ultra) as neutral, equal-weight badges — differentiated by label, not by escalating visual richness (principle 2: tiers are fit descriptors, not a podium).
- Status badges (admin): published/draft/retired with
success/neutral/warningtreatments.
Admin data tables
- Dense rows, sortable headers, row actions (edit/retire), pagination or virtualized scroll for 60+ rows, empty state with a create action, bulk-select pattern, and an audit-trail row treatment (
--ns-font-monotimestamps). Retired/unpublished rows visually muted but readable.
Shared interaction rules
- Every interactive element: hover + focus-visible + active states from theme tokens; focus ring via
--ns-color-focus. - Motion: 0.15s ease-in-out (the house idiom,
--nw-transition-fast) as the default; all motion behindprefers-reduced-motion. - Overlays/modals (admin confirms):
--ns-color-overlayscrim, focus trap, Escape closes. Public surfaces avoid modals entirely (the resume offer is a card, not a dialog).