From ba7f2e391522f95b6bfd9e47e16115e553424f88 Mon Sep 17 00:00:00 2001 From: JoniMartin27 <130197986+JoniMartin27@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:02:57 +0200 Subject: [PATCH 1/4] feat(web): ES/EN segmented language toggle + dedicated contact/hire page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace the single EN/ES button with an illuminated ES/EN segmented control (built in shared.js, styled in shared.css) — applies to all pages. - Redesign the Servicios cards and contact form on the home with the forge styling (flame chips, glow, two-column form, focus-glow). - Move the contact form off the home into a standalone /contacto/ page and expand it into a full "work with me / hire" page: hero, what I can build, how it works, why Fervon, contact form and FAQ. Bilingual + responsive. - Repoint all "Hablemos" links from #contacto to /contacto/. Co-Authored-By: Claude Opus 4.8 --- assets/shared.css | 7 +- assets/shared.js | 32 ++++++- contacto/index.html | 205 ++++++++++++++++++++++++++++++++++++++++++++ index.css | 76 +++++++++++++--- index.html | 28 +----- 5 files changed, 305 insertions(+), 43 deletions(-) create mode 100644 contacto/index.html diff --git a/assets/shared.css b/assets/shared.css index 1e107f7..e79b116 100644 --- a/assets/shared.css +++ b/assets/shared.css @@ -14,7 +14,12 @@ a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible, /* Anchored sections clear the fixed/sticky bar */ section[id]{scroll-margin-top:84px} -#lang{min-width:42px;justify-content:center} +/* ES / EN segmented language toggle (built by shared.js, replaces the old single button) */ +.langseg{display:inline-flex;align-items:center;gap:2px;padding:3px;border:1px solid var(--line2,#3A2C22);border-radius:10px;background:rgba(0,0,0,.22)} +.langseg .langopt{font-family:inherit;font-size:12.5px;font-weight:700;letter-spacing:.4px;color:var(--dim,#94867A);background:transparent;border:0;border-radius:7px;padding:5px 9px;cursor:pointer;line-height:1;transition:color .14s,background .14s,box-shadow .14s} +.langseg .langopt:hover{color:var(--bone,#EFE7DC)} +.langseg .langopt.on{color:#1A0E06;background:linear-gradient(180deg,var(--ember,#FF6A00),var(--brasa,#E0480F));box-shadow:0 4px 14px rgba(255,106,0,.35)} +.langseg .langopt.on:hover{color:#1A0E06} /* Skip link */ .skip{position:absolute;left:8px;top:-52px;z-index:200;background:var(--card,var(--panel,#1A1310));color:var(--bone,#EFE7DC);border:1px solid var(--ember,#FF6A00);padding:10px 16px;border-radius:10px;font-weight:600;transition:top .15s} diff --git a/assets/shared.js b/assets/shared.js index 60b8837..0a1e132 100644 --- a/assets/shared.js +++ b/assets/shared.js @@ -37,24 +37,48 @@ window.addEventListener('resize',function(){ if(window.innerWidth>880) set(false); }); })(); -/* Fervon bilingual toggle — ES/EN, persisted, used by every page */ +/* Fervon bilingual toggle — ES/EN segmented control, persisted, used by every page */ (function(){ var KEY="fervon-lang"; var base=(document.documentElement.getAttribute("lang")||"es").slice(0,2).toLowerCase(); var other=base==="es"?"en":"es"; var nodes=[].slice.call(document.querySelectorAll("[data-"+other+"]")); nodes.forEach(function(n){ var a=n.getAttribute("data-i18n-attr"); n.setAttribute("data-"+base, a?(n.getAttribute(a)||""):n.innerHTML); }); + + // Replace the legacy single #lang button with an ES/EN segmented control. + var opts={}; + (function(){ + var old=document.getElementById("lang"); if(!old) return; + var seg=document.createElement("div"); + seg.id="lang"; seg.className="langseg"; + seg.setAttribute("role","group"); seg.setAttribute("aria-label","Idioma / Language"); + ["es","en"].forEach(function(lg){ + var o=document.createElement("button"); + o.type="button"; o.className="langopt"; o.setAttribute("data-lang",lg); + o.textContent=lg.toUpperCase(); + o.setAttribute("aria-label",lg==="es"?"Español":"English"); + o.addEventListener("click",function(){ + if(document.documentElement.getAttribute("lang")===lg) return; + try{localStorage.setItem(KEY,lg);}catch(e){} + apply(lg); + }); + opts[lg]=o; seg.appendChild(o); + }); + old.parentNode.replaceChild(seg,old); + })(); + function apply(lang){ document.documentElement.setAttribute("lang",lang); for(var i=0;i + + + + + + Contacto · Fervon + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+

Construyamos algo. Forjado al rojo vivo.

+

Aplico el mismo motor con el que construyo mis productos —flotas de agentes de IA y un enfoque local-first— a los retos de tu empresa. De la idea al producto, rápido, y hablando directamente conmigo.

+ +
+ + +
+

Qué puedo construir

+

Software a medida, con agentes de IA.

+
+

De un MVP a tu propia fábrica de software

+

Tanto si tienes una idea clara como si solo tienes un problema que resolver, lo llevo del concepto al producto funcionando —dirigiendo flotas de agentes autónomos, con todo corriendo local-first cuando importa.

+
    +
  • Desarrollo a medidaProductos y MVPs de principio a fin, listos para lanzar.
  • +
  • Automatización con agentesFlotas de IA que se encargan de tus procesos y tu código.
  • +
  • Herramientas internasDashboards, CLIs y observabilidad local-first.
  • +
  • ConsultoríaCómo montar tu propia fábrica de software con IA.
  • +
+
+
+ + +
+

Cómo trabajo

+

Claro, directo y sin sorpresas.

+
+
+ 1 +

Hablamos

+

Me cuentas el problema. Sin compromiso y sin intermediarios — me hablas a mí.

+
+
+ 2 +

Propuesta clara

+

Alcance, plazos y precio cerrado, acordados antes de empezar a trabajar.

+
+
+ 3 +

Construyo con flotas de IA

+

Dirijo agentes autónomos para ir de la idea al producto en tiempo récord, sin pausa.

+
+
+ 4 +

Entrega y soporte

+

Tu código, documentado y tuyo. Te acompaño también después del lanzamiento.

+
+
+
+ + +
+

Por qué trabajar conmigo

+

Un estudio que entrega como un equipo, llevado por una persona a la que puedes llegar.

+
+
+

Velocidad real

+

Flotas de agentes trabajando en paralelo y sin pausa — lo que antes era cosa de un equipo entero sale en días.

+
+
+

Local-first y privado

+

Tu código y tus datos se quedan donde deben. La inferencia puede correr incluso en modelos locales, a coste $0.

+
+
+

Producto, no horas

+

Recibes algo que funciona, con alcance y precio cerrados — no una factura por horas.

+
+
+

Hablas conmigo

+

Sin gestores de cuenta ni capa comercial. Quien lo construye es quien te responde.

+
+
+
+ + +
+

Hablemos

+

¿Un producto, un servicio o solo saludar? Escríbeme — me llega a mí directamente.

+
+
+ + + + + + + + + +
+

Te respondo yo, sin intermediarios. ¿Prefieres código? Encuéntrame en GitHub.

+
+
+ + +
+

Preguntas frecuentes

+

Lo que la gente suele preguntar antes de empezar.

+
+
+ ¿Con qué tecnologías trabajas? +

TypeScript/Node y React en el front, Python donde encaja, SQLite/Postgres para datos, e integración profunda con LLMs —Claude y modelos locales vía llama.cpp. El mismo stack que hay detrás de mis productos.

+
+
+ ¿Trabajas con startups o con empresas? +

Con ambas. Desde un MVP para un fundador hasta automatizar procesos internos de un equipo ya establecido. Si se puede forjar, podemos hablar.

+
+
+ ¿Cómo es el precio? +

Por proyecto, con alcance y precio cerrados acordados antes de empezar —no por horas. Siempre sabes lo que vas a pagar antes de que arranque nada.

+
+
+ ¿Dónde estás? +

Remoto, desde España (CET). Trabajo con clientes de cualquier zona horaria — asíncrono por defecto y llamadas cuando hacen falta.

+
+
+ ¿De quién es el código? +

Tuyo. Todo lo que entrego es tuyo, documentado y traspasado — sin dependencia de mí ni de ninguna plataforma.

+
+
+
+ +
+ + + + + + diff --git a/index.css b/index.css index 5b83099..89a618e 100644 --- a/index.css +++ b/index.css @@ -120,23 +120,71 @@ .badge.paid{background:rgba(255,176,46,.14);color:var(--amber);border:1px solid rgba(255,176,46,.32)} /* Servicios */ - .services{background:linear-gradient(150deg,#1A1310,#140E0B);border:1px solid var(--line);border-radius:18px;padding:34px 32px} - .services h3{font-size:22px;font-weight:800} - .services .intro{color:var(--ash);margin-top:10px;max-width:640px} - .services ul{list-style:none;margin-top:22px;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 26px} - .services li{padding-left:24px;position:relative;color:var(--bone);font-size:15px;font-weight:600} - .services li::before{content:"";position:absolute;left:0;top:4px;width:15px;height:15px;background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF6A00' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E")} - .services li span{display:block;color:var(--ash);font-size:13.5px;font-weight:400} - .services .sact{margin-top:26px} + .services{position:relative;background:linear-gradient(150deg,#1d1510,#140E0B);border:1px solid var(--line2);border-radius:20px;padding:40px 36px;overflow:hidden} + .services::before{content:"";position:absolute;right:-90px;top:-90px;width:360px;height:360px;background:radial-gradient(circle,rgba(255,106,0,.16),rgba(224,72,15,.05) 42%,transparent 68%);pointer-events:none} + .services>*{position:relative;z-index:2} + .services h3{font-size:23px;font-weight:800;letter-spacing:-.3px} + .services .intro{color:var(--ash);margin-top:11px;max-width:620px;line-height:1.62} + .services ul{list-style:none;margin-top:28px;display:grid;grid-template-columns:repeat(2,1fr);gap:13px} + @media(max-width:620px){.services ul{grid-template-columns:1fr}} + .services li{padding:16px 16px 16px 54px;position:relative;background:rgba(255,255,255,.02);border:1px solid var(--line);border-radius:13px;color:var(--bone);font-size:15px;font-weight:700;transition:border-color .16s ease,background .16s ease,transform .16s ease} + .services li:hover{border-color:color-mix(in srgb,var(--ember) 44%,var(--line));background:rgba(255,106,0,.055);transform:translateY(-2px)} + .services li::before{content:"";position:absolute;left:14px;top:15px;width:28px;height:28px;border-radius:9px;border:1px solid color-mix(in srgb,var(--ember) 28%,transparent);background:color-mix(in srgb,var(--ember) 12%,#0c0908) no-repeat center/15px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF6A00' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E");transition:transform .16s ease} + .services li:hover::before{transform:scale(1.08)} + .services li span{display:block;color:var(--ash);font-size:13.5px;font-weight:400;margin-top:5px;line-height:1.45} + .services .sact{margin-top:30px} + @media(max-width:560px){.services{padding:30px 22px}} /* Contacto */ - .contact{max-width:580px;margin:0 auto} - .contact form{display:flex;flex-direction:column;gap:14px;margin-top:8px} - .contact input,.contact textarea{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:13px 15px;color:var(--bone);font-family:inherit;font-size:15px;transition:border-color .15s ease;resize:vertical} + .contact{max-width:600px;margin:0 auto} + .contact form{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:8px;background:linear-gradient(150deg,#1A1310,#140E0B);border:1px solid var(--line2);border-radius:18px;padding:28px;overflow:hidden} + .contact form::before{content:"";position:absolute;left:-80px;bottom:-90px;width:320px;height:320px;background:radial-gradient(circle,rgba(255,106,0,.13),transparent 66%);pointer-events:none} + .contact input,.contact textarea{position:relative;z-index:2;background:#0E0B0A;border:1px solid var(--line);border-radius:11px;padding:14px 16px;color:var(--bone);font-family:inherit;font-size:15px;transition:border-color .15s ease,box-shadow .15s ease;resize:vertical} + .contact textarea,.contact button{grid-column:1 / -1} .contact input::placeholder,.contact textarea::placeholder{color:var(--dim)} - .contact input:focus,.contact textarea:focus{outline:none;border-color:var(--ember)} - .contact button{align-self:flex-start} - .contact .note{text-align:center;color:var(--dim);font-size:13px;margin-top:14px} + .contact input:focus,.contact textarea:focus{outline:none;border-color:var(--ember);box-shadow:0 0 0 3px rgba(255,106,0,.15)} + .contact button{position:relative;z-index:2;justify-self:start} + .contact .note{text-align:center;color:var(--dim);font-size:13px;margin-top:16px} + .contact .note a{color:var(--amber);font-weight:600} + .contact .note a:hover{text-decoration:underline} + /* Standalone contact / hire page */ + .contact-page{display:flex;flex-direction:column;min-height:100vh} + .contact-page main{flex:1;padding-bottom:32px} + .chero{text-align:center;padding:62px 0 4px} + .chero h1{font-size:clamp(30px,5vw,46px);font-weight:800;letter-spacing:-1px;line-height:1.08;color:var(--bone)} + .chero h1 .grad{background:linear-gradient(90deg,var(--ember),var(--amber));-webkit-background-clip:text;background-clip:text;color:transparent} + .chero p{max-width:600px;margin:18px auto 0;color:var(--ash);font-size:18px;line-height:1.6} + .chero .cta-row{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin-top:30px} + + /* Process steps */ + .steps{display:grid;grid-template-columns:repeat(4,1fr);gap:14px} + @media(max-width:860px){.steps{grid-template-columns:repeat(2,1fr)}} + @media(max-width:520px){.steps{grid-template-columns:1fr}} + .step{background:linear-gradient(165deg,rgba(255,255,255,.022),transparent),var(--card);border:1px solid var(--line);border-radius:14px;padding:22px 20px} + .step .n{display:inline-grid;place-items:center;width:34px;height:34px;border-radius:10px;font-weight:800;font-size:15px;color:#1A0E06;background:linear-gradient(180deg,var(--ember),var(--brasa));box-shadow:0 4px 14px rgba(255,106,0,.3)} + .step h4{margin-top:14px;font-size:16px;font-weight:700;color:var(--bone)} + .step p{margin-top:7px;color:var(--ash);font-size:13.6px;line-height:1.55} + + /* Why cards */ + .why{display:grid;grid-template-columns:repeat(4,1fr);gap:14px} + @media(max-width:860px){.why{grid-template-columns:repeat(2,1fr)}} + @media(max-width:520px){.why{grid-template-columns:1fr}} + .whycard{background:linear-gradient(165deg,rgba(255,255,255,.022),transparent),var(--card);border:1px solid var(--line);border-radius:14px;padding:22px 20px;transition:border-color .16s ease,transform .16s ease} + .whycard:hover{border-color:color-mix(in srgb,var(--ember) 40%,var(--line));transform:translateY(-3px)} + .whycard h4{font-size:16px;font-weight:700;color:var(--bone);display:flex;align-items:center;gap:10px} + .whycard h4::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--ember);box-shadow:0 0 10px var(--ember);flex:none} + .whycard p{margin-top:9px;color:var(--ash);font-size:13.8px;line-height:1.55} + + /* FAQ */ + .faq{max-width:720px;margin:0 auto;display:flex;flex-direction:column;gap:10px} + .faq details{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:2px 18px;transition:border-color .16s ease} + .faq details[open]{border-color:var(--line2)} + .faq summary{cursor:pointer;list-style:none;padding:15px 0;font-weight:600;font-size:15px;color:var(--bone);display:flex;justify-content:space-between;align-items:center;gap:14px} + .faq summary::-webkit-details-marker{display:none} + .faq summary::after{content:"+";color:var(--ember);font-size:22px;font-weight:300;line-height:1;transition:transform .2s ease} + .faq details[open] summary::after{transform:rotate(45deg)} + .faq details p{color:var(--ash);font-size:14px;line-height:1.6;margin:0;padding:0 0 16px} + @media(max-width:560px){.contact form{grid-template-columns:1fr;padding:22px}} /* Footer */ footer{border-top:1px solid var(--line);margin-top:70px;padding:40px 0 56px;text-align:center} diff --git a/index.html b/index.html index 9101e46..34c0151 100644 --- a/index.html +++ b/index.html @@ -71,7 +71,7 @@ Servicios - Hablemos + Hablemos @@ -106,7 +106,7 @@

Fervon — estudio de software autónomo. Forjado al rojo

del latín fervere — arder, hervir, bullir con fervor

@@ -182,27 +182,7 @@

Software a medida, con agentes de
  • Herramientas internasDashboards, CLIs y observabilidad local-first.
  • ConsultoríaCómo montar tu propia fábrica de software con IA.
  • - - - - - -
    -

    Hablemos

    -

    ¿Un producto, un servicio o solo saludar? Escríbeme.

    -
    -
    - - - - - - - - - -
    -

    Te respondo yo, sin intermediarios.

    +
    @@ -213,7 +193,7 @@

    Hablemos

    Forjado al rojo vivo · © 2026 Fervon
    From aee1a9e7cfe2abebcbe783420d812a67f0f0c826 Mon Sep 17 00:00:00 2001 From: JoniMartin27 <130197986+JoniMartin27@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:06:39 +0200 Subject: [PATCH 2/4] refactor(web): drop Services section from home, add Contact to the nav MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove the Servicios section from the home (it now lives on /contacto/ as "Qué puedo construir" + "Cómo trabajo"). - Add a "Contacto" link to the nav on both pages; mark it aria-current on the contact page. Point the "Hablemos" CTA straight to the form (#form). - Repoint the now-dead #servicios links and drop them from the footers. Co-Authored-By: Claude Opus 4.8 --- contacto/index.html | 5 ++--- index.html | 22 ++-------------------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/contacto/index.html b/contacto/index.html index 5879893..6c415d7 100644 --- a/contacto/index.html +++ b/contacto/index.html @@ -53,9 +53,9 @@ - Servicios + Contacto - Hablemos + Hablemos @@ -193,7 +193,6 @@

    Preguntas frecuentes

    fervon
    diff --git a/index.html b/index.html index 34c0151..74d9127 100644 --- a/index.html +++ b/index.html @@ -69,9 +69,9 @@ - Servicios + Contacto - Hablemos + Hablemos @@ -169,30 +169,12 @@

    Productos

    - -
    -

    Servicios

    -

    ¿Necesitas que forje algo para ti?

    -
    -

    Software a medida, con agentes de IA

    -

    Aplico el mismo motor con el que construyo mis productos —flotas de agentes autónomos y un enfoque local-first— a los retos de tu empresa. De la idea al producto, rápido.

    -
      -
    • Desarrollo a medidaProductos y MVPs de principio a fin.
    • -
    • Automatización con agentesFlotas de IA para procesos y código.
    • -
    • Herramientas internasDashboards, CLIs y observabilidad local-first.
    • -
    • ConsultoríaCómo montar tu propia fábrica de software con IA.
    • -
    - -
    -
    -