Template web profesional disenado para empresas del sector industrial y metalurgico. Construido con FastHTML para demostrar que sitios corporativos modernos no necesitan frameworks JavaScript pesados.
Concepto de Diseno
El diseno "Forja Moderna" combina: - Estetica industrial (grises, naranjas, texturas metalicas) - Tipografia bold y legible - Imagenes de alto impacto - UX clara para decision-makers B2B
:root {
/* Paleta Industrial */
--steel-dark: #1a1a2e;
--steel-medium: #2d2d44;
--forge-orange: #e94560;
--metal-gray: #4a4a5a;
--spark-yellow: #f9a826;
/* Tipografia Bold */
--font-heading: 'Oswald', sans-serif;
--font-body: 'Open Sans', sans-serif;
}
Estructura del Sitio
/
├── Hero con video de fondo
├── Servicios (grid de cards)
├── Galeria de proyectos (HTMX)
├── Proceso de trabajo (timeline)
├── Testimonios
├── Formulario de cotizacion
└── Footer con mapa
Componentes FastHTML
Hero con Video
def Hero():
return Section(
# Video de fondo
Video(
Source(src='/static/video/forge.mp4', type='video/mp4'),
autoplay=True,
muted=True,
loop=True,
cls='hero-video'
),
# Overlay
Div(cls='hero-overlay'),
# Contenido
Div(
H1('Soluciones en Acero', cls='hero-title'),
P('40 anos de experiencia en metalurgia industrial'),
A('Solicitar Cotizacion', href='#cotizacion', cls='btn-primary'),
cls='hero-content'
),
cls='hero'
)
Galeria Interactiva con HTMX
def GalleryGrid():
"""Grid de proyectos con carga dinamica."""
return Div(
# Filtros
Div(
Button('Todos', hx_get='/gallery?filter=all', hx_target='#gallery-items'),
Button('Estructuras', hx_get='/gallery?filter=estructuras', hx_target='#gallery-items'),
Button('Maquinaria', hx_get='/gallery?filter=maquinaria', hx_target='#gallery-items'),
cls='gallery-filters'
),
# Items (cargados via HTMX)
Div(
id='gallery-items',
hx_get='/gallery?filter=all',
hx_trigger='load'
),
cls='gallery-section'
)
@rt('/gallery')
def get(filter: str = 'all'):
"""Endpoint para cargar items de galeria."""
projects = get_projects(filter)
return Div(
*[ProjectCard(p) for p in projects],
cls='gallery-grid'
)
def ProjectCard(project):
return Div(
Img(src=project.image, alt=project.title, loading='lazy'),
Div(
H3(project.title),
P(project.description),
cls='project-info'
),
cls='project-card',
**{'@click': f"$dispatch('open-modal', {{ id: {project.id} }})"}
)
Formulario de Cotizacion
def QuoteForm():
return Form(
H2('Solicitar Cotizacion'),
Div(
Label('Nombre', fr='name'),
Input(type='text', name='name', id='name', required=True),
cls='form-group'
),
Div(
Label('Email', fr='email'),
Input(type='email', name='email', id='email', required=True),
cls='form-group'
),
Div(
Label('Telefono', fr='phone'),
Input(type='tel', name='phone', id='phone'),
cls='form-group'
),
Div(
Label('Tipo de Proyecto', fr='project_type'),
Select(
Option('Seleccionar...', value=''),
Option('Estructuras metalicas'),
Option('Maquinaria industrial'),
Option('Reparaciones'),
Option('Otro'),
name='project_type',
id='project_type'
),
cls='form-group'
),
Div(
Label('Descripcion del proyecto', fr='description'),
Textarea(name='description', id='description', rows=4),
cls='form-group'
),
Button('Enviar Solicitud', type='submit', cls='btn-primary'),
hx_post='/quote',
hx_target='#form-response',
hx_swap='innerHTML',
cls='quote-form'
)
@rt('/quote')
async def post(name: str, email: str, phone: str, project_type: str, description: str):
# Guardar cotizacion
quote = save_quote(name, email, phone, project_type, description)
# Enviar email de notificacion
await send_notification_email(quote)
return Div(
H3('Solicitud Enviada'),
P(f'Gracias {name}, nos pondremos en contacto pronto.'),
cls='form-success'
)
Animaciones con Alpine.js
Scroll Reveal
<div x-data="{ shown: false }"
x-intersect="shown = true"
:class="shown ? 'animate-in' : 'animate-out'">
<!-- Contenido -->
</div>
Modal de Galeria
<div x-data="{ open: false, project: null }"
@open-modal.window="open = true; project = $event.detail">
<div x-show="open"
x-transition
class="modal-overlay"
@click.self="open = false">
<div class="modal-content">
<img :src="project?.image" :alt="project?.title">
<h3 x-text="project?.title"></h3>
<p x-text="project?.description"></p>
<button @click="open = false">Cerrar</button>
</div>
</div>
</div>
Optimizaciones
Lazy Loading de Imagenes
def OptimizedImage(src: str, alt: str):
return Picture(
Source(srcset=f'{src}?w=400', media='(max-width: 600px)'),
Source(srcset=f'{src}?w=800', media='(max-width: 1200px)'),
Img(src=f'{src}?w=1200', alt=alt, loading='lazy'),
cls='responsive-image'
)
CSS Critico Inline
def Page(*children):
return Html(
Head(
# CSS critico inline para First Contentful Paint
Style(CRITICAL_CSS),
# CSS completo cargado async
Link(rel='preload', href='/static/css/main.css', as_='style'),
Link(rel='stylesheet', href='/static/css/main.css', media='print', onload="this.media='all'"),
),
Body(*children)
)
Uso del Template
# Clonar repositorio
git clone https://github.com/estebanmartinezsoto/metalurgica-spa
# Instalar dependencias
pip install -r requirements.txt
# Ejecutar
python main.py
Personalizacion
- Editar
data/content.pycon informacion de la empresa - Reemplazar imagenes en
static/images/ - Ajustar colores en
static/css/variables.css - Modificar formulario de cotizacion segun necesidades
Por Que FastHTML
Este template demuestra que: - No necesitas React para sitios corporativos - HTMX permite interactividad sin bundle JavaScript - Server-side rendering = mejor SEO - Menos complejidad = mantenimiento mas facil