Apple Native Style Guide
Native iOS/macOS companion to the Clapilot UI style guide.
This is the native iOS/macOS companion to the main UI Style Guide. It is written for anyone building SwiftUI screens in the Apple client and lists the FDS tokens, controls, and layout rules that keep native screens visually synced with Clapilot web.
Visual reference page: /clapilot-ios-styleguide.html.
Canonical client file: clients/apple/ClapilotApple/STYLEGUIDE.md.
Core rule
Apple screens should feel synced with Clapilot web: quiet professional workspace, white outlined surfaces, compact controls, navy actions, pale AI gradients, dense list/detail flows, and practical first-view workflows.
The native differences are intentional:
- Use SwiftUI and
FDSiOSMactokens, not copied CSS. - Use SF/System typography, not Avenir or imported web fonts.
- Keep iPhone navigation native: compact rows open dedicated full detail screens.
- Keep bottom composers and reply bars anchored outside scrollable content.
- The profile icon opens profile/settings on a normal tap. A long press on iOS or long-click/right-click on macOS opens the compact account popover for switching among signed-in instances and adding another instance. Keep one account per instance, show the user and instance together, mark the active account with a checkmark, and retain each instance session in its own Keychain slot.
- Agent Orchestrator activity preserves normal runtime chats as first-class
Sessions. Load the full persisted transcript for detail inspection and gate reply, lifecycle, workspace, terminal, diff, checkpoint, and Git controls by the thread projection instead of inferring capabilities from the provider icon. - Agent Orchestrator uses one searchable compact activity list on iPhone, iPad, and macOS instead of an adaptive card grid. Rows expose category, provider, identity, title, latest output, model, status, and latest tool at a glance; iPhone still opens a dedicated full detail screen.
- Agent Orchestrator session details use
FDSSegmentedControlforConversation,Activity, andDetails, plus capability-gatedTerminal,Changes, andFilesfor local repository-backed coding sessions. Keep chronological user/assistant chat in Conversation, work/tool events in Activity, read-only command output in Terminal, read-only Git state in Changes, relative inventory in Files, and identifiers/runtime metadata in Details. Normal chats must not show coding workspace modes; show reply composers only in Conversation. - Detached Agent Orchestrator jobs use the same compact title/context/provider/status header hierarchy as sessions on iPhone, iPad, and macOS. Do not repeat the job title inside the scroll region or show the full job id, runner, workspace, and command metadata grid above the terminal output.
- New Agent uses one model menu across Codex, Claude, and Clapilot Code instead of a separate harness selector. Prefix each model with its harness icon and derive the provider from the selected model; remote jobs expose Codex models only.
- Agent Orchestrator conversations use unboxed assistant markdown, trailing user bubbles, compact recent tool disclosures, collapsed older tool history, and a bounded Terminal output disclosure. Hide routine runtime startup lines and suppress duplicate job prose when a linked session already owns the conversation.
- Agent Orchestrator workspace changes use a dedicated Changes segment for sessions and detached jobs; changed-file trees and diffs do not appear inline in conversation history.
- Keep the follow-up composer outside the scrolling transcript. Put the provider-scoped model menu inside its controls instead of adding a separate Follow-up heading or model form.
- Pending image/file attachments on macOS render inside the composer card via
ClapilotComposerAttachmentStrip(compact tiles above the text input: 56pt image thumbnails, icon+name+size mini cards for other files, each with a remove control); iOS keeps its chip strip above the composer. - The composer "+" attachment menu offers, in order: take photo (iOS only, hidden when no camera is available), choose photo, choose file. Camera capture goes through the shared
ChatCameraCapture/ChatCameraPickerhelpers inSources/Clapilot/Views/ChatCameraPicker.swift, which own availability, localized permission handling, orientation normalization, bounded JPEG encoding, and unique filenames; the captured photo then reuses the existing photo-attachment preparation path. Keep the chat, Team Chat, and coding-agent composers in sync when this menu changes. - Keep the floating chat launcher available across top-level app screens and iPhone detail views. Hide it while the side drawer is open so navigation remains the active layer.
- Add
clapilotScrollableBottomInset(isCompactLayout:)to scrollable lists so final rows clear the iPhone bottom safe area and floating controls. Do not add this extra inset to chat transcripts that already sit above an anchored composer. - Use SF Symbols for normal controls.
Native tokens
- Colors:
Color.fdsBackground,Color.fdsCard,Color.fdsSidebar,Color.fdsAccent,Color.fdsBorder,Color.fdsDot. - Header surface: plain white
Color.fdsBackgroundwith a subtleColor.fdsBorderbottom hairline viaClapilotPageHeaderBand. - Header tint tokens:
Color.fdsHeaderIceBlueFillandColor.fdsHeaderIceBlueBorderremain only for in-content accents (Tasks Kanban column headers, board badges), not the page header band. - Spacing:
FDSSpacing.micro,micro6,small,small10,small12,medium,medium18,medium20,large,xlarge. - Radius:
FDSCornerRadius.standard(14pt) is the single rounded-box radius; legacy aliases such assmall,medium18,medium20, andlargeresolve to the same value. - Shadows:
FDSShadow.standard,light,lightAlt,medium, and.fdsShadowStandardLayered()provide subtle neutral surface elevation for cards, rows, panels, and circular controls; reserve strong/custom shadows for true overlays.
Controls
- Primary actions use
.buttonStyle(.fdsPrimary). - Secondary actions use
.buttonStyle(.fdsSecondary). - Leading-icon actions use
Label. - Utility actions use borderless circular SF Symbol buttons such as
FDSIconButton,AppTopBarCircleButton, or.fdsCircleSurface(...). - Binary settings use
Toggle(...).tint(Color.fdsAccent). - Segmented controls use
FDSSegmentedControlwhere possible. Selected states use deep navy, never the brighter legacy module blue. - Coding-agent approvals and read-only workspace checkpoints share one compact
Approvalsinspector across iPhone, iPad, and macOS. Approval decisions stay explicit, and checkpoint creation is non-mutating. - Coding-agent Git mutations stay inside
Changes: stage/unstage are per-file, commit requires a message, and push requires a second explicit tap. Force push, reset, and arbitrary Git arguments are not native UI actions. - Persist the coding activity filter across launches, but reset each newly selected thread to
Conversation. macOS supports Command-K for activity search and Command-Shift-N for a new agent. - Generic loading states use
ClapilotLoadingAnimation, which renders the Clapilot logo with a clockwise fill and respects Reduce Motion. Chat assistant answer/work indicators use the profile activity selection on both platforms: the compact native three-dot bubble is the default, while explicit Pet selections render their assets. iOS plays built-in Pet GIFs through the embedded animation web view; macOS plays them natively through theNSImageView-backedAgentAnimationNativeGIFView(with Reduce Motion showing the static first frame). Do not add WKWebView-based animation views to macOS rows. - Admin-only operational settings such as Subscription Usage should use the same compact outlined surfaces on iOS and macOS. The macOS menu bar extra uses left click for the chat popover and right click for the compact usage popover.
Haptics
- All haptic feedback goes through
FDSHapticsinFDSiOSMac(no-op on macOS). FDS buttons, toggles, and selection controls fire their own light-impact/selection haptics, so feature code must not double-fire around them. - Feature code adds haptics only for domain events: soft impact when a chat response starts streaming or the app becomes ready, medium impact for sends/stops/drag commits/pull-to-refresh, and notification success/error when AI workflows (mail reply automation, document creation, calendar event save, chat response) finish or fail.
- Remote-push registration is installation-scoped: every locally stored, authenticated account/instance gets its own server subscription for the stable installation ID. Switching accounts keeps all subscriptions; logout removes only the selected account. Notification taps must validate
instance_id, activate that locally known instance first, and only then follow the allowlisted target route. The app badge reflects delivered notifications across all signed-in instances. - Haptics respond to user interaction or workflow completion, never to programmatic state loads or background refreshes.
Lists and forms
- Primary list screens (Mail, News, Notes, Documents, Wiki, Tasks, Automations, Agents, Canvas) render rows directly in the content area — one continuous list with hairline row separators, no surrounding card and no per-row bordered boxes or gaps. Use sticky uppercase group headers only for real groupings (e.g. Mail date buckets, Tasks status lanes); single-entity lists omit the header since the page title already names the screen.
- Rows use two shared heights only: a compact height for the dense Documents list and a standard height for every richer list, kept in one place (
ClapilotListMetrics). - The macOS main app window keeps the native outer window shadow so it remains distinct from other windows. Dashboard tiles, Team Chat surfaces, and anchored chat composers use shared outlined surfaces with subtle FDS elevation.
- The regular-width Team Chat trailing pane lists every accessible channel with the open channel visibly selected. Its agent section includes the primary assistant only while it is invited to that channel and, for channel rooms, only enabled specialized agents invited there; it must not fall back to the primary assistant or global specialist directory when a channel has no agent invitations. Native channel settings mirror web invite/remove and
mention_only/all_messagescontrols. - Selected rows use soft background, tint, or outline emphasis. Do not use the retired left vertical selection bar.
- Form labels sit directly above the field they describe. Use a smaller label-to-field gap than row-to-row gap.
- Fields use white fill, neutral border, outlined inset treatment, and subtle navy focus.
AI surfaces
Use pale blue/lavender gradients for AI-specific smart search, generated drafts, summaries, and recommendations. Keep them functional and subtle, not hero banners.
While an assistant response is streaming, model reasoning may appear temporarily as unboxed multiline text with the shared left-to-right AI gradient. Do not add a surrounding card, icon, or persistent Thinking section; remove the reasoning as soon as final answer or Canvas content starts, keep it out of completion notifications, and stop the animation when Reduce Motion is enabled.
Top-level native app screens should use ClapilotPageHeaderBand for the main top bar plus search/filter controls. On iOS/iPadOS this plain white band (subtle bottom hairline) spans the full header and extends into the top safe area, and content should start directly after it with 0pt root stack spacing. Main compact list surfaces should also use clapilotCompactBottomSafeAreaFill(isCompactLayout:) with 0pt root bottom padding so the screen reaches the bottom edge; protect final rows with scroll content margins instead. Do not use bottom safe-area fill or artificial bottom scroll margins on screens with anchored composers or input bars. macOS keeps its frosted translucent title-bar treatment.
Asset prompt
Use the asset generation prompt in clients/apple/ClapilotApple/STYLEGUIDE.md for native icons, thumbnails, onboarding images, and empty-state art. Prefer SF Symbols for ordinary controls. Custom navigation/sidebar icons must match the flat, full-canvas style of the existing Kunden, Kalender, Aufgaben, Dokumente, and Notizen icons.
