theme

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package theme turns Godwit's settings into semantic colors and sizes drawn from internal/palette, and installs them as the mygo theme.

Index

Constants

View Source
const (
	LineXs, LineSm, LineBase, LineBody, LineLg = 1.4, 1.45, 1.3, 1.3, 1.5
	LineTitle, LineXl, LineX2l, LineDisplay    = 1.4, 1.35, 1.3, 1.25
	LineReading, LineSummary, LineProse        = 1.75, 1.65, 1.6
	LineLede, LineTight                        = 1.7, 1
	LineCJK                                    = 1.4  // a CJK line at the fallback font's normal height (the drafts pane's fields, an AI panel's title, the remote-image notice)
	LineSubject                                = 1.35 // a mail's subject over the reader and the drafts pane
	LineRow                                    = 1.45 // settings' labels, subtitles and section titles with CJK in them (LineFor)
)

Line heights, multipliers of a text's own size, one per TextScale step: tokens.json's, but Base and Body are 1.3, the font's normal line height, which the design's screens render (its 1.5 and 1.6 make list rows 13 px taller than the design's). Reading is mail bodies, translations and the drafts pane; Summary a summary's points; Prose onboarding's and empty states' paragraphs; Lede onboarding's lede; Tight text in a box of fixed height.

View Source
const (
	Hairline        = 1   // dividers
	SidebarWidth    = 248 // the page sidebars, until the user drags them
	SidebarMinWidth = 240 // the narrowest and widest a drag makes them
	SidebarMaxWidth = 480
	// SidebarCollapsePull is how far past SidebarMinWidth a drag goes on
	// before it folds the sidebar away.
	SidebarCollapsePull = 80
	ListWidth           = 340 // the mail list column, until the user drags it
	ListMinWidth        = 280 // the narrowest and widest a drag makes it
	ListMaxWidth        = 560
	TopBarHeight        = 44   // the top bar's least height
	DialogSmWidth       = 440  // confirmations
	BackdropBlur        = 4    // a dialog's backdrop blurs what is behind it this much
	SheetWidth          = 560  // DialogMd: forms, the add-account dialog
	DialogWideWidth     = 640  // DialogLg
	DialogWideMax       = 788  // DialogLg's tallest
	SheetMaxHeight      = 760  // DialogSm's and DialogMd's tallest
	AsideWidth          = 440  // onboarding's left panel
	FormMaxWidth        = 520  // onboarding's form column
	ContentMaxWidth     = 1040 // settings pages
	ControlWidth        = 220  // settings' wide buttons
	SettingsMaxWidth    = 760  // a settings page's column
	SettingsSelectMin   = 200  // a select in a settings row
	SettingsSelectMax   = 280
	UsageSelectMin      = 240 // a select in the model services' 用途 card
	SettingsInputWidth  = 260 // an input in a settings row
	// SignatureEditorHeight is the signature page: its toolbar (4+28+4 and a
	// hairline) over the editor's least 96 and its 10/10 padding; the editor
	// scrolls inside.
	SignatureEditorHeight = 153
	HeadingGap            = 6  // a page heading to its subtitle
	SectionGap            = 10 // a section's title to its card
	PortWidth             = 90 // port fields
	SelectMinWidth        = 120
	FilterMenuMin         = 200 // a search filter chip's menu
	LabelMenuWidth        = 240 // the reader's label menu
	LabelSwatch           = 32  // a label color's button: a 24 dot, a 2 ring when chosen
	LabelSwatchDot        = 24
	LabelSwatchRing       = 2
	LabelIconCell         = 36 // a cell of the label icon grid
	ToastMaxWidth         = 420
	ToastMax              = 3  // toasts shown at once
	TitleButtonHeight     = 24 // buttons in the top bar
	PopupOffset           = 4  // room between a popup and its anchor
	SelectedBorder        = 2  // the border of a chosen tile
	GripWidth             = 3  // a resize grip's line, down the middle of the panels' gap
	GripHeight            = 56
	RingWidth             = 2   // a focused box's ring, outside its border
	QuoteBar              = 2   // the bar left of a quote in a mail body
	ImagePlaceholder      = 64  // an image not loaded, when its size is unknown
	ReaderMaxWidth        = 720 // the reading pane's text column
	AttachmentWidth       = 282 // an attachment in the reading pane, with its download button
	DraftAttachmentWidth  = 286 // an attachment in the drafts pane
	WitMaxWidth           = 760 // the Ask page's conversation column
	CitationsWidth        = 320 // the Ask page's cited mail column
)

Layout sizes that do not follow the density.

View Source
const (
	IconXs, IconSm, Icon, IconMd, IconLg, IconXl     = 12, 14, 16, 18, 20, 28
	MarkSm, MarkMd, MarkLg, MarkXl                   = 20, 28, 40, 48 // provider marks
	CloseButton                                      = 20             // a toast's close button
	LabelChip, LabelChipX, LabelChipXIcon            = 20, 16, 10     // a mail label chip, its × and the ×'s glyph
	Control                                          = 16             // check boxes and radio buttons
	RadioDot, StatusDot                              = 8, 6           // a chosen radio's dot; status dots
	SwitchWidth, SwitchHeight, SwitchThumb           = 32, 18, 14     // a switch's track and thumb
	SwitchInset                                      = (SwitchHeight - SwitchThumb) / 2
	StepDot, PendingDot, DoneBadge                   = 20, 10, 36     // onboarding's check steps, OAuth wait, done mark
	ThemeTileWidth, ThemeTileHeight, ThemeTileGap    = 76, 48, 10     // settings' theme pictures and the space between them
	TileRail, TileSide, TileInset, TileGap, TileLine = 8, 18, 6, 4, 3 // the parts of a theme picture
	SkeletonShort                                    = 160            // a placeholder row's shorter line
	OlderRowHeight                                   = 36             // the list's row while older mail loads from the server
	EmptyIcon, EmptyDescMax                          = 40, 400        // an empty state's icon tile; its text's widest
	GroupHeight, GroupSepHeight                      = 32, 16         // a button group; its separators
	TabUnderline                                     = 2              // the selected underline tab's bottom border
	Watermark                                        = 96             // the empty reader pane's bird
	FormLabelWidth, ModelIDInputWidth                = 96, 132        // a dialog form's label column; the add-model-ID field
	AIButtonHeight, SummaryIndent, CardTracking      = 30, 18, 3      // the reader's Summary/Translate buttons; a summary's bullets; a card value's letter spacing
	SummaryDot                                       = 5              // a summary point's disc
)

Sizes of glyphs and small parts; they do not follow the density.

View Source
const (
	MotionFast = 120 * time.Millisecond
	MotionBase = 200 * time.Millisecond
	// MotionOffset is how far, in DIPs, an overlay rises as it comes in.
	MotionOffset = 4

	SkeletonPulse = 1500 * time.Millisecond // one dim-and-return of a Skeleton
)

Component transitions: MotionFast for hover and selection, MotionBase for moves.

View Source
const BoldWeight = 600

BoldWeight is the font weight of bold text in mail bodies and the editor.

View Source
const FloatInsetBlur = 1

FloatInsetBlur is the blur of FloatInset's inner edge, in DIPs.

View Source
const Mono = "monospace"

Mono is the font for code-like text: the system's monospace font.

Variables

View Source
var (
	ShadowXs = Elevation{{1, 2, 0, 0.05}}
	ShadowSm = Elevation{{1, 3, 0, 0.1}, {1, 2, -1, 0.1}}
	ShadowMd = Elevation{{4, 6, -1, 0.1}, {2, 4, -2, 0.1}}
	ShadowLg = Elevation{{10, 15, -3, 0.1}, {4, 6, -4, 0.1}}
	ShadowXl = Elevation{{20, 25, -5, 0.1}, {8, 10, -6, 0.1}}
)

Shadows, Tailwind v4's as shadcn uses them: Xs under inputs, selects, checkboxes, outline buttons and the page panel; Sm under cards and the selected tab; Md under popovers and select lists; Lg under dialogs, sheets and toasts; Xl for anything above those.

View Source
var HeadingScale = [6]float32{1.6, 1.4, 1.2, 1.1, 1, 1}

HeadingScale is the size of mail body headings h1–h6 in body font sizes.

View Source
var LabelNames = [8]string{"gray", "red", "orange", "amber", "green", "blue", "violet", "pink"}

LabelNames are the label colors' names, in the picker's order.

View Source
var ShadowFloat = Elevation{{0, 0, 1, 0x0a / 255.0}, {2, 8, 0, 0x0a / 255.0}, {4, 80, 8, 0x06 / 255.0}}

ShadowFloat is a floating input's edge and lift in the light appearance: a 1 px ring of the ink at 4% (its outline), then two soft drops, 0 0 0 1px #0000000a, 0 2px 8px #0000000a, 0 4px 80px 8px #00000006. The dark appearance's is an inner edge, FloatInset (kit.Float).

Functions

func Apply

func Apply(c *ui.Context, t Tokens)

Apply makes the frame draw with t: mygo's theme for the appearance with t's colors, the system's font and t's font size. Of(c) returns t afterwards.

func LineFor

func LineFor(s string) float32

LineFor is the line height of a settings label, subtitle or section title s: LineRow with CJK in it, whose fallback font has the taller normal line (1.448), else Body's, as a browser lays out the design's settings pages.

Types

type Elevation

type Elevation []ShadowLayer

Elevation is a drop shadow of one or more layers, drawn in order.

type LabelColor added in v0.3.0

type LabelColor struct{ Dot, Fill, Edge, Text ui.Color }

LabelColor is one label color: Dot on the color picker, Fill under a label set by hand, Edge around one the model set, Text for its name and icon.

type RadiusScale

type RadiusScale struct{ Xs, Sm, Md, Lg, Xl, X2l, X3l, X4l, Full float32 }

RadiusScale are corner radii, Tailwind v4's rounded-* steps (xs 2 … 4xl 32); they do not follow the density. Full rounds a box's short sides into half circles (renderers fit radii as CSS does).

type ShadowLayer

type ShadowLayer struct{ Y, Blur, Spread, Alpha float32 }

ShadowLayer is one layer of a drop shadow: its offset down, blur and spread (negative tucks it under the box), and its opacity of the ink.

type TextScale

type TextScale struct{ Xs, Sm, Base, Body, Lg, Title, Xl, X2l, Display float32 }

TextScale are the interface's text sizes, steps from FontSize. Mail bodies use BodyFontSize. Body is FontSize itself (the user's setting, 14 by default); Base is the denser 13 under it. Title is dialog titles, Xl page headings, X2l brand text and Display the onboarding headline.

