lotusui the ikaito design language for Gio — desktop, mobile, web
GitHub

Card

The grouping surface: three variants, size-scaled padding, everything else composed.

Card is a rounded panel around arbitrary content. Header, body and footer are composition — stack labels, media and buttons; the card only owns chrome and padding. It honors Constraints.Min.Y, which is what makes equal-height rows work inside grids.

Installation

Use the module import (the default), or own the source: lotusui add vendors the component into your app and lotusui update keeps the copy mergeable — see Registry.

Go
go get github.com/ikaito-com/lotusui

# or vendor the source into your app:
go run github.com/ikaito-com/lotusui/cmd/lotusui add card

Usage

Header, content and footer are COMPOSITION — the login card: title and description with an action at the end, form fields, full-width footer buttons.

Go
lotusui.Card(th, lotusui.CardOpts{}, lotusui.VStack(th.Space.MD,
	header("Login to your account", "Enter your email below to login to your account",
		lotusui.Button(th, &signup, "Sign Up", lotusui.ButtonOpts{Variant: lotusui.ButtonLink})),
	emailField, passwordField,
	lotusui.FullWidth(lotusui.Button(th, &login, "Login", lotusui.ButtonOpts{})),
	lotusui.FullWidth(lotusui.Button(th, &google, "Login with Google", lotusui.ButtonOpts{Variant: lotusui.ButtonOutline})),
))

Variants

CardOutline (bordered panel, default), CardElevated (soft shadow — the design language's standard surface, also available as SurfaceCard), CardSubtle (tinted fill, no border).

Go
lotusui.Card(th, lotusui.CardOpts{Variant: lotusui.CardElevated}, content)
lotusui.Card(th, lotusui.CardOpts{Variant: lotusui.CardSubtle}, content)

Sizes and spacing

The shared Size presets scale the content padding; app-wide spacing customization goes through the theme's WithSpace scale — the token, not a per-card knob.

Go
lotusui.Card(th, lotusui.CardOpts{Size: lotusui.Size2XL}, content)

Image

The event card: a 16:9 cover (an image in your app) with a badge overlaid, title, description, and a full-width action.

Go
lotusui.Card(th, lotusui.CardOpts{}, lotusui.VStack(th.Space.MD,
	cover, // media with lotusui.Badge overlaid
	lotusui.LabelCardTitle(th, "Design systems meetup").Layout,
	description,
	lotusui.FullWidth(lotusui.Button(th, &view, "View Event", lotusui.ButtonOpts{})),
))

Edge to edge

A muted, scrolling well inside the card — long content (terms, logs) scrolls while the title and the action stay fixed.

Go
lotusui.Card(th, lotusui.CardOpts{}, lotusui.VStack(th.Space.SM,
	lotusui.LabelCardTitle(th, "Terms of Service").Layout,
	func(gtx C) D { return lotusui.Scrollable(th, &scroll, gtx, terms) },
	lotusui.FullWidth(lotusui.Button(th, &accept, "Accept", lotusui.ButtonOpts{})),
))

Horizontal

Go
lotusui.Card(th, lotusui.CardOpts{}, lotusui.HStack(th.Space.MD,
	media, textColumn))

API

OptionTypeDescription
VariantCardVariantCardOutline (default), CardElevated, CardSubtle.
SizeSizeScales the content padding (Size2XS–Size2XL).
contentlayout.WidgetLayout parameter — arbitrary content; header/body/footer are composition.

Every demo on this site is the real Go component compiled to WebAssembly — one gallery app, one bundle, addressed by URL hash.