④段整套同步(六节 + P/S/F/J + 模板)+ open-design 移到技能根
一、④段整套同步(用户选候选 A)
- 新增 `references/stage-proto-doc/assets/产品文档模板.html`(16 KB/247 行,从备份拷、转 LF)。
- ④段 SKILL.md 换成备份 15:28 那版,并按模板口径改齐:
· 「产品文档框架」从「四块+一附录」改成**六节** —— 页面结构/功能清单/使用场景/操作流程/
跨页与界面状态/待确认与偏离;与模板同构,⛔ 不从空白页重写结构。
· 编号从 R/S/F 改成 **P 页面/S 场景/F 功能/J 二级功能**,各自唯一、按展示顺序通排。
· 保留旧版有价值的要求:每项功能补齐 做什么/入口在哪/输入边界/异常与恢复;重点功能三处标红;
横向流程图每步写清页面/功能/操作/完成判据。
· 完成标准「七节」→「六节」,自查清单同步换掉「需求」那批条目,补模板与配图两条。
· 路径 `designs/<项目>/` → `docs/pm/<项目>/ui/`(2 处)。
· 补回本机那条「每份产出文档开头都要有一张图」的引用(指向主 skill,段内不复述)。
- 主 skill 同步:四段结构表④行、④段沿革、画图小节(④段画页面结构图 + 用户路径)。
二、open-design 移到技能根(用户选候选 A)
- `git mv product-planning/references/stage-delivery/assets/open-design → open-design/`(4178 文件)。
- `.gitignore` 白名单加 `!/open-design/` —— 否则移出去就不再纳入版本控制。
- 引用改 11 处:路径形态 `assets/open-design/...` → `<技能根>/open-design/...`;
「随段携带的自带件」改称「同根技能」;「路径怎么找」那条改成自带件(段内相对路径)与
同根技能(`<技能根>/<技能名>/`)两类分开写。
- open-design 自己的 ATTRIBUTION.md 两处同步(它现在与 oil-ui-pro 同层)。
- 副作用(有益):命名闸门读数由 2063 降到 225 —— 此前它把 open-design 里 919 个第三方 md
当成规则一起扫了;现在只扫本包 23 个 md。已确认④段的 H1 与 4a/4b/4c 子步仍在检查范围内。
三、验收
- check_naming.py --ws E:/ProgramData/AIProject/contentm_agent = 通过 225 / 失败 0 / 提示 27。
- 活文件里 `assets/open-design` 残留 0;工作区 CRLF 文件 0。
This commit is contained in:
1 parent
fa0a9026c8
commit
5afeb6b78a
4184 files changed
+326
-70
No files matched your search
@@ -0,0 +1,160 @@
|
||||
# نظام تصميم مستوحى من Duolingo
|
||||
|
||||
> Category: الإنتاجية والبرمجيات كخدمة
|
||||
> منصة تعلّم اللغات. الأخضر البومي الزاهي، الظلال السميكة، البهجة المحوّلة إلى ألعاب.
|
||||
|
||||
## 1. الثيم البصري والأجواء
|
||||
|
||||
Duolingo هو تحويل الألعاب إلى لغة بصرية. الواجهة زاهية بجرأة واضحة، مع **الأخضر البومي** (`#58cc02`) كلون رئيسي للعلامة التجارية، وظل سفلي سميك بارتفاع 4px على كل عنصر تفاعلي يشبه زر ثلاثي الأبعاد ينتظر الضغط عليه. الصفحة بيضاء (`#ffffff`) مع حدود سميكة 2–3px بلون رمادي داكن (`#e5e5e5`)، ويُقرأ النظام بأكمله كتطبيق iOS من عام 2015 أُعيد توليده بتدرج هرمي أفضل.
|
||||
|
||||
تستخدم الطباعة **Feather Bold** (خط مستدير مخصص بلا أسنان) لعناصر الواجهة و**Mona Sans** (أو Inter) لمحتوى النص. أحجام العرض كبيرة وواثقة — Duolingo لا يهمس أبدًا. غالبًا ما تحمل العناوين خطًا أخضر تحتها أو تجلس على حبة خضراء، وتظهر تميمة Duo (بومة خضراء) كشخصية توضيحية نشطة، لا كشعار ثابت.
|
||||
|
||||
لغة الأشكال ودية: نصف قطر 16–20px على البطاقات، 12px على الأزرار، 9999px على الشرائح وأشرطة التقدم. الأيقونات مملوءة، مستديرة، ومشفّرة بالألوان حسب المهارة — لكل سطح درس زوج ألوان يمكن التعرف عليه فورًا.
|
||||
|
||||
**الخصائص الرئيسية:**
|
||||
- الأخضر البومي (`#58cc02`) كلون مهيمن للعلامة التجارية، يُستخدم في أكثر من 30% من السطح
|
||||
- ظل سفلي سميك 4px على كل زر (خاصية "الضغط اللمسي")
|
||||
- حدود صلبة 2–3px، لا خطوط رفيعة أبدًا
|
||||
- Feather Bold (عرض مستدير) + Mona Sans (المحتوى)
|
||||
- نص كبير وواثق — أحجام العرض تبدأ من 48px وتتصاعد
|
||||
- التميمة كشخصية: تظهر بومة Duo في الإعداد الأولي، الأخطاء، التتاليات
|
||||
- البرتقالي للتتاليات (`#ff9600`) والزهري الجوهرة (`#ce82ff`) كألوان ثانوية للعلامة التجارية
|
||||
|
||||
## 2. لوحة الألوان والأدوار
|
||||
|
||||
### الأساسية
|
||||
- **الأخضر البومي** (`#58cc02`): الأساسي للعلامة التجارية، CTA الرئيسي، الإجابة الصحيحة.
|
||||
- **الأخضر البومي العميق** (`#58a700`): لون الضغط/الظل لأزرار خضراء.
|
||||
- **الأخضر البومي الفاتح** (`#89e219`): التمرير فوقه، التعبئات الخفيفة.
|
||||
- **الأخضر البومي الباهت** (`#dbf8c5`): سطح خفيف، لافتة النجاح.
|
||||
|
||||
### النبرات الثانوية
|
||||
- **البرتقالي للتتاليات** (`#ff9600`): عداد التتاليات، أيقونة اللهب، الطاقة المميزة.
|
||||
- **البرتقالي العميق للتتاليات** (`#cc7a00`): البرتقالي عند الضغط.
|
||||
- **الزهري الجوهرة** (`#ce82ff`): عملة الجواهر، Super Duolingo.
|
||||
- **الأزرق الثعبان** (`#1cb0f6`): زر التلميح، رابط المعلومات.
|
||||
- **الأحمر الكاردينالي** (`#ff4b4b`): إجابة خاطئة، فقدان حياة.
|
||||
- **الأصفر النحلة** (`#ffc800`): شارة المحترفين، الإنجاز.
|
||||
|
||||
### السطح
|
||||
- **الثلج** (`#ffffff`): الخلفية الأساسية.
|
||||
- **الثعبان** (`#f7f7f7`): فاصل الأقسام، السطح الثانوي.
|
||||
- **البجعة** (`#e5e5e5`): خلفية معطّلة، كتلة مضمّنة.
|
||||
- **الذئب** (`#777777`): فاصل داكن، نص ثانوي.
|
||||
|
||||
### الحبر والنص
|
||||
- **أسود الثعبان** (`#3c3c3c`): النص الأساسي.
|
||||
- **الذئب** (`#777777`): النص الثانوي، التعليقات التوضيحية.
|
||||
- **الأرنب** (`#afafaf`): معطّل، عنصر نائب.
|
||||
|
||||
### الحدود
|
||||
- **البجعة** (`#e5e5e5`): حد قياسي 2px.
|
||||
- **الأرنب** (`#afafaf`): حد مؤكد عند التمرير.
|
||||
|
||||
## 3. قواعد الطباعة
|
||||
|
||||
### عائلة الخطوط
|
||||
- **العرض / واجهة المستخدم / العناوين**: `Feather Bold`، مع بديل: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **المحتوى / النص الطويل**: `Mona Sans`، مع بديل: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **الكود (نادر، المدارس/الإدارة)**: `JetBrains Mono`، مع بديل: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### التسلسل الهرمي
|
||||
|
||||
| الدور | الخط | الحجم | الوزن | ارتفاع السطر | تباعد الأحرف | ملاحظات |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| العرض | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | بطل الإعداد الأولي |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | عنوان الصفحة |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | عنوان القسم |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | عنوان البطاقة، صف الدرس |
|
||||
| محتوى كبير | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | تلميح الدرس، التعليمات |
|
||||
| المحتوى | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | النثر القياسي |
|
||||
| التعليق التوضيحي | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | عداد XP، البيانات الوصفية |
|
||||
| الزر | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | تسمية الزر القياسية |
|
||||
| التتالي | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | رقم التتالي، على اللهب |
|
||||
|
||||
### المبادئ
|
||||
- **800 هو الافتراضي**: يعمل Feather Bold بوزن 800 على العناوين والأزرار. يبدو 700 ضعيفًا في هذا النظام.
|
||||
- **نص كبير**: أحجام العناوين أكبر بنسبة 25–40% من العلامات التجارية النموذجية للمنتجات — الثقة كهوية.
|
||||
- **أحرف مستديرة**: لكل رمز نهايات ناعمة؛ ستؤدي الأحرف المسنّنة إلى كسر عقد الودية.
|
||||
|
||||
## 4. تصميم المكونات
|
||||
|
||||
### الأزرار
|
||||
|
||||
**الأساسي (الأخضر البومي)**
|
||||
- الخلفية: `#58cc02`
|
||||
- النص: `#ffffff`
|
||||
- الحشو: 14px 24px
|
||||
- الزاوية: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (الظل السميك)
|
||||
- التمرير فوقه: خلفية `#89e219`
|
||||
- النشط: translate-y 4px، border-bottom 0 (الزر "ينضغط")
|
||||
- الاستخدام: "متابعة"، "تحقق"، CTA الرئيسي.
|
||||
|
||||
**الثانوي (أبيض مع ظل سفلي)**
|
||||
- الخلفية: `#ffffff`
|
||||
- النص: `#777777`
|
||||
- الحد: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- الزاوية: 16px
|
||||
- الحشو: 14px 24px
|
||||
- التمرير فوقه: النص `#3c3c3c`، الحد `#afafaf`
|
||||
|
||||
**برتقالي التتاليات**
|
||||
- الخلفية: `#ff9600`
|
||||
- النص: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- الاستخدام: هدف التتالي، "ابدأ التتالي"
|
||||
|
||||
**الخطأ (الأحمر الكاردينالي)**
|
||||
- الخلفية: `#ff4b4b`
|
||||
- النص: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- الاستخدام: تغذية راجعة للإجابة الخاطئة.
|
||||
|
||||
### البطاقات / بلاطات الدرس
|
||||
- الخلفية: `#ffffff`
|
||||
- الحد: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- الزاوية: 16px
|
||||
- الحشو: 16px
|
||||
- التمرير فوقه: رفع 2px، ظل `0 4px 0 #d7d7d7`
|
||||
|
||||
### عقدة شجرة المهارات (فقاعة الدرس)
|
||||
- الحجم: 80×72px
|
||||
- الخلفية: لون المهارة مظلّل (أخضر للنشط، رمادي للمقفل)
|
||||
- Border-bottom: 6px solid متغير أغمق
|
||||
- الزاوية: 50% (دائري)
|
||||
- النشط: ينبض 1.0 → 1.05 كل 1.6s
|
||||
|
||||
### حقول الإدخال
|
||||
- الخلفية: `#ffffff`
|
||||
- الحد: 2px solid `#e5e5e5`
|
||||
- الزاوية: 12px
|
||||
- الحشو: 12px 16px
|
||||
- التركيز: حد `#1cb0f6` (أزرق الثعبان)، حلقة `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### شريط التقدم
|
||||
- المسار: `#e5e5e5`
|
||||
- التعبئة: `#58cc02` (أو `#ff9600` للتتالي)
|
||||
- الزاوية: 9999px
|
||||
- الارتفاع: 16px
|
||||
- تعبئة متحركة: 320ms ease-out عند الزيادة.
|
||||
|
||||
## 5. التباعد والتخطيط
|
||||
|
||||
- **الوحدة الأساسية**: 4px. المقياس: 4، 8، 12، 16، 24، 32، 48، 64.
|
||||
- **الحاوية**: حد أقصى 1080px، هامش 24px.
|
||||
- **عمود شجرة الدروس**: عرض 320px؛ محاذاة مركزية على سطح المكتب.
|
||||
|
||||
## 6. الحركة
|
||||
|
||||
- **المدة**: 180ms لضغط الزر؛ 320ms لفتح قفل عقدة المهارة؛ 1.6s لنبضة العقدة النشطة.
|
||||
- **التسهيل**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out، تجاوز طفيف) لفتح الأقفال.
|
||||
- **التميمة**: تومض Duo كل 4–6s، وتقفز عند معالم التتاليات (480ms ease-out نابض).
|
||||
|
||||
## 7. إرشادات الاستخدام
|
||||
|
||||
- حافظ على الأخضر البومي عالي التشبع، والظلال السفلية السميكة، وهندسة الدروس المستديرة معًا؛ الأزرار الخضراء المسطحة وحدها لا تُعطي انطباع Duolingo.
|
||||
- احتفظ بالنص الغامق كبير الحجم لحظات الدروس والتتاليات والتقدم حيث يحتاج المنتج إلى تشجيع أو تغذية راجعة.
|
||||
- استخدم الحركة المرحة بتقتير حول تغييرات حالة التقدم، مع تجنب الرسوم المتحركة المرتدة العامة على كل عنصر تحكم.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Von Duolingo inspiriertes Designsystem
|
||||
|
||||
> Category: Produktivität & SaaS
|
||||
> Sprachlernplattform. Leuchtendes Eulengrün, wuchtige Schatten, spielerische Freude.
|
||||
|
||||
## 1. Visuelles Thema und Atmosphäre
|
||||
|
||||
Duolingo ist Gamification als visuelle Sprache. Die Oberfläche ist unverblümt leuchtend, mit **Eulengrün** (`#58cc02`) als Marken-Primärfarbe und einem wuchtigen 4px-Bodenschatten auf jedem interaktiven Element, das wie ein 3D-Button wirkt, der darauf wartet, gedrückt zu werden. Die Seite ist weiß (`#ffffff`) mit kräftigen 2–3px-Rändern in tiefem Grau (`#e5e5e5`), und das gesamte System liest sich wie eine iOS-App von 2015, die mit besserer Hierarchie neugeboren wurde.
|
||||
|
||||
Die Typografie verwendet **Feather Bold** (eine benutzerdefinierte gerundete Serifenlose) für das Chrome und **Mona Sans** (oder Inter) für den Fließtext. Displaygrößen sind groß und selbstbewusst – Duolingo flüstert nie. Überschriften tragen oft einen grünen Unterstrichstrich oder sitzen auf einer grünen Pille, und das Maskottchen Duo (eine grüne Eule) erscheint als aktiver Illustrationscharakter, nicht als statisches Logo.
|
||||
|
||||
Die Formensprache ist freundlich: 16–20px Radien auf Karten, 12px auf Buttons, 9999px auf Chips und Fortschrittsbalken. Das Ikonografie-System ist gefüllt, gerundet und farbcodiert nach Fähigkeit – jede Lernoberfläche hat eine sofort erkennbare Farbkombination.
|
||||
|
||||
**Hauptmerkmale:**
|
||||
- Eulengrün (`#58cc02`) als dominante Markenfarbe, die auf über 30% der Oberfläche verwendet wird
|
||||
- Wuchtiger 4px-Bodenschatten auf jedem Button (die „taktile Drück"-Affordanz)
|
||||
- 2–3px Vollränder, niemals Haarlinien
|
||||
- Feather Bold (gerundetes Display) + Mona Sans (Fließtext)
|
||||
- Großer, selbstbewusster Text – Displaygrößen beginnen bei 48px und steigen
|
||||
- Maskottchen als Charakter: Duo die Eule erscheint beim Onboarding, Fehlern, Streaks
|
||||
- Streak-Orange (`#ff9600`) und Juwelen-Pink (`#ce82ff`) als sekundäre Markenfarben
|
||||
|
||||
## 2. Farbpalette & Rollen
|
||||
|
||||
### Primär
|
||||
- **Eulengrün** (`#58cc02`): Marken-Primär, primärer CTA, richtige Antwort.
|
||||
- **Eulengrün Tief** (`#58a700`): Gedrückt-/Schattenfarbe für grüne Buttons.
|
||||
- **Eulengrün Hell** (`#89e219`): Hover, weiche Füllungen.
|
||||
- **Eulengrün Blass** (`#dbf8c5`): Weiche Oberfläche, Erfolgsbanner.
|
||||
|
||||
### Sekundäre Akzente
|
||||
- **Streak-Orange** (`#ff9600`): Streak-Zähler, Feuersymbol, Premium-Energie.
|
||||
- **Streak-Orange Tief** (`#cc7a00`): Gedrücktes Orange.
|
||||
- **Juwelen-Pink** (`#ce82ff`): Juwelenwährung, Super Duolingo.
|
||||
- **Aal-Blau** (`#1cb0f6`): Hinweis-Button, Info-Link.
|
||||
- **Kardinalrot** (`#ff4b4b`): Falsche Antwort, Leben verloren.
|
||||
- **Bienengelb** (`#ffc800`): Pro-Abzeichen, Auszeichnung.
|
||||
|
||||
### Oberfläche
|
||||
- **Schnee** (`#ffffff`): Primärer Hintergrund.
|
||||
- **Aal** (`#f7f7f7`): Abschnittstrennung, sekundäre Oberfläche.
|
||||
- **Schwan** (`#e5e5e5`): Deaktivierter Hintergrund, eingebetteter Block.
|
||||
- **Wolf** (`#777777`): Dunkler Trenner, sekundärer Text.
|
||||
|
||||
### Tinte & Text
|
||||
- **Aalschwarz** (`#3c3c3c`): Primärer Text.
|
||||
- **Wolf** (`#777777`): Sekundärer Text, Bildunterschriften.
|
||||
- **Hase** (`#afafaf`): Deaktiviert, Platzhalter.
|
||||
|
||||
### Rand
|
||||
- **Schwan** (`#e5e5e5`): Standard-2px-Rand.
|
||||
- **Hase** (`#afafaf`): Betonter Rand beim Hover.
|
||||
|
||||
## 3. Typografieregeln
|
||||
|
||||
### Schriftfamilie
|
||||
- **Display / UI / Überschriften**: `Feather Bold`, Fallback: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Fließtext / Langtext**: `Mona Sans`, Fallback: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Code (selten, Schulen/Admin)**: `JetBrains Mono`, Fallback: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hierarchie
|
||||
|
||||
| Rolle | Schrift | Größe | Stärke | Zeilenhöhe | Zeichenabstand | Hinweise |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Onboarding-Hero |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Seitentitel |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Abschnittsüberschrift |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Kartentitel, Lernzeile |
|
||||
| Fließtext Groß | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Lernaufgabe, Anweisung |
|
||||
| Fließtext | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Standardtext |
|
||||
| Bildunterschrift | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | XP-Zähler, Metadaten |
|
||||
| Button | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Standard-Button-Label |
|
||||
| Streak | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Streak-Zahl, auf der Flamme |
|
||||
|
||||
### Prinzipien
|
||||
- **800 ist Standard**: Feather Bold läuft bei Überschriften und Buttons mit 800. 700 wirkt in diesem System schwach.
|
||||
- **Großer Text**: Überschriftengrößen sind 25–40% größer als bei typischen Produktmarken – Selbstvertrauen als Identität.
|
||||
- **Gerundete Buchstabenformen**: Jede Glyphe hat weiche Abschlüsse; scharfe Serifen würden den Freundlichkeitsvertrag brechen.
|
||||
|
||||
## 4. Komponenten-Styling
|
||||
|
||||
### Buttons
|
||||
|
||||
**Primär (Eulengrün)**
|
||||
- Hintergrund: `#58cc02`
|
||||
- Text: `#ffffff`
|
||||
- Padding: 14px 24px
|
||||
- Radius: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (der wuchtige Schatten)
|
||||
- Hover: Hintergrund `#89e219`
|
||||
- Aktiv: translate-y 4px, border-bottom 0 (Button „drückt")
|
||||
- Verwendung: „Weiter", „Prüfen", Haupt-CTA.
|
||||
|
||||
**Sekundär (Weiß mit Bodenschatten)**
|
||||
- Hintergrund: `#ffffff`
|
||||
- Text: `#777777`
|
||||
- Rand: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Padding: 14px 24px
|
||||
- Hover: Text `#3c3c3c`, Rand `#afafaf`
|
||||
|
||||
**Streak-Orange**
|
||||
- Hintergrund: `#ff9600`
|
||||
- Text: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Verwendung: Streak-Ziel, „Streak starten"
|
||||
|
||||
**Fehler (Kardinalrot)**
|
||||
- Hintergrund: `#ff4b4b`
|
||||
- Text: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Verwendung: Feedback bei falscher Antwort.
|
||||
|
||||
### Karten / Lernkacheln
|
||||
- Hintergrund: `#ffffff`
|
||||
- Rand: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Padding: 16px
|
||||
- Hover: 2px anheben, Schatten `0 4px 0 #d7d7d7`
|
||||
|
||||
### Fähigkeitsbaum-Knoten (Lernblase)
|
||||
- Größe: 80×72px
|
||||
- Hintergrund: fähigkeitsfarbengetönt (grün für aktiv, grau für gesperrt)
|
||||
- Border-bottom: 6px solid dunklere Variante
|
||||
- Radius: 50% (kreisförmig)
|
||||
- Aktiv: pulsiert 1.0 → 1.05 alle 1.6s
|
||||
|
||||
### Eingaben
|
||||
- Hintergrund: `#ffffff`
|
||||
- Rand: 2px solid `#e5e5e5`
|
||||
- Radius: 12px
|
||||
- Padding: 12px 16px
|
||||
- Fokus: Rand `#1cb0f6` (Aal-Blau), Ring `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Fortschrittsbalken
|
||||
- Spur: `#e5e5e5`
|
||||
- Füllung: `#58cc02` (oder `#ff9600` für Streak)
|
||||
- Radius: 9999px
|
||||
- Höhe: 16px
|
||||
- Animierte Füllung: 320ms ease-out beim Inkrementieren.
|
||||
|
||||
## 5. Abstände & Layout
|
||||
|
||||
- **Basiseinheit**: 4px. Skala: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Container**: max. 1080px, 24px Rinne.
|
||||
- **Lernbaumspalte**: 320px breit; auf Desktop zentriert.
|
||||
|
||||
## 6. Motion
|
||||
|
||||
- **Dauer**: 180ms für Button-Druck; 320ms für Knoten-Freischalten; 1.6s für aktiven Knoten-Puls.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (Back-out, leichter Überschwinger) für Freischalt-Animationen.
|
||||
- **Maskottchen**: Duo blinzelt alle 4–6s, springt bei Streak-Meilensteinen (480ms ease-out Feder).
|
||||
|
||||
## 7. Verwendungsrichtlinien
|
||||
|
||||
- Behalten Sie das hochgesättigte Eulengrün, die wuchtigen Bodenschatten und die gerundete Lerngeometrie zusammen; flache grüne Buttons allein lesen sich nicht als Duolingo.
|
||||
- Reservieren Sie übergroßen Fettdruck für Lern-, Streak- und Fortschrittsmomente, bei denen das Produkt Ermutigung oder Feedback benötigt.
|
||||
- Verwenden Sie spielerische Bewegungen sparsam rund um Fortschrittsstatusänderungen und vermeiden Sie generische Bouncy-Animationen auf jedem Steuerelement.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Sistema de diseño inspirado en Duolingo
|
||||
|
||||
> Category: Productividad y SaaS
|
||||
> Plataforma de aprendizaje de idiomas. Verde búho brillante, sombras gruesas, alegría gamificada.
|
||||
|
||||
## 1. Tema visual y atmósfera
|
||||
|
||||
Duolingo es la gamificación expresada como lenguaje visual. La interfaz es descaradamente brillante, con el **verde búho** (`#58cc02`) como color primario de marca y una gruesa sombra de 4px en la parte inferior de cada elemento interactivo que se lee como un botón 3D esperando ser presionado. La página es blanca (`#ffffff`) con bordes gruesos de 2–3px en gris oscuro (`#e5e5e5`), y el sistema completo se lee como una aplicación iOS de 2015 renacida con mejor jerarquía.
|
||||
|
||||
La tipografía usa **Feather Bold** (una sans-serif redondeada personalizada) para el chrome y **Mona Sans** (o Inter) para el cuerpo del texto. Los tamaños de visualización son grandes y seguros — Duolingo nunca susurra. Los encabezados a menudo llevan el trazo subrayado verde o se asientan sobre una pastilla verde, y la mascota Duo (un búho verde) aparece como un personaje de ilustración activo, no como un logotipo estático.
|
||||
|
||||
El lenguaje de formas es amigable: radios de 16–20px en tarjetas, 12px en botones, 9999px en chips y barras de progreso. La iconografía es rellena, redondeada y codificada por color según la habilidad — cada superficie de lección tiene un par de colores identificable al instante.
|
||||
|
||||
**Características clave:**
|
||||
- Verde búho (`#58cc02`) como color de marca dominante, usado en más del 30% de la superficie
|
||||
- Gruesa sombra inferior de 4px en cada botón (la affordance de "presión táctil")
|
||||
- Bordes sólidos de 2–3px, nunca líneas finas
|
||||
- Feather Bold (display redondeado) + Mona Sans (cuerpo)
|
||||
- Texto grande y seguro — los tamaños de display comienzan en 48px y suben
|
||||
- Mascota-personaje: Duo el búho aparece en el onboarding, errores, rachas
|
||||
- Naranja de racha (`#ff9600`) y rosa gema (`#ce82ff`) como colores de marca secundarios
|
||||
|
||||
## 2. Paleta de colores y roles
|
||||
|
||||
### Primario
|
||||
- **Verde búho** (`#58cc02`): Primario de marca, CTA principal, respuesta correcta.
|
||||
- **Verde búho profundo** (`#58a700`): Color de presión/sombra para botones verdes.
|
||||
- **Verde búho claro** (`#89e219`): Hover, rellenos suaves.
|
||||
- **Verde búho pálido** (`#dbf8c5`): Superficie suave, banner de éxito.
|
||||
|
||||
### Acentos secundarios
|
||||
- **Naranja de racha** (`#ff9600`): Contador de racha, icono de fuego, energía premium.
|
||||
- **Naranja de racha profundo** (`#cc7a00`): Naranja presionado.
|
||||
- **Rosa gema** (`#ce82ff`): Moneda gema, Super Duolingo.
|
||||
- **Azul anguila** (`#1cb0f6`): Botón de pista, enlace informativo.
|
||||
- **Rojo cardenal** (`#ff4b4b`): Respuesta incorrecta, vida perdida.
|
||||
- **Amarillo abeja** (`#ffc800`): Insignia pro, logro.
|
||||
|
||||
### Superficie
|
||||
- **Nieve** (`#ffffff`): Fondo principal.
|
||||
- **Anguila** (`#f7f7f7`): Separación de sección, superficie secundaria.
|
||||
- **Cisne** (`#e5e5e5`): Fondo desactivado, bloque incrustado.
|
||||
- **Lobo** (`#777777`): Divisor oscuro, texto secundario.
|
||||
|
||||
### Tinta y texto
|
||||
- **Negro anguila** (`#3c3c3c`): Texto principal.
|
||||
- **Lobo** (`#777777`): Texto secundario, pies de foto.
|
||||
- **Liebre** (`#afafaf`): Desactivado, marcador de posición.
|
||||
|
||||
### Borde
|
||||
- **Cisne** (`#e5e5e5`): Borde estándar de 2px.
|
||||
- **Liebre** (`#afafaf`): Borde enfatizado al pasar el cursor.
|
||||
|
||||
## 3. Reglas tipográficas
|
||||
|
||||
### Familia tipográfica
|
||||
- **Display / UI / Encabezados**: `Feather Bold`, con respaldo: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Cuerpo / Texto largo**: `Mona Sans`, con respaldo: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Código (raro, escuelas/admin)**: `JetBrains Mono`, con respaldo: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Jerarquía
|
||||
|
||||
| Rol | Fuente | Tamaño | Peso | Altura de línea | Espaciado | Notas |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Héroe de onboarding |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Título de página |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Encabezado de sección |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Título de tarjeta, fila de lección |
|
||||
| Cuerpo grande | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Consigna de lección, instrucción |
|
||||
| Cuerpo | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Prosa estándar |
|
||||
| Pie de foto | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Contador XP, metadatos |
|
||||
| Botón | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Etiqueta estándar de botón |
|
||||
| Racha | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Número de racha, sobre la llama |
|
||||
|
||||
### Principios
|
||||
- **800 es el predeterminado**: Feather Bold funciona a 800 en encabezados y botones. 700 se ve débil en este sistema.
|
||||
- **Texto grande**: los tamaños de encabezado son 25–40% más grandes que las marcas de productos típicas — la confianza como identidad.
|
||||
- **Letras redondeadas**: cada glifo tiene terminaciones suaves; los serif afilados romperían el contrato de amabilidad.
|
||||
|
||||
## 4. Estilos de componentes
|
||||
|
||||
### Botones
|
||||
|
||||
**Primario (Verde búho)**
|
||||
- Fondo: `#58cc02`
|
||||
- Texto: `#ffffff`
|
||||
- Relleno: 14px 24px
|
||||
- Radio: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (la sombra gruesa)
|
||||
- Hover: fondo `#89e219`
|
||||
- Activo: translate-y 4px, border-bottom 0 (el botón se "presiona")
|
||||
- Uso: "Continuar", "Comprobar", CTA principal.
|
||||
|
||||
**Secundario (Blanco con sombra inferior)**
|
||||
- Fondo: `#ffffff`
|
||||
- Texto: `#777777`
|
||||
- Borde: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radio: 16px
|
||||
- Relleno: 14px 24px
|
||||
- Hover: texto `#3c3c3c`, borde `#afafaf`
|
||||
|
||||
**Naranja de racha**
|
||||
- Fondo: `#ff9600`
|
||||
- Texto: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Uso: objetivo de racha, "Iniciar racha"
|
||||
|
||||
**Error (Rojo cardenal)**
|
||||
- Fondo: `#ff4b4b`
|
||||
- Texto: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Uso: retroalimentación de respuesta incorrecta.
|
||||
|
||||
### Tarjetas / Mosaicos de lección
|
||||
- Fondo: `#ffffff`
|
||||
- Borde: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radio: 16px
|
||||
- Relleno: 16px
|
||||
- Hover: elevar 2px, sombra `0 4px 0 #d7d7d7`
|
||||
|
||||
### Nodo del árbol de habilidades (Burbuja de lección)
|
||||
- Tamaño: 80×72px
|
||||
- Fondo: tintado con color de habilidad (verde para activo, gris para bloqueado)
|
||||
- Border-bottom: 6px solid variante más oscura
|
||||
- Radio: 50% (circular)
|
||||
- Activo: pulsa 1.0 → 1.05 cada 1.6s
|
||||
|
||||
### Entradas
|
||||
- Fondo: `#ffffff`
|
||||
- Borde: 2px solid `#e5e5e5`
|
||||
- Radio: 12px
|
||||
- Relleno: 12px 16px
|
||||
- Foco: borde `#1cb0f6` (azul anguila), anillo `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Barra de progreso
|
||||
- Pista: `#e5e5e5`
|
||||
- Relleno: `#58cc02` (o `#ff9600` para racha)
|
||||
- Radio: 9999px
|
||||
- Altura: 16px
|
||||
- Relleno animado: 320ms ease-out al incrementar.
|
||||
|
||||
## 5. Espaciado y diseño
|
||||
|
||||
- **Unidad base**: 4px. Escala: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Contenedor**: máx. 1080px, canaleta de 24px.
|
||||
- **Columna del árbol de lecciones**: 320px de ancho; centrada en escritorio.
|
||||
|
||||
## 6. Movimiento
|
||||
|
||||
- **Duración**: 180ms para presionar botón; 320ms para desbloqueo de nodo de habilidad; 1.6s para pulso de nodo activo.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, ligero rebase) para desbloqueos.
|
||||
- **Mascota**: Duo parpadea cada 4–6s, salta en hitos de racha (480ms ease-out resorte).
|
||||
|
||||
## 7. Directrices de uso
|
||||
|
||||
- Mantenga juntos el verde búho de alta saturación, las gruesas sombras inferiores y la geometría redondeada de las lecciones; los botones verdes planos solos no se leen como Duolingo.
|
||||
- Reserve el texto en negrita de gran tamaño para los momentos de lección, racha y progreso donde el producto necesita aliento o retroalimentación.
|
||||
- Use el movimiento lúdico con moderación alrededor de los cambios de estado de progreso, evitando animaciones genéricas de rebote en cada control.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Système de design inspiré de Duolingo
|
||||
|
||||
> Category: Productivité & SaaS
|
||||
> Plateforme d'apprentissage des langues. Vert hibou lumineux, ombres épaisses, joie gamifiée.
|
||||
|
||||
## 1. Thème visuel et atmosphère
|
||||
|
||||
Duolingo est la gamification rendue en langage visuel. L'interface est délibérément lumineuse, avec le **vert hibou** (`#58cc02`) comme couleur primaire de marque, et une épaisse ombre de 4px en bas de chaque élément interactif qui ressemble à un bouton 3D attendant d'être pressé. La page est blanche (`#ffffff`) avec des bordures épaisses de 2–3px dans un gris profond (`#e5e5e5`), et l'ensemble du système se lit comme une application iOS de 2015 réincarnée avec une meilleure hiérarchie.
|
||||
|
||||
La typographie utilise **Feather Bold** (un sans-serif arrondi personnalisé) pour le chrome et **Mona Sans** (ou Inter) pour le corps du texte. Les tailles d'affichage sont grandes et confiantes — Duolingo ne murmure jamais. Les titres portent souvent un trait souligné vert ou reposent sur une pastille verte, et la mascotte Duo (un hibou vert) apparaît comme un personnage d'illustration actif, non comme un logo statique.
|
||||
|
||||
Le langage des formes est amical : rayons de 16–20px sur les cartes, 12px sur les boutons, 9999px sur les puces et les barres de progression. L'iconographie est remplie, arrondie et codée par couleur selon la compétence — chaque surface de leçon possède une combinaison de couleurs identifiable instantanément.
|
||||
|
||||
**Caractéristiques clés :**
|
||||
- Vert hibou (`#58cc02`) comme couleur de marque dominante, utilisée sur plus de 30% de la surface
|
||||
- Épaisse ombre de 4px en bas de chaque bouton (l'affordance « pression tactile »)
|
||||
- Bordures solides de 2–3px, jamais de filets
|
||||
- Feather Bold (affichage arrondi) + Mona Sans (corps)
|
||||
- Grand texte confiant — les tailles d'affichage commencent à 48px et montent
|
||||
- Mascotte-personnage : Duo le hibou apparaît à l'onboarding, lors des erreurs, des séries
|
||||
- Orange série (`#ff9600`) et rose gemme (`#ce82ff`) comme couleurs de marque secondaires
|
||||
|
||||
## 2. Palette de couleurs & rôles
|
||||
|
||||
### Primaire
|
||||
- **Vert hibou** (`#58cc02`) : Primaire marque, CTA principal, bonne réponse.
|
||||
- **Vert hibou profond** (`#58a700`) : Couleur de pression/ombre pour les boutons verts.
|
||||
- **Vert hibou clair** (`#89e219`) : Survol, remplissages doux.
|
||||
- **Vert hibou pâle** (`#dbf8c5`) : Surface douce, bannière de succès.
|
||||
|
||||
### Accents secondaires
|
||||
- **Orange série** (`#ff9600`) : Compteur de série, icône de flamme, énergie premium.
|
||||
- **Orange série profond** (`#cc7a00`) : Orange enfoncé.
|
||||
- **Rose gemme** (`#ce82ff`) : Monnaie gemme, Super Duolingo.
|
||||
- **Bleu anguille** (`#1cb0f6`) : Bouton d'indice, lien d'information.
|
||||
- **Rouge cardinal** (`#ff4b4b`) : Mauvaise réponse, vie perdue.
|
||||
- **Jaune abeille** (`#ffc800`) : Badge pro, récompense.
|
||||
|
||||
### Surface
|
||||
- **Neige** (`#ffffff`) : Arrière-plan principal.
|
||||
- **Anguille** (`#f7f7f7`) : Séparation de section, surface secondaire.
|
||||
- **Cygne** (`#e5e5e5`) : Arrière-plan désactivé, bloc encastré.
|
||||
- **Loup** (`#777777`) : Séparateur foncé, texte secondaire.
|
||||
|
||||
### Encre & texte
|
||||
- **Noir anguille** (`#3c3c3c`) : Texte principal.
|
||||
- **Loup** (`#777777`) : Texte secondaire, légendes.
|
||||
- **Lièvre** (`#afafaf`) : Désactivé, espace réservé.
|
||||
|
||||
### Bordure
|
||||
- **Cygne** (`#e5e5e5`) : Bordure standard de 2px.
|
||||
- **Lièvre** (`#afafaf`) : Bordure accentuée au survol.
|
||||
|
||||
## 3. Règles typographiques
|
||||
|
||||
### Famille de polices
|
||||
- **Affichage / UI / Titres** : `Feather Bold`, avec repli : `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Corps / Texte long** : `Mona Sans`, avec repli : `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Code (rare, écoles/admin)** : `JetBrains Mono`, avec repli : `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hiérarchie
|
||||
|
||||
| Rôle | Police | Taille | Graisse | Hauteur de ligne | Espacement | Notes |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Affichage | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Héros d'onboarding |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Titre de page |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | En-tête de section |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Titre de carte, ligne de leçon |
|
||||
| Corps grand | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Consigne de leçon, instruction |
|
||||
| Corps | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Prose standard |
|
||||
| Légende | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Compteur XP, métadonnées |
|
||||
| Bouton | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Libellé de bouton standard |
|
||||
| Série | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Numéro de série, sur la flamme |
|
||||
|
||||
### Principes
|
||||
- **800 est la valeur par défaut** : Feather Bold s'exécute à 800 sur les titres et les boutons. 700 semble faible dans ce système.
|
||||
- **Grand texte** : les tailles de titres sont 25–40% plus grandes que les marques de produits typiques — la confiance comme identité.
|
||||
- **Lettres arrondies** : chaque glyphe a des terminaisons douces ; les empattements tranchants rompraient le contrat de convivialité.
|
||||
|
||||
## 4. Styles des composants
|
||||
|
||||
### Boutons
|
||||
|
||||
**Primaire (Vert hibou)**
|
||||
- Arrière-plan : `#58cc02`
|
||||
- Texte : `#ffffff`
|
||||
- Rembourrage : 14px 24px
|
||||
- Rayon : 16px
|
||||
- Border-bottom : 4px solid `#58a700` (l'ombre épaisse)
|
||||
- Survol : arrière-plan `#89e219`
|
||||
- Actif : translate-y 4px, border-bottom 0 (le bouton « s'enfonce »)
|
||||
- Utilisation : « Continuer », « Vérifier », CTA principal.
|
||||
|
||||
**Secondaire (Blanc avec ombre basse)**
|
||||
- Arrière-plan : `#ffffff`
|
||||
- Texte : `#777777`
|
||||
- Bordure : 2px solid `#e5e5e5`
|
||||
- Border-bottom : 4px solid `#e5e5e5`
|
||||
- Rayon : 16px
|
||||
- Rembourrage : 14px 24px
|
||||
- Survol : texte `#3c3c3c`, bordure `#afafaf`
|
||||
|
||||
**Orange série**
|
||||
- Arrière-plan : `#ff9600`
|
||||
- Texte : `#ffffff`
|
||||
- Border-bottom : 4px solid `#cc7a00`
|
||||
- Utilisation : objectif de série, « Commencer la série »
|
||||
|
||||
**Erreur (Rouge cardinal)**
|
||||
- Arrière-plan : `#ff4b4b`
|
||||
- Texte : `#ffffff`
|
||||
- Border-bottom : 4px solid `#cc3b3b`
|
||||
- Utilisation : retour sur mauvaise réponse.
|
||||
|
||||
### Cartes / Tuiles de leçon
|
||||
- Arrière-plan : `#ffffff`
|
||||
- Bordure : 2px solid `#e5e5e5`
|
||||
- Border-bottom : 4px solid `#e5e5e5`
|
||||
- Rayon : 16px
|
||||
- Rembourrage : 16px
|
||||
- Survol : élévation de 2px, ombre `0 4px 0 #d7d7d7`
|
||||
|
||||
### Nœud de l'arbre de compétences (Bulle de leçon)
|
||||
- Taille : 80×72px
|
||||
- Arrière-plan : teinte couleur compétence (vert pour actif, gris pour verrouillé)
|
||||
- Border-bottom : 6px solid variante plus sombre
|
||||
- Rayon : 50% (circulaire)
|
||||
- Actif : pulsation 1.0 → 1.05 toutes les 1.6s
|
||||
|
||||
### Champs de saisie
|
||||
- Arrière-plan : `#ffffff`
|
||||
- Bordure : 2px solid `#e5e5e5`
|
||||
- Rayon : 12px
|
||||
- Rembourrage : 12px 16px
|
||||
- Focus : bordure `#1cb0f6` (bleu anguille), anneau `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Barre de progression
|
||||
- Piste : `#e5e5e5`
|
||||
- Remplissage : `#58cc02` (ou `#ff9600` pour la série)
|
||||
- Rayon : 9999px
|
||||
- Hauteur : 16px
|
||||
- Remplissage animé : 320ms ease-out lors de l'incrémentation.
|
||||
|
||||
## 5. Espacement & mise en page
|
||||
|
||||
- **Unité de base** : 4px. Échelle : 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Conteneur** : max 1080px, gouttière de 24px.
|
||||
- **Colonne de l'arbre de leçons** : 320px de large ; centré sur le bureau.
|
||||
|
||||
## 6. Mouvement
|
||||
|
||||
- **Durée** : 180ms pour la pression du bouton ; 320ms pour le déverrouillage du nœud de compétence ; 1.6s pour le pulse du nœud actif.
|
||||
- **Easing** : `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, léger dépassement) pour les déverrouillages.
|
||||
- **Mascotte** : Duo cligne des yeux toutes les 4–6s, saute lors des jalons de série (480ms ease-out ressort).
|
||||
|
||||
## 7. Directives d'utilisation
|
||||
|
||||
- Gardez le vert hibou à haute saturation, les épaisses ombres basses et la géométrie arrondie des leçons ensemble ; les boutons verts plats seuls ne se lisent pas comme Duolingo.
|
||||
- Réservez le texte en gras surdimensionné pour les moments de leçon, de série et de progression où le produit a besoin d'encouragement ou de retour.
|
||||
- Utilisez les mouvements ludiques avec parcimonie autour des changements d'état de progression, en évitant les animations rebondissantes génériques sur chaque contrôle.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Sistem desain terinspirasi Duolingo
|
||||
|
||||
> Category: Produktivitas & SaaS
|
||||
> Platform pembelajaran bahasa. Hijau burung hantu cerah, bayangan tebal, kegembiraan gamifikasi.
|
||||
|
||||
## 1. Tema visual dan atmosfer
|
||||
|
||||
Duolingo adalah gamifikasi yang diwujudkan sebagai bahasa visual. Antarmuka ini dengan berani cerah, dengan **hijau burung hantu** (`#58cc02`) sebagai warna utama merek dan bayangan bawah 4px yang tebal pada setiap elemen interaktif yang terlihat seperti tombol 3D menunggu ditekan. Halaman berwarna putih (`#ffffff`) dengan border tebal 2–3px berwarna abu-abu gelap (`#e5e5e5`), dan seluruh sistem terasa seperti aplikasi iOS tahun 2015 yang terlahir kembali dengan hierarki yang lebih baik.
|
||||
|
||||
Tipografi menggunakan **Feather Bold** (sans-serif bulat kustom) untuk chrome dan **Mona Sans** (atau Inter) untuk teks isi. Ukuran tampilan besar dan percaya diri — Duolingo tidak pernah berbisik. Judul sering membawa coretan garis bawah hijau atau duduk di atas pil hijau, dan maskot Duo (burung hantu hijau) muncul sebagai karakter ilustrasi aktif, bukan logo statis.
|
||||
|
||||
Bahasa bentuk ramah: radius 16–20px pada kartu, 12px pada tombol, 9999px pada chip dan progress bar. Ikonografi terisi, dibulatkan, dan dikodekan warna berdasarkan keterampilan — setiap permukaan pelajaran memiliki pasangan warna yang langsung dapat diidentifikasi.
|
||||
|
||||
**Karakteristik utama:**
|
||||
- Hijau burung hantu (`#58cc02`) sebagai warna merek dominan, digunakan pada lebih dari 30% permukaan
|
||||
- Bayangan bawah tebal 4px pada setiap tombol (affordansi "tekanan taktil")
|
||||
- Border solid 2–3px, tidak pernah garis tipis
|
||||
- Feather Bold (tampilan bulat) + Mona Sans (isi)
|
||||
- Teks besar percaya diri — ukuran tampilan mulai dari 48px dan naik
|
||||
- Maskot sebagai karakter: burung hantu Duo muncul di onboarding, kesalahan, streak
|
||||
- Oranye streak (`#ff9600`) dan merah muda permata (`#ce82ff`) sebagai warna merek sekunder
|
||||
|
||||
## 2. Palet warna & peran
|
||||
|
||||
### Primer
|
||||
- **Hijau burung hantu** (`#58cc02`): Primer merek, CTA utama, jawaban benar.
|
||||
- **Hijau burung hantu dalam** (`#58a700`): Warna tekan/bayangan untuk tombol hijau.
|
||||
- **Hijau burung hantu terang** (`#89e219`): Hover, isian lembut.
|
||||
- **Hijau burung hantu pucat** (`#dbf8c5`): Permukaan lembut, spanduk sukses.
|
||||
|
||||
### Aksen sekunder
|
||||
- **Oranye streak** (`#ff9600`): Penghitung streak, ikon api, energi premium.
|
||||
- **Oranye streak dalam** (`#cc7a00`): Oranye ditekan.
|
||||
- **Merah muda permata** (`#ce82ff`): Mata uang permata, Super Duolingo.
|
||||
- **Biru belut** (`#1cb0f6`): Tombol petunjuk, tautan info.
|
||||
- **Merah kardinal** (`#ff4b4b`): Jawaban salah, nyawa hilang.
|
||||
- **Kuning lebah** (`#ffc800`): Lencana pro, pencapaian.
|
||||
|
||||
### Permukaan
|
||||
- **Salju** (`#ffffff`): Latar belakang utama.
|
||||
- **Belut** (`#f7f7f7`): Pemisah bagian, permukaan sekunder.
|
||||
- **Angsa** (`#e5e5e5`): Latar belakang dinonaktifkan, blok tersemat.
|
||||
- **Serigala** (`#777777`): Pembagi gelap, teks sekunder.
|
||||
|
||||
### Tinta & teks
|
||||
- **Hitam belut** (`#3c3c3c`): Teks utama.
|
||||
- **Serigala** (`#777777`): Teks sekunder, keterangan.
|
||||
- **Kelinci** (`#afafaf`): Dinonaktifkan, placeholder.
|
||||
|
||||
### Border
|
||||
- **Angsa** (`#e5e5e5`): Border standar 2px.
|
||||
- **Kelinci** (`#afafaf`): Border ditekankan saat hover.
|
||||
|
||||
## 3. Aturan tipografi
|
||||
|
||||
### Keluarga font
|
||||
- **Tampilan / UI / Judul**: `Feather Bold`, dengan fallback: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Isi / Teks panjang**: `Mona Sans`, dengan fallback: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Kode (jarang, sekolah/admin)**: `JetBrains Mono`, dengan fallback: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hierarki
|
||||
|
||||
| Peran | Font | Ukuran | Berat | Tinggi baris | Jarak huruf | Catatan |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Tampilan | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Hero onboarding |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Judul halaman |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Judul bagian |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Judul kartu, baris pelajaran |
|
||||
| Isi besar | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Prompt pelajaran, instruksi |
|
||||
| Isi | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Prosa standar |
|
||||
| Keterangan | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Penghitung XP, metadata |
|
||||
| Tombol | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Label tombol standar |
|
||||
| Streak | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Nomor streak, di atas api |
|
||||
|
||||
### Prinsip
|
||||
- **800 adalah default**: Feather Bold berjalan di 800 pada judul dan tombol. 700 terasa lemah dalam sistem ini.
|
||||
- **Teks besar**: ukuran judul 25–40% lebih besar dari merek produk tipikal — kepercayaan diri sebagai identitas.
|
||||
- **Bentuk huruf bulat**: setiap glif memiliki terminal yang lembut; serif tajam akan merusak kontrak keramahan.
|
||||
|
||||
## 4. Styling komponen
|
||||
|
||||
### Tombol
|
||||
|
||||
**Primer (Hijau burung hantu)**
|
||||
- Latar belakang: `#58cc02`
|
||||
- Teks: `#ffffff`
|
||||
- Padding: 14px 24px
|
||||
- Radius: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (bayangan tebal)
|
||||
- Hover: latar belakang `#89e219`
|
||||
- Aktif: translate-y 4px, border-bottom 0 (tombol "ditekan")
|
||||
- Penggunaan: "Lanjutkan", "Periksa", CTA utama.
|
||||
|
||||
**Sekunder (Putih dengan bayangan bawah)**
|
||||
- Latar belakang: `#ffffff`
|
||||
- Teks: `#777777`
|
||||
- Border: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Padding: 14px 24px
|
||||
- Hover: teks `#3c3c3c`, border `#afafaf`
|
||||
|
||||
**Oranye streak**
|
||||
- Latar belakang: `#ff9600`
|
||||
- Teks: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Penggunaan: target streak, "Mulai streak"
|
||||
|
||||
**Kesalahan (Merah kardinal)**
|
||||
- Latar belakang: `#ff4b4b`
|
||||
- Teks: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Penggunaan: umpan balik jawaban salah.
|
||||
|
||||
### Kartu / Ubin pelajaran
|
||||
- Latar belakang: `#ffffff`
|
||||
- Border: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Padding: 16px
|
||||
- Hover: angkat 2px, bayangan `0 4px 0 #d7d7d7`
|
||||
|
||||
### Node pohon keterampilan (Gelembung pelajaran)
|
||||
- Ukuran: 80×72px
|
||||
- Latar belakang: warna keterampilan tint (hijau untuk aktif, abu-abu untuk terkunci)
|
||||
- Border-bottom: 6px solid varian lebih gelap
|
||||
- Radius: 50% (lingkaran)
|
||||
- Aktif: berdenyut 1.0 → 1.05 setiap 1.6s
|
||||
|
||||
### Input
|
||||
- Latar belakang: `#ffffff`
|
||||
- Border: 2px solid `#e5e5e5`
|
||||
- Radius: 12px
|
||||
- Padding: 12px 16px
|
||||
- Fokus: border `#1cb0f6` (biru belut), cincin `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Progress bar
|
||||
- Jalur: `#e5e5e5`
|
||||
- Isian: `#58cc02` (atau `#ff9600` untuk streak)
|
||||
- Radius: 9999px
|
||||
- Tinggi: 16px
|
||||
- Isian animasi: 320ms ease-out saat bertambah.
|
||||
|
||||
## 5. Jarak & Tata letak
|
||||
|
||||
- **Unit dasar**: 4px. Skala: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Kontainer**: maks. 1080px, gutter 24px.
|
||||
- **Kolom pohon pelajaran**: lebar 320px; dipusatkan di desktop.
|
||||
|
||||
## 6. Gerakan
|
||||
|
||||
- **Durasi**: 180ms untuk tekanan tombol; 320ms untuk membuka kunci node keterampilan; 1.6s untuk denyut node aktif.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, sedikit lewat) untuk membuka kunci.
|
||||
- **Maskot**: Duo berkedip setiap 4–6s, melompat pada tonggak streak (480ms ease-out pegas).
|
||||
|
||||
## 7. Panduan penggunaan
|
||||
|
||||
- Pertahankan hijau burung hantu saturasi tinggi, bayangan bawah tebal, dan geometri pelajaran bulat secara bersamaan; tombol hijau datar saja tidak terbaca sebagai Duolingo.
|
||||
- Simpan teks tebal berukuran besar untuk momen pelajaran, streak, dan kemajuan di mana produk membutuhkan dorongan atau umpan balik.
|
||||
- Gunakan gerakan ceria dengan hemat di sekitar perubahan status kemajuan, hindari animasi memantul generik pada setiap kontrol.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Sistema di design ispirato a Duolingo
|
||||
|
||||
> Category: Produttività e SaaS
|
||||
> Piattaforma di apprendimento delle lingue. Verde gufo brillante, ombre spesse, gioia gamificata.
|
||||
|
||||
## 1. Tema visivo e atmosfera
|
||||
|
||||
Duolingo è la gamificazione resa come linguaggio visivo. L'interfaccia è senza riserve luminosa, con il **verde gufo** (`#58cc02`) come colore primario del brand e una spessa ombra di 4px nella parte inferiore di ogni elemento interattivo, che si legge come un pulsante 3D in attesa di essere premuto. La pagina è bianca (`#ffffff`) con bordi spessi di 2–3px in grigio scuro (`#e5e5e5`), e l'intero sistema si legge come un'app iOS del 2015 rinata con una gerarchia migliore.
|
||||
|
||||
La tipografia usa **Feather Bold** (un sans-serif arrotondato personalizzato) per il chrome e **Mona Sans** (o Inter) per il corpo del testo. Le dimensioni display sono grandi e sicure — Duolingo non sussurra mai. I titoli portano spesso il tratto sottolineato verde o siedono su una pillola verde, e la mascotte Duo (un gufo verde) appare come un personaggio illustrativo attivo, non come un logo statico.
|
||||
|
||||
Il linguaggio delle forme è amichevole: raggi di 16–20px sulle schede, 12px sui pulsanti, 9999px su chip e barre di avanzamento. L'iconografia è piena, arrotondata e codificata per colore per competenza — ogni superficie di lezione ha una combinazione di colori immediatamente identificabile.
|
||||
|
||||
**Caratteristiche principali:**
|
||||
- Verde gufo (`#58cc02`) come colore di brand dominante, usato in oltre il 30% della superficie
|
||||
- Spessa ombra inferiore di 4px su ogni pulsante (l'affordance della "pressione tattile")
|
||||
- Bordi solidi di 2–3px, mai linee sottili
|
||||
- Feather Bold (display arrotondato) + Mona Sans (corpo)
|
||||
- Testo grande e sicuro — le dimensioni display partono da 48px e salgono
|
||||
- Mascotte come personaggio: Duo il gufo appare nell'onboarding, negli errori, nelle serie
|
||||
- Arancione serie (`#ff9600`) e rosa gemma (`#ce82ff`) come colori di brand secondari
|
||||
|
||||
## 2. Palette colori e ruoli
|
||||
|
||||
### Primario
|
||||
- **Verde gufo** (`#58cc02`): Primario brand, CTA principale, risposta corretta.
|
||||
- **Verde gufo scuro** (`#58a700`): Colore di pressione/ombra per i pulsanti verdi.
|
||||
- **Verde gufo chiaro** (`#89e219`): Hover, riempimenti morbidi.
|
||||
- **Verde gufo pallido** (`#dbf8c5`): Superficie morbida, banner di successo.
|
||||
|
||||
### Accenti secondari
|
||||
- **Arancione serie** (`#ff9600`): Contatore serie, icona fiamma, energia premium.
|
||||
- **Arancione serie scuro** (`#cc7a00`): Arancione premuto.
|
||||
- **Rosa gemma** (`#ce82ff`): Valuta gemma, Super Duolingo.
|
||||
- **Blu anguilla** (`#1cb0f6`): Pulsante suggerimento, link informativo.
|
||||
- **Rosso cardinale** (`#ff4b4b`): Risposta errata, vita persa.
|
||||
- **Giallo ape** (`#ffc800`): Badge pro, risultato.
|
||||
|
||||
### Superficie
|
||||
- **Neve** (`#ffffff`): Sfondo principale.
|
||||
- **Anguilla** (`#f7f7f7`): Separazione sezione, superficie secondaria.
|
||||
- **Cigno** (`#e5e5e5`): Sfondo disabilitato, blocco incorporato.
|
||||
- **Lupo** (`#777777`): Divisore scuro, testo secondario.
|
||||
|
||||
### Inchiostro e testo
|
||||
- **Nero anguilla** (`#3c3c3c`): Testo principale.
|
||||
- **Lupo** (`#777777`): Testo secondario, didascalie.
|
||||
- **Lepre** (`#afafaf`): Disabilitato, segnaposto.
|
||||
|
||||
### Bordo
|
||||
- **Cigno** (`#e5e5e5`): Bordo standard 2px.
|
||||
- **Lepre** (`#afafaf`): Bordo enfatizzato all'hover.
|
||||
|
||||
## 3. Regole tipografiche
|
||||
|
||||
### Famiglia di font
|
||||
- **Display / UI / Titoli**: `Feather Bold`, con fallback: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Corpo / Testo lungo**: `Mona Sans`, con fallback: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Codice (raro, scuole/admin)**: `JetBrains Mono`, con fallback: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Gerarchia
|
||||
|
||||
| Ruolo | Font | Dimensione | Peso | Altezza riga | Spaziatura | Note |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Eroe onboarding |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Titolo pagina |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Intestazione sezione |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Titolo scheda, riga lezione |
|
||||
| Corpo grande | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Prompt lezione, istruzione |
|
||||
| Corpo | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Prosa standard |
|
||||
| Didascalia | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Contatore XP, metadati |
|
||||
| Pulsante | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Etichetta pulsante standard |
|
||||
| Serie | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Numero serie, sulla fiamma |
|
||||
|
||||
### Principi
|
||||
- **800 è il predefinito**: Feather Bold gira a 800 su titoli e pulsanti. 700 risulta debole in questo sistema.
|
||||
- **Testo grande**: le dimensioni dei titoli sono 25–40% più grandi rispetto ai brand di prodotto tipici — la sicurezza come identità.
|
||||
- **Forme delle lettere arrotondate**: ogni glifo ha terminazioni morbide; le grazie taglienti romperebbero il contratto di amichevolezza.
|
||||
|
||||
## 4. Stile dei componenti
|
||||
|
||||
### Pulsanti
|
||||
|
||||
**Primario (Verde gufo)**
|
||||
- Sfondo: `#58cc02`
|
||||
- Testo: `#ffffff`
|
||||
- Spaziatura interna: 14px 24px
|
||||
- Raggio: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (l'ombra spessa)
|
||||
- Hover: sfondo `#89e219`
|
||||
- Attivo: translate-y 4px, border-bottom 0 (il pulsante "si preme")
|
||||
- Utilizzo: "Continua", "Controlla", CTA principale.
|
||||
|
||||
**Secondario (Bianco con ombra inferiore)**
|
||||
- Sfondo: `#ffffff`
|
||||
- Testo: `#777777`
|
||||
- Bordo: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Raggio: 16px
|
||||
- Spaziatura interna: 14px 24px
|
||||
- Hover: testo `#3c3c3c`, bordo `#afafaf`
|
||||
|
||||
**Arancione serie**
|
||||
- Sfondo: `#ff9600`
|
||||
- Testo: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Utilizzo: obiettivo serie, "Inizia serie"
|
||||
|
||||
**Errore (Rosso cardinale)**
|
||||
- Sfondo: `#ff4b4b`
|
||||
- Testo: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Utilizzo: feedback risposta errata.
|
||||
|
||||
### Schede / Riquadri lezione
|
||||
- Sfondo: `#ffffff`
|
||||
- Bordo: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Raggio: 16px
|
||||
- Spaziatura interna: 16px
|
||||
- Hover: sollevare di 2px, ombra `0 4px 0 #d7d7d7`
|
||||
|
||||
### Nodo albero competenze (Bolla lezione)
|
||||
- Dimensione: 80×72px
|
||||
- Sfondo: tinta colore competenza (verde per attivo, grigio per bloccato)
|
||||
- Border-bottom: 6px solid variante più scura
|
||||
- Raggio: 50% (circolare)
|
||||
- Attivo: pulsa 1.0 → 1.05 ogni 1.6s
|
||||
|
||||
### Input
|
||||
- Sfondo: `#ffffff`
|
||||
- Bordo: 2px solid `#e5e5e5`
|
||||
- Raggio: 12px
|
||||
- Spaziatura interna: 12px 16px
|
||||
- Focus: bordo `#1cb0f6` (blu anguilla), anello `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Barra di avanzamento
|
||||
- Traccia: `#e5e5e5`
|
||||
- Riempimento: `#58cc02` (o `#ff9600` per la serie)
|
||||
- Raggio: 9999px
|
||||
- Altezza: 16px
|
||||
- Riempimento animato: 320ms ease-out all'incremento.
|
||||
|
||||
## 5. Spaziatura e layout
|
||||
|
||||
- **Unità base**: 4px. Scala: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Contenitore**: max 1080px, grondaia 24px.
|
||||
- **Colonna albero lezioni**: 320px di larghezza; centrata su desktop.
|
||||
|
||||
## 6. Movimento
|
||||
|
||||
- **Durata**: 180ms per la pressione del pulsante; 320ms per lo sblocco del nodo competenza; 1.6s per il pulse del nodo attivo.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, leggero superamento) per gli sblocchi.
|
||||
- **Mascotte**: Duo sbatte le palpebre ogni 4–6s, salta ai traguardi della serie (480ms ease-out molla).
|
||||
|
||||
## 7. Linee guida sull'uso
|
||||
|
||||
- Mantieni insieme il verde gufo ad alta saturazione, le spesse ombre inferiori e la geometria arrotondata delle lezioni; i pulsanti verdi piatti da soli non si leggono come Duolingo.
|
||||
- Riserva il testo in grassetto sovradimensionato per i momenti di lezione, serie e progresso in cui il prodotto ha bisogno di incoraggiamento o feedback.
|
||||
- Usa il movimento giocoso con parsimonia attorno ai cambiamenti di stato di avanzamento, evitando animazioni rimbalzanti generiche su ogni controllo.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Duolingo にインスパイアされたデザインシステム
|
||||
|
||||
> Category: 生産性 & SaaS
|
||||
> 語学学習プラットフォーム。明るいフクロウグリーン、ぶ厚いシャドウ、ゲーミフィケーションの喜び。
|
||||
|
||||
## 1. ビジュアルテーマと雰囲気
|
||||
|
||||
Duolingo はゲーミフィケーションをビジュアル言語として体現したデザインです。インターフェースは遠慮なく鮮やかで、**フクロウグリーン**(`#58cc02`)をブランドプライマリとし、すべてのインタラクティブ要素の下部に 4px のぶ厚いシャドウを持ち、まるで押されるのを待っている 3D ボタンのように見えます。ページは白(`#ffffff`)で、2〜3px の太いボーダーは深いグレー(`#e5e5e5`)、システム全体がより良い階層構造で生まれ変わった 2015 年の iOS アプリのように読めます。
|
||||
|
||||
タイポグラフィは、クロームに **Feather Bold**(カスタムの丸みを帯びたサンセリフ)、本文に **Mona Sans**(または Inter)を使用しています。ディスプレイサイズは大きく自信に満ちており——Duolingo は決してささやきません。見出しはグリーンのアンダーラインストロークを持つか、グリーンのピルの上に置かれることが多く、マスコットの Duo(緑のフクロウ)は静的なロゴではなく、アクティブなイラストキャラクターとして登場します。
|
||||
|
||||
形状言語は親しみやすく:カードは 16〜20px の角丸、ボタンは 12px、チップとプログレスバーは 9999px です。アイコノグラフィは塗りつぶし、丸みを帯び、スキルでカラーコード化されており——すべてのレッスン面には一目で識別できるカラーペアリングがあります。
|
||||
|
||||
**主要な特徴:**
|
||||
- フクロウグリーン(`#58cc02`)が支配的なブランドカラーとして、サーフェスの 30% 以上を占める
|
||||
- すべてのボタンに 4px のぶ厚いボトムシャドウ(「触覚的プレス」のアフォーダンス)
|
||||
- 2〜3px のソリッドボーダー、ヘアラインは一切使わない
|
||||
- Feather Bold(丸みのあるディスプレイ)+ Mona Sans(本文)
|
||||
- 大きく自信のあるテキスト——ディスプレイサイズは 48px から始まり上昇する
|
||||
- マスコット=キャラクター:Duo フクロウはオンボーディング、エラー、ストリークに登場
|
||||
- ストリークオレンジ(`#ff9600`)とジェムピンク(`#ce82ff`)がセカンダリブランドカラー
|
||||
|
||||
## 2. カラーパレットと役割
|
||||
|
||||
### プライマリ
|
||||
- **フクロウグリーン**(`#58cc02`):ブランドプライマリ、プライマリ CTA、正解。
|
||||
- **フクロウグリーンディープ**(`#58a700`):グリーンボタンのプレス/シャドウカラー。
|
||||
- **フクロウグリーンライト**(`#89e219`):ホバー、ソフトフィル。
|
||||
- **フクロウグリーンペール**(`#dbf8c5`):ソフトサーフェス、成功バナー。
|
||||
|
||||
### セカンダリアクセント
|
||||
- **ストリークオレンジ**(`#ff9600`):ストリークカウンター、炎アイコン、プレミアムエネルギー。
|
||||
- **ストリークオレンジディープ**(`#cc7a00`):オレンジのプレス状態。
|
||||
- **ジェムピンク**(`#ce82ff`):ジェム通貨、Super Duolingo。
|
||||
- **ウナギブルー**(`#1cb0f6`):ヒントボタン、情報リンク。
|
||||
- **カーディナルレッド**(`#ff4b4b`):不正解、ライフ喪失。
|
||||
- **ビーイエロー**(`#ffc800`):プロバッジ、実績。
|
||||
|
||||
### サーフェス
|
||||
- **スノー**(`#ffffff`):プライマリ背景。
|
||||
- **ウナギ**(`#f7f7f7`):セクション区切り、セカンダリサーフェス。
|
||||
- **スワン**(`#e5e5e5`):無効化背景、インセットブロック。
|
||||
- **ウルフ**(`#777777`):ダークディバイダー、セカンダリテキスト。
|
||||
|
||||
### インクとテキスト
|
||||
- **ウナギブラック**(`#3c3c3c`):プライマリテキスト。
|
||||
- **ウルフ**(`#777777`):セカンダリテキスト、キャプション。
|
||||
- **ヘア**(`#afafaf`):無効化、プレースホルダー。
|
||||
|
||||
### ボーダー
|
||||
- **スワン**(`#e5e5e5`):標準 2px ボーダー。
|
||||
- **ヘア**(`#afafaf`):ホバー時の強調ボーダー。
|
||||
|
||||
## 3. タイポグラフィルール
|
||||
|
||||
### フォントファミリー
|
||||
- **ディスプレイ / UI / 見出し**:`Feather Bold`、フォールバック:`'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **本文 / 長文**:`Mona Sans`、フォールバック:`'Helvetica Neue', system-ui, sans-serif`
|
||||
- **コード(稀、学校/管理)**:`JetBrains Mono`、フォールバック:`ui-monospace, Menlo, monospace`
|
||||
|
||||
### 階層
|
||||
|
||||
| 役割 | フォント | サイズ | ウェイト | 行間 | 字間 | 備考 |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| ディスプレイ | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | オンボーディングヒーロー |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | ページタイトル |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | セクション見出し |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | カードタイトル、レッスン行 |
|
||||
| 本文ラージ | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | レッスンプロンプト、説明 |
|
||||
| 本文 | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | 標準テキスト |
|
||||
| キャプション | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | XP カウンター、メタデータ |
|
||||
| ボタン | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | 標準ボタンラベル |
|
||||
| ストリーク | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | ストリーク数字、炎の上 |
|
||||
|
||||
### 原則
|
||||
- **800 がデフォルト**:Feather Bold は見出しとボタンで 800 で動作します。700 はこのシステムでは弱く見えます。
|
||||
- **大きなタイプ**:見出しサイズは典型的なプロダクトブランドより 25〜40% 大きく——自信がアイデンティティです。
|
||||
- **丸みのある字形**:すべてのグリフにソフトなターミナルがあります。シャープなセリフは親しみやすさの契約を壊します。
|
||||
|
||||
## 4. コンポーネントスタイリング
|
||||
|
||||
### ボタン
|
||||
|
||||
**プライマリ(フクロウグリーン)**
|
||||
- 背景:`#58cc02`
|
||||
- テキスト:`#ffffff`
|
||||
- パディング:14px 24px
|
||||
- 角丸:16px
|
||||
- ボーダーボトム:4px solid `#58a700`(ぶ厚いシャドウ)
|
||||
- ホバー:背景 `#89e219`
|
||||
- アクティブ:translate-y 4px、ボーダーボトム 0(ボタンが「押される」)
|
||||
- 使用:「続ける」、「確認」、メイン CTA。
|
||||
|
||||
**セカンダリ(ボトムシャドウ付き白)**
|
||||
- 背景:`#ffffff`
|
||||
- テキスト:`#777777`
|
||||
- ボーダー:2px solid `#e5e5e5`
|
||||
- ボーダーボトム:4px solid `#e5e5e5`
|
||||
- 角丸:16px
|
||||
- パディング:14px 24px
|
||||
- ホバー:テキスト `#3c3c3c`、ボーダー `#afafaf`
|
||||
|
||||
**ストリークオレンジ**
|
||||
- 背景:`#ff9600`
|
||||
- テキスト:`#ffffff`
|
||||
- ボーダーボトム:4px solid `#cc7a00`
|
||||
- 使用:ストリークゴール、「ストリーク開始」
|
||||
|
||||
**エラー(カーディナルレッド)**
|
||||
- 背景:`#ff4b4b`
|
||||
- テキスト:`#ffffff`
|
||||
- ボーダーボトム:4px solid `#cc3b3b`
|
||||
- 使用:不正解フィードバック。
|
||||
|
||||
### カード / レッスンタイル
|
||||
- 背景:`#ffffff`
|
||||
- ボーダー:2px solid `#e5e5e5`
|
||||
- ボーダーボトム:4px solid `#e5e5e5`
|
||||
- 角丸:16px
|
||||
- パディング:16px
|
||||
- ホバー:2px 浮上、シャドウ `0 4px 0 #d7d7d7`
|
||||
|
||||
### スキルツリーノード(レッスンバブル)
|
||||
- サイズ:80×72px
|
||||
- 背景:スキルカラー色調(アクティブは緑、ロック済みはグレー)
|
||||
- ボーダーボトム:6px solid 暗いバリアント
|
||||
- 角丸:50%(円形)
|
||||
- アクティブ:1.6s ごとに 1.0 → 1.05 でパルス
|
||||
|
||||
### 入力
|
||||
- 背景:`#ffffff`
|
||||
- ボーダー:2px solid `#e5e5e5`
|
||||
- 角丸:12px
|
||||
- パディング:12px 16px
|
||||
- フォーカス:ボーダー `#1cb0f6`(ウナギブルー)、リング `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### プログレスバー
|
||||
- トラック:`#e5e5e5`
|
||||
- フィル:`#58cc02`(またはストリーク時 `#ff9600`)
|
||||
- 角丸:9999px
|
||||
- 高さ:16px
|
||||
- アニメーションフィル:増分時 320ms ease-out。
|
||||
|
||||
## 5. スペーシングとレイアウト
|
||||
|
||||
- **ベースユニット**:4px。スケール:4、8、12、16、24、32、48、64。
|
||||
- **コンテナ**:最大 1080px、24px ガター。
|
||||
- **レッスンツリー列**:幅 320px;デスクトップで中央配置。
|
||||
|
||||
## 6. モーション
|
||||
|
||||
- **デュレーション**:ボタンプレス 180ms;スキルノードアンロック 320ms;アクティブノードパルス 1.6s。
|
||||
- **イージング**:`cubic-bezier(0.34, 1.56, 0.64, 1)`(バックアウト、わずかなオーバーシュート)アンロック用。
|
||||
- **マスコット**:Duo は 4〜6s ごとにまばたきし、ストリークのマイルストーンでジャンプ(480ms ease-out スプリング)。
|
||||
|
||||
## 7. 使用ガイドライン
|
||||
|
||||
- 高彩度のフクロウグリーン、ぶ厚いボトムシャドウ、丸みのあるレッスンジオメトリは一緒に保ってください。フラットなグリーンボタン単体では Duolingo らしく読まれません。
|
||||
- 特大の太字テキストは、プロダクトが励ましやフィードバックを必要とするレッスン、ストリーク、進捗の瞬間のために取っておいてください。
|
||||
- プレイフルなモーションは進捗状態の変化の周りに控えめに使い、すべてのコントロールに汎用のバウンシーアニメーションを使うのは避けてください。
|
||||
@@ -0,0 +1,160 @@
|
||||
# Duolingo에서 영감을 받은 디자인 시스템
|
||||
|
||||
> Category: 생산성 & SaaS
|
||||
> 언어 학습 플랫폼. 밝은 올빼미 그린, 굵직한 그림자, 게임화된 즐거움.
|
||||
|
||||
## 1. 비주얼 테마와 분위기
|
||||
|
||||
Duolingo는 시각 언어로 표현된 게임화 디자인입니다. 인터페이스는 거리낌 없이 밝으며, **올빼미 그린**(`#58cc02`)을 브랜드 프라이머리로 사용하고 모든 인터랙티브 요소 하단에 4px의 굵직한 그림자를 두어 눌리기를 기다리는 3D 버튼처럼 보입니다. 페이지는 흰색(`#ffffff`)이며 2–3px의 굵은 테두리는 진한 회색(`#e5e5e5`)으로, 전체 시스템은 더 나은 계층 구조로 재탄생한 2015년 iOS 앱처럼 읽힙니다.
|
||||
|
||||
타이포그래피는 크롬에 **Feather Bold**(커스텀 둥근 산세리프), 본문에 **Mona Sans**(또는 Inter)를 사용합니다. 디스플레이 크기는 크고 자신감 넘치며——Duolingo는 절대 속삭이지 않습니다. 제목에는 종종 초록색 밑줄 획이 있거나 초록색 필 위에 올라가며, 마스코트 Duo(초록색 올빼미)는 정적인 로고가 아닌 활동적인 일러스트 캐릭터로 등장합니다.
|
||||
|
||||
형태 언어는 친근합니다: 카드에 16–20px 반지름, 버튼에 12px, 칩과 프로그레스 바에 9999px. 아이코노그래피는 채워진 형태의 둥근 스타일이며 스킬별로 색상이 코딩되어——모든 레슨 화면에는 즉시 식별 가능한 색상 쌍이 있습니다.
|
||||
|
||||
**주요 특징:**
|
||||
- 올빼미 그린(`#58cc02`)이 지배적인 브랜드 컬러로 서페이스의 30% 이상 사용
|
||||
- 모든 버튼에 4px 굵직한 바텀 그림자("촉각적 누름" 어포던스)
|
||||
- 2–3px 솔리드 테두리, 헤어라인은 절대 사용 안 함
|
||||
- Feather Bold(둥근 디스플레이) + Mona Sans(본문)
|
||||
- 크고 자신감 넘치는 텍스트——디스플레이 크기는 48px에서 시작해 올라감
|
||||
- 마스코트=캐릭터: Duo 올빼미가 온보딩, 오류, 스트릭에 등장
|
||||
- 스트릭 오렌지(`#ff9600`)와 젬 핑크(`#ce82ff`)가 세컨더리 브랜드 컬러
|
||||
|
||||
## 2. 컬러 팔레트와 역할
|
||||
|
||||
### 프라이머리
|
||||
- **올빼미 그린**(`#58cc02`): 브랜드 프라이머리, 주요 CTA, 정답.
|
||||
- **올빼미 그린 딥**(`#58a700`): 초록 버튼의 누름/그림자 색상.
|
||||
- **올빼미 그린 라이트**(`#89e219`): 호버, 소프트 필.
|
||||
- **올빼미 그린 페일**(`#dbf8c5`): 소프트 서페이스, 성공 배너.
|
||||
|
||||
### 세컨더리 악센트
|
||||
- **스트릭 오렌지**(`#ff9600`): 스트릭 카운터, 불꽃 아이콘, 프리미엄 에너지.
|
||||
- **스트릭 오렌지 딥**(`#cc7a00`): 오렌지 눌림 상태.
|
||||
- **젬 핑크**(`#ce82ff`): 젬 화폐, Super Duolingo.
|
||||
- **장어 블루**(`#1cb0f6`): 힌트 버튼, 정보 링크.
|
||||
- **카디널 레드**(`#ff4b4b`): 오답, 목숨 소실.
|
||||
- **비 옐로우**(`#ffc800`): 프로 배지, 업적.
|
||||
|
||||
### 서페이스
|
||||
- **스노우**(`#ffffff`): 프라이머리 배경.
|
||||
- **장어**(`#f7f7f7`): 섹션 구분, 세컨더리 서페이스.
|
||||
- **스완**(`#e5e5e5`): 비활성화 배경, 인셋 블록.
|
||||
- **울프**(`#777777`): 다크 구분선, 세컨더리 텍스트.
|
||||
|
||||
### 잉크 & 텍스트
|
||||
- **장어 블랙**(`#3c3c3c`): 프라이머리 텍스트.
|
||||
- **울프**(`#777777`): 세컨더리 텍스트, 캡션.
|
||||
- **헤어**(`#afafaf`): 비활성화, 플레이스홀더.
|
||||
|
||||
### 테두리
|
||||
- **스완**(`#e5e5e5`): 표준 2px 테두리.
|
||||
- **헤어**(`#afafaf`): 호버 시 강조 테두리.
|
||||
|
||||
## 3. 타이포그래피 규칙
|
||||
|
||||
### 폰트 패밀리
|
||||
- **디스플레이 / UI / 제목**: `Feather Bold`, 폴백: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **본문 / 장문**: `Mona Sans`, 폴백: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **코드 (드물게, 학교/관리)**: `JetBrains Mono`, 폴백: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### 계층 구조
|
||||
|
||||
| 역할 | 폰트 | 크기 | 굵기 | 줄간격 | 자간 | 비고 |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| 디스플레이 | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | 온보딩 히어로 |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | 페이지 제목 |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | 섹션 제목 |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | 카드 제목, 레슨 행 |
|
||||
| 본문 라지 | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | 레슨 프롬프트, 안내 |
|
||||
| 본문 | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | 표준 산문 |
|
||||
| 캡션 | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | XP 카운터, 메타데이터 |
|
||||
| 버튼 | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | 표준 버튼 레이블 |
|
||||
| 스트릭 | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | 스트릭 숫자, 불꽃 위 |
|
||||
|
||||
### 원칙
|
||||
- **800이 기본값**: Feather Bold는 제목과 버튼에서 800으로 실행됩니다. 이 시스템에서 700은 약하게 보입니다.
|
||||
- **큰 타입**: 제목 크기가 일반적인 제품 브랜드보다 25–40% 더 크며——자신감이 곧 정체성입니다.
|
||||
- **둥근 글자꼴**: 모든 글리프에 부드러운 끝부분이 있습니다. 날카로운 세리프는 친근함의 계약을 깨뜨립니다.
|
||||
|
||||
## 4. 컴포넌트 스타일링
|
||||
|
||||
### 버튼
|
||||
|
||||
**프라이머리 (올빼미 그린)**
|
||||
- 배경: `#58cc02`
|
||||
- 텍스트: `#ffffff`
|
||||
- 패딩: 14px 24px
|
||||
- 반지름: 16px
|
||||
- 바텀 테두리: 4px solid `#58a700` (굵직한 그림자)
|
||||
- 호버: 배경 `#89e219`
|
||||
- 액티브: translate-y 4px, 바텀 테두리 0 (버튼 "눌림")
|
||||
- 사용: "계속", "확인", 메인 CTA.
|
||||
|
||||
**세컨더리 (바텀 그림자가 있는 흰색)**
|
||||
- 배경: `#ffffff`
|
||||
- 텍스트: `#777777`
|
||||
- 테두리: 2px solid `#e5e5e5`
|
||||
- 바텀 테두리: 4px solid `#e5e5e5`
|
||||
- 반지름: 16px
|
||||
- 패딩: 14px 24px
|
||||
- 호버: 텍스트 `#3c3c3c`, 테두리 `#afafaf`
|
||||
|
||||
**스트릭 오렌지**
|
||||
- 배경: `#ff9600`
|
||||
- 텍스트: `#ffffff`
|
||||
- 바텀 테두리: 4px solid `#cc7a00`
|
||||
- 사용: 스트릭 목표, "스트릭 시작"
|
||||
|
||||
**에러 (카디널 레드)**
|
||||
- 배경: `#ff4b4b`
|
||||
- 텍스트: `#ffffff`
|
||||
- 바텀 테두리: 4px solid `#cc3b3b`
|
||||
- 사용: 오답 피드백.
|
||||
|
||||
### 카드 / 레슨 타일
|
||||
- 배경: `#ffffff`
|
||||
- 테두리: 2px solid `#e5e5e5`
|
||||
- 바텀 테두리: 4px solid `#e5e5e5`
|
||||
- 반지름: 16px
|
||||
- 패딩: 16px
|
||||
- 호버: 2px 상승, 그림자 `0 4px 0 #d7d7d7`
|
||||
|
||||
### 스킬 트리 노드 (레슨 버블)
|
||||
- 크기: 80×72px
|
||||
- 배경: 스킬 색상 tint (활성화는 초록, 잠김은 회색)
|
||||
- 바텀 테두리: 6px solid 더 어두운 변형
|
||||
- 반지름: 50% (원형)
|
||||
- 활성화: 1.6s마다 1.0 → 1.05 펄스
|
||||
|
||||
### 입력
|
||||
- 배경: `#ffffff`
|
||||
- 테두리: 2px solid `#e5e5e5`
|
||||
- 반지름: 12px
|
||||
- 패딩: 12px 16px
|
||||
- 포커스: 테두리 `#1cb0f6` (장어 블루), 링 `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### 프로그레스 바
|
||||
- 트랙: `#e5e5e5`
|
||||
- 필: `#58cc02` (또는 스트릭 시 `#ff9600`)
|
||||
- 반지름: 9999px
|
||||
- 높이: 16px
|
||||
- 애니메이션 필: 증가 시 320ms ease-out.
|
||||
|
||||
## 5. 간격 & 레이아웃
|
||||
|
||||
- **기본 단위**: 4px. 스케일: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **컨테이너**: 최대 1080px, 24px 거터.
|
||||
- **레슨 트리 열**: 너비 320px; 데스크톱에서 중앙 정렬.
|
||||
|
||||
## 6. 모션
|
||||
|
||||
- **지속시간**: 버튼 누름 180ms; 스킬 노드 잠금 해제 320ms; 활성 노드 펄스 1.6s.
|
||||
- **이징**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (백아웃, 약간의 오버슈트) 잠금 해제용.
|
||||
- **마스코트**: Duo는 4–6s마다 눈을 깜빡이고, 스트릭 마일스톤에서 점프 (480ms ease-out 스프링).
|
||||
|
||||
## 7. 사용 가이드라인
|
||||
|
||||
- 고채도 올빼미 그린, 굵직한 바텀 그림자, 둥근 레슨 기하학적 요소를 함께 유지하세요. 평평한 초록 버튼 단독으로는 Duolingo처럼 읽히지 않습니다.
|
||||
- 특대형 볼드 타입은 제품이 격려나 피드백이 필요한 레슨, 스트릭, 진행 상황 순간을 위해 아껴두세요.
|
||||
- 플레이풀한 모션은 진행 상태 변화 주변에 절제하여 사용하고, 모든 컨트롤에 일반적인 바운시 애니메이션을 사용하는 것은 피하세요.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Ontwerpsysteem geïnspireerd op Duolingo
|
||||
|
||||
> Category: Productiviteit & SaaS
|
||||
> Taallerenplatform. Helder uilengroen, dikke schaduwen, geGamificeerde vreugde.
|
||||
|
||||
## 1. Visueel thema en sfeer
|
||||
|
||||
Duolingo is gamificatie als visuele taal. De interface is zonder omwegen helder, met **uilengroen** (`#58cc02`) als primaire merkkleur en een dikke onderschaduw van 4px op elk interactief element dat eruitziet als een 3D-knop die wacht om ingedrukt te worden. De pagina is wit (`#ffffff`) met dikke randen van 2–3px in donkergrijs (`#e5e5e5`), en het hele systeem leest als een iOS-app uit 2015 die herboren is met een betere hiërarchie.
|
||||
|
||||
De typografie gebruikt **Feather Bold** (een aangepast afgerond schreefloos lettertype) voor de chrome en **Mona Sans** (of Inter) voor de hoofdtekst. Weergaveformaten zijn groot en zelfverzekerd — Duolingo fluistert nooit. Koppen dragen vaak een groene onderstrepingsstreek of zitten op een groene pil, en het mascotte Duo (een groene uil) verschijnt als een actief illustratiepersonage, niet als een statisch logo.
|
||||
|
||||
De vormentaal is vriendelijk: 16–20px stralen op kaarten, 12px op knoppen, 9999px op chips en voortgangsbalken. Iconografie is gevuld, afgerond en kleurgecodeerd per vaardigheid — elk lesoppervlak heeft een direct herkenbaar kleurenpaar.
|
||||
|
||||
**Kenmerken:**
|
||||
- Uilengroen (`#58cc02`) als dominante merkkleur, gebruikt op meer dan 30% van het oppervlak
|
||||
- Dikke onderschaduw van 4px op elke knop (de "tactiele druk"-affordantie)
|
||||
- Solide randen van 2–3px, nooit haarlijnen
|
||||
- Feather Bold (afgerond display) + Mona Sans (hoofdtekst)
|
||||
- Grote, zelfverzekerde tekst — weergaveformaten beginnen bij 48px en klimmen
|
||||
- Mascotte als personage: Duo de uil verschijnt bij onboarding, fouten, streken
|
||||
- Streeksoranje (`#ff9600`) en gemroze (`#ce82ff`) als secundaire merkkleuren
|
||||
|
||||
## 2. Kleurpalet & rollen
|
||||
|
||||
### Primair
|
||||
- **Uilengroen** (`#58cc02`): Merkprimair, primaire CTA, juist antwoord.
|
||||
- **Uilengroen diep** (`#58a700`): Druk-/schaduwkleur voor groene knoppen.
|
||||
- **Uilengroen licht** (`#89e219`): Hover, zachte vullingen.
|
||||
- **Uilengroen bleek** (`#dbf8c5`): Zacht oppervlak, succesbanner.
|
||||
|
||||
### Secundaire accenten
|
||||
- **Streeksoranje** (`#ff9600`): Streeksteller, vlampictogram, premium energie.
|
||||
- **Streeksoranje diep** (`#cc7a00`): Ingedrukt oranje.
|
||||
- **Gemroze** (`#ce82ff`): Gemvaluta, Super Duolingo.
|
||||
- **Aalblauwe** (`#1cb0f6`): Hintknop, informatielink.
|
||||
- **Kardinaalsrood** (`#ff4b4b`): Fout antwoord, leven verloren.
|
||||
- **Bijengeel** (`#ffc800`): Pro-badge, prestatie.
|
||||
|
||||
### Oppervlak
|
||||
- **Sneeuw** (`#ffffff`): Primaire achtergrond.
|
||||
- **Aal** (`#f7f7f7`): Sectie-einde, secundair oppervlak.
|
||||
- **Zwaan** (`#e5e5e5`): Uitgeschakelde achtergrond, ingebed blok.
|
||||
- **Wolf** (`#777777`): Donkere scheider, secundaire tekst.
|
||||
|
||||
### Inkt & tekst
|
||||
- **Aalzwart** (`#3c3c3c`): Primaire tekst.
|
||||
- **Wolf** (`#777777`): Secundaire tekst, bijschriften.
|
||||
- **Haas** (`#afafaf`): Uitgeschakeld, tijdelijke aanduiding.
|
||||
|
||||
### Rand
|
||||
- **Zwaan** (`#e5e5e5`): Standaardrand 2px.
|
||||
- **Haas** (`#afafaf`): Benadrukte rand bij hover.
|
||||
|
||||
## 3. Typografieregels
|
||||
|
||||
### Lettertypenreeks
|
||||
- **Display / UI / Koppen**: `Feather Bold`, met terugval: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Hoofdtekst / Lange tekst**: `Mona Sans`, met terugval: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Code (zeldzaam, scholen/admin)**: `JetBrains Mono`, met terugval: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hiërarchie
|
||||
|
||||
| Rol | Lettertype | Grootte | Gewicht | Regelhoogte | Letterafstand | Notities |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Onboarding-hero |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Paginatitel |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Sectiekop |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Kaarttitel, lesrij |
|
||||
| Grote tekst | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Lesprompt, instructie |
|
||||
| Tekst | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Standaardtekst |
|
||||
| Bijschrift | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | XP-teller, metadata |
|
||||
| Knop | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Standaard knooplabel |
|
||||
| Streek | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Streeknummer, op vlam |
|
||||
|
||||
### Principes
|
||||
- **800 is de standaard**: Feather Bold loopt op 800 bij koppen en knoppen. 700 voelt zwak aan in dit systeem.
|
||||
- **Grote tekst**: kopformaten zijn 25–40% groter dan typische productmerken — zelfvertrouwen als identiteit.
|
||||
- **Afgeronde lettervormingen**: elke glyph heeft zachte uiteinden; scherpe schreven zouden het vriendelijkheidscontract breken.
|
||||
|
||||
## 4. Componentstijlen
|
||||
|
||||
### Knoppen
|
||||
|
||||
**Primair (Uilengroen)**
|
||||
- Achtergrond: `#58cc02`
|
||||
- Tekst: `#ffffff`
|
||||
- Opvulling: 14px 24px
|
||||
- Radius: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (de dikke schaduw)
|
||||
- Hover: achtergrond `#89e219`
|
||||
- Actief: translate-y 4px, border-bottom 0 (knop "drukt in")
|
||||
- Gebruik: "Doorgaan", "Controleren", hoofd-CTA.
|
||||
|
||||
**Secundair (Wit met onderschaduw)**
|
||||
- Achtergrond: `#ffffff`
|
||||
- Tekst: `#777777`
|
||||
- Rand: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Opvulling: 14px 24px
|
||||
- Hover: tekst `#3c3c3c`, rand `#afafaf`
|
||||
|
||||
**Streeksoranje**
|
||||
- Achtergrond: `#ff9600`
|
||||
- Tekst: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Gebruik: streekdoel, "Streek starten"
|
||||
|
||||
**Fout (Kardinaalsrood)**
|
||||
- Achtergrond: `#ff4b4b`
|
||||
- Tekst: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Gebruik: feedback bij fout antwoord.
|
||||
|
||||
### Kaarten / Lestegels
|
||||
- Achtergrond: `#ffffff`
|
||||
- Rand: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Opvulling: 16px
|
||||
- Hover: 2px optillen, schaduw `0 4px 0 #d7d7d7`
|
||||
|
||||
### Vaardigheidsboomknoop (Lesbelletje)
|
||||
- Grootte: 80×72px
|
||||
- Achtergrond: vaardigheidskleur getint (groen voor actief, grijs voor vergrendeld)
|
||||
- Border-bottom: 6px solid donkerder variant
|
||||
- Radius: 50% (cirkelvormig)
|
||||
- Actief: pulseert 1.0 → 1.05 elke 1.6s
|
||||
|
||||
### Invoervelden
|
||||
- Achtergrond: `#ffffff`
|
||||
- Rand: 2px solid `#e5e5e5`
|
||||
- Radius: 12px
|
||||
- Opvulling: 12px 16px
|
||||
- Focus: rand `#1cb0f6` (aalblauw), ring `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Voortgangsbalk
|
||||
- Spoor: `#e5e5e5`
|
||||
- Vulling: `#58cc02` (of `#ff9600` voor streek)
|
||||
- Radius: 9999px
|
||||
- Hoogte: 16px
|
||||
- Geanimeerde vulling: 320ms ease-out bij toename.
|
||||
|
||||
## 5. Afstanden & Lay-out
|
||||
|
||||
- **Basiseenheid**: 4px. Schaal: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Container**: max. 1080px, 24px goot.
|
||||
- **Lesboomkolom**: 320px breed; gecentreerd op desktop.
|
||||
|
||||
## 6. Beweging
|
||||
|
||||
- **Duur**: 180ms voor knopdruk; 320ms voor vaardigheidsknoop-ontgrendeling; 1.6s voor actieve knooppuls.
|
||||
- **Versnelling**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, lichte overschrijding) voor ontgrendelingen.
|
||||
- **Mascotte**: Duo knippert elke 4–6s, springt bij streekmijlpalen (480ms ease-out veer).
|
||||
|
||||
## 7. Gebruiksrichtlijnen
|
||||
|
||||
- Houd het hoogverzadigde uilengroen, dikke onderschaduwen en afgeronde lesgeometrie samen; vlakke groene knoppen alleen lezen niet als Duolingo.
|
||||
- Reserveer oversized vetgedrukte tekst voor les-, streek- en voortgangsmomenten waar het product aanmoediging of feedback nodig heeft.
|
||||
- Gebruik speelse beweging spaarzaam rond voortgangsstatuswijzigingen, vermijd generieke stuiteranimaties op elk besturingselement.
|
||||
@@ -0,0 +1,160 @@
|
||||
# System projektowania inspirowany Duolingo
|
||||
|
||||
> Category: Produktywność i SaaS
|
||||
> Platforma do nauki języków. Jaskrawa zieleń sowy, grubaśne cienie, grywalizowana radość.
|
||||
|
||||
## 1. Motyw wizualny i atmosfera
|
||||
|
||||
Duolingo to grywalizacja jako język wizualny. Interfejs jest bezwstydnie jaskrawy, z **zielenią sowy** (`#58cc02`) jako głównym kolorem marki i grubym cieniem 4px u dołu każdego elementu interaktywnego, który wygląda jak przycisk 3D czekający na naciśnięcie. Strona jest biała (`#ffffff`) z grubymi obramowaniami 2–3px w ciemnej szarości (`#e5e5e5`), a cały system przypomina aplikację iOS z 2015 roku odrodzoną z lepszą hierarchią.
|
||||
|
||||
Typografia używa **Feather Bold** (niestandardowy zaokrąglony bezszeryfowy) dla chrome i **Mona Sans** (lub Inter) dla treści. Rozmiary wyświetlania są duże i pewne siebie — Duolingo nigdy nie szepcze. Nagłówki często noszą zielony podkreślony pociągnięcie lub siedzą na zielonej pigułce, a maskotka Duo (zielona sowa) pojawia się jako aktywna postać ilustracyjna, a nie statyczne logo.
|
||||
|
||||
Język kształtów jest przyjazny: promienie 16–20px na kartach, 12px na przyciskach, 9999px na chipach i paskach postępu. Ikonografia jest wypełniona, zaokrąglona i kodowana kolorami według umiejętności — każda powierzchnia lekcji ma natychmiast rozpoznawalną parę kolorów.
|
||||
|
||||
**Kluczowe cechy:**
|
||||
- Zieleń sowy (`#58cc02`) jako dominujący kolor marki, używany na ponad 30% powierzchni
|
||||
- Gruby cień dolny 4px na każdym przycisku (afordancja „dotykowego naciśnięcia")
|
||||
- Solidne obramowania 2–3px, nigdy cienkie linie
|
||||
- Feather Bold (zaokrąglony wyświetlacz) + Mona Sans (treść)
|
||||
- Duży pewny tekst — rozmiary wyświetlania zaczynają się od 48px i rosną
|
||||
- Maskotka jako postać: sowa Duo pojawia się podczas onboardingu, błędów, serii
|
||||
- Pomarańcz serii (`#ff9600`) i różowy klejnot (`#ce82ff`) jako drugorzędne kolory marki
|
||||
|
||||
## 2. Paleta kolorów i role
|
||||
|
||||
### Podstawowe
|
||||
- **Zieleń sowy** (`#58cc02`): Główny kolor marki, podstawowe CTA, poprawna odpowiedź.
|
||||
- **Głęboka zieleń sowy** (`#58a700`): Kolor naciśnięcia/cienia dla zielonych przycisków.
|
||||
- **Jasna zieleń sowy** (`#89e219`): Najechanie, delikatne wypełnienia.
|
||||
- **Blada zieleń sowy** (`#dbf8c5`): Delikatna powierzchnia, baner sukcesu.
|
||||
|
||||
### Drugorzędne akcenty
|
||||
- **Pomarańcz serii** (`#ff9600`): Licznik serii, ikona ognia, energia premium.
|
||||
- **Głęboka pomarańcz serii** (`#cc7a00`): Naciśnięta pomarańcz.
|
||||
- **Różowy klejnot** (`#ce82ff`): Waluta klejnotów, Super Duolingo.
|
||||
- **Niebieski węgorz** (`#1cb0f6`): Przycisk podpowiedzi, link informacyjny.
|
||||
- **Czerwień kardynała** (`#ff4b4b`): Błędna odpowiedź, utrata życia.
|
||||
- **Żółty pszczoły** (`#ffc800`): Odznaka pro, osiągnięcie.
|
||||
|
||||
### Powierzchnia
|
||||
- **Śnieg** (`#ffffff`): Główne tło.
|
||||
- **Węgorz** (`#f7f7f7`): Przerwa sekcji, drugorzędna powierzchnia.
|
||||
- **Łabędź** (`#e5e5e5`): Wyłączone tło, blok wbudowany.
|
||||
- **Wilk** (`#777777`): Ciemny separator, drugorzędny tekst.
|
||||
|
||||
### Tusz i tekst
|
||||
- **Czarny węgorz** (`#3c3c3c`): Główny tekst.
|
||||
- **Wilk** (`#777777`): Drugorzędny tekst, podpisy.
|
||||
- **Zając** (`#afafaf`): Wyłączony, symbol zastępczy.
|
||||
|
||||
### Obramowanie
|
||||
- **Łabędź** (`#e5e5e5`): Standardowe obramowanie 2px.
|
||||
- **Zając** (`#afafaf`): Podkreślone obramowanie po najechaniu.
|
||||
|
||||
## 3. Zasady typografii
|
||||
|
||||
### Rodzina czcionek
|
||||
- **Wyświetlacz / UI / Nagłówki**: `Feather Bold`, z rezerwą: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Treść / Długi tekst**: `Mona Sans`, z rezerwą: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Kod (rzadko, szkoły/admin)**: `JetBrains Mono`, z rezerwą: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hierarchia
|
||||
|
||||
| Rola | Czcionka | Rozmiar | Grubość | Wysokość wiersza | Odstęp | Uwagi |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Wyświetlacz | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Bohater onboardingu |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Tytuł strony |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Nagłówek sekcji |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Tytuł karty, wiersz lekcji |
|
||||
| Duża treść | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Podpowiedź lekcji, instrukcja |
|
||||
| Treść | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Standardowa proza |
|
||||
| Podpis | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Licznik XP, metadane |
|
||||
| Przycisk | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Standardowa etykieta przycisku |
|
||||
| Seria | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Numer serii, na płomieniu |
|
||||
|
||||
### Zasady
|
||||
- **800 to wartość domyślna**: Feather Bold działa na 800 na nagłówkach i przyciskach. 700 wygląda słabo w tym systemie.
|
||||
- **Duży tekst**: rozmiary nagłówków są 25–40% większe niż typowe marki produktów — pewność siebie jako tożsamość.
|
||||
- **Zaokrąglone kształty liter**: każdy glif ma miękkie zakończenia; ostre szeryfowe złamałyby kontrakt przyjazności.
|
||||
|
||||
## 4. Stylizacja komponentów
|
||||
|
||||
### Przyciski
|
||||
|
||||
**Podstawowy (Zieleń sowy)**
|
||||
- Tło: `#58cc02`
|
||||
- Tekst: `#ffffff`
|
||||
- Wypełnienie: 14px 24px
|
||||
- Promień: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (gruby cień)
|
||||
- Najechanie: tło `#89e219`
|
||||
- Aktywny: translate-y 4px, border-bottom 0 (przycisk „wciska się")
|
||||
- Użycie: „Kontynuuj", „Sprawdź", główne CTA.
|
||||
|
||||
**Drugorzędny (Biały z dolnym cieniem)**
|
||||
- Tło: `#ffffff`
|
||||
- Tekst: `#777777`
|
||||
- Obramowanie: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Promień: 16px
|
||||
- Wypełnienie: 14px 24px
|
||||
- Najechanie: tekst `#3c3c3c`, obramowanie `#afafaf`
|
||||
|
||||
**Pomarańcz serii**
|
||||
- Tło: `#ff9600`
|
||||
- Tekst: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Użycie: cel serii, „Rozpocznij serię"
|
||||
|
||||
**Błąd (Czerwień kardynała)**
|
||||
- Tło: `#ff4b4b`
|
||||
- Tekst: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Użycie: informacja zwrotna o błędnej odpowiedzi.
|
||||
|
||||
### Karty / Kafelki lekcji
|
||||
- Tło: `#ffffff`
|
||||
- Obramowanie: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Promień: 16px
|
||||
- Wypełnienie: 16px
|
||||
- Najechanie: unieść o 2px, cień `0 4px 0 #d7d7d7`
|
||||
|
||||
### Węzeł drzewa umiejętności (Bąbel lekcji)
|
||||
- Rozmiar: 80×72px
|
||||
- Tło: odcień koloru umiejętności (zielony dla aktywnego, szary dla zablokowanego)
|
||||
- Border-bottom: 6px solid ciemniejszy wariant
|
||||
- Promień: 50% (okrągły)
|
||||
- Aktywny: pulsuje 1.0 → 1.05 co 1.6s
|
||||
|
||||
### Pola wejściowe
|
||||
- Tło: `#ffffff`
|
||||
- Obramowanie: 2px solid `#e5e5e5`
|
||||
- Promień: 12px
|
||||
- Wypełnienie: 12px 16px
|
||||
- Focus: obramowanie `#1cb0f6` (niebieski węgorz), pierścień `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Pasek postępu
|
||||
- Tor: `#e5e5e5`
|
||||
- Wypełnienie: `#58cc02` (lub `#ff9600` dla serii)
|
||||
- Promień: 9999px
|
||||
- Wysokość: 16px
|
||||
- Animowane wypełnienie: 320ms ease-out przy przyroście.
|
||||
|
||||
## 5. Odstępy i układ
|
||||
|
||||
- **Jednostka podstawowa**: 4px. Skala: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Kontener**: maks. 1080px, rynna 24px.
|
||||
- **Kolumna drzewa lekcji**: 320px szerokości; wyśrodkowana na pulpicie.
|
||||
|
||||
## 6. Ruch
|
||||
|
||||
- **Czas trwania**: 180ms dla naciśnięcia przycisku; 320ms dla odblokowania węzła umiejętności; 1.6s dla pulsu aktywnego węzła.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, lekkie przekroczenie) dla odblokowań.
|
||||
- **Maskotka**: Duo mruga co 4–6s, skacze przy kamieniach milowych serii (480ms ease-out sprężyna).
|
||||
|
||||
## 7. Wytyczne użytkowania
|
||||
|
||||
- Zachowaj razem mocno nasyconą zieleń sowy, grube dolne cienie i zaokrągloną geometrię lekcji; same płaskie zielone przyciski nie brzmią jak Duolingo.
|
||||
- Zarezerwuj duży pogrubiony tekst dla momentów lekcji, serii i postępu, w których produkt potrzebuje zachęty lub informacji zwrotnej.
|
||||
- Używaj żywiołowego ruchu oszczędnie przy zmianach stanu postępu, unikając generycznych odbijających się animacji na każdym kontrolce.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Sistema de design inspirado no Duolingo
|
||||
|
||||
> Category: Produtividade & SaaS
|
||||
> Plataforma de aprendizado de idiomas. Verde coruja brilhante, sombras grossas, alegria gamificada.
|
||||
|
||||
## 1. Tema visual e atmosfera
|
||||
|
||||
O Duolingo é a gamificação expressa como linguagem visual. A interface é descaradamente brilhante, com o **verde coruja** (`#58cc02`) como cor primária da marca e uma sombra grossa de 4px na parte inferior de cada elemento interativo, que parece um botão 3D esperando para ser pressionado. A página é branca (`#ffffff`) com bordas grossas de 2–3px em cinza escuro (`#e5e5e5`), e o sistema inteiro lembra um aplicativo iOS de 2015 renascido com melhor hierarquia.
|
||||
|
||||
A tipografia usa **Feather Bold** (uma sans-serif arredondada personalizada) para o chrome e **Mona Sans** (ou Inter) para o corpo do texto. Os tamanhos de exibição são grandes e confiantes — o Duolingo nunca sussurra. Os títulos frequentemente têm o traço de sublinhado verde ou ficam sobre uma pílula verde, e o mascote Duo (uma coruja verde) aparece como um personagem de ilustração ativo, não como um logotipo estático.
|
||||
|
||||
A linguagem de formas é amigável: raios de 16–20px nos cartões, 12px nos botões, 9999px nos chips e barras de progresso. A iconografia é preenchida, arredondada e codificada por cor de acordo com a habilidade — cada superfície de lição tem um par de cores instantaneamente identificável.
|
||||
|
||||
**Características principais:**
|
||||
- Verde coruja (`#58cc02`) como cor de marca dominante, usada em mais de 30% da superfície
|
||||
- Sombra inferior grossa de 4px em cada botão (a affordance de "pressão tátil")
|
||||
- Bordas sólidas de 2–3px, nunca linhas finas
|
||||
- Feather Bold (display arredondado) + Mona Sans (corpo)
|
||||
- Texto grande e confiante — os tamanhos de exibição começam em 48px e crescem
|
||||
- Mascote como personagem: a coruja Duo aparece no onboarding, erros, sequências
|
||||
- Laranja de sequência (`#ff9600`) e rosa gema (`#ce82ff`) como cores de marca secundárias
|
||||
|
||||
## 2. Paleta de cores e papéis
|
||||
|
||||
### Primário
|
||||
- **Verde coruja** (`#58cc02`): Primário da marca, CTA principal, resposta correta.
|
||||
- **Verde coruja escuro** (`#58a700`): Cor de pressionamento/sombra para botões verdes.
|
||||
- **Verde coruja claro** (`#89e219`): Hover, preenchimentos suaves.
|
||||
- **Verde coruja pálido** (`#dbf8c5`): Superfície suave, banner de sucesso.
|
||||
|
||||
### Acentos secundários
|
||||
- **Laranja de sequência** (`#ff9600`): Contador de sequência, ícone de chama, energia premium.
|
||||
- **Laranja de sequência escuro** (`#cc7a00`): Laranja pressionado.
|
||||
- **Rosa gema** (`#ce82ff`): Moeda gema, Super Duolingo.
|
||||
- **Azul enguia** (`#1cb0f6`): Botão de dica, link de informação.
|
||||
- **Vermelho cardeal** (`#ff4b4b`): Resposta errada, vida perdida.
|
||||
- **Amarelo abelha** (`#ffc800`): Distintivo pro, conquista.
|
||||
|
||||
### Superfície
|
||||
- **Neve** (`#ffffff`): Fundo principal.
|
||||
- **Enguia** (`#f7f7f7`): Separação de seção, superfície secundária.
|
||||
- **Cisne** (`#e5e5e5`): Fundo desativado, bloco embutido.
|
||||
- **Lobo** (`#777777`): Divisor escuro, texto secundário.
|
||||
|
||||
### Tinta e texto
|
||||
- **Preto enguia** (`#3c3c3c`): Texto principal.
|
||||
- **Lobo** (`#777777`): Texto secundário, legendas.
|
||||
- **Lebre** (`#afafaf`): Desativado, espaço reservado.
|
||||
|
||||
### Borda
|
||||
- **Cisne** (`#e5e5e5`): Borda padrão de 2px.
|
||||
- **Lebre** (`#afafaf`): Borda enfatizada ao passar o cursor.
|
||||
|
||||
## 3. Regras tipográficas
|
||||
|
||||
### Família de fontes
|
||||
- **Display / UI / Títulos**: `Feather Bold`, com fallback: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Corpo / Texto longo**: `Mona Sans`, com fallback: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Código (raro, escolas/admin)**: `JetBrains Mono`, com fallback: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hierarquia
|
||||
|
||||
| Papel | Fonte | Tamanho | Peso | Altura de linha | Espaçamento | Notas |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Herói de onboarding |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Título da página |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Cabeçalho de seção |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Título do cartão, linha de lição |
|
||||
| Corpo grande | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Prompt de lição, instrução |
|
||||
| Corpo | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Prosa padrão |
|
||||
| Legenda | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Contador de XP, metadados |
|
||||
| Botão | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Rótulo padrão de botão |
|
||||
| Sequência | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Número de sequência, na chama |
|
||||
|
||||
### Princípios
|
||||
- **800 é o padrão**: O Feather Bold usa peso 800 em títulos e botões. 700 parece fraco neste sistema.
|
||||
- **Texto grande**: os tamanhos de título são 25–40% maiores do que marcas de produtos típicas — confiança como identidade.
|
||||
- **Formas de letras arredondadas**: cada glifo tem terminações suaves; serifas afiadas quebrariam o contrato de amizade.
|
||||
|
||||
## 4. Estilização de componentes
|
||||
|
||||
### Botões
|
||||
|
||||
**Primário (Verde coruja)**
|
||||
- Fundo: `#58cc02`
|
||||
- Texto: `#ffffff`
|
||||
- Preenchimento: 14px 24px
|
||||
- Raio: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (a sombra grossa)
|
||||
- Hover: fundo `#89e219`
|
||||
- Ativo: translate-y 4px, border-bottom 0 (o botão "pressiona")
|
||||
- Uso: "Continuar", "Verificar", CTA principal.
|
||||
|
||||
**Secundário (Branco com sombra inferior)**
|
||||
- Fundo: `#ffffff`
|
||||
- Texto: `#777777`
|
||||
- Borda: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Raio: 16px
|
||||
- Preenchimento: 14px 24px
|
||||
- Hover: texto `#3c3c3c`, borda `#afafaf`
|
||||
|
||||
**Laranja de sequência**
|
||||
- Fundo: `#ff9600`
|
||||
- Texto: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Uso: meta de sequência, "Iniciar sequência"
|
||||
|
||||
**Erro (Vermelho cardeal)**
|
||||
- Fundo: `#ff4b4b`
|
||||
- Texto: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Uso: feedback de resposta errada.
|
||||
|
||||
### Cartões / Blocos de lição
|
||||
- Fundo: `#ffffff`
|
||||
- Borda: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Raio: 16px
|
||||
- Preenchimento: 16px
|
||||
- Hover: elevar 2px, sombra `0 4px 0 #d7d7d7`
|
||||
|
||||
### Nó da árvore de habilidades (Bolha de lição)
|
||||
- Tamanho: 80×72px
|
||||
- Fundo: tonalidade da cor da habilidade (verde para ativo, cinza para bloqueado)
|
||||
- Border-bottom: 6px solid variante mais escura
|
||||
- Raio: 50% (circular)
|
||||
- Ativo: pulsa 1.0 → 1.05 a cada 1.6s
|
||||
|
||||
### Entradas
|
||||
- Fundo: `#ffffff`
|
||||
- Borda: 2px solid `#e5e5e5`
|
||||
- Raio: 12px
|
||||
- Preenchimento: 12px 16px
|
||||
- Foco: borda `#1cb0f6` (azul enguia), anel `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Barra de progresso
|
||||
- Trilha: `#e5e5e5`
|
||||
- Preenchimento: `#58cc02` (ou `#ff9600` para sequência)
|
||||
- Raio: 9999px
|
||||
- Altura: 16px
|
||||
- Preenchimento animado: 320ms ease-out ao incrementar.
|
||||
|
||||
## 5. Espaçamento e layout
|
||||
|
||||
- **Unidade base**: 4px. Escala: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Contêiner**: máx. 1080px, calha de 24px.
|
||||
- **Coluna da árvore de lições**: 320px de largura; centralizada no desktop.
|
||||
|
||||
## 6. Movimento
|
||||
|
||||
- **Duração**: 180ms para pressionar botão; 320ms para desbloqueio de nó de habilidade; 1.6s para pulso do nó ativo.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, leve ultrapassagem) para desbloqueios.
|
||||
- **Mascote**: Duo pisca a cada 4–6s, pula em marcos de sequência (480ms ease-out mola).
|
||||
|
||||
## 7. Diretrizes de uso
|
||||
|
||||
- Mantenha juntos o verde coruja de alta saturação, as sombras inferiores grossas e a geometria arredondada das lições; botões verdes planos sozinhos não transmitem a identidade do Duolingo.
|
||||
- Reserve o texto em negrito de tamanho grande para momentos de lição, sequência e progresso onde o produto precisa de encorajamento ou feedback.
|
||||
- Use movimento lúdico com moderação em torno de mudanças de estado de progresso, evitando animações genéricas de quique em cada controle.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Дизайн-система, вдохновлённая Duolingo
|
||||
|
||||
> Category: Продуктивность и SaaS
|
||||
> Платформа для изучения языков. Яркий зелёный цвет совы, массивные тени, геймифицированная радость.
|
||||
|
||||
## 1. Визуальная тема и атмосфера
|
||||
|
||||
Duolingo — это геймификация, воплощённая в визуальном языке. Интерфейс намеренно яркий: **зелёный цвет совы** (`#58cc02`) — основной цвет бренда, а у каждого интерактивного элемента снизу есть массивная тень в 4px, которая выглядит как 3D-кнопка, ожидающая нажатия. Страница белая (`#ffffff`) с жирными границами 2–3px тёмно-серого цвета (`#e5e5e5`), и вся система читается как iOS-приложение 2015 года, переродившееся с лучшей иерархией.
|
||||
|
||||
Типографика использует **Feather Bold** (пользовательский скруглённый гротеск) для интерфейсных элементов и **Mona Sans** (или Inter) для основного текста. Размеры для отображения большие и уверенные — Duolingo никогда не шепчет. Заголовки часто несут зелёный подчёркивающий штрих или располагаются на зелёной таблетке, а талисман Duo (зелёная сова) появляется как активный персонаж-иллюстрация, а не статичный логотип.
|
||||
|
||||
Язык форм дружелюбный: радиусы 16–20px у карточек, 12px у кнопок, 9999px у чипов и прогресс-баров. Иконография заливная, скруглённая и цветово закодирована по навыку — у каждой поверхности урока есть мгновенно узнаваемое сочетание цветов.
|
||||
|
||||
**Ключевые характеристики:**
|
||||
- Зелёный цвет совы (`#58cc02`) как доминирующий цвет бренда, занимающий более 30% поверхности
|
||||
- Массивная тень 4px снизу каждой кнопки (аффорданс «тактильного нажатия»)
|
||||
- Сплошные границы 2–3px, никаких тонких линий
|
||||
- Feather Bold (скруглённый дисплей) + Mona Sans (текст)
|
||||
- Крупный уверенный текст — дисплейные размеры начинаются с 48px и растут
|
||||
- Талисман-персонаж: сова Duo появляется при онбординге, ошибках, сериях
|
||||
- Оранжевый серии (`#ff9600`) и розовый самоцвета (`#ce82ff`) как вторичные цвета бренда
|
||||
|
||||
## 2. Цветовая палитра и роли
|
||||
|
||||
### Основные
|
||||
- **Зелёный совы** (`#58cc02`): основной цвет бренда, основной CTA, правильный ответ.
|
||||
- **Тёмный зелёный совы** (`#58a700`): цвет нажатия/тени для зелёных кнопок.
|
||||
- **Светлый зелёный совы** (`#89e219`): наведение курсора, мягкие заливки.
|
||||
- **Бледный зелёный совы** (`#dbf8c5`): мягкая поверхность, баннер успеха.
|
||||
|
||||
### Вторичные акценты
|
||||
- **Оранжевый серии** (`#ff9600`): счётчик серий, иконка огня, премиальная энергия.
|
||||
- **Тёмный оранжевый серии** (`#cc7a00`): нажатый оранжевый.
|
||||
- **Розовый самоцвета** (`#ce82ff`): валюта самоцветов, Super Duolingo.
|
||||
- **Синий угря** (`#1cb0f6`): кнопка подсказки, информационная ссылка.
|
||||
- **Кардинальный красный** (`#ff4b4b`): неправильный ответ, потеря жизни.
|
||||
- **Пчелиный жёлтый** (`#ffc800`): профессиональный значок, достижение.
|
||||
|
||||
### Поверхность
|
||||
- **Снег** (`#ffffff`): основной фон.
|
||||
- **Угорь** (`#f7f7f7`): разделитель разделов, вторичная поверхность.
|
||||
- **Лебедь** (`#e5e5e5`): фон отключённых элементов, встроенный блок.
|
||||
- **Волк** (`#777777`): тёмный разделитель, вторичный текст.
|
||||
|
||||
### Чернила и текст
|
||||
- **Чёрный угорь** (`#3c3c3c`): основной текст.
|
||||
- **Волк** (`#777777`): вторичный текст, подписи.
|
||||
- **Заяц** (`#afafaf`): отключённый, заполнитель.
|
||||
|
||||
### Граница
|
||||
- **Лебедь** (`#e5e5e5`): стандартная граница 2px.
|
||||
- **Заяц** (`#afafaf`): акцентная граница при наведении.
|
||||
|
||||
## 3. Правила типографики
|
||||
|
||||
### Семейство шрифтов
|
||||
- **Дисплей / UI / Заголовки**: `Feather Bold`, запасной: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Основной текст / Длинные тексты**: `Mona Sans`, запасной: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Код (редко, для школ/администрирования)**: `JetBrains Mono`, запасной: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Иерархия
|
||||
|
||||
| Роль | Шрифт | Размер | Насыщенность | Высота строки | Трекинг | Примечания |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Дисплей | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Онбординг-герой |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Заголовок страницы |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Заголовок раздела |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Заголовок карточки, строка урока |
|
||||
| Крупный текст | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Задание урока, инструкция |
|
||||
| Текст | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Стандартный текст |
|
||||
| Подпись | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Счётчик XP, метаданные |
|
||||
| Кнопка | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Стандартный ярлык кнопки |
|
||||
| Серия | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Число серий, на пламени |
|
||||
|
||||
### Принципы
|
||||
- **800 — значение по умолчанию**: Feather Bold использует насыщенность 800 для заголовков и кнопок. 700 выглядит слабо в этой системе.
|
||||
- **Крупный текст**: размеры заголовков на 25–40% крупнее, чем у типичных продуктовых брендов — уверенность как идентичность.
|
||||
- **Скруглённые буквы**: каждый глиф имеет мягкие окончания; острые засечки нарушили бы договор дружелюбности.
|
||||
|
||||
## 4. Стилизация компонентов
|
||||
|
||||
### Кнопки
|
||||
|
||||
**Основная (зелёный совы)**
|
||||
- Фон: `#58cc02`
|
||||
- Текст: `#ffffff`
|
||||
- Отступ: 14px 24px
|
||||
- Радиус: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (массивная тень)
|
||||
- Наведение: фон `#89e219`
|
||||
- Активная: translate-y 4px, border-bottom 0 (кнопка «нажимается»)
|
||||
- Использование: «Продолжить», «Проверить», основной CTA.
|
||||
|
||||
**Вторичная (белая с нижней тенью)**
|
||||
- Фон: `#ffffff`
|
||||
- Текст: `#777777`
|
||||
- Граница: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Радиус: 16px
|
||||
- Отступ: 14px 24px
|
||||
- Наведение: текст `#3c3c3c`, граница `#afafaf`
|
||||
|
||||
**Оранжевая серии**
|
||||
- Фон: `#ff9600`
|
||||
- Текст: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Использование: цель серии, «Начать серию»
|
||||
|
||||
**Ошибка (кардинальный красный)**
|
||||
- Фон: `#ff4b4b`
|
||||
- Текст: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Использование: обратная связь при неправильном ответе.
|
||||
|
||||
### Карточки / Плитки уроков
|
||||
- Фон: `#ffffff`
|
||||
- Граница: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Радиус: 16px
|
||||
- Отступ: 16px
|
||||
- Наведение: подъём на 2px, тень `0 4px 0 #d7d7d7`
|
||||
|
||||
### Узел дерева навыков (Пузырь урока)
|
||||
- Размер: 80×72px
|
||||
- Фон: оттенок цвета навыка (зелёный для активного, серый для заблокированного)
|
||||
- Border-bottom: 6px solid более тёмный вариант
|
||||
- Радиус: 50% (круглый)
|
||||
- Активный: пульсирует 1.0 → 1.05 каждые 1.6s
|
||||
|
||||
### Поля ввода
|
||||
- Фон: `#ffffff`
|
||||
- Граница: 2px solid `#e5e5e5`
|
||||
- Радиус: 12px
|
||||
- Отступ: 12px 16px
|
||||
- Фокус: граница `#1cb0f6` (синий угря), кольцо `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Прогресс-бар
|
||||
- Дорожка: `#e5e5e5`
|
||||
- Заливка: `#58cc02` (или `#ff9600` для серии)
|
||||
- Радиус: 9999px
|
||||
- Высота: 16px
|
||||
- Анимированная заливка: 320ms ease-out при увеличении.
|
||||
|
||||
## 5. Отступы и компоновка
|
||||
|
||||
- **Базовая единица**: 4px. Шкала: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Контейнер**: максимум 1080px, отступ 24px.
|
||||
- **Колонка дерева уроков**: ширина 320px; по центру на рабочем столе.
|
||||
|
||||
## 6. Движение
|
||||
|
||||
- **Длительность**: 180ms для нажатия кнопки; 320ms для разблокировки узла навыка; 1.6s для пульсации активного узла.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, небольшой перелёт) для разблокировок.
|
||||
- **Талисман**: Duo моргает каждые 4–6s, прыгает при достижении вехи серии (480ms ease-out пружина).
|
||||
|
||||
## 7. Руководство по использованию
|
||||
|
||||
- Сохраняйте высокую насыщенность зелёного цвета совы, массивные нижние тени и скруглённую геометрию уроков вместе; плоские зелёные кнопки сами по себе не создают ощущения Duolingo.
|
||||
- Оставьте крупный жирный шрифт для уроков, серий и моментов прогресса, когда продукту нужна поддержка или обратная связь.
|
||||
- Используйте игривое движение умеренно при изменениях состояния прогресса, избегая типичных прыгающих анимаций на каждом элементе управления.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Duolingo'dan İlham Alan Tasarım Sistemi
|
||||
|
||||
> Category: Üretkenlik ve SaaS
|
||||
> Dil öğrenme platformu. Parlak baykuş yeşili, kalın gölgeler, oyunlaştırılmış neşe.
|
||||
|
||||
## 1. Görsel Tema ve Atmosfer
|
||||
|
||||
Duolingo, görsel dil olarak işlenmiş oyunlaştırmadır. Arayüz çekinmeden parlaktır; **baykuş yeşili** (`#58cc02`) marka birincil rengi olarak kullanılır ve her etkileşimli öğenin altında, basılmayı bekleyen bir 3D düğme gibi görünen kalın 4px alt gölgesi bulunur. Sayfa beyazdır (`#ffffff`) ve 2–3px kalın kenarlıklar koyu gri (`#e5e5e5`) renktedir; tüm sistem daha iyi hiyerarşiyle yeniden doğmuş 2015 iOS uygulaması gibi okunur.
|
||||
|
||||
Tipografi, krom için **Feather Bold** (özel yuvarlak köşeli sans-serif) ve gövde metni için **Mona Sans** (veya Inter) kullanır. Görüntüleme boyutları büyük ve kendinden emin — Duolingo asla fısıldamaz. Başlıklar genellikle yeşil alt çizgi darbesi taşır veya yeşil bir hap üzerinde oturur; maskot Duo (yeşil bir baykuş) statik bir logo olarak değil, aktif bir illüstrasyon karakteri olarak görünür.
|
||||
|
||||
Şekil dili dostanedir: kartlarda 16–20px yarıçap, düğmelerde 12px, çipler ve ilerleme çubuklarında 9999px. İkonografi dolu, yuvarlak ve beceriye göre renk kodludur — her ders yüzeyi anında tanımlanabilir bir renk çifti içerir.
|
||||
|
||||
**Temel Özellikler:**
|
||||
- Baykuş yeşili (`#58cc02`) yüzeyin %30'undan fazlasında kullanılan baskın marka rengi
|
||||
- Her düğmede 4px kalın alt gölge ("dokunsal basma" karşılığı)
|
||||
- 2–3px düz kenarlıklar, asla ince çizgiler
|
||||
- Feather Bold (yuvarlak görüntüleme) + Mona Sans (gövde)
|
||||
- Büyük, kendinden emin metin — görüntüleme boyutları 48px'den başlayıp yükselir
|
||||
- Karakter olarak maskot: Duo baykuşu katılım sürecinde, hatalarda, serilerde görünür
|
||||
- Seri turuncusu (`#ff9600`) ve mücevher pembesi (`#ce82ff`) ikincil marka renkleri olarak
|
||||
|
||||
## 2. Renk Paleti & Roller
|
||||
|
||||
### Birincil
|
||||
- **Baykuş Yeşili** (`#58cc02`): Marka birincili, birincil CTA, doğru cevap.
|
||||
- **Koyu Baykuş Yeşili** (`#58a700`): Yeşil düğmeler için basma/gölge rengi.
|
||||
- **Açık Baykuş Yeşili** (`#89e219`): Hover, yumuşak dolgular.
|
||||
- **Soluk Baykuş Yeşili** (`#dbf8c5`): Yumuşak yüzey, başarı afişi.
|
||||
|
||||
### İkincil Vurgular
|
||||
- **Seri Turuncusu** (`#ff9600`): Seri sayacı, alev ikonu, premium enerji.
|
||||
- **Koyu Seri Turuncusu** (`#cc7a00`): Basılmış turuncu.
|
||||
- **Mücevher Pembesi** (`#ce82ff`): Mücevher para birimi, Super Duolingo.
|
||||
- **Yılan Balığı Mavisi** (`#1cb0f6`): İpucu düğmesi, bilgi bağlantısı.
|
||||
- **Kardinal Kırmızı** (`#ff4b4b`): Yanlış cevap, can kaybı.
|
||||
- **Arı Sarısı** (`#ffc800`): Pro rozeti, başarı.
|
||||
|
||||
### Yüzey
|
||||
- **Kar** (`#ffffff`): Birincil arka plan.
|
||||
- **Yılan Balığı** (`#f7f7f7`): Bölüm ayırıcı, ikincil yüzey.
|
||||
- **Kuğu** (`#e5e5e5`): Devre dışı arka plan, gömülü blok.
|
||||
- **Kurt** (`#777777`): Koyu ayırıcı, ikincil metin.
|
||||
|
||||
### Mürekkep & Metin
|
||||
- **Yılan Balığı Siyahı** (`#3c3c3c`): Birincil metin.
|
||||
- **Kurt** (`#777777`): İkincil metin, alt yazılar.
|
||||
- **Tavşan** (`#afafaf`): Devre dışı, yer tutucu.
|
||||
|
||||
### Kenarlık
|
||||
- **Kuğu** (`#e5e5e5`): Standart 2px kenarlık.
|
||||
- **Tavşan** (`#afafaf`): Hover'da vurgulanan kenarlık.
|
||||
|
||||
## 3. Tipografi Kuralları
|
||||
|
||||
### Yazı Tipi Ailesi
|
||||
- **Görüntüleme / UI / Başlıklar**: `Feather Bold`, yedek: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Gövde / Uzun Metin**: `Mona Sans`, yedek: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Kod (nadir, okullar/yönetim)**: `JetBrains Mono`, yedek: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hiyerarşi
|
||||
|
||||
| Rol | Yazı Tipi | Boyut | Ağırlık | Satır Yüksekliği | Harf Aralığı | Notlar |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Görüntüleme | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Katılım kahramanı |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Sayfa başlığı |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Bölüm başlığı |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Kart başlığı, ders satırı |
|
||||
| Büyük Gövde | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Ders istemi, talimat |
|
||||
| Gövde | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Standart düzyazı |
|
||||
| Açıklama | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | XP sayacı, meta veri |
|
||||
| Düğme | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Standart düğme etiketi |
|
||||
| Seri | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Seri sayısı, alev üzerinde |
|
||||
|
||||
### İlkeler
|
||||
- **800 varsayılandır**: Feather Bold, başlıklarda ve düğmelerde 800 ağırlıkta çalışır. Bu sistemde 700 zayıf görünür.
|
||||
- **Büyük metin**: Başlık boyutları tipik ürün markalarından %25–40 daha büyüktür — güven kimlik olarak.
|
||||
- **Yuvarlak harf biçimleri**: Her glif yumuşak uçlara sahiptir; keskin serifler dostluk sözleşmesini bozar.
|
||||
|
||||
## 4. Bileşen Stilleri
|
||||
|
||||
### Düğmeler
|
||||
|
||||
**Birincil (Baykuş Yeşili)**
|
||||
- Arka plan: `#58cc02`
|
||||
- Metin: `#ffffff`
|
||||
- Dolgu: 14px 24px
|
||||
- Yarıçap: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (kalın gölge)
|
||||
- Hover: arka plan `#89e219`
|
||||
- Aktif: translate-y 4px, border-bottom 0 (düğme "basılır")
|
||||
- Kullanım: "Devam Et", "Kontrol Et", ana CTA.
|
||||
|
||||
**İkincil (Alt Gölgeli Beyaz)**
|
||||
- Arka plan: `#ffffff`
|
||||
- Metin: `#777777`
|
||||
- Kenarlık: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Yarıçap: 16px
|
||||
- Dolgu: 14px 24px
|
||||
- Hover: metin `#3c3c3c`, kenarlık `#afafaf`
|
||||
|
||||
**Seri Turuncusu**
|
||||
- Arka plan: `#ff9600`
|
||||
- Metin: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Kullanım: seri hedefi, "Seriyi Başlat"
|
||||
|
||||
**Hata (Kardinal Kırmızı)**
|
||||
- Arka plan: `#ff4b4b`
|
||||
- Metin: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Kullanım: yanlış cevap geri bildirimi.
|
||||
|
||||
### Kartlar / Ders Karoları
|
||||
- Arka plan: `#ffffff`
|
||||
- Kenarlık: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Yarıçap: 16px
|
||||
- Dolgu: 16px
|
||||
- Hover: 2px yükselt, gölge `0 4px 0 #d7d7d7`
|
||||
|
||||
### Beceri Ağacı Düğümü (Ders Balonu)
|
||||
- Boyut: 80×72px
|
||||
- Arka plan: beceri rengi tonlu (aktif için yeşil, kilitli için gri)
|
||||
- Border-bottom: 6px solid daha koyu varyant
|
||||
- Yarıçap: 50% (dairesel)
|
||||
- Aktif: 1.6s'de bir 1.0 → 1.05 nabız atar
|
||||
|
||||
### Giriş Alanları
|
||||
- Arka plan: `#ffffff`
|
||||
- Kenarlık: 2px solid `#e5e5e5`
|
||||
- Yarıçap: 12px
|
||||
- Dolgu: 12px 16px
|
||||
- Odak: kenarlık `#1cb0f6` (yılan balığı mavisi), halka `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### İlerleme Çubuğu
|
||||
- Yol: `#e5e5e5`
|
||||
- Dolgu: `#58cc02` (veya seri için `#ff9600`)
|
||||
- Yarıçap: 9999px
|
||||
- Yükseklik: 16px
|
||||
- Animasyonlu dolgu: artışta 320ms ease-out.
|
||||
|
||||
## 5. Boşluk & Düzen
|
||||
|
||||
- **Temel birim**: 4px. Ölçek: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Kapsayıcı**: maks. 1080px, 24px oluk.
|
||||
- **Ders ağacı sütunu**: 320px genişlik; masaüstünde ortalı.
|
||||
|
||||
## 6. Hareket
|
||||
|
||||
- **Süre**: Düğme basması için 180ms; beceri düğümü kilit açma için 320ms; aktif düğüm nabzı için 1.6s.
|
||||
- **Hızlanma**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, hafif aşma) kilit açma animasyonları için.
|
||||
- **Maskot**: Duo her 4–6s'de bir göz kırpar, seri dönüm noktalarında zıplar (480ms ease-out yay).
|
||||
|
||||
## 7. Kullanım Yönergeleri
|
||||
|
||||
- Yüksek doygunluktaki baykuş yeşilini, kalın alt gölgeleri ve yuvarlak ders geometrisini birlikte tutun; düz yeşil düğmeler tek başına Duolingo gibi okunmaz.
|
||||
- Aşırı büyük kalın metni, ürünün teşvik veya geri bildirime ihtiyaç duyduğu ders, seri ve ilerleme anları için ayırın.
|
||||
- Eğlenceli hareketi ilerleme durumu değişikliklerinde tutumlu kullanın; her denetimde genel zıpla animasyonlarından kaçının.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Дизайн-система, натхненна Duolingo
|
||||
|
||||
> Category: Продуктивність і SaaS
|
||||
> Платформа для вивчення мов. Яскравий совиний зелений, масивні тіні, гейміфікована радість.
|
||||
|
||||
## 1. Візуальна тема та атмосфера
|
||||
|
||||
Duolingo — це гейміфікація, виражена як візуальна мова. Інтерфейс безсоромно яскравий: **совиний зелений** (`#58cc02`) є основним брендовим кольором, а масивна тінь 4px знизу на кожному інтерактивному елементі нагадує тривимірну кнопку, яку хочеться натиснути. Сторінка біла (`#ffffff`) із товстими рамками 2–3px у темно-сірому (`#e5e5e5`), а вся система сприймається як iOS-застосунок 2015 року, відроджений із кращою ієрархією.
|
||||
|
||||
Типографіка використовує **Feather Bold** (кастомний закруглений гротеск) для інтерфейсу та **Mona Sans** (або Inter) для основного тексту. Розміри відображення великі й впевнені — Duolingo ніколи не шепоче. Заголовки часто мають зелений підкреслювальний штрих або розміщені на зеленій таблетці, а маскот Дуо (зелена сова) виступає активним персонажем-ілюстрацією, а не статичним логотипом.
|
||||
|
||||
Мова форм дружня: радіус 16–20px на картках, 12px на кнопках, 9999px на чіпах і смугах прогресу. Іконографія заповнена, закруглена й кольорово-кодована за навиком — кожна поверхня уроку має миттєво впізнаване кольорове поєднання.
|
||||
|
||||
**Ключові характеристики:**
|
||||
- Совиний зелений (`#58cc02`) як домінуючий брендовий колір, використовується на 30%+ поверхні
|
||||
- Масивна тінь 4px знизу на кожній кнопці (тактильна «можливість натиснути»)
|
||||
- Суцільні рамки 2–3px, ніколи не тонші за піксель
|
||||
- Feather Bold (закруглений відображальний) + Mona Sans (основний текст)
|
||||
- Великий впевнений шрифт — відображальні розміри починаються від 48px і більше
|
||||
- Маскот як персонаж: Дуо-сова з'являється в онбордингу, помилках, серіях
|
||||
- Помаранчевий серії (`#ff9600`) і рожевий самоцвітів (`#ce82ff`) як вторинні брендові кольори
|
||||
|
||||
## 2. Кольорова палітра та ролі
|
||||
|
||||
### Основні
|
||||
- **Совиний зелений** (`#58cc02`): Основний бренд, основний CTA, правильна відповідь.
|
||||
- **Совиний зелений темний** (`#58a700`): Колір натискання/тіні зелених кнопок.
|
||||
- **Совиний зелений світлий** (`#89e219`): Наведення курсора, м'які заливки.
|
||||
- **Совиний зелений блідий** (`#dbf8c5`): М'яка поверхня, банер успіху.
|
||||
|
||||
### Вторинні акценти
|
||||
- **Помаранчевий серії** (`#ff9600`): Лічильник серії, іконка вогню, преміум-енергія.
|
||||
- **Помаранчевий серії темний** (`#cc7a00`): Натиснутий помаранчевий.
|
||||
- **Рожевий самоцвітів** (`#ce82ff`): Валюта самоцвітів, Super Duolingo.
|
||||
- **Блакитний вугра** (`#1cb0f6`): Кнопка підказки, інформаційне посилання.
|
||||
- **Кардинальний червоний** (`#ff4b4b`): Неправильна відповідь, втрачене життя.
|
||||
- **Жовтий бджоли** (`#ffc800`): Значок Pro, досягнення.
|
||||
|
||||
### Поверхня
|
||||
- **Сніговий** (`#ffffff`): Основний фон.
|
||||
- **Вугор** (`#f7f7f7`): Розрив секцій, вторинна поверхня.
|
||||
- **Лебідь** (`#e5e5e5`): Вимкнений фон, вставний блок.
|
||||
- **Вовк** (`#777777`): Темний роздільник, вторинний текст.
|
||||
|
||||
### Чорнило та текст
|
||||
- **Чорний вугра** (`#3c3c3c`): Основний текст.
|
||||
- **Вовк** (`#777777`): Вторинний текст, підписи.
|
||||
- **Заєць** (`#afafaf`): Вимкнений, плейсхолдер.
|
||||
|
||||
### Рамка
|
||||
- **Лебідь** (`#e5e5e5`): Стандартна рамка 2px.
|
||||
- **Заєць** (`#afafaf`): Підсилена рамка при наведенні.
|
||||
|
||||
## 3. Правила типографіки
|
||||
|
||||
### Шрифтова сім'я
|
||||
- **Відображення / UI / Заголовки**: `Feather Bold`, з резервними варіантами: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Основний текст / Довгий формат**: `Mona Sans`, з резервними варіантами: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Код (рідко, школи/адмін)**: `JetBrains Mono`, з резервними варіантами: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Ієрархія
|
||||
|
||||
| Роль | Шрифт | Розмір | Насиченість | Висота рядка | Міжлітерний інтервал | Примітки |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Відображення | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Герой онбордингу |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Заголовок сторінки |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Заголовок секції |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Заголовок картки, рядок уроку |
|
||||
| Великий основний | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Підказка уроку, інструкція |
|
||||
| Основний | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Стандартна проза |
|
||||
| Підпис | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Лічильник XP, метадані |
|
||||
| Кнопка | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Стандартний підпис кнопки |
|
||||
| Серія | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Число серії, на полум'ї |
|
||||
|
||||
### Принципи
|
||||
- **800 — за замовчуванням**: Feather Bold використовує 800 у заголовках і кнопках. 700 виглядає слабко в цій системі.
|
||||
- **Великий шрифт**: розміри заголовків на 25–40% більші, ніж у типових продуктових брендах — впевненість як ідентичність.
|
||||
- **Закруглені літери**: кожен гліф має м'які закінчення; гострі засічки порушили б договір дружелюбності.
|
||||
|
||||
## 4. Стилі компонентів
|
||||
|
||||
### Кнопки
|
||||
|
||||
**Основна (совиний зелений)**
|
||||
- Фон: `#58cc02`
|
||||
- Текст: `#ffffff`
|
||||
- Відступ: 14px 24px
|
||||
- Радіус: 16px
|
||||
- Рамка знизу: 4px solid `#58a700` (масивна тінь)
|
||||
- Наведення: фон `#89e219`
|
||||
- Активна: translate-y 4px, border-bottom 0 (кнопка «натискається»)
|
||||
- Використання: «Продовжити», «Перевірити», основний CTA.
|
||||
|
||||
**Вторинна (біла з тінню знизу)**
|
||||
- Фон: `#ffffff`
|
||||
- Текст: `#777777`
|
||||
- Рамка: 2px solid `#e5e5e5`
|
||||
- Рамка знизу: 4px solid `#e5e5e5`
|
||||
- Радіус: 16px
|
||||
- Відступ: 14px 24px
|
||||
- Наведення: текст `#3c3c3c`, рамка `#afafaf`
|
||||
|
||||
**Помаранчева серії**
|
||||
- Фон: `#ff9600`
|
||||
- Текст: `#ffffff`
|
||||
- Рамка знизу: 4px solid `#cc7a00`
|
||||
- Використання: ціль серії, «Почати серію»
|
||||
|
||||
**Помилка (кардинальний червоний)**
|
||||
- Фон: `#ff4b4b`
|
||||
- Текст: `#ffffff`
|
||||
- Рамка знизу: 4px solid `#cc3b3b`
|
||||
- Використання: зворотний зв'язок при неправильній відповіді.
|
||||
|
||||
### Картки / Плитки уроків
|
||||
- Фон: `#ffffff`
|
||||
- Рамка: 2px solid `#e5e5e5`
|
||||
- Рамка знизу: 4px solid `#e5e5e5`
|
||||
- Радіус: 16px
|
||||
- Відступ: 16px
|
||||
- Наведення: підйом 2px, тінь `0 4px 0 #d7d7d7`
|
||||
|
||||
### Вузол дерева навиків (бульбашка уроку)
|
||||
- Розмір: 80×72px
|
||||
- Фон: відтінок кольору навику (зелений для активного, сірий для заблокованого)
|
||||
- Рамка знизу: 6px solid темніший варіант
|
||||
- Радіус: 50% (круглий)
|
||||
- Активний: пульсує 1.0 → 1.05 кожні 1.6s
|
||||
|
||||
### Поля введення
|
||||
- Фон: `#ffffff`
|
||||
- Рамка: 2px solid `#e5e5e5`
|
||||
- Радіус: 12px
|
||||
- Відступ: 12px 16px
|
||||
- Фокус: рамка `#1cb0f6` (блакитний вугра), обведення `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Смуга прогресу
|
||||
- Доріжка: `#e5e5e5`
|
||||
- Заповнення: `#58cc02` (або `#ff9600` для серії)
|
||||
- Радіус: 9999px
|
||||
- Висота: 16px
|
||||
- Анімація заповнення: 320ms ease-out при збільшенні.
|
||||
|
||||
## 5. Відступи та макет
|
||||
|
||||
- **Базова одиниця**: 4px. Шкала: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Контейнер**: максимум 1080px, відступ 24px.
|
||||
- **Стовпець дерева уроків**: ширина 320px; по центру на десктопі.
|
||||
|
||||
## 6. Анімація
|
||||
|
||||
- **Тривалість**: 180ms для натискання кнопки; 320ms для розблокування вузла навику; 1.6s для пульсації активного вузла.
|
||||
- **Пом'якшення**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (з зворотнім виходом, легке перевищення) для розблокувань.
|
||||
- **Маскот**: Дуо кліпає кожні 4–6s, стрибає на ключових моментах серії (480ms ease-out пружина).
|
||||
|
||||
## 7. Обмеження використання
|
||||
|
||||
- Зберігайте насичений совиний зелений, масивні тіні знизу та закруглену геометрію уроків разом; самі по собі плоскі зелені кнопки не читаються як Duolingo.
|
||||
- Залишайте великий жирний шрифт для уроку, серії та моментів прогресу, де продукт потребує заохочення або зворотного зв'язку.
|
||||
- Використовуйте ігрову анімацію помірно, лише навколо змін стану прогресу, уникаючи загальної «пружинистої» анімації на кожному елементі керування.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Hệ thống thiết kế lấy cảm hứng từ Duolingo
|
||||
|
||||
> Category: Năng suất & SaaS
|
||||
> Nền tảng học ngôn ngữ. Xanh cú mèo tươi sáng, bóng đổ dày, niềm vui gamification.
|
||||
|
||||
## 1. Chủ đề hình ảnh và bầu không khí
|
||||
|
||||
Duolingo là gamification được thể hiện qua ngôn ngữ hình ảnh. Giao diện sáng rực một cách không ngại ngùng, với **xanh cú mèo** (`#58cc02`) là màu chính của thương hiệu và bóng đổ dày 4px ở đáy mỗi phần tử tương tác trông như một nút 3D đang chờ được nhấn. Trang có nền trắng (`#ffffff`) với viền dày 2–3px màu xám đậm (`#e5e5e5`), toàn bộ hệ thống gợi nhớ đến ứng dụng iOS năm 2015 được tái sinh với phân cấp tốt hơn.
|
||||
|
||||
Kiểu chữ dùng **Feather Bold** (phông sans-serif bo tròn tùy chỉnh) cho chrome và **Mona Sans** (hoặc Inter) cho thân văn bản. Kích thước hiển thị lớn và tự tin — Duolingo không bao giờ thì thầm. Tiêu đề thường có nét gạch chân màu xanh hoặc đặt trên viên thuốc xanh, và linh vật Duo (một con cú xanh) xuất hiện như một nhân vật minh họa năng động, không phải logo tĩnh.
|
||||
|
||||
Ngôn ngữ hình dạng thân thiện: bán kính 16–20px trên thẻ, 12px trên nút, 9999px trên chip và thanh tiến trình. Biểu tượng được tô đầy, bo tròn và mã hóa màu theo kỹ năng — mỗi bề mặt bài học có một cặp màu có thể nhận biết ngay lập tức.
|
||||
|
||||
**Đặc điểm chính:**
|
||||
- Xanh cú mèo (`#58cc02`) là màu thương hiệu chiếm ưu thế, dùng trên hơn 30% bề mặt
|
||||
- Bóng đổ dày 4px ở đáy mỗi nút (tính năng "nhấn xúc giác")
|
||||
- Viền đặc 2–3px, không bao giờ dùng đường mảnh
|
||||
- Feather Bold (hiển thị bo tròn) + Mona Sans (thân văn bản)
|
||||
- Chữ lớn tự tin — kích thước hiển thị bắt đầu từ 48px và tăng lên
|
||||
- Linh vật-nhân vật: cú Duo xuất hiện trong onboarding, lỗi, chuỗi
|
||||
- Cam chuỗi (`#ff9600`) và hồng đá quý (`#ce82ff`) là màu thương hiệu phụ
|
||||
|
||||
## 2. Bảng màu và vai trò
|
||||
|
||||
### Màu chính
|
||||
- **Xanh cú mèo** (`#58cc02`): Màu chính thương hiệu, CTA chính, câu trả lời đúng.
|
||||
- **Xanh cú mèo đậm** (`#58a700`): Màu nhấn/bóng cho nút xanh.
|
||||
- **Xanh cú mèo nhạt** (`#89e219`): Hover, tô màu nhẹ.
|
||||
- **Xanh cú mèo lạt** (`#dbf8c5`): Bề mặt nhẹ, banner thành công.
|
||||
|
||||
### Điểm nhấn phụ
|
||||
- **Cam chuỗi** (`#ff9600`): Đếm chuỗi, biểu tượng lửa, năng lượng cao cấp.
|
||||
- **Cam chuỗi đậm** (`#cc7a00`): Cam khi nhấn.
|
||||
- **Hồng đá quý** (`#ce82ff`): Tiền tệ đá quý, Super Duolingo.
|
||||
- **Xanh lươn** (`#1cb0f6`): Nút gợi ý, liên kết thông tin.
|
||||
- **Đỏ hồng y** (`#ff4b4b`): Câu trả lời sai, mất mạng.
|
||||
- **Vàng ong** (`#ffc800`): Huy hiệu chuyên nghiệp, thành tích.
|
||||
|
||||
### Bề mặt
|
||||
- **Tuyết** (`#ffffff`): Nền chính.
|
||||
- **Lươn** (`#f7f7f7`): Phân tách phần, bề mặt phụ.
|
||||
- **Thiên nga** (`#e5e5e5`): Nền bị vô hiệu hóa, khối nhúng.
|
||||
- **Sói** (`#777777`): Đường phân chia tối, văn bản phụ.
|
||||
|
||||
### Mực và văn bản
|
||||
- **Đen lươn** (`#3c3c3c`): Văn bản chính.
|
||||
- **Sói** (`#777777`): Văn bản phụ, chú thích.
|
||||
- **Thỏ** (`#afafaf`): Bị vô hiệu hóa, chỗ đặt dữ liệu.
|
||||
|
||||
### Viền
|
||||
- **Thiên nga** (`#e5e5e5`): Viền tiêu chuẩn 2px.
|
||||
- **Thỏ** (`#afafaf`): Viền nhấn mạnh khi hover.
|
||||
|
||||
## 3. Quy tắc kiểu chữ
|
||||
|
||||
### Họ phông chữ
|
||||
- **Hiển thị / UI / Tiêu đề**: `Feather Bold`, dự phòng: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Thân văn bản / Dài**: `Mona Sans`, dự phòng: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Mã (hiếm, trường học/quản trị)**: `JetBrains Mono`, dự phòng: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Phân cấp
|
||||
|
||||
| Vai trò | Phông | Kích thước | Độ đậm | Chiều cao dòng | Khoảng cách | Ghi chú |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Hiển thị | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Anh hùng onboarding |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Tiêu đề trang |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Tiêu đề phần |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Tiêu đề thẻ, hàng bài học |
|
||||
| Thân lớn | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Gợi ý bài học, hướng dẫn |
|
||||
| Thân | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Văn xuôi tiêu chuẩn |
|
||||
| Chú thích | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | Đếm XP, siêu dữ liệu |
|
||||
| Nút | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Nhãn nút tiêu chuẩn |
|
||||
| Chuỗi | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Số chuỗi, trên ngọn lửa |
|
||||
|
||||
### Nguyên tắc
|
||||
- **800 là mặc định**: Feather Bold chạy ở 800 trên tiêu đề và nút. 700 trông yếu trong hệ thống này.
|
||||
- **Chữ lớn**: kích thước tiêu đề lớn hơn 25–40% so với các thương hiệu sản phẩm điển hình — sự tự tin là bản sắc.
|
||||
- **Hình dạng chữ bo tròn**: mỗi glyph có đầu cuối mềm mại; chân cứng sẽ phá vỡ hợp đồng thân thiện.
|
||||
|
||||
## 4. Kiểu dáng thành phần
|
||||
|
||||
### Nút
|
||||
|
||||
**Chính (Xanh cú mèo)**
|
||||
- Nền: `#58cc02`
|
||||
- Văn bản: `#ffffff`
|
||||
- Đệm: 14px 24px
|
||||
- Bán kính: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (bóng đổ dày)
|
||||
- Hover: nền `#89e219`
|
||||
- Kích hoạt: translate-y 4px, border-bottom 0 (nút "nhấn xuống")
|
||||
- Dùng: "Tiếp tục", "Kiểm tra", CTA chính.
|
||||
|
||||
**Phụ (Trắng có bóng dưới)**
|
||||
- Nền: `#ffffff`
|
||||
- Văn bản: `#777777`
|
||||
- Viền: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Bán kính: 16px
|
||||
- Đệm: 14px 24px
|
||||
- Hover: văn bản `#3c3c3c`, viền `#afafaf`
|
||||
|
||||
**Cam chuỗi**
|
||||
- Nền: `#ff9600`
|
||||
- Văn bản: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Dùng: mục tiêu chuỗi, "Bắt đầu chuỗi"
|
||||
|
||||
**Lỗi (Đỏ hồng y)**
|
||||
- Nền: `#ff4b4b`
|
||||
- Văn bản: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Dùng: phản hồi câu trả lời sai.
|
||||
|
||||
### Thẻ / Ô bài học
|
||||
- Nền: `#ffffff`
|
||||
- Viền: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Bán kính: 16px
|
||||
- Đệm: 16px
|
||||
- Hover: nâng 2px, bóng `0 4px 0 #d7d7d7`
|
||||
|
||||
### Nút cây kỹ năng (Bong bóng bài học)
|
||||
- Kích thước: 80×72px
|
||||
- Nền: tông màu kỹ năng (xanh khi kích hoạt, xám khi khóa)
|
||||
- Border-bottom: 6px solid biến thể đậm hơn
|
||||
- Bán kính: 50% (tròn)
|
||||
- Kích hoạt: nhịp 1.0 → 1.05 mỗi 1.6s
|
||||
|
||||
### Ô nhập liệu
|
||||
- Nền: `#ffffff`
|
||||
- Viền: 2px solid `#e5e5e5`
|
||||
- Bán kính: 12px
|
||||
- Đệm: 12px 16px
|
||||
- Tiêu điểm: viền `#1cb0f6` (xanh lươn), vòng `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Thanh tiến trình
|
||||
- Đường ray: `#e5e5e5`
|
||||
- Tô: `#58cc02` (hoặc `#ff9600` cho chuỗi)
|
||||
- Bán kính: 9999px
|
||||
- Chiều cao: 16px
|
||||
- Tô hoạt ảnh: 320ms ease-out khi tăng.
|
||||
|
||||
## 5. Khoảng cách & Bố cục
|
||||
|
||||
- **Đơn vị cơ sở**: 4px. Thang: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Vùng chứa**: tối đa 1080px, rãnh 24px.
|
||||
- **Cột cây bài học**: rộng 320px; canh giữa trên desktop.
|
||||
|
||||
## 6. Chuyển động
|
||||
|
||||
- **Thời lượng**: 180ms nhấn nút; 320ms mở khóa nút kỹ năng; 1.6s nhịp nút kích hoạt.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, vượt nhẹ) cho mở khóa.
|
||||
- **Linh vật**: Duo chớp mắt mỗi 4–6s, nhảy tại các mốc chuỗi (480ms ease-out lò xo).
|
||||
|
||||
## 7. Hướng dẫn sử dụng
|
||||
|
||||
- Giữ nguyên màu xanh cú mèo bão hòa cao, bóng đổ dày ở đáy và hình học bài học bo tròn cùng nhau; nút xanh phẳng đơn lẻ không tạo ra cảm giác Duolingo.
|
||||
- Dành kiểu chữ đậm cỡ lớn cho các khoảnh khắc bài học, chuỗi và tiến trình khi sản phẩm cần sự khích lệ hoặc phản hồi.
|
||||
- Dùng chuyển động vui nhộn tiết kiệm xung quanh các thay đổi trạng thái tiến trình, tránh hoạt ảnh nảy generic trên mọi điều khiển.
|
||||
@@ -0,0 +1,160 @@
|
||||
# 受 Duolingo 啟發的設計系統
|
||||
|
||||
> Category: 效率與 SaaS
|
||||
> 語言學習平台。明亮的貓頭鷹綠、粗厚陰影、遊戲化的愉悅感。
|
||||
|
||||
## 1. 視覺主題與氛圍
|
||||
|
||||
Duolingo 是以視覺語言呈現的遊戲化設計。介面毫無保留地鮮亮,以**貓頭鷹綠**(`#58cc02`)為品牌主色,每個可互動元素底部都有粗厚的 4px 陰影,看起來像一個等待被按下的 3D 按鈕。頁面背景為白色(`#ffffff`),邊框為 2–3px 深灰色(`#e5e5e5`),整體系統讀起來就像一款 2015 年 iOS 應用以更好的層級感重生。
|
||||
|
||||
排版使用 **Feather Bold**(一種自訂圓角無襯線字體)用於介面框架,**Mona Sans**(或 Inter)用於正文。展示尺寸大而自信——Duolingo 從不低語。標題通常帶有綠色下劃線筆觸或置於綠色膠囊上,吉祥物 Duo(一隻綠色貓頭鷹)以活躍的插畫角色出現,而非靜態 logo。
|
||||
|
||||
形狀語言友好親切:卡片圓角 16–20px,按鈕 12px,標籤與進度條 9999px。圖示系統為填充、圓角風格,並按技能進行色彩編碼——每個課程介面都有一對一眼就能辨識的配色。
|
||||
|
||||
**關鍵特徵:**
|
||||
- 貓頭鷹綠(`#58cc02`)作為主導品牌色,在介面中佔據 30% 以上的面積
|
||||
- 每個按鈕底部有粗厚 4px 陰影(「觸覺按壓」可供性)
|
||||
- 2–3px 實線邊框,從不使用細線
|
||||
- Feather Bold(圓角展示字體)+ Mona Sans(正文)
|
||||
- 大而自信的文字——展示尺寸從 48px 起步並向上攀升
|
||||
- 吉祥物即角色:Duo 貓頭鷹出現在引導、錯誤、連擊等場景中
|
||||
- 連擊橙(`#ff9600`)和寶石粉(`#ce82ff`)作為次級品牌色
|
||||
|
||||
## 2. 色彩方案與角色
|
||||
|
||||
### 主色
|
||||
- **貓頭鷹綠**(`#58cc02`):品牌主色、主要行動按鈕、正確答案。
|
||||
- **深貓頭鷹綠**(`#58a700`):綠色按鈕的按壓/陰影色。
|
||||
- **淺貓頭鷹綠**(`#89e219`):懸停狀態、柔和填充。
|
||||
- **淡貓頭鷹綠**(`#dbf8c5`):柔和表面、成功橫幅。
|
||||
|
||||
### 次級強調色
|
||||
- **連擊橙**(`#ff9600`):連擊計數器、火焰圖示、付費能量。
|
||||
- **深連擊橙**(`#cc7a00`):橙色按壓狀態。
|
||||
- **寶石粉**(`#ce82ff`):寶石貨幣、Super Duolingo。
|
||||
- **鰻魚藍**(`#1cb0f6`):提示按鈕、資訊連結。
|
||||
- **紅衣主教紅**(`#ff4b4b`):答錯、失去生命。
|
||||
- **蜜蜂黃**(`#ffc800`):專業徽章、成就。
|
||||
|
||||
### 表面色
|
||||
- **雪白**(`#ffffff`):主背景。
|
||||
- **鰻魚灰**(`#f7f7f7`):區塊分隔、次級表面。
|
||||
- **天鵝灰**(`#e5e5e5`):停用背景、內嵌塊。
|
||||
- **狼灰**(`#777777`):深色分隔線、次要文字。
|
||||
|
||||
### 墨色與文字
|
||||
- **鰻魚黑**(`#3c3c3c`):主要文字。
|
||||
- **狼灰**(`#777777`):次要文字、說明文字。
|
||||
- **野兔灰**(`#afafaf`):停用、佔位符。
|
||||
|
||||
### 邊框
|
||||
- **天鵝灰**(`#e5e5e5`):標準 2px 邊框。
|
||||
- **野兔灰**(`#afafaf`):懸停時的強調邊框。
|
||||
|
||||
## 3. 排版規則
|
||||
|
||||
### 字體家族
|
||||
- **展示 / UI / 標題**:`Feather Bold`,備用字體:`'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **正文 / 長文**:`Mona Sans`,備用字體:`'Helvetica Neue', system-ui, sans-serif`
|
||||
- **程式碼(少用,學校/管理場景)**:`JetBrains Mono`,備用字體:`ui-monospace, Menlo, monospace`
|
||||
|
||||
### 層級
|
||||
|
||||
| 角色 | 字體 | 尺寸 | 字重 | 行高 | 字間距 | 備註 |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| 展示 | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | 引導主視覺 |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | 頁面標題 |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | 版塊標題 |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | 卡片標題、課程列 |
|
||||
| 大正文 | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | 課程提示、說明 |
|
||||
| 正文 | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | 標準文段 |
|
||||
| 說明文字 | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | 經驗值計數、元資料 |
|
||||
| 按鈕 | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | 標準按鈕標籤 |
|
||||
| 連擊 | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | 連擊數字、火焰上 |
|
||||
|
||||
### 原則
|
||||
- **800 是預設值**:Feather Bold 在標題和按鈕中以 800 字重運行。在此系統中,700 看起來偏弱。
|
||||
- **大字號**:標題尺寸比典型產品品牌大 25–40%——自信即身份。
|
||||
- **圓潤字形**:每個字形都有柔和末端;鋒利襯線會破壞親和感契約。
|
||||
|
||||
## 4. 元件樣式
|
||||
|
||||
### 按鈕
|
||||
|
||||
**主要按鈕(貓頭鷹綠)**
|
||||
- 背景:`#58cc02`
|
||||
- 文字:`#ffffff`
|
||||
- 內邊距:14px 24px
|
||||
- 圓角:16px
|
||||
- 底部邊框:4px solid `#58a700`(粗厚陰影)
|
||||
- 懸停:背景 `#89e219`
|
||||
- 激活:向下位移 4px,底部邊框 0(按鈕「按下」)
|
||||
- 用途:「繼續」、「檢查」、主要行動。
|
||||
|
||||
**次要按鈕(白色帶底部陰影)**
|
||||
- 背景:`#ffffff`
|
||||
- 文字:`#777777`
|
||||
- 邊框:2px solid `#e5e5e5`
|
||||
- 底部邊框:4px solid `#e5e5e5`
|
||||
- 圓角:16px
|
||||
- 內邊距:14px 24px
|
||||
- 懸停:文字 `#3c3c3c`,邊框 `#afafaf`
|
||||
|
||||
**連擊橙按鈕**
|
||||
- 背景:`#ff9600`
|
||||
- 文字:`#ffffff`
|
||||
- 底部邊框:4px solid `#cc7a00`
|
||||
- 用途:連擊目標、「開始連擊」
|
||||
|
||||
**錯誤按鈕(紅衣主教紅)**
|
||||
- 背景:`#ff4b4b`
|
||||
- 文字:`#ffffff`
|
||||
- 底部邊框:4px solid `#cc3b3b`
|
||||
- 用途:答錯回饋。
|
||||
|
||||
### 卡片 / 課程格
|
||||
- 背景:`#ffffff`
|
||||
- 邊框:2px solid `#e5e5e5`
|
||||
- 底部邊框:4px solid `#e5e5e5`
|
||||
- 圓角:16px
|
||||
- 內邊距:16px
|
||||
- 懸停:上浮 2px,陰影 `0 4px 0 #d7d7d7`
|
||||
|
||||
### 技能樹節點(課程氣泡)
|
||||
- 尺寸:80×72px
|
||||
- 背景:技能色調(激活為綠色,鎖定為灰色)
|
||||
- 底部邊框:6px solid 深色變體
|
||||
- 圓角:50%(圓形)
|
||||
- 激活:每 1.6s 在 1.0 → 1.05 之間脈衝
|
||||
|
||||
### 輸入框
|
||||
- 背景:`#ffffff`
|
||||
- 邊框:2px solid `#e5e5e5`
|
||||
- 圓角:12px
|
||||
- 內邊距:12px 16px
|
||||
- 聚焦:邊框 `#1cb0f6`(鰻魚藍),光暈 `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### 進度條
|
||||
- 軌道:`#e5e5e5`
|
||||
- 填充:`#58cc02`(或連擊時使用 `#ff9600`)
|
||||
- 圓角:9999px
|
||||
- 高度:16px
|
||||
- 動畫填充:遞增時 320ms ease-out。
|
||||
|
||||
## 5. 間距與版面
|
||||
|
||||
- **基礎單位**:4px。比例:4, 8, 12, 16, 24, 32, 48, 64。
|
||||
- **容器**:最大 1080px,24px 邊距。
|
||||
- **課程樹欄**:寬 320px;在桌面端置中。
|
||||
|
||||
## 6. 動效
|
||||
|
||||
- **時長**:按鈕按壓 180ms;技能節點解鎖 320ms;激活節點脈衝 1.6s。
|
||||
- **緩動**:`cubic-bezier(0.34, 1.56, 0.64, 1)`(回彈緩出,輕微過衝)用於解鎖動效。
|
||||
- **吉祥物**:Duo 每 4–6s 眨眼,在連擊里程碑時跳躍(480ms ease-out 彈簧)。
|
||||
|
||||
## 7. 使用守則
|
||||
|
||||
- 保持高飽和度貓頭鷹綠、粗厚底部陰影和圓潤課程幾何形狀的組合;單獨使用扁平綠色按鈕並不能讀出 Duolingo 的感覺。
|
||||
- 將超大粗體文字保留用於課程、連擊和進度等需要鼓勵或回饋的產品時刻。
|
||||
- 將趣味動效克制地用在進度狀態變化周圍,避免在每個控件上都使用通用的彈跳動畫。
|
||||
@@ -0,0 +1,160 @@
|
||||
# 受 Duolingo 启发的设计系统
|
||||
|
||||
> Category: 效率与 SaaS
|
||||
> 语言学习平台。明亮的猫头鹰绿、粗厚阴影、游戏化的愉悦感。
|
||||
|
||||
## 1. 视觉主题与氛围
|
||||
|
||||
Duolingo 是以视觉语言呈现的游戏化设计。界面毫无保留地鲜亮,以**猫头鹰绿**(`#58cc02`)为品牌主色,每个可交互元素底部都有粗厚的 4px 阴影,看起来像一个等待被按下的 3D 按钮。页面背景为白色(`#ffffff`),边框为 2–3px 深灰色(`#e5e5e5`),整体系统读起来就像一款 2015 年 iOS 应用以更好的层级感重生。
|
||||
|
||||
排版使用 **Feather Bold**(一种自定义圆角无衬线字体)用于界面框架,**Mona Sans**(或 Inter)用于正文。展示尺寸大而自信——Duolingo 从不低语。标题通常带有绿色下划线笔触或置于绿色胶囊上,吉祥物 Duo(一只绿色猫头鹰)以活跃的插画角色出现,而非静态 logo。
|
||||
|
||||
形状语言友好亲切:卡片圆角 16–20px,按钮 12px,标签与进度条 9999px。图标系统为填充、圆角风格,并按技能进行色彩编码——每个课程界面都有一对一眼就能辨识的配色。
|
||||
|
||||
**关键特征:**
|
||||
- 猫头鹰绿(`#58cc02`)作为主导品牌色,在界面中占据 30% 以上的面积
|
||||
- 每个按钮底部有粗厚 4px 阴影("触觉按压"可供性)
|
||||
- 2–3px 实线边框,从不使用细线
|
||||
- Feather Bold(圆角展示字体)+ Mona Sans(正文)
|
||||
- 大而自信的文字——展示尺寸从 48px 起步并向上攀升
|
||||
- 吉祥物即角色:Duo 猫头鹰出现在引导、错误、连击等场景中
|
||||
- 连击橙(`#ff9600`)和宝石粉(`#ce82ff`)作为次级品牌色
|
||||
|
||||
## 2. 色彩方案与角色
|
||||
|
||||
### 主色
|
||||
- **猫头鹰绿**(`#58cc02`):品牌主色、主要行动按钮、正确答案。
|
||||
- **深猫头鹰绿**(`#58a700`):绿色按钮的按压/阴影色。
|
||||
- **浅猫头鹰绿**(`#89e219`):悬停状态、柔和填充。
|
||||
- **淡猫头鹰绿**(`#dbf8c5`):柔和表面、成功横幅。
|
||||
|
||||
### 次级强调色
|
||||
- **连击橙**(`#ff9600`):连击计数器、火焰图标、付费能量。
|
||||
- **深连击橙**(`#cc7a00`):橙色按压状态。
|
||||
- **宝石粉**(`#ce82ff`):宝石货币、Super Duolingo。
|
||||
- **鳗鱼蓝**(`#1cb0f6`):提示按钮、信息链接。
|
||||
- **红衣主教红**(`#ff4b4b`):答错、失去生命。
|
||||
- **蜜蜂黄**(`#ffc800`):专业徽章、成就。
|
||||
|
||||
### 表面色
|
||||
- **雪白**(`#ffffff`):主背景。
|
||||
- **鳗鱼灰**(`#f7f7f7`):区块分隔、次级表面。
|
||||
- **天鹅灰**(`#e5e5e5`):禁用背景、内嵌块。
|
||||
- **狼灰**(`#777777`):深色分隔线、次级文字。
|
||||
|
||||
### 墨色与文字
|
||||
- **鳗鱼黑**(`#3c3c3c`):主要文字。
|
||||
- **狼灰**(`#777777`):次要文字、说明文字。
|
||||
- **野兔灰**(`#afafaf`):禁用、占位符。
|
||||
|
||||
### 边框
|
||||
- **天鹅灰**(`#e5e5e5`):标准 2px 边框。
|
||||
- **野兔灰**(`#afafaf`):悬停时的强调边框。
|
||||
|
||||
## 3. 排版规则
|
||||
|
||||
### 字体家族
|
||||
- **展示 / UI / 标题**:`Feather Bold`,备用字体:`'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **正文 / 长文**:`Mona Sans`,备用字体:`'Helvetica Neue', system-ui, sans-serif`
|
||||
- **代码(少用,学校/管理场景)**:`JetBrains Mono`,备用字体:`ui-monospace, Menlo, monospace`
|
||||
|
||||
### 层级
|
||||
|
||||
| 角色 | 字体 | 尺寸 | 字重 | 行高 | 字间距 | 备注 |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| 展示 | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | 引导主视觉 |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | 页面标题 |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | 版块标题 |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | 卡片标题、课程行 |
|
||||
| 大正文 | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | 课程提示、说明 |
|
||||
| 正文 | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | 标准文段 |
|
||||
| 说明文字 | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | 经验值计数、元数据 |
|
||||
| 按钮 | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | 标准按钮标签 |
|
||||
| 连击 | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | 连击数字、火焰上 |
|
||||
|
||||
### 原则
|
||||
- **800 是默认值**:Feather Bold 在标题和按钮中以 800 字重运行。在此系统中,700 看起来偏弱。
|
||||
- **大字号**:标题尺寸比典型产品品牌大 25–40%——自信即身份。
|
||||
- **圆润字形**:每个字形都有柔和末端;锋利衬线会破坏亲和感契约。
|
||||
|
||||
## 4. 组件样式
|
||||
|
||||
### 按钮
|
||||
|
||||
**主要按钮(猫头鹰绿)**
|
||||
- 背景:`#58cc02`
|
||||
- 文字:`#ffffff`
|
||||
- 内边距:14px 24px
|
||||
- 圆角:16px
|
||||
- 底部边框:4px solid `#58a700`(粗厚阴影)
|
||||
- 悬停:背景 `#89e219`
|
||||
- 激活:向下位移 4px,底部边框 0(按钮"按下")
|
||||
- 用途:"继续"、"检查"、主要行动。
|
||||
|
||||
**次要按钮(白色带底部阴影)**
|
||||
- 背景:`#ffffff`
|
||||
- 文字:`#777777`
|
||||
- 边框:2px solid `#e5e5e5`
|
||||
- 底部边框:4px solid `#e5e5e5`
|
||||
- 圆角:16px
|
||||
- 内边距:14px 24px
|
||||
- 悬停:文字 `#3c3c3c`,边框 `#afafaf`
|
||||
|
||||
**连击橙按钮**
|
||||
- 背景:`#ff9600`
|
||||
- 文字:`#ffffff`
|
||||
- 底部边框:4px solid `#cc7a00`
|
||||
- 用途:连击目标、"开始连击"
|
||||
|
||||
**错误按钮(红衣主教红)**
|
||||
- 背景:`#ff4b4b`
|
||||
- 文字:`#ffffff`
|
||||
- 底部边框:4px solid `#cc3b3b`
|
||||
- 用途:答错反馈。
|
||||
|
||||
### 卡片 / 课程格
|
||||
- 背景:`#ffffff`
|
||||
- 边框:2px solid `#e5e5e5`
|
||||
- 底部边框:4px solid `#e5e5e5`
|
||||
- 圆角:16px
|
||||
- 内边距:16px
|
||||
- 悬停:上浮 2px,阴影 `0 4px 0 #d7d7d7`
|
||||
|
||||
### 技能树节点(课程气泡)
|
||||
- 尺寸:80×72px
|
||||
- 背景:技能色调(激活为绿色,锁定为灰色)
|
||||
- 底部边框:6px solid 深色变体
|
||||
- 圆角:50%(圆形)
|
||||
- 激活:每 1.6s 在 1.0 → 1.05 之间脉冲
|
||||
|
||||
### 输入框
|
||||
- 背景:`#ffffff`
|
||||
- 边框:2px solid `#e5e5e5`
|
||||
- 圆角:12px
|
||||
- 内边距:12px 16px
|
||||
- 聚焦:边框 `#1cb0f6`(鳗鱼蓝),光晕 `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### 进度条
|
||||
- 轨道:`#e5e5e5`
|
||||
- 填充:`#58cc02`(或连击时使用 `#ff9600`)
|
||||
- 圆角:9999px
|
||||
- 高度:16px
|
||||
- 动画填充:递增时 320ms ease-out。
|
||||
|
||||
## 5. 间距与布局
|
||||
|
||||
- **基础单位**:4px。比例:4, 8, 12, 16, 24, 32, 48, 64。
|
||||
- **容器**:最大 1080px,24px 边距。
|
||||
- **课程树列**:宽 320px;在桌面端居中。
|
||||
|
||||
## 6. 动效
|
||||
|
||||
- **时长**:按钮按压 180ms;技能节点解锁 320ms;激活节点脉冲 1.6s。
|
||||
- **缓动**:`cubic-bezier(0.34, 1.56, 0.64, 1)`(回弹缓出,轻微过冲)用于解锁动效。
|
||||
- **吉祥物**:Duo 每 4–6s 眨眼,在连击里程碑时跳跃(480ms ease-out 弹簧)。
|
||||
|
||||
## 7. 使用守则
|
||||
|
||||
- 保持高饱和度猫头鹰绿、粗厚底部阴影和圆润课程几何形状的组合;单独使用扁平绿色按钮并不能读出 Duolingo 的感觉。
|
||||
- 将超大粗体文字保留用于课程、连击和进度等需要鼓励或反馈的产品时刻。
|
||||
- 将趣味动效克制地用在进度状态变化周围,避免在每个控件上都使用通用的弹跳动画。
|
||||
@@ -0,0 +1,160 @@
|
||||
# Design System Inspired by Duolingo
|
||||
|
||||
> Category: Productivity & SaaS
|
||||
> Language-learning platform. Bright owl green, chunky shadows, gamified joy.
|
||||
|
||||
## 1. Visual Theme & Atmosphere
|
||||
|
||||
Duolingo is gamification rendered as visual language. The interface is unapologetically bright, with **owl green** (`#58cc02`) as the brand primary and a chunky 4px bottom-shadow on every interactive element that reads like a 3D button waiting to be pressed. The page is white (`#ffffff`) with thick 2–3px borders in a deep gray (`#e5e5e5`) and the entire system reads like an iOS app from 2015 reborn with better hierarchy.
|
||||
|
||||
Typography uses **Feather Bold** (a custom rounded sans) for chrome and **Mona Sans** (or Inter) for body. Display sizes are big and confident — Duolingo never whispers. Headings often carry the green underline-stroke or sit on a green pill, and the mascot Duo (a green owl) appears as an active illustration character, not a static logo.
|
||||
|
||||
Shape language is friendly: 16–20px radii on cards, 12px on buttons, 9999px on chips and progress bars. Iconography is filled, rounded, and color-coded by skill — every lesson surface has an instantly identifiable color pairing.
|
||||
|
||||
**Key Characteristics:**
|
||||
- Owl green (`#58cc02`) as the dominant brand color, used in 30%+ of the surface
|
||||
- Chunky 4px bottom-shadow on every button (the "tactile press" affordance)
|
||||
- 2–3px solid borders, never hairlines
|
||||
- Feather Bold (rounded display) + Mona Sans (body)
|
||||
- Big confident type — display sizes start at 48px and climb
|
||||
- Mascot-as-character: Duo the owl appears in onboarding, errors, streaks
|
||||
- Streak orange (`#ff9600`) and gem pink (`#ce82ff`) as secondary brand colors
|
||||
|
||||
## 2. Color Palette & Roles
|
||||
|
||||
### Primary
|
||||
- **Owl Green** (`#58cc02`): Brand primary, primary CTA, correct answer.
|
||||
- **Owl Green Deep** (`#58a700`): Pressed/shadow color for green buttons.
|
||||
- **Owl Green Light** (`#89e219`): Hover, soft fills.
|
||||
- **Owl Green Pale** (`#dbf8c5`): Soft surface, success banner.
|
||||
|
||||
### Secondary Accents
|
||||
- **Streak Orange** (`#ff9600`): Streak counter, fire icon, premium energy.
|
||||
- **Streak Orange Deep** (`#cc7a00`): Pressed orange.
|
||||
- **Gem Pink** (`#ce82ff`): Gem currency, Super Duolingo.
|
||||
- **Eel Blue** (`#1cb0f6`): Hint button, info link.
|
||||
- **Cardinal Red** (`#ff4b4b`): Wrong answer, life lost.
|
||||
- **Bee Yellow** (`#ffc800`): Pro badge, achievement.
|
||||
|
||||
### Surface
|
||||
- **Snow** (`#ffffff`): Primary background.
|
||||
- **Eel** (`#f7f7f7`): Section break, secondary surface.
|
||||
- **Swan** (`#e5e5e5`): Disabled background, inset block.
|
||||
- **Wolf** (`#777777`): Dark divider, secondary text.
|
||||
|
||||
### Ink & Text
|
||||
- **Eel Black** (`#3c3c3c`): Primary text.
|
||||
- **Wolf** (`#777777`): Secondary text, captions.
|
||||
- **Hare** (`#afafaf`): Disabled, placeholder.
|
||||
|
||||
### Border
|
||||
- **Swan** (`#e5e5e5`): Standard 2px border.
|
||||
- **Hare** (`#afafaf`): Emphasized border on hover.
|
||||
|
||||
## 3. Typography Rules
|
||||
|
||||
### Font Family
|
||||
- **Display / UI / Headings**: `Feather Bold`, with fallback: `'DIN Round Pro', 'Helvetica Neue', sans-serif`
|
||||
- **Body / Long-form**: `Mona Sans`, with fallback: `'Helvetica Neue', system-ui, sans-serif`
|
||||
- **Code (rare, schools/admin)**: `JetBrains Mono`, with fallback: `ui-monospace, Menlo, monospace`
|
||||
|
||||
### Hierarchy
|
||||
|
||||
| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display | Feather Bold | 56px (3.5rem) | 800 | 1.05 | -0.01em | Onboarding hero |
|
||||
| H1 | Feather Bold | 32px (2rem) | 800 | 1.15 | -0.005em | Page title |
|
||||
| H2 | Feather Bold | 24px (1.5rem) | 800 | 1.2 | normal | Section heading |
|
||||
| H3 | Feather Bold | 18px (1.125rem) | 700 | 1.25 | normal | Card title, lesson row |
|
||||
| Body Large | Mona Sans | 17px (1.0625rem) | 500 | 1.5 | normal | Lesson prompt, instruction |
|
||||
| Body | Mona Sans | 15px (0.9375rem) | 400 | 1.5 | normal | Standard prose |
|
||||
| Caption | Mona Sans | 13px (0.8125rem) | 600 | 1.4 | 0.01em | XP counter, metadata |
|
||||
| Button | Feather Bold | 16px (1rem) | 800 | 1.2 | 0.02em | Standard button label |
|
||||
| Streak | Feather Bold | 14px (0.875rem) | 800 | 1.2 | normal | Streak number, on flame |
|
||||
|
||||
### Principles
|
||||
- **800 is default**: Feather Bold runs at 800 across headings and buttons. 700 feels weak in this system.
|
||||
- **Big type**: heading sizes are 25–40% larger than typical product brands — confidence as identity.
|
||||
- **Rounded letterforms**: every glyph has soft terminals; sharp serifs would break the friendliness contract.
|
||||
|
||||
## 4. Component Stylings
|
||||
|
||||
### Buttons
|
||||
|
||||
**Primary (Owl Green)**
|
||||
- Background: `#58cc02`
|
||||
- Text: `#ffffff`
|
||||
- Padding: 14px 24px
|
||||
- Radius: 16px
|
||||
- Border-bottom: 4px solid `#58a700` (the chunky shadow)
|
||||
- Hover: background `#89e219`
|
||||
- Active: translate-y 4px, border-bottom 0 (button "presses")
|
||||
- Use: "Continue", "Check", main CTA.
|
||||
|
||||
**Secondary (White with Bottom-Shadow)**
|
||||
- Background: `#ffffff`
|
||||
- Text: `#777777`
|
||||
- Border: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Padding: 14px 24px
|
||||
- Hover: text `#3c3c3c`, border `#afafaf`
|
||||
|
||||
**Streak Orange**
|
||||
- Background: `#ff9600`
|
||||
- Text: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc7a00`
|
||||
- Use: streak goal, "Start streak"
|
||||
|
||||
**Error (Cardinal Red)**
|
||||
- Background: `#ff4b4b`
|
||||
- Text: `#ffffff`
|
||||
- Border-bottom: 4px solid `#cc3b3b`
|
||||
- Use: wrong answer feedback.
|
||||
|
||||
### Cards / Lesson Tiles
|
||||
- Background: `#ffffff`
|
||||
- Border: 2px solid `#e5e5e5`
|
||||
- Border-bottom: 4px solid `#e5e5e5`
|
||||
- Radius: 16px
|
||||
- Padding: 16px
|
||||
- Hover: lift 2px, shadow `0 4px 0 #d7d7d7`
|
||||
|
||||
### Skill Tree Node (Lesson Bubble)
|
||||
- Size: 80×72px
|
||||
- Background: skill-color tinted (green for active, gray for locked)
|
||||
- Border-bottom: 6px solid darker variant
|
||||
- Radius: 50% (circular)
|
||||
- Active: pulses 1.0 → 1.05 every 1.6s
|
||||
|
||||
### Inputs
|
||||
- Background: `#ffffff`
|
||||
- Border: 2px solid `#e5e5e5`
|
||||
- Radius: 12px
|
||||
- Padding: 12px 16px
|
||||
- Focus: border `#1cb0f6` (eel blue), ring `0 0 0 3px rgba(28, 176, 246, 0.2)`
|
||||
|
||||
### Progress Bar
|
||||
- Track: `#e5e5e5`
|
||||
- Fill: `#58cc02` (or `#ff9600` for streak)
|
||||
- Radius: 9999px
|
||||
- Height: 16px
|
||||
- Animated fill: 320ms ease-out on increment.
|
||||
|
||||
## 5. Spacing & Layout
|
||||
|
||||
- **Base unit**: 4px. Scale: 4, 8, 12, 16, 24, 32, 48, 64.
|
||||
- **Container**: max 1080px, 24px gutter.
|
||||
- **Lesson tree column**: 320px wide; centered on desktop.
|
||||
|
||||
## 6. Motion
|
||||
|
||||
- **Duration**: 180ms for button press; 320ms for skill-node unlock; 1.6s for active-node pulse.
|
||||
- **Easing**: `cubic-bezier(0.34, 1.56, 0.64, 1)` (back-out, slight overshoot) for unlocks.
|
||||
- **Mascot**: Duo blinks every 4–6s, jumps on streak milestones (480ms ease-out spring).
|
||||
|
||||
## 7. Usage Guardrails
|
||||
|
||||
- Keep the high-saturation owl green, chunky bottom shadows, and rounded lesson geometry together; flat green buttons alone do not read as Duolingo.
|
||||
- Reserve oversized bold type for lesson, streak, and progress moments where the product needs encouragement or feedback.
|
||||
- Use playful motion sparingly around progress state changes, avoiding generic bouncy animation on every control.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Duolingo Usage
|
||||
|
||||
Design System 2.0 package guide for OpenDesign agents and reviewers.
|
||||
|
||||
## Read Order
|
||||
|
||||
1. Read this file first to understand the package contract.
|
||||
2. Read `DESIGN.md` for visual intent, constraints, and anti-patterns.
|
||||
3. Paste `tokens.css` into the first artifact `<style>` block before writing component CSS.
|
||||
4. Use `components.manifest.json` for the compact component inventory; open `components.html` when exact selectors or states matter.
|
||||
5. Inspect `preview/` pages when a visual sanity check is useful.
|
||||
|
||||
## Design Highlights
|
||||
|
||||
- Owl green (`#58cc02`) as the dominant brand color, used in 30%+ of the surface
|
||||
- Chunky 4px bottom-shadow on every button (the "tactile press" affordance)
|
||||
- 2–3px solid borders, never hairlines
|
||||
- Feather Bold (rounded display) + Mona Sans (body)
|
||||
|
||||
## Do
|
||||
|
||||
- Preserve the schema token names exactly so cross-brand switching stays reliable.
|
||||
- Use `--accent` for primary actions, links, focus states, and one clear focal element.
|
||||
- Reuse component groups from `components.manifest.json` before inventing new controls.
|
||||
- Treat `source/` files as audit evidence for the bundled fixture backfill.
|
||||
|
||||
## Avoid
|
||||
|
||||
- Avoid raw hex values outside the copied `:root` token block.
|
||||
- Avoid redefining Tailwind or design-token values independently of `tokens.css`.
|
||||
- Avoid claiming original upstream source evidence; this package is based on the curated bundled fixture.
|
||||
- Avoid adding new component recipes that are not represented in `components.html` or `DESIGN.md`.
|
||||
@@ -0,0 +1,532 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo — reference components</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Reference fixture for design-systems/duolingo. Owl-green gamified
|
||||
universe, chunky 4px tactile shadows, big confident type, friendly pill geometry."
|
||||
/>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--bg: #ffffff;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--muted: #777777;
|
||||
--meta: #afafaf;
|
||||
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
|
||||
--accent: #58cc02;
|
||||
--accent-on: #ffffff;
|
||||
--accent-hover: #89e219;
|
||||
--accent-active: #58a700;
|
||||
|
||||
--success: #58cc02;
|
||||
--warn: #ffc800;
|
||||
--danger: #ff4b4b;
|
||||
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
|
||||
--text-xs: 12px;
|
||||
--text-sm: 13px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-xl: 24px;
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--tracking-display: -0.01em;
|
||||
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-12: 48px;
|
||||
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-tablet: 56px;
|
||||
--section-y-phone: 40px;
|
||||
|
||||
--radius-sm: 12px;
|
||||
--radius-md: 16px;
|
||||
--radius-lg: 20px;
|
||||
--radius-pill: 9999px;
|
||||
|
||||
--elev-flat: none;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
|
||||
--motion-fast: 180ms;
|
||||
--motion-base: 320ms;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
|
||||
--container-max: 1080px;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-gutter-phone: 16px;
|
||||
}
|
||||
|
||||
/* ─── Reset ─────────────────────────────────────────────── */
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body { margin: 0; padding: 0; }
|
||||
body {
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
line-height: var(--leading-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* ─── Layout ────────────────────────────────────────────── */
|
||||
.container {
|
||||
max-width: var(--container-max);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--container-gutter-desktop);
|
||||
}
|
||||
section { padding-block: var(--section-y-desktop); }
|
||||
section + section { border-top: 2px solid var(--border); }
|
||||
@media (max-width: 1023px) {
|
||||
.container { padding-inline: var(--container-gutter-tablet); }
|
||||
section { padding-block: var(--section-y-tablet); }
|
||||
}
|
||||
@media (max-width: 639px) {
|
||||
.container { padding-inline: var(--container-gutter-phone); }
|
||||
section { padding-block: var(--section-y-phone); }
|
||||
}
|
||||
|
||||
/* ─── Typography — Feather Bold @ 800 across chrome ─────── */
|
||||
h1, h2, h3 {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 800;
|
||||
line-height: var(--leading-tight);
|
||||
margin: 0;
|
||||
color: var(--fg);
|
||||
}
|
||||
h1 {
|
||||
font-size: var(--text-4xl);
|
||||
letter-spacing: var(--tracking-display);
|
||||
line-height: 1.05;
|
||||
}
|
||||
h2 { font-size: var(--text-2xl); letter-spacing: -0.005em; }
|
||||
h3 { font-size: var(--text-lg); font-weight: 700; line-height: 1.25; }
|
||||
p { margin: 0; }
|
||||
.lead { font-size: var(--text-lg); color: var(--fg); line-height: var(--leading-body); }
|
||||
.body-muted { color: var(--muted); }
|
||||
.body-meta { color: var(--meta); }
|
||||
.body-sm { font-size: var(--text-sm); }
|
||||
.eyebrow {
|
||||
display: inline-block;
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-xs);
|
||||
color: var(--accent-active);
|
||||
background: color-mix(in oklab, var(--accent), transparent 82%);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
font-weight: 800;
|
||||
padding: var(--space-1) var(--space-3);
|
||||
border-radius: var(--radius-pill);
|
||||
}
|
||||
.stack-2 > * + * { margin-block-start: var(--space-2); }
|
||||
.stack-3 > * + * { margin-block-start: var(--space-3); }
|
||||
.stack-4 > * + * { margin-block-start: var(--space-4); }
|
||||
.stack-6 > * + * { margin-block-start: var(--space-6); }
|
||||
|
||||
/* ─── Buttons — chunky 4px bottom-shadow tactile press ──── */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--space-2);
|
||||
padding: 14px var(--space-6);
|
||||
border-radius: var(--radius-md);
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-base);
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
transition:
|
||||
background-color var(--motion-fast) var(--ease-standard),
|
||||
transform var(--motion-fast) var(--ease-standard),
|
||||
box-shadow var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
||||
|
||||
/* Primary — Owl Green with darker green underside */
|
||||
.btn-primary {
|
||||
background: var(--accent);
|
||||
color: var(--accent-on);
|
||||
box-shadow: 0 4px 0 var(--accent-active);
|
||||
}
|
||||
.btn-primary:hover { background: var(--accent-hover); }
|
||||
.btn-primary:active {
|
||||
transform: translateY(4px);
|
||||
box-shadow: 0 0 0 var(--accent-active);
|
||||
}
|
||||
|
||||
/* Secondary — White with neutral underside */
|
||||
.btn-secondary {
|
||||
background: var(--bg);
|
||||
color: var(--muted);
|
||||
border: 2px solid var(--border);
|
||||
box-shadow: 0 4px 0 var(--border);
|
||||
padding: 12px calc(var(--space-6) - 2px);
|
||||
}
|
||||
.btn-secondary:hover { color: var(--fg); border-color: var(--meta); }
|
||||
.btn-secondary:active {
|
||||
transform: translateY(4px);
|
||||
box-shadow: 0 0 0 var(--border);
|
||||
}
|
||||
|
||||
/* Streak — Bee Yellow with warm underside */
|
||||
.btn-streak {
|
||||
background: var(--warn);
|
||||
color: var(--fg);
|
||||
box-shadow: 0 4px 0 color-mix(in oklab, var(--warn), black 18%);
|
||||
}
|
||||
.btn-streak:hover { background: color-mix(in oklab, var(--warn), white 8%); }
|
||||
.btn-streak:active {
|
||||
transform: translateY(4px);
|
||||
box-shadow: 0 0 0 color-mix(in oklab, var(--warn), black 18%);
|
||||
}
|
||||
|
||||
/* ─── Inputs — thick borders, soft eel-blue focus glow ─── */
|
||||
.field { display: flex; flex-direction: column; gap: var(--space-2); }
|
||||
.field label {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-sm);
|
||||
font-weight: 800;
|
||||
color: var(--fg);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
.field input {
|
||||
padding: 14px var(--space-4);
|
||||
border-radius: var(--radius-sm);
|
||||
border: 2px solid var(--border);
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
outline: none;
|
||||
transition:
|
||||
border-color var(--motion-fast) var(--ease-standard),
|
||||
box-shadow var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
.field input::placeholder { color: var(--meta); }
|
||||
.field input:hover { border-color: var(--meta); }
|
||||
.field input:focus-visible {
|
||||
border-color: var(--accent);
|
||||
box-shadow: var(--focus-ring);
|
||||
}
|
||||
.field-help { font-size: var(--text-xs); color: var(--muted); }
|
||||
|
||||
/* ─── Cards / Lesson tiles — chunky offset shadow ───────── */
|
||||
.card {
|
||||
background: var(--bg);
|
||||
border: 2px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-6);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
box-shadow: var(--elev-raised);
|
||||
transition:
|
||||
transform var(--motion-fast) var(--ease-standard),
|
||||
box-shadow var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 0 #d7d7d7;
|
||||
}
|
||||
.card-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: var(--radius-pill);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--accent-on);
|
||||
font-family: var(--font-display);
|
||||
font-weight: 800;
|
||||
font-size: var(--text-xl);
|
||||
box-shadow: 0 3px 0 color-mix(in oklab, currentColor, black 22%);
|
||||
}
|
||||
.card-icon-green { background: var(--accent); }
|
||||
.card-icon-red { background: var(--danger); }
|
||||
.card-icon-yellow { background: var(--warn); color: var(--fg); }
|
||||
|
||||
/* ─── Badges + chips ────────────────────────────────────── */
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-1) var(--space-3);
|
||||
border-radius: var(--radius-pill);
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1.6;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.badge-success { color: var(--accent-on); background: var(--success); }
|
||||
.badge-streak { color: var(--fg); background: var(--warn); }
|
||||
.badge-muted { color: var(--muted); background: var(--surface); border: 2px solid var(--border); }
|
||||
.badge-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
|
||||
|
||||
/* ─── Progress bar ──────────────────────────────────────── */
|
||||
.progress {
|
||||
position: relative;
|
||||
background: var(--border);
|
||||
border-radius: var(--radius-pill);
|
||||
height: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress > .progress-fill {
|
||||
height: 100%;
|
||||
width: 64%;
|
||||
background: var(--accent);
|
||||
border-radius: var(--radius-pill);
|
||||
box-shadow: inset 0 -4px 0 var(--accent-active);
|
||||
}
|
||||
|
||||
/* ─── Mascot panel ──────────────────────────────────────── */
|
||||
.mascot-card {
|
||||
background: var(--surface);
|
||||
border: 2px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-6);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
box-shadow: var(--elev-raised);
|
||||
}
|
||||
.mascot-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
.mascot-svg {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
flex-shrink: 0;
|
||||
filter: drop-shadow(0 3px 0 var(--accent-active));
|
||||
}
|
||||
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
|
||||
|
||||
/* ─── Links + kbd ───────────────────────────────────────── */
|
||||
a { color: var(--accent-active); text-decoration: none; font-weight: 700; }
|
||||
a:hover { text-decoration: underline; text-underline-offset: 3px; }
|
||||
kbd {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-xs);
|
||||
padding: 2px var(--space-2);
|
||||
border-radius: var(--radius-sm);
|
||||
border: 2px solid var(--border);
|
||||
background: var(--bg);
|
||||
color: var(--muted);
|
||||
box-shadow: 0 2px 0 var(--border);
|
||||
}
|
||||
|
||||
/* ─── Layout helpers ────────────────────────────────────── */
|
||||
.hero-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 1fr;
|
||||
gap: var(--space-12);
|
||||
align-items: center;
|
||||
}
|
||||
@media (max-width: 1023px) {
|
||||
.hero-grid { grid-template-columns: 1fr; gap: var(--space-8); }
|
||||
}
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
margin-block-start: var(--space-6);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: var(--space-5);
|
||||
}
|
||||
@media (max-width: 1023px) { .features-grid { grid-template-columns: 1fr 1fr; } }
|
||||
@media (max-width: 639px) { .features-grid { grid-template-columns: 1fr; } }
|
||||
.form-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 1fr;
|
||||
gap: var(--space-12);
|
||||
align-items: start;
|
||||
}
|
||||
@media (max-width: 1023px) { .form-row { grid-template-columns: 1fr; } }
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
max-width: 420px;
|
||||
background: var(--bg);
|
||||
border: 2px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-6);
|
||||
box-shadow: var(--elev-raised);
|
||||
}
|
||||
.form-actions { display: flex; gap: var(--space-3); margin-block-start: var(--space-2); }
|
||||
.icon { width: 18px; height: 18px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<section data-od-id="hero">
|
||||
<div class="hero-grid">
|
||||
<div class="stack-6">
|
||||
<span class="eyebrow">Reference fixture · duolingo</span>
|
||||
<div class="stack-4">
|
||||
<h1>Free language learning for the world.</h1>
|
||||
<p class="lead" style="max-width: 48ch">
|
||||
15 minutes a day can teach you a language. Practice with bite-sized lessons,
|
||||
keep your streak alive, and let Duo the owl cheer you on every step of the way.
|
||||
</p>
|
||||
</div>
|
||||
<div class="hero-actions">
|
||||
<a href="./tokens.css" class="btn btn-primary">
|
||||
Get started — it's free
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="3"
|
||||
stroke-linecap="round" stroke-linejoin="round"
|
||||
aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
|
||||
</a>
|
||||
<a href="./DESIGN.md" class="btn btn-secondary">I already have an account</a>
|
||||
</div>
|
||||
</div>
|
||||
<aside class="mascot-card" aria-label="Today's lesson">
|
||||
<div class="mascot-row">
|
||||
<svg class="mascot-svg" viewBox="0 0 96 96" aria-hidden="true">
|
||||
<ellipse cx="48" cy="58" rx="34" ry="32" fill="var(--accent)"/>
|
||||
<ellipse cx="48" cy="58" rx="22" ry="22" fill="color-mix(in oklab, var(--accent), white 22%)"/>
|
||||
<circle cx="36" cy="46" r="9" fill="#ffffff"/>
|
||||
<circle cx="60" cy="46" r="9" fill="#ffffff"/>
|
||||
<circle cx="36" cy="48" r="4.5" fill="var(--fg)"/>
|
||||
<circle cx="60" cy="48" r="4.5" fill="var(--fg)"/>
|
||||
<circle cx="34.5" cy="46.5" r="1.6" fill="#ffffff"/>
|
||||
<circle cx="58.5" cy="46.5" r="1.6" fill="#ffffff"/>
|
||||
<path d="M40 60 L48 67 L56 60 Z" fill="var(--warn)"/>
|
||||
<path d="M22 32 Q30 18 42 26" fill="none" stroke="var(--accent-active)" stroke-width="6" stroke-linecap="round"/>
|
||||
<path d="M74 32 Q66 18 54 26" fill="none" stroke="var(--accent-active)" stroke-width="6" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<div class="stack-2">
|
||||
<h3>Spanish · Unit 3</h3>
|
||||
<p class="body-sm body-muted">Order food at the café</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stack-2">
|
||||
<div class="row-between">
|
||||
<span class="body-sm" style="font-family: var(--font-display); font-weight: 800">Lesson progress</span>
|
||||
<span class="body-sm" style="color: var(--muted)">3 / 5 crowns</span>
|
||||
</div>
|
||||
<div class="progress" aria-label="Lesson progress 64%">
|
||||
<div class="progress-fill"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-between">
|
||||
<span class="badge badge-streak">
|
||||
<span class="badge-dot" aria-hidden="true"></span>
|
||||
14 day streak
|
||||
</span>
|
||||
<span class="body-sm" style="color: var(--muted)">+15 XP today</span>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section data-od-id="features">
|
||||
<div class="stack-3">
|
||||
<span class="eyebrow">What this fixture exercises</span>
|
||||
<h2 style="max-width: 22ch">Joy is the curriculum.</h2>
|
||||
<p class="body-muted" style="max-width: 56ch">
|
||||
Every surface is built for the next correct answer — green to celebrate,
|
||||
chunky shadows to invite the press, and Duo waiting on the other side.
|
||||
</p>
|
||||
</div>
|
||||
<div class="features-grid" style="margin-block-start: var(--space-8)">
|
||||
<article class="card">
|
||||
<span class="card-icon card-icon-green" aria-hidden="true">✓</span>
|
||||
<h3>Owl green throughout</h3>
|
||||
<p class="body-muted body-sm">
|
||||
--accent (#58cc02) covers 30%+ of every screen. Primary CTA, correct
|
||||
answer, progress fill — they're all the same affirming green.
|
||||
</p>
|
||||
<a href="./tokens.css" class="body-sm">Inspect tokens →</a>
|
||||
</article>
|
||||
<article class="card">
|
||||
<span class="card-icon card-icon-yellow" aria-hidden="true">★</span>
|
||||
<h3>Tactile 4px shadow</h3>
|
||||
<p class="body-muted body-sm">
|
||||
--elev-raised drops a hard 4px offset under every button. On :active
|
||||
we translateY(4px) and zero the shadow — the button literally presses.
|
||||
</p>
|
||||
<a href="./DESIGN.md" class="body-sm">Read the rule →</a>
|
||||
</article>
|
||||
<article class="card">
|
||||
<span class="card-icon card-icon-red" aria-hidden="true">!</span>
|
||||
<h3>Big confident type</h3>
|
||||
<p class="body-muted body-sm">
|
||||
--text-4xl (56px) is +25% over typical product brands. Feather Bold at
|
||||
800 is the default — we never whisper, we never apologize for size.
|
||||
</p>
|
||||
<a href="./tokens.css" class="body-sm">Inspect ladder →</a>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section data-od-id="form">
|
||||
<div class="form-row">
|
||||
<div class="stack-4">
|
||||
<span class="eyebrow">Start your streak</span>
|
||||
<h2>One inbox is all it takes.</h2>
|
||||
<p class="body-muted" style="max-width: 48ch">
|
||||
We'll send a friendly nudge when Duo notices you missed a day. No tricks,
|
||||
no spam — just the kind of gentle accountability that turns 15 minutes
|
||||
into a year-long habit.
|
||||
</p>
|
||||
<p class="body-meta body-sm">
|
||||
Press <kbd>⌘</kbd> <kbd>K</kbd> to search the lesson library.
|
||||
</p>
|
||||
</div>
|
||||
<form class="form" onsubmit="event.preventDefault();">
|
||||
<div class="field">
|
||||
<label for="email">Email</label>
|
||||
<input id="email" type="email" placeholder="[email protected]" autocomplete="email" required />
|
||||
<p class="field-help">Free forever · 600M+ learners worldwide</p>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Create account</button>
|
||||
<button type="button" class="btn btn-secondary">Sign in</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,532 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"brandId": "duolingo",
|
||||
"source": {
|
||||
"componentsHtml": "components.html",
|
||||
"tokensCss": "tokens.css"
|
||||
},
|
||||
"fixture": {
|
||||
"title": "Duolingo — reference components",
|
||||
"description": "Reference fixture for design-systems/duolingo. Owl-green gamified universe, chunky 4px tactile shadows, big confident type, friendly pill geometry.",
|
||||
"styleBlockCount": 1,
|
||||
"selectorCount": 66,
|
||||
"classCount": 36,
|
||||
"elementCount": 26
|
||||
},
|
||||
"tokens": {
|
||||
"declared": [
|
||||
"--accent",
|
||||
"--accent-active",
|
||||
"--accent-hover",
|
||||
"--accent-on",
|
||||
"--bg",
|
||||
"--border",
|
||||
"--border-soft",
|
||||
"--container-gutter-desktop",
|
||||
"--container-gutter-phone",
|
||||
"--container-gutter-tablet",
|
||||
"--container-max",
|
||||
"--danger",
|
||||
"--ease-standard",
|
||||
"--elev-flat",
|
||||
"--elev-raised",
|
||||
"--elev-ring",
|
||||
"--fg",
|
||||
"--fg-2",
|
||||
"--focus-ring",
|
||||
"--font-body",
|
||||
"--font-display",
|
||||
"--font-mono",
|
||||
"--leading-body",
|
||||
"--leading-tight",
|
||||
"--meta",
|
||||
"--motion-base",
|
||||
"--motion-fast",
|
||||
"--muted",
|
||||
"--radius-lg",
|
||||
"--radius-md",
|
||||
"--radius-pill",
|
||||
"--radius-sm",
|
||||
"--section-y-desktop",
|
||||
"--section-y-phone",
|
||||
"--section-y-tablet",
|
||||
"--space-1",
|
||||
"--space-12",
|
||||
"--space-2",
|
||||
"--space-3",
|
||||
"--space-4",
|
||||
"--space-5",
|
||||
"--space-6",
|
||||
"--space-8",
|
||||
"--success",
|
||||
"--surface",
|
||||
"--surface-warm",
|
||||
"--text-2xl",
|
||||
"--text-3xl",
|
||||
"--text-4xl",
|
||||
"--text-base",
|
||||
"--text-lg",
|
||||
"--text-sm",
|
||||
"--text-xl",
|
||||
"--text-xs",
|
||||
"--tracking-display",
|
||||
"--warn"
|
||||
],
|
||||
"referenced": [
|
||||
"--accent",
|
||||
"--accent-active",
|
||||
"--accent-hover",
|
||||
"--accent-on",
|
||||
"--bg",
|
||||
"--border",
|
||||
"--container-gutter-desktop",
|
||||
"--container-gutter-phone",
|
||||
"--container-gutter-tablet",
|
||||
"--container-max",
|
||||
"--danger",
|
||||
"--ease-standard",
|
||||
"--elev-raised",
|
||||
"--fg",
|
||||
"--focus-ring",
|
||||
"--font-body",
|
||||
"--font-display",
|
||||
"--font-mono",
|
||||
"--leading-body",
|
||||
"--leading-tight",
|
||||
"--meta",
|
||||
"--motion-fast",
|
||||
"--muted",
|
||||
"--radius-lg",
|
||||
"--radius-md",
|
||||
"--radius-pill",
|
||||
"--radius-sm",
|
||||
"--section-y-desktop",
|
||||
"--section-y-phone",
|
||||
"--section-y-tablet",
|
||||
"--space-1",
|
||||
"--space-12",
|
||||
"--space-2",
|
||||
"--space-3",
|
||||
"--space-4",
|
||||
"--space-5",
|
||||
"--space-6",
|
||||
"--space-8",
|
||||
"--success",
|
||||
"--surface",
|
||||
"--text-2xl",
|
||||
"--text-4xl",
|
||||
"--text-base",
|
||||
"--text-lg",
|
||||
"--text-sm",
|
||||
"--text-xl",
|
||||
"--text-xs",
|
||||
"--tracking-display",
|
||||
"--warn"
|
||||
],
|
||||
"unusedDeclared": [
|
||||
"--border-soft",
|
||||
"--elev-flat",
|
||||
"--elev-ring",
|
||||
"--fg-2",
|
||||
"--motion-base",
|
||||
"--surface-warm",
|
||||
"--text-3xl"
|
||||
],
|
||||
"undeclaredReferenced": []
|
||||
},
|
||||
"selectors": [
|
||||
".badge",
|
||||
".badge-dot",
|
||||
".badge-muted",
|
||||
".badge-streak",
|
||||
".badge-success",
|
||||
".body-meta",
|
||||
".body-muted",
|
||||
".body-sm",
|
||||
".btn",
|
||||
".btn-primary",
|
||||
".btn-primary:active",
|
||||
".btn-primary:hover",
|
||||
".btn-secondary",
|
||||
".btn-secondary:active",
|
||||
".btn-secondary:hover",
|
||||
".btn-streak",
|
||||
".btn-streak:active",
|
||||
".btn-streak:hover",
|
||||
".btn:focus-visible",
|
||||
".card",
|
||||
".card-icon",
|
||||
".card-icon-green",
|
||||
".card-icon-red",
|
||||
".card-icon-yellow",
|
||||
".card:hover",
|
||||
".container",
|
||||
".eyebrow",
|
||||
".features-grid",
|
||||
".field",
|
||||
".field input",
|
||||
".field input::placeholder",
|
||||
".field input:focus-visible",
|
||||
".field input:hover",
|
||||
".field label",
|
||||
".field-help",
|
||||
".form",
|
||||
".form-actions",
|
||||
".form-row",
|
||||
".hero-actions",
|
||||
".hero-grid",
|
||||
".icon",
|
||||
".lead",
|
||||
".mascot-card",
|
||||
".mascot-row",
|
||||
".mascot-svg",
|
||||
".progress",
|
||||
".progress > .progress-fill",
|
||||
".row-between",
|
||||
".stack-2 > * + *",
|
||||
".stack-3 > * + *",
|
||||
".stack-4 > * + *",
|
||||
".stack-6 > * + *",
|
||||
"*",
|
||||
"*::after",
|
||||
"*::before",
|
||||
"a",
|
||||
"a:hover",
|
||||
"body",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"html",
|
||||
"kbd",
|
||||
"p",
|
||||
"section",
|
||||
"section + section"
|
||||
],
|
||||
"classes": [
|
||||
"badge",
|
||||
"badge-dot",
|
||||
"badge-streak",
|
||||
"body-meta",
|
||||
"body-muted",
|
||||
"body-sm",
|
||||
"btn",
|
||||
"btn-primary",
|
||||
"btn-secondary",
|
||||
"card",
|
||||
"card-icon",
|
||||
"card-icon-green",
|
||||
"card-icon-red",
|
||||
"card-icon-yellow",
|
||||
"container",
|
||||
"eyebrow",
|
||||
"features-grid",
|
||||
"field",
|
||||
"field-help",
|
||||
"form",
|
||||
"form-actions",
|
||||
"form-row",
|
||||
"hero-actions",
|
||||
"hero-grid",
|
||||
"icon",
|
||||
"lead",
|
||||
"mascot-card",
|
||||
"mascot-row",
|
||||
"mascot-svg",
|
||||
"progress",
|
||||
"progress-fill",
|
||||
"row-between",
|
||||
"stack-2",
|
||||
"stack-3",
|
||||
"stack-4",
|
||||
"stack-6"
|
||||
],
|
||||
"elements": [
|
||||
"a",
|
||||
"article",
|
||||
"aside",
|
||||
"body",
|
||||
"button",
|
||||
"circle",
|
||||
"div",
|
||||
"ellipse",
|
||||
"form",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"head",
|
||||
"html",
|
||||
"input",
|
||||
"kbd",
|
||||
"label",
|
||||
"main",
|
||||
"meta",
|
||||
"p",
|
||||
"path",
|
||||
"section",
|
||||
"span",
|
||||
"style",
|
||||
"svg",
|
||||
"title"
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"id": "buttons",
|
||||
"label": "Buttons and calls to action",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".btn",
|
||||
".btn-primary",
|
||||
".btn-primary:active",
|
||||
".btn-primary:hover",
|
||||
".btn-secondary",
|
||||
".btn-secondary:active",
|
||||
".btn-secondary:hover",
|
||||
".btn-streak",
|
||||
".btn-streak:active",
|
||||
".btn-streak:hover",
|
||||
".btn:focus-visible"
|
||||
],
|
||||
"classes": [
|
||||
"btn",
|
||||
"btn-primary",
|
||||
"btn-secondary"
|
||||
],
|
||||
"elements": [
|
||||
"button"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--accent",
|
||||
"--accent-active",
|
||||
"--accent-on",
|
||||
"--ease-standard",
|
||||
"--fg",
|
||||
"--font-display",
|
||||
"--meta",
|
||||
"--motion-fast",
|
||||
"--radius-md",
|
||||
"--space-2",
|
||||
"--space-6",
|
||||
"--text-base",
|
||||
"--warn"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "inputs",
|
||||
"label": "Form fields and controls",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".field",
|
||||
".field input",
|
||||
".field input::placeholder",
|
||||
".field input:focus-visible",
|
||||
".field input:hover",
|
||||
".field label",
|
||||
".field-help"
|
||||
],
|
||||
"classes": [
|
||||
"field",
|
||||
"field-help",
|
||||
"form",
|
||||
"form-actions",
|
||||
"form-row"
|
||||
],
|
||||
"elements": [
|
||||
"form",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--accent",
|
||||
"--fg",
|
||||
"--focus-ring",
|
||||
"--font-display",
|
||||
"--meta",
|
||||
"--text-sm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cards",
|
||||
"label": "Cards and panels",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".card",
|
||||
".card-icon",
|
||||
".card-icon-green",
|
||||
".card-icon-red",
|
||||
".card-icon-yellow",
|
||||
".card:hover"
|
||||
],
|
||||
"classes": [
|
||||
"card",
|
||||
"card-icon",
|
||||
"card-icon-green",
|
||||
"card-icon-red",
|
||||
"card-icon-yellow"
|
||||
],
|
||||
"elements": [],
|
||||
"tokenReferences": [
|
||||
"--accent-on",
|
||||
"--bg",
|
||||
"--border",
|
||||
"--danger",
|
||||
"--ease-standard",
|
||||
"--elev-raised",
|
||||
"--font-display",
|
||||
"--motion-fast",
|
||||
"--radius-md",
|
||||
"--radius-pill",
|
||||
"--space-3",
|
||||
"--space-6",
|
||||
"--text-xl"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "badges",
|
||||
"label": "Badges, chips, and status labels",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".badge",
|
||||
".badge-dot",
|
||||
".badge-muted",
|
||||
".badge-streak",
|
||||
".badge-success"
|
||||
],
|
||||
"classes": [
|
||||
"badge",
|
||||
"badge-dot",
|
||||
"badge-streak"
|
||||
],
|
||||
"elements": [],
|
||||
"tokenReferences": [
|
||||
"--fg",
|
||||
"--font-display",
|
||||
"--radius-pill",
|
||||
"--space-1",
|
||||
"--space-2",
|
||||
"--space-3",
|
||||
"--text-xs",
|
||||
"--warn"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "links",
|
||||
"label": "Links and inline actions",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
"a",
|
||||
"a:hover"
|
||||
],
|
||||
"classes": [],
|
||||
"elements": [
|
||||
"a"
|
||||
],
|
||||
"tokenReferences": []
|
||||
},
|
||||
{
|
||||
"id": "keyboard",
|
||||
"label": "Keyboard hints",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
"kbd"
|
||||
],
|
||||
"classes": [],
|
||||
"elements": [
|
||||
"kbd"
|
||||
],
|
||||
"tokenReferences": []
|
||||
},
|
||||
{
|
||||
"id": "icons",
|
||||
"label": "Icon slots",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".icon"
|
||||
],
|
||||
"classes": [
|
||||
"icon"
|
||||
],
|
||||
"elements": [
|
||||
"svg"
|
||||
],
|
||||
"tokenReferences": []
|
||||
},
|
||||
{
|
||||
"id": "typography",
|
||||
"label": "Typography scale and text utilities",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".body-muted",
|
||||
".body-sm",
|
||||
".eyebrow",
|
||||
".lead",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3"
|
||||
],
|
||||
"classes": [
|
||||
"body-muted",
|
||||
"body-sm",
|
||||
"eyebrow",
|
||||
"lead"
|
||||
],
|
||||
"elements": [
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"p"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--fg",
|
||||
"--font-display",
|
||||
"--leading-tight",
|
||||
"--muted",
|
||||
"--text-2xl",
|
||||
"--text-sm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "layout",
|
||||
"label": "Layout primitives",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".container",
|
||||
".row-between",
|
||||
".stack-2 > * + *",
|
||||
".stack-3 > * + *",
|
||||
".stack-4 > * + *",
|
||||
".stack-6 > * + *",
|
||||
"section",
|
||||
"section + section"
|
||||
],
|
||||
"classes": [
|
||||
"container",
|
||||
"features-grid",
|
||||
"hero-grid",
|
||||
"row-between",
|
||||
"stack-2",
|
||||
"stack-3",
|
||||
"stack-4",
|
||||
"stack-6"
|
||||
],
|
||||
"elements": [
|
||||
"main",
|
||||
"section"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--border",
|
||||
"--container-gutter-desktop",
|
||||
"--container-gutter-phone",
|
||||
"--container-gutter-tablet",
|
||||
"--container-max",
|
||||
"--space-2",
|
||||
"--space-3",
|
||||
"--space-4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"literals": {
|
||||
"colorExpressions": 6,
|
||||
"pixelValues": 42,
|
||||
"hardcodedFontFamilies": 9
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,701 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"format": "od-design-tokens/v1",
|
||||
"contract": "TOKEN_SCHEMA",
|
||||
"generatedAt": "2026-06-06T00:00:00.000Z",
|
||||
"source": {
|
||||
"tokensCss": "tokens.css",
|
||||
"tokenContractReport": "source/token-contract.report.json"
|
||||
},
|
||||
"summary": {
|
||||
"totalTokens": 56,
|
||||
"declaredTokens": 56,
|
||||
"sourceBackedTokens": 56,
|
||||
"sourceBackedA1": 26,
|
||||
"fallbackTokens": 26,
|
||||
"aliasTokens": 3,
|
||||
"layerCounts": {
|
||||
"A1-identity": 8,
|
||||
"B-slot": 4,
|
||||
"A2": 26,
|
||||
"A1-structure": 18
|
||||
},
|
||||
"score": 100,
|
||||
"grade": "excellent",
|
||||
"recommendRebuild": false
|
||||
},
|
||||
"tokens": [
|
||||
{
|
||||
"name": "--bg",
|
||||
"value": "#ffffff",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --bg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:23"
|
||||
],
|
||||
"sourceName": "--bg"
|
||||
},
|
||||
{
|
||||
"name": "--surface",
|
||||
"value": "#f7f7f7",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:24"
|
||||
],
|
||||
"sourceName": "--surface"
|
||||
},
|
||||
{
|
||||
"name": "--surface-warm",
|
||||
"value": "var(--surface)",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface-warm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:25"
|
||||
],
|
||||
"sourceName": "--surface-warm"
|
||||
},
|
||||
{
|
||||
"name": "--fg",
|
||||
"value": "#3c3c3c",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:30"
|
||||
],
|
||||
"sourceName": "--fg"
|
||||
},
|
||||
{
|
||||
"name": "--fg-2",
|
||||
"value": "var(--fg)",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:31"
|
||||
],
|
||||
"sourceName": "--fg-2"
|
||||
},
|
||||
{
|
||||
"name": "--muted",
|
||||
"value": "#777777",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --muted; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:32"
|
||||
],
|
||||
"sourceName": "--muted"
|
||||
},
|
||||
{
|
||||
"name": "--meta",
|
||||
"value": "#afafaf",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --meta; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:33"
|
||||
],
|
||||
"sourceName": "--meta"
|
||||
},
|
||||
{
|
||||
"name": "--border",
|
||||
"value": "#e5e5e5",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:38"
|
||||
],
|
||||
"sourceName": "--border"
|
||||
},
|
||||
{
|
||||
"name": "--border-soft",
|
||||
"value": "var(--border)",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border-soft; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:39"
|
||||
],
|
||||
"sourceName": "--border-soft"
|
||||
},
|
||||
{
|
||||
"name": "--accent",
|
||||
"value": "#58cc02",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:44"
|
||||
],
|
||||
"sourceName": "--accent"
|
||||
},
|
||||
{
|
||||
"name": "--accent-on",
|
||||
"value": "#ffffff",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-on; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:45"
|
||||
],
|
||||
"sourceName": "--accent-on"
|
||||
},
|
||||
{
|
||||
"name": "--accent-hover",
|
||||
"value": "#89e219",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-hover; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:46"
|
||||
],
|
||||
"sourceName": "--accent-hover"
|
||||
},
|
||||
{
|
||||
"name": "--accent-active",
|
||||
"value": "#58a700",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-active; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:47"
|
||||
],
|
||||
"sourceName": "--accent-active"
|
||||
},
|
||||
{
|
||||
"name": "--success",
|
||||
"value": "#58cc02",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --success; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:52"
|
||||
],
|
||||
"sourceName": "--success"
|
||||
},
|
||||
{
|
||||
"name": "--warn",
|
||||
"value": "#ffc800",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --warn; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:53"
|
||||
],
|
||||
"sourceName": "--warn"
|
||||
},
|
||||
{
|
||||
"name": "--danger",
|
||||
"value": "#ff4b4b",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --danger; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:54"
|
||||
],
|
||||
"sourceName": "--danger"
|
||||
},
|
||||
{
|
||||
"name": "--font-display",
|
||||
"value": "\"Feather Bold\", \"DIN Round Pro\", \"Helvetica Neue\", sans-serif",
|
||||
"type": "fontFamily",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:59"
|
||||
],
|
||||
"sourceName": "--font-display"
|
||||
},
|
||||
{
|
||||
"name": "--font-body",
|
||||
"value": "\"Mona Sans\", \"Helvetica Neue\", system-ui, sans-serif",
|
||||
"type": "fontFamily",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:60"
|
||||
],
|
||||
"sourceName": "--font-body"
|
||||
},
|
||||
{
|
||||
"name": "--font-mono",
|
||||
"value": "\"JetBrains Mono\", ui-monospace, Menlo, Monaco, Consolas, monospace",
|
||||
"type": "fontFamily",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-mono; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:61"
|
||||
],
|
||||
"sourceName": "--font-mono"
|
||||
},
|
||||
{
|
||||
"name": "--text-xs",
|
||||
"value": "12px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xs; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:65"
|
||||
],
|
||||
"sourceName": "--text-xs"
|
||||
},
|
||||
{
|
||||
"name": "--text-sm",
|
||||
"value": "13px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:66"
|
||||
],
|
||||
"sourceName": "--text-sm"
|
||||
},
|
||||
{
|
||||
"name": "--text-base",
|
||||
"value": "15px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:67"
|
||||
],
|
||||
"sourceName": "--text-base"
|
||||
},
|
||||
{
|
||||
"name": "--text-lg",
|
||||
"value": "18px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:68"
|
||||
],
|
||||
"sourceName": "--text-lg"
|
||||
},
|
||||
{
|
||||
"name": "--text-xl",
|
||||
"value": "24px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:69"
|
||||
],
|
||||
"sourceName": "--text-xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-2xl",
|
||||
"value": "32px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-2xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:70"
|
||||
],
|
||||
"sourceName": "--text-2xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-3xl",
|
||||
"value": "40px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-3xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:71"
|
||||
],
|
||||
"sourceName": "--text-3xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-4xl",
|
||||
"value": "56px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-4xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:72"
|
||||
],
|
||||
"sourceName": "--text-4xl"
|
||||
},
|
||||
{
|
||||
"name": "--leading-body",
|
||||
"value": "1.5",
|
||||
"type": "number",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:74"
|
||||
],
|
||||
"sourceName": "--leading-body"
|
||||
},
|
||||
{
|
||||
"name": "--leading-tight",
|
||||
"value": "1.15",
|
||||
"type": "number",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-tight; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:75"
|
||||
],
|
||||
"sourceName": "--leading-tight"
|
||||
},
|
||||
{
|
||||
"name": "--tracking-display",
|
||||
"value": "-0.01em",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --tracking-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:76"
|
||||
],
|
||||
"sourceName": "--tracking-display"
|
||||
},
|
||||
{
|
||||
"name": "--space-1",
|
||||
"value": "4px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-1; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:80"
|
||||
],
|
||||
"sourceName": "--space-1"
|
||||
},
|
||||
{
|
||||
"name": "--space-2",
|
||||
"value": "8px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:81"
|
||||
],
|
||||
"sourceName": "--space-2"
|
||||
},
|
||||
{
|
||||
"name": "--space-3",
|
||||
"value": "12px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-3; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:82"
|
||||
],
|
||||
"sourceName": "--space-3"
|
||||
},
|
||||
{
|
||||
"name": "--space-4",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-4; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:83"
|
||||
],
|
||||
"sourceName": "--space-4"
|
||||
},
|
||||
{
|
||||
"name": "--space-5",
|
||||
"value": "20px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-5; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:84"
|
||||
],
|
||||
"sourceName": "--space-5"
|
||||
},
|
||||
{
|
||||
"name": "--space-6",
|
||||
"value": "24px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-6; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:85"
|
||||
],
|
||||
"sourceName": "--space-6"
|
||||
},
|
||||
{
|
||||
"name": "--space-8",
|
||||
"value": "32px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-8; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:86"
|
||||
],
|
||||
"sourceName": "--space-8"
|
||||
},
|
||||
{
|
||||
"name": "--space-12",
|
||||
"value": "48px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-12; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:87"
|
||||
],
|
||||
"sourceName": "--space-12"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-desktop",
|
||||
"value": "80px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:91"
|
||||
],
|
||||
"sourceName": "--section-y-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-tablet",
|
||||
"value": "56px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:92"
|
||||
],
|
||||
"sourceName": "--section-y-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-phone",
|
||||
"value": "40px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:93"
|
||||
],
|
||||
"sourceName": "--section-y-phone"
|
||||
},
|
||||
{
|
||||
"name": "--radius-sm",
|
||||
"value": "12px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:98"
|
||||
],
|
||||
"sourceName": "--radius-sm"
|
||||
},
|
||||
{
|
||||
"name": "--radius-md",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-md; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:99"
|
||||
],
|
||||
"sourceName": "--radius-md"
|
||||
},
|
||||
{
|
||||
"name": "--radius-lg",
|
||||
"value": "20px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:100"
|
||||
],
|
||||
"sourceName": "--radius-lg"
|
||||
},
|
||||
{
|
||||
"name": "--radius-pill",
|
||||
"value": "9999px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-pill; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:101"
|
||||
],
|
||||
"sourceName": "--radius-pill"
|
||||
},
|
||||
{
|
||||
"name": "--elev-flat",
|
||||
"value": "none",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-flat; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:107"
|
||||
],
|
||||
"sourceName": "--elev-flat"
|
||||
},
|
||||
{
|
||||
"name": "--elev-ring",
|
||||
"value": "0 0 0 2px var(--border)",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:108"
|
||||
],
|
||||
"sourceName": "--elev-ring"
|
||||
},
|
||||
{
|
||||
"name": "--elev-raised",
|
||||
"value": "0 4px 0 #d7d7d7",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-raised; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:109"
|
||||
],
|
||||
"sourceName": "--elev-raised"
|
||||
},
|
||||
{
|
||||
"name": "--focus-ring",
|
||||
"value": "0 0 0 3px rgba(28, 176, 246, 0.2)",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --focus-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:114"
|
||||
],
|
||||
"sourceName": "--focus-ring"
|
||||
},
|
||||
{
|
||||
"name": "--motion-fast",
|
||||
"value": "180ms",
|
||||
"type": "duration",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-fast; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:119"
|
||||
],
|
||||
"sourceName": "--motion-fast"
|
||||
},
|
||||
{
|
||||
"name": "--motion-base",
|
||||
"value": "320ms",
|
||||
"type": "duration",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:120"
|
||||
],
|
||||
"sourceName": "--motion-base"
|
||||
},
|
||||
{
|
||||
"name": "--ease-standard",
|
||||
"value": "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
||||
"type": "cubicBezier",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --ease-standard; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:121"
|
||||
],
|
||||
"sourceName": "--ease-standard"
|
||||
},
|
||||
{
|
||||
"name": "--container-max",
|
||||
"value": "1080px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-max; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:126"
|
||||
],
|
||||
"sourceName": "--container-max"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-desktop",
|
||||
"value": "24px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:127"
|
||||
],
|
||||
"sourceName": "--container-gutter-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-tablet",
|
||||
"value": "20px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:128"
|
||||
],
|
||||
"sourceName": "--container-gutter-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-phone",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:129"
|
||||
],
|
||||
"sourceName": "--container-gutter-phone"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"schemaVersion": "od-design-system-project/v1",
|
||||
"id": "duolingo",
|
||||
"name": "Duolingo",
|
||||
"category": "Productivity & SaaS",
|
||||
"description": "Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.",
|
||||
"source": {
|
||||
"type": "bundled",
|
||||
"origin": "OpenDesign curated bundled fixture"
|
||||
},
|
||||
"files": {
|
||||
"design": "DESIGN.md",
|
||||
"tokens": "tokens.css",
|
||||
"designTokens": "design-tokens.json",
|
||||
"tailwind": "tailwind-v4.css",
|
||||
"components": "components.html"
|
||||
},
|
||||
"usage": "USAGE.md",
|
||||
"componentsManifest": "components.manifest.json",
|
||||
"importMode": "normalized",
|
||||
"craft": {
|
||||
"applies": [],
|
||||
"suggested": [
|
||||
"color",
|
||||
"accessibility-baseline"
|
||||
],
|
||||
"exemptions": []
|
||||
},
|
||||
"preview": {
|
||||
"dir": "preview",
|
||||
"pages": [
|
||||
{
|
||||
"path": "preview/colors.html",
|
||||
"role": "colors",
|
||||
"title": "Colors"
|
||||
},
|
||||
{
|
||||
"path": "preview/typography.html",
|
||||
"role": "typography",
|
||||
"title": "Typography"
|
||||
},
|
||||
{
|
||||
"path": "preview/spacing.html",
|
||||
"role": "spacing",
|
||||
"title": "Spacing"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sourceFiles": {
|
||||
"evidence": "source/evidence.md",
|
||||
"tokens": "source/tokens.source.json",
|
||||
"report": "source/token-contract.report.json"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo colors</title>
|
||||
<link rel="stylesheet" href="../tokens.css" />
|
||||
<style>
|
||||
body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--font-body); }
|
||||
main { max-width: var(--container-max); margin: 0 auto; padding: var(--space-12) var(--space-6); }
|
||||
h1 { margin: 0 0 var(--space-6); font-family: var(--font-display); font-size: var(--text-2xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-4); }
|
||||
.swatch { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); overflow: hidden; box-shadow: var(--elev-ring); }
|
||||
.color { height: 88px; background: var(--value); }
|
||||
.meta { padding: var(--space-3); color: var(--muted); font-size: var(--text-sm); }
|
||||
strong { display: block; margin-bottom: var(--space-1); color: var(--fg); }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Color roles</h1>
|
||||
|
||||
<section class="grid">
|
||||
<article class="swatch" style="--value: var(--bg)"><div class="color"></div><div class="meta"><strong>Background</strong>--bg</div></article>
|
||||
<article class="swatch" style="--value: var(--surface)"><div class="color"></div><div class="meta"><strong>Surface</strong>--surface</div></article>
|
||||
<article class="swatch" style="--value: var(--fg)"><div class="color"></div><div class="meta"><strong>Foreground</strong>--fg</div></article>
|
||||
<article class="swatch" style="--value: var(--muted)"><div class="color"></div><div class="meta"><strong>Muted</strong>--muted</div></article>
|
||||
<article class="swatch" style="--value: var(--border)"><div class="color"></div><div class="meta"><strong>Border</strong>--border</div></article>
|
||||
<article class="swatch" style="--value: var(--accent)"><div class="color"></div><div class="meta"><strong>Accent</strong>--accent</div></article>
|
||||
<article class="swatch" style="--value: var(--success)"><div class="color"></div><div class="meta"><strong>Success</strong>--success</div></article>
|
||||
<article class="swatch" style="--value: var(--warn)"><div class="color"></div><div class="meta"><strong>Warning</strong>--warn</div></article>
|
||||
<article class="swatch" style="--value: var(--danger)"><div class="color"></div><div class="meta"><strong>Danger</strong>--danger</div></article>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo spacing</title>
|
||||
<link rel="stylesheet" href="../tokens.css" />
|
||||
<style>
|
||||
body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--font-body); }
|
||||
main { max-width: var(--container-max); margin: 0 auto; padding: var(--space-12) var(--space-6); }
|
||||
h1 { margin: 0 0 var(--space-6); font-family: var(--font-display); font-size: var(--text-2xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
|
||||
.stack { display: grid; gap: var(--space-3); margin-bottom: var(--space-8); }
|
||||
.row { display: grid; grid-template-columns: 120px 1fr; align-items: center; gap: var(--space-4); color: var(--muted); font-size: var(--text-sm); }
|
||||
.bar { height: var(--space-4); min-width: 2px; background: var(--accent); }
|
||||
.radii { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-4); }
|
||||
.radii article { min-height: 88px; display: grid; place-items: center; border: 1px solid var(--border); background: var(--surface); color: var(--fg-2); font-size: var(--text-sm); box-shadow: var(--elev-ring); }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Spacing and radius</h1>
|
||||
|
||||
<section class="stack">
|
||||
<div class="row"><span>--space-2</span><div class="bar" style="width: var(--space-2)"></div></div>
|
||||
<div class="row"><span>--space-4</span><div class="bar" style="width: var(--space-4)"></div></div>
|
||||
<div class="row"><span>--space-6</span><div class="bar" style="width: var(--space-6)"></div></div>
|
||||
<div class="row"><span>--space-8</span><div class="bar" style="width: var(--space-8)"></div></div>
|
||||
<div class="row"><span>--space-12</span><div class="bar" style="width: var(--space-12)"></div></div>
|
||||
</section>
|
||||
<section class="radii">
|
||||
<article style="border-radius: var(--radius-sm)">--radius-sm</article>
|
||||
<article style="border-radius: var(--radius-md)">--radius-md</article>
|
||||
<article style="border-radius: var(--radius-lg)">--radius-lg</article>
|
||||
<article style="border-radius: var(--radius-pill)">--radius-pill</article>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo typography</title>
|
||||
<link rel="stylesheet" href="../tokens.css" />
|
||||
<style>
|
||||
body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--font-body); }
|
||||
main { max-width: var(--container-max); margin: 0 auto; padding: var(--space-12) var(--space-6); }
|
||||
h1 { margin: 0 0 var(--space-6); font-family: var(--font-display); font-size: var(--text-2xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
|
||||
.type-stack { display: grid; gap: var(--space-4); max-width: 760px; }
|
||||
.eyebrow { margin: 0; color: var(--accent); font-size: var(--text-xs); letter-spacing: var(--tracking-display); text-transform: uppercase; }
|
||||
h2 { margin: 0; font-family: var(--font-display); font-size: var(--text-4xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
.lede { margin: 0; color: var(--fg-2); font-size: var(--text-lg); line-height: var(--leading-body); }
|
||||
.body { margin: 0; color: var(--muted); font-size: var(--text-base); line-height: var(--leading-body); }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Typography</h1>
|
||||
|
||||
<section class="type-stack">
|
||||
<p class="eyebrow">Productivity & SaaS</p>
|
||||
<h2>Display sample for Duolingo</h2>
|
||||
<p class="lede">Body rhythm, heading scale, and muted metadata all resolve through the committed token contract.</p>
|
||||
<p class="body">The preview intentionally uses only schema tokens so reviewers can confirm the package remains portable across OpenDesign artifacts.</p>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
# Duolingo Source Evidence
|
||||
|
||||
## Source Scope
|
||||
|
||||
This Design System 2.0 backfill is derived from the curated OpenDesign bundled fixture.
|
||||
It does not claim a fresh crawl of the original upstream brand repository or website.
|
||||
|
||||
## Included Fixture Files
|
||||
|
||||
- design-systems/duolingo/DESIGN.md
|
||||
- design-systems/duolingo/tokens.css
|
||||
- design-systems/duolingo/components.html
|
||||
|
||||
## Token Contract
|
||||
|
||||
`source/token-contract.report.json` maps every TOKEN_SCHEMA binding back to the committed `tokens.css` declaration line.
|
||||
`design-tokens.json` and `tailwind-v4.css` are derived outputs and should be regenerated from the report and token stylesheet rather than edited by hand.
|
||||
@@ -0,0 +1,641 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"contract": "TOKEN_SCHEMA",
|
||||
"generatedAt": "2026-06-06T00:00:00.000Z",
|
||||
"sourceScope": "open-design-bundled-fixture",
|
||||
"summary": {
|
||||
"totalTokens": 56,
|
||||
"declaredTokens": 56,
|
||||
"sourceBackedTokens": 56,
|
||||
"sourceBackedA1": 26,
|
||||
"fallbackTokens": 26,
|
||||
"aliasTokens": 3,
|
||||
"layerCounts": {
|
||||
"A1-identity": 8,
|
||||
"B-slot": 4,
|
||||
"A2": 26,
|
||||
"A1-structure": 18
|
||||
},
|
||||
"score": 100,
|
||||
"grade": "excellent",
|
||||
"recommendRebuild": false
|
||||
},
|
||||
"tokens": [
|
||||
{
|
||||
"name": "--bg",
|
||||
"layer": "A1-identity",
|
||||
"value": "#ffffff",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --bg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:23"
|
||||
],
|
||||
"sourceName": "--bg"
|
||||
},
|
||||
{
|
||||
"name": "--surface",
|
||||
"layer": "A1-identity",
|
||||
"value": "#f7f7f7",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:24"
|
||||
],
|
||||
"sourceName": "--surface"
|
||||
},
|
||||
{
|
||||
"name": "--surface-warm",
|
||||
"layer": "B-slot",
|
||||
"value": "var(--surface)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface-warm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:25"
|
||||
],
|
||||
"sourceName": "--surface-warm"
|
||||
},
|
||||
{
|
||||
"name": "--fg",
|
||||
"layer": "A1-identity",
|
||||
"value": "#3c3c3c",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:30"
|
||||
],
|
||||
"sourceName": "--fg"
|
||||
},
|
||||
{
|
||||
"name": "--fg-2",
|
||||
"layer": "B-slot",
|
||||
"value": "var(--fg)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:31"
|
||||
],
|
||||
"sourceName": "--fg-2"
|
||||
},
|
||||
{
|
||||
"name": "--muted",
|
||||
"layer": "A1-identity",
|
||||
"value": "#777777",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --muted; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:32"
|
||||
],
|
||||
"sourceName": "--muted"
|
||||
},
|
||||
{
|
||||
"name": "--meta",
|
||||
"layer": "B-slot",
|
||||
"value": "#afafaf",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --meta; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:33"
|
||||
],
|
||||
"sourceName": "--meta"
|
||||
},
|
||||
{
|
||||
"name": "--border",
|
||||
"layer": "A1-identity",
|
||||
"value": "#e5e5e5",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:38"
|
||||
],
|
||||
"sourceName": "--border"
|
||||
},
|
||||
{
|
||||
"name": "--border-soft",
|
||||
"layer": "B-slot",
|
||||
"value": "var(--border)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border-soft; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:39"
|
||||
],
|
||||
"sourceName": "--border-soft"
|
||||
},
|
||||
{
|
||||
"name": "--accent",
|
||||
"layer": "A1-identity",
|
||||
"value": "#58cc02",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:44"
|
||||
],
|
||||
"sourceName": "--accent"
|
||||
},
|
||||
{
|
||||
"name": "--accent-on",
|
||||
"layer": "A2",
|
||||
"value": "#ffffff",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-on; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:45"
|
||||
],
|
||||
"sourceName": "--accent-on"
|
||||
},
|
||||
{
|
||||
"name": "--accent-hover",
|
||||
"layer": "A2",
|
||||
"value": "#89e219",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-hover; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:46"
|
||||
],
|
||||
"sourceName": "--accent-hover"
|
||||
},
|
||||
{
|
||||
"name": "--accent-active",
|
||||
"layer": "A2",
|
||||
"value": "#58a700",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-active; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:47"
|
||||
],
|
||||
"sourceName": "--accent-active"
|
||||
},
|
||||
{
|
||||
"name": "--success",
|
||||
"layer": "A2",
|
||||
"value": "#58cc02",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --success; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:52"
|
||||
],
|
||||
"sourceName": "--success"
|
||||
},
|
||||
{
|
||||
"name": "--warn",
|
||||
"layer": "A2",
|
||||
"value": "#ffc800",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --warn; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:53"
|
||||
],
|
||||
"sourceName": "--warn"
|
||||
},
|
||||
{
|
||||
"name": "--danger",
|
||||
"layer": "A2",
|
||||
"value": "#ff4b4b",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --danger; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:54"
|
||||
],
|
||||
"sourceName": "--danger"
|
||||
},
|
||||
{
|
||||
"name": "--font-display",
|
||||
"layer": "A1-identity",
|
||||
"value": "\"Feather Bold\", \"DIN Round Pro\", \"Helvetica Neue\", sans-serif",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:59"
|
||||
],
|
||||
"sourceName": "--font-display"
|
||||
},
|
||||
{
|
||||
"name": "--font-body",
|
||||
"layer": "A1-identity",
|
||||
"value": "\"Mona Sans\", \"Helvetica Neue\", system-ui, sans-serif",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:60"
|
||||
],
|
||||
"sourceName": "--font-body"
|
||||
},
|
||||
{
|
||||
"name": "--font-mono",
|
||||
"layer": "A2",
|
||||
"value": "\"JetBrains Mono\", ui-monospace, Menlo, Monaco, Consolas, monospace",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-mono; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:61"
|
||||
],
|
||||
"sourceName": "--font-mono"
|
||||
},
|
||||
{
|
||||
"name": "--text-xs",
|
||||
"layer": "A1-structure",
|
||||
"value": "12px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xs; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:65"
|
||||
],
|
||||
"sourceName": "--text-xs"
|
||||
},
|
||||
{
|
||||
"name": "--text-sm",
|
||||
"layer": "A1-structure",
|
||||
"value": "13px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:66"
|
||||
],
|
||||
"sourceName": "--text-sm"
|
||||
},
|
||||
{
|
||||
"name": "--text-base",
|
||||
"layer": "A1-structure",
|
||||
"value": "15px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:67"
|
||||
],
|
||||
"sourceName": "--text-base"
|
||||
},
|
||||
{
|
||||
"name": "--text-lg",
|
||||
"layer": "A1-structure",
|
||||
"value": "18px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:68"
|
||||
],
|
||||
"sourceName": "--text-lg"
|
||||
},
|
||||
{
|
||||
"name": "--text-xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "24px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:69"
|
||||
],
|
||||
"sourceName": "--text-xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-2xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "32px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-2xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:70"
|
||||
],
|
||||
"sourceName": "--text-2xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-3xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "40px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-3xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:71"
|
||||
],
|
||||
"sourceName": "--text-3xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-4xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "56px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-4xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:72"
|
||||
],
|
||||
"sourceName": "--text-4xl"
|
||||
},
|
||||
{
|
||||
"name": "--leading-body",
|
||||
"layer": "A1-structure",
|
||||
"value": "1.5",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:74"
|
||||
],
|
||||
"sourceName": "--leading-body"
|
||||
},
|
||||
{
|
||||
"name": "--leading-tight",
|
||||
"layer": "A1-structure",
|
||||
"value": "1.15",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-tight; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:75"
|
||||
],
|
||||
"sourceName": "--leading-tight"
|
||||
},
|
||||
{
|
||||
"name": "--tracking-display",
|
||||
"layer": "A1-structure",
|
||||
"value": "-0.01em",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --tracking-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:76"
|
||||
],
|
||||
"sourceName": "--tracking-display"
|
||||
},
|
||||
{
|
||||
"name": "--space-1",
|
||||
"layer": "A2",
|
||||
"value": "4px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-1; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:80"
|
||||
],
|
||||
"sourceName": "--space-1"
|
||||
},
|
||||
{
|
||||
"name": "--space-2",
|
||||
"layer": "A2",
|
||||
"value": "8px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:81"
|
||||
],
|
||||
"sourceName": "--space-2"
|
||||
},
|
||||
{
|
||||
"name": "--space-3",
|
||||
"layer": "A2",
|
||||
"value": "12px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-3; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:82"
|
||||
],
|
||||
"sourceName": "--space-3"
|
||||
},
|
||||
{
|
||||
"name": "--space-4",
|
||||
"layer": "A2",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-4; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:83"
|
||||
],
|
||||
"sourceName": "--space-4"
|
||||
},
|
||||
{
|
||||
"name": "--space-5",
|
||||
"layer": "A2",
|
||||
"value": "20px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-5; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:84"
|
||||
],
|
||||
"sourceName": "--space-5"
|
||||
},
|
||||
{
|
||||
"name": "--space-6",
|
||||
"layer": "A2",
|
||||
"value": "24px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-6; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:85"
|
||||
],
|
||||
"sourceName": "--space-6"
|
||||
},
|
||||
{
|
||||
"name": "--space-8",
|
||||
"layer": "A2",
|
||||
"value": "32px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-8; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:86"
|
||||
],
|
||||
"sourceName": "--space-8"
|
||||
},
|
||||
{
|
||||
"name": "--space-12",
|
||||
"layer": "A2",
|
||||
"value": "48px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-12; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:87"
|
||||
],
|
||||
"sourceName": "--space-12"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-desktop",
|
||||
"layer": "A1-structure",
|
||||
"value": "80px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:91"
|
||||
],
|
||||
"sourceName": "--section-y-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-tablet",
|
||||
"layer": "A1-structure",
|
||||
"value": "56px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:92"
|
||||
],
|
||||
"sourceName": "--section-y-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-phone",
|
||||
"layer": "A1-structure",
|
||||
"value": "40px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:93"
|
||||
],
|
||||
"sourceName": "--section-y-phone"
|
||||
},
|
||||
{
|
||||
"name": "--radius-sm",
|
||||
"layer": "A2",
|
||||
"value": "12px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:98"
|
||||
],
|
||||
"sourceName": "--radius-sm"
|
||||
},
|
||||
{
|
||||
"name": "--radius-md",
|
||||
"layer": "A2",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-md; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:99"
|
||||
],
|
||||
"sourceName": "--radius-md"
|
||||
},
|
||||
{
|
||||
"name": "--radius-lg",
|
||||
"layer": "A2",
|
||||
"value": "20px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:100"
|
||||
],
|
||||
"sourceName": "--radius-lg"
|
||||
},
|
||||
{
|
||||
"name": "--radius-pill",
|
||||
"layer": "A2",
|
||||
"value": "9999px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-pill; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:101"
|
||||
],
|
||||
"sourceName": "--radius-pill"
|
||||
},
|
||||
{
|
||||
"name": "--elev-flat",
|
||||
"layer": "A2",
|
||||
"value": "none",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-flat; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:107"
|
||||
],
|
||||
"sourceName": "--elev-flat"
|
||||
},
|
||||
{
|
||||
"name": "--elev-ring",
|
||||
"layer": "A2",
|
||||
"value": "0 0 0 2px var(--border)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:108"
|
||||
],
|
||||
"sourceName": "--elev-ring"
|
||||
},
|
||||
{
|
||||
"name": "--elev-raised",
|
||||
"layer": "A2",
|
||||
"value": "0 4px 0 #d7d7d7",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-raised; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:109"
|
||||
],
|
||||
"sourceName": "--elev-raised"
|
||||
},
|
||||
{
|
||||
"name": "--focus-ring",
|
||||
"layer": "A2",
|
||||
"value": "0 0 0 3px rgba(28, 176, 246, 0.2)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --focus-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:114"
|
||||
],
|
||||
"sourceName": "--focus-ring"
|
||||
},
|
||||
{
|
||||
"name": "--motion-fast",
|
||||
"layer": "A2",
|
||||
"value": "180ms",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-fast; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:119"
|
||||
],
|
||||
"sourceName": "--motion-fast"
|
||||
},
|
||||
{
|
||||
"name": "--motion-base",
|
||||
"layer": "A2",
|
||||
"value": "320ms",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:120"
|
||||
],
|
||||
"sourceName": "--motion-base"
|
||||
},
|
||||
{
|
||||
"name": "--ease-standard",
|
||||
"layer": "A2",
|
||||
"value": "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --ease-standard; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:121"
|
||||
],
|
||||
"sourceName": "--ease-standard"
|
||||
},
|
||||
{
|
||||
"name": "--container-max",
|
||||
"layer": "A1-structure",
|
||||
"value": "1080px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-max; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:126"
|
||||
],
|
||||
"sourceName": "--container-max"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-desktop",
|
||||
"layer": "A1-structure",
|
||||
"value": "24px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:127"
|
||||
],
|
||||
"sourceName": "--container-gutter-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-tablet",
|
||||
"layer": "A1-structure",
|
||||
"value": "20px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:128"
|
||||
],
|
||||
"sourceName": "--container-gutter-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-phone",
|
||||
"layer": "A1-structure",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:129"
|
||||
],
|
||||
"sourceName": "--container-gutter-phone"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"sourceScope": "open-design-bundled-fixture",
|
||||
"brandId": "duolingo",
|
||||
"files": [
|
||||
"DESIGN.md",
|
||||
"tokens.css",
|
||||
"components.html"
|
||||
],
|
||||
"generatedAt": "2026-06-06T00:00:00.000Z",
|
||||
"tokens": [
|
||||
{
|
||||
"name": "--bg",
|
||||
"value": "#ffffff",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:23"
|
||||
},
|
||||
{
|
||||
"name": "--surface",
|
||||
"value": "#f7f7f7",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:24"
|
||||
},
|
||||
{
|
||||
"name": "--surface-warm",
|
||||
"value": "var(--surface)",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:25"
|
||||
},
|
||||
{
|
||||
"name": "--fg",
|
||||
"value": "#3c3c3c",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:30"
|
||||
},
|
||||
{
|
||||
"name": "--fg-2",
|
||||
"value": "var(--fg)",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:31"
|
||||
},
|
||||
{
|
||||
"name": "--muted",
|
||||
"value": "#777777",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:32"
|
||||
},
|
||||
{
|
||||
"name": "--meta",
|
||||
"value": "#afafaf",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:33"
|
||||
},
|
||||
{
|
||||
"name": "--border",
|
||||
"value": "#e5e5e5",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:38"
|
||||
},
|
||||
{
|
||||
"name": "--border-soft",
|
||||
"value": "var(--border)",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:39"
|
||||
},
|
||||
{
|
||||
"name": "--accent",
|
||||
"value": "#58cc02",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:44"
|
||||
},
|
||||
{
|
||||
"name": "--accent-on",
|
||||
"value": "#ffffff",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:45"
|
||||
},
|
||||
{
|
||||
"name": "--accent-hover",
|
||||
"value": "#89e219",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:46"
|
||||
},
|
||||
{
|
||||
"name": "--accent-active",
|
||||
"value": "#58a700",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:47"
|
||||
},
|
||||
{
|
||||
"name": "--success",
|
||||
"value": "#58cc02",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:52"
|
||||
},
|
||||
{
|
||||
"name": "--warn",
|
||||
"value": "#ffc800",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:53"
|
||||
},
|
||||
{
|
||||
"name": "--danger",
|
||||
"value": "#ff4b4b",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:54"
|
||||
},
|
||||
{
|
||||
"name": "--font-display",
|
||||
"value": "\"Feather Bold\", \"DIN Round Pro\", \"Helvetica Neue\", sans-serif",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:59"
|
||||
},
|
||||
{
|
||||
"name": "--font-body",
|
||||
"value": "\"Mona Sans\", \"Helvetica Neue\", system-ui, sans-serif",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:60"
|
||||
},
|
||||
{
|
||||
"name": "--font-mono",
|
||||
"value": "\"JetBrains Mono\", ui-monospace, Menlo, Monaco, Consolas, monospace",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:61"
|
||||
},
|
||||
{
|
||||
"name": "--text-xs",
|
||||
"value": "12px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:65"
|
||||
},
|
||||
{
|
||||
"name": "--text-sm",
|
||||
"value": "13px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:66"
|
||||
},
|
||||
{
|
||||
"name": "--text-base",
|
||||
"value": "15px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:67"
|
||||
},
|
||||
{
|
||||
"name": "--text-lg",
|
||||
"value": "18px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:68"
|
||||
},
|
||||
{
|
||||
"name": "--text-xl",
|
||||
"value": "24px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:69"
|
||||
},
|
||||
{
|
||||
"name": "--text-2xl",
|
||||
"value": "32px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:70"
|
||||
},
|
||||
{
|
||||
"name": "--text-3xl",
|
||||
"value": "40px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:71"
|
||||
},
|
||||
{
|
||||
"name": "--text-4xl",
|
||||
"value": "56px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:72"
|
||||
},
|
||||
{
|
||||
"name": "--leading-body",
|
||||
"value": "1.5",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:74"
|
||||
},
|
||||
{
|
||||
"name": "--leading-tight",
|
||||
"value": "1.15",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:75"
|
||||
},
|
||||
{
|
||||
"name": "--tracking-display",
|
||||
"value": "-0.01em",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:76"
|
||||
},
|
||||
{
|
||||
"name": "--space-1",
|
||||
"value": "4px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:80"
|
||||
},
|
||||
{
|
||||
"name": "--space-2",
|
||||
"value": "8px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:81"
|
||||
},
|
||||
{
|
||||
"name": "--space-3",
|
||||
"value": "12px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:82"
|
||||
},
|
||||
{
|
||||
"name": "--space-4",
|
||||
"value": "16px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:83"
|
||||
},
|
||||
{
|
||||
"name": "--space-5",
|
||||
"value": "20px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:84"
|
||||
},
|
||||
{
|
||||
"name": "--space-6",
|
||||
"value": "24px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:85"
|
||||
},
|
||||
{
|
||||
"name": "--space-8",
|
||||
"value": "32px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:86"
|
||||
},
|
||||
{
|
||||
"name": "--space-12",
|
||||
"value": "48px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:87"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-desktop",
|
||||
"value": "80px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:91"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-tablet",
|
||||
"value": "56px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:92"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-phone",
|
||||
"value": "40px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:93"
|
||||
},
|
||||
{
|
||||
"name": "--radius-sm",
|
||||
"value": "12px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:98"
|
||||
},
|
||||
{
|
||||
"name": "--radius-md",
|
||||
"value": "16px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:99"
|
||||
},
|
||||
{
|
||||
"name": "--radius-lg",
|
||||
"value": "20px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:100"
|
||||
},
|
||||
{
|
||||
"name": "--radius-pill",
|
||||
"value": "9999px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:101"
|
||||
},
|
||||
{
|
||||
"name": "--elev-flat",
|
||||
"value": "none",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:107"
|
||||
},
|
||||
{
|
||||
"name": "--elev-ring",
|
||||
"value": "0 0 0 2px var(--border)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:108"
|
||||
},
|
||||
{
|
||||
"name": "--elev-raised",
|
||||
"value": "0 4px 0 #d7d7d7",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:109"
|
||||
},
|
||||
{
|
||||
"name": "--focus-ring",
|
||||
"value": "0 0 0 3px rgba(28, 176, 246, 0.2)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:114"
|
||||
},
|
||||
{
|
||||
"name": "--motion-fast",
|
||||
"value": "180ms",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:119"
|
||||
},
|
||||
{
|
||||
"name": "--motion-base",
|
||||
"value": "320ms",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:120"
|
||||
},
|
||||
{
|
||||
"name": "--ease-standard",
|
||||
"value": "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:121"
|
||||
},
|
||||
{
|
||||
"name": "--container-max",
|
||||
"value": "1080px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:126"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-desktop",
|
||||
"value": "24px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:127"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-tablet",
|
||||
"value": "20px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:128"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-phone",
|
||||
"value": "16px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:129"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - Pitch deck</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Deck module</p>
|
||||
<h1>Duolingo Executive deck</h1>
|
||||
<p class="lead">Slide-scale title, metric, and section patterns for presentation work.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Pitch deck</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Duolingo" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - Email</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Email module</p>
|
||||
<h1>Duolingo Email module</h1>
|
||||
<p class="lead">Transactional header, body copy, and primary call-to-action treatment.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Email</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Duolingo" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - Form page</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Form module</p>
|
||||
<h1>Duolingo Capture form</h1>
|
||||
<p class="lead">Input, selection, helper text, and submission states in one focused page.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Form page</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Duolingo" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - Landing page</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Landing module</p>
|
||||
<h1>Duolingo Launch narrative</h1>
|
||||
<p class="lead">Hero, proof points, and conversion actions composed from the design system tokens.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Landing page</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Duolingo" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - Newsletter</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Newsletter module</p>
|
||||
<h1>Duolingo Editorial issue</h1>
|
||||
<p class="lead">Readable long-form layout with heading hierarchy and compact story modules.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Newsletter</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Duolingo" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - Poster</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Poster module</p>
|
||||
<h1>Duolingo Campaign poster</h1>
|
||||
<p class="lead">High-impact display composition using the system color, type, and spacing rhythm.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Poster</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Duolingo" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,128 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - system assets</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<p class="eyebrow">Productivity & SaaS</p>
|
||||
<h1>Duolingo system assets</h1>
|
||||
<p class="lead">Generated preview modules for bundled official presets.</p>
|
||||
<section class="card-grid"><a class="card" href="kit.html"><h3>Component kit</h3><p>kit.html</p></a>
|
||||
<a class="card" href="kit.dark.html"><h3>Dark component kit</h3><p>kit.dark.html</p></a>
|
||||
<a class="card" href="artifacts/landing.html"><h3>Landing page</h3><p>artifacts/landing.html</p></a>
|
||||
<a class="card" href="artifacts/deck.html"><h3>Pitch deck</h3><p>artifacts/deck.html</p></a>
|
||||
<a class="card" href="artifacts/poster.html"><h3>Poster</h3><p>artifacts/poster.html</p></a>
|
||||
<a class="card" href="artifacts/email.html"><h3>Email</h3><p>artifacts/email.html</p></a>
|
||||
<a class="card" href="artifacts/newsletter.html"><h3>Newsletter</h3><p>artifacts/newsletter.html</p></a>
|
||||
<a class="card" href="artifacts/form.html"><h3>Form page</h3><p>artifacts/form.html</p></a></section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,149 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - dark component kit</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #0f1115;
|
||||
--od-surface: #171a21;
|
||||
--od-text: #f8fafc;
|
||||
--od-muted: #a7adba;
|
||||
--od-border: #2a2f3a;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #0b0b0b; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.32); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Productivity & SaaS system</p>
|
||||
<h1>Duolingo component kit</h1>
|
||||
<p class="lead">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Primary</a>
|
||||
<a class="button secondary" href="#">Default</a>
|
||||
<a class="button secondary" href="#">Dashed</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Reference module</p>
|
||||
<h3>Token-driven surface</h3>
|
||||
<div class="metric-grid">
|
||||
<div class="metric"><strong>12</strong><span>Components</span></div>
|
||||
<div class="metric"><strong>4</strong><span>States</span></div>
|
||||
<div class="metric"><strong>1</strong><span>Token contract</span></div>
|
||||
</div>
|
||||
<div class="chip-row">
|
||||
<span class="chip">Hover</span>
|
||||
<span class="chip">Focus</span>
|
||||
<span class="chip">Active</span>
|
||||
<span class="chip">Disabled</span>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<section class="card-grid" aria-label="Component examples">
|
||||
<article class="card"><h3>Buttons</h3><p>Primary, secondary, text, and destructive treatments resolve through shared color tokens.</p></article>
|
||||
<article class="card"><h3>Inputs</h3><p>Labels, helper text, and focus state use the same spacing and radius scale.</p></article>
|
||||
<article class="card"><h3>Cards</h3><p>Information modules keep elevation, border, and padding consistent across breakpoints.</p></article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,149 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Duolingo - component kit</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #58cc02;
|
||||
--accent-active: #58a700;
|
||||
--accent-hover: #89e219;
|
||||
--accent-on: #ffffff;
|
||||
--bg: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--border-soft: var(--border);
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-max: 1080px;
|
||||
--danger: #ff4b4b;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 4px 0 #d7d7d7;
|
||||
--elev-ring: 0 0 0 2px var(--border);
|
||||
--fg: #3c3c3c;
|
||||
--fg-2: var(--fg);
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15;
|
||||
--meta: #afafaf;
|
||||
--motion-base: 320ms;
|
||||
--motion-fast: 180ms;
|
||||
--muted: #777777;
|
||||
--radius-lg: 20px;
|
||||
--radius-md: 16px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 12px;
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-phone: 40px;
|
||||
--section-y-tablet: 56px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #58cc02;
|
||||
--surface: #f7f7f7;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 40px;
|
||||
--text-4xl: 56px;
|
||||
--text-base: 15px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 13px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: -0.01em;
|
||||
--warn: #ffc800;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #ffffff;
|
||||
--od-surface: #f7f7f7;
|
||||
--od-text: #3c3c3c;
|
||||
--od-muted: #777777;
|
||||
--od-border: #e5e5e5;
|
||||
--od-accent: #58cc02;
|
||||
--od-radius: 16px;
|
||||
--od-font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--od-font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Productivity & SaaS system</p>
|
||||
<h1>Duolingo component kit</h1>
|
||||
<p class="lead">Bundled OpenDesign package for Duolingo, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Primary</a>
|
||||
<a class="button secondary" href="#">Default</a>
|
||||
<a class="button secondary" href="#">Dashed</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Reference module</p>
|
||||
<h3>Token-driven surface</h3>
|
||||
<div class="metric-grid">
|
||||
<div class="metric"><strong>12</strong><span>Components</span></div>
|
||||
<div class="metric"><strong>4</strong><span>States</span></div>
|
||||
<div class="metric"><strong>1</strong><span>Token contract</span></div>
|
||||
</div>
|
||||
<div class="chip-row">
|
||||
<span class="chip">Hover</span>
|
||||
<span class="chip">Focus</span>
|
||||
<span class="chip">Active</span>
|
||||
<span class="chip">Disabled</span>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<section class="card-grid" aria-label="Component examples">
|
||||
<article class="card"><h3>Buttons</h3><p>Primary, secondary, text, and destructive treatments resolve through shared color tokens.</p></article>
|
||||
<article class="card"><h3>Inputs</h3><p>Labels, helper text, and focus state use the same spacing and radius scale.</p></article>
|
||||
<article class="card"><h3>Cards</h3><p>Information modules keep elevation, border, and padding consistent across breakpoints.</p></article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"colorPrimary": "#58cc02",
|
||||
"colorPrimaryBg": "var(--surface)",
|
||||
"colorPrimaryHover": "#89e219",
|
||||
"colorPrimaryActive": "#58a700",
|
||||
"fontSize": 15,
|
||||
"borderRadius": 16
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Derived from tokens.css. Keep tokens.css as the source of truth. */
|
||||
@import "tailwindcss";
|
||||
@import "./tokens.css";
|
||||
|
||||
@theme {
|
||||
--color-bg: var(--bg);
|
||||
--color-surface: var(--surface);
|
||||
--color-surface-warm: var(--surface-warm);
|
||||
--color-fg: var(--fg);
|
||||
--color-fg-2: var(--fg-2);
|
||||
--color-muted: var(--muted);
|
||||
--color-meta: var(--meta);
|
||||
--color-border: var(--border);
|
||||
--color-border-soft: var(--border-soft);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-on: var(--accent-on);
|
||||
--color-accent-hover: var(--accent-hover);
|
||||
--color-accent-active: var(--accent-active);
|
||||
--color-success: var(--success);
|
||||
--color-warn: var(--warn);
|
||||
--color-danger: var(--danger);
|
||||
--font-display: var(--font-display);
|
||||
--font-body: var(--font-body);
|
||||
--font-sans: var(--font-body);
|
||||
--font-mono: var(--font-mono);
|
||||
--text-xs: var(--text-xs);
|
||||
--text-sm: var(--text-sm);
|
||||
--text-base: var(--text-base);
|
||||
--text-lg: var(--text-lg);
|
||||
--text-xl: var(--text-xl);
|
||||
--text-2xl: var(--text-2xl);
|
||||
--text-3xl: var(--text-3xl);
|
||||
--text-4xl: var(--text-4xl);
|
||||
--leading-body: var(--leading-body);
|
||||
--leading-tight: var(--leading-tight);
|
||||
--tracking-display: var(--tracking-display);
|
||||
--spacing-1: var(--space-1);
|
||||
--spacing-2: var(--space-2);
|
||||
--spacing-3: var(--space-3);
|
||||
--spacing-4: var(--space-4);
|
||||
--spacing-5: var(--space-5);
|
||||
--spacing-6: var(--space-6);
|
||||
--spacing-8: var(--space-8);
|
||||
--spacing-12: var(--space-12);
|
||||
--spacing-section-desktop: var(--section-y-desktop);
|
||||
--spacing-section-tablet: var(--section-y-tablet);
|
||||
--spacing-section-phone: var(--section-y-phone);
|
||||
--radius-sm: var(--radius-sm);
|
||||
--radius-md: var(--radius-md);
|
||||
--radius-lg: var(--radius-lg);
|
||||
--radius-pill: var(--radius-pill);
|
||||
--shadow-flat: var(--elev-flat);
|
||||
--shadow-ring: var(--elev-ring);
|
||||
--shadow-raised: var(--elev-raised);
|
||||
--shadow-focus-ring: var(--focus-ring);
|
||||
--duration-fast: var(--motion-fast);
|
||||
--duration-base: var(--motion-base);
|
||||
--ease-standard: var(--ease-standard);
|
||||
--container-max: var(--container-max);
|
||||
--spacing-container-desktop: var(--container-gutter-desktop);
|
||||
--spacing-container-tablet: var(--container-gutter-tablet);
|
||||
--spacing-container-phone: var(--container-gutter-phone);
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/* ─────────────────────────────────────────────────────────────────────────
|
||||
* design-systems/duolingo/tokens.css
|
||||
*
|
||||
* Structured token bindings for "Design System Inspired by Duolingo".
|
||||
* Bright owl-green gamified universe: chunky 4px bottom-shadows, big
|
||||
* confident type, friendly pill geometry, mascot-driven warmth.
|
||||
*
|
||||
* Key brand decisions encoded here:
|
||||
* - Owl Green (#58cc02) — dominant brand color, primary CTA + correct answer
|
||||
* - Snow white canvas (#ffffff) — never tinted; optical clarity is the foundation
|
||||
* - 4px chunky offset shadow (--elev-raised) — the "tactile press" signature
|
||||
* - Feather Bold + Mona Sans — rounded display + Swiss workhorse body
|
||||
* - Display starts at 56px — Duolingo never whispers; size is identity
|
||||
* - Pill-and-rounded radii — 16px cards, 12px buttons/inputs, 9999px chips
|
||||
* - Spring easing (back-out, slight overshoot) — gamified joy in motion
|
||||
* - Eel-blue focus ring (#1cb0f6 tinted) — playful contrast to the green brand
|
||||
* ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
:root {
|
||||
/* ─── Surface ─────────────────────────────────────────────────────
|
||||
* Snow white canvas with Eel as the section-break tone. Pure optical
|
||||
* clarity — Duolingo never tints the page itself, only the chrome. */
|
||||
--bg: #ffffff; /* Snow — primary background, the page canvas */
|
||||
--surface: #f7f7f7; /* Eel — section break, secondary surface, lesson row */
|
||||
--surface-warm: var(--surface); /* alias — palette has no third (warm) surface tier */
|
||||
|
||||
/* ─── Foreground ──────────────────────────────────────────────────
|
||||
* Three real text tiers: Eel Black for primary, Wolf for secondary,
|
||||
* Hare for tertiary. Each tier carries clear, child-readable contrast. */
|
||||
--fg: #3c3c3c; /* Eel Black — primary text, headings, button labels */
|
||||
--fg-2: var(--fg); /* alias — single primary text weight throughout */
|
||||
--muted: #777777; /* Wolf — secondary text, captions, dividers */
|
||||
--meta: #afafaf; /* Hare — tertiary metadata, placeholder, disabled */
|
||||
|
||||
/* ─── Border ──────────────────────────────────────────────────────
|
||||
* Swan grey at thick 2–3px on most surfaces. Borders are visual,
|
||||
* never hairlines — they read as part of the chunky aesthetic. */
|
||||
--border: #e5e5e5; /* Swan — standard 2px border, card edge */
|
||||
--border-soft: var(--border); /* alias — single border tier (no inner-row separation) */
|
||||
|
||||
/* ─── Accent ──────────────────────────────────────────────────────
|
||||
* Owl Green — the brand IS this green. Used liberally in 30%+ of the
|
||||
* surface for buttons, progress bars, success states, brand chrome. */
|
||||
--accent: #58cc02;
|
||||
--accent-on: #ffffff;
|
||||
--accent-hover: #89e219; /* Owl Green Light — hover state, soft fills */
|
||||
--accent-active: #58a700; /* Owl Green Deep — pressed state, the chunky shadow color */
|
||||
|
||||
/* ─── Semantic ────────────────────────────────────────────────────
|
||||
* Success IS owl green — DESIGN.md: "primary CTA, correct answer" are
|
||||
* the same affordance. Bee Yellow warns; Cardinal Red marks wrong. */
|
||||
--success: #58cc02; /* Owl Green — "correct answer" is the brand */
|
||||
--warn: #ffc800; /* Bee Yellow — pro badge, achievement glow */
|
||||
--danger: #ff4b4b; /* Cardinal Red — wrong answer, life lost */
|
||||
|
||||
/* ─── Typography ──────────────────────────────────────────────────
|
||||
* Feather Bold (rounded display) drives chrome and headings; Mona Sans
|
||||
* carries body. Default weight is 800 — Duolingo never whispers. */
|
||||
--font-display: "Feather Bold", "DIN Round Pro", "Helvetica Neue", sans-serif;
|
||||
--font-body: "Mona Sans", "Helvetica Neue", system-ui, sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
||||
|
||||
/* Type scale — DESIGN.md §3. Display 56px is +25–40% above typical
|
||||
* product brands; the ladder favors round whole-pixel sizes. */
|
||||
--text-xs: 12px; /* Tiny utility, progress numerals */
|
||||
--text-sm: 13px; /* Caption — XP counter, metadata */
|
||||
--text-base: 15px; /* Body — standard prose */
|
||||
--text-lg: 18px; /* H3 / lesson row title / featured body */
|
||||
--text-xl: 24px; /* H2 — section heading */
|
||||
--text-2xl: 32px; /* H1 — page title */
|
||||
--text-3xl: 40px; /* Sub-display — hero secondary, marketing eyebrow */
|
||||
--text-4xl: 56px; /* Display — onboarding hero, never timid */
|
||||
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.15; /* Headings — slight breathing under big rounded faces */
|
||||
--tracking-display: -0.01em; /* ≈ -0.56px at 56px — confident, not condensed */
|
||||
|
||||
/* ─── Spacing ─────────────────────────────────────────────────────
|
||||
* 4px base unit (DESIGN.md §5): 4, 8, 12, 16, 20, 24, 32, 48. */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-12: 48px;
|
||||
|
||||
/* Section rhythm — generous on desktop, tight on phone so the lesson
|
||||
* tree column reads as a continuous flow rather than chunked pages. */
|
||||
--section-y-desktop: 80px;
|
||||
--section-y-tablet: 56px;
|
||||
--section-y-phone: 40px;
|
||||
|
||||
/* ─── Radius ──────────────────────────────────────────────────────
|
||||
* Pill-and-rounded everywhere. Cards 16px (DESIGN.md §4), buttons +
|
||||
* inputs 12px, chips and progress bars 9999px — friendly forever. */
|
||||
--radius-sm: 12px; /* Inputs, buttons — friendly compact corners */
|
||||
--radius-md: 16px; /* Cards, lesson tiles — primary signature */
|
||||
--radius-lg: 20px; /* Featured containers, modals */
|
||||
--radius-pill: 9999px; /* Chips, progress bars, avatars */
|
||||
|
||||
/* ─── Elevation ───────────────────────────────────────────────────
|
||||
* Chunky 4px bottom-shadow IS Duolingo. Buttons and cards cast a hard
|
||||
* offset shadow that reads as a 3D button waiting to be pressed. The
|
||||
* raised value pairs with translateY(4px) on :active to "press" it. */
|
||||
--elev-flat: none;
|
||||
--elev-ring: 0 0 0 2px var(--border); /* 2px ring matches the chunky border weight */
|
||||
--elev-raised: 0 4px 0 #d7d7d7; /* Hard tactile shadow — the press affordance */
|
||||
|
||||
/* ─── Focus ring ──────────────────────────────────────────────────
|
||||
* Eel Blue 20% tint (DESIGN.md §4 inputs) — playful contrast against
|
||||
* the ambient owl-green brand; signals "you can interact with this". */
|
||||
--focus-ring: 0 0 0 3px rgba(28, 176, 246, 0.2);
|
||||
|
||||
/* ─── Motion ──────────────────────────────────────────────────────
|
||||
* 180ms button press, 320ms skill-node unlock; back-out spring with
|
||||
* slight overshoot (DESIGN.md §6). Every state change feels gamified. */
|
||||
--motion-fast: 180ms;
|
||||
--motion-base: 320ms;
|
||||
--ease-standard: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
|
||||
/* ─── Layout ──────────────────────────────────────────────────────
|
||||
* 1080px container (DESIGN.md §5) — narrower than a SaaS deck because
|
||||
* Duolingo content reads vertically as a focused lesson tree column. */
|
||||
--container-max: 1080px;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-tablet: 20px;
|
||||
--container-gutter-phone: 16px;
|
||||
}
|
||||
Reference in new issue
Block a user