New system, done right — the first time. We install all major brands across Florida with same-day availability and free estimates.
Free Estimate · All Major Brands · Same-Day Available
Add Photo
Click to upload a photo from our gallery
Add Photo
Click to upload a photo from our gallery
We visit your property, assess your space, and recommend the best system — at no cost and no obligation.
We size your unit correctly for your square footage, ceiling height, and sun exposure. No guesswork.
Our certified techs install your new system following all local codes, typically in a single day.
We test every component, check refrigerant levels, and walk you through your new system before we leave.
We work with the industry's most trusted brands to deliver lasting comfort and efficiency for every home and business.
Premium HVAC systems known for advanced technology, high efficiency, and ultra-quiet operation.
Engineered for durability and reliable performance, designed to handle demanding climates like Florida.
Industry-leading brand offering proven reliability, comfort, and energy-efficient solutions.
Advanced HVAC technology with high-efficiency systems, including mini-split and ductless solutions.
Dependable and efficient systems offering excellent comfort and value.
Reliable performance with quality engineering and long-term durability.
Premium inverter and ductless technology focused on efficiency and personalized comfort.
Affordable and reliable HVAC solutions with excellent value and serviceability.
Reliable HVAC solutions designed for residential and commercial applications.
And many more HVAC brands available. Ask us about your system →
en cualquier sitio: * <" + "script src="aaj-widget.js">" + "script> * * No requiere frameworks. Vanilla JS. Preferencias guardadas en localStorage. */ (function () { "use strict"; const STORAGE_KEY = "aaj-web-prefs"; /** * Configuración por sitio. Cada cliente define esto ANTES de cargar * aaj-widget.js, por ejemplo: * * window.AAJ_CONFIG = { * siteId: "cliente-001", * simplifyEndpoint: "https://us-central1-TU-PROYECTO.cloudfunctions.net/aajSimplify" * }; * (luego cargar aaj-widget.js) * * Si no se define simplifyEndpoint, el botón "Simplificar" se oculta. */ const config = Object.assign( { siteId: null, simplifyEndpoint: null }, window.AAJ_CONFIG || {} ); const defaultPrefs = { fontScale: 1, // 1 = 100% lineSpacing: 1, // 1 = normal, 1.5 / 2 = aumentado dyslexiaFont: false, highContrast: false, mode: "default", // "default" | "zen" | "gamer" }; let prefs = loadPrefs(); // ---------- Persistencia ---------- function loadPrefs() { try { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) return { ...defaultPrefs }; return { ...defaultPrefs, ...JSON.parse(raw) }; } catch (e) { return { ...defaultPrefs }; } } function savePrefs() { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs)); } catch (e) { /* almacenamiento no disponible, continuar sin persistencia */ } } // ---------- Estilos ---------- function injectStyles() { const style = document.createElement("style"); style.id = "aaj-web-styles"; style.textContent = ` #aaj-toggle { position: fixed; bottom: 20px; left: 20px; width: 56px; height: 56px; border-radius: 50%; background: linear-gradient(135deg, #8aff5e, #5ec6ff); border: none; box-shadow: 0 4px 14px rgba(0,0,0,0.25); cursor: pointer; z-index: 2147483000; display: flex; align-items: center; justify-content: center; font-size: 26px; line-height: 1; transition: transform 0.2s ease; } #aaj-toggle:hover { transform: scale(1.08); } #aaj-toggle:focus-visible { outline: 3px solid #222; outline-offset: 2px; } #aaj-panel { position: fixed; bottom: 86px; right: 20px; width: 300px; max-width: calc(100vw - 40px); max-height: 70vh; overflow-y: auto; background: #14171c; color: #f2f2f2; border-radius: 14px; box-shadow: 0 8px 30px rgba(0,0,0,0.35); font-family: Arial, Helvetica, sans-serif; font-size: 15px; padding: 16px; z-index: 2147483000; display: none; } #aaj-panel.aaj-open { display: block; } #aaj-panel h2 { font-size: 16px; margin: 0 0 12px 0; display: flex; align-items: center; gap: 8px; } #aaj-panel .aaj-section { margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px solid rgba(255,255,255,0.08); } #aaj-panel .aaj-section:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } #aaj-panel label { display: block; margin-bottom: 6px; font-weight: bold; } #aaj-panel .aaj-row { display: flex; gap: 8px; flex-wrap: wrap; } #aaj-panel button.aaj-btn { flex: 1; min-width: 60px; padding: 8px 10px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.15); background: #20252d; color: #f2f2f2; cursor: pointer; font-size: 14px; } #aaj-panel button.aaj-btn:hover { background: #2c333d; } #aaj-panel button.aaj-btn.aaj-active { background: #5ec6ff; color: #0a0a0a; border-color: #5ec6ff; font-weight: bold; } #aaj-panel .aaj-toggle-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; } #aaj-panel .aaj-footer { font-size: 11px; opacity: 0.6; text-align: center; margin-top: 4px; } /* ---- Estados aplicados al sitio ---- */ html.aaj-dyslexia-font, html.aaj-dyslexia-font * { font-family: "OpenDyslexic", "Comic Sans MS", Arial, sans-serif !important; } html.aaj-high-contrast, html.aaj-high-contrast body { background: #000 !important; color: #fff !important; } html.aaj-high-contrast a { color: #ffd400 !important; } html.aaj-high-contrast img { filter: grayscale(40%) contrast(1.1); } /* Modo Zen (filtro Franz): tonos suaves, baja saturación */ html.aaj-mode-zen { filter: saturate(0.75) brightness(0.97); } html.aaj-mode-zen, html.aaj-mode-zen body { background-color: #f4f1ec !important; } /* Modo Gamer (filtro Kalman): contraste y saturación elevados */ html.aaj-mode-gamer { filter: saturate(1.25) contrast(1.05); } #aaj-reading-highlight { outline: 2px solid #5ec6ff; outline-offset: 2px; border-radius: 3px; } `; document.head.appendChild(style); } // ---------- UI ---------- function buildUI() { // Botón flotante const toggle = document.createElement("button"); toggle.id = "aaj-toggle"; toggle.type = "button"; toggle.setAttribute("aria-label", "Abrir opciones de accesibilidad AimAndJoy"); toggle.setAttribute("aria-expanded", "false"); toggle.innerHTML = "♿"; // Panel const panel = document.createElement("div"); panel.id = "aaj-panel"; panel.setAttribute("role", "dialog"); panel.setAttribute("aria-label", "Opciones de accesibilidad AimAndJoy"); panel.innerHTML = `
`;
document.body.appendChild(toggle);
document.body.appendChild(panel);
toggle.addEventListener("click", () => {
const isOpen = panel.classList.toggle("aaj-open");
toggle.setAttribute("aria-expanded", String(isOpen));
});
panel.addEventListener("click", handlePanelClick);
return { toggle, panel };
}
// ---------- Lógica de acciones ----------
function handlePanelClick(e) {
const btn = e.target.closest("button[data-action]");
if (!btn) return;
const action = btn.dataset.action;
switch (action) {
case "font-inc":
prefs.fontScale = Math.min(2, +(prefs.fontScale + 0.1).toFixed(2));
break;
case "font-dec":
prefs.fontScale = Math.max(0.8, +(prefs.fontScale - 0.1).toFixed(2));
break;
case "font-reset":
prefs.fontScale = 1;
break;
case "spacing-normal":
prefs.lineSpacing = 1;
break;
case "spacing-comfortable":
prefs.lineSpacing = 1.5;
break;
case "spacing-wide":
prefs.lineSpacing = 2;
break;
case "toggle-dyslexia":
prefs.dyslexiaFont = !prefs.dyslexiaFont;
break;
case "toggle-contrast":
prefs.highContrast = !prefs.highContrast;
break;
case "mode-default":
prefs.mode = "default";
break;
case "mode-zen":
prefs.mode = "zen";
break;
case "mode-gamer":
prefs.mode = "gamer";
break;
case "read-page":
readPageAloud();
return; // no necesita re-render del panel
case "stop-read":
stopReadingAloud();
return;
case "simplify":
simplifyPage(btn);
return;
}
savePrefs();
applyPrefs();
syncPanelState();
}
function applyPrefs() {
const html = document.documentElement;
// Tamaño de texto
html.style.fontSize = (prefs.fontScale * 100) + "%";
// Espaciado de línea
if (prefs.lineSpacing === 1) {
html.style.removeProperty("--aaj-line-height");
document.body.style.removeProperty("line-height");
} else {
document.body.style.lineHeight = String(prefs.lineSpacing);
}
// Fuente para dislexia
html.classList.toggle("aaj-dyslexia-font", !!prefs.dyslexiaFont);
// Alto contraste
html.classList.toggle("aaj-high-contrast", !!prefs.highContrast);
// Modo visual (Zen / Gamer / Original)
html.classList.remove("aaj-mode-zen", "aaj-mode-gamer");
if (prefs.mode === "zen") html.classList.add("aaj-mode-zen");
if (prefs.mode === "gamer") html.classList.add("aaj-mode-gamer");
}
function syncPanelState() {
const panel = document.getElementById("aaj-panel");
if (!panel) return;
const dyslexiaBtn = panel.querySelector("#aaj-dyslexia");
dyslexiaBtn.classList.toggle("aaj-active", !!prefs.dyslexiaFont);
dyslexiaBtn.textContent = prefs.dyslexiaFont ? "Desactivar" : "Activar";
const contrastBtn = panel.querySelector("#aaj-contrast");
contrastBtn.classList.toggle("aaj-active", !!prefs.highContrast);
contrastBtn.textContent = prefs.highContrast ? "Desactivar" : "Activar";
const spacingMap = { 1: "spacing-normal", 1.5: "spacing-comfortable", 2: "spacing-wide" };
highlightGroup(panel, ["spacing-normal", "spacing-comfortable", "spacing-wide"], spacingMap[prefs.lineSpacing]);
const modeMap = { default: "mode-default", zen: "mode-zen", gamer: "mode-gamer" };
highlightGroup(panel, ["mode-default", "mode-zen", "mode-gamer"], modeMap[prefs.mode]);
}
function highlightGroup(panel, actions, activeAction) {
actions.forEach((action) => {
const btn = panel.querySelector(`[data-action="${action}"]`);
if (btn) btn.classList.toggle("aaj-active", action === activeAction);
});
}
// ---------- Lectura en voz alta ----------
function readPageAloud() {
if (!("speechSynthesis" in window)) {
alert("Tu navegador no soporta lectura en voz alta.");
return;
}
stopReadingAloud();
const text = getReadableText();
if (!text.trim()) return;
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = document.documentElement.lang || "es-ES";
window.speechSynthesis.speak(utterance);
}
function stopReadingAloud() {
if ("speechSynthesis" in window) {
window.speechSynthesis.cancel();
}
}
function getReadableText() {
// Extrae texto visible del