From eced6404c34ac39ef641ff1e5b6e3d6273eb1574 Mon Sep 17 00:00:00 2001 From: akumar-99 Date: Thu, 11 Jun 2026 08:00:30 +0530 Subject: [PATCH] Add brand identity: logo, themed docs site, richer landing page - Hand-crafted SVG logo (chat bubble + ascending bars) used as navbar logo, hero image, favicon, and README mark - Custom VitePress theme: ink/amber brand palette, hero gradient, feature-card hover, dark-mode variants - Landing page gains "How a morning works" steps, a styled example thread, a self-host comparison table, and a CTA section - Web dashboard restyled to match the brand (top bar with logo) --- README.md | 13 ++- docs/.vitepress/config.mts | 13 +++ docs/.vitepress/theme/index.ts | 4 + docs/.vitepress/theme/style.css | 188 ++++++++++++++++++++++++++++++++ docs/index.md | 108 ++++++++++++++++-- docs/public/favicon.svg | 11 ++ docs/public/logo.svg | 11 ++ src/dashboard/dashboard.ts | 31 ++++-- 8 files changed, 355 insertions(+), 24 deletions(-) create mode 100644 docs/.vitepress/theme/index.ts create mode 100644 docs/.vitepress/theme/style.css create mode 100644 docs/public/favicon.svg create mode 100644 docs/public/logo.svg diff --git a/README.md b/README.md index 4eb4c8e..93cffb6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ -# AsyncUp +

+ AsyncUp +