func (TextScale) Line

func (s TextScale) Line(size float32) float32

Line returns the line height of the step whose size is size, Body's for a size between steps.

type Tokens

type Tokens struct {
	Dark                                                            bool
	Window, Sidebar, Background, Foreground, Muted, Border, Primary ui.Color
	PrimaryText, SidebarSelected, Hover, Success                    ui.Color
	// HoverTint is a tint of the foreground for what sits on the window's
	// material (the page switch's track, the top bar's ghost buttons), which
	// a solid gray would cover; over white it is Hover's gray.
	HoverTint                                                       ui.Color
	WarningBg, WarningBorder, WarningText, Danger, DangerBg         ui.Color
	SuccessBg, SuccessBorder, SuccessText, DangerBorder, DangerText ui.Color
	InsBg, InsText, DelBg, DelText                                  ui.Color
	Attention, Unread, Input, Ring                                  ui.Color
	// Idle is the grey of a status dot with nothing to report (neutral-400).
	Idle ui.Color
	// Outline is the faint edge of a mark's tile: the foreground at 5%,
	// lighter than Border.
	Outline ui.Color
	// FloatInset is the color of a floating input's inner edge in the dark
	// appearance: white at 20%, drawn inset with no offset or spread and a
	// 1 px blur (FloatInsetBlur), rgba(255 255 255 / 0.2) 0 0 1px 0 inset.
	FloatInset ui.Color
	// DividerHover is a draggable divider hovered or dragged: a step darker
	// than Border.
	DividerHover ui.Color
	// Raised is a dialog's panel: Background in the light, a step up
	// (neutral-900) in the dark, so it stands off the window behind.
	Raised ui.Color
	// MarkTile is the tile under a provider's logo: white in either
	// appearance, as logos are drawn for white.
	MarkTile ui.Color
	// OnSolid is text on a solid status fill (AlertAction): white in either appearance.
	OnSolid ui.Color
	// Highlight marks matched text (search hits) in either appearance, with
	// HighlightText on it.
	Highlight, HighlightText ui.Color
	// Labels are the mail labels' colors in LabelNames' order; Label looks
	// one up by name. An array keeps Tokens comparable.
	Labels [8]LabelColor
	// Scale is the density (1.25 comfortable); outside this package sizes
	// come from c.Theme().Space(n), which it scales.
	FontSize, BodyFontSize, Scale float32
	Radius                        RadiusScale
	Text                          TextScale
}

Tokens are Godwit's semantic colors and sizes, shadcn's neutral ones: Border outlines panels and cards, Input the controls (a step stronger in the dark), Ring the keyboard focus (at half opacity) and a hovered divider. Attention is the amber of status dots that ask for a look (amber-500); Unread, the blue of the dot beside unread mail (blue-500).

func Dark

func Dark() Tokens

Dark is the dark appearance: shadcn neutral's dark values.

func FromSettings

func FromSettings(st core.Settings, systemDark bool) Tokens

FromSettings picks the appearance (Theme "system" follows systemDark), the font sizes, and the density: comfortable rows and paddings are 1.25×.

func Light

func Light() Tokens

Light is the light appearance (spec 7.0).

func Of

func Of(c *ui.Context) Tokens

Of returns the tokens Apply gave this frame, or, without Apply, the default ones for the window's appearance.

func (Tokens) Label added in v0.3.0

func (t Tokens) Label(name string) LabelColor

Label is the label color of a name; an unknown name is gray.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL