/* Torre Auro — Level page (editorial) */ function AvailabilityStrip({ floor }) { const z = ZONES[floor.zone]; const rentedCount = floor.tot - floor.av; const urgent = floor.av === 1; return (
{Array.from({ length: floor.tot }).map((_, j) => { const rented = j < rentedCount; const cls = `av-strip-dot ${!rented && urgent ? 'urgent' : ''}`; return (
); })}
{floor.av === 0 ? 'Nivel completamente ocupado.' : floor.av === 1 ? <>Solo un espacio disponible de {floor.tot}. : <>{floor.av} de {floor.tot} disponibles.}
{floor.av <= 1 ? 'Los espacios se están llenando. Una vez rentado, el nivel queda cerrado.' : floor.av <= 2 ? 'Los espacios se están llenando. Agenda la visita esta semana.' : 'Buena disponibilidad. Elige el espacio que mejor se adapte a tu empresa.'}
); } function OfficeHierarchy({ floor }) { const eco = ZONES[floor.zone]?.eco || 'corporativo'; const types = TYPE_META[eco] || {}; // Retail = single planta libre if (eco === 'retail') { const o = floor.offices[0]; const meta = types['Planta libre']; return (
); } // Group by type letter const groupByType = (letter) => floor.offices.filter(o => typeKey(o) === letter); const anchors = groupByType('C'); const mids = groupByType('B'); const boutiqs = groupByType('A'); return (
{/* TIER 01 · ANCLA — gold prominence */} {anchors.length > 0 && (
01
Ancla · Tipo C · {types.C?.m2} {types.C?.capacity}

{types.C?.tagline}

{anchors.map(o => )}
)} {/* TIER 02 · CONSOLIDACIÓN */} {mids.length > 0 && (
02
Consolidación · Tipo B · {types.B?.m2} {types.B?.capacity}

{types.B?.tagline}

{mids.map(o => )}
)} {/* TIER 03 · BOUTIQUE */} {boutiqs.length > 0 && (
03
Boutique · Tipo A · {types.A?.m2} {types.A?.capacity}

{types.A?.tagline}

{boutiqs.map(o => )}
)}
); } function AnchorCard({ office, meta, floor }) { const isAvail = office.ok; return (
{meta?.letter} {office.m2} m²
{office.code} {isAvail ? Disponible : Rentado}

{meta?.tagline}

{meta?.anchorCopy && (

{meta.anchorCopy}

)}
Ideal para
    {(meta?.idealFor || []).map((it, i) =>
  • {it}
  • )}
Capacidad
{meta?.capacity}
Entrega
Obra gris
{FMT(office.price)}/mes
{isAvail ? ( ) : ( Rentado · sin disponibilidad )}
); } function MidCard({ office, meta, floor }) { const isAvail = office.ok; return (
isAvail && openChat(floor.id)}>
{meta?.letter}
{office.code}
{office.m2} m²
{meta?.tagline}
Ideal para {(meta?.idealFor || []).join(' · ')}
{meta?.capacity}
{FMT(office.price)}/mes
{isAvail ? Disponible : Rentado}
); } function BoutiqueCard({ office, meta, floor }) { const isAvail = office.ok; return (
isAvail && openChat(floor.id)}>
{meta?.letter} {office.code}
{office.m2} m²
{meta?.tagline}
{FMT(office.price)}/mes
{isAvail ? Disponible : }
); } function Faq({ items }) { const [open, setOpen] = useState(new Set([0])); const refs = useRef({}); function toggle(i) { setOpen(prev => { const next = new Set(prev); if (next.has(i)) next.delete(i); else next.add(i); return next; }); } return (
{items.map((f, i) => { const isOp = open.has(i); const h = refs.current[i]?.scrollHeight || 0; return (
{ refs.current[i] = el; }} >
{f.a}
); })}
); } function LevelPage({ floor }) { const z = ZONES[floor.zone]; return (
{/* HERO */}
{/* AVAILABILITY */} {/* INFO */}
01 / La propuesta del nivel

Por qué este nivel, y para quién.

01 · Argumentos

Por qué este nivel

{floor.bens.map((b, i) => (
/ {pad2(i + 1)} {b}
))}
02 · Buyer persona

Perfecto para

{floor.personas.map((p, i) => (
{pad2(i + 1)}
{p.name}
{p.desc}
))}
{/* OFFICE TABLE */}
02 / Los tres tamaños

Una lógica de ancla.

Cada nivel se compone de tres tamaños. El espacio ancla (137 m²) define la imagen del nivel y atrae el flujo principal. Los de consolidación (120 m²) acompañan. Los boutique (85 m²) se benefician del clúster que el ancla construye.

{/* THE PLAN */} {floor.planClass && (
03 / El plano

La distribución del nivel.

Plano arquitectónico del nivel {floor.sh}. La franja de color en la elevación lateral indica la posición del nivel en el edificio. En la planta se identifican las oficinas A (boutique), B (consolidación) y C (ancla).

Sección {floor.sh}
Ancla · C 137.45 m²
Consolidación · B 120.00 m²
Boutique · A 3 × 85.00 m²
Orientación Av. Tiburón · Ruiz Cortines
)} {/* FAQ */}
04 / Preguntas frecuentes

Dudas sobre este nivel.

{/* CTA */} openChat(floor.id)} onSecondary={() => openChat(floor.id + '-planos')} /> {/* NEXT LEVEL */}
04 / Continuar el recorrido
navigate('/' + floor.next.id)}>
{FLOOR_BY_ID[floor.next.id]?.sh}
{floor.next.sub}
{floor.next.label.split('—')[0]}— {floor.next.label.split('—')[1]?.trim()}
{FLOOR_BY_ID[floor.next.id]?.av ?? 0}/{FLOOR_BY_ID[floor.next.id]?.tot ?? 0} disponibles · desde {FMT(FLOOR_BY_ID[floor.next.id]?.pMin ?? 0)}/mes
); } Object.assign(window, { LevelPage });