Эх сурвалжийг харах

Release: Version 0.1 (Beta) - Cleanup and documentation

Preparing for v0.1 beta release with cleanup and updated documentation.

**Cleanup:**
- Removed style.css.backup (no longer needed)
- Cleaned up temporary files

**Documentation:**
- Updated README.md with comprehensive v0.1 information
- Added feature list and what's new section
- Added installation and quick start guide
- Added usage instructions
- Added configuration table
- Added branching strategy documentation
- Added version history section
- Added beta release notice

**Version 0.1 Features:**
- Multi-user authentication system
- AI-powered recommendations with Google Gemini
- Reading log with statistics and charts
- Admin panel with user management
- *arr-style dark theme with sidebar navigation
- Book rating system
- Local cover image caching
- Fixed author extraction and hours calculation

**Going Forward:**
- Using feature branches for all changes
- Master branch is stable/production
- All new work happens in feature/* branches

This marks the first official beta release of Dewy Oracle!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Brad Lance 3 сар өмнө
parent
commit
44f6d4e16b
2 өөрчлөгдсөн 130 нэмэгдсэн , 870 устгасан
  1. 130 19
      README.md
  2. 0 851
      app/static/css/style.css.backup

+ 130 - 19
README.md

@@ -1,41 +1,152 @@
 # Dewy Oracle
 
-A web application that tracks your Audiobookshelf listening history and provides AI-powered book recommendations.
+> **Version 0.1 (Beta)** - AI-powered book recommendations for Audiobookshelf
 
-## Features
+A self-hosted web application that syncs with your Audiobookshelf server to track listening history and provide personalized book recommendations using Google Gemini AI.
 
-- Syncs with Audiobookshelf server to track reading progress
-- AI-powered book recommendations based on your listening history
-- Web interface to view history and recommendations
-- REST API for programmatic access
+## ✨ Features
 
-## Setup
+### Core Features
+- 🔄 **Audiobookshelf Sync** - Automatic sync of listening history and progress
+- 🤖 **AI Recommendations** - Google Gemini-powered book suggestions based on your tastes
+- 📊 **Reading Analytics** - Track books finished, hours listened, streaks, and genres
+- ⭐ **Book Ratings** - Rate and track your favorite audiobooks
+- 👥 **Multi-User Support** - Individual accounts with separate libraries
+- 🎨 ***arr-Style Dark Theme** - Professional UI matching Sonarr/Radarr aesthetic
+- 🔐 **Admin Panel** - User management, password changes, and settings
 
-1. Install dependencies:
+### What's New in v0.1
+- Complete dark theme redesign with sidebar navigation
+- Admin user creation and password management
+- Fixed author name extraction from Audiobookshelf API
+- Accurate hours calculation using actual audiobook duration
+- Working book rating system
+- Local cover image caching
+
+## 🚀 Quick Start
+
+### Prerequisites
+- Python 3.12+
+- Audiobookshelf server with API access
+- Google Gemini API key
+
+### Installation
+
+1. **Clone the repository**
+```bash
+git clone https://git.mrbamm.xyz/Dewey_Orcale/dewey-oracle.git
+cd dewey-oracle
+```
+
+2. **Create virtual environment**
+```bash
+python3 -m venv venv
+source venv/bin/activate
+```
+
+3. **Install dependencies**
 ```bash
 pip install -r requirements.txt
 ```
 
-2. Configure environment variables:
+4. **Configure environment**
 ```bash
 cp .env.example .env
-# Edit .env with your Audiobookshelf URL, API token, and AI API key
+# Edit .env and add your GEMINI_API_KEY
 ```
 
-3. Run the application:
+5. **Run the application**
 ```bash
 python main.py
 ```
 
-4. Access the web interface at `http://localhost:8000`
+6. **Access the web interface**
+- Open http://localhost:8000
+- Register first user account
+- Enter your Audiobookshelf server URL and API token
+- Sync your library and generate recommendations!
+
+### Production Deployment (systemd)
+
+```bash
+./setup-service.sh
+```
+
+## 📖 Usage
+
+1. **Register** - Create your account with Audiobookshelf credentials
+2. **Sync** - Click "Sync with Audiobookshelf" to import your library
+3. **Get Recommendations** - Click "Generate New Recommendations"
+4. **View Stats** - Check your reading log for analytics and insights
+5. **Rate Books** - Rate finished books to improve future recommendations
+
+## 🛠️ Configuration
+
+### Environment Variables
+
+| Variable | Required | Default | Description |
+|----------|----------|---------|-------------|
+| `GEMINI_API_KEY` | Yes | - | Google Gemini API key |
+| `SECRET_KEY` | No | Auto-generated | Session encryption key |
+| `DATABASE_URL` | No | `sqlite:///./absrecommend.db` | Database path |
+| `HOST` | No | `0.0.0.0` | Server host |
+| `PORT` | No | `8000` | Server port |
+
+### Per-User Settings
+- Audiobookshelf server URL
+- Audiobookshelf API token (encrypted in database)
+
+## 🏗️ Development
+
+### Branching Strategy (v0.1+)
+Starting with version 0.1, we use feature branches:
+
+```bash
+# Create feature branch
+git checkout -b feature/your-feature-name
+
+# Make changes and commit
+git add .
+git commit -m "Description"
+
+# Push to remote
+git push origin feature/your-feature-name
+
+# Merge to master when ready
+```
+
+### Tech Stack
+- **Backend**: FastAPI, Python 3.12, SQLAlchemy (async)
+- **Frontend**: Jinja2, Vanilla JS, Chart.js
+- **Database**: SQLite (aiosqlite)
+- **AI**: Google Gemini 2.5 Flash
+- **External API**: Audiobookshelf REST API
+
+## 📝 Version History
+
+### v0.1 (Beta) - January 2026
+- Initial beta release
+- Multi-user authentication system
+- AI-powered recommendations with Gemini
+- Reading log with statistics and charts
+- Admin panel with user management
+- Dark theme with sidebar navigation
+- Book rating system
+- Local cover caching
+
+## 🤝 Contributing
+
+This project uses feature branches. Create a branch for your changes and submit via pull request.
+
+## 📄 License
+
+See repository for license information.
 
-## API Endpoints
+## 🔗 Links
 
-- `GET /` - Web interface
-- `GET /api/sync` - Sync with Audiobookshelf
-- `GET /api/recommendations` - Get book recommendations
-- `GET /api/history` - View listening history
+- **Repository**: https://git.mrbamm.xyz/Dewey_Orcale/dewey-oracle
+- **Issues**: Use Gogs issue tracker
 
-## Configuration
+---
 
-See `.env.example` for all configuration options.
+**Note**: This is a beta release (v0.1). Some features may have rough edges. Please report issues via the Gogs issue tracker.

+ 0 - 851
app/static/css/style.css.backup

@@ -1,851 +0,0 @@
-* {
-    margin: 0;
-    padding: 0;
-    box-sizing: border-box;
-}
-
-body {
-    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
-    line-height: 1.6;
-    color: #333;
-    background-color: #f5f5f5;
-}
-
-.container {
-    max-width: 1200px;
-    margin: 0 auto;
-    padding: 20px;
-}
-
-header {
-    text-align: center;
-    margin-bottom: 40px;
-    padding: 30px 0;
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    color: white;
-    border-radius: 10px;
-}
-
-header h1 {
-    font-size: 2.5rem;
-    margin-bottom: 10px;
-}
-
-.subtitle {
-    font-size: 1.1rem;
-    opacity: 0.9;
-}
-
-.actions {
-    display: flex;
-    gap: 15px;
-    justify-content: center;
-    margin-bottom: 30px;
-}
-
-.btn {
-    padding: 12px 24px;
-    font-size: 1rem;
-    border: none;
-    border-radius: 6px;
-    cursor: pointer;
-    transition: all 0.3s ease;
-    font-weight: 500;
-}
-
-.btn-primary {
-    background-color: #667eea;
-    color: white;
-}
-
-.btn-primary:hover {
-    background-color: #5568d3;
-    transform: translateY(-2px);
-}
-
-.btn-secondary {
-    background-color: #764ba2;
-    color: white;
-}
-
-.btn-secondary:hover {
-    background-color: #643a8a;
-    transform: translateY(-2px);
-}
-
-.message {
-    padding: 15px 20px;
-    border-radius: 6px;
-    margin-bottom: 20px;
-    text-align: center;
-}
-
-.message.success {
-    background-color: #d4edda;
-    color: #155724;
-    border: 1px solid #c3e6cb;
-}
-
-.message.error {
-    background-color: #f8d7da;
-    color: #721c24;
-    border: 1px solid #f5c6cb;
-}
-
-/* General hidden class */
-.hidden {
-    display: none;
-}
-
-.message.hidden {
-    display: none;
-}
-
-.section {
-    background: white;
-    padding: 30px;
-    border-radius: 10px;
-    margin-bottom: 30px;
-    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
-}
-
-.section h2 {
-    font-size: 1.8rem;
-    margin-bottom: 20px;
-    color: #667eea;
-}
-
-.recommendations-grid {
-    display: grid;
-    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
-    gap: 20px;
-}
-
-.recommendation-card {
-    background: #f9f9f9;
-    padding: 20px;
-    border-radius: 8px;
-    border: 1px solid #e0e0e0;
-    transition: transform 0.2s ease, box-shadow 0.2s ease;
-}
-
-.recommendation-card:hover {
-    transform: translateY(-4px);
-    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
-}
-
-.recommendation-card h3 {
-    font-size: 1.3rem;
-    margin-bottom: 5px;
-    color: #333;
-}
-
-.author {
-    color: #666;
-    font-style: italic;
-    margin-bottom: 10px;
-}
-
-.description {
-    margin-bottom: 15px;
-    line-height: 1.5;
-}
-
-.reason {
-    background: #fff;
-    padding: 10px;
-    border-left: 3px solid #667eea;
-    margin-bottom: 10px;
-}
-
-.reason strong {
-    color: #667eea;
-}
-
-.reason p {
-    margin-top: 5px;
-    font-size: 0.95rem;
-}
-
-.genres {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 8px;
-    margin-top: 10px;
-}
-
-.genre-tag {
-    background: #667eea;
-    color: white;
-    padding: 4px 12px;
-    border-radius: 20px;
-    font-size: 0.85rem;
-}
-
-.history-list {
-    display: flex;
-    flex-direction: column;
-    gap: 15px;
-}
-
-.history-item {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    padding: 15px;
-    background: #f9f9f9;
-    border-radius: 8px;
-    border: 1px solid #e0e0e0;
-}
-
-.book-info h3 {
-    font-size: 1.1rem;
-    margin-bottom: 5px;
-}
-
-.status {
-    padding: 6px 12px;
-    border-radius: 20px;
-    font-size: 0.9rem;
-    font-weight: 500;
-}
-
-.status.finished {
-    background-color: #d4edda;
-    color: #155724;
-}
-
-.status.in-progress {
-    background-color: #fff3cd;
-    color: #856404;
-}
-
-.empty-state {
-    text-align: center;
-    color: #999;
-    padding: 40px;
-    font-size: 1.1rem;
-}
-
-/* ==================== Navigation ====================*/
-
-.navbar {
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    color: white;
-    padding: 0;
-    margin-bottom: 20px;
-    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
-}
-
-.nav-container {
-    max-width: 1200px;
-    margin: 0 auto;
-    padding: 15px 20px;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-}
-
-.nav-brand a {
-    color: white;
-    text-decoration: none;
-    font-size: 1.3rem;
-    font-weight: 600;
-    display: flex;
-    align-items: center;
-}
-
-.nav-logo {
-    height: 32px;
-    margin-right: 12px;
-}
-
-.nav-links {
-    display: flex;
-    list-style: none;
-    gap: 30px;
-}
-
-.nav-links a {
-    color: white;
-    text-decoration: none;
-    transition: opacity 0.3s ease;
-}
-
-.nav-links a:hover {
-    opacity: 0.8;
-}
-
-.nav-user {
-    display: flex;
-    align-items: center;
-    gap: 15px;
-}
-
-.user-name {
-    font-weight: 500;
-}
-
-.btn-text {
-    background: transparent;
-    color: white;
-    border: 1px solid rgba(255,255,255,0.3);
-    padding: 8px 16px;
-}
-
-.btn-text:hover {
-    background: rgba(255,255,255,0.1);
-}
-
-
-/* ==================== Authentication Pages ====================*/
-
-.auth-container {
-    min-height: 100vh;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    padding: 20px;
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-}
-
-.auth-card {
-    background: white;
-    padding: 40px;
-    border-radius: 12px;
-    box-shadow: 0 8px 24px rgba(0,0,0,0.15);
-    max-width: 480px;
-    width: 100%;
-}
-
-.auth-card h1 {
-    text-align: center;
-    color: #333;
-    margin-bottom: 10px;
-    font-size: 2rem;
-}
-
-.auth-subtitle {
-    text-align: center;
-    color: #666;
-    margin-bottom: 30px;
-}
-
-.form-group {
-    margin-bottom: 20px;
-}
-
-.form-group label {
-    display: block;
-    margin-bottom: 8px;
-    color: #333;
-    font-weight: 500;
-}
-
-.form-group input {
-    width: 100%;
-    padding: 12px;
-    border: 1px solid #ddd;
-    border-radius: 6px;
-    font-size: 1rem;
-    transition: border-color 0.3s ease;
-}
-
-.form-group input:focus {
-    outline: none;
-    border-color: #667eea;
-    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
-}
-
-.form-group small {
-    display: block;
-    margin-top: 5px;
-    color: #666;
-    font-size: 0.85rem;
-}
-
-.form-section {
-    margin-top: 30px;
-    padding-top: 30px;
-    border-top: 1px solid #e0e0e0;
-}
-
-.form-section h3 {
-    color: #667eea;
-    margin-bottom: 10px;
-}
-
-.form-help {
-    color: #666;
-    font-size: 0.9rem;
-    margin-bottom: 20px;
-}
-
-.btn-full {
-    width: 100%;
-    padding: 14px;
-    font-size: 1.1rem;
-}
-
-.auth-footer {
-    text-align: center;
-    margin-top: 20px;
-    padding-top: 20px;
-    border-top: 1px solid #e0e0e0;
-}
-
-.auth-footer a {
-    color: #667eea;
-    text-decoration: none;
-    font-weight: 500;
-}
-
-.auth-footer a:hover {
-    text-decoration: underline;
-}
-
-
-/* ==================== Landing Page ====================*/
-
-.landing-container {
-    min-height: 100vh;
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    color: white;
-    padding: 40px 20px;
-}
-
-.landing-hero {
-    text-align: center;
-    max-width: 800px;
-    margin: 0 auto 80px;
-    padding-top: 80px;
-}
-
-.landing-hero h1 {
-    font-size: 3.5rem;
-    margin-bottom: 20px;
-}
-
-.landing-subtitle {
-    font-size: 1.3rem;
-    opacity: 0.95;
-    margin-bottom: 40px;
-}
-
-.landing-actions {
-    display: flex;
-    gap: 20px;
-    justify-content: center;
-}
-
-.btn-large {
-    padding: 16px 40px;
-    font-size: 1.2rem;
-    text-decoration: none;
-    display: inline-block;
-}
-
-.landing-features {
-    max-width: 1000px;
-    margin: 0 auto;
-}
-
-.landing-features h2 {
-    text-align: center;
-    font-size: 2.5rem;
-    margin-bottom: 40px;
-}
-
-.features-grid {
-    display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
-    gap: 30px;
-}
-
-.feature-card {
-    background: rgba(255,255,255,0.1);
-    padding: 30px;
-    border-radius: 12px;
-    backdrop-filter: blur(10px);
-    border: 1px solid rgba(255,255,255,0.2);
-}
-
-.feature-card h3 {
-    font-size: 1.5rem;
-    margin-bottom: 15px;
-}
-
-.feature-card p {
-    opacity: 0.9;
-    line-height: 1.6;
-}
-
-
-/* ==================== Reading Log ====================*/
-
-.stats-grid {
-    display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
-    gap: 20px;
-    margin-bottom: 30px;
-}
-
-.stat-card {
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    color: white;
-    padding: 25px;
-    border-radius: 10px;
-    text-align: center;
-    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
-}
-
-.stat-value {
-    font-size: 2.5rem;
-    font-weight: bold;
-    margin-bottom: 5px;
-}
-
-.stat-label {
-    font-size: 0.95rem;
-    opacity: 0.9;
-}
-
-.charts-container {
-    display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
-    gap: 30px;
-}
-
-.chart-card {
-    background: white;
-    padding: 20px;
-    border-radius: 10px;
-    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
-}
-
-.chart-card h3 {
-    color: #667eea;
-    margin-bottom: 20px;
-    text-align: center;
-}
-
-.books-grid {
-    display: grid;
-    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
-    gap: 20px;
-}
-
-.book-card {
-    background: #f9f9f9;
-    padding: 20px;
-    border-radius: 8px;
-    border: 1px solid #e0e0e0;
-    transition: transform 0.2s ease, box-shadow 0.2s ease;
-}
-
-.book-card:hover {
-    transform: translateY(-4px);
-    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
-}
-
-.book-cover {
-    width: 100%;
-    height: 200px;
-    object-fit: cover;
-    border-radius: 6px;
-    margin-bottom: 15px;
-}
-
-.book-title {
-    font-size: 1.2rem;
-    margin-bottom: 5px;
-    color: #333;
-}
-
-.book-author {
-    color: #666;
-    font-style: italic;
-    margin-bottom: 10px;
-}
-
-.book-meta {
-    display: flex;
-    justify-content: space-between;
-    font-size: 0.85rem;
-    color: #666;
-    margin-bottom: 10px;
-}
-
-.book-rating {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-top: 15px;
-    padding-top: 15px;
-    border-top: 1px solid #e0e0e0;
-}
-
-.rating-stars {
-    color: #f59e0b;
-    font-size: 1.2rem;
-}
-
-.btn-small {
-    padding: 6px 14px;
-    font-size: 0.85rem;
-}
-
-.loading {
-    text-align: center;
-    padding: 40px;
-    color: #999;
-}
-
-
-/* ==================== Responsive Design ====================*/
-
-@media (max-width: 768px) {
-    header h1 {
-        font-size: 2rem;
-    }
-
-    .actions {
-        flex-direction: column;
-    }
-
-    .recommendations-grid {
-        grid-template-columns: 1fr;
-    }
-
-    .history-item {
-        flex-direction: column;
-        align-items: flex-start;
-        gap: 10px;
-    }
-
-    .nav-container {
-        flex-direction: column;
-        gap: 15px;
-    }
-
-    .nav-links {
-        gap: 15px;
-    }
-
-    .landing-hero h1 {
-        font-size: 2.5rem;
-    }
-
-    .landing-actions {
-        flex-direction: column;
-        align-items: center;
-    }
-
-    .charts-container {
-        grid-template-columns: 1fr;
-    }
-
-    .stats-grid {
-        grid-template-columns: repeat(2, 1fr);
-    }
-}
-
-/* ==================== Admin Panel Styles ==================== */
-
-.settings-grid {
-    display: grid;
-    gap: 20px;
-    margin-top: 20px;
-}
-
-.setting-item {
-    background: white;
-    padding: 20px;
-    border-radius: 8px;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.setting-item label {
-    display: flex;
-    align-items: center;
-    gap: 10px;
-    cursor: pointer;
-    font-size: 1rem;
-}
-
-.setting-item input[type="checkbox"] {
-    width: 20px;
-    height: 20px;
-    cursor: pointer;
-}
-
-.section-actions {
-    display: flex;
-    gap: 10px;
-    margin-bottom: 20px;
-}
-
-.users-table {
-    width: 100%;
-    background: white;
-    border-radius: 8px;
-    overflow: hidden;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-    border-collapse: collapse;
-}
-
-.users-table thead {
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    color: white;
-}
-
-.users-table th {
-    padding: 15px;
-    text-align: left;
-    font-weight: 600;
-}
-
-.users-table td {
-    padding: 15px;
-    border-bottom: 1px solid #e0e0e0;
-}
-
-.users-table tbody tr:hover {
-    background-color: #f5f5f5;
-}
-
-.users-table tbody tr:last-child td {
-    border-bottom: none;
-}
-
-.badge {
-    display: inline-block;
-    padding: 4px 8px;
-    border-radius: 4px;
-    font-size: 0.85rem;
-    font-weight: 600;
-}
-
-.badge-admin {
-    background-color: #fbbf24;
-    color: #78350f;
-}
-
-.badge-active {
-    background-color: #34d399;
-    color: #064e3b;
-}
-
-.badge-inactive {
-    background-color: #f87171;
-    color: #7f1d1d;
-}
-
-.btn-danger {
-    background-color: #ef4444;
-}
-
-.btn-danger:hover {
-    background-color: #dc2626;
-}
-
-.text-muted {
-    color: #999;
-    font-style: italic;
-}
-
-/* ==================== Modals ==================== */
-
-.modal {
-    position: fixed;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background-color: rgba(0, 0, 0, 0.6);
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    z-index: 1000;
-}
-
-.modal.hidden {
-    display: none;
-}
-
-.modal-content {
-    background: white;
-    border-radius: 12px;
-    padding: 0;
-    width: 90%;
-    max-width: 600px;
-    max-height: 90vh;
-    overflow-y: auto;
-    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
-}
-
-.modal-content.modal-small {
-    max-width: 400px;
-}
-
-.modal-header {
-    padding: 20px 25px;
-    border-bottom: 1px solid #e0e0e0;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    color: white;
-    border-radius: 12px 12px 0 0;
-}
-
-.modal-header h2 {
-    margin: 0;
-    font-size: 1.5rem;
-}
-
-.btn-close {
-    background: none;
-    border: none;
-    color: white;
-    font-size: 2rem;
-    cursor: pointer;
-    padding: 0;
-    width: 32px;
-    height: 32px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    border-radius: 4px;
-    transition: background-color 0.2s;
-}
-
-.btn-close:hover {
-    background-color: rgba(255, 255, 255, 0.2);
-}
-
-.modal-content form {
-    padding: 25px;
-}
-
-.modal-actions {
-    display: flex;
-    gap: 10px;
-    justify-content: flex-end;
-    margin-top: 20px;
-    padding-top: 20px;
-    border-top: 1px solid #e0e0e0;
-}
-
-.form-section {
-    margin-top: 20px;
-    padding-top: 20px;
-    border-top: 1px solid #e0e0e0;
-}
-
-.form-section h3 {
-    margin-top: 0;
-    margin-bottom: 15px;
-    color: #333;
-    font-size: 1.1rem;
-}