Compare commits

..

3 Commits

Author SHA1 Message Date
Flatlogic Bot
cb50a4f05e Auto commit: 2025-12-18T02:00:12.638Z 2025-12-18 02:00:12 +00:00
Flatlogic Bot
ac6e16f3bd ai agent 2025-12-17 05:03:15 +00:00
Flatlogic Bot
551b959be1 ai agent creator 2025-12-17 04:34:43 +00:00
24 changed files with 809 additions and 168 deletions

View File

@ -155,6 +155,8 @@ STATICFILES_DIRS = [
BASE_DIR / 'node_modules', BASE_DIR / 'node_modules',
] ]
LOGIN_URL = '/login/'
# Email # Email
EMAIL_BACKEND = os.getenv( EMAIL_BACKEND = os.getenv(
"EMAIL_BACKEND", "EMAIL_BACKEND",

Binary file not shown.

View File

@ -1,3 +1,10 @@
from django.contrib import admin from django.contrib import admin
from .models import Agent
# Register your models here. # Register your models here.
@admin.register(Agent)
class AgentAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'published', 'created_at')
list_filter = ('published', 'user')
search_fields = ('name', 'description')

10
core/forms.py Normal file
View File

@ -0,0 +1,10 @@
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')
class Meta:
model = User
fields = ('username', 'email', 'password', 'password2')

View File

@ -0,0 +1,29 @@
# Generated by Django 5.2.7 on 2025-12-17 04:36
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Agent',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('description', models.TextField(blank=True)),
('published', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -1,3 +1,15 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User
# Create your models here. # Create your models here.
class Agent(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) # Allow null user for now
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>{% block title %}Knowledge Base{% endblock %}</title> <title>{% block title %}AI Agent Studio{% endblock %}</title>
{% if project_description %} {% if project_description %}
<meta name="description" content="{{ project_description }}"> <meta name="description" content="{{ project_description }}">
<meta property="og:description" content="{{ project_description }}"> <meta property="og:description" content="{{ project_description }}">
@ -14,12 +14,41 @@
<meta property="twitter:image" content="{{ project_image_url }}"> <meta property="twitter:image" content="{{ project_image_url }}">
{% endif %} {% endif %}
{% load static %} {% load static %}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}"> <link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
{% block head %}{% endblock %} {% block head %}{% endblock %}
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: #1A237E;">
<div class="container">
<a class="navbar-brand" href="{% url 'home' %}">AI Agent Studio</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="{% url 'home' %}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'create_agent' %}">Create Agent</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'my_agents' %}">My Agents</a>
</li>
</ul>
</div>
</div>
</nav>
{% block content %}{% endblock %} {% block content %}{% endblock %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
{% block extra_js %}{% endblock %}
</body> </body>
</html> </html>

View File

@ -1,14 +1,19 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}{{ article.title }}{% endblock %} {% block title %}{{ agent.name }} - AI Agent{% endblock %}
{% block content %} {% block content %}
<div class="container mt-5"> <div class="container mt-5">
<h1>{{ article.title }}</h1> <div class="row">
<p class="text-muted">Published on {{ article.created_at|date:"F d, Y" }}</p> <div class="col-lg-8 offset-lg-2">
<hr> <div class="agent-detail-header text-center mb-4">
<div> <h1 class="display-4">{{ agent.name }}</h1>
{{ article.content|safe }} </div>
<div class="agent-detail-body">
<p class="lead">{{ agent.description }}</p>
<!-- Add more agent details here as needed -->
</div>
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block content %}
<div class="container mt-5">
<h1 class="display-4">Create a New Agent</h1>
<p class="lead">Define the name and description of your new AI agent.</p>
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="e.g., 'Customer Support Bot'">
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="3" placeholder="e.g., 'An AI assistant that answers customer questions.'"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create Agent</button>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block content %}
<div class="container mt-5">
<h1 class="display-4">Edit Agent</h1>
<p class="lead">Edit the details of your AI agent.</p>
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" value="{{ agent.name }}">
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="3">{{ agent.description }}</textarea>
</div>
<button type="submit" class="btn btn-primary">Save Changes</button>
</form>
</div>
{% endblock %}

View File

@ -1,145 +1,52 @@
{% extends "base.html" %} {% extends 'base.html' %}
{% load static %}
{% block title %}{{ project_name }}{% endblock %} {% block title %}AI Agent Studio - Build & Deploy AI Agents{% endblock %}
{% block head %} {% block head %}
<link rel="preconnect" href="https://fonts.googleapis.com"> <meta name="description" content="A collaborative platform to design, test, and run high-end AI agents with unlimited usage.">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'><path d='M-10 10L110 10M10 -10L10 110' stroke-width='1' stroke='rgba(255,255,255,0.05)'/></svg>");
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% {
background-position: 0% 0%;
}
100% {
background-position: 100% 100%;
}
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2.5rem 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25);
}
h1 {
font-size: clamp(2.2rem, 3vw + 1.2rem, 3.2rem);
font-weight: 700;
margin: 0 0 1.2rem;
letter-spacing: -0.02em;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
opacity: 0.92;
}
.loader {
margin: 1.5rem auto;
width: 56px;
height: 56px;
border: 4px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.runtime code {
background: rgba(0, 0, 0, 0.25);
padding: 0.15rem 0.45rem;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
footer {
position: absolute;
bottom: 1rem;
width: 100%;
text-align: center;
font-size: 0.85rem;
opacity: 0.75;
}
</style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<main> <div class="hero">
<div class="card"> <div class="container">
<h1>Analyzing your requirements and generating your app…</h1> <h1>Welcome to AI Agent Studio</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes"> <p>The open-source platform to design, test, and deploy powerful AI agents. No limits, no pricing tiers.</p>
<span class="sr-only">Loading…</span> <a href="{% url 'create_agent' %}" class="btn btn-primary btn-lg">Start Building Your First Agent</a>
</div> </div>
<p class="hint">AppWizzy AI is collecting your requirements and applying the first changes.</p> </div>
<p class="hint">This page will refresh automatically as the plan is implemented.</p>
<p class="runtime"> <div class="container agent-showcase">
Runtime: Django <code>{{ django_version }}</code> · Python <code>{{ python_version }}</code>
— UTC <code>{{ current_time|date:"Y-m-d H:i:s" }}</code> <div class="text-center mb-5">
</p>
</div> <h2>Explore Published Agents</h2>
</main>
<footer> <p class="lead">These are the agents that have been published by our users.</p>
Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC)
</footer> </div>
<div class="agent-grid">
{% for agent in agents %}
<a href="{% url 'agent_detail' agent.id %}" class="agent-card-link">
<div class="agent-card">
<div class="card-body d-flex flex-column">
<h3 class="card-title">{{ agent.name }}</h3>
<p class="card-text flex-grow-1">{{ agent.description }}</p>
</div>
</div>
</a>
{% empty %}
<div class="text-center w-100">
<p class="lead">No agents have been published yet. Be the first!</p>
</div>
{% endfor %}
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% block content %}
<h2>Login to Your Account</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<p>Don't have an account? <a href="{% url 'signup' %}">Sign up</a></p>
{% endblock %}

View File

@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block content %}
<div class="container mt-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="display-4">My Agents</h1>
<a href="{% url 'create_agent' %}" class="btn btn-primary">Create New Agent</a>
</div>
<p class="lead mb-5">Here is a list of all the AI agents you have created.</p>
{% if agents %}
<div class="agent-grid">
{% for agent in agents %}
<div class="agent-card">
<div class="card-body d-flex flex-column">
<h3 class="card-title">{{ agent.name }}</h3>
<p class="card-text flex-grow-1">{{ agent.description }}</p>
<div class="d-flex justify-content-between align-items-center mb-3">
<strong>Status:</strong>
{% if agent.published %}
<span class="badge bg-success">Published</span>
{% else %}
<span class="badge bg-secondary">Draft</span>
{% endif %}
</div>
<div class="d-flex justify-content-center">
<a href="{% url 'edit_agent' agent.id %}" class="btn btn-sm btn-outline-primary me-2">Edit</a>
<form action="{% url 'delete_agent' agent.id %}" method="post" onsubmit="return confirm('Are you sure you want to delete this agent?');">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-outline-danger me-2">Delete</button>
</form>
<a href="{% url 'publish_agent' agent.id %}" class="btn btn-sm btn-outline-info">
{% if agent.published %}Unpublish{% else %}Publish{% endif %}
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center py-5">
<h2 class="display-5">No Agents Yet</h2>
<p class="lead">You haven't created any agents. Why not create your first one?</p>
<a href="{% url 'create_agent' %}" class="btn btn-primary btn-lg mt-3">Create an Agent</a>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,10 @@
{% extends 'base.html' %}
{% block content %}
<h2>Create a New Account</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock %}

View File

@ -1,7 +1,15 @@
from django.urls import path from django.urls import path
from .views import home from .views import home, create_agent, my_agents, publish_agent, delete_agent, edit_agent, agent_detail, signup, CustomLoginView
urlpatterns = [ urlpatterns = [
path("", home, name="home"), path("", home, name="home"),
path("signup/", signup, name="signup"),
path("login/", CustomLoginView.as_view(), name="login"),
path("create-agent/", create_agent, name="create_agent"),
path("my-agents/", my_agents, name="my_agents"),
path("agents/<int:agent_id>/publish/", publish_agent, name="publish_agent"),
path("agents/<int:agent_id>/delete/", delete_agent, name="delete_agent"),
path("agents/<int:agent_id>/edit/", edit_agent, name="edit_agent"),
path("agent/<int:agent_id>/", agent_detail, name="agent_detail"),
] ]

View File

@ -2,15 +2,25 @@ import os
import platform import platform
from django import get_version as django_version from django import get_version as django_version
from django.shortcuts import render from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_POST
from django.http import JsonResponse
from django.utils import timezone from django.utils import timezone
from .models import Agent
from .forms import SignUpForm
from django.contrib.auth import login
from django.contrib.auth import views as auth_views
class CustomLoginView(auth_views.LoginView):
template_name = 'core/login.html'
def home(request): def home(request):
"""Render the landing screen with loader and environment details.""" """Render the landing screen with loader and environment details."""
host_name = request.get_host().lower() host_name = request.get_host().lower()
agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
now = timezone.now() now = timezone.now()
published_agents = Agent.objects.filter(published=True)
context = { context = {
"project_name": "New Style", "project_name": "New Style",
@ -21,5 +31,59 @@ def home(request):
"host_name": host_name, "host_name": host_name,
"project_description": os.getenv("PROJECT_DESCRIPTION", ""), "project_description": os.getenv("PROJECT_DESCRIPTION", ""),
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
"agents": published_agents,
} }
return render(request, "core/index.html", context) return render(request, "core/index.html", context)
@login_required
def create_agent(request):
if request.method == 'POST':
name = request.POST.get('name')
description = request.POST.get('description')
agent = Agent.objects.create(name=name, description=description, user=request.user)
return redirect('my_agents')
return render(request, "core/create_agent.html")
@login_required
def my_agents(request):
agents = Agent.objects.filter(user=request.user)
return render(request, "core/my_agents.html", {"agents": agents})
@login_required
def publish_agent(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id, user=request.user)
agent.published = not agent.published
agent.save()
return redirect('my_agents')
@login_required
@require_POST
def delete_agent(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id, user=request.user)
agent.delete()
return redirect('my_agents')
@login_required
def edit_agent(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id, user=request.user)
if request.method == 'POST':
agent.name = request.POST.get('name')
agent.description = request.POST.get('description')
agent.save()
return redirect('my_agents')
return render(request, 'core/edit_agent.html', {'agent': agent})
def agent_detail(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id)
return render(request, 'core/article_detail.html', {'agent': agent})
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'core/signup.html', {'form': form})

View File

@ -1,4 +1,243 @@
/* Custom styles for the application */ /* static/css/custom.css */
body {
font-family: system-ui, -apple-system, sans-serif; /* Core Palette & Typography */
:root {
--primary-color: #1A237E; /* Dark Blue */
--secondary-color: #F5F5F5; /* Light Gray */
--accent-color: #2962FF; /* Bright Blue */
--text-dark: #212121;
--text-light: #FFFFFF;
--font-headings: 'Poppins', sans-serif;
--font-body: 'Roboto', sans-serif;
}
body {
font-family: var(--font-body);
color: var(--text-dark);
background-color: var(--secondary-color);
line-height: 1.6;
}
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-headings);
font-weight: 600;
color: var(--primary-color);
}
a {
color: var(--accent-color);
text-decoration: none;
transition: color 0.3s ease;
}
a:hover {
color: var(--primary-color);
text-decoration: underline;
}
.btn-primary {
background-color: var(--accent-color);
border-color: var(--accent-color);
font-family: var(--font-headings);
font-weight: 500;
padding: 0.75rem 1.5rem;
border-radius: 50px; /* Pill-shaped buttons */
transition: all 0.3s ease;
}
.btn-primary:hover {
background-color: var(--primary-color);
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
/* Hero Section */
.hero {
background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
color: var(--text-light);
padding: 6rem 1rem;
text-align: center;
margin-bottom: 4rem;
}
.hero h1 {
font-size: 3.5rem;
font-weight: 700;
color: var(--text-light);
margin-bottom: 1rem;
}
.hero p {
font-size: 1.25rem;
max-width: 600px;
margin: 0 auto 2rem;
opacity: 0.9;
}
/* Agent Showcase */
.agent-showcase {
padding-bottom: 4rem;
}
.agent-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.agent-card {
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.05);
padding: 2rem;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.agent-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
}
.agent-card .icon {
font-size: 3rem;
margin-bottom: 1rem;
/* Using a simple emoji as a placeholder */
/* In a real app, this would be an image or SVG icon */
}
.agent-card h3 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
.agent-card p {
color: #6c757d;
font-size: 1rem;
}
.agent-card-link {
text-decoration: none;
color: inherit;
}
/* Chat Interface */
.chat-container {
max-width: 800px;
margin: 0 auto;
background-color: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
.chat-messages {
padding: 2rem;
overflow-y: auto;
}
.message-bubble {
padding: 0.75rem 1.25rem;
border-radius: 20px;
margin-bottom: 1rem;
max-width: 80%;
line-height: 1.5;
}
.message-bubble.sent {
background-color: var(--accent-color);
color: var(--text-light);
margin-left: auto;
border-bottom-right-radius: 5px;
}
.message-bubble.received {
background-color: var(--secondary-color);
color: var(--text-dark);
margin-right: auto;
border-bottom-left-radius: 5px;
}
.chat-input-container {
padding: 1rem 2rem;
background-color: #fff;
border-top: 1px solid #eee;
}
.chat-input-container .form-control {
border-radius: 50px;
border-color: #ced4da;
padding: 0.75rem 1.25rem;
}
.chat-input-container .form-control:focus {
box-shadow: none;
border-color: var(--accent-color);
}
.chat-input-container .btn {
border-radius: 50px;
} }

View File

@ -1,21 +1,239 @@
/* static/css/custom.css */
/* Core Palette & Typography */
:root { :root {
--bg-color-start: #6a11cb; --primary-color: #1A237E; /* Dark Blue */
--bg-color-end: #2575fc; --secondary-color: #F5F5F5; /* Light Gray */
--text-color: #ffffff; --accent-color: #2962FF; /* Bright Blue */
--card-bg-color: rgba(255, 255, 255, 0.01); --text-dark: #212121;
--card-border-color: rgba(255, 255, 255, 0.1); --text-light: #FFFFFF;
--font-headings: 'Poppins', sans-serif;
--font-body: 'Roboto', sans-serif;
} }
body { body {
margin: 0; font-family: var(--font-body);
font-family: 'Inter', sans-serif; color: var(--text-dark);
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end)); background-color: var(--secondary-color);
color: var(--text-color); line-height: 1.6;
display: flex; }
justify-content: center;
align-items: center; h1, h2, h3, h4, h5, h6 {
min-height: 100vh; font-family: var(--font-headings);
text-align: center; font-weight: 600;
overflow: hidden; color: var(--primary-color);
position: relative; }
a {
color: var(--accent-color);
text-decoration: none;
transition: color 0.3s ease;
}
a:hover {
color: var(--primary-color);
text-decoration: underline;
}
.btn-primary {
background-color: var(--accent-color);
border-color: var(--accent-color);
font-family: var(--font-headings);
font-weight: 500;
padding: 0.75rem 1.5rem;
border-radius: 50px; /* Pill-shaped buttons */
transition: all 0.3s ease;
}
.btn-primary:hover {
background-color: var(--primary-color);
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
/* Hero Section */
.hero {
background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
color: var(--text-light);
padding: 6rem 1rem;
text-align: center;
margin-bottom: 4rem;
}
.hero h1 {
font-size: 3.5rem;
font-weight: 700;
color: var(--text-light);
margin-bottom: 1rem;
}
.hero p {
font-size: 1.25rem;
max-width: 600px;
margin: 0 auto 2rem;
opacity: 0.9;
}
/* Agent Showcase */
.agent-showcase {
padding-bottom: 4rem;
}
.agent-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.agent-card {
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.05);
padding: 2rem;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.agent-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
}
.agent-card .icon {
font-size: 3rem;
margin-bottom: 1rem;
/* Using a simple emoji as a placeholder */
/* In a real app, this would be an image or SVG icon */
}
.agent-card h3 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
.agent-card p {
color: #6c757d;
font-size: 1rem;
}
/* Chat Interface */
.chat-container {
max-width: 800px;
margin: 0 auto;
background-color: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
.chat-messages {
padding: 2rem;
overflow-y: auto;
}
.message-bubble {
padding: 0.75rem 1.25rem;
border-radius: 20px;
margin-bottom: 1rem;
max-width: 80%;
line-height: 1.5;
}
.message-bubble.sent {
background-color: var(--accent-color);
color: var(--text-light);
margin-left: auto;
border-bottom-right-radius: 5px;
}
.message-bubble.received {
background-color: var(--secondary-color);
color: var(--text-dark);
margin-right: auto;
border-bottom-left-radius: 5px;
}
.chat-input-container {
padding: 1rem 2rem;
background-color: #fff;
border-top: 1px solid #eee;
}
.chat-input-container .form-control {
border-radius: 50px;
border-color: #ced4da;
padding: 0.75rem 1.25rem;
}
.chat-input-container .form-control:focus {
box-shadow: none;
border-color: var(--accent-color);
}
.chat-input-container .btn {
border-radius: 50px;
} }