- Add hybrid modal/page navigation based on screen size (1024px breakpoint) - Desktop (>1024px): Uses modal overlays for quick interactions - Mobile (≤1024px): Navigates to dedicated full pages for better UX - Extract shared NPC chat content into reusable partial template - Add responsive navigation JavaScript (responsive-modals.js) - Create dedicated NPC chat page route with back button navigation - Add mobile-optimized CSS with sticky header and chat input - Fix HTMX indicator errors by using htmx-indicator class pattern - Document responsive modal pattern for future features Addresses mobile UX issues: cramped space, nested scrolling, keyboard conflicts, and lack of native back button support in modals. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Code of Conquest - Public Web Frontend
Traditional web frontend for Code of Conquest, providing HTML/HTMX UI for browser-based gameplay.
Overview
This is the public web frontend component of Code of Conquest. It provides:
- HTML-based UI using Jinja2 templates
- Interactive forms with HTMX
- Character creation wizard
- Session-based authentication
- Responsive design
Architecture: Lightweight view layer that makes HTTP requests to the API backend for all business logic.
Tech Stack
- Framework: Flask 3.x
- Templates: Jinja2
- Interactivity: HTMX
- Styling: Vanilla CSS
- API Client: Python requests library
- Logging: Structlog
- WSGI Server: Gunicorn
Setup
Prerequisites
- Python 3.11+
- Running API backend (see
/api)
Installation
- Create virtual environment:
python3 -m venv venv
source venv/bin/activate
- Install dependencies:
pip install -r requirements.txt
- Configure environment:
cp .env.example .env
# Edit .env with your settings
Running Locally
Development mode:
# Activate virtual environment
source venv/bin/activate
# Set environment
export FLASK_ENV=development
# Run development server
python wsgi.py
The web UI will be available at http://localhost:5001
Production mode:
gunicorn --bind 0.0.0.0:8080 --workers 4 wsgi:app
Configuration
Environment-specific configs are in /config:
development.yaml- Local development settingsproduction.yaml- Production settings
Key settings:
- Server: Port (5001 dev, 8080 prod), workers
- API: Backend URL, timeout
- Session: Cookie settings, lifetime
- UI: Theme, pagination
Project Structure
public_web/
├── app/ # Application code
│ ├── views/ # View blueprints (Flask routes)
│ └── utils/ # Utilities (logging, auth helpers, API client)
├── templates/ # Jinja2 HTML templates
│ ├── auth/ # Authentication pages
│ ├── character/ # Character pages
│ ├── errors/ # Error pages (404, 500)
│ └── base.html # Base template
├── static/ # CSS, JS, images
│ └── css/ # Stylesheets
├── docs/ # Service-specific documentation
├── config/ # Configuration files
├── logs/ # Application logs
├── requirements.txt # Python dependencies
├── wsgi.py # WSGI entry point
└── .env.example # Environment template
Features
Authentication
- Login / Register
- Password reset
- Email verification
- Session management
Character Management
- Character creation wizard (4 steps)
- Origin selection
- Class selection
- Customization
- Confirmation
- Character list view
- Character detail page
UI/UX
- Dark theme
- Responsive design
- HTMX-powered interactivity
- Form validation
- Loading states
Development
Adding New Pages
- Create template in
/templates:
{% extends "base.html" %}
{% block content %}
<!-- Your content -->
{% endblock %}
- Create view in
/app/views:
@blueprint.route('/your-route')
def your_view():
return render_template('your_template.html')
- Register blueprint in
/app/__init__.py
Making API Calls
All views use the APIClient class to communicate with the API backend:
from app.utils.api_client import get_api_client, APIError
api_client = get_api_client()
# GET request
try:
response = api_client.get("/api/v1/characters")
characters = response.get('result', {}).get('characters', [])
except APIError as e:
flash(f'Error: {e.message}', 'error')
# POST request
response = api_client.post("/api/v1/characters", data={
'name': 'Hero',
'class_id': 'warrior',
'origin_id': 'noble'
})
The API client handles:
- Session cookie forwarding
- Error handling with typed exceptions (
APIError,APINotFoundError,APITimeoutError) - JSON serialization/deserialization
- SSL verification and timeouts from config
Testing
Currently, the public web frontend relies on manual testing. Use the API for automated testing.
Manual testing checklist:
- Login flow
- Registration flow
- Character creation wizard (all 4 steps)
- Character list and detail views
- Logout
- Error handling
Deployment
See DEPLOYMENT.md for production deployment instructions.
Environment Variables
Required environment variables:
FLASK_ENV- development or productionSECRET_KEY- Flask session secret (generate random string)API_BASE_URL- (Optional) API backend URL
Related Components
- API Backend:
/api- REST API that this frontend calls - Godot Client:
/godot_client- Alternative native game client
Development Guidelines
See CLAUDE.md in the project root for:
- Coding standards
- Template best practices
- Git conventions
- Project workflow
License
Proprietary - All rights reserved