Dokument pro frontend developera. Popisuje co a jak implementovat — ne jak to kódovat.
Referenční design:
/workspace/design/design_handoff_talkide/auth.jsx+styles.css
Obsah
- Landing page (
/) - Login (
/login) - Signup (
/sign-up) - Forgot password (
/forgot-password) - Sdílené design tokeny
- Acceptance checklist
1. Landing page (/)
Routing change
Aktuálně: router/index.ts řádek 8–10 — path: '/' redirectuje na { name: 'studio' }.
Změna: Místo redirect namapuj / na novou komponentu LandingScreen.vue s meta: { public: true }. Route pro /studio zůstává protected (meta: { requiresAuth: true }).
// PŘED
{ path: '/', redirect: { name: 'studio' } }
// PO
{ path: '/', name: 'landing', component: () => import('@/screens/landing/LandingScreen.vue'), meta: { public: true } }
Neautentizovaný uživatel co přijde na /studio (nebo jakoukoli protected route) dostane redirect na / (landing), ne na /login. Uprav router.beforeEach guard: místo next('/login') použij next('/').
Struktura stránky
Stránka je single-scroll, žádné side navigation. Pozadí je var(--bg-1) s AuthBackdrop efektem (viz sekci 5).
Top bar (výška 56 px)
- Vlevo: Logo (
<Logo />komponenta — amber glyph + “TalkIDE” text) - Vpravo: dropdown “Resources” + tlačítko “Pricing” (placeholder, nic neotevírá) + ThemeToggle + separator + CTA “Sign in” →
/login - Pozadí top baru: průhledné (backdrop prosvítá)
- Mobile (< 768 px): schovat “Resources” a “Pricing”, zachovat Logo + ThemeToggle + “Sign in”
Hero sekce
Padding top: 100 px desktop / 64 px mobile. Max-width kontejneru: 880 px, centered.
Headline (největší element na stránce):
Build a real web app
by talking about it.
- Font:
var(--font-display), weight 600 - Velikost:
clamp(48px, 7vw, 84px), line-height 1.02, letter-spacing -0.03em - Druhý řádek (nebo fragment “by talking about it.”) v barvě
var(--fg-3)— ztlumený
Animated subheadline (typing efekt):
Text se postupně typewrituje rychlostí ~22 ms/znak. Kurzor (2 px wide block, barva var(--amber)) bliká dokud text není hotový. Po dokončení kurzor zmizí.
Copy:
We provide the professional-grade engine and a world-class pit crew
of AI agents; you just sit in the driver's seat and tell us
where the finish line is.
- Font:
var(--font-display), size 18 px, line-height 1.55, colorvar(--fg-2) - Max-width 680 px, min-height 84 px (rezerva pro blikání layoutu při typování)
CTA tlačítka (flex row, gap 12 px, margin-bottom 60 px):
| Tlačítko | Varianta | Akce | Copy |
|---|---|---|---|
| Primární | .btn.primary | router.push('/sign-up') | ”Vyzkoušej zdarma →“ |
| Sekundární | .btn.ghost | router.push('/login') | ”Mám účet” |
Primární: padding 14px 28px, font-size 15 px, ikona ArrowRight (16 px) vpravo od textu. Sekundární: padding 14px 24px, font-size 14 px.
How it works (3 kroky)
Pod CTA tlačítky, odděleno horní linkou (border-top: 1px solid var(--line-1)), padding 24px 0.
Grid 3 sloupce (desktop) / 1 sloupec (mobile < 768 px). Max-width 720 px.
Každý krok:
- Kicker:
var(--font-mono), 10 px, uppercase, letter-spacing 0.1em, barvavar(--amber) - Text: 13 px,
var(--fg-2), line-height 1.45
| Kicker | Text |
|---|---|
| Step 1 | Describe what you want — in plain language. |
| Step 2 | The PM agent assigns specialists and gets to work. |
| Step 3 | Your app goes live. You manage it by chatting. |
Footer
Centered, padding 32px 24px. Font-size 12 px, barva var(--fg-4).
© 2026 TalkIDE · Made for makers
Přidat placeholder linky (vedle copyright nebo pod ním):
- “Terms of Service” →
#(placeholder) - “Privacy Policy” →
#(placeholder) - “Sign in” →
/login
Linky: color var(--fg-3), hover var(--fg-2), žádný underline.
Animace a efekty
AuthBackdrop: viz sekci 5 — amber blob top-right, indigo blob bottom-left, dot grid, grain overlay. Pointer-events none, z-index 0. Vizauth.jsxřádky 16–67 pro implementační referenci.- Hero kontejner:
z-index: 2,position: relative - ThemeToggle: přepíná
data-theme="dark"/"light"na<html>, uložit dolocalStorageklíč"talkide-theme"
2. Login (/login)
Co se mění oproti dnešku
Dnešní LoginForm.vue je centrovaný card bez pozadí a bez top baru. Nový design přidává:
- Stejný
AuthBackdropjako landing (efekt kontinuity) MiniTopBars logem, Resources, Pricing, ThemeToggle — bez “Sign in” tlačítka (hideSignIn: true)- “Back” tlačítko vlevo v top baru →
/(landing) - Karta je vizuálně formovanější:
background: var(--bg-2),border: 1px solid var(--line-2),border-radius: var(--r-xl)(20 px),box-shadow: var(--shadow-strong), padding 44 px
Layout karty
- Max-width: 460 px, centered horizontálně + vertikálně (
flex: 1,align-items: center) - Nahoře v kartě: Logo (22 px) + H1 “Welcome back” + subtitle “Sign in to your TalkIDE Studio.”
- H1:
var(--font-display), weight 600, 24 px, letter-spacing -0.02em
Obsah formuláře (shora dolů)
- Google button — “Sign in with Google”, celá šířka, varianta outlined (viz sekci 5)
- OR separator —
var(--font-mono), 11 px, uppercase, barvavar(--fg-4); po stranáchvar(--line-1)čáry - Email field — label “Email”, placeholder “you@example.com”
- Password field — label “Password” (required
*) + inline link “Forgot?” vpravo (barvavar(--amber), 12 px) →/forgot-password - Form error — červený text pod password fieldem, barva
var(--rose)(zachovat dnešní chování) - Submit button — “Sign in”, celá šířka,
.btn.primary, padding 12 px
Footer karty
Odděleno border-top: 1px solid var(--line-1). Text 13 px, var(--fg-3):
Don't have an account? Create one
“Create one” je link barvy var(--amber), weight 500, → /sign-up.
Validace (zachovat dnešní logiku beze změny)
- Field-level validace on blur: red border + error text pod fieldem
- Form-level error (AUTHENTICATION_FAILED, VALIDATION_ERROR, generic): text
var(--rose)nad submit buttonem animate-shakepři form erroru — zachovat- Submit button disabled dokud
formData.isValid() === false - Loading state: spinner + loading text v ButtonPrimary — zachovat
- Po úspěchu:
animate-slide-out+ redirect na{ name: 'studio' }po 500 ms (desktop) / 0 ms (mobile) — zachovat
Input focus styl
Focus state: border-color: var(--amber), box-shadow: 0 0 0 3px var(--amber-soft). Transition 0.12s.
3. Signup (/sign-up)
Co se mění oproti dnešku
Stejná struktura jako Login — přidat AuthBackdrop + MiniTopBar (s Back → /). Karta stejný styl.
H1: “Create your account” Subtitle: “Free to start. Pay only for what you build.”
Obsah formuláře
- Google button — “Sign up with Google”
- OR separator
- Full name (label “Full name”, required, placeholder “Jan Novák”, autofocus)
- “What should the team call you?” (label, required, placeholder “např. Mike”) + live preview chip (viz níže)
- Email (label “Email”, required, placeholder “you@example.com”)
- Password (label “Password”, required, placeholder “Min. 8 characters”)
- T&C text (11 px,
var(--fg-4), margin 12px 0 16px):
“Terms” a “Privacy Policy” jsou underlined linky barvyBy creating an account you agree to our Terms and Privacy Policy.var(--fg-3)→#(placeholder). - Submit button — “Create account”, celá šířka
Live preview chip (pod “call name” fieldem)
Malý banner který se zobrazí vždy (i když pole je prázdné — pak zobrazí ”—”):
- Pozadí:
var(--amber-soft), border:1px solid var(--amber-line), border-radius 10 px, padding 10px 12px - Obsah: avatar M (inline-flex, 22px, border-radius 50%, background
oklch(0.78 0.15 70), text#1a1408, font-size 11px, weight 600) + text “Mara will say:” (colorvar(--fg-3)) + text"Hi {callName}, what are we building?"(colorvar(--fg-1), weight 500) {callName}= reaktivní hodnota pole, fallback ”—“
Footer karty
Already have an account? Sign in
“Sign in” → /login.
Validace (zachovat dnešní logiku)
- Pole name: notEmpty, minLength 1, maxLength 100
- Pole email: notEmpty, pattern email
- Pole password: notEmpty, minLength 8, maxLength 72
- Nové pole “call name”: notEmpty, maxLength 50 — přidat do
SignupRequestaSignupFormData - CONFLICT_USER error → field-level error na email
animate-shakepři erroru — zachovat
Pozn. pro BE: signup payload bude potřebovat nové pole
callName(string). Domluvit s BE developerem.
4. Forgot password (/forgot-password)
Co se mění oproti dnešku
Přidat AuthBackdrop + MiniTopBar (Back → /login). Karta stejný styl jako login/signup.
H1: “Reset your password” Subtitle: “Enter your account email and we’ll send you a link to reset your password.”
Obsah formuláře (výchozí stav)
- Email field (label “Email”, required, placeholder “you@example.com”, autofocus)
- Form error — barva
var(--rose)(zachovat) - Submit button — “Send reset link”, celá šířka
- Footer karty: link “Back to sign in” →
/login, barvavar(--amber)
Confirmation state (po úspěšném odeslání)
Přepnout celý obsah karty na confirmation. H1 se změní na “Check your inbox”, subtitle zobrazí email:
We've sent a password reset link to {email}. The link expires in 30 minutes.
Uvnitř karty (místo formuláře):
- Success banner: padding 16px, border-radius 12px,
background: var(--green-soft),border: 1px solid oklch(0.78 0.13 150 / 0.4)- Vlevo: zelený kruh 32px s ikonou Check,
background: var(--green), text#0a1a10 - Vpravo: “Email sent. Check your spam folder if you don’t see it.” (13 px,
var(--fg-1))
- Vlevo: zelený kruh 32px s ikonou Check,
- Ghost button “Back to sign in” celá šířka →
/login - Pod buttonem (14 px od buttonem): “Didn’t get it?” + link “Try again” (
var(--amber)) → reset stavu zpět na formulář
Validace (zachovat dnešní logiku)
- Email: notEmpty, pattern
- API vždy vrátí success (i když email neexistuje) — UX záměr (nechceme prozradit registrace)
animate-shakepři síťové chybě — zachovat
5. Sdílené design tokeny
Fonty — PONECHAT EXISTUJÍCÍ, NEPŘIDÁVAT NOVÉ
Aplikace má definované fonty v:
index.htmlřádek 13: Google Fonts importInter:wght@400;500;600;700+JetBrains+Mono:wght@400;500src/main.cssřádky 43–45: CSS proměnné
--font-display: "Inter", system-ui, -apple-system, sans-serif;
--font-ui: "Inter", system-ui, -apple-system, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, monospace;
Neinstalovat Fraunces ani žádný jiný font z design handoffu. Design handoff používá Fraunces pro display typ, ale my zůstáváme na Inter pro konzistenci s existující apkou.
Všude kde handoff říká font-family: var(--font-display) nebo serif → použij naše var(--font-display) = Inter.
Barvy (přebrat z styles.css)
Barvy jsou již definovány v src/main.css (dark + light theme). Klíčové proměnné:
Surfaces (dark)
| Proměnná | Hex | Použití |
|---|---|---|
--bg-0 | #0e0d0c | nejhlubší pozadí |
--bg-1 | #15140f | hlavní canvas |
--bg-2 | #1c1a14 | karty / panely |
--bg-3 | #25221a | raised elementy |
--bg-4 | #2f2b21 | hover stav |
Linky
| Proměnná | Hodnota |
|---|---|
--line-1 | rgba(255, 240, 200, 0.06) |
--line-2 | rgba(255, 240, 200, 0.10) |
--line-3 | rgba(255, 240, 200, 0.16) |
Text
| Proměnná | Hex | Použití |
|---|---|---|
--fg-1 | #f5efe0 | primární text |
--fg-2 | #c8c1ad | sekundární text |
--fg-3 | #8a836f | ztlumený |
--fg-4 | #5c5747 | nejslabší (copyright, footnotes) |
Akcenty
| Proměnná | Hodnota | Použití |
|---|---|---|
--amber | oklch(0.78 0.15 70) | primární akce, linky, focus |
--amber-soft | oklch(0.78 0.15 70 / 0.15) | focus ring, preview chip bg |
--amber-line | oklch(0.78 0.15 70 / 0.4) | preview chip border |
--indigo | oklch(0.72 0.13 270) | agent / working stav |
--indigo-soft | oklch(0.72 0.13 270 / 0.14) | blob efekt |
--green | oklch(0.78 0.13 150) | success / live |
--green-soft | oklch(0.78 0.13 150 / 0.14) | success banner bg |
--rose | oklch(0.72 0.15 25) | error |
--rose-soft | oklch(0.72 0.15 25 / 0.16) | error bg |
Ostatní
| Proměnná | Hodnota |
|---|---|
--primary-fg | #1a1408 (dark) / #fbf6ea (light) — text na amber bg |
--shadow-strong | 0 30px 80px rgba(0,0,0,0.4) |
Spacing a border-radius
| Proměnná | Hodnota | Použití |
|---|---|---|
--r-sm | 6px | malé prvky (badges) |
--r-md | 10px | inputy, malé karty |
--r-lg | 14px | střední karty |
--r-xl | 20px | auth karty, velké modaly |
Tlačítka
Třída .btn je base, kombinuje se s variantou:
| Varianta | CSS třída | Styl |
|---|---|---|
| Primary | .btn.primary | background: var(--amber), color: var(--primary-fg), weight 600, hover: filter: brightness(1.05) |
| Default | .btn | background: var(--bg-3), border var(--line-2), hover var(--bg-4) |
| Ghost | .btn.ghost | průhledné pozadí, hover var(--bg-3) |
| Danger | .btn.danger | background: var(--rose-soft), border var(--rose), color var(--rose) |
Všechna tlačítka: border-radius var(--r-md), font-weight 500, transition 0.12s.
Inputy
Styl AuthInput (nový, přidat do common nebo inline):
- Padding: 12px 16px
- Border-radius:
var(--r-md)(10 px) - Background:
var(--bg-1) - Border:
1px solid var(--line-2)výchozí →var(--amber)on focus - Box-shadow on focus:
0 0 0 3px var(--amber-soft) - Error stav:
border-color: var(--rose), box-shadow0 0 0 3px var(--rose-soft) - Transition: 0.12s
Google button styl
- Full-width, padding 11px 16px, border-radius
var(--r-md) - Background:
var(--bg-1), bordervar(--line-2), colorvar(--fg-1), weight 500 - Hover: background
var(--bg-3) - Ikona: Google SVG barevná (viz
auth.jsxřádky 4–13), size 18 px - Akce: placeholder (OAuth flow v budoucnu) — button je přítomen ale nedělá API call
AuthBackdrop efekt
Tři vrstvy, position: absolute; inset: 0; pointer-events: none; z-index: 0:
- Amber blob:
top: -20%, right: -10%, 700x700 px,radial-gradient(circle, var(--amber-soft), transparent 60%),filter: blur(60px), animaceauthBlob124s - Indigo blob:
bottom: -25%, left: -15%, 800x800 px,radial-gradient(circle, var(--indigo-soft), transparent 60%),filter: blur(80px), animaceauthBlob230s - Dot grid: SVG pattern, tečky r=1px
var(--line-3), repeat 32x32px, opacity 0.4
Keyframes (přidat do main.css nebo landing komponentu):
@keyframes authBlob1 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(-40px, 30px) scale(1.1); }
}
@keyframes authBlob2 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(50px, -40px) scale(1.15); }
}
@keyframes authCursor {
0%, 49% { opacity: 1; }
50%, 100% { opacity: 0; }
}
6. Acceptance checklist
Co musí frontend developer udělat
- Vytvořit
src/screens/landing/LandingScreen.vues top barem, hero sekcí, 3 kroky a footerem - Změnit router
path: '/'z redirect naLandingScreen.vue(smeta: { public: true }) - Změnit
router.beforeEachguard: neautentizovaný uživatel jde na/místo/login - Obalit
LoginScreen.vuedo nového layoutu sAuthBackdrop+MiniTopBar(Back →/) - Přidat
GoogleButton+OrSeparatordoLoginForm.vuenad email field - Obalit
SignupScreen.vuedo nového layoutu sAuthBackdrop+MiniTopBar(Back →/) - Přidat
GoogleButton+OrSeparatordoSignupForm.vuenad name field - Přidat pole “Call name” do
SignupForm.vues live preview chipem - Přidat T&C text do
SignupForm.vuenad submit button - Obalit
ForgotPasswordScreen.vuedo nového layoutu sAuthBackdrop+MiniTopBar(Back →/login) - Aktualizovat confirmation state
ForgotPasswordForm.vuena nový design (green banner + ghost button + try again) - Přidat keyframes (
authBlob1,authBlob2,authCursor) domain.css - Přidat ThemeToggle komponentu do top baru (pokud ještě neexistuje jako sdílená)
- Ověřit responsive chování na 375px (iPhone) a 1280px (desktop)
Co NEDĚLAT
- Neinstalovat nové fonty (Fraunces ani jiné) — pouze Inter + JetBrains Mono z
index.html - Nerefaktorovat jiné obrazovky (workspace, studio, dashboard, profile, projects)
- Nepřepisovat validační logiku v
LoginFormData,SignupFormData,ForgotPasswordFormData— pouze vizuál - Neměnit API endpointy ani request/response modely (s výjimkou přidání
callNamedo signup po domluvě s BE) - Neměnit barvy v
main.css— design tokeny jsou již v pořádku
Feedback od designera (interní)
Design handoff (auth.jsx) byl výborně strukturovaný — komponenty pojmenované konzistentně, inline styly s CSS proměnnými, takže překlad do Vue byl přímočarý. Chyběla mi informace o tom, zda Google OAuth flow má být v tomto sprintu funkční nebo jen placeholder — musel jsem to rozhodnout sám (zvolil jsem placeholder). Příště by pomohlo uvést v handoffu explicitně “tato tlačítka jsou zatím decorative / budou funkční v iteraci X”.
Thanks for the feedback.