-[![CI](https://github.com/asyncup-dev/asyncup/actions/workflows/ci.yml/badge.svg)](https://github.com/asyncup-dev/asyncup/actions/workflows/ci.yml) -[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) +

AsyncUp

+ +

+ CI + License: MIT + Docs +

**Open-source, self-hosted async daily standups for Google Chat.** No meetings, no SaaS, no telemetry โ€” one small container you run yourself, forever free. diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 61c7d86..c61ae6f 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -4,7 +4,20 @@ export default defineConfig({ title: 'AsyncUp', description: 'Open-source, self-hosted async daily standups for Google Chat', base: process.env.DOCS_BASE || '/', + head: [ + ['link', { rel: 'icon', type: 'image/svg+xml', href: `${process.env.DOCS_BASE || '/'}favicon.svg` }], + ['meta', { name: 'theme-color', content: '#15435f' }], + ['meta', { property: 'og:title', content: 'AsyncUp โ€” async daily standups for Google Chat' }], + [ + 'meta', + { + property: 'og:description', + content: 'Open source and self-hosted: standup prompts, date threads, blocker tracking, AI summaries with your own key.', + }, + ], + ], themeConfig: { + logo: '/logo.svg', search: { provider: 'local', }, diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..d050e52 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme'; +import './style.css'; + +export default DefaultTheme; diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css new file mode 100644 index 0000000..9948adb --- /dev/null +++ b/docs/.vitepress/theme/style.css @@ -0,0 +1,188 @@ +/** + * AsyncUp brand theme + * Ink ocean blues + sunrise amber, matching the logo. + */ +:root { + --au-ink: #15435f; + --au-ink-deep: #0e2f44; + --au-amber: #ff8a3d; + --au-amber-soft: #ffae52; + --au-sand: #fff4e6; + + --vp-c-brand-1: #176d94; + --vp-c-brand-2: #1d83b2; + --vp-c-brand-3: #15435f; + --vp-c-brand-soft: rgba(23, 109, 148, 0.14); + + --vp-button-brand-bg: var(--au-amber); + --vp-button-brand-border: var(--au-amber); + --vp-button-brand-text: #3b2204; + --vp-button-brand-hover-bg: var(--au-amber-soft); + --vp-button-brand-hover-border: var(--au-amber-soft); + --vp-button-brand-hover-text: #3b2204; + --vp-button-brand-active-bg: #f07b2e; + --vp-button-brand-active-border: #f07b2e; + + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: linear-gradient(115deg, #15435f 30%, #ff8a3d); + --vp-home-hero-image-background-image: radial-gradient( + circle at 50% 45%, + rgba(255, 174, 82, 0.55) 0%, + rgba(23, 109, 148, 0.35) 55%, + transparent 72% + ); + --vp-home-hero-image-filter: blur(56px); +} + +.dark { + --vp-c-brand-1: #5cb6dd; + --vp-c-brand-2: #7cc6e6; + --vp-c-brand-3: #1d83b2; + --vp-c-brand-soft: rgba(92, 182, 221, 0.16); + --vp-home-hero-name-background: linear-gradient(115deg, #7cc6e6 25%, #ffae52); +} + +.VPHero .VPImage { + border-radius: 22%; + box-shadow: 0 18px 50px rgba(21, 67, 95, 0.35); +} + +.VPNavBarTitle .title { + font-weight: 700; + letter-spacing: -0.01em; +} + +.VPFeature { + border: 1px solid transparent; + transition: border-color 0.25s, transform 0.25s; +} +.VPFeature:hover { + border-color: var(--vp-c-brand-1); + transform: translateY(-2px); +} + +/* ---------- landing-page sections ---------- */ + +.au-section { + max-width: 1152px; + margin: 0 auto; + padding: 48px 24px 8px; +} +.au-section h2 { + border-top: none; + font-size: 26px; + text-align: center; + margin-bottom: 8px; +} +.au-section > p.au-sub { + text-align: center; + color: var(--vp-c-text-2); + margin: 0 auto 32px; + max-width: 560px; +} + +.au-steps { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; +} +@media (max-width: 720px) { + .au-steps { grid-template-columns: 1fr; } +} +.au-step { + background: var(--vp-c-bg-soft); + border-radius: 14px; + padding: 22px 22px 18px; + position: relative; +} +.au-step .num { + display: inline-flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: 10px; + background: linear-gradient(135deg, var(--au-amber-soft), var(--au-amber)); + color: #3b2204; + font-weight: 800; + margin-bottom: 12px; +} +.au-step h3 { margin: 0 0 6px; font-size: 17px; } +.au-step p { margin: 0; color: var(--vp-c-text-2); font-size: 14px; line-height: 1.55; } + +/* chat thread mockup */ +.au-thread { + max-width: 660px; + margin: 0 auto; + background: var(--vp-c-bg-soft); + border: 1px solid var(--vp-c-divider); + border-radius: 16px; + padding: 22px 26px; + font-size: 14px; + line-height: 1.5; +} +.au-thread .day { + font-weight: 700; + color: var(--vp-c-text-1); + padding-bottom: 10px; + border-bottom: 1px solid var(--vp-c-divider); + margin-bottom: 14px; +} +.au-msg { + display: flex; + gap: 12px; + margin: 14px 0; +} +.au-msg .avatar { + flex: none; + width: 34px; + height: 34px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 17px; + background: var(--au-sand); +} +.dark .au-msg .avatar { background: #3a3022; } +.au-msg .bubble { + background: var(--vp-c-bg); + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + padding: 10px 14px; + flex: 1; +} +.au-msg .who { font-weight: 600; margin-bottom: 4px; } +.au-msg .q { color: var(--vp-c-text-3); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; margin-top: 8px; } +.au-msg .q:first-of-type { margin-top: 0; } +.au-msg .blocked { color: #c2410c; } +.dark .au-msg .blocked { color: var(--au-amber-soft); } +.au-wrapup { + margin-top: 16px; + background: linear-gradient(135deg, rgba(255, 174, 82, 0.16), rgba(23, 109, 148, 0.12)); + border-radius: 12px; + padding: 12px 16px; + font-weight: 500; +} + +/* comparison table */ +.au-compare table { width: 100%; display: table; } +.au-compare th:first-child { width: 38%; } +.au-compare td:nth-child(2) { font-weight: 600; } + +.au-cta { + text-align: center; + padding: 40px 24px 72px; +} +.au-cta a.button { + display: inline-block; + background: var(--au-amber); + color: #3b2204; + font-weight: 700; + border-radius: 24px; + padding: 11px 26px; + transition: background 0.2s; + text-decoration: none; +} +.au-cta a.button:hover { background: var(--au-amber-soft); } +.au-cta .alt { display: block; margin-top: 14px; color: var(--vp-c-text-2); font-size: 14px; } diff --git a/docs/index.md b/docs/index.md index 48011c0..a2926d7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,10 +4,13 @@ layout: home hero: name: AsyncUp text: Async daily standups for Google Chat - tagline: Open source. Self-hosted. No meeting required. + tagline: Open source. Self-hosted. Your data, your keys, your database โ€” no meeting required. + image: + src: /logo.svg + alt: AsyncUp actions: - theme: brand - text: Get started + text: Get started โ†’ link: /guide/getting-started - theme: alt text: View on GitHub @@ -16,20 +19,103 @@ hero: features: - icon: ๐Ÿ’ฌ title: One-tap standups - details: A DM card opens a four-question form โ€” yesterday, today, blockers, mood. No chat interrogation. + details: A DM card opens a four-question form โ€” yesterday, today, blockers, mood. Edit until the deadline; the posted card updates in place. - icon: ๐Ÿงต title: Tidy date threads - details: Every answer lands as one card per person under the day's thread in your team space. + details: Every answer lands as one card per person under the day's thread. The wrap-up posts the count and exactly who's missing. + - icon: ๐Ÿ–๏ธ + title: Away-aware + details: Skip-today button, vacation mode, and automatic Google Calendar OOO sync โ€” away people are never nagged or counted as missing. + - icon: โš ๏ธ + title: Blockers that follow up + details: Blockers open from answers, auto-resolve on the next clean submission, and escalate to a contact when they go stale. - icon: ๐Ÿ“Š - title: Accountability built in - details: Choose whose updates are mandatory โ€” the wrap-up posts the count and exactly who's missing. - - icon: ๐ŸŒ - title: Timezone-aware - details: Prompts go out at the configured time in each participant's own timezone, with a reminder nudge before the deadline. + title: Insights built in + details: Mood trends, weekly digests, anonymous team-mood mode, CSV export, and a token-gated web dashboard for config and history. + - icon: ๐Ÿค– + title: AI summaries, your key + details: Opt-in daily TL;DR and week-in-review via your own Anthropic or OpenAI key. Nothing leaves your infra otherwise. - icon: ๐Ÿชถ title: Lightweight forever - details: One small container with SQLite inside. Scale-to-zero friendly, no telemetry, MIT licensed โ€” never SaaS. + details: One ~300 MB container on 1 vCPU / 512 MB. Embedded SQLite by default โ€” or bring your own PostgreSQL with one env var. - icon: ๐Ÿ”Œ title: Platform-agnostic core - details: Google Chat today. Slack and Microsoft Teams adapters are on the roadmap, plus bring-your-own-key AI summaries. + details: Google Chat today; Slack and Microsoft Teams adapters are next on the roadmap. MIT licensed, never SaaS. --- + +
+

How a morning works

+

No meeting, no interrogation bot โ€” one card, one form, one thread.

+
+
+ 1 +

The bot DMs your team

+

At 09:30 in each person's own timezone, everyone gets a card with a Fill standup button โ€” yesterday pre-filled from their last "today". One gentle reminder before the deadline.

+
+
+ 2 +

Answers thread up neatly

+

Each submission posts as a card under the day's thread in your team space. Re-submit to edit in place. Skips, vacations, and calendar OOO show as away โ€” never as missing.

+
+
+ 3 +

The wrap-up holds the line

+

At the deadline: who submitted, who didn't, open blockers, team mood โ€” plus an optional AI TL;DR and a weekly digest with trends.

+
+
+
+ +
+

What your team space sees

+

A real thread from a Wednesday.

+
+
๐Ÿ“… Daily Standup โ€” Wed, 11 Jun
+
+
๐Ÿ˜„
+
+
Asha
+
Yesterday
+ Shipped the payments retry queue +
Today
+ Start on the invoice exports +
Blockers
+ โœ… None +
+
+
+
๐Ÿ˜
+
+
Rohit ยท edited
+
Yesterday
+ Auth refactor review rounds +
Today
+ Land it, then pick up the flaky e2e +
Blockers
+ โš ๏ธ Waiting on staging API keys (2d) +
+
+
+ ๐Ÿ“Š Wrap-up  ยท  โœ… 7/8 submitted  ยท  โŒ Missing: Dev  ยท  ๐Ÿ–๏ธ Away: Mei  ยท  โš ๏ธ 1 open blocker +
+
+
+ +
+

Why self-host AsyncUp?

+

Hosted standup bots charge per user per month and hold your team's daily history.

+ +| | **AsyncUp** | Hosted standup bots | +|---|---|---| +| Cost | $0 forever โ€” MIT licensed | Per user, per month | +| Your standup history | In **your** SQLite file or Postgres | On their servers | +| AI features | Bring your own key, opt-in per standup | Their model, their terms | +| Infrastructure | One small container, scale-to-zero friendly | โ€” | +| Customization | Questions, schedules, escalation, dashboard โ€” and the source code | What the plan allows | + +
+ +
+

Up and running in 15 minutes

+ Read the guide + docker compose up -d โ€” amd64 & arm64 images on GHCR +
diff --git a/docs/public/favicon.svg b/docs/public/favicon.svg new file mode 100644 index 0000000..6075e35 --- /dev/null +++ b/docs/public/favicon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/docs/public/logo.svg b/docs/public/logo.svg new file mode 100644 index 0000000..6075e35 --- /dev/null +++ b/docs/public/logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/dashboard/dashboard.ts b/src/dashboard/dashboard.ts index bc1aa83..24ec5b1 100644 --- a/src/dashboard/dashboard.ts +++ b/src/dashboard/dashboard.ts @@ -272,23 +272,34 @@ function esc(value: string): string { .replace(/"/g, '"'); } +const LOGO_SVG = + ''; + function layout(title: string, body: string): string { return ` ${esc(title)} ${body}`; + +
${LOGO_SVG}AsyncUp
+${body}`; }