Files
shaynee-flutter/DESIGN_DOC.md
mav 6311088256 redesign: duolingo-pattern onboarding, no gradient, pressable button
- Nunito font replacing Plus Jakarta Sans
- SButton: Stack-based 3D pressable (dark shadow layer + top layer translates on press)
- SCard: flat border-based selection, no shadows
- SProgressBar: 4px thin bar, animated fill
- All screens: white bg, no gradients
- Duolingo layout: illustration top zone, content below, sticky button
2026-05-28 16:34:04 +02:00

307 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Shaynee Flutter — Design System (Duolingo-study edition)
## 1. How Duolingo Screens Actually Work (first 20 screens)
### Master Layout Template (used on ~80% of screens)
```
┌─────────────────────────────────┐ safe area top
│ [←/×] ████████░░░░░░ [skip] │ nav row: 48px tall, 16px padding
├─────────────────────────────────┤
│ │
│ [ILLUSTRATION / MASCOT] │ top zone: ~40% of remaining height
│ centered, ~220px │ image sits here, NO text
│ │
├─────────────────────────────────┤
│ │
│ Headline │ 24px h-padding
│ (bold, 22-26px, dark) │
│ │
│ Sub text (15px, gray) │
│ │
│ ┌─────────────────────────┐ │ option cards: 16px h-padding
│ │ [icon] Label [radio○] │ │ card height: 62px
│ └─────────────────────────┘ │ gap between cards: 8px
│ ┌─────────────────────────┐ │
│ │ [icon] Label [radio○] │ │
│ └─────────────────────────┘ │
│ ┌─────────────────────────┐ │
│ │ [icon] Label [radio○] │ │
│ └─────────────────────────┘ │
│ │
├─────────────────────────────────┤
│ ┌─────────────────────────┐ │ button zone: 16px h-padding
│ │ CONTINUE │ │ button: 52px tall
│ └─────────────────────────┘ │
└─────────────────────────────────┘ safe area bottom
```
### Nav Row breakdown
- Left: back arrow `←` in 36×36 box with gray border OR `×` to exit
- Center: thin progress bar (4px height, full remaining width)
- Right: "Skip" as plain gray text link (no box, no border)
- Background: white, no shadow
### Illustration Zone rules
- NO text inside illustration zone
- Image centered horizontally
- ~40% of screen height (not fixed pixel — scales)
- Mascot/character always faces slightly right or center
- White background behind image (no colored backdrop)
### Card style (EXACT)
```
height: 62px
borderRadius: 12px
background: white (default) / #f7f7f7 tint (hover)
border: 1.5px solid #e5e5e5 (default)
2px solid #58CC02 (Duolingo green, selected)
→ for Shaynee: 2px solid #5B4FCF
icon box: 40×40, radius 10, bg #f7f7f7, icon 22px
label: left-aligned, bold 16px, dark #3c3c3c
radio circle: right side, 22px, empty or filled+check
gap between: 8px
h-padding: 16px from screen edge
```
### Pressable Button (THE KEY THING — not box-shadow, uses border-bottom trick)
```
height: 52px
borderRadius: 16px
background: #58CC02 (Duo green) → Shaynee: #5B4FCF
border-bottom: 4px solid #58A700 → Shaynee: 4px solid #3D32A8
(this IS the shadow — not box-shadow, not gradient)
text: WHITE, ExtraBold, 15px, uppercase or title-case
disabled state: bg #e5e5e5, border-bottom #b0b0b0, text gray
pressed state: translateY(+4px), border-bottom: 0 (collapses — button "sinks")
width: full (16px h-padding each side)
```
### Specific screen patterns
**Screen 1 — Splash/Welcome**
```
BG: white (NOT gradient)
Center: Duo mascot (large, ~280px, animated float)
Below mascot:
"Learn a language\nfor free." (bold 28px, centered)
Bottom stack:
[GET STARTED] green pressable button
[I already have an account] — plain text link, no button style
```
**Screen 2 — Reason/Goal (first question)**
```
Nav: [×] ░░░░░░░░░░ [no skip]
Illustration: topic-specific art (school bag, brain, etc), centered
Headline: "What is your reason for learning?" (22px bold)
Cards: list of 5-7 options (career, family, travel, school, brain, other)
Bottom: [CONTINUE] — disabled until selection
```
**Screen 3 — Language selection**
```
Nav row with progress
Grid of flag+name cards (2 columns or scrollable list)
Searchable (search bar at top of list area)
Bottom: [CONTINUE]
```
**Screen 4-5 — Proficiency / experience**
```
Illustration centered
Big question text
3-4 cards: "I'm new" / "I know a little" / "I'm comfortable" / "It's complicated"
[CONTINUE]
```
**Screen 6-7 — Daily goal**
```
Illustration: Duo with calendar or clock
Question: "Choose your daily goal"
Cards: Casual (5min) / Regular (10min) / Serious (15min) / Intense (20min)
Each card has icon + name + description (3 lines in card)
Selected card: green border + light green bg
[CONTINUE]
```
**Screen 8-10 — First mini lesson (before signup)**
```
Quiz layout:
Top: progress bar (green fill) + × + hearts ♥♥♥
Middle: question illustration
Question text below illustration
Answer options (A/B/C/D) as square/rounded cards in 2×2 grid or vertical
Bottom: [CHECK] button (green, disabled until pick)
After correct: [CHECK] becomes green checkmark animation, then [CONTINUE]
After wrong: button turns red, explanation text appears below
```
**Screen 11 — Lesson complete / celebration**
```
Confetti animation full screen
Mascot celebrating (arms up)
"You did it!" bold centered
XP earned badge
[CONTINUE]
```
**Screen 12 — Streak intro**
```
Flame icon (large, centered)
"You're on a streak!"
Explanation of how streaks work
[CONTINUE]
```
**Screen 13-16 — Signup gate**
```
Illustration: Duo with "Save your progress"
"Create a profile to save your progress"
[CREATE PROFILE] green button
[Maybe later] plain text link (NOT a button)
```
**Screen 17-20 — Account creation**
```
Individual input screens, one field per screen:
Enter your age → Enter your name → Enter email → Set password
Each screen: input field centered, big, full-width below headline
[CONTINUE] stays disabled until field valid
```
---
## 2. Shaynee Design Rules (derived from Duolingo study)
### RULE 1: NO gradients anywhere (kills premium feel on cheap gradient)
### RULE 2: White backgrounds on all content screens
### RULE 3: Pressable button = border-bottom trick, NOT box-shadow
### RULE 4: One illustration zone (top 40%) + one content zone (bottom 60%)
### RULE 5: Button always stuck to bottom, full width, 16px h-padding
### RULE 6: Cards: 62px, border-based selection, no shadows
### RULE 7: Mascot only on: splash, analysing complete, result reveal
### RULE 8: "Skip" / "Maybe later" = plain text, never in a button/box
---
## 3. Shaynee Color System (no gradients)
```dart
// Backgrounds
bgPage: #FAFAFE // very light lavender-white
bgSurface: #FFFFFF // pure white (cards, inputs)
// Primary (Indigo — replaces Duo's green)
primary: #5B4FCF
primaryDark: #3D32A8 // button bottom border
primaryLight: #EAE7FB // selected card bg tint
primaryBorder: #5B4FCF // selected card border
// Text
textHead: #1C1A2E // nearly black
textBody: #4B4B6B // medium dark
textSub: #9898AA // gray subtext
textDisabled: #C4C4D4
// Borders
borderLight: #E8E6F0 // card default border
borderMedium: #D0CDEA // input default
// Accent
accent: #FF7EB3 // pink — celebrations, badges only
accentLight: #FFF0F6
// States
success: #4CAF50
error: #FF4B4B
```
---
## 4. Typography — Nunito (Google Fonts)
```dart
// Weights to use:
// 900 Black → main headlines (36px+)
// 800 ExtraBold → section heads (22-28px), button text
// 700 Bold → card labels (16px), input text
// 600 SemiBold → body (15px), subtitles
// 500 Medium → captions (12-13px), subtext
// 400 Regular → (avoid — too thin)
// Scale:
headline1: Nunito 900, 36px, lh 1.15
headline2: Nunito 800, 26px, lh 1.2
title: Nunito 800, 22px, lh 1.25
subtitle: Nunito 600, 15px, lh 1.5
body: Nunito 600, 15px, lh 1.5
caption: Nunito 500, 12px, lh 1.4
button: Nunito 800, 15px, lh 1.0, letterSpacing 0.3
```
---
## 5. Component Specs (Flutter implementation)
### SButton (Pressable)
```dart
// Use GestureDetector with onTapDown/onTapUp for press animation
// AnimatedContainer: on press, translate Y +4, remove bottom border
decoration: BoxDecoration(
color: SColors.primary, // flat, NO gradient
borderRadius: BorderRadius.circular(16),
border: Border(
bottom: BorderSide(
color: SColors.primaryDark, // #3D32A8
width: 4, // THIS is the "shadow"
),
),
),
// On press: transform translate(0, 4), border bottom 0
// Duration: 80ms
```
### SCard (Option row)
```dart
height: 62,
decoration: BoxDecoration(
color: selected ? SColors.primaryLight : SColors.bgSurface,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: selected ? SColors.primary : SColors.borderLight,
width: selected ? 2.0 : 1.5,
),
),
// NO shadow
// Icon box: 40×40, radius 10, bg #f4f2ff (selected) or #f7f7f7
// Radio: right side, 22×22 circle
```
### SProgressBar
```dart
height: 4,
borderRadius: BorderRadius.circular(2),
// Track: SColors.borderLight
// Fill: SColors.primary
// Animate width change: 300ms ease-out
```
---
## 6. Screen Flow & Rules per Screen
| Screen | BG | Illustration zone | Nav | Button text |
|--------|----|--------------------|-----|-------------|
| Splash | White | Shaynee hero (center, large) | none | auto-advance |
| Intro/Welcome | White | Feature art or stats visual | none | "Get started" |
| Name | White | Small Shaynee avatar (top, 100px) | ← + 1/5 + skip | "Continue" |
| Skin type | White | Skin illustration (120px) | ← + 2/5 | "Continue" |
| Age | White | Age illustration (120px) | ← + 3/5 | "Continue" |
| Concerns | White | Skincare illustration (120px) | ← + 4/5 | "Continue" |
| Goal | White | Goal illustration (120px) | ← + 5/5 | "See my results" |
| Analysing | White + spinner | Shaynee pulsing (center) | none | auto-advance |
| Result | White | Shaynee hero mascot (top 35%) | none | "Start my routine" |
| Sign up | White | none | × | "Save my results" |