style: refine design system aesthetics to flat solid dark-mode theme

This commit is contained in:
2026-05-30 13:28:25 +05:00
parent 110fc61fa2
commit 1e705053f5
10 changed files with 59 additions and 101 deletions
+40 -82
View File
@@ -1,6 +1,6 @@
# Detailed Project Architecture & Design System Reference Manual # Detailed Project Architecture & Design System Reference Manual
This document provides a comprehensive technical overview of the **Stick** template, detailing its vertical structure, core dependencies, event delegation contracts, component reuse solutions, and our current implementation plan. This document provides a comprehensive technical overview of the **Stick** template, detailing its vertical structure, core dependencies, event delegation contracts, component reuse solutions, and our completed implementation history.
--- ---
@@ -15,116 +15,74 @@ stick/
├── package.json # Node assets configuration (optional tooling) ├── package.json # Node assets configuration (optional tooling)
├── src/ ├── src/
│ ├── main.rs # Core composition, shared state, and route merging │ ├── main.rs # Core composition, shared state, and route merging
│ ├── common/ # Shared utilities & configurations │ ├── common/ # Shared features (errors, database, settings)
│ │ ├── config.rs # Configuration parsed from environment variables (.env)
│ │ ├── database.rs # MongoDB initialization and connections
│ │ └── errors.rs # AppError implementation wrapping custom responses
│ ├── auth/ # AUTH USE-CASE (Users, Passwords, Session cookies) │ ├── auth/ # AUTH USE-CASE (Users, Passwords, Session cookies)
│ │ ├── extractors.rs # Native Axum extractors for authentication state
│ │ ├── handlers.rs # Login and registration endpoint handlers
│ │ ├── models.rs # User database schemas
│ │ └── repository.rs # MongoDB operations for authentication
│ ├── tasks/ # TASKS USE-CASE (CRUD tasks, dashboard view) │ ├── tasks/ # TASKS USE-CASE (CRUD tasks, dashboard view)
│ ├── handlers.rs │ ├── developers/ # DEVELOPERS USE-CASE (Assignee autocomplete query)
│ │ ├── models.rs
│ │ └── repository.rs
│ ├── developers/ # DEVELOPERS USE-CASE (HTMX-based assignee autocomplete query)
│ │ ├── handlers.rs
│ │ ├── models.rs
│ │ └── repository.rs
│ ├── main_view/ # STATIC VIEWS & GLOBAL ASSET ENDPOINTS │ ├── main_view/ # STATIC VIEWS & GLOBAL ASSET ENDPOINTS
│ │ └── mod.rs # Serves index.html, static css, and static javascript files
│ ├── components/ # WIKI & INTERACTIVE DESIGN SYSTEM │ ├── components/ # WIKI & INTERACTIVE DESIGN SYSTEM
│ │ ├── mod.rs # Wiki routing table
│ │ └── handlers.rs # Handlers serving reference pages
│ └── input.css # Tailwind CSS v4 custom theme mappings and custom scrollbars │ └── input.css # Tailwind CSS v4 custom theme mappings and custom scrollbars
├── static/ # Raw assets compiled/included in compilation ├── static/ # Raw assets compiled/included in compilation
│ ├── tailwind.css # Output/input css rules
│ └── js/
│ ├── components.js # Main component event delegation system
│ └── combobox.js # HTMX-friendly autocomplete combobox scripts
└── templates/ # Raw HTML template layout files (Askama templates) └── templates/ # Raw HTML template layout files (Askama templates)
├── base.html # Global HTML layout wrapper (injects headers, navigation) ├── base.html # Global HTML layout wrapper
├── auth/ # Login / registration markup ├── auth/ # Login / registration markup (refactored to macros)
├── tasks/ # Task management layouts ├── tasks/ # Task management layouts (refactored to macros)
├── main_view/ # Landing page layout ├── main_view/ # Landing page layout
└── components/ # Component Wiki pages (Buttons, Modals, Comboboxes, etc.) └── components/ # Component Wiki pages (refactored to macros)
```
### Route Composition
In [src/main.rs](file:///home/enciphered/Desktop/Code/stick/src/main.rs), routers from each vertical module are instantiated and merged using Axum's `.merge()` method:
```rust
let app = Router::new()
.merge(main_view::router())
.merge(components::router())
.merge(auth::router())
.merge(tasks::router())
.merge(developers::router())
.with_state(state);
``` ```
--- ---
## 🛠️ 2. Core Technical Dependencies ## 🛠️ 2. Core Technical Dependencies
* **Web Server**: `axum = "0.8.9"` — Native asynchronous routing with type-safe extractor traits. * **Web Server**: `axum = "0.8.9"`
* **Database**: `mongodb = "3.7.0"` — Offical Rust driver, using `bson = "3.1.0"` with serde serialization. * **Database**: `mongodb = "3.7.0"` (using `bson = "3.1.0"`)
* **Template Rendering**: `askama = "0.16.0"` — Compile-time type safety; views are compiled directly into the binary. * **Template Rendering**: `askama = "0.16.0"`
* **Styling Engine**: Tailwind CSS (v4) — Uses native CSS variables and `@import "tailwindcss"` rather than complex configuration JSONs. * **Styling Engine**: Tailwind CSS (v4)
* **Security & JWT**: `jsonwebtoken = "10.4.0"` (via `rust_crypto` backend) + `bcrypt = "0.19.1"` for password hashing. JWTs are stored in secure `HttpOnly` cookie wrappers. * **Security & JWT**: `jsonwebtoken = "10.4.0"` + `bcrypt = "0.19.1"`
--- ---
## 🎨 3. JavaScript & HTML Event Delegation Contract ## 🎨 3. JavaScript & HTML Event Delegation Contract
Rather than attaching individual event listeners to elements upon page load (which degrades performance and fails when elements are swapped dynamically via HTMX), Stick uses **document-level event delegation** via [static/js/components.js](file:///home/enciphered/Desktop/Code/stick/static/js/components.js) and [static/js/combobox.js](file:///home/enciphered/Desktop/Code/stick/static/js/combobox.js). Stick uses **document-level event delegation** via `components.js` and `combobox.js`.
### Active Binding Attributes & Hooks
To make components function, developers must preserve specific HTML attributes and class structures that JavaScript expects:
| Component Type | JavaScript Trigger / Hook | Expected Target / Functional Structure | | Component Type | JavaScript Trigger / Hook | Expected Target / Functional Structure |
| :--- | :--- | :--- | | :--- | :--- | :--- |
| **Modal / Dialog** | `[data-modal-target="id"]` | `.modal-dialog` (wrapper), `.modal-backdrop`, `.modal-close` | | **Modal / Dialog** | `[data-modal-target="id"]` | `.modal-dialog`, `.modal-backdrop`, `.modal-close` |
| **Sheets / Drawers** | `[data-sheet-target="id"]` | `.sheet-dialog` (wrapper), `.sheet-backdrop`, `.sheet-close` | | **Sheets / Drawers** | `[data-sheet-target="id"]` | `.sheet-dialog`, `.sheet-backdrop`, `.sheet-close` |
| **Custom Dropdowns** | `.dropdown-trigger` | `.dropdown-menu` (container), `.dropdown-content` | | **Custom Dropdowns** | `.dropdown-trigger` | `.dropdown-menu`, `.dropdown-content` |
| **Interactive Tabs**| `[data-tab-target="pane-id"]` | `[data-tab-group="group-name"]` on buttons & content wrappers | | **Interactive Tabs**| `[data-tab-target="pane-id"]` | `[data-tab-group="group-name"]` on buttons & content wrappers |
| **Accordions** | `.accordion-trigger` | `.accordion-item` (container), `.accordion-content`, `.accordion-chevron` | | **Accordions** | `.accordion-trigger` | `.accordion-item`, `.accordion-content`, `.accordion-chevron` |
| **Custom Select** | `.select-trigger` | `.custom-select` (container), `.select-popover`, `.select-item`, `.select-value` | | **Custom Select** | `.select-trigger` | `.custom-select`, `.select-popover`, `.select-item`, `.select-value` |
| **Autocomplete Combobox**| `.combobox-input` | `.autocomplete-combobox` (container), `.combobox-results`, `.combobox-value` | | **Autocomplete Combobox**| `.combobox-input` | `.autocomplete-combobox`, `.combobox-results`, `.combobox-value` |
*Any customized styling classes (colors, borders, rounded corners) can be freely added or changed. However, the core class naming hierarchy listed above must remain intact to preserve interaction animations and keyboard controls.*
--- ---
## 🧩 4. Proposed Scalability & Code Reuse Solutions ## 🚀 4. Completed Askama Macros Refactoring (Completed Tasks)
We successfully migrated all UI components to type-safe templates on the branch `demo/askama-macros`.
### Solution 1: Askama Macros (Selected Demo) ### A. Phase 1: Form Inputs & Basic Controls
Consolidate UI components into a global macros registry template. Consolidated basic form controls into [templates/components/macros.html](file:///home/enciphered/Desktop/Code/stick/templates/components/macros.html):
* *Pros*: Safe compilation (missing variables or typos are checked at build time), zero performance cost. * `button`: Unified visual styles with custom icon inclusion (`label|safe`).
* *Cons*: Complex child structures (e.g. slots or dynamic SVG parameters) require passing strings/blocks, which can look verbose. * `text_input` & `textarea`: Standardized label, placeholder, name, and value variables.
* `select_open`, `select_item`, `select_close`: Structural paired macros bypassing Askama's lack of template slots.
* `toggle_switch` & `checkbox`: Standardized custom check styles.
* `range_slider` & `datepicker` & `timepicker`: Popover-based pickers integration.
### Solution 2: CSS Component Classes ### B. Phase 2: Layout & Overlays (Paired Macro Pattern)
Define custom components in [src/input.css](file:///home/enciphered/Desktop/Code/stick/src/input.css) using Tailwind CSS v4's components layer (e.g. `@apply btn btn-primary`). * `modal_open` & `modal_close`: Paired overlay layout block wrapping.
* *Pros*: Clear, descriptive markup syntax; easily consumable by pure front-end web developers. * `sheet_open` & `sheet_close`: Paired slide-out detail drawers.
* *Cons*: Partially moves styling definitions out of HTML files and back into stylesheet files. * `tabs_header_open`, `tab_trigger`, `tabs_header_close`, `tabs_content_open`, `tab_pane_open`, `tab_pane_close`, `tabs_content_close`: Flexible dynamic tabs.
* `accordion_open` & `accordion_close`: Paired collapsible vertical containers.
### Solution 3: Rust Struct Components ### C. Phase 3: Global Cleanup & Integration
Represent reusable buttons, grids, or select widgets as Rust structs that implement Askama's `Template` trait. * Refactored the Component Wiki demo views to use all new macros (`buttons.html`, `inputs.html`, `toggles.html`, `date_time.html`, `modals.html`, `sheets.html`, `tabs_accordion.html`).
* *Pros*: Advanced data-driven structures and type constraints managed entirely in Rust code. * Refactored the authentication views (`login.html` and `register.html`) to use unified `text_input` and `button` macros.
* *Cons*: Visual updates require recompiling Rust binaries, which limits swift CSS experimentation. * Refactored the rest of the Task Dashboard (`dashboard.html`) to use macro inputs for the task name and task description fields.
--- ---
## 🚀 5. Action Plan: Askama Macros Implementation ## 🧪 5. Testing & Verification Results
We are implementing a demo showcasing Askama Macros in a new git branch: * **Compile-time Check**: Successfully ran `cargo check` to ensure all macro scopes, imports, and variables are resolved at compilation time.
* **Docker Container Status**: Image rebuilt successfully. Running on network port `3009`.
1. **Branch Setup**: Create `demo/askama-macros`.
2. **Define Macros**: Create `templates/components/macros.html` to define reusable snippets for:
* **Button**: Primary, secondary, outline, destructive, status indicators.
* **Modal**: Accessibility markup, background overlays, closing controls.
* **Autocomplete Combobox**: Dynamic HTMX data queries and search hooks.
3. **Refactor Views**: Replace manual HTML blocks in [dashboard.html](file:///home/enciphered/Desktop/Code/stick/templates/tasks/dashboard.html) with:
```html
{% import "components/macros.html" as ui %}
{{ ui::button("Submit", "primary") }}
```
+2 -2
View File
@@ -67,7 +67,7 @@ impl IntoResponse for AppError {
</head> </head>
<body class="bg-[#0f172a] text-slate-100 min-h-screen flex items-center justify-center p-4"> <body class="bg-[#0f172a] text-slate-100 min-h-screen flex items-center justify-center p-4">
<div class="max-w-md w-full bg-[#1e293b] border border-slate-800 rounded-2xl p-8 text-center shadow-2xl relative overflow-hidden"> <div class="max-w-md w-full bg-[#1e293b] border border-slate-800 rounded-2xl p-8 text-center shadow-2xl relative overflow-hidden">
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-red-500 via-rose-500 to-pink-600"></div> <div class="absolute top-0 left-0 w-full h-1 bg-rose-500"></div>
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-rose-950/50 border border-rose-900/50 text-rose-500 mb-6"> <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-rose-950/50 border border-rose-900/50 text-rose-500 mb-6">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-8 h-8"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-8 h-8">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" /> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" />
@@ -79,7 +79,7 @@ impl IntoResponse for AppError {
<a href="/" class="px-5 py-2.5 rounded-xl bg-slate-800 hover:bg-slate-750 transition font-medium text-sm text-slate-200 border border-slate-700"> <a href="/" class="px-5 py-2.5 rounded-xl bg-slate-800 hover:bg-slate-750 transition font-medium text-sm text-slate-200 border border-slate-700">
Go to Safety Go to Safety
</a> </a>
<a href="/auth/login" class="px-5 py-2.5 rounded-xl bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-90 transition font-medium text-sm text-white"> <a href="/auth/login" class="px-5 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 transition font-medium text-sm text-white">
Log In Log In
</a> </a>
</div> </div>
+1 -1
View File
@@ -6,7 +6,7 @@
{% block content %} {% block content %}
<div class="grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8"> <div class="grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-md w-full bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden"> <div class="max-w-md w-full bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden">
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-sky-400 via-blue-500 to-indigo-600"></div> <div class="absolute top-0 left-0 w-full h-1 bg-sky-500"></div>
<div class="text-center mb-8"> <div class="text-center mb-8">
<h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Welcome Back</h2> <h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Welcome Back</h2>
+2 -2
View File
@@ -6,7 +6,7 @@
{% block content %} {% block content %}
<div class="grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8"> <div class="grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-md w-full bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden"> <div class="max-w-md w-full bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden">
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-emerald-400 via-teal-500 to-cyan-600"></div> <div class="absolute top-0 left-0 w-full h-1 bg-emerald-500"></div>
<div class="text-center mb-8"> <div class="text-center mb-8">
<h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Create Account</h2> <h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Create Account</h2>
@@ -37,7 +37,7 @@
{{ ui::text_input(id="password", name="password", label="Password", type="password", placeholder="••••••••", required=true) }} {{ ui::text_input(id="password", name="password", label="Password", type="password", placeholder="••••••••", required=true) }}
<div> <div>
{{ ui::button(label="Sign Up", variant="primary", type="submit", extra_class="w-full py-3.5 bg-gradient-to-r from-emerald-500 to-teal-600 hover:opacity-95 text-white shadow-lg shadow-emerald-500/10 focus:ring-emerald-500") }} {{ ui::button(label="Sign Up", variant="primary", type="submit", extra_class="w-full py-3.5 bg-emerald-600 hover:bg-emerald-700 text-white shadow-lg shadow-emerald-500/10 focus:ring-emerald-500") }}
</div> </div>
</form> </form>
+3 -3
View File
@@ -36,12 +36,12 @@
<!-- Logo --> <!-- Logo -->
<div class="flex items-center space-x-3"> <div class="flex items-center space-x-3">
<a href="/" class="flex items-center space-x-2.5 group"> <a href="/" class="flex items-center space-x-2.5 group">
<div class="w-9 h-9 rounded-xl bg-gradient-to-tr from-sky-400 to-indigo-600 flex items-center justify-center shadow-lg shadow-sky-500/20 group-hover:scale-105 transition-all duration-300"> <div class="w-9 h-9 rounded-xl bg-indigo-600 flex items-center justify-center shadow-lg shadow-indigo-600/10 group-hover:scale-105 transition-all duration-300">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-5 h-5 text-white"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-5 h-5 text-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" /> <path stroke-linecap="round" stroke-linejoin="round" d="m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
</svg> </svg>
</div> </div>
<span class="text-xl font-bold tracking-tight bg-gradient-to-r from-slate-100 to-slate-300 bg-clip-text text-transparent group-hover:from-white group-hover:to-slate-200 transition duration-300"> <span class="text-xl font-bold tracking-tight text-slate-100 group-hover:text-white transition duration-300">
stick stick
</span> </span>
</a> </a>
@@ -72,7 +72,7 @@
<a href="/auth/login" class="text-sm font-medium text-muted-foreground hover:text-white transition py-2 px-3 rounded-lg hover:bg-secondary"> <a href="/auth/login" class="text-sm font-medium text-muted-foreground hover:text-white transition py-2 px-3 rounded-lg hover:bg-secondary">
Log In Log In
</a> </a>
<a href="/auth/register" class="text-sm font-medium text-white bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-90 transition px-4 py-2 rounded-xl shadow-md shadow-sky-500/10"> <a href="/auth/register" class="text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-500 transition px-4 py-2 rounded-xl shadow-md shadow-indigo-600/10">
Sign Up Sign Up
</a> </a>
{% endif %} {% endif %}
+2 -2
View File
@@ -25,7 +25,7 @@
<!-- Architecture & Concept --> <!-- Architecture & Concept -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="border border-border bg-secondary/10 rounded-2xl p-6 space-y-3"> <div class="border border-border bg-secondary/10 rounded-2xl p-6 space-y-3">
<div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-sky-400/20 to-indigo-500/20 border border-sky-500/30 flex items-center justify-center"> <div class="w-10 h-10 rounded-xl bg-sky-500/10 border border-sky-500/20 flex items-center justify-center">
<svg class="h-5 w-5 text-sky-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <svg class="h-5 w-5 text-sky-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/> <path stroke-linecap="round" stroke-linejoin="round" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/>
</svg> </svg>
@@ -37,7 +37,7 @@
</div> </div>
<div class="border border-border bg-secondary/10 rounded-2xl p-6 space-y-3"> <div class="border border-border bg-secondary/10 rounded-2xl p-6 space-y-3">
<div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-emerald-400/20 to-teal-500/20 border border-emerald-500/30 flex items-center justify-center"> <div class="w-10 h-10 rounded-xl bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center">
<svg class="h-5 w-5 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <svg class="h-5 w-5 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z"/> <path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg> </svg>
+2 -2
View File
@@ -6,7 +6,7 @@
{% block content %} {% block content %}
<div class="grow py-12 px-4 sm:px-6 lg:px-8 max-w-lg mx-auto w-full"> <div class="grow py-12 px-4 sm:px-6 lg:px-8 max-w-lg mx-auto w-full">
<div class="bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden"> <div class="bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl p-8 shadow-2xl relative overflow-hidden">
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-sky-400 via-blue-500 to-indigo-600"></div> <div class="absolute top-0 left-0 w-full h-1 bg-sky-500"></div>
<div class="text-center mb-8"> <div class="text-center mb-8">
<h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Edit Developer</h2> <h2 class="text-3xl font-extrabold text-slate-100 tracking-tight">Edit Developer</h2>
@@ -24,7 +24,7 @@
<a href="/developers" class="flex-1 py-3 px-4 text-center text-sm font-semibold rounded-xl text-slate-300 bg-slate-900 border border-slate-800 hover:border-slate-700 transition"> <a href="/developers" class="flex-1 py-3 px-4 text-center text-sm font-semibold rounded-xl text-slate-300 bg-slate-900 border border-slate-800 hover:border-slate-700 transition">
Cancel Cancel
</a> </a>
{{ ui::button(label="Save Changes", variant="indigo", type="submit", extra_class="flex-1 py-3 bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-95 transition shadow-lg shadow-sky-500/10") }} {{ ui::button(label="Save Changes", variant="indigo", type="submit", extra_class="flex-1 py-3 transition shadow-lg shadow-indigo-500/10") }}
</div> </div>
</form> </form>
</div> </div>
+1 -1
View File
@@ -37,7 +37,7 @@
{{ ui::text_input(id="skills", name="skills", label="Skills (Comma-separated)", type="text", placeholder="e.g. Rust, Axum, MongoDB") }} {{ ui::text_input(id="skills", name="skills", label="Skills (Comma-separated)", type="text", placeholder="e.g. Rust, Axum, MongoDB") }}
{{ ui::button(label="Create Developer", variant="indigo", type="submit", extra_class="w-full py-3 bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-95 transition shadow-md shadow-sky-500/10") }} {{ ui::button(label="Create Developer", variant="indigo", type="submit", extra_class="w-full py-3 transition shadow-md shadow-indigo-500/10") }}
</form> </form>
</div> </div>
</div> </div>
+4 -4
View File
@@ -12,9 +12,9 @@
</span> </span>
<!-- Hero Title --> <!-- Hero Title -->
<h1 class="text-4xl sm:text-6xl font-extrabold tracking-tight mb-6 bg-linear-to-r from-slate-100 via-slate-200 to-slate-400 bg-clip-text text-transparent leading-none"> <h1 class="text-4xl sm:text-6xl font-extrabold tracking-tight mb-6 text-slate-100 leading-none">
Clean, Use-Case Centric <br class="hidden sm:inline"> Clean, Use-Case Centric <br class="hidden sm:inline">
<span class="bg-linear-to-r from-sky-400 via-blue-500 to-indigo-500 bg-clip-text">Rust Web Development</span> <span class="text-indigo-500">Rust Web Development</span>
</h1> </h1>
<!-- Subtitle --> <!-- Subtitle -->
@@ -25,11 +25,11 @@
<!-- CTA Buttons --> <!-- CTA Buttons -->
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16"> <div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
{% if authenticated %} {% if authenticated %}
<a href="/tasks" class="px-8 py-4 rounded-2xl bg-linear-to-r from-sky-500 via-blue-600 to-indigo-600 hover:opacity-95 transition font-semibold text-white shadow-xl shadow-sky-500/10 hover:shadow-sky-500/20 scale-100 hover:scale-[1.02] transform duration-200"> <a href="/tasks" class="px-8 py-4 rounded-2xl bg-indigo-600 hover:bg-indigo-500 transition font-semibold text-white shadow-xl shadow-indigo-600/10 hover:shadow-indigo-600/20 scale-100 hover:scale-[1.02] transform duration-200">
Go to Tasks Dashboard Go to Tasks Dashboard
</a> </a>
{% else %} {% else %}
<a href="/auth/register" class="px-8 py-4 rounded-2xl bg-linear-to-r from-sky-500 via-blue-600 to-indigo-600 hover:opacity-95 transition font-semibold text-white shadow-xl shadow-sky-500/10 hover:shadow-sky-500/20 scale-100 hover:scale-[1.02] transform duration-200"> <a href="/auth/register" class="px-8 py-4 rounded-2xl bg-indigo-600 hover:bg-indigo-500 transition font-semibold text-white shadow-xl shadow-indigo-600/10 hover:shadow-indigo-600/20 scale-100 hover:scale-[1.02] transform duration-200">
Get Started Free Get Started Free
</a> </a>
<a href="/auth/login" class="px-8 py-4 rounded-2xl bg-slate-900/60 hover:bg-slate-900 border border-slate-800 hover:border-slate-700 transition font-semibold text-slate-200 scale-100 hover:scale-[1.02] transform duration-200"> <a href="/auth/login" class="px-8 py-4 rounded-2xl bg-slate-900/60 hover:bg-slate-900 border border-slate-800 hover:border-slate-700 transition font-semibold text-slate-200 scale-100 hover:scale-[1.02] transform duration-200">
+2 -2
View File
@@ -17,7 +17,7 @@
Total Tasks: {{ tasks.len() }} Total Tasks: {{ tasks.len() }}
</span> </span>
<!-- Info trigger button --> <!-- Info trigger button -->
{{ ui::modal_trigger(target_id="task-info-modal", label="<svg class='w-4 h-4' fill='none' stroke='currentColor' viewBox='0 0 24 24'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z'/></svg>", variant="outline", extra_class="px-2.5 py-2.5") }} {{ ui::modal_trigger(target_id="task-info-modal", label="<svg class='w-4 h-4' fill='none' stroke='currentColor' viewBox='0 0 24 24'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z'/></svg>", variant="outline", extra_class="w-9 h-9 !p-0 flex items-center justify-center") }}
</div> </div>
</div> </div>
@@ -43,7 +43,7 @@
{{ ui::search_combobox(name="assignee_id", label="Assignee (Optional)", placeholder="Search developer...", search_url="/developers/search", input_id="assignee-search", value_id="assignee-id") }} {{ ui::search_combobox(name="assignee_id", label="Assignee (Optional)", placeholder="Search developer...", search_url="/developers/search", input_id="assignee-search", value_id="assignee-id") }}
<!-- Create Task submit button using macro --> <!-- Create Task submit button using macro -->
{{ ui::button(label="Create Task", variant="indigo", type="submit", extra_class="w-full py-3 bg-gradient-to-r from-sky-500 to-indigo-600 hover:opacity-95 transition shadow-md shadow-sky-500/10") }} {{ ui::button(label="Create Task", variant="indigo", type="submit", extra_class="w-full py-3 transition shadow-md shadow-indigo-500/10") }}
</form> </form>
</div> </div>
</div> </div>