{{ highlight_task.title }}
+{{ highlight_task.description }}
+ {% if supporting_task %} +{{ supporting_task.title }}
+{{ supporting_task.description }}
+diff --git a/docs/ui-ux-implementation-todo.md b/docs/ui-ux-implementation-todo.md index 3dbe244..d2b4c67 100644 --- a/docs/ui-ux-implementation-todo.md +++ b/docs/ui-ux-implementation-todo.md @@ -1,64 +1,106 @@ -# Daftar To-Do Implementasi UI/UX Sensasiwangi.id +# Daftar To-Do Implementasi UI/UX Sensasiwangi.id (Versi Tanpa Figma) -Dokumen ini merinci langkah implementasi UI/UX dari fondasi desain ke dalam antarmuka yang siap dikembangkan. Urutan tugas disusun berdasarkan prioritas delivery MVP. +Dokumen ini memetakan pekerjaan UI/UX langsung ke artefak kode pada stack FastAPI + HTMX + Jinja2. Referensi visual utama menggunakan contoh mockup (glassmorphism futuristik) yang sudah diberikan, sehingga setiap tugas berfokus pada implementasi HTML/CSS/JS dan dokumentasi teknis tanpa perantara file desain. -## 1. Setup Desain & Sistem Komponen -- [ ] Siapkan file desain kolaboratif (Figma/penyunting setara) dengan gaya glassmorphism sesuai panduan foundation. -- [ ] Definisikan style guide global: warna, tipografi (Playfair Display & Inter), ukuran heading, dan states warna teks. -- [ ] Bangun library komponen dasar (button, card, input, badge, progress bar) lengkap dengan variasi state (default, hover, aktif, disabled). -- [ ] Buat auto-layout/grid responsif untuk breakpoint desktop, tablet, dan mobile. +Legenda status: ☐ belum mulai · ◐ in-progress · ✅ selesai. + +## 0. Panduan Visual & Prinsip Umum + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Kanvas inspirasi UI | Tangkap elemen kunci dari mockup (palet, tipografi serif+sans, bubble glass, refleksi) dan tuangkan ke dokumen panduan kode. Sertakan referensi ukuran dan behavior animasi dasar. | `docs/ui-style-reference.md` berisi moodboard singkat + token awal. | +| ☐ | Susun token desain berbasis CSS | Definisikan CSS custom properties untuk warna, radius, blur, shadow, gradient dan timing animasi sesuai mockup. Token dideklarasikan di `:root` dan dipublikasikan melalui `static/css/tokens.css`. | File `src/app/web/static/css/tokens.css` berisi token komprehensif. | +| ☐ | Setup tipografi & ikon | Implementasi font Playfair Display + Inter (atau alternatif open source mirip) via `@font-face`/Google Fonts, serta siapkan set ikon Feather/Phosphor yang akan dipakai. | Update `base.html` + `static/css/base.css` untuk import font & ikon. | + +## 1. Sistem Desain Berbasis Kode + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Utilitas glassmorphism | Buat kelas utilitas (mis. `.glass-card`, `.glass-panel`, `.blur-pill`) yang mengatur backdrop-filter, border, dan shadow sesuai inspirasi UI. | `static/css/glass.css` + dokumentasi pemakaian di `docs/ui-style-reference.md`. | +| ☐ | Komponen tombol & chip | Rancang varian tombol utama/sekunder/ghost serta chip filter dengan state hover/active menggunakan CSS variables & HTMX states. | Partial `templates/components/button.html` + CSS di `static/css/components/button.css`. | +| ☐ | Komponen kartu & badge status | Implementasikan kartu produk dengan preview gambar, badge sambatan, dan progress bar radial sesuai sample 3D. Sediakan versi horizontal dan grid. | `templates/components/product-card.html` + CSS & script animasi progress. | +| ☐ | Layout responsif dasar | Definisikan grid dan spacing untuk breakpoint desktop/tablet/mobile menggunakan CSS Grid/Flex. Sertakan helper kelas `container-xl`, `stack-lg` dsb. | `static/css/layout.css` + README singkat pada file yang sama. | ## 2. Navigasi & Struktur Global -- [ ] Rancang layout navbar sticky dengan versi desktop dan mobile (hamburger drawer). -- [ ] Definisikan struktur footer lengkap (CTA newsletter, tautan legal, sosial, highlight komunitas). -- [ ] Siapkan breadcrumb template untuk halaman dalam (Dashboard, Profil). + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Navbar sticky adaptif | Implementasikan navbar glass dengan menu utama, indikator halaman aktif, CTA login/signup, serta varian mobile (drawer). Gunakan HTMX untuk aksi open/close. | `templates/partials/navbar.html`, CSS di `static/css/components/navbar.css`, dan skrip `static/js/navbar.js`. | +| ☐ | Footer komunitas | Bangun footer dengan CTA newsletter, link legal, sosial, dan highlight komunitas. Pastikan layout stack rapi di mobile. | `templates/partials/footer.html` + CSS pendukung. | +| ☐ | Breadcrumb reusable | Buat component breadcrumb HTML dengan data-props Jinja (list tuple). Sediakan styling glass pill dan fallback mobile (horizontal scroll). | `templates/components/breadcrumb.html` + CSS. | ## 3. Halaman Prioritas MVP + ### 3.1 Landing Page / Marketplace Overview -- [ ] Desain hero section dengan headline, subcopy, CTA ganda, dan kartu statistik. -- [ ] Implementasikan tab kategori, filter kaca, search bar, dan sort chip. -- [ ] Buat grid produk responsif dengan states hover dan indikator sambatan (progress bar + deadline). -- [ ] Rancang carousel highlight Nusantarum. -- [ ] Bangun footer CTA komunitas + newsletter. + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Hero interaktif | Bangun hero dengan headline besar, subcopy, CTA ganda, slider produk unggulan dan latar bubble 3D (SVG atau Lottie). Sertakan animasi hover subtle. | `templates/pages/landing.html` (section hero) + asset di `static/media/hero`. | +| ☐ | Tab kategori & filter | Implementasikan tab + filter kaca menggunakan HTMX untuk swap konten tanpa reload. Sediakan chip active/hover, search bar, dan sort toggle. | Partial `templates/components/category-tabs.html` + JS `static/js/tabs.js`. | +| ☐ | Grid produk responsif | Layout grid dengan indikator sambatan (progress bar + deadline) dan varian card untuk desktop/tablet/mobile. Pastikan `aria` label lengkap. | Block pada landing.html + CSS di `components/product-grid.css`. | +| ☐ | Carousel highlight Nusantarum | Implementasikan carousel horizontal dengan pill navigation dan auto-play opsional menggunakan Swiper.js atau implementasi custom. | Partial `templates/components/story-carousel.html` + JS `static/js/carousel.js`. | +| ☐ | Footer CTA komunitas | Section CTA akhir dengan glass panel dan call-to-action bergaya mockup. | Section di landing.html + CSS section. | ### 3.2 Detail Produk -- [ ] Siapkan galeri foto dengan thumbnail dan view utama. -- [ ] Desain panel informasi produk (harga, stok, deskripsi aroma, CTA Sambatan/Pesanan). -- [ ] Buat modul info brand dan tautan cerita Nusantarum. -- [ ] Implementasikan panel sambatan (progress circle, slot tersisa, countdown, kontributor terbaru). -### 3.3 Dashboard Internal (Tim Ops) -- [ ] Susun layout dengan sidebar kaca dan konten utama. -- [ ] Definisikan header ringkasan metrik (kartu KPI). -- [ ] Buat tabel pesanan dengan filter status dan tombol ekspor. -- [ ] Desain panel drawer detail pesanan yang muncul saat baris dipilih. +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Galeri foto produk | Implementasikan viewer utama + thumbnail scroll dengan efek parallax ringan. Dukungan keyboard navigation dan fallback non-JS. | Partial `templates/components/product-gallery.html` + JS `static/js/gallery.js`. | +| ☐ | Panel informasi produk | Panel kanan berisi harga, stok, deskripsi aroma, CTA Sambatan/Pesanan dengan badge status. Pastikan sticky di desktop. | `templates/pages/product_detail.html` section info + CSS. | +| ☐ | Modul info brand | Kartu brand kaca dengan logo, sertifikasi, link Nusantarum, CTA follow. | Partial `templates/components/brand-module.html`. | +| ☐ | Panel sambatan | Komponen progress radial, slot tersisa, countdown realtime (menggunakan Stimulus/HTMX). Varian state aktif/penuh/tutup. | JS `static/js/sambatan-panel.js` + partial HTML & CSS. | + +### 3.3 Dashboard Internal (Ops) + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Layout dashboard | Sidebar kaca, topbar, dan konten utama responsif. Gunakan CSS Grid dua kolom + collapse mobile. | `templates/pages/dashboard/index.html` + CSS `static/css/dashboard.css`. | +| ☐ | Header metrik | Kartu KPI dengan gradient glow, icon, delta up/down. Animated counters optional. | Partial `templates/components/kpi-card.html` + JS kecil untuk animasi angka. | +| ☐ | Tabel pesanan | Tabel dengan filter status (tabs), tombol ekspor, empty state ilustrasi. Responsif via CSS `display: block` di mobile. | Partial `templates/components/order-table.html` + CSS/JS filter. | +| ☐ | Drawer detail pesanan | Drawer kanan yang muncul saat klik baris, menampilkan detail & log. Implementasi HTMX swap + overlay backdrop. | Template `templates/components/order-drawer.html` + JS `static/js/drawer.js`. | ### 3.4 Nusantarum Hub -- [ ] Desain hero kaca dengan headline kuratorial. -- [ ] Buat panel filter (kategori aroma, wilayah, kurator) untuk desktop & mobile. -- [ ] Rancang kartu cerita Nusantarum termasuk tag brand/perfumer. -- [ ] Siapkan CTA "Ajukan cerita" dengan state hover. + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Hero kuratorial | Hero kaca dengan headline, subcopy, CTA, background partikel (canvas/SVG). | Section `templates/pages/nusantarum.html` + asset. | +| ☐ | Panel filter multiplatform | Panel filter desktop + bottom sheet mobile (dialog). Gunakan CSS `position: sticky` dan HTMX update results. | `templates/components/nusantarum-filter.html` + JS `static/js/filter-sheet.js`. | +| ☐ | Kartu cerita | Kartu cerita dengan foto, tag brand/perfumer, CTA. Pastikan variant grid/list. | Partial `templates/components/story-card.html`. | +| ☐ | CTA ajukan cerita | Form CTA dengan state hover, disabled, dan note integrasi backend. | Section + CSS. | ### 3.5 Profil Pengguna -- [ ] Bangun header profil (avatar kaca, nama, preferensi aroma chip). -- [ ] Implementasikan tab Aktivitas, Favorit, Sambatan Saya. -- [ ] Desain timeline aktivitas dengan kartu kaca. -- [ ] Buat grid favorit dan daftar sambatan dengan indikator status. + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Header profil | Header kaca dengan avatar, nama, preferensi aroma chip, dan tombol edit. | Section `templates/pages/profile.html` + CSS. | +| ☐ | Tab aktivitas/favorit/sambatan | Tab berbasis HTMX untuk switch konten tanpa reload, dengan animasi underline. | `templates/components/profile-tabs.html` + JS `static/js/profile-tabs.js`. | +| ☐ | Timeline aktivitas | Komponen timeline card dengan icon status, timestamp, deskripsi. | Partial `templates/components/activity-card.html`. | +| ☐ | Grid favorit & daftar sambatan | Layout grid/list dengan status indicator & CTA lanjutkan. | Blocks di profile.html + CSS. | ## 4. Interaksi & Animasi -- [ ] Definisikan animasi hover umum (translateY -2px, glow border) dan timing function. -- [ ] Rancang transisi antar halaman (mis. fade-in + blur subtle) untuk menjaga kesan premium. -- [ ] Siapkan guideline microinteraction untuk tombol, progress bar, dan badge sambatan. -## 5. Aset & Dokumentasi Developer Handoff -- [ ] Export ikon Feather dengan gaya garis tipis + efek neon bila diperlukan. -- [ ] Siapkan placeholder foto produk/brand dengan kontainer kaca dan drop shadow. -- [ ] Dokumentasikan spesifikasi spacing, padding, dan shadow di setiap komponen. -- [ ] Susun checklist QA visual sebelum handoff (kontras, keterbacaan, konsistensi grid). +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Token animasi global | Definisikan utilitas animasi (hover lift, fade-blur, glow pulse) dalam `static/css/animation.css` dan contoh di dokumentasi. | File animasi + update doc gaya. | +| ☐ | Transisi antar halaman | Implementasi transisi halus menggunakan HTMX `hx-boost` + CSS `view-transition` (jika didukung) atau fallback fade. | Skrip `static/js/page-transitions.js` + konfigurasi di base template. | +| ☐ | Microinteraction komponen | Tambahkan feedback state untuk tombol, progress bar, badge sambatan (pulse countdown). Deskripsikan perilaku di dokumentasi. | Update CSS/JS terkait + section dokumentasi. | + +## 5. Aset & Dokumentasi Handoff Developer + +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Paket ikon & ilustrasi | Kumpulkan ikon SVG dan ilustrasi latar bubble sesuai gaya. Optimasi via SVGO. | Direktori `static/icons/` & `static/illustrations/` + README listing. | +| ☐ | Placeholder produk & brand | Sediakan placeholder gambar dengan efek kaca (PNG/WebP) untuk fallback. | Folder `static/media/placeholders/`. | +| ☐ | Dokumentasi spacing & shadow | Tuliskan guideline di `docs/ui-style-reference.md` terkait jarak, layering, depth. | Update dokumen referensi. | +| ☐ | Checklist QA visual | Buat checklist HTML/Markdown untuk review kontras, responsive, accesibility (keyboard, aria). | `docs/ui-qa-checklist.md`. | ## 6. Integrasi & Validasi -- [ ] Kolaborasikan dengan tim frontend untuk mapping komponen desain ke stack teknologi. -- [ ] Buat prototipe interaktif utama (landing, detail produk, dashboard) untuk validasi flow. -- [ ] Lakukan usability testing ringan (5-7 pengguna internal) dan catat temuan prioritas. -- [ ] Revisi desain berdasarkan feedback dan siapkan versi final untuk development sprint. +| Status | Task | Deskripsi Implementasi | Deliverable | +| --- | --- | --- | --- | +| ☐ | Mapping komponen ke backend | Dokumentasikan bagaimana tiap komponen template menerima data (context dict). Sertakan contoh payload. | `docs/ui-component-contracts.md`. | +| ☐ | Prototipe interaktif via Storybook/Pattern Library | Setup Storybook (atau alternatif minimal `docs/site` dengan `npm run dev`) untuk preview komponen glass secara isolasi. | Konfigurasi Storybook di `story/` + panduan run. | +| ☐ | Usability testing ringan | Jalankan tes internal (5-7 orang) menggunakan build SSR aktual, catat temuan. | Laporan `docs/research/usability-round1.md`. | +| ☐ | Revisi & finalisasi | Terapkan feedback, tandai komponen siap produksi, update changelog. | Update doc + commit changelog di `docs/ui-style-reference.md`. | + +> Catatan: seluruh deliverable harus versioned di repo ini. Gunakan screenshot dari implementasi aktual (bukan Figma) untuk dokumentasi visual. diff --git a/src/app/api/routes/root.py b/src/app/api/routes/root.py index 7809b39..9c8e145 100644 --- a/src/app/api/routes/root.py +++ b/src/app/api/routes/root.py @@ -8,6 +8,437 @@ router = APIRouter() +STATUS_META = { + "todo": {"icon": "☐", "label": "Belum mulai"}, + "progress": {"icon": "◐", "label": "Sedang berjalan"}, + "done": {"icon": "✅", "label": "Selesai"}, +} + + +UIUX_IMPLEMENTATION_PLAN = [ + { + "section": "0. Panduan Visual & Prinsip Umum", + "slug": "panduan-visual", + "tasks": [ + { + "status": "todo", + "title": "Kanvas inspirasi UI", + "description": ( + "Tangkap elemen kunci dari mockup (palet, tipografi serif+sans, bubble glass, " + "refleksi) dan tuangkan ke dokumen panduan kode. Sertakan referensi ukuran dan " + "behavior animasi dasar." + ), + "deliverable": "docs/ui-style-reference.md", + }, + { + "status": "todo", + "title": "Susun token desain berbasis CSS", + "description": ( + "Definisikan CSS custom properties untuk warna, radius, blur, shadow, gradient dan " + "timing animasi sesuai mockup. Token dideklarasikan di :root dan dipublikasikan " + "melalui static/css/tokens.css." + ), + "deliverable": "src/app/web/static/css/tokens.css", + }, + { + "status": "todo", + "title": "Setup tipografi & ikon", + "description": ( + "Implementasi font Playfair Display + Inter (atau alternatif open source mirip) via " + "@font-face/Google Fonts, serta siapkan set ikon Feather/Phosphor yang akan dipakai." + ), + "deliverable": "Perbarui base.html & static/css/base.css", + }, + ], + }, + { + "section": "1. Sistem Desain Berbasis Kode", + "slug": "sistem-desain", + "tasks": [ + { + "status": "todo", + "title": "Utilitas glassmorphism", + "description": ( + "Buat kelas utilitas (mis. .glass-card, .glass-panel, .blur-pill) yang mengatur " + "backdrop-filter, border, dan shadow sesuai inspirasi UI." + ), + "deliverable": "static/css/glass.css + dokumentasi di docs/ui-style-reference.md", + }, + { + "status": "todo", + "title": "Komponen tombol & chip", + "description": ( + "Rancang varian tombol utama/sekunder/ghost serta chip filter dengan state hover/active " + "menggunakan CSS variables & HTMX states." + ), + "deliverable": "templates/components/button.html + static/css/components/button.css", + }, + { + "status": "todo", + "title": "Komponen kartu & badge status", + "description": ( + "Implementasikan kartu produk dengan preview gambar, badge sambatan, dan progress bar radial " + "sesuai sample 3D. Sediakan versi horizontal dan grid." + ), + "deliverable": "templates/components/product-card.html + aset animasi progress", + }, + { + "status": "todo", + "title": "Layout responsif dasar", + "description": ( + "Definisikan grid dan spacing untuk breakpoint desktop/tablet/mobile menggunakan CSS Grid/Flex. " + "Sertakan helper kelas container-xl, stack-lg dsb." + ), + "deliverable": "static/css/layout.css + catatan README", + }, + ], + }, + { + "section": "2. Navigasi & Struktur Global", + "slug": "navigasi", + "tasks": [ + { + "status": "todo", + "title": "Navbar sticky adaptif", + "description": ( + "Implementasikan navbar glass dengan menu utama, indikator halaman aktif, CTA login/signup, serta " + "varian mobile (drawer). Gunakan HTMX untuk aksi open/close." + ), + "deliverable": "templates/partials/navbar.html + static/css/components/navbar.css + static/js/navbar.js", + }, + { + "status": "todo", + "title": "Footer komunitas", + "description": ( + "Bangun footer dengan CTA newsletter, link legal, sosial, dan highlight komunitas. Pastikan layout " + "stack rapi di mobile." + ), + "deliverable": "templates/partials/footer.html + CSS pendukung", + }, + { + "status": "todo", + "title": "Breadcrumb reusable", + "description": ( + "Buat component breadcrumb HTML dengan data-props Jinja (list tuple). Sediakan styling glass pill dan " + "fallback mobile (horizontal scroll)." + ), + "deliverable": "templates/components/breadcrumb.html + CSS", + }, + ], + }, + { + "section": "3. Halaman Prioritas MVP", + "slug": "halaman-prioritas", + "groups": [ + { + "title": "3.1 Landing Page / Marketplace Overview", + "tasks": [ + { + "status": "todo", + "title": "Hero interaktif", + "description": ( + "Bangun hero dengan headline besar, subcopy, CTA ganda, slider produk unggulan dan latar bubble 3D (SVG " + "atau Lottie). Sertakan animasi hover subtle." + ), + "deliverable": "templates/pages/landing.html section hero + asset di static/media/hero", + }, + { + "status": "todo", + "title": "Tab kategori & filter", + "description": ( + "Implementasikan tab + filter kaca menggunakan HTMX untuk swap konten tanpa reload. Sediakan chip " + "active/hover, search bar, dan sort toggle." + ), + "deliverable": "templates/components/category-tabs.html + static/js/tabs.js", + }, + { + "status": "todo", + "title": "Grid produk responsif", + "description": ( + "Layout grid dengan indikator sambatan (progress bar + deadline) dan varian card untuk desktop/tablet/" + "mobile. Pastikan aria label lengkap." + ), + "deliverable": "Blok di landing.html + static/css/components/product-grid.css", + }, + { + "status": "todo", + "title": "Carousel highlight Nusantarum", + "description": ( + "Implementasikan carousel horizontal dengan pill navigation dan auto-play opsional menggunakan Swiper.js " + "atau implementasi custom." + ), + "deliverable": "templates/components/story-carousel.html + static/js/carousel.js", + }, + { + "status": "todo", + "title": "Footer CTA komunitas", + "description": ( + "Section CTA akhir dengan glass panel dan call-to-action bergaya mockup." + ), + "deliverable": "Section di landing.html + styling khusus", + }, + ], + }, + { + "title": "3.2 Detail Produk", + "tasks": [ + { + "status": "todo", + "title": "Galeri foto produk", + "description": ( + "Implementasikan viewer utama + thumbnail scroll dengan efek parallax ringan. Dukungan keyboard navigation " + "dan fallback non-JS." + ), + "deliverable": "templates/components/product-gallery.html + static/js/gallery.js", + }, + { + "status": "todo", + "title": "Panel informasi produk", + "description": ( + "Panel kanan berisi harga, stok, deskripsi aroma, CTA Sambatan/Pesanan dengan badge status. Pastikan sticky di desktop." + ), + "deliverable": "templates/pages/product_detail.html section info + CSS", + }, + { + "status": "todo", + "title": "Modul info brand", + "description": ( + "Kartu brand kaca dengan logo, sertifikasi, link Nusantarum, CTA follow." + ), + "deliverable": "templates/components/brand-module.html", + }, + { + "status": "todo", + "title": "Panel sambatan", + "description": ( + "Komponen progress radial, slot tersisa, countdown realtime (menggunakan Stimulus/HTMX). Varian state aktif/penuh/tutup." + ), + "deliverable": "static/js/sambatan-panel.js + partial HTML & CSS", + }, + ], + }, + { + "title": "3.3 Dashboard Internal (Ops)", + "tasks": [ + { + "status": "todo", + "title": "Layout dashboard", + "description": ( + "Sidebar kaca, topbar, dan konten utama responsif. Gunakan CSS Grid dua kolom + collapse mobile." + ), + "deliverable": "templates/pages/dashboard/index.html + static/css/dashboard.css", + }, + { + "status": "todo", + "title": "Header metrik", + "description": ( + "Kartu KPI dengan gradient glow, icon, delta up/down. Animated counters optional." + ), + "deliverable": "templates/components/kpi-card.html + animasi angka", + }, + { + "status": "todo", + "title": "Tabel pesanan", + "description": ( + "Tabel dengan filter status (tabs), tombol ekspor, empty state ilustrasi. Responsif via CSS display: block di mobile." + ), + "deliverable": "templates/components/order-table.html + CSS/JS filter", + }, + { + "status": "todo", + "title": "Drawer detail pesanan", + "description": ( + "Drawer kanan yang muncul saat klik baris, menampilkan detail & log. Implementasi HTMX swap + overlay backdrop." + ), + "deliverable": "templates/components/order-drawer.html + static/js/drawer.js", + }, + ], + }, + { + "title": "3.4 Nusantarum Hub", + "tasks": [ + { + "status": "todo", + "title": "Hero kuratorial", + "description": ( + "Hero kaca dengan headline, subcopy, CTA, background partikel (canvas/SVG)." + ), + "deliverable": "templates/pages/nusantarum.html section hero + asset", + }, + { + "status": "todo", + "title": "Panel filter multiplatform", + "description": ( + "Panel filter desktop + bottom sheet mobile (dialog). Gunakan CSS position: sticky dan HTMX update results." + ), + "deliverable": "templates/components/nusantarum-filter.html + static/js/filter-sheet.js", + }, + { + "status": "todo", + "title": "Kartu cerita", + "description": ( + "Kartu cerita dengan foto, tag brand/perfumer, CTA. Pastikan variant grid/list." + ), + "deliverable": "templates/components/story-card.html", + }, + { + "status": "todo", + "title": "CTA ajukan cerita", + "description": ( + "Form CTA dengan state hover, disabled, dan note integrasi backend." + ), + "deliverable": "Section + CSS di nusantarum.html", + }, + ], + }, + { + "title": "3.5 Profil Pengguna", + "tasks": [ + { + "status": "todo", + "title": "Header profil", + "description": ( + "Header kaca dengan avatar, nama, preferensi aroma chip, dan tombol edit." + ), + "deliverable": "templates/pages/profile.html section header + CSS", + }, + { + "status": "todo", + "title": "Tab aktivitas/favorit/sambatan", + "description": ( + "Tab berbasis HTMX untuk switch konten tanpa reload, dengan animasi underline." + ), + "deliverable": "templates/components/profile-tabs.html + static/js/profile-tabs.js", + }, + { + "status": "todo", + "title": "Timeline aktivitas", + "description": ( + "Komponen timeline card dengan icon status, timestamp, deskripsi." + ), + "deliverable": "templates/components/activity-card.html", + }, + { + "status": "todo", + "title": "Grid favorit & daftar sambatan", + "description": ( + "Layout grid/list dengan status indicator & CTA lanjutkan." + ), + "deliverable": "Blok di profile.html + CSS", + }, + ], + }, + ], + }, + { + "section": "4. Interaksi & Animasi", + "slug": "interaksi", + "tasks": [ + { + "status": "todo", + "title": "Token animasi global", + "description": ( + "Definisikan utilitas animasi (hover lift, fade-blur, glow pulse) dalam static/css/animation.css dan contoh di dokumentasi." + ), + "deliverable": "static/css/animation.css + update docs/ui-style-reference.md", + }, + { + "status": "todo", + "title": "Transisi antar halaman", + "description": ( + "Implementasi transisi halus menggunakan HTMX hx-boost + CSS view-transition (jika didukung) atau fallback fade." + ), + "deliverable": "static/js/page-transitions.js + konfigurasi di base template", + }, + { + "status": "todo", + "title": "Microinteraction komponen", + "description": ( + "Tambahkan feedback state untuk tombol, progress bar, badge sambatan (pulse countdown). Deskripsikan perilaku di dokumentasi." + ), + "deliverable": "Update CSS/JS terkait + dokumentasi", + }, + ], + }, + { + "section": "5. Aset & Dokumentasi Handoff Developer", + "slug": "aset-dokumentasi", + "tasks": [ + { + "status": "todo", + "title": "Paket ikon & ilustrasi", + "description": ( + "Kumpulkan ikon SVG dan ilustrasi latar bubble sesuai gaya. Optimasi via SVGO." + ), + "deliverable": "Direktori static/icons/ & static/illustrations/ + README listing", + }, + { + "status": "todo", + "title": "Placeholder produk & brand", + "description": ( + "Sediakan placeholder gambar dengan efek kaca (PNG/WebP) untuk fallback." + ), + "deliverable": "Folder static/media/placeholders/", + }, + { + "status": "todo", + "title": "Dokumentasi spacing & shadow", + "description": ( + "Tuliskan guideline di docs/ui-style-reference.md terkait jarak, layering, depth." + ), + "deliverable": "Update docs/ui-style-reference.md", + }, + { + "status": "todo", + "title": "Checklist QA visual", + "description": ( + "Buat checklist HTML/Markdown untuk review kontras, responsive, accesibility (keyboard, aria)." + ), + "deliverable": "docs/ui-qa-checklist.md", + }, + ], + }, + { + "section": "6. Integrasi & Validasi", + "slug": "integrasi", + "tasks": [ + { + "status": "todo", + "title": "Mapping komponen ke backend", + "description": ( + "Dokumentasikan bagaimana tiap komponen template menerima data (context dict). Sertakan contoh payload." + ), + "deliverable": "docs/ui-component-contracts.md", + }, + { + "status": "todo", + "title": "Prototipe interaktif via Storybook/Pattern Library", + "description": ( + "Setup Storybook (atau alternatif minimal docs/site dengan npm run dev) untuk preview komponen glass secara isolasi." + ), + "deliverable": "Konfigurasi Storybook di story/ + panduan run", + }, + { + "status": "todo", + "title": "Usability testing ringan", + "description": ( + "Jalankan tes internal (5-7 orang) menggunakan build SSR aktual, catat temuan." + ), + "deliverable": "docs/research/usability-round1.md", + }, + { + "status": "todo", + "title": "Revisi & finalisasi", + "description": ( + "Terapkan feedback, tandai komponen siap produksi, update changelog." + ), + "deliverable": "Update docs/ui-style-reference.md", + }, + ], + }, +] + + @router.get("/", response_class=HTMLResponse) async def read_home(request: Request) -> HTMLResponse: """Render the marketplace landing page placeholder.""" @@ -199,3 +630,21 @@ async def read_onboarding(request: Request) -> HTMLResponse: "steps": steps, } return templates.TemplateResponse("onboarding.html", context) + + +@router.get("/ui-ux/implementation", response_class=HTMLResponse) +async def read_uiux_tracker(request: Request) -> HTMLResponse: + """Render a glassmorphism-flavored tracker of the UI/UX implementation to-do list.""" + + settings = get_settings() + templates = request.app.state.templates + + context = { + "request": request, + "app_name": settings.app_name, + "environment": settings.environment, + "title": "UI/UX Implementation Tracker", + "status_meta": STATUS_META, + "sections": UIUX_IMPLEMENTATION_PLAN, + } + return templates.TemplateResponse("ui_ux_tracker.html", context) diff --git a/src/app/web/static/css/base.css b/src/app/web/static/css/base.css index d74158c..eb1e783 100644 --- a/src/app/web/static/css/base.css +++ b/src/app/web/static/css/base.css @@ -1,17 +1,17 @@ :root { - --gradient-background: radial-gradient(circle at 15% 20%, rgba(249, 115, 22, 0.15), transparent 55%), - radial-gradient(circle at 85% 15%, rgba(192, 38, 211, 0.18), transparent 60%), - linear-gradient(135deg, #0f172a, #1e293b 55%, #0b1120); - --glass-surface: rgba(15, 23, 42, 0.62); - --glass-border: rgba(148, 163, 184, 0.35); - --glass-shadow: 0 25px 45px rgba(15, 23, 42, 0.45); - --text-primary: #f8fafc; - --text-secondary: #cbd5f5; - --accent-primary: linear-gradient(135deg, #f97316, #c026d3); - --accent-secondary: #38bdf8; - --muted: #94a3b8; - --success: #34d399; - --danger: #f87171; + --gradient-background: radial-gradient(circle at 12% 18%, rgba(255, 199, 168, 0.55), transparent 52%), + radial-gradient(circle at 88% 12%, rgba(255, 179, 220, 0.55), transparent 58%), + linear-gradient(140deg, #fef6ec, #fde4f2 55%, #f6d8ff); + --glass-surface: rgba(255, 255, 255, 0.68); + --glass-border: rgba(255, 255, 255, 0.55); + --glass-shadow: 0 28px 55px rgba(247, 170, 203, 0.32); + --text-primary: #3e2443; + --text-secondary: #6f5466; + --accent-primary: linear-gradient(130deg, #ffb86c, #ff6f91); + --accent-secondary: #ff8fa3; + --muted: #b791a3; + --success: #4bbd8b; + --danger: #ff7a7a; --radius-lg: 28px; --radius-md: 20px; --radius-sm: 14px; @@ -42,8 +42,8 @@ body::before { content: ""; position: fixed; inset: 0; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160' viewBox='0 0 160 160'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='.06'%3E%3Cpath d='M80 0h1v160h-1zM0 80h160v1H0z'/%3E%3C/g%3E%3C/svg%3E"); - opacity: 0.4; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160' viewBox='0 0 160 160'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='.16'%3E%3Cpath d='M80 0h1v160h-1zM0 80h160v1H0z'/%3E%3C/g%3E%3C/svg%3E"); + opacity: 0.65; pointer-events: none; z-index: -1; } @@ -64,25 +64,25 @@ body::before { } .glass-surface { - backdrop-filter: blur(24px) saturate(140%); - background: linear-gradient(145deg, rgba(15, 23, 42, 0.65), rgba(15, 23, 42, 0.4)); + backdrop-filter: blur(26px) saturate(160%); + background: linear-gradient(145deg, rgba(255, 255, 255, 0.82), rgba(255, 255, 255, 0.6)); border: 1px solid var(--glass-border); border-radius: var(--radius-lg); box-shadow: var(--glass-shadow); } .glass-card { - backdrop-filter: blur(22px) saturate(150%); - background: rgba(15, 23, 42, 0.68); - border: 1px solid rgba(148, 163, 184, 0.25); + backdrop-filter: blur(20px) saturate(160%); + background: rgba(255, 255, 255, 0.78); + border: 1px solid rgba(255, 255, 255, 0.6); border-radius: var(--radius-md); - box-shadow: 0 18px 40px rgba(8, 15, 29, 0.35); + box-shadow: 0 18px 48px rgba(239, 173, 204, 0.32); transition: transform var(--transition-base), box-shadow var(--transition-base); } .glass-card:hover { transform: translateY(-6px); - box-shadow: 0 28px 60px rgba(8, 15, 29, 0.45); + box-shadow: 0 28px 60px rgba(239, 173, 204, 0.42); } h1, @@ -118,23 +118,23 @@ p { .gradient-button { background: var(--accent-primary); - color: #0f172a; - box-shadow: 0 12px 30px rgba(249, 115, 22, 0.3); + color: #42253f; + box-shadow: 0 16px 36px rgba(255, 143, 163, 0.32); } .gradient-button:hover { - box-shadow: 0 18px 40px rgba(192, 38, 211, 0.25); + box-shadow: 0 22px 48px rgba(255, 143, 163, 0.42); } .btn-outline { - background: transparent; - border: 1px solid rgba(56, 189, 248, 0.35); + background: rgba(255, 255, 255, 0.55); + border: 1px solid rgba(255, 143, 163, 0.5); color: var(--accent-secondary); } .btn-outline:hover { - border-color: rgba(56, 189, 248, 0.75); - background: rgba(56, 189, 248, 0.08); + border-color: rgba(255, 143, 163, 0.8); + background: rgba(255, 143, 163, 0.15); } .btn-ghost { @@ -145,7 +145,7 @@ p { .btn-ghost:hover { color: var(--text-primary); - border-color: rgba(148, 163, 184, 0.3); + border-color: rgba(255, 255, 255, 0.4); } .navbar { diff --git a/src/app/web/static/css/ui-ux-tracker.css b/src/app/web/static/css/ui-ux-tracker.css new file mode 100644 index 0000000..ed277b2 --- /dev/null +++ b/src/app/web/static/css/ui-ux-tracker.css @@ -0,0 +1,676 @@ +.uiux-hero { + display: flex; + flex-direction: column; + gap: 2.5rem; + position: relative; +} + +.glass-shell { + position: relative; + backdrop-filter: blur(32px) saturate(165%); + background: linear-gradient(155deg, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.6)); + border-radius: 42px; + border: 1px solid rgba(255, 255, 255, 0.55); + box-shadow: 0 34px 70px rgba(244, 182, 207, 0.32); +} + +.glass-loop { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1.5rem; + padding: 1.4rem 1.8rem; + border-radius: 999px; + backdrop-filter: blur(24px) saturate(170%); + background: rgba(255, 255, 255, 0.6); + border: 1px solid rgba(255, 255, 255, 0.65); + box-shadow: 0 22px 48px rgba(244, 182, 207, 0.32); +} + +.hero-nav { + flex-wrap: wrap; + gap: 1.5rem; +} + +.hero-nav__group { + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; + justify-content: center; + flex: 1 1 auto; +} + +.hero-brand { + flex-shrink: 0; + display: flex; + align-items: center; + gap: 0.9rem; +} + +.hero-brand__mark { + width: 56px; + height: 56px; + border-radius: 20px; + background: linear-gradient(135deg, #ffb86c, #ff6f91); + box-shadow: 0 18px 36px rgba(255, 143, 163, 0.32); + display: grid; + place-items: center; + overflow: hidden; +} + +.hero-brand__mark svg { + width: 32px; + height: 32px; +} + +.hero-brand__text { + display: flex; + flex-direction: column; + gap: 0.2rem; +} + +.hero-brand__title { + font-weight: 700; + font-size: 1.05rem; + color: var(--text-primary); +} + +.hero-brand__subtitle { + font-size: 0.78rem; + letter-spacing: 0.2em; + text-transform: uppercase; + color: var(--accent-secondary); +} + +.hero-chip { + display: inline-flex; + align-items: center; + gap: 0.7rem; + padding: 0.75rem 1.6rem; + border-radius: 999px; + border: 1px solid rgba(255, 255, 255, 0.65); + background: rgba(255, 255, 255, 0.55); + color: var(--text-primary); + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; + cursor: pointer; + transition: transform var(--transition-base), background var(--transition-base), border var(--transition-base); +} + +.hero-chip.is-active { + background: var(--accent-primary); + color: #fff9f4; + border-color: transparent; + box-shadow: 0 16px 42px rgba(255, 143, 163, 0.38); +} + +.hero-chip:hover { + transform: translateY(-2px); + border-color: rgba(255, 255, 255, 0.8); +} + +.hero-chip__index { + font-size: 1rem; +} + +.hero-chip__label { + font-size: 0.85rem; + letter-spacing: 0.2em; +} + +.hero-chip--icon { + width: 58px; + height: 58px; + border-radius: 50%; + align-items: center; + justify-content: center; + padding: 0; + font-size: 1.25rem; + background: rgba(255, 255, 255, 0.52); + border: 1px solid rgba(255, 255, 255, 0.7); + color: var(--accent-secondary); + box-shadow: 0 16px 32px rgba(244, 182, 207, 0.28); +} + +.hero-stage { + display: grid; + grid-template-columns: minmax(240px, 320px) 1fr; + gap: 2rem; + padding: 2.5rem; + overflow: hidden; +} + +.stage-panel { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + gap: 1.6rem; +} + +.stage-panel--side { + max-width: 320px; +} + +.mini-card { + display: flex; + flex-direction: column; + gap: 1.2rem; + padding: 1.8rem; + border-radius: 28px; + background: rgba(255, 255, 255, 0.78); + border: 1px solid rgba(255, 255, 255, 0.6); + box-shadow: 0 22px 48px rgba(244, 182, 207, 0.32); +} + +.mini-card header { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.mini-card__eyebrow { + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.2em; + color: var(--muted); +} + +.mini-card h3 { + margin: 0; + font-size: 1.2rem; +} + +.mini-card p { + margin: 0; + font-size: 0.95rem; + color: var(--text-secondary); +} + +.mini-card__cta { + display: flex; + flex-direction: column; + gap: 0.35rem; + font-size: 0.85rem; +} + +.badge { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.35rem 1.2rem; + border-radius: 999px; + border: 1px solid rgba(255, 143, 163, 0.55); + background: rgba(255, 143, 163, 0.18); + text-transform: uppercase; + letter-spacing: 0.22em; + font-size: 0.7rem; + font-weight: 600; + color: var(--accent-secondary); +} + +.refresh-btn { + align-self: flex-start; + padding: 0.6rem 1.4rem; + border-radius: 999px; + border: 1px solid rgba(255, 143, 163, 0.55); + background: rgba(255, 143, 163, 0.15); + color: var(--accent-secondary); + font-weight: 600; + cursor: pointer; + transition: transform var(--transition-base), border var(--transition-base); +} + +.refresh-btn:hover { + transform: translateY(-2px); + border-color: rgba(255, 143, 163, 0.85); +} + +.stage-panel--main { + padding: 2rem 2.5rem; + border-radius: 34px; + border: 1px solid rgba(255, 255, 255, 0.55); + background: linear-gradient(160deg, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.65)); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3); +} + +.stage-meta { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 1.5rem; +} + +.stage-meta__index { + display: inline-flex; + align-items: center; + justify-content: center; + width: 3.6rem; + height: 3.6rem; + border-radius: 1.6rem; + background: rgba(255, 199, 168, 0.28); + font-size: 1.25rem; + font-weight: 600; +} + +.stage-meta__eyebrow { + margin-top: 0.75rem; + font-size: 0.78rem; + letter-spacing: 0.22em; + text-transform: uppercase; + color: var(--muted); +} + +.stage-meta h1 { + margin: 0.3rem 0; + font-size: clamp(2rem, 4vw, 2.8rem); +} + +.ghost-btn { + border: 1px solid rgba(255, 143, 163, 0.45); + border-radius: 999px; + background: rgba(255, 255, 255, 0.4); + color: var(--accent-secondary); + padding: 0.65rem 1.6rem; + font-weight: 600; + cursor: pointer; +} + +.stage-description { + margin: 1.2rem 0 1.8rem; + max-width: 46ch; +} + +.stage-support { + display: grid; + grid-template-columns: auto 1fr; + gap: 1rem 1.2rem; + align-items: start; + padding: 1.4rem 1.6rem; + border-radius: 24px; + background: rgba(255, 255, 255, 0.75); + border: 1px solid rgba(255, 255, 255, 0.55); +} + +.stage-support h4 { + margin: 0; + font-size: 1.1rem; +} + +.stage-support p { + margin: 0.35rem 0 0; + font-size: 0.95rem; +} + +.stage-footer { + display: flex; + gap: 1rem; + margin-top: 2rem; +} + +.primary-btn { + border: none; + border-radius: 999px; + padding: 0.85rem 2.2rem; + background: var(--accent-primary); + color: #fff9f4; + font-weight: 700; + cursor: pointer; + box-shadow: 0 18px 44px rgba(255, 143, 163, 0.38); +} + +.secondary-btn { + border-radius: 999px; + padding: 0.85rem 2rem; + border: 1px solid rgba(255, 143, 163, 0.45); + background: rgba(255, 255, 255, 0.55); + color: var(--text-primary); + font-weight: 600; + cursor: pointer; +} + +.stage-media { + position: absolute; + inset: 0; + pointer-events: none; +} + +.bubble { + position: absolute; + border-radius: 50%; + background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.95), rgba(255, 186, 205, 0.2)); + filter: blur(0px); + opacity: 0.85; +} + +.bubble-lg { + width: 300px; + height: 300px; + right: 10%; + top: 18%; +} + +.bubble-md { + width: 200px; + height: 200px; + left: 42%; + bottom: 12%; +} + +.bubble-sm { + width: 140px; + height: 140px; + right: 28%; + bottom: 22%; +} + +.media-orb { + position: absolute; + width: 240px; + height: 240px; + border-radius: 50%; + inset: 50% auto auto 50%; + transform: translate(-50%, -45%); + background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.95), rgba(255, 190, 210, 0.4)); + box-shadow: inset 0 0 25px rgba(255, 255, 255, 0.6), 0 34px 68px rgba(244, 182, 207, 0.35); + display: flex; + align-items: center; + justify-content: center; + font-size: 2.6rem; + color: var(--accent-secondary); +} + +.hero-carousel { + position: relative; + align-items: stretch; + flex-direction: column; + gap: 1.4rem; +} + +.carousel-meta { + display: flex; + justify-content: space-between; + align-items: center; + gap: 1rem; + font-size: 1rem; + text-transform: uppercase; + letter-spacing: 0.18em; + color: var(--text-secondary); +} + +.carousel-track { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 1.4rem; + width: 100%; +} + +.carousel-card { + display: flex; + flex-direction: column; + gap: 0.9rem; + padding: 1.5rem; + border-radius: 24px; + background: rgba(255, 255, 255, 0.72); + border: 1px solid rgba(255, 255, 255, 0.55); + box-shadow: 0 18px 42px rgba(244, 182, 207, 0.28); +} + +.carousel-status { + font-size: 1.2rem; +} + +.carousel-card h3 { + margin: 0; + font-size: 1.1rem; +} + +.carousel-card p { + margin: 0; + font-size: 0.9rem; +} + +.carousel-deliverable { + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.18em; + color: var(--accent-secondary); +} + +.carousel-action { + align-self: flex-start; + padding: 0.65rem 1.6rem; + border-radius: 999px; + border: 1px solid rgba(255, 143, 163, 0.55); + background: rgba(255, 143, 163, 0.18); + color: var(--accent-secondary); + font-weight: 600; + cursor: pointer; +} + +.carousel-action:hover { + border-color: rgba(255, 143, 163, 0.85); + background: rgba(255, 143, 163, 0.3); +} + +.carousel-next { + position: absolute; + right: 1.2rem; + bottom: 1.6rem; + width: 60px; + height: 60px; + border-radius: 50%; + border: 1px solid rgba(255, 255, 255, 0.65); + background: rgba(255, 255, 255, 0.6); + color: var(--accent-secondary); + font-size: 1.4rem; + cursor: pointer; + box-shadow: 0 16px 34px rgba(244, 182, 207, 0.32); +} + +.uiux-tracker { + display: flex; + flex-direction: column; + gap: 2.4rem; +} + +.tracker-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 2rem; +} + +.tracker-eyebrow { + font-size: 0.78rem; + letter-spacing: 0.28em; + text-transform: uppercase; + color: var(--muted); +} + +.tracker-header h2 { + margin: 0.6rem 0 0; + font-size: clamp(2rem, 4vw, 2.6rem); +} + +.status-legend { + display: flex; + gap: 1.2rem; + flex-wrap: wrap; +} + +.legend-item { + display: inline-flex; + align-items: center; + gap: 0.6rem; + padding: 0.45rem 1rem; + border-radius: 999px; + border: 1px solid rgba(255, 255, 255, 0.55); + background: rgba(255, 255, 255, 0.58); +} + +.legend-icon { + width: 1.6rem; + height: 1.6rem; + display: flex; + align-items: center; + justify-content: center; + border-radius: 0.6rem; + background: rgba(255, 255, 255, 0.85); + color: var(--accent-secondary); +} + +.tracker-grid { + display: grid; + gap: 1.8rem; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); +} + +.tracker-card { + display: flex; + flex-direction: column; + gap: 1.2rem; + padding: 1.8rem; + border-radius: 30px; + background: rgba(255, 255, 255, 0.78); + border: 1px solid rgba(255, 255, 255, 0.6); + box-shadow: 0 24px 55px rgba(244, 182, 207, 0.3); +} + +.tracker-card header { + display: flex; + align-items: baseline; + gap: 0.8rem; +} + +.tracker-card__index { + font-family: "Playfair Display", serif; + font-size: 1.8rem; + color: rgba(255, 143, 163, 0.75); +} + +.tracker-card h3 { + margin: 0; + font-size: 1.25rem; +} + +.tracker-list { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + gap: 1.2rem; +} + +.tracker-item { + display: flex; + flex-direction: column; + gap: 0.6rem; + padding: 1.1rem 1.2rem; + border-radius: 20px; + background: rgba(255, 255, 255, 0.72); + border: 1px solid rgba(255, 255, 255, 0.55); +} + +.tracker-item__meta { + display: flex; + gap: 0.9rem; +} + +.tracker-item__status { + width: 2rem; + height: 2rem; + display: flex; + align-items: center; + justify-content: center; + border-radius: 0.9rem; + background: rgba(255, 255, 255, 0.85); +} + +.tracker-item__deliverable { + font-size: 0.78rem; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--accent-secondary); +} + +.tracker-group { + display: flex; + flex-direction: column; + gap: 1rem; + padding: 1.2rem 1.4rem; + border-radius: 24px; + background: rgba(255, 255, 255, 0.72); + border: 1px solid rgba(255, 255, 255, 0.55); +} + +.tracker-group h4 { + margin: 0; + font-size: 1.05rem; +} + +@media (max-width: 1024px) { + .hero-stage { + grid-template-columns: 1fr; + padding: 2rem; + } + + .stage-panel--side { + order: 2; + } + + .stage-panel--main { + order: 1; + } +} + +@media (max-width: 768px) { + .hero-nav, + .hero-carousel { + flex-direction: column; + border-radius: 32px; + } + + .hero-nav__group { + flex-wrap: wrap; + justify-content: center; + } + + .hero-stage { + border-radius: 32px; + } + + .stage-footer { + flex-direction: column; + align-items: stretch; + } + + .carousel-meta { + flex-direction: column; + align-items: flex-start; + } + + .carousel-next { + position: static; + } + + .tracker-header { + flex-direction: column; + align-items: flex-start; + } +} + +.status-todo { + color: var(--muted); +} + +.status-progress { + color: #ff8f70; +} + +.status-done { + color: var(--success); +} diff --git a/src/app/web/templates/base.html b/src/app/web/templates/base.html index 1cbf289..11d27be 100644 --- a/src/app/web/templates/base.html +++ b/src/app/web/templates/base.html @@ -10,9 +10,10 @@ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Playfair+Display:wght@600;700&display=swap" rel="stylesheet" /> - - - + + + {% block head_extra %}{% endblock %} +
diff --git a/src/app/web/templates/partials/navbar.html b/src/app/web/templates/partials/navbar.html index 550abe2..ef1e9de 100644 --- a/src/app/web/templates/partials/navbar.html +++ b/src/app/web/templates/partials/navbar.html @@ -21,6 +21,14 @@ Onboarding +{{ highlight_task.description }}
+ {% if supporting_task %} +{{ supporting_task.description }}
+{{ task.description }}
+ {{ task.deliverable }} + +