App Home Tab Design Proposal
Date: 2026-04-22
Scope: Design + implement the @brandbot App Home tab as a persistent premium brand surface.
Why the Home tab matters for this product
The Home tab is the ONLY always-visible Slack surface we control — when a user clicks the bot in their sidebar, the Home tab renders. Unlike slash command responses (ephemeral, single-use, disappear on channel switch), Home persists. For a "premium brand agent" product, this is the single best place to deliver the product-surface-not-chat-log experience.
Block budget: 100 (vs. 50 for messages). Roughly 2× what we have to work with on /brand {category}.
Design principles applied
Running the same /critique + /arrange + /typeset lens, plus the shared design language from docs/SLACK-UX.md:
- Hierarchy: Logo hero → identity anchors (tagline, mission one-liner) → palette preview → quick jumps → help footer. Eye flows top to bottom in two-second scans.
- Scannability: User opens Home, should see at-a-glance: "this bot is California Forever's brand guide." Reading any further is optional.
- Restraint: Don't duplicate every
/brandresponse inline. The Home is the index — it points to the slash-command surfaces and the brand guide site. - Rhythm: Dividers between groups only. Same tight-group + generous-gap pattern as the responses.
- Brand presence: Logo image + palette swatches create visual identity within the Home tab. Don't rely on typography alone.
Proposed layout
[image block] CF navy wordmark on beige (600px wide PNG via rasterizer)
← hero identity anchor, visual signature
header: California Forever Brand Guide ← 📖 prefix? or clean?
context: Powered by Grain & Mortar · {lastUpdated}
divider
header: Tagline
rich_text_preformatted: "Building the next great American city." ← copy button
divider
header: Mission
section: [one-line truncated mission, plain prose]
divider
header: Colors at a glance
rich_text: (rich_text_section with color swatches, bold name, hex — same pattern as /brand colors but condensed to 4-6 top colors)
context: Full palette → <url|/brand colors>
← "Full palette" context points to the slash command AND the web section
divider
header: Explore the guide
[actions block with URL buttons]:
[Colors] [Typography] [Voice & Tone] [Messaging] (row 1 — max 5 per actions block)
[Foundation] [Logo] [Applications] [Icons] (row 2 — second actions block)
[Photography] [Open full brand guide →] (row 3)
Each button is a URL button linking to the brand guide site section. Not a slash-command trigger — this keeps things simple (no interactivity endpoint wiring needed for v1) and the full brand guide UX is richer than the Slack summary anyway.
divider
header: Use in Slack
rich_text_list:
• `/brand colors` (code) — palette with hex + usage
• `/brand voice` (code) — traits, tone, writing rules
• `/brand messaging` (code) — tagline, pitch, pillars
• …
context: 10 commands available. Try `/brand help` for the full list.
divider
context: 📖 View the full brand guide → <url|california-forever-brand-guide.vercel.app>
Total block count: ~25 blocks. Well under the 100 limit, room to expand.
Interaction model
v1 — URL buttons only. Every button in the "Explore the guide" actions block is a URL button (url property, no action_id needed). Clicking opens the brand guide site section in a new tab. This is the simplest approach — no interactivity endpoint wiring, no request signing for button clicks, no action_id → handler routing.
v2 (later) — Action buttons. Wire /app/api/slack/interactivity/route.ts + action_id-based routing so buttons trigger things INSIDE Slack (e.g. post the /brand colors response to the user's DM). Requires a new Slack scope (interactivity.is_enabled: true in manifest) and a re-install. Defer until v1 lands.
Publish trigger
Event-driven via app_home_opened. Subscribe in the Slack app manifest. When the event fires for a user, the /api/slack/events handler:
- Looks up tenant by team_id.
- Fetches the tenant's brand content (colors + messaging + brand-foundation minimally — three API calls in parallel).
- Builds the Home view.
- Calls
views.publishwith the user_id and the view.
Caching: render in-memory per (tenant, user) with a short TTL (60s) so repeat opens in the same minute skip the fetches. Content updates propagate on the next open past TTL.
Scope addition: app_home_opened is a bot event; subscribing requires no new OAuth scope (reads tenant's own bot events). Manifest update + re-install only.
What this doesn't cover
- Buttons that trigger slash-command responses in-channel. That's the v2 interactivity route. For now, users go to the brand guide site or use the slash command themselves.
- Per-user personalization. Every user in a workspace sees the same Home tab for v1. Personalization (e.g. "you've looked up colors 12 times") is a long-tail enhancement.
- Dynamic content based on what's been edited. If the brand guide site is updated, the Home reflects it on the next open (60s cache). No push invalidation.
What happens next
- Approval on this doc.
- Implement in these steps:
- Update
slack-app-manifest.jsonto subscribe toapp_home_opened. - Reinstall the app in G&M workspace (manifest changes require re-install). - Build aformatHome()formatter inlib/slack/format.tsthat returns the view object. - Extendapp/api/slack/events/route.tswith anapp_home_openedhandler that fetches tenant content and callsviews.publish. - Smoke-test by opening@brandbot's Home tab in G&M Slack. - Preview via
scripts/post-redesign-previews.tsanalog (or directviews.publishto Eric's user). - Iterate on layout.
- Commit atomically, push, verify in Slack.
- Update
docs/SLACK-UX.mdwith the Home tab spec + publish flow.
Open questions
- Emoji on top header?
📖 California Forever Brand Guideor justCalifornia Forever Brand Guide? The slash-command responses use emoji anchors per category; the Home tab IS the whole guide, not one category. Leaning toward no emoji here — cleaner. - "At a glance" color subset — which colors? Top 4 from the primary palette (Navy, Stone Blue, Blue, Beige)? Or top 2 + a divider + 2 accents? Defer to the first preview.
- Logo hero image — which variant? Navy-on-beige feels more "daytime" and grounded for a brand reference tool. Cream-on-navy would be higher contrast. Leaning Navy-on-beige for the default Home.