Parcourir la source

feat: initial commit - Festival Armadillos web page

Luis Rosales il y a 4 jours
commit
d75f1166db
3 fichiers modifiés avec 745 ajouts et 0 suppressions
  1. 11 0
      package.json
  2. 689 0
      public/index.html
  3. 45 0
      server.js

+ 11 - 0
package.json

@@ -0,0 +1,11 @@
+{
+  "name": "armadillos",
+  "version": "1.0.0",
+  "description": "Ensamble Armadillos - Festival Cultural",
+  "main": "server.js",
+  "scripts": {
+    "start": "node server.js",
+    "dev": "node server.js"
+  },
+  "dependencies": {}
+}

+ 689 - 0
public/index.html

@@ -0,0 +1,689 @@
+<!DOCTYPE html>
+<html lang="es">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Ensamble Armadillos | Festival Cultural</title>
+  <link rel="preconnect" href="https://fonts.googleapis.com">
+  <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Source+Sans+Pro:wght@300;400;600&display=swap" rel="stylesheet">
+  <style>
+    :root {
+      --color-primary: #8B4513;
+      --color-secondary: #D2691E;
+      --color-accent: #CD853F;
+      --color-dark: #2C1810;
+      --color-cream: #FFF8DC;
+      --color-light: #FFFDF5;
+      --color-text: #3E2723;
+      --color-muted: #6D4C41;
+    }
+
+    * {
+      margin: 0;
+      padding: 0;
+      box-sizing: border-box;
+    }
+
+    body {
+      font-family: 'Source Sans Pro', sans-serif;
+      background-color: var(--color-light);
+      color: var(--color-text);
+      line-height: 1.7;
+    }
+
+    /* Header / Hero */
+    header {
+      background: linear-gradient(135deg, var(--color-dark) 0%, var(--color-primary) 100%);
+      color: var(--color-cream);
+      padding: 4rem 2rem 3rem;
+      text-align: center;
+    }
+
+    header h1 {
+      font-family: 'Playfair Display', serif;
+      font-size: 3rem;
+      font-weight: 700;
+      letter-spacing: 2px;
+      margin-bottom: 0.3rem;
+    }
+
+    header .tagline {
+      font-family: 'Playfair Display', serif;
+      font-style: italic;
+      font-size: 1.3rem;
+      opacity: 0.9;
+      margin-bottom: 1.5rem;
+    }
+
+    .header-badge {
+      display: inline-block;
+      background: rgba(255,248,220,0.15);
+      border: 1px solid rgba(255,248,220,0.3);
+      border-radius: 50px;
+      padding: 0.4rem 1.2rem;
+      font-size: 0.85rem;
+      letter-spacing: 1px;
+      text-transform: uppercase;
+    }
+
+    /* Nav */
+    nav {
+      background: var(--color-dark);
+      position: sticky;
+      top: 0;
+      z-index: 100;
+      box-shadow: 0 2px 8px rgba(0,0,0,0.3);
+    }
+
+    nav ul {
+      list-style: none;
+      display: flex;
+      justify-content: center;
+      flex-wrap: wrap;
+      padding: 0.8rem;
+      gap: 0.5rem;
+    }
+
+    nav a {
+      color: var(--color-cream);
+      text-decoration: none;
+      font-size: 0.9rem;
+      padding: 0.4rem 1rem;
+      border-radius: 4px;
+      transition: background 0.2s;
+      letter-spacing: 0.5px;
+    }
+
+    nav a:hover {
+      background: rgba(255,248,220,0.15);
+    }
+
+    /* Sections */
+    section {
+      max-width: 900px;
+      margin: 0 auto;
+      padding: 3rem 2rem;
+    }
+
+    section:nth-child(even) {
+      background: var(--color-cream);
+    }
+
+    h2 {
+      font-family: 'Playfair Display', serif;
+      font-size: 2rem;
+      color: var(--color-primary);
+      margin-bottom: 1.5rem;
+      padding-bottom: 0.5rem;
+      border-bottom: 3px solid var(--color-accent);
+      display: inline-block;
+    }
+
+    h3 {
+      font-family: 'Playfair Display', serif;
+      font-size: 1.3rem;
+      color: var(--color-secondary);
+      margin-top: 1.5rem;
+      margin-bottom: 0.8rem;
+    }
+
+    p {
+      margin-bottom: 1rem;
+      font-size: 1.05rem;
+    }
+
+    /* Mission / Vision cards */
+    .cards {
+      display: grid;
+      grid-template-columns: 1fr 1fr;
+      gap: 1.5rem;
+      margin-top: 1.5rem;
+    }
+
+    .card {
+      background: white;
+      border-radius: 12px;
+      padding: 1.8rem;
+      box-shadow: 0 4px 16px rgba(139,69,19,0.1);
+      border-top: 4px solid var(--color-accent);
+    }
+
+    .card h3 {
+      margin-top: 0;
+    }
+
+    /* Valores */
+    .values-grid {
+      display: grid;
+      grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
+      gap: 1rem;
+      margin-top: 1.5rem;
+    }
+
+    .value-item {
+      background: white;
+      border-radius: 8px;
+      padding: 1.2rem;
+      text-align: center;
+      box-shadow: 0 2px 8px rgba(139,69,19,0.08);
+      font-weight: 600;
+      color: var(--color-primary);
+      font-size: 1rem;
+      border-bottom: 3px solid var(--color-accent);
+    }
+
+    /* Historia */
+    .history-text {
+      background: white;
+      border-radius: 12px;
+      padding: 2rem;
+      box-shadow: 0 4px 16px rgba(139,69,19,0.1);
+      border-left: 4px solid var(--color-secondary);
+      font-size: 1.05rem;
+    }
+
+    .highlight-box {
+      background: var(--color-dark);
+      color: var(--color-cream);
+      border-radius: 12px;
+      padding: 1.5rem 2rem;
+      margin-top: 1.5rem;
+      font-style: italic;
+      text-align: center;
+      font-family: 'Playfair Display', serif;
+      font-size: 1.2rem;
+    }
+
+    /* Timeline */
+    .timeline {
+      position: relative;
+      padding-left: 2rem;
+      margin-top: 1.5rem;
+    }
+
+    .timeline::before {
+      content: '';
+      position: absolute;
+      left: 6px;
+      top: 0;
+      bottom: 0;
+      width: 3px;
+      background: var(--color-accent);
+      border-radius: 2px;
+    }
+
+    .timeline-item {
+      position: relative;
+      margin-bottom: 1.5rem;
+      background: white;
+      border-radius: 8px;
+      padding: 1rem 1.5rem;
+      box-shadow: 0 2px 8px rgba(139,69,19,0.08);
+    }
+
+    .timeline-item::before {
+      content: '';
+      position: absolute;
+      left: -2rem;
+      top: 1.2rem;
+      width: 14px;
+      height: 14px;
+      background: var(--color-secondary);
+      border-radius: 50%;
+      border: 3px solid var(--color-cream);
+    }
+
+    .timeline-year {
+      font-family: 'Playfair Display', serif;
+      font-weight: 700;
+      font-size: 1.1rem;
+      color: var(--color-primary);
+    }
+
+    .timeline-desc {
+      color: var(--color-muted);
+      font-size: 0.95rem;
+      margin-top: 0.2rem;
+    }
+
+    .timeline-note {
+      font-style: italic;
+      color: var(--color-secondary);
+      font-size: 0.85rem;
+      margin-top: 0.3rem;
+    }
+
+    /* Actividades */
+    .activities {
+      display: grid;
+      grid-template-columns: 1fr 1fr;
+      gap: 1.5rem;
+      margin-top: 1.5rem;
+    }
+
+    .activity {
+      background: white;
+      border-radius: 12px;
+      padding: 1.8rem;
+      box-shadow: 0 4px 16px rgba(139,69,19,0.1);
+    }
+
+    .activity h3 {
+      margin-top: 0;
+      color: var(--color-primary);
+    }
+
+    .activity ul {
+      list-style: none;
+      padding: 0;
+    }
+
+    .activity li {
+      padding: 0.3rem 0;
+      padding-left: 1.5rem;
+      position: relative;
+    }
+
+    .activity li::before {
+      content: '♪';
+      position: absolute;
+      left: 0;
+      color: var(--color-secondary);
+    }
+
+    /* Impact */
+    .impact-banner {
+      background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
+      color: white;
+      border-radius: 12px;
+      padding: 2rem;
+      margin-top: 1.5rem;
+      text-align: center;
+    }
+
+    .impact-banner h3 {
+      color: var(--color-cream);
+      margin-top: 0;
+    }
+
+    /* Alianzas */
+    .alliance-grid {
+      display: grid;
+      grid-template-columns: 1fr 1fr;
+      gap: 1.5rem;
+      margin-top: 1.5rem;
+    }
+
+    .alliance-card {
+      background: white;
+      border-radius: 12px;
+      padding: 1.5rem;
+      box-shadow: 0 4px 16px rgba(139,69,19,0.1);
+      text-align: center;
+    }
+
+    .alliance-icon {
+      font-size: 2.5rem;
+      margin-bottom: 0.5rem;
+    }
+
+    /* Voluntarios stats */
+    .stats-row {
+      display: grid;
+      grid-template-columns: repeat(3, 1fr);
+      gap: 1rem;
+      margin-top: 1.5rem;
+    }
+
+    .stat-box {
+      background: var(--color-dark);
+      color: var(--color-cream);
+      border-radius: 10px;
+      padding: 1.5rem;
+      text-align: center;
+    }
+
+    .stat-number {
+      font-family: 'Playfair Display', serif;
+      font-size: 2.2rem;
+      font-weight: 700;
+      color: var(--color-accent);
+    }
+
+    .stat-label {
+      font-size: 0.9rem;
+      opacity: 0.8;
+    }
+
+    /* Contact */
+    .contact-grid {
+      display: grid;
+      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+      gap: 1rem;
+      margin-top: 1.5rem;
+    }
+
+    .contact-item {
+      background: white;
+      border-radius: 8px;
+      padding: 1.2rem;
+      display: flex;
+      align-items: center;
+      gap: 0.8rem;
+      box-shadow: 0 2px 8px rgba(139,69,19,0.08);
+    }
+
+    .contact-icon {
+      font-size: 1.5rem;
+    }
+
+    .contact-label {
+      font-size: 0.8rem;
+      color: var(--color-muted);
+      text-transform: uppercase;
+      letter-spacing: 0.5px;
+    }
+
+    .contact-value {
+      font-weight: 600;
+      color: var(--color-primary);
+    }
+
+    /* Transparencia */
+    .transparency-box {
+      background: white;
+      border-radius: 12px;
+      padding: 1.8rem;
+      box-shadow: 0 4px 16px rgba(139,69,19,0.1);
+      border-left: 4px solid var(--color-accent);
+    }
+
+    .budget-highlight {
+      background: var(--color-cream);
+      border-radius: 8px;
+      padding: 1rem;
+      margin-top: 1rem;
+      text-align: center;
+    }
+
+    .budget-amount {
+      font-family: 'Playfair Display', serif;
+      font-size: 1.8rem;
+      color: var(--color-primary);
+      font-weight: 700;
+    }
+
+    /* Footer */
+    footer {
+      background: var(--color-dark);
+      color: var(--color-cream);
+      text-align: center;
+      padding: 2rem;
+      font-size: 0.9rem;
+    }
+
+    footer .footer-title {
+      font-family: 'Playfair Display', serif;
+      font-size: 1.1rem;
+      margin-bottom: 0.5rem;
+    }
+
+    /* Responsive */
+    @media (max-width: 700px) {
+      header h1 { font-size: 2rem; }
+      .cards { grid-template-columns: 1fr; }
+      .activities { grid-template-columns: 1fr; }
+      .alliance-grid { grid-template-columns: 1fr; }
+      .stats-row { grid-template-columns: 1fr 1fr; }
+      section { padding: 2rem 1rem; }
+    }
+  </style>
+</head>
+<body>
+
+  <!-- Header -->
+  <header>
+    <h1>Ensamble Armadillos</h1>
+    <p class="tagline">Sembrando Cultura, Cosechando Futuro</p>
+    <span class="header-badge">Asociación cultural sin fines de lucro — en proceso de constitución como A.C.</span>
+    <p style="margin-top:1rem; opacity:0.7; font-size:0.95rem;">Acapetahua, Chiapas, México</p>
+  </header>
+
+  <!-- Navigation -->
+  <nav>
+    <ul>
+      <li><a href="#mision">Misión y Visión</a></li>
+      <li><a href="#historia">Historia</a></li>
+      <li><a href="#actividades">Actividades</a></li>
+      <li><a href="#linea-tiempo">Línea del Tiempo</a></li>
+      <li><a href="#alianzas">Alianzas</a></li>
+      <li><a href="#contacto">Contacto</a></li>
+    </ul>
+  </nav>
+
+  <!-- Misión y Visión -->
+  <section id="mision">
+    <h2>Misión y Visión</h2>
+    <div class="cards">
+      <div class="card">
+        <h3>Misión</h3>
+        <p>Sembrar cultura en nuestra comunidad a través del arte y la educación, creando espacios de encuentro que fortalezcan los valores sociales y acerquen los valores artísticos y humanos a cada rincón de nuestra comunidad, para cosechar un futuro más humano y solidaria.</p>
+      </div>
+      <div class="card">
+        <h3>Visión</h3>
+        <p>Ser un referente cultural en nuestra región, reconocido por generar comunidad a través del arte y por formar ciudadanos con valores.</p>
+      </div>
+    </div>
+
+    <h3 style="margin-top:2rem;">Valores</h3>
+    <div class="values-grid">
+      <div class="value-item">Identidad</div>
+      <div class="value-item">Trabajo en equipo</div>
+      <div class="value-item">Creatividad</div>
+      <div class="value-item">Compromiso social</div>
+    </div>
+  </section>
+
+  <!-- Historia -->
+  <section id="historia">
+    <h2>Nuestra Historia</h2>
+    <div class="history-text">
+      <p>Todo comenzó cuando el antropólogo <strong>Guillermo Coutiño Archilla</strong> reunió a diversos personajes de la vida de Acapetahua, Chiapas, con un propósito sencillo pero poderoso: compartir poesía, música y relatos en un ambiente bohemio. Lo que nació como una reunión de amigos alrededor del arte fue evolucionando hasta convertirse en lo que hoy conocemos como el <strong>Festival Armadillo</strong>.</p>
+      <p>El nombre hace honor a nuestro origen: "Armadillos" es el gentilicio cariñoso con el que se conoce a los acapetahuenses. Aunque el festival congrega hoy a público de comunidades aledañas y nuestros miembros residen en distintos puntos del país, con un alcance regional, la semilla siempre fue y será Acapetahua.</p>
+      <p>Un momento que marcó un antes y un después fue el cuarto Festival Armadillos, celebrado el <strong>28 de diciembre de 2015</strong>, cuando por primera vez el festival se realizó en las instalaciones del Auditorio de la UNICACH en Acapetahua. Desde entonces, el reconocimiento ha crecido tanto que, según los propios habitantes, asistir al Festival Armadillos figura entre las diez cosas más importantes que hacer en Acapetahua.</p>
+      <p>Después de siete ediciones (2012–2019), el festival guardó una pausa en los años recientes, en parte a causa de la pandemia. Hoy, <strong>Ensamble Armadillos</strong> retoma su misión con la misma fuerza del primer día: porque la cultura no se hereda, se siembra.</p>
+      <p class="timeline-note" style="margin-top:1rem;">Próximamente: homenaje a los maestros Felipe Orozco y Humberto Velázquez.</p>
+    </div>
+
+    <div class="highlight-box">
+      "La cultura no se hereda, se siembra."
+    </div>
+  </section>
+
+  <!-- Actividades -->
+  <section id="actividades">
+    <h2>Actividades y Programas</h2>
+
+    <div class="activities">
+      <div class="activity">
+        <h3>Festival Armadillos</h3>
+        <p>Nuestro evento principal es el Festival Armadillos, un encuentro cultural que reúne:</p>
+        <ul>
+          <li>Música</li>
+          <li>Danza</li>
+          <li>Poesía y literatura</li>
+          <li>Cápsulas de contenido sobre salud y prevención</li>
+        </ul>
+        <p style="margin-top:1rem;">El festival está dirigido a la comunidad en general, con un énfasis especial en las nuevas generaciones, para que las mentes jóvenes comprendan y amen la cultura.</p>
+      </div>
+
+      <div class="activity">
+        <h3>Impacto en la Juventud</h3>
+        <p>Algunos de nuestros jóvenes participantes han decidido realizar estudios formales en instituciones de arte del estado de Chiapas, lo que demuestra que brindar una ventana de acercamiento al arte y la cultura trae resultados concretos y transformadores.</p>
+        <p>El arte abre puertas que nunca se habían imaginado. Cada festival es una semilla que germina en las vidas de quienes participan.</p>
+      </div>
+    </div>
+
+    <div class="impact-banner">
+      <h3>Impacto en la comunidad</h3>
+      <p>El Festival Armadillos se ha consolidado como un espacio donde la música, la poesía y la danza se encuentran para fortalecer la identidad y los valores de nuestra comunidad.</p>
+    </div>
+  </section>
+
+  <!-- Línea del Tiempo -->
+  <section id="linea-tiempo">
+    <h2>Línea del Tiempo del Festival</h2>
+    <div class="timeline">
+      <div class="timeline-item">
+        <div class="timeline-year">I Festival — 2012</div>
+        <div class="timeline-desc">Primera edición del festival</div>
+        <div class="timeline-note">(por confirmar detalles)</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">II Festival — 2013</div>
+        <div class="timeline-desc">Segunda edición del festival</div>
+        <div class="timeline-note">(por confirmar detalles)</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">III Festival — 2014</div>
+        <div class="timeline-desc">Tercera edición del festival</div>
+        <div class="timeline-note">(por confirmar detalles)</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">IV Festival — 2015</div>
+        <div class="timeline-desc">Auditorio UNICACH Acapetahua</div>
+        <div class="timeline-note">Por primera vez en estas instalaciones — punto de inflexión</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">V Festival — 2017</div>
+        <div class="timeline-desc">Auditorio UNICACH Acapetahua</div>
+        <div class="timeline-note">Homenaje al Prof. Felipe Orozco</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">VI Festival — 2018</div>
+        <div class="timeline-desc">Auditorio UNICACH Acapetahua</div>
+        <div class="timeline-note">(por confirmar detalles)</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">VII Festival — 2019</div>
+        <div class="timeline-desc">Auditorio UNICACH Acapetahua</div>
+        <div class="timeline-note">Homenaje al Prof. Humberto Velázquez</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">2020 – 2025</div>
+        <div class="timeline-desc">Pausa del festival</div>
+        <div class="timeline-note">A causa de la pandemia y circunstancias externas</div>
+      </div>
+      <div class="timeline-item">
+        <div class="timeline-year">VIII Festival — Próximamente</div>
+        <div class="timeline-desc">En preparación</div>
+        <div class="timeline-note">¡El festival regresa con nueva energía!</div>
+      </div>
+    </div>
+  </section>
+
+  <!-- Alianzas y Voluntariado -->
+  <section id="alianzas">
+    <h2>Alianzas y Voluntariado</h2>
+
+    <div class="alliance-grid">
+      <div class="alliance-card">
+        <div class="alliance-icon">🏛️</div>
+        <h3>Iniciativa Privada</h3>
+        <p>Empresas y negocios locales que creen en el poder transformador de la cultura.</p>
+      </div>
+      <div class="alliance-card">
+        <div class="alliance-icon">🏢</div>
+        <h3>Gobierno Municipal</h3>
+        <p>Apoyo institucional para la realización de los festivales.</p>
+      </div>
+    </div>
+
+    <h3 style="margin-top:2rem;">Voluntariado</h3>
+    <p>Contamos con aproximadamente <strong>20 voluntarios activos</strong> entre organizadores, músicos, médicos y personal de apoyo, quienes hacen posible la realización de cada evento. A la fecha, han participado más de <strong>50 voluntarios</strong> a lo largo de nuestra trayectoria.</p>
+
+    <div class="stats-row">
+      <div class="stat-box">
+        <div class="stat-number">20+</div>
+        <div class="stat-label">Voluntarios activos</div>
+      </div>
+      <div class="stat-box">
+        <div class="stat-number">50+</div>
+        <div class="stat-label">Voluntarios históricos</div>
+      </div>
+      <div class="stat-box">
+        <div class="stat-number">100%</div>
+        <div class="stat-label">Donaciones</div>
+      </div>
+    </div>
+  </section>
+
+  <!-- Transparencia -->
+  <section id="transparencia">
+    <h2>Transparencia</h2>
+    <div class="transparency-box">
+      <p><strong>Presupuesto aproximado por festival:</strong> $50,000 MXN</p>
+      <p class="timeline-note" style="margin-top:0.3rem;">(Dato referente al año 2019 — por actualizar)</p>
+
+      <div class="budget-highlight">
+        <div class="budget-amount">$50,000 MXN</div>
+        <div>por festival — financiado al 100% con donaciones</div>
+      </div>
+
+      <h3 style="margin-top:1.5rem;">Formas de aportación</h3>
+      <ul style="list-style:none; padding:0;">
+        <li style="padding:0.3rem 0;">💵 Efectivo</li>
+        <li style="padding:0.3rem 0;">🤝 Voluntariado</li>
+        <li style="padding:0.3rem 0;" class="timeline-note">Datos bancarios para donativos — pendientes</li>
+      </ul>
+    </div>
+  </section>
+
+  <!-- Contacto -->
+  <section id="contacto">
+    <h2>Datos de Contacto</h2>
+    <div class="contact-grid">
+      <div class="contact-item">
+        <div class="contact-icon">📧</div>
+        <div>
+          <div class="contact-label">Correo</div>
+          <div class="contact-value">festival@armadillos.org.mx</div>
+        </div>
+      </div>
+      <div class="contact-item">
+        <div class="contact-icon">📞</div>
+        <div>
+          <div class="contact-label">Teléfono</div>
+          <div class="contact-value">918 126 1222</div>
+        </div>
+      </div>
+      <div class="contact-item">
+        <div class="contact-icon">📍</div>
+        <div>
+          <div class="contact-label">Ubicación</div>
+          <div class="contact-value">Acapetahua, Chiapas, México</div>
+        </div>
+      </div>
+      <div class="contact-item">
+        <div class="contact-icon">🌐</div>
+        <div>
+          <div class="contact-label">Sitio web</div>
+          <div class="contact-value">En proceso</div>
+        </div>
+      </div>
+    </div>
+
+    <h3 style="margin-top:2rem;">Directorio</h3>
+    <p class="timeline-note" style="margin-top:0.5rem;">Pendiente: presidente, secretario, tesorero y vocales.</p>
+  </section>
+
+  <!-- Footer -->
+  <footer>
+    <div class="footer-title">Ensamble Armadillos</div>
+    <div>Sembrando Cultura, Cosechando Futuro</div>
+    <div style="margin-top:0.5rem; opacity:0.6;">Acapetahua, Chiapas, México</div>
+    <div style="margin-top:0.5rem; opacity:0.5; font-size:0.8rem;">Documento institucional · 2026</div>
+  </footer>
+
+</body>
+</html>

+ 45 - 0
server.js

@@ -0,0 +1,45 @@
+const http = require('http');
+const fs = require('fs');
+const path = require('path');
+
+const PORT = 7777;
+
+const server = http.createServer((req, res) => {
+  let filePath = req.url === '/' ? '/index.html' : req.url;
+  filePath = path.join(__dirname, 'public', filePath);
+
+  const extname = path.extname(filePath);
+  const contentTypes = {
+    '.html': 'text/html',
+    '.css': 'text/css',
+    '.js': 'application/javascript',
+    '.json': 'application/json',
+    '.png': 'image/png',
+    '.jpg': 'image/jpeg',
+    '.jpeg': 'image/jpeg',
+    '.gif': 'image/gif',
+    '.svg': 'image/svg+xml',
+    '.ico': 'image/x-icon',
+  };
+
+  const contentType = contentTypes[extname] || 'text/plain';
+
+  fs.readFile(filePath, (err, content) => {
+    if (err) {
+      if (err.code === 'ENOENT') {
+        res.writeHead(404, { 'Content-Type': 'text/html' });
+        res.end('<h1>404 - Página no encontrada</h1>', 'utf-8');
+      } else {
+        res.writeHead(500);
+        res.end('Error interno del servidor');
+      }
+    } else {
+      res.writeHead(200, { 'Content-Type': contentType });
+      res.end(content, 'utf-8');
+    }
+  });
+});
+
+server.listen(PORT, () => {
+  console.log(`Servidor del Festival Armadillos corriendo en http://localhost:${PORT}`);
+});