# ThemeKit > A token-driven, **brand-neutral** SwiftUI design system — **205 components** (49 atoms · 88 molecules · 68 organisms), **34 theme presets**, **217 design tokens**, runtime theming, and an AI-native toolchain (MCP server + agent skill + Figma round-trip). Every color, radius, spacing, type style and shadow is a design token resolved at runtime from the active `Theme`; **components never hardcode a color**, so the whole UI re-skins from a single accent color. Swift 6.2 · iOS 17+ / macOS 14+ · zero core dependencies. This is the quick-reference index. Deeper files: - **llms-full.txt** — architecture, token deep-dive, code-generation rules, patterns, integration. - **llms-components.txt** — every component's init + modifiers + usage snippet. - **llms-patterns.txt** — recipes (custom themes, per-subtree theming, custom styles, forms…). ## Philosophy 1. **Token-driven.** No literal colors/radii/spacings in UI — only tokens from the active `Theme`. 2. **Brand-neutral.** One accent hex generates a full palette on-device (`ThemeGenerator`). 3. **Composable & chainable.** Required content/bindings in `init`; everything else a modifier. 4. **AI-native.** The same data drives an MCP server (22 tools), an agent skill, and Figma round-trip. ## Rules for generating ThemeKit code (critical) 1. **Never hardcode a color.** No `.foregroundStyle(.blue)` / `Color(hex:)`. Use `theme.text(.textPrimary)`, `theme.background(.bgWhite)`, or a `SemanticColor`. 2. **Read the theme from the environment:** `@Environment(\.theme) private var theme` (defaults to `Theme.shared`). **Inject once at the root:** `.environment(Theme.shared)`. 3. **Required content/bindings/actions in `init`;** variants/sizes/flags/colors/callbacks are **chainable modifiers** — `Badge("New").badgeStyle(.info).badgeShape(.rounded)`. 4. **Sizes** use `.controlSize(_:)`; **disabled** uses `.disabled(_:)` (native, universal). Never `size:` / `isEnabled:` init args. Many components also expose `.a11yID(_:)` — check the component's modifier list; where absent use SwiftUI's `.accessibilityIdentifier(_:)`. 5. **No hardcoded radius/spacing.** Use `Theme.RadiusRole.box.value` / `Theme.SpacingKey.md.value`. 6. **Recolor** with `Theme.shared.applyGenerated(primaryHex:)` or `ThemePreset.named("dracula")?.apply()`. Scope to one subtree with `.theme(customTheme)`. 7. **Don't re-implement** a Card / Sheet / Toast / field — use the existing component. ## Token system (resolved from the active `Theme`) - **Text** `theme.text(_:)` — `.textPrimary .textSecondary .textTertiary .textDisabled .textHero .textPurple .textSecondaryInverse` - **Surfaces** `theme.background(_:)` — `.bgWhite` (default surface) `.bgHero .bgElevatorPrimary .bgSecondary .bgTertiary` + system/badge tints (24 keys) - **Borders** `theme.border(_:)` (12 keys) · **Foreground** `theme.foreground(_:)` (10 keys) - **Semantic colors** `SemanticColor` — `.primary .secondary .accent .neutral .info .success .warning .error .turquoise .orange .purple .pink`; 50→900 shade ladder; pair with `FillVariant` (`.solid .soft .outline .ghost`). - **Radius** — role: `Theme.RadiusRole.box|field|selector`; size: `Theme.RadiusKey.none|xs|sm|md|base|lg|xl|xl4` (`rd-xs`…`rd-4xl`). - **Spacing** `Theme.SpacingKey.none|xs|sm|md|base|lg|xl|xl4` (`sp-xs`…`sp-4xl`). - **Typography** `.textStyle(_:)` — 34 `TextStyle`s (Montserrat): Display, Heading (2xl→3xs), Label, Body, Overline, Link. - **Shadows** `ShadowStyle.elevated|.tabBar|.soft`. ## Packages (SPM products) - **ThemeKit** — full catalog (re-exports the core). `import ThemeKit`. - **ThemeKitCore** — token engine only (tokens + `@Environment(\.theme)` + presets + generator), zero components, zero third-party deps. - **ThemeKitLottie** — optional Lottie animations (behind the `Lottie` package trait). - **ThemeKitCalendar** — optional token-bound calendar (behind the `Calendar` trait, iOS-only). Default traits are **empty**, so a plain package reference resolves **zero** dependencies. ## Atoms (49) `AnimatedImage`, `Aura`, `Avatar`, `AvatarGroup`, `Badge`, `Barcode`, `Chip`, `CloseButton`, `CodeBlock`, `Confetti`, `Ribbon`, `CountdownTimer`, `DividerView`, `FareFeatureRow`, `FlightStatusBadge`, `GaugeView`, `HelperText`, `Icon`, `IconTile`, `InlineText`, `InputLabel`, `Join`, `Kbd`, `PointsBadge`, `PriceTag`, `ProgressBar`, `StepIndicator`, `QRCode`, `RadialProgress`, `Rating`, `RemoteImage`, `RollingNumber`, `ScoreBadge`, `SearchBadge`, `SeatCell`, `ShareButton`, `Skeleton`, `SkeletonGroup`, `Spinner`, `StatusDot`, `SurfaceView`, `Swap`, `SwapButton`, `Tag`, `CheckableTag`, `TextLink`, `TextRotate`, `TiltCard`, `Title` ## Molecules (88) `Affix`, `AmenityGrid`, `AnchorNav`, `Autocomplete`, `Breadcrumbs`, `ButtonGroup`, `PrimaryButton`, `SecondaryButton`, `OutlineButton`, `GhostButton`, `LinkButton`, `ThemeButton`, `CalendarView`, `Cascader`, `Checkbox`, `CheckboxGroup`, `ImageChip`, `CompactChip`, `ChoseChip`, `FilterChip`, `ChipGroup`, `ColorField`, `ColumnsGrid`, `ControlRow`, `CurrencyPicker`, `DateField`, `DatePriceCard`, `DatePriceStrip`, `Dropdown`, `FieldButton`, `Fieldset`, `FileInput`, `FilterGroup`, `FilterRow`, `Flex`, `FlightRoute`, `GuestSelector`, `InputNumber`, `InstallmentPicker`, `InstallmentSelector`, `LayoverRow`, `MapPriceMarker`, `Masonry`, `Mentions`, `MultiLineTextInput`, `MultiSelect`, `OTPInput`, `Pagination`, `PassengerRow`, `PaymentCardField`, `PriceBreakdown`, `PriceHistogram`, `PriceTrendChart`, `ProgressIndicator`, `QuantityStepper`, `RadioButton`, `RadioGroup`, `RadioButtonGroup`, `RangeSlider`, `RecentSearchRow`, `ScrollShadow`, `ScrubGallery`, `SearchBar`, `SearchField`, `SearchSummary`, `SeatLegend`, `SegmentedControl`, `Select`, `SelectBox`, `Slider`, `SmartSuggestion`, `SortTab`, `SortSummaryBar`, `Space`, `Splitter`, `Stat`, `StepperRow`, `Steps`, `SuggestionRow`, `TextInput`, `ThemeController`, `ThemeToggle`, `TimeField`, `ToggleGroup`, `Transfer`, `TreeSelect`, `TreeView`, `TripTypeToggle` ## Organisms (68) `Accordion`, `AccordionGroup`, `AgentPriceRow`, `AlertToast`, `AncillaryCard`, `BlogCard`, `BoardingPass`, `BrowserFrame`, `Callout`, `Card`, `CardStack`, `Carousel`, `ChatBubble`, `Counter`, `Coupon`, `DataTable`, `DestinationCard`, `Diff`, `EmptyState`, `FareFamilyCard`, `FareSummary`, `FilterBar`, `FilterList`, `FlightCard`, `FlightListItem`, `FlightResultRow`, `FlightTicketCard`, `FloatingActionButton`, `Footer`, `Gallery`, `Hero`, `HeroSurface`, `HotelResultCard`, `ImageCollage`, `InfoBanner`, `KeyValueTable`, `ListRow`, `ListSectionHeader`, `ListView`, `LocationCard`, `LoyaltyCard`, `MapCallout`, `MenuCard`, `NavigationBar`, `NotificationCard`, `PageHeader`, `PagingCarousel`, `PhoneFrame`, `PriceAlertCard`, `PromoBanner`, `RatingSummary`, `ResultView`, `ReviewCard`, `RoomCard`, `SeatMap`, `SegmentedTabBar`, `RadioCard`, `CheckboxCard`, `SheetHeader`, `Sidebar`, `StickyBookingBar`, `ThemePicker`, `TicketStub`, `Timeline`, `Upload`, `UploadList`, `VideoPlayerView`, `WindowFrame` ## Style protocols (flexibility architecture) Six component families are style-driven (`ButtonStyle`-shaped — a `Configuration` + `makeBody`): - `CardStyle` → `.cardStyle(_:)` — cards. Built-ins `.default`, `.outlined`. - `FieldStyle` → `.fieldStyle(_:)` — text fields. Built-ins `.default`, `.muted`, `.underlined`. - `ChipStyle` → chips. Built-ins `.tonal`, `.solid`. - `BarStyle` → `.barStyle(_:)` — bottom/booking bars. Built-ins `.default`, `.floating`. - `MeterStyle` → `.meterStyle(_:)` — progress/meters. Built-ins `.linear`, `.striped`, `.radial`. - `ToastStyle` → `.toastStyle(_:)` — toasts. Built-ins `.default`, `.capsule`. ## Chainable modifiers `.a11yID()` `.a11yLabel()` `.accent()` `.accessory()` `.action()` `.actions()` `.adaptive()` `.addLeg()` `.added()` `.addons()` `.adultRange()` `.airline()` `.airlineIcon()` `.airlineLogo()` `.aisleWidth()` `.alertCount()` `.align()` `.alignment()` `.allowHalf()` `.amenities()` `.animatesValue()` `.arrows()` `.aspect()` `.autocorrectionDisabled()` `.autoplay()` `.avatar()` `.axis()` `.backButton()` `.background()` `.badge()` `.badgeColor()` `.badgeShape()` `.badgeStyle()` `.baggage()` `.barHeight()` `.barWidth()` `.barcode()` `.bezel()` `.block()` `.board()` `.bookingRef()` `.bookmark()` `.borderColor()` `.bordered()` `.bounds()` `.boxed()` `.buttonTitle()` `.cabin()` `.calloutStyle()` `.cascade()` `.changeOnSelect()` `.characterLimit()` `.characters()` `.cheapest()` `.checkable()` `.childRange()` `.children()` `.chipColors()` `.chipStyle()` `.circle()` `.cities()` `.clearable()` `.closable()` `.code()` `.collapsible()` `.color()` `.colors()` `.columns()` `.compact()` `.components()` `.confirmsSuccess()` `.content()` `.contentMode()` `.contentPadding()` `.control()` `.copyable()` `.cornerRadius()` `.count()` `.countLabel()` `.countStyle()` `.couponStyle()` `.cta()` `.ctaIcon()` `.ctaTitle()` `.currency()` `.customSize()` `.dark()` `.dashColor()` `.dashboard()` `.dashed()` `.date()` `.dateRange()` `.dates()` `.deal()` `.debounce()` `.density()` `.departures()` `.description()` `.details()` `.digitCount()` `.dimension()` `.direction()` `.directions()` `.discount()` `.discountBadge()` `.distance()` `.divider()` `.dividers()` `.dots()` `.duration()` `.edge()` `.editable()` `.elevation()` `.emphasis()` `.emptyText()` `.enabled()` `.errorText()` `.excerpt()` `.exists()` `.expandable()` `.expanded()` `.expands()` `.expiry()` `.externalFocus()` `.extra()` `.extraAction()` `.extraDiscount()` `.eyebrow()` `.fade()` `.fadeColor()` `.fareBrand()` `.fares()` `.favorite()` `.features()` `.fileName()` `.fill()` `.fillColor()` `.firstWeekday()` `.flightNo()` `.flippable()` `.focused()` `.footer()` `.format()` `.formatter()` `.fractionDigits()` `.free()` `.from()` `.fullWidth()` `.fuselage()` `.gap()` `.gate()` `.gaugeStyle()` `.gradient()` `.groupStyle()` `.groups()` `.gutter()` `.hasError()` `.hasInfo()` `.header()` `.height()` `.helper()` `.helperText()` `.hidesOnError()` `.highlight()` `.highlightCheapest()` `.highlighted()` `.hint()` `.holder()` `.hourCycle()` `.icon()` `.iconBackground()` `.iconCircleSize()` `.iconColor()` `.iconForeground()` `.iconSize()` `.iconTile()` `.icons()` `.image()` `.imageHeight()` `.imageMaxHeight()` `.imageURL()` `.images()` `.indeterminate()` `.indicator()` `.infantRange()` `.infoMessages()` `.infos()` `.inlineStyle()` `.inputs()` `.intensity()` `.interactive()` `.interestFreeUpTo()` `.interval()` `.itemDisabled()` `.jumper()` `.justify()` `.keyboard()` `.label()` `.large()` `.layout()` `.layoverLabel()` `.leading()` `.leadingIcon()` `.leadingIconColor()` `.leadingImage()` `.leadingSelection()` `.leadingShape()` `.legend()` `.length()` `.level()` `.limit()` `.lineWidth()` `.loading()` `.locale()` `.location()` `.logo()` `.loop()` `.mapFilter()` `.mapHeight()` `.marks()` `.maxAngle()` `.maxCount()` `.maxDays()` `.maxLength()` `.maxResults()` `.maxSelection()` `.maxTags()` `.maxTotal()` `.maxValue()` `.maxVisible()` `.memberName()` `.membership()` `.menuWidth()` `.message()` `.meta()` `.minHeight()` `.minuteInterval()` `.mode()` `.multilineTitle()` `.muteToggle()` `.muted()` `.nested()` `.nextDay()` `.nodeEnabled()` `.notch()` `.notchRadius()` `.note()` `.number()` `.occupancy()` `.onBack()` `.onChange()` `.onChangeEnd()` `.onClear()` `.onClose()` `.onCommit()` `.onDetails()` `.onDirections()` `.onDismiss()` `.onEdit()` `.onFilter()` `.onFinish()` `.onInfo()` `.onMore()` `.onPage()` `.onPhotoTap()` `.onRate()` `.onRemove()` `.onReviewTap()` `.onRowTap()` `.onSearch()` `.onSelect()` `.onSort()` `.onTap()` `.onValidation()` `.onValueChange()` `.optionDescription()` `.optionEnabled()` `.original()` `.originalBelow()` `.overlayTitle()` `.pageSize()` `.passengerLabel()` `.passengers()` `.pathColor()` `.peek()` `.peekOffset()` `.pending()` `.perforation()` `.photos()` `.pieceCount()` `.pill()` `.placeholder()` `.placeholderColor()` `.placeholders()` `.plain()` `.pointer()` `.pois()` `.prefix()` `.presence()` `.price()` `.primaryAction()` `.primaryButton()` `.progress()` `.progressDot()` `.progressLabel()` `.promos()` `.prompt()` `.pulse()` `.qr()` `.quantity()` `.radioStyle()` `.radius()` `.range()` `.rating()` `.ratio()` `.recent()` `.recents()` `.recommended()` `.removable()` `.required()` `.resend()` `.resultCount()` `.returnLeg()` `.reversed()` `.reviews()` `.reviewsSuffix()` `.ribbon()` `.ringColor()` `.roomRange()` `.rooms()` `.rotate()` `.rotation()` `.roundTrip()` `.scarcity()` `.score()` `.scrollAlign()` `.scrollable()` `.searchAccent()` `.searchField()` `.searchSummary()` `.searchable()` `.seat()` `.seatDisplay()` `.seatEnabled()` `.seatSize()` `.secondaryAction()` `.secure()` `.selectAll()` `.selected()` `.selection()` `.selectionAccent()` `.selectionColor()` `.selectionStyle()` `.sentiment()` `.separator()` `.shape()` `.shine()` `.shouldCloseOnSelect()` `.showTitle()` `.showTotal()` `.showsAxis()` `.showsBounds()` `.showsCount()` `.showsDays()` `.showsDivider()` `.showsIcon()` `.showsInfants()` `.showsLabel()` `.showsLabels()` `.showsName()` `.showsPageDots()` `.showsPercentage()` `.showsPremium()` `.showsRooms()` `.showsSeatInfo()` `.showsSeparator()` `.showsSeparators()` `.showsShadow()` `.showsSign()` `.showsValue()` `.showsValueTooltip()` `.showsValues()` `.showsWeekday()` `.showsWeekdayHeader()` `.side()` `.simple()` `.size()` `.skeletonOnly()` `.sliceLabels()` `.small()` `.snapshot()` `.soldOut()` `.solid()` `.spacing()` `.spanMeters()` `.split()` `.starSize()` `.stars()` `.status()` `.stay()` `.step()` `.stepText()` `.stepper()` `.steps()` `.stops()` `.strip()` `.striped()` `.style()` `.subtitle()` `.subtitleStyle()` `.successSegment()` `.suffix()` `.suggestionEnabled()` `.suggestions()` `.supportsOpacity()` `.surcharge()` `.surface()` `.symbol()` `.symbols()` `.systemImage()` `.tabStyle()` `.tabs()` `.tagStyle()` `.tags()` `.tapToToggle()` `.target()` `.textStyle()` `.tierColors()` `.time()` `.times()` `.tint()` `.tinted()` `.title()` `.titleAlign()` `.titleSize()` `.titleStyle()` `.titleTextStyle()` `.titles()` `.totalPrice()` `.track()` `.trackSymbols()` `.trailing()` `.trailingIcon()` `.trend()` `.truncateSubtitle()` `.type()` `.underline()` `.unit()` `.unread()` `.urgency()` `.urgentBelow()` `.validate()` `.value()` `.valueFormat()` `.valueLabel()` `.variant()` `.verified()` `.vertical()` `.videoProgress()` `.visibility()` `.warning()` `.warningText()` `.weight()` `.width()` `.window()` `.wrap()` `.zoomable()` ## Theme presets `default`, `neutral`, `light`, `dark`, `cupcake`, `bumblebee`, `emerald`, `corporate`, `synthwave`, `retro`, `cyberpunk`, `valentine`, `halloween`, `garden`, `forest`, `aqua`, `lofi`, `pastel`, `fantasy`, `wireframe`, `black`, `luxury`, `dracula`, `cmyk`, `autumn`, `business`, `acid`, `lemonade`, `night`, `coffee`, `winter`, `dim`, `nord`, `sunset` ```swift ThemePreset.named("dracula")?.apply() // recolor Theme.shared live Theme.shared.applyGenerated(primaryHex: "7C3AED") // generate a full palette from one accent ThemePicker(selection: $activeThemeID) // tappable grid of all presets ``` ## AI-native toolchain - **MCP server** (`@isamercan/themekit-mcp`, 22 tools) — `list_components`, `get_component_api`, `get_design_tokens`, `get_usage_snippet`, `search_components`, `list_themes`, `generate_theme`, `lint_snippet`, `validate_code`, `a11y_audit`, `scaffold_screen`, `compose_screen`, `design_via_figma_mcp`, `export_figma_variables`, `import_figma_variables`, … (full list in llms-full.txt). - **Agent skill** — `skills/themekit/SKILL.md` (idioms, setup, anti-patterns) + references. - **Figma round-trip** — `export_figma_variables` / `import_figma_variables` and `design_via_figma_mcp`. ## Localization & accessibility - **Strings:** bundled String Catalog, English default (`en`); every user-facing string is also overridable via an init/modifier parameter. Add your own localizations in-app. - **Accessibility:** many components expose `.a11yID(_:)` / `.a11yLabel(_:)` (not global — use SwiftUI's `.accessibilityIdentifier(_:)` where a component lacks it); 44 pt touch targets and RTL-directional mirroring are built in. ## Links - Docs — https://isamercan.github.io/ThemeKit/ - API reference (DocC) — https://isamercan.github.io/ThemeKit/api/documentation/themekit - GitHub — https://github.com/isamercan/ThemeKit · Wiki — https://github.com/isamercan/ThemeKit/wiki - MCP (npm) — https://www.npmjs.com/package/@isamercan/themekit-mcp - Skill — [skills/themekit/SKILL.md](skills/themekit/SKILL.md) · Components ref — [skills/themekit/references/components.md](skills/themekit/references/components.md)