Design System · DS-001

Lago Button System

Internal QA/reference page for the canonical LAGO button primitive. Every example uses the real production Button component. Not linked from any product navigation.

01

Overview

DS-001 Lago Button System is the canonical shared button primitive. One component, two layers: canonical DS-001 variants (12px radius, shadow-free, LAGO tokens) and legacy compatibility variants (unchanged from pre-DS-001 shadcn).

Identifier

DS-001 — Lago Button System

Status: Implemented in production

Canonical primitive

src/components/ui/button.jsx — no second button component.

Canonical variants

PrimaryPrimary DarkNavySecondaryTeal OutlineGhostDestructiveDestructive OutlineLinkIcon

Sizes

Small 32px · Medium 40px (default) · Large 48px · Icon is square at each size

Note:Legacy variants (default, outline, secondary, ghost, destructive) are intentionally preserved for backward compatibility. They are shown in the Variants section below — do not remove them.
02

Variants & Sizes

All canonical DS-001 variants and legacy compatibility variants. Canonical variants carry 12px radius and shadow-free treatment; legacy variants retain their original geometry.

Canonical variants — default state

primary
primaryDark
navy
lagoSecondary
tealOutline
lagoGhost
lagoDestructive
destructiveOutline

Link variant

link — teal text, underline on hover

Legacy compatibility variants

Preserved unchanged for existing consumers. Note the 8px radius (rounded-md) and shadow on some.

default
outline
secondary
ghost
destructive

Sizes — 32px / 40px / 48px

Small (h-8), Medium (h-10, default), Large (h-12). Icon scales with size.

navy
primary
tealOutline
03

Icon Usage, Loading & Disabled

Icon integration (DS-002 Lucide), the canonical loading spinner, and the disabled treatment — all using the real production Button behavior.

Icon + text

Icon-only (square)

variant='icon' is square at every size with zero padding. Pass aria-label when no visible text is present.

32 / 40 / 48px square

Loading state

Full variant colour preserved — no muting, no layout shift. Spinner + aria-busy + native disabled.

Click any button to see the canonical loading spinner for 2 seconds.

Disabled state

Distinct muted treatment (bg-muted text-muted-foreground), not just opacity.

04

Responsive, Accessibility & Reference

Full-width usage, keyboard/focus behavior, and the DS-001 dependency/reference notes.

Full-width / responsive

w-full makes the button fill its container — useful for mobile CTAs and modal footers.

Wrapping behavior

Multiple buttons wrap naturally on narrow screens. The primary action stays dominant.

Accessibility

  • Keyboard: Tab to focus, Enter/Space to activate
  • Focus: Teal focus ring (ring-2 ring-ring ring-offset-2) — visible on keyboard navigation
  • Disabled: Native disabled + pointer-events-none — not clickable, not focusable
  • Loading: aria-busy + native disabled — blocks duplicate submission
  • Icon-only: Consumer must pass aria-label (not enforced at primitive level)

Tab through the buttons above to see the canonical focus ring.

Dependency / reference

Primitive: src/components/ui/button.jsx

Typography: Montserrat, sentence case — Test C approved: Compact 13/18/500 · Medium 14/20/500 · Large 14/20/500 (see Typography Calibration section; production primitive still renders 600 pending calibration)

Geometry: 12px radius (canonical, currently in production — pending calibration), 1px border (outline), 8px icon/text gap (pending calibration)

Colour tokens: --lago-button-* aliases (no new hex)

Iconography: DS-002 Lucide, 16px (sm) / 20px (md, lg)

Note:Canonical variants use lago-prefixed keys where they collide with legacy names (ghost, destructive, secondary). Non-colliding concepts use direct keys (primary, navy, tealOutline, icon).
05

Typography Calibration — Test C Approved

The button typography direction has been approved as Typography Test C. This section documents the approved values and separates them from the still-pending button visual calibration. The production Button implementation is not modified here.

Approved Typography Direction — Test C

SizeFont sizeLine heightWeightToken
Compact13px18px500lago-type-button-compact
Medium14px20px500lago-type-button
Large14px20px500lago-type-button-large
Note:Test C replaces the previous 14/20/600 direction. Weight moves from 600 (semibold) to500 (medium), and the Large size drops from 16/22 to 14/20 — matching Medium. These values are encoded in src/index.css andtailwind.config.js.

Production specimens — current vs. approved

The real production Button is shown below. It currently renders weight 600 (font-semibold). The approved Test C target is weight 500. The visual difference is documented here; the primitive is NOT changed in this reconciliation step.

Small (32px)Compact 13/18/500 target · primitive still 600
Medium (40px)Medium 14/20/500 target · primitive still 600
Large (48px)Large 14/20/500 target · primitive still 600

Pending button calibration — NOT part of Test C

Test C resolves typography only. The following visual properties remain unresolved and will be evaluated in the upcoming button calibration step.

  • Corner radius by button size (currently 12px on canonical variants — not yet finalized)
  • Text/icon vertical centering and optical alignment
  • Icon-to-label spacing (currently 8px / gap-2 — not yet finalized)
  • Optical centering within the button height
  • Actual visual weight in the LAGO UI (production primitive still renders weight 600)
Note:DS-001 remains open. This reconciliation documents the approved typography direction only — it does not close the button visual calibration.
06

Button Calibration — Approved & Implemented

The approved Test C + Candidate B calibration is now implemented in the production Button primitive via compoundVariants. This harness remains the internal visual QA/reference page, showing the selected candidate beside the prior production rendering for regression checking.

Selected candidate:SELECTED CANDIDATE — TEST C + CANDIDATE B

Typography — Test C

Small 13/18/500 · Medium 14/20/500 · Large 14/20/500

Geometry — Candidate B

Small 6px · Medium 8px · Large 10px radius

Note:Approved and implemented in production. The selected candidate (Test C + Candidate B) is now live in src/components/ui/button.jsx via compoundVariants. This page remains the internal visual QA/reference. The specimens below show the selected candidate beside the prior production rendering for regression checking.
07

Test 1 — Radius (Selected: Candidate B)

Candidate B (6 / 8 / 10px) is selected. Shown beside current production (12 / 12 / 12px). Candidate classes override the production rounded-lg via className; the primitive is unchanged.

Test C + Candidate B — SELECTED

Typography 13/18/500 · 14/20/500 · 14/20/500 · Radius 6 / 8 / 10px

navy6 / 8 / 10px
primary6 / 8 / 10px
tealOutline6 / 8 / 10px

Current production

Typography 14/20/600 · Radius 12 / 12 / 12px

navy12 / 12 / 12px
primary12 / 12 / 12px
tealOutline12 / 12 / 12px
Size labels: Small 32px · Medium 40px · Large 48px
Note:Candidate B scales the radius down with button size: 6px on Small, 8px on Medium, 10px on Large. Production uses a flat 12px across all sizes.
08

Test 2 — Typography (Selected: Test C, weight 500)

Test C (weight 500) is selected. Shown beside current production (weight 600). Weight override is applied via className; the primitive is unchanged.

Test C + Candidate B — SELECTED

Typography 13/18/500 · 14/20/500 · 14/20/500 · Radius 6 / 8 / 10px

navy13/18 · 50014/20 · 50014/20 · 500
primary13/18 · 50014/20 · 50014/20 · 500
tealOutline13/18 · 50014/20 · 50014/20 · 500

Current production

Typography 14/20/600 · Radius 12 / 12 / 12px

navy13/18 · 60014/20 · 60014/20 · 600
primary13/18 · 60014/20 · 60014/20 · 600
tealOutline13/18 · 60014/20 · 60014/20 · 600
Note:The Test C className overrides use font-medium (500) and explicit text-[13px] leading-[18px] for Small. Medium and Large keep the production text-sm leading-5 (14/20) with weight 500.
09

Test 3 — Content Alignment & Centering (Selected: Test C + Candidate B)

The selected candidate beside current production across all content configurations. The centering correction is verified below — no arbitrary offsets are introduced.

Size: Small 32px

Test C + Candidate B — SELECTED

navy
primary
tealOutline

Current production

navy
primary
tealOutline

Size: Medium 40px

Test C + Candidate B — SELECTED

navy
primary
tealOutline

Current production

navy
primary
tealOutline

Size: Large 48px

Test C + Candidate B — SELECTED

navy
primary
tealOutline

Current production

navy
primary
tealOutline

Content-centering correction — verification

The production Button uses flex-based centering (items-center justify-center gap-2). The selected candidate inherits this exactly — no arbitrary offsets are added.

  • Button contents centered horizontally (justify-center)
  • Button contents centered vertically (items-center)
  • Icon and text baseline aligned (items-center + shrink-0)
  • Consistent icon-to-label gap (gap-2 = 8px) across all variants/sizes
  • No arbitrary positional offsets — centering is purely flex-based
Note:The className override only changes typography weight/size and corner radius. It does not touch items-center, justify-center, gap-2, or [&_svg]:shrink-0 — so centering is preserved exactly as production.
010

Test 4 — Combined Candidate (Selected: Test C + Candidate B)

The selected candidate beside current production as full rows. Weight and radius interact; evaluate the combined visual effect.

Test C + Candidate B — SELECTED

Typography 13/18/500 · 14/20/500 · 14/20/500 · Radius 6 / 8 / 10px

navy
primary
tealOutline

Current production

Typography 14/20/600 · Radius 12 / 12 / 12px

navy
primary
tealOutline
Note:Compare the two rows as full sets. The selected candidate (Test C + Candidate B) is the visual approval target; current production remains beside it for reference.
011

Test 5 — Real LAGO UI Context (Selected: Test C + Candidate B)

The selected candidate inside realistic LAGO component contexts, with current production beside it. Production components (LagoPageHeader, LagoContentCard) are used as-is and not modified.

PageHeader context

LagoPageHeader primary + secondary actions. Selected candidate first, then current production.

SELECTED — Test C + Candidate B

Experiences

Manage your published and draft experiences.

Current production

Experiences

Manage your published and draft experiences.

ContentCard context

LagoContentCard with footer actions. Selected candidate first, then current production.

SELECTED

Sunset Pontoon Cruise
Muskoka · 2h
A relaxed evening cruise on Lake Rosseau.

Current production

Sunset Pontoon Cruise
Muskoka · 2h
A relaxed evening cruise on Lake Rosseau.

Form context

A typical form footer with cancel + submit.

SELECTED

Form fields would appear here.

Current production

Form fields would appear here.

Modal footer context

A representative modal footer with dismiss + confirm.

SELECTED

Delete experience?

This action cannot be undone.

Current production

Delete experience?

This action cannot be undone.

Table / action context

A representative table row with row actions.

SELECTED

ExperienceStatusActions
Sunset Pontoon CruisePublished
Fishing Charter — Half DayDraft

Current production

ExperienceStatusActions
Sunset Pontoon CruisePublished
Fishing Charter — Half DayDraft
Note:These specimens use real LagoPageHeader and LagoContentCard components. The buttons inside the SELECTED columns carry the Test C + Candidate B className override; the container components themselves are unchanged.
012

Responsive & Accessibility (Selected: Test C + Candidate B)

Desktop, tablet, and mobile examples plus preserved accessibility states. Selected candidate first, then current production.

Responsive — desktop (full row)

Buttons at natural width in a wide container.

SELECTED

Current production

Responsive — tablet (constrained)

Simulated tablet width (max-w-md).

SELECTED

Current production

Responsive — mobile (full-width CTA)

Simulated mobile width (max-w-sm) with full-width primary CTA.

SELECTED

Current production

Accessibility — focus-visible

Tab through to see the teal focus ring (ring-2 ring-ring ring-offset-2).

SELECTED

Current production

Keyboard: Tab to focus, Enter/Space to activate.

Accessibility — disabled

Native disabled + pointer-events-none. Not clickable, not focusable.

SELECTED

Current production

Accessibility — loading

aria-busy + native disabled. Blocks duplicate submission.

SELECTED

Current production

Accessibility — icon-only label

Icon-only buttons require an aria-label (consumer responsibility).

SELECTED

Current production

Note:All accessibility states (focus, disabled, loading, keyboard, aria-label) are preserved from the production Button. The className override only changes typography weight/size and corner radius; it does not touch state behavior.

DS-001 Lago Button preview · PREVIEW COVERAGE COMPLETE. Visual validation pending.