Compare commits
10
Commits
b875fe2af4
...
d17407a302
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d17407a302 | ||
|
|
492dc5436c | ||
|
|
696ff9fa51 | ||
|
|
2985433ecb | ||
|
|
e76d7b5027 | ||
|
|
40e378bff8 | ||
|
|
d9062ce754 | ||
|
|
2587826fa6 | ||
|
|
b7db0d6741 | ||
|
|
34b4c2d6d2 |
+8
-1
@@ -7,15 +7,22 @@ COPY . .
|
|||||||
RUN pnpm install --frozen-lockfile 2>/dev/null || pnpm install --no-frozen-lockfile --force
|
RUN pnpm install --frozen-lockfile 2>/dev/null || pnpm install --no-frozen-lockfile --force
|
||||||
RUN pnpm --filter @moraworld/database exec prisma generate && pnpm --filter @moraworld/database build
|
RUN pnpm --filter @moraworld/database exec prisma generate && pnpm --filter @moraworld/database build
|
||||||
RUN pnpm --filter @moraworld/api build
|
RUN pnpm --filter @moraworld/api build
|
||||||
|
RUN pnpm deploy --filter @moraworld/api --prod /app/deploy
|
||||||
|
# pnpm deploy no incluye .prisma (binario generado) — copiarlo al mismo path relativo que usa pnpm
|
||||||
|
RUN src=$(find /app/node_modules/.pnpm -name ".prisma" -path "*@prisma+client*" -type d | head -1) && \
|
||||||
|
rel="${src#/app/node_modules/}" && \
|
||||||
|
mkdir -p "/app/deploy/node_modules/$(dirname "$rel")" && \
|
||||||
|
cp -rL "$src" "/app/deploy/node_modules/$(dirname "$rel")/"
|
||||||
|
|
||||||
FROM node:22-alpine AS runner
|
FROM node:22-alpine AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
RUN addgroup -S app && adduser -S app app
|
RUN addgroup -S app && adduser -S app app
|
||||||
COPY --from=builder /app/node_modules ./node_modules
|
COPY --from=builder /app/deploy/node_modules ./node_modules
|
||||||
COPY --from=builder /app/apps/api/dist ./dist
|
COPY --from=builder /app/apps/api/dist ./dist
|
||||||
COPY --from=builder /app/apps/api/package.json ./
|
COPY --from=builder /app/apps/api/package.json ./
|
||||||
COPY --from=builder /app/packages/database ./packages/database
|
COPY --from=builder /app/packages/database ./packages/database
|
||||||
|
RUN mkdir -p /app/uploads && chown -R app:app /app
|
||||||
USER app
|
USER app
|
||||||
EXPOSE 3001
|
EXPOSE 3001
|
||||||
CMD ["node", "dist/main.js"]
|
CMD ["node", "dist/main.js"]
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
"use client";
|
||||||
|
import { useState, useEffect, useRef } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export function LandingNavbar() {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const menuRef = useRef<HTMLDivElement>(null);
|
||||||
|
const btnRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function handleClick(e: MouseEvent) {
|
||||||
|
if (
|
||||||
|
menuRef.current && !menuRef.current.contains(e.target as Node) &&
|
||||||
|
btnRef.current && !btnRef.current.contains(e.target as Node)
|
||||||
|
) {
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener("click", handleClick);
|
||||||
|
return () => document.removeEventListener("click", handleClick);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function close() { setOpen(false); }
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<nav className="ln-nav">
|
||||||
|
<div className="ln-inner container">
|
||||||
|
<Link href="/" className="ln-logo">
|
||||||
|
Moraworld<span>.</span>Imports
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="ln-links">
|
||||||
|
<Link href="/calculadora" className="ln-link">Calculadora</Link>
|
||||||
|
<Link href="/tracking" className="ln-link">Tracking</Link>
|
||||||
|
<Link href="/como-funciona" className="ln-link">Cómo funciona</Link>
|
||||||
|
<Link href="/carga-pesada" className="ln-link">Carga Pesada</Link>
|
||||||
|
<Link href="/quienes-somos" className="ln-link">Nosotros</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ln-cta">
|
||||||
|
<Link href="/login" className="btn btn-outline btn-sm">Iniciar sesión</Link>
|
||||||
|
<Link href="/registro" className="btn btn-primary btn-sm">Abrir casillero</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
ref={btnRef}
|
||||||
|
className={`ln-hamburger${open ? " open" : ""}`}
|
||||||
|
onClick={() => setOpen(v => !v)}
|
||||||
|
aria-label="Abrir menú"
|
||||||
|
>
|
||||||
|
<span />
|
||||||
|
<span />
|
||||||
|
<span />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div ref={menuRef} className={`ln-mobile-menu${open ? " open" : ""}`}>
|
||||||
|
<div className="ln-mobile-links">
|
||||||
|
<Link href="/calculadora" onClick={close}>Calculadora</Link>
|
||||||
|
<Link href="/tracking" onClick={close}>Tracking</Link>
|
||||||
|
<Link href="/como-funciona" onClick={close}>Cómo funciona</Link>
|
||||||
|
<Link href="/carga-pesada" onClick={close}>Carga Pesada</Link>
|
||||||
|
<Link href="/quienes-somos" onClick={close}>Nosotros</Link>
|
||||||
|
</div>
|
||||||
|
<div className="ln-mobile-cta">
|
||||||
|
<Link href="/login" className="btn btn-outline w-full" onClick={close}>Iniciar sesión</Link>
|
||||||
|
<Link href="/registro" className="btn btn-primary w-full" onClick={close}>Abrir casillero gratis →</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -472,3 +472,233 @@ tbody tr:hover { background: var(--gray-50); }
|
|||||||
.grid-4 { grid-template-columns: repeat(2,1fr); }
|
.grid-4 { grid-template-columns: repeat(2,1fr); }
|
||||||
.grid-3 { grid-template-columns: repeat(2,1fr); }
|
.grid-3 { grid-template-columns: repeat(2,1fr); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════════════════════════════════════════
|
||||||
|
LANDING PAGE — Responsive Layout
|
||||||
|
═══════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
/* ── Navbar ── */
|
||||||
|
.ln-nav {
|
||||||
|
position: sticky; top: 0; z-index: 50;
|
||||||
|
background: rgba(255,255,255,.97); backdrop-filter: blur(12px);
|
||||||
|
border-bottom: 1px solid var(--gray-200);
|
||||||
|
height: 64px; display: flex; align-items: center;
|
||||||
|
}
|
||||||
|
.ln-inner {
|
||||||
|
display: flex; align-items: center; justify-content: space-between; gap: 1rem;
|
||||||
|
}
|
||||||
|
.ln-logo {
|
||||||
|
font-size: 1.2rem; font-weight: 800; color: var(--dark); white-space: nowrap; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.ln-logo span { color: var(--accent); }
|
||||||
|
.ln-links {
|
||||||
|
display: flex; align-items: center; gap: 1.5rem; flex: 1; justify-content: center;
|
||||||
|
}
|
||||||
|
.ln-link {
|
||||||
|
font-size: .875rem; font-weight: 500; color: var(--gray-700); transition: color .15s; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ln-link:hover { color: var(--primary); }
|
||||||
|
.ln-cta { display: flex; gap: .5rem; flex-shrink: 0; }
|
||||||
|
.ln-hamburger {
|
||||||
|
display: none; flex-direction: column; gap: 5px;
|
||||||
|
background: none; border: none; padding: 4px; cursor: pointer; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.ln-hamburger span {
|
||||||
|
display: block; width: 24px; height: 2px;
|
||||||
|
background: var(--gray-900); border-radius: 2px; transition: all .3s;
|
||||||
|
}
|
||||||
|
.ln-hamburger.open span:nth-child(1) { transform: rotate(45deg) translate(5px, 5px); }
|
||||||
|
.ln-hamburger.open span:nth-child(2) { opacity: 0; }
|
||||||
|
.ln-hamburger.open span:nth-child(3) { transform: rotate(-45deg) translate(5px, -5px); }
|
||||||
|
|
||||||
|
/* ── Mobile menu ── */
|
||||||
|
.ln-mobile-menu {
|
||||||
|
display: none; position: fixed; top: 64px; left: 0; right: 0; z-index: 49;
|
||||||
|
background: var(--white); border-bottom: 1px solid var(--gray-200);
|
||||||
|
padding: 1rem 1.5rem 1.5rem; box-shadow: 0 8px 32px rgba(0,0,0,.12);
|
||||||
|
}
|
||||||
|
.ln-mobile-menu.open { display: block; }
|
||||||
|
.ln-mobile-links { display: flex; flex-direction: column; }
|
||||||
|
.ln-mobile-links a {
|
||||||
|
display: block; padding: .85rem 0; border-bottom: 1px solid var(--gray-100);
|
||||||
|
font-size: .95rem; font-weight: 500; color: var(--gray-700);
|
||||||
|
}
|
||||||
|
.ln-mobile-links a:last-child { border-bottom: none; }
|
||||||
|
.ln-mobile-links a:hover { color: var(--primary); }
|
||||||
|
.ln-mobile-cta { display: flex; flex-direction: column; gap: .5rem; margin-top: 1rem; }
|
||||||
|
|
||||||
|
/* ── Hero ── */
|
||||||
|
.ln-hero {
|
||||||
|
background: linear-gradient(135deg, #0D1117 0%, #0D2150 100%);
|
||||||
|
padding: 6rem 0 4.5rem; color: var(--white);
|
||||||
|
}
|
||||||
|
.ln-hero-badge {
|
||||||
|
display: inline-flex; align-items: center; gap: .5rem;
|
||||||
|
background: rgba(0,87,255,.15); border: 1px solid rgba(0,87,255,.3);
|
||||||
|
color: #7AADFF; font-size: .8rem; font-weight: 600;
|
||||||
|
padding: 6px 14px; border-radius: 999px; margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.ln-hero-badge-dot {
|
||||||
|
width: 8px; height: 8px; border-radius: 50%; background: #7AADFF;
|
||||||
|
animation: pulse-dot 2s infinite;
|
||||||
|
}
|
||||||
|
@keyframes pulse-dot { 0%,100%{opacity:1} 50%{opacity:.4} }
|
||||||
|
.ln-hero h1 {
|
||||||
|
font-size: clamp(2rem, 5vw, 3.2rem); font-weight: 800;
|
||||||
|
line-height: 1.15; margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.ln-hero h1 em { color: var(--accent); font-style: normal; }
|
||||||
|
.ln-hero-sub {
|
||||||
|
color: #9CA3AF; font-size: 1.05rem; max-width: 540px; margin-bottom: 1rem; line-height: 1.7;
|
||||||
|
}
|
||||||
|
.ln-hero-address {
|
||||||
|
background: rgba(0,87,255,.1); border: 1px solid rgba(0,87,255,.25);
|
||||||
|
border-radius: 10px; padding: .875rem 1.25rem; margin-bottom: 2rem;
|
||||||
|
font-family: monospace; font-size: .9rem; color: #A5B4FC; max-width: 520px;
|
||||||
|
}
|
||||||
|
.ln-hero-actions { display: flex; gap: .75rem; flex-wrap: wrap; margin-bottom: 3rem; }
|
||||||
|
.ln-hero-trust { display: flex; gap: 2rem; flex-wrap: wrap; }
|
||||||
|
.ln-trust-item { display: flex; gap: .625rem; align-items: flex-start; }
|
||||||
|
.ln-trust-icon { font-size: 1.4rem; }
|
||||||
|
.ln-trust-name { font-weight: 600; font-size: .875rem; color: var(--white); display: block; }
|
||||||
|
.ln-trust-sub { font-size: .75rem; color: #6B7280; }
|
||||||
|
|
||||||
|
/* ── Section wrappers ── */
|
||||||
|
.ln-section { padding: 5rem 0; }
|
||||||
|
.ln-section-gray { padding: 5rem 0; background: var(--gray-100); }
|
||||||
|
.ln-section-dark { padding: 5rem 0; background: var(--dark); }
|
||||||
|
.ln-section-head { text-align: center; margin-bottom: 3rem; }
|
||||||
|
.ln-section-tag {
|
||||||
|
display: inline-block; background: #EEF3FF; color: var(--primary);
|
||||||
|
font-size: .72rem; font-weight: 700; letter-spacing: .08em;
|
||||||
|
text-transform: uppercase; padding: 4px 14px; border-radius: 999px; margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.ln-section-title { font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 800; margin-bottom: .5rem; }
|
||||||
|
.ln-section-sub { font-size: .95rem; color: var(--gray-500); max-width: 560px; margin: 0 auto; }
|
||||||
|
|
||||||
|
/* ── Responsive grids (landing specific) ── */
|
||||||
|
.ln-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
|
||||||
|
.ln-grid-3 { display: grid; grid-template-columns: repeat(3,1fr); gap: 1rem; }
|
||||||
|
.ln-grid-4 { display: grid; grid-template-columns: repeat(4,1fr); gap: 1rem; }
|
||||||
|
.ln-grid-2-1 { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: start; }
|
||||||
|
|
||||||
|
/* ── Service cards ── */
|
||||||
|
.ln-service-card {
|
||||||
|
background: var(--white); border-radius: 16px; padding: 2rem;
|
||||||
|
border: 2px solid var(--gray-200); transition: border-color .25s, box-shadow .25s, transform .25s;
|
||||||
|
}
|
||||||
|
.ln-service-card:hover { border-color: var(--primary); box-shadow: var(--shadow-xl); transform: translateY(-4px); }
|
||||||
|
.ln-service-card.featured { border-color: #BFDBFE; }
|
||||||
|
.ln-service-icon { font-size: 2.5rem; margin-bottom: .75rem; }
|
||||||
|
.ln-service-card h3 { font-weight: 800; font-size: 1.15rem; margin-bottom: .5rem; }
|
||||||
|
.ln-service-card p { color: var(--gray-500); margin-bottom: 1rem; font-size: .88rem; }
|
||||||
|
.ln-service-list { padding-left: 1.25rem; display: flex; flex-direction: column; gap: 5px; font-size: .85rem; color: var(--gray-700); margin-bottom: 1.25rem; }
|
||||||
|
|
||||||
|
/* ── Module cards ── */
|
||||||
|
.ln-module-card {
|
||||||
|
background: var(--gray-50); border-radius: 12px; padding: 1.25rem;
|
||||||
|
border: 1px solid var(--gray-200); transition: box-shadow .2s, transform .2s;
|
||||||
|
}
|
||||||
|
.ln-module-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
|
||||||
|
.ln-module-icon { font-size: 1.8rem; margin-bottom: .625rem; }
|
||||||
|
.ln-module-title { font-weight: 700; font-size: .9rem; margin-bottom: .375rem; }
|
||||||
|
.ln-module-desc { color: var(--gray-500); font-size: .8rem; margin-bottom: .625rem; line-height: 1.5; }
|
||||||
|
.ln-module-tag { background: #EEF3FF; color: var(--primary); font-size: .68rem; font-weight: 700; padding: 2px 8px; border-radius: 999px; }
|
||||||
|
|
||||||
|
/* ── Tracking states ── */
|
||||||
|
.ln-tracking-state {
|
||||||
|
display: flex; gap: .75rem; align-items: center;
|
||||||
|
background: var(--white); border-radius: 8px; padding: .5rem .875rem;
|
||||||
|
border: 1px solid var(--gray-200);
|
||||||
|
}
|
||||||
|
.ln-state-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
|
||||||
|
.ln-state-num { font-family: monospace; font-size: .68rem; color: #9CA3AF; min-width: 20px; }
|
||||||
|
.ln-state-name { font-family: monospace; font-size: .78rem; font-weight: 700; flex: 1; }
|
||||||
|
.ln-state-desc { font-size: .72rem; color: var(--gray-500); text-align: right; }
|
||||||
|
|
||||||
|
/* ── Calculator preview ── */
|
||||||
|
.ln-calc-formula {
|
||||||
|
background: var(--dark); border-radius: 12px; padding: 1.25rem 1.5rem;
|
||||||
|
font-family: monospace; font-size: .82rem; color: #A5B4FC;
|
||||||
|
text-align: left; max-width: 600px; margin: 0 auto 1.75rem;
|
||||||
|
line-height: 2; border: 1px solid rgba(255,255,255,.08);
|
||||||
|
}
|
||||||
|
.ln-senae-card {
|
||||||
|
border-radius: 12px; padding: 1.5rem; text-align: center;
|
||||||
|
}
|
||||||
|
.ln-senae-rate { font-size: 2rem; font-weight: 900; line-height: 1; margin: .25rem 0 .5rem; }
|
||||||
|
|
||||||
|
/* ── Role cards ── */
|
||||||
|
.ln-role-card {
|
||||||
|
border-radius: 12px; padding: 1.25rem; border: 1px solid var(--gray-200);
|
||||||
|
transition: box-shadow .2s, transform .2s;
|
||||||
|
}
|
||||||
|
.ln-role-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
|
||||||
|
.ln-role-icon { font-size: 1.5rem; margin-bottom: .625rem; }
|
||||||
|
.ln-role-name { font-weight: 700; margin-bottom: .375rem; font-size: .95rem; }
|
||||||
|
.ln-role-desc { color: var(--gray-500); font-size: .82rem; margin-bottom: .75rem; line-height: 1.5; }
|
||||||
|
.ln-role-badge { background: rgba(0,0,0,.06); font-size: .7rem; font-weight: 700; padding: 2px 10px; border-radius: 999px; }
|
||||||
|
|
||||||
|
/* ── Company cards ── */
|
||||||
|
.ln-company-card {
|
||||||
|
background: var(--white); border-radius: 16px; padding: 1.75rem;
|
||||||
|
border: 2px solid var(--gray-200); display: flex; gap: 1rem; align-items: flex-start;
|
||||||
|
transition: border-color .25s;
|
||||||
|
}
|
||||||
|
.ln-company-card:hover { border-color: var(--primary); }
|
||||||
|
.ln-company-flag { font-size: 2.5rem; flex-shrink: 0; }
|
||||||
|
.ln-company-name { font-weight: 800; margin-bottom: .375rem; }
|
||||||
|
.ln-company-desc { color: var(--gray-500); font-size: .82rem; line-height: 1.6; margin-bottom: .625rem; }
|
||||||
|
.ln-company-badge { background: #EEF3FF; color: var(--primary); font-size: .7rem; font-weight: 700; padding: 2px 10px; border-radius: 999px; }
|
||||||
|
|
||||||
|
/* ── CTA final ── */
|
||||||
|
.ln-cta-section {
|
||||||
|
padding: 5rem 0;
|
||||||
|
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.ln-cta-section h2 { font-size: clamp(1.6rem, 4vw, 2.5rem); font-weight: 800; color: var(--white); margin-bottom: 1rem; }
|
||||||
|
.ln-cta-section p { color: rgba(255,255,255,.75); font-size: 1rem; margin-bottom: 2rem; }
|
||||||
|
|
||||||
|
/* ── Footer ── */
|
||||||
|
.ln-footer { background: var(--dark); padding: 3.5rem 0 2rem; color: rgba(255,255,255,.5); }
|
||||||
|
.ln-footer-logo { font-size: 1.1rem; font-weight: 800; color: var(--white); margin-bottom: .5rem; }
|
||||||
|
.ln-footer-logo span { color: var(--accent); }
|
||||||
|
.ln-footer-links {
|
||||||
|
display: flex; gap: 1.5rem; flex-wrap: wrap; justify-content: center;
|
||||||
|
margin: 1.5rem 0; font-size: .82rem;
|
||||||
|
}
|
||||||
|
.ln-footer-links a:hover { color: var(--white); }
|
||||||
|
.ln-footer-badges { display: flex; gap: .5rem; flex-wrap: wrap; justify-content: center; margin-bottom: 1.5rem; }
|
||||||
|
.ln-footer-badge {
|
||||||
|
background: rgba(255,255,255,.07); color: rgba(255,255,255,.5);
|
||||||
|
font-size: .7rem; font-weight: 700; padding: 4px 12px; border-radius: 999px;
|
||||||
|
border: 1px solid rgba(255,255,255,.1);
|
||||||
|
}
|
||||||
|
.ln-footer-legal {
|
||||||
|
border-top: 1px solid rgba(255,255,255,.07); margin-top: 1.5rem; padding-top: 1rem;
|
||||||
|
font-size: .72rem; color: rgba(255,255,255,.3); line-height: 1.7; text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Responsive breakpoints (landing) ─────────────────── */
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.ln-grid-4 { grid-template-columns: repeat(2,1fr); }
|
||||||
|
.ln-grid-3 { grid-template-columns: repeat(2,1fr); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.ln-links, .ln-cta { display: none !important; }
|
||||||
|
.ln-hamburger { display: flex; }
|
||||||
|
|
||||||
|
.ln-grid-2, .ln-grid-3, .ln-grid-4, .ln-grid-2-1 { grid-template-columns: 1fr !important; }
|
||||||
|
|
||||||
|
.ln-hero { padding: 3rem 0 2.5rem; }
|
||||||
|
.ln-section, .ln-section-gray, .ln-section-dark { padding: 3rem 0; }
|
||||||
|
.ln-cta-section { padding: 3rem 0; }
|
||||||
|
|
||||||
|
.ln-hero-trust { gap: 1.25rem; }
|
||||||
|
.ln-state-desc { display: none; }
|
||||||
|
|
||||||
|
.ln-tracking-state { flex-wrap: wrap; }
|
||||||
|
.ln-state-name { font-size: .72rem; }
|
||||||
|
}
|
||||||
|
|||||||
+203
-238
@@ -1,6 +1,6 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { WhatsAppFloat } from "./_components/whatsapp-float";
|
import { LandingNavbar } from "./_components/landing-navbar";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Moraworld Imports — Tu casillero en New Jersey para Ecuador",
|
title: "Moraworld Imports — Tu casillero en New Jersey para Ecuador",
|
||||||
@@ -9,17 +9,17 @@ export const metadata: Metadata = {
|
|||||||
keywords: ["casillero New Jersey", "importaciones Ecuador", "SENAE", "Amazon Ecuador", "envíos EE.UU. Ecuador"],
|
keywords: ["casillero New Jersey", "importaciones Ecuador", "SENAE", "Amazon Ecuador", "envíos EE.UU. Ecuador"],
|
||||||
};
|
};
|
||||||
|
|
||||||
// ─── Datos estáticos de la landing (sin DB, SSG) ──────────────
|
// ─── Datos estáticos (SSG) ──────────────────────────────
|
||||||
|
|
||||||
const TRACKING_STATES = [
|
const TRACKING_STATES = [
|
||||||
{ num: "01", name: "REGISTRADO", color: "#6B7280", desc: "El cliente registró la compra" },
|
{ num: "01", name: "REGISTRADO", color: "#6B7280", desc: "El cliente registró la compra" },
|
||||||
{ num: "02", name: "EN_TRANSITO_BODEGA", color: "#F59E0B", desc: "El vendedor despachó hacia bodega NJ" },
|
{ num: "02", name: "EN_TRANSITO_BODEGA", color: "#F59E0B", desc: "Vendedor despachó a bodega NJ" },
|
||||||
{ num: "03", name: "RECIBIDO_BODEGA", color: "#3B82F6", desc: "Bodega NJ confirmó recepción" },
|
{ num: "03", name: "RECIBIDO_BODEGA", color: "#3B82F6", desc: "Bodega NJ confirmó recepción" },
|
||||||
{ num: "04", name: "EN_VERIFICACION", color: "#8B5CF6", desc: "Pesando, midiendo y fotografiando" },
|
{ num: "04", name: "EN_VERIFICACION", color: "#8B5CF6", desc: "Pesando, midiendo y fotografiando" },
|
||||||
{ num: "05", name: "VERIFICADO", color: "#10B981", desc: "Peso confirmado. Cobro aplicado." },
|
{ num: "05", name: "VERIFICADO", color: "#10B981", desc: "Peso confirmado. Cobro aplicado." },
|
||||||
{ num: "06", name: "DECLARACION_ADUANERA", color: "#0057FF", desc: "DSI aprobada por la SENAE" },
|
{ num: "06", name: "DECLARACION_SENAE", color: "#0057FF", desc: "DSI aprobada por la SENAE" },
|
||||||
{ num: "07", name: "EN_TRANSITO_ECUADOR", color: "#F97316", desc: "En vuelo hacia Ecuador" },
|
{ num: "07", name: "EN_TRANSITO_EC", color: "#F97316", desc: "En vuelo hacia Ecuador" },
|
||||||
{ num: "08", name: "EN_ADUANA_ECUADOR", color: "#EF4444", desc: "Inspección en aduana Ecuador" },
|
{ num: "08", name: "EN_ADUANA_EC", color: "#EF4444", desc: "Inspección en aduana Ecuador" },
|
||||||
{ num: "09", name: "LISTO_ENTREGA", color: "#84CC16", desc: "Listo para entrega al cliente" },
|
{ num: "09", name: "LISTO_ENTREGA", color: "#84CC16", desc: "Listo para entrega al cliente" },
|
||||||
{ num: "10", name: "ENTREGADO", color: "#10B981", desc: "Paquete entregado en Ecuador ✓" },
|
{ num: "10", name: "ENTREGADO", color: "#10B981", desc: "Paquete entregado en Ecuador ✓" },
|
||||||
{ num: "11", name: "INCIDENCIA", color: "#EF4444", desc: "Problema reportado ⚠" },
|
{ num: "11", name: "INCIDENCIA", color: "#EF4444", desc: "Problema reportado ⚠" },
|
||||||
@@ -28,15 +28,15 @@ const TRACKING_STATES = [
|
|||||||
const SENAE_CATEGORIES = [
|
const SENAE_CATEGORIES = [
|
||||||
{ name: "Régimen 4×4", rate: "0%", color: "#10B981", bg: "#D1FAE5", desc: "Hasta 4 envíos/año · máx. $400 · máx. 4 kg · Sin arancel" },
|
{ name: "Régimen 4×4", rate: "0%", color: "#10B981", bg: "#D1FAE5", desc: "Hasta 4 envíos/año · máx. $400 · máx. 4 kg · Sin arancel" },
|
||||||
{ name: "Categoría B", rate: "10%", color: "#1D4ED8", bg: "#DBEAFE", desc: "Bienes de consumo general" },
|
{ name: "Categoría B", rate: "10%", color: "#1D4ED8", bg: "#DBEAFE", desc: "Bienes de consumo general" },
|
||||||
{ name: "Categoría C", rate: "20%", color: "#FF6B00", bg: "#FFEDD5", desc: "Textiles, calzado, hogar" },
|
{ name: "Categoría C", rate: "20%", color: "#C2410C", bg: "#FFEDD5", desc: "Textiles, calzado, hogar" },
|
||||||
{ name: "Categoría D", rate: "0–15%", color: "#8B5CF6", bg: "#EDE9FE", desc: "Electrónicos · puede requerir INEN" },
|
{ name: "Categoría D", rate: "0–15%", color: "#7C3AED", bg: "#EDE9FE", desc: "Electrónicos · puede requerir INEN" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
{ icon: "🌐", title: "Landing Pública", desc: "Calculadora SENAE, tracking sin login, tarifas y FAQ", tag: "Sin registro" },
|
{ icon: "🌐", title: "Landing Pública", desc: "Calculadora SENAE, tracking sin login, tarifas y FAQ", tag: "Sin registro" },
|
||||||
{ icon: "👤", title: "Portal Cliente", desc: "Suite personalizada, pre-alertas, mis paquetes, historial", tag: "B2C · Ecuador" },
|
{ icon: "👤", title: "Portal Cliente", desc: "Suite personalizada, pre-alertas, mis paquetes, historial", tag: "B2C · Ecuador" },
|
||||||
{ icon: "🏭", title: "Portal Bodega NJ", desc: "Recepción, peso, fotos, despacho desde 150 N Day St", tag: "Operador · NJ" },
|
{ icon: "🏭", title: "Portal Bodega NJ", desc: "Recepción, peso, fotos y despacho desde 150 N Day St", tag: "Operador · NJ" },
|
||||||
{ icon: "⚙️", title: "Portal Admin", desc: "Dashboard, usuarios, tarifas, reportes, auditoría", tag: "Admin / Super Admin" },
|
{ icon: "⚙️", title: "Portal Admin", desc: "Dashboard, usuarios, tarifas, reportes, auditoría", tag: "Admin" },
|
||||||
{ icon: "🛃", title: "Módulo SENAE", desc: "DSI automática, cálculo FODINFA+IVA+Arancel, WebService", tag: "Agente Aduanero" },
|
{ icon: "🛃", title: "Módulo SENAE", desc: "DSI automática, cálculo FODINFA+IVA+Arancel, WebService", tag: "Agente Aduanero" },
|
||||||
{ icon: "📍", title: "Tracking", desc: "ID único EC-YYYYMMDD-XXXXXX · 11 estados · búsqueda pública", tag: "Todos los roles" },
|
{ icon: "📍", title: "Tracking", desc: "ID único EC-YYYYMMDD-XXXXXX · 11 estados · búsqueda pública", tag: "Todos los roles" },
|
||||||
{ icon: "📄", title: "Pre-alerta", desc: "Aviso previo con factura antes de llegada a bodega", tag: "Cliente" },
|
{ icon: "📄", title: "Pre-alerta", desc: "Aviso previo con factura antes de llegada a bodega", tag: "Cliente" },
|
||||||
@@ -52,90 +52,55 @@ const ROLES = [
|
|||||||
{ icon: "🎧", name: "Soporte", desc: "Solo lectura: puede ver info de clientes y paquetes.", badge: "Solo lectura", bg: "#F3F4F6" },
|
{ icon: "🎧", name: "Soporte", desc: "Solo lectura: puede ver info de clientes y paquetes.", badge: "Solo lectura", bg: "#F3F4F6" },
|
||||||
];
|
];
|
||||||
|
|
||||||
// ─── Componentes ──────────────────────────────────────────────
|
// ─── Secciones ──────────────────────────────────────────
|
||||||
|
|
||||||
function Navbar() {
|
|
||||||
return (
|
|
||||||
<nav style={{
|
|
||||||
position: "sticky", top: 0, zIndex: 50,
|
|
||||||
background: "rgba(255,255,255,0.95)",
|
|
||||||
backdropFilter: "blur(12px)",
|
|
||||||
borderBottom: "1px solid #E5E7EB",
|
|
||||||
display: "flex", alignItems: "center", justifyContent: "space-between",
|
|
||||||
padding: "0 40px", height: 60,
|
|
||||||
}}>
|
|
||||||
<span style={{ fontWeight: 800, fontSize: "1.15rem", color: "#111827" }}>
|
|
||||||
Moraworld<span style={{ color: "#FF6B00" }}>.</span>Imports
|
|
||||||
</span>
|
|
||||||
<div style={{ display: "flex", gap: 24, alignItems: "center", fontSize: ".9rem" }}>
|
|
||||||
<Link href="/calculadora" style={{ color: "#4B5563" }}>Calculadora</Link>
|
|
||||||
<Link href="/tracking" style={{ color: "#4B5563" }}>Tracking</Link>
|
|
||||||
<Link href="/carga-pesada" style={{ color: "#4B5563" }}>Carga Pesada</Link>
|
|
||||||
<Link href="/portal" style={{
|
|
||||||
background: "#0057FF", color: "#fff",
|
|
||||||
padding: "8px 20px", borderRadius: 8, fontWeight: 600,
|
|
||||||
}}>Mi Portal</Link>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Hero() {
|
function Hero() {
|
||||||
return (
|
return (
|
||||||
<section style={{
|
<section className="ln-hero">
|
||||||
background: "linear-gradient(135deg, #0D1117 0%, #0D2150 100%)",
|
<div className="container">
|
||||||
padding: "100px 40px", color: "#fff",
|
<div className="ln-hero-badge">
|
||||||
}}>
|
<span className="ln-hero-badge-dot" />
|
||||||
<div style={{ maxWidth: 1100, margin: "0 auto" }}>
|
|
||||||
<div style={{
|
|
||||||
display: "inline-block",
|
|
||||||
background: "rgba(0,87,255,.15)", border: "1px solid rgba(0,87,255,.3)",
|
|
||||||
color: "#7AADFF", fontSize: ".8rem", fontWeight: 600,
|
|
||||||
padding: "6px 14px", borderRadius: 999, marginBottom: 24,
|
|
||||||
}}>
|
|
||||||
ISO/IEC 27001 · SENAE Autorizado · Cuenca, Ecuador
|
ISO/IEC 27001 · SENAE Autorizado · Cuenca, Ecuador
|
||||||
</div>
|
</div>
|
||||||
<h1 style={{ fontSize: "clamp(2rem,5vw,3.2rem)", fontWeight: 800, lineHeight: 1.15, marginBottom: 20 }}>
|
|
||||||
Tu casillero en <span style={{ color: "#FF6B00" }}>New Jersey</span>
|
<h1>
|
||||||
|
Tu casillero en <em>New Jersey</em>
|
||||||
<br />para recibir en Ecuador
|
<br />para recibir en Ecuador
|
||||||
</h1>
|
</h1>
|
||||||
<p style={{ color: "#9CA3AF", maxWidth: 560, fontSize: "1.05rem", marginBottom: 16 }}>
|
|
||||||
|
<p className="ln-hero-sub">
|
||||||
Compra en Amazon, eBay, Walmart y más. Te asignamos una Suite personal en nuestra
|
Compra en Amazon, eBay, Walmart y más. Te asignamos una Suite personal en nuestra
|
||||||
bodega en NJ. Gestionamos el envío y la declaración aduanera SENAE por ti.
|
bodega en NJ. Gestionamos el envío y la declaración aduanera SENAE por ti.
|
||||||
</p>
|
</p>
|
||||||
<div style={{
|
|
||||||
background: "rgba(0,87,255,.1)", border: "1px solid rgba(0,87,255,.25)",
|
<div className="ln-hero-address">
|
||||||
borderRadius: 10, padding: "14px 18px", marginBottom: 32,
|
|
||||||
fontFamily: "monospace", fontSize: ".9rem", color: "#A5B4FC", maxWidth: 520,
|
|
||||||
}}>
|
|
||||||
📍 <strong style={{ color: "#FF6B00" }}>Tu Suite:</strong>{" "}
|
📍 <strong style={{ color: "#FF6B00" }}>Tu Suite:</strong>{" "}
|
||||||
150 N Day St, Suite EC-XXXXX, City of Orange, NJ 07050, EE.UU.
|
150 N Day St, Suite EC-XXXXX, City of Orange, NJ 07050, EE.UU.
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
|
|
||||||
<Link href="/registro" style={{
|
<div className="ln-hero-actions">
|
||||||
background: "#0057FF", color: "#fff",
|
<Link href="/registro" className="btn btn-primary btn-lg">
|
||||||
padding: "14px 28px", borderRadius: 8, fontWeight: 700, fontSize: ".95rem",
|
|
||||||
}}>
|
|
||||||
Crear mi Suite gratis →
|
Crear mi Suite gratis →
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/calculadora" style={{
|
<Link href="/calculadora" style={{
|
||||||
border: "2px solid rgba(255,255,255,.2)", color: "#9CA3AF",
|
border: "2px solid rgba(255,255,255,.2)", color: "#9CA3AF",
|
||||||
padding: "12px 26px", borderRadius: 8, fontSize: ".9rem",
|
padding: "12px 24px", borderRadius: 8, fontSize: ".9rem", display: "inline-flex", alignItems: "center",
|
||||||
}}>
|
}}>
|
||||||
Calcular mi envío
|
Calcular mi envío
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", gap: 32, marginTop: 48, flexWrap: "wrap" }}>
|
|
||||||
|
<div className="ln-hero-trust">
|
||||||
{[
|
{[
|
||||||
["🏢", "Moraworld Imports S.A.S.", "Ecuador · RUC activo"],
|
["🏢", "Moraworld Imports S.A.S.", "Ecuador · RUC activo"],
|
||||||
["🏭", "Mora Global Import LLC", "New Jersey, EE.UU."],
|
["🏭", "Mora Global Import LLC", "New Jersey, EE.UU."],
|
||||||
["🛃", "Autorización SENAE", "Declaración automática"],
|
["🛃", "Autorización SENAE", "Declaración automática"],
|
||||||
].map(([icon, title, sub]) => (
|
].map(([icon, name, sub]) => (
|
||||||
<div key={title} style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
|
<div key={name} className="ln-trust-item">
|
||||||
<span style={{ fontSize: "1.5rem" }}>{icon}</span>
|
<span className="ln-trust-icon">{icon}</span>
|
||||||
<div>
|
<div>
|
||||||
<div style={{ fontWeight: 600, fontSize: ".88rem", color: "#fff" }}>{title}</div>
|
<span className="ln-trust-name">{name}</span>
|
||||||
<div style={{ fontSize: ".78rem", color: "#6B7280" }}>{sub}</div>
|
<span className="ln-trust-sub">{sub}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -147,48 +112,33 @@ function Hero() {
|
|||||||
|
|
||||||
function ServicesSection() {
|
function ServicesSection() {
|
||||||
return (
|
return (
|
||||||
<section style={{ padding: "80px 40px", background: "#F3F4F6" }}>
|
<section className="ln-section-gray">
|
||||||
<div style={{ maxWidth: 1100, margin: "0 auto" }}>
|
<div className="container">
|
||||||
<div style={{ textAlign: "center", marginBottom: 48 }}>
|
<div className="ln-section-head">
|
||||||
<h2 style={{ fontSize: "1.8rem", fontWeight: 800, marginBottom: 8 }}>Dos servicios, un solo sistema</h2>
|
<span className="ln-section-tag">Nuestros Servicios</span>
|
||||||
<p style={{ color: "#6B7280", fontSize: ".95rem" }}>Casillero personal para compras online y carga pesada para importadores B2B.</p>
|
<h2 className="ln-section-title">Dos soluciones, un solo sistema</h2>
|
||||||
|
<p className="ln-section-sub">Casillero personal para compras online e importación B2B para mayoristas.</p>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24 }}>
|
<div className="ln-grid-2">
|
||||||
<div style={{ background: "#fff", borderRadius: 16, padding: 32, border: "2px solid #BFDBFE" }}>
|
<div className="ln-service-card featured">
|
||||||
<div style={{ fontSize: "2.5rem", marginBottom: 12 }}>📦</div>
|
<div className="ln-service-icon">📦</div>
|
||||||
<h3 style={{ fontWeight: 800, fontSize: "1.2rem", marginBottom: 8 }}>Casillero Personal</h3>
|
<h3>Casillero Personal (B2C)</h3>
|
||||||
<p style={{ color: "#6B7280", marginBottom: 16 }}>
|
<p>Para compras individuales en Amazon, eBay, Walmart y más. Suite personalizada, tracking en tiempo real y declaración SENAE automática bajo el régimen 4×4.</p>
|
||||||
Para compras individuales en Amazon, eBay, Walmart y más. Suite personalizada, tracking en tiempo real
|
<ul className="ln-service-list">
|
||||||
y declaración SENAE automática bajo el régimen 4×4.
|
{["Suite virtual asignada al registrarse", "Pre-alerta con carga de factura", "Calculadora de costos SENAE", "11 estados de tracking en tiempo real", "Notificaciones WhatsApp · SMS · Email", "Declaración aduanera incluida"].map(i => <li key={i}>{i}</li>)}
|
||||||
</p>
|
|
||||||
<ul style={{ color: "#374151", paddingLeft: 20, display: "flex", flexDirection: "column", gap: 6, fontSize: ".88rem" }}>
|
|
||||||
{["Suite virtual asignada al registrarse", "Pre-alerta con carga de factura", "Calculadora de costos SENAE", "11 estados de tracking en tiempo real", "Notificaciones WhatsApp · SMS · Email"].map(i => (
|
|
||||||
<li key={i}>{i}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
</ul>
|
||||||
<Link href="/casillero" style={{
|
<Link href="/registro" className="btn btn-primary w-full" style={{ justifyContent: "center" }}>
|
||||||
display: "inline-block", marginTop: 20, background: "#0057FF", color: "#fff",
|
Abrir casillero gratis →
|
||||||
padding: "10px 20px", borderRadius: 8, fontWeight: 600, fontSize: ".88rem",
|
|
||||||
}}>
|
|
||||||
Conocer más →
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ background: "#fff", borderRadius: 16, padding: 32, border: "2px solid #FED7AA" }}>
|
<div className="ln-service-card">
|
||||||
<div style={{ fontSize: "2.5rem", marginBottom: 12 }}>🚢</div>
|
<div className="ln-service-icon">🚢</div>
|
||||||
<h3 style={{ fontWeight: 800, fontSize: "1.2rem", marginBottom: 8 }}>Carga Pesada / Pallets B2B</h3>
|
<h3>Carga Pesada / Pallets (B2B)</h3>
|
||||||
<p style={{ color: "#6B7280", marginBottom: 16 }}>
|
<p>Para importadores mayoristas: pallets, contenedores y carga a granel. Cotización personalizada, certificación INEN y declaración formal DAI ante la SENAE.</p>
|
||||||
Para importadores mayoristas: pallets, contenedores, volumen alto. Cotización personalizada,
|
<ul className="ln-service-list">
|
||||||
certificación INEN y declaración formal DAI ante la SENAE.
|
{["Cotización especial por mercancía", "Verificación de requisitos INEN", "Declaración formal DAI", "Asesoría en partidas arancelarias", "Expediente B2B con seguimiento", "Agente dedicado en WhatsApp"].map(i => <li key={i}>{i}</li>)}
|
||||||
</p>
|
|
||||||
<ul style={{ color: "#374151", paddingLeft: 20, display: "flex", flexDirection: "column", gap: 6, fontSize: ".88rem" }}>
|
|
||||||
{["Cotización especial por tipo de mercancía", "Verificación de requisitos INEN", "Declaración formal DAI", "Asesoría en partidas arancelarias", "Expediente B2B con ID de seguimiento"].map(i => (
|
|
||||||
<li key={i}>{i}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
</ul>
|
||||||
<Link href="/carga-pesada/cotizacion" style={{
|
<Link href="/carga-pesada/cotizacion" className="btn btn-accent w-full" style={{ justifyContent: "center" }}>
|
||||||
display: "inline-block", marginTop: 20, background: "#FF6B00", color: "#fff",
|
|
||||||
padding: "10px 20px", borderRadius: 8, fontWeight: 600, fontSize: ".88rem",
|
|
||||||
}}>
|
|
||||||
Solicitar cotización →
|
Solicitar cotización →
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -198,28 +148,57 @@ function ServicesSection() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function HowItWorksSection() {
|
||||||
|
const steps = [
|
||||||
|
{ n: "1", t: "Regístrate", d: "Crea tu cuenta y obtén tu Suite exclusiva en New Jersey al instante." },
|
||||||
|
{ n: "2", t: "Compra en EE.UU.", d: "Usa tu dirección Suite en Amazon, eBay, Walmart o cualquier tienda online." },
|
||||||
|
{ n: "3", t: "Recibimos en NJ", d: "Tu paquete llega a nuestra bodega. Lo verificamos, fotografiamos y preparamos." },
|
||||||
|
{ n: "4", t: "Te llega a Ecuador", d: "Enviamos con declaración SENAE incluida. Sigues todo con tu Tracking ID." },
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<section className="ln-section">
|
||||||
|
<div className="container">
|
||||||
|
<div className="ln-section-head">
|
||||||
|
<span className="ln-section-tag">Proceso</span>
|
||||||
|
<h2 className="ln-section-title">Así de simple. 4 pasos.</h2>
|
||||||
|
<p className="ln-section-sub">Desde tu compra hasta la puerta de tu casa en Ecuador, lo manejamos todo.</p>
|
||||||
|
</div>
|
||||||
|
<div className="ln-grid-4">
|
||||||
|
{steps.map(s => (
|
||||||
|
<div key={s.n} style={{ textAlign: "center", padding: "1.5rem 1rem" }}>
|
||||||
|
<div style={{
|
||||||
|
width: 64, height: 64, borderRadius: "50%",
|
||||||
|
background: "var(--white)", border: "3px solid var(--primary)",
|
||||||
|
display: "flex", alignItems: "center", justifyContent: "center",
|
||||||
|
fontSize: "1.4rem", fontWeight: 800, color: "var(--primary)",
|
||||||
|
margin: "0 auto 1rem", boxShadow: "var(--shadow-md)",
|
||||||
|
}}>{s.n}</div>
|
||||||
|
<h4 style={{ fontWeight: 700, marginBottom: ".5rem" }}>{s.t}</h4>
|
||||||
|
<p style={{ fontSize: ".85rem", color: "var(--gray-500)" }}>{s.d}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function ModulesSection() {
|
function ModulesSection() {
|
||||||
return (
|
return (
|
||||||
<section style={{ padding: "80px 40px", background: "#fff" }}>
|
<section className="ln-section-gray">
|
||||||
<div style={{ maxWidth: 1100, margin: "0 auto" }}>
|
<div className="container">
|
||||||
<div style={{ textAlign: "center", marginBottom: 48 }}>
|
<div className="ln-section-head">
|
||||||
<h2 style={{ fontSize: "1.8rem", fontWeight: 800, marginBottom: 8 }}>8 módulos integrados</h2>
|
<span className="ln-section-tag">Plataforma</span>
|
||||||
<p style={{ color: "#6B7280" }}>Toda la operación logística cubierta en una sola plataforma.</p>
|
<h2 className="ln-section-title">8 módulos integrados</h2>
|
||||||
|
<p className="ln-section-sub">Toda la operación logística cubierta en una sola plataforma.</p>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 16 }}>
|
<div className="ln-grid-4">
|
||||||
{MODULES.map((m) => (
|
{MODULES.map(m => (
|
||||||
<div key={m.title} style={{
|
<div key={m.title} className="ln-module-card">
|
||||||
background: "#F9FAFB", borderRadius: 12, padding: 20,
|
<div className="ln-module-icon">{m.icon}</div>
|
||||||
border: "1px solid #E5E7EB", transition: "box-shadow .2s",
|
<div className="ln-module-title">{m.title}</div>
|
||||||
}}>
|
<p className="ln-module-desc">{m.desc}</p>
|
||||||
<div style={{ fontSize: "1.8rem", marginBottom: 10 }}>{m.icon}</div>
|
<span className="ln-module-tag">{m.tag}</span>
|
||||||
<div style={{ fontWeight: 700, fontSize: ".9rem", marginBottom: 6 }}>{m.title}</div>
|
|
||||||
<p style={{ color: "#6B7280", fontSize: ".8rem", marginBottom: 10, lineHeight: 1.5 }}>{m.desc}</p>
|
|
||||||
<span style={{
|
|
||||||
background: "#EEF3FF", color: "#0057FF",
|
|
||||||
fontSize: ".68rem", fontWeight: 700, padding: "2px 8px",
|
|
||||||
borderRadius: 999,
|
|
||||||
}}>{m.tag}</span>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -230,47 +209,40 @@ function ModulesSection() {
|
|||||||
|
|
||||||
function TrackingSection() {
|
function TrackingSection() {
|
||||||
return (
|
return (
|
||||||
<section style={{ padding: "80px 40px", background: "#F3F4F6" }}>
|
<section className="ln-section">
|
||||||
<div style={{ maxWidth: 1100, margin: "0 auto" }}>
|
<div className="container">
|
||||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 48, alignItems: "start" }}>
|
<div className="ln-grid-2-1" style={{ gap: "3rem" }}>
|
||||||
<div>
|
<div>
|
||||||
<h2 style={{ fontSize: "1.8rem", fontWeight: 800, marginBottom: 12 }}>
|
<span className="ln-section-tag">Tracking en Tiempo Real</span>
|
||||||
Tracking en tiempo real
|
<h2 className="ln-section-title" style={{ textAlign: "left", marginBottom: ".75rem" }}>
|
||||||
|
Sigue tu paquete en cada paso
|
||||||
</h2>
|
</h2>
|
||||||
<p style={{ color: "#6B7280", marginBottom: 16 }}>
|
<p style={{ color: "var(--gray-500)", marginBottom: "1rem", fontSize: ".95rem" }}>
|
||||||
Cada paquete recibe un ID único con 11 estados que cubren todo el ciclo de vida.
|
Cada paquete recibe un ID único con 11 estados que cubren todo el ciclo de vida.
|
||||||
Búsqueda pública sin necesidad de crear cuenta.
|
Búsqueda pública sin necesidad de crear cuenta.
|
||||||
</p>
|
</p>
|
||||||
<div style={{
|
<div style={{
|
||||||
background: "#0D1117", borderRadius: 10, padding: "14px 18px",
|
background: "var(--dark)", borderRadius: 10, padding: "14px 18px",
|
||||||
fontFamily: "monospace", fontSize: ".88rem", color: "#A5B4FC",
|
fontFamily: "monospace", fontSize: ".88rem", color: "#A5B4FC",
|
||||||
marginBottom: 20, border: "1px solid rgba(0,87,255,.3)",
|
marginBottom: "1.5rem", border: "1px solid rgba(0,87,255,.3)",
|
||||||
}}>
|
}}>
|
||||||
Formato: <strong style={{ color: "#FF6B00" }}>EC-YYYYMMDD-XXXXXX</strong><br />
|
Formato: <strong style={{ color: "#FF6B00" }}>EC-YYYYMMDD-XXXXXX</strong><br />
|
||||||
Ejemplo: <strong>EC-20260506-082341</strong>
|
Ejemplo: <strong>EC-20260628-082341</strong>
|
||||||
</div>
|
</div>
|
||||||
<Link href="/tracking" style={{
|
<p style={{ fontSize: ".82rem", color: "var(--gray-500)", marginBottom: "1.5rem" }}>
|
||||||
background: "#0057FF", color: "#fff",
|
Notificaciones automáticas por <strong>correo</strong>, <strong>SMS</strong> y <strong>WhatsApp</strong> en cada cambio de estado.
|
||||||
padding: "12px 24px", borderRadius: 8, fontWeight: 600, fontSize: ".9rem",
|
</p>
|
||||||
display: "inline-block",
|
<Link href="/tracking" className="btn btn-primary">
|
||||||
}}>
|
|
||||||
Buscar mi paquete →
|
Buscar mi paquete →
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
|
<div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
|
||||||
{TRACKING_STATES.map((s) => (
|
{TRACKING_STATES.map(s => (
|
||||||
<div key={s.num} style={{
|
<div key={s.num} className="ln-tracking-state">
|
||||||
display: "flex", gap: 12, alignItems: "center",
|
<div className="ln-state-dot" style={{ background: s.color }} />
|
||||||
background: "#fff", borderRadius: 8, padding: "8px 14px",
|
<span className="ln-state-num">{s.num}</span>
|
||||||
border: "1px solid #E5E7EB",
|
<span className="ln-state-name">{s.name}</span>
|
||||||
}}>
|
<span className="ln-state-desc">{s.desc}</span>
|
||||||
<div style={{
|
|
||||||
width: 10, height: 10, borderRadius: "50%",
|
|
||||||
background: s.color, flexShrink: 0,
|
|
||||||
}} />
|
|
||||||
<span style={{ fontFamily: "monospace", fontSize: ".68rem", color: "#9CA3AF", minWidth: 22 }}>{s.num}</span>
|
|
||||||
<span style={{ fontFamily: "monospace", fontSize: ".78rem", fontWeight: 700, flex: 1 }}>{s.name}</span>
|
|
||||||
<span style={{ fontSize: ".75rem", color: "#6B7280" }}>{s.desc}</span>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -282,46 +254,32 @@ function TrackingSection() {
|
|||||||
|
|
||||||
function CalculatorPreviewSection() {
|
function CalculatorPreviewSection() {
|
||||||
return (
|
return (
|
||||||
<section style={{ padding: "80px 40px", background: "#fff" }}>
|
<section className="ln-section-gray">
|
||||||
<div style={{ maxWidth: 1100, margin: "0 auto", textAlign: "center" }}>
|
<div className="container" style={{ textAlign: "center" }}>
|
||||||
<h2 style={{ fontSize: "1.8rem", fontWeight: 800, marginBottom: 8 }}>
|
<span className="ln-section-tag">Calculadora SENAE</span>
|
||||||
Calculadora SENAE gratuita
|
<h2 className="ln-section-title">Calcula tu costo antes de comprar</h2>
|
||||||
</h2>
|
<p className="ln-section-sub" style={{ marginBottom: "2.5rem" }}>
|
||||||
<p style={{ color: "#6B7280", marginBottom: 40 }}>
|
Sin registro. Ingresa peso y valor y obtén el desglose completo con impuestos SENAE.
|
||||||
Sin registro. Conoce el costo total de tu envío antes de comprar.
|
|
||||||
</p>
|
</p>
|
||||||
<div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 16, marginBottom: 32 }}>
|
<div className="ln-grid-4" style={{ marginBottom: "2rem" }}>
|
||||||
{SENAE_CATEGORIES.map((c) => (
|
{SENAE_CATEGORIES.map(c => (
|
||||||
<div key={c.name} style={{
|
<div key={c.name} className="ln-senae-card" style={{ background: c.bg, border: `1px solid ${c.color}30` }}>
|
||||||
borderRadius: 12, padding: 24, background: c.bg,
|
|
||||||
border: `1px solid ${c.color}30`, textAlign: "center",
|
|
||||||
}}>
|
|
||||||
<div style={{ fontWeight: 800, marginBottom: 4 }}>{c.name}</div>
|
<div style={{ fontWeight: 800, marginBottom: 4 }}>{c.name}</div>
|
||||||
<div style={{ fontSize: "2.2rem", fontWeight: 900, color: c.color, lineHeight: 1, marginBottom: 8 }}>{c.rate}</div>
|
<div className="ln-senae-rate" style={{ color: c.color }}>{c.rate}</div>
|
||||||
<div style={{ fontSize: ".75rem", color: "#4B5563" }}>{c.desc}</div>
|
<div style={{ fontSize: ".75rem", color: "#4B5563" }}>{c.desc}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
<div className="ln-calc-formula">
|
||||||
background: "#0D1117", borderRadius: 12, padding: "20px 24px",
|
<span style={{ color: "rgba(255,255,255,.25)" }}>{"// Fórmula (doc §15)"}</span><br />
|
||||||
fontFamily: "monospace", fontSize: ".82rem", color: "#A5B4FC",
|
|
||||||
textAlign: "left", maxWidth: 600, margin: "0 auto 28px",
|
|
||||||
lineHeight: 2, border: "1px solid rgba(255,255,255,.08)",
|
|
||||||
}}>
|
|
||||||
<span style={{ color: "rgba(255,255,255,.25)" }}>// Fórmula (doc §15)</span><br />
|
|
||||||
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>Flete</span> = Peso_final × <span style={{ color: "#FCD34D" }}>$3.50</span>/lb<br />
|
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>Flete</span> = Peso_final × <span style={{ color: "#FCD34D" }}>$3.50</span>/lb<br />
|
||||||
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>Seguro</span> = Valor × <span style={{ color: "#FCD34D" }}>2%</span><br />
|
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>Seguro</span> = Valor × <span style={{ color: "#FCD34D" }}>2%</span><br />
|
||||||
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>FODINFA</span> = Valor × <span style={{ color: "#FCD34D" }}>0.5%</span><br />
|
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>FODINFA</span> = Valor × <span style={{ color: "#FCD34D" }}>0.5%</span><br />
|
||||||
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>Arancel</span> = Valor × <span style={{ color: "#FCD34D" }}>% categoría</span><br />
|
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>Arancel</span> = Valor × <span style={{ color: "#FCD34D" }}>% categoría</span><br />
|
||||||
<span style={{ color: "#6EE7B7", fontWeight: 700 }}>IVA</span> = (Valor + FODINFA + Arancel) × <span style={{ color: "#FCD34D" }}>15%</span><br />
|
|
||||||
<span style={{ color: "#F9A8D4", fontWeight: 700 }}>TOTAL</span> = Flete + Seguro + FODINFA + Arancel + IVA
|
<span style={{ color: "#F9A8D4", fontWeight: 700 }}>TOTAL</span> = Flete + Seguro + FODINFA + Arancel + IVA
|
||||||
</div>
|
</div>
|
||||||
<Link href="/calculadora" style={{
|
<Link href="/calculadora" className="btn btn-primary btn-lg">
|
||||||
background: "#0057FF", color: "#fff",
|
Ir a la calculadora →
|
||||||
padding: "14px 32px", borderRadius: 8, fontWeight: 700,
|
|
||||||
display: "inline-block", fontSize: ".95rem",
|
|
||||||
}}>
|
|
||||||
Calcular mi envío →
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -330,25 +288,20 @@ function CalculatorPreviewSection() {
|
|||||||
|
|
||||||
function RolesSection() {
|
function RolesSection() {
|
||||||
return (
|
return (
|
||||||
<section style={{ padding: "80px 40px", background: "#F3F4F6" }}>
|
<section className="ln-section">
|
||||||
<div style={{ maxWidth: 1100, margin: "0 auto" }}>
|
<div className="container">
|
||||||
<div style={{ textAlign: "center", marginBottom: 48 }}>
|
<div className="ln-section-head">
|
||||||
<h2 style={{ fontSize: "1.8rem", fontWeight: 800, marginBottom: 8 }}>6 roles, accesos diferenciados</h2>
|
<span className="ln-section-tag">Accesos</span>
|
||||||
<p style={{ color: "#6B7280" }}>Cada usuario tiene exactamente lo que necesita. Ni más, ni menos.</p>
|
<h2 className="ln-section-title">6 roles, accesos diferenciados</h2>
|
||||||
|
<p className="ln-section-sub">Cada usuario tiene exactamente lo que necesita. Ni más, ni menos.</p>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 16 }}>
|
<div className="ln-grid-3">
|
||||||
{ROLES.map((r) => (
|
{ROLES.map(r => (
|
||||||
<div key={r.name} style={{
|
<div key={r.name} className="ln-role-card" style={{ background: r.bg }}>
|
||||||
background: r.bg, borderRadius: 12, padding: 20,
|
<div className="ln-role-icon">{r.icon}</div>
|
||||||
border: "1px solid #E5E7EB",
|
<div className="ln-role-name">{r.name}</div>
|
||||||
}}>
|
<p className="ln-role-desc">{r.desc}</p>
|
||||||
<div style={{ fontSize: "1.5rem", marginBottom: 10 }}>{r.icon}</div>
|
<span className="ln-role-badge">{r.badge}</span>
|
||||||
<div style={{ fontWeight: 700, marginBottom: 6 }}>{r.name}</div>
|
|
||||||
<p style={{ color: "#6B7280", fontSize: ".82rem", marginBottom: 12, lineHeight: 1.5 }}>{r.desc}</p>
|
|
||||||
<span style={{
|
|
||||||
background: "rgba(0,0,0,.06)", fontSize: ".7rem", fontWeight: 700,
|
|
||||||
padding: "2px 10px", borderRadius: 999,
|
|
||||||
}}>{r.badge}</span>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -359,37 +312,34 @@ function RolesSection() {
|
|||||||
|
|
||||||
function CompaniesSection() {
|
function CompaniesSection() {
|
||||||
return (
|
return (
|
||||||
<section style={{ padding: "80px 40px", background: "#fff" }}>
|
<section className="ln-section-gray">
|
||||||
<div style={{ maxWidth: 1100, margin: "0 auto", textAlign: "center" }}>
|
<div className="container">
|
||||||
<h2 style={{ fontSize: "1.8rem", fontWeight: 800, marginBottom: 8 }}>Operación legal en dos países</h2>
|
<div className="ln-section-head">
|
||||||
<p style={{ color: "#6B7280", marginBottom: 40 }}>Empresas constituidas legalmente en Ecuador y EE.UU.</p>
|
<span className="ln-section-tag">Confianza y Legalidad</span>
|
||||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24, maxWidth: 800, margin: "0 auto" }}>
|
<h2 className="ln-section-title">Operación legal en dos países</h2>
|
||||||
|
<p className="ln-section-sub">Empresas constituidas legalmente en Ecuador y EE.UU. con representación visible en ambos países.</p>
|
||||||
|
</div>
|
||||||
|
<div className="ln-grid-2" style={{ maxWidth: 800, margin: "0 auto" }}>
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
flag: "🇪🇨",
|
flag: "🇪🇨",
|
||||||
name: "Moraworld Imports S.A.S.",
|
name: "Moraworld Imports S.A.S.",
|
||||||
detail: "Constituida en Ecuador. Representante legal en Cuenca. RUC activo, permisos aduaneros vigentes ante la SENAE.",
|
desc: "Constituida en Ecuador. Representante legal en Cuenca. RUC activo, permisos aduaneros vigentes ante la SENAE.",
|
||||||
badge: "Ecuador · S.A.S. · SENAE · Cuenca",
|
badge: "Ecuador · S.A.S. · SENAE · Cuenca",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
flag: "🇺🇸",
|
flag: "🇺🇸",
|
||||||
name: "Mora Global Import LLC",
|
name: "Mora Global Import LLC",
|
||||||
detail: "LLC registrada en New Jersey, EE.UU. Bodega operativa en 150 N Day St, City of Orange, NJ 07050.",
|
desc: "LLC registrada en New Jersey, EE.UU. Bodega operativa en 150 N Day St, City of Orange, NJ 07050.",
|
||||||
badge: "New Jersey · LLC · NJ 07050",
|
badge: "New Jersey · LLC · NJ 07050",
|
||||||
},
|
},
|
||||||
].map((c) => (
|
].map(c => (
|
||||||
<div key={c.name} style={{
|
<div key={c.name} className="ln-company-card">
|
||||||
background: "#fff", borderRadius: 16, padding: 28,
|
<span className="ln-company-flag">{c.flag}</span>
|
||||||
border: "2px solid #E5E7EB", display: "flex", gap: 16, alignItems: "flex-start",
|
<div>
|
||||||
}}>
|
<div className="ln-company-name">{c.name}</div>
|
||||||
<span style={{ fontSize: "2.5rem" }}>{c.flag}</span>
|
<p className="ln-company-desc">{c.desc}</p>
|
||||||
<div style={{ textAlign: "left" }}>
|
<span className="ln-company-badge">{c.badge}</span>
|
||||||
<div style={{ fontWeight: 800, marginBottom: 6 }}>{c.name}</div>
|
|
||||||
<p style={{ color: "#6B7280", fontSize: ".82rem", lineHeight: 1.6, marginBottom: 10 }}>{c.detail}</p>
|
|
||||||
<span style={{
|
|
||||||
background: "#EEF3FF", color: "#0057FF",
|
|
||||||
fontSize: ".7rem", fontWeight: 700, padding: "2px 10px", borderRadius: 999,
|
|
||||||
}}>{c.badge}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -399,27 +349,39 @@ function CompaniesSection() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function CtaSection() {
|
||||||
|
return (
|
||||||
|
<section className="ln-cta-section">
|
||||||
|
<div className="container">
|
||||||
|
<h2>¿Listo para comprar en EE.UU.<br />y recibir en Ecuador?</h2>
|
||||||
|
<p>Regístrate gratis y obtén tu Suite en New Jersey en menos de 2 minutos.</p>
|
||||||
|
<Link href="/registro" style={{
|
||||||
|
display: "inline-block", background: "var(--white)", color: "var(--primary)",
|
||||||
|
padding: "16px 36px", borderRadius: 8, fontWeight: 700, fontSize: "1rem",
|
||||||
|
}}>
|
||||||
|
Abrir mi casillero gratis →
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function Footer() {
|
function Footer() {
|
||||||
return (
|
return (
|
||||||
<footer style={{
|
<footer className="ln-footer">
|
||||||
background: "#0D1117", padding: "48px 40px", color: "rgba(255,255,255,.5)",
|
<div className="container" style={{ textAlign: "center" }}>
|
||||||
textAlign: "center",
|
<div className="ln-footer-logo">
|
||||||
}}>
|
Moraworld<span>.</span>Imports
|
||||||
<div style={{ fontSize: "1.1rem", fontWeight: 800, color: "#fff", marginBottom: 8 }}>
|
|
||||||
Moraworld<span style={{ color: "#FF6B00" }}>.</span>Imports
|
|
||||||
</div>
|
</div>
|
||||||
<p style={{ fontSize: ".82rem", marginBottom: 20 }}>
|
<p style={{ fontSize: ".82rem", marginBottom: ".5rem" }}>
|
||||||
Moraworld Imports S.A.S. · Mora Global Import LLC
|
Moraworld Imports S.A.S. · Mora Global Import LLC
|
||||||
</p>
|
</p>
|
||||||
<div style={{ display: "flex", gap: 8, flexWrap: "wrap", justifyContent: "center", marginBottom: 24 }}>
|
<div className="ln-footer-badges">
|
||||||
{["ISO/IEC 27001", "SENAE Autorizado", "INEN", "LOPDP Ecuador", "Multi-Tenant"].map((b) => (
|
{["ISO/IEC 27001", "SENAE Autorizado", "INEN", "LOPDP Ecuador"].map(b => (
|
||||||
<span key={b} style={{
|
<span key={b} className="ln-footer-badge">{b}</span>
|
||||||
background: "rgba(255,255,255,.07)", color: "rgba(255,255,255,.5)",
|
|
||||||
fontSize: ".7rem", fontWeight: 700, padding: "4px 12px", borderRadius: 999,
|
|
||||||
}}>{b}</span>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", gap: 24, justifyContent: "center", flexWrap: "wrap", fontSize: ".82rem" }}>
|
<nav className="ln-footer-links">
|
||||||
<Link href="/como-funciona">Cómo funciona</Link>
|
<Link href="/como-funciona">Cómo funciona</Link>
|
||||||
<Link href="/calculadora">Calculadora</Link>
|
<Link href="/calculadora">Calculadora</Link>
|
||||||
<Link href="/tracking">Tracking</Link>
|
<Link href="/tracking">Tracking</Link>
|
||||||
@@ -427,33 +389,36 @@ function Footer() {
|
|||||||
<Link href="/quienes-somos">Quiénes somos</Link>
|
<Link href="/quienes-somos">Quiénes somos</Link>
|
||||||
<Link href="/casillero">Casillero</Link>
|
<Link href="/casillero">Casillero</Link>
|
||||||
<Link href="/carga-pesada">Carga Pesada</Link>
|
<Link href="/carga-pesada">Carga Pesada</Link>
|
||||||
</div>
|
<Link href="/login">Iniciar sesión</Link>
|
||||||
{/* LOPDP §21 — aviso de protección de datos */}
|
</nav>
|
||||||
<div style={{ borderTop: "1px solid rgba(255,255,255,.07)", marginTop: 24, paddingTop: 16, fontSize: ".72rem", color: "rgba(255,255,255,.3)", lineHeight: 1.7, textAlign: "center" }}>
|
<div className="ln-footer-legal">
|
||||||
🛡️ Los datos personales de clientes ecuatorianos están protegidos por la{" "}
|
🛡️ Los datos personales de clientes ecuatorianos están protegidos por la{" "}
|
||||||
<strong style={{ color: "rgba(255,255,255,.5)" }}>Ley Orgánica de Protección de Datos Personales (LOPDP) de Ecuador</strong>.
|
<strong style={{ color: "rgba(255,255,255,.5)" }}>Ley Orgánica de Protección de Datos Personales (LOPDP) de Ecuador</strong>.
|
||||||
Al procesarse en EE.UU., aplica también la normativa del estado de New Jersey.
|
Al procesarse en EE.UU., aplica también la normativa del estado de New Jersey.
|
||||||
Moraworld Imports S.A.S. (Ecuador) · Mora Global Import LLC (NJ, EE.UU.) · Documento v1.1 — 2026
|
<br />
|
||||||
|
© 2026 Moraworld Imports S.A.S. (Ecuador) · Mora Global Import LLC (NJ, EE.UU.)
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Página principal ─────────────────────────────────────────
|
// ─── Página principal ────────────────────────────────────
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar />
|
<LandingNavbar />
|
||||||
<Hero />
|
<Hero />
|
||||||
<ServicesSection />
|
<ServicesSection />
|
||||||
|
<HowItWorksSection />
|
||||||
<ModulesSection />
|
<ModulesSection />
|
||||||
<TrackingSection />
|
<TrackingSection />
|
||||||
<CalculatorPreviewSection />
|
<CalculatorPreviewSection />
|
||||||
<RolesSection />
|
<RolesSection />
|
||||||
<CompaniesSection />
|
<CompaniesSection />
|
||||||
|
<CtaSection />
|
||||||
<Footer />
|
<Footer />
|
||||||
<WhatsAppFloat />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-2
@@ -1,5 +1,9 @@
|
|||||||
# Coolify Deployment — docker-compose for production (managed DB/Redis by Coolify)
|
# Coolify Deployment — docker-compose for production (managed DB/Redis by Coolify)
|
||||||
|
|
||||||
|
networks:
|
||||||
|
coolify:
|
||||||
|
external: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
api:
|
api:
|
||||||
build:
|
build:
|
||||||
@@ -7,6 +11,8 @@ services:
|
|||||||
dockerfile: apps/api/Dockerfile
|
dockerfile: apps/api/Dockerfile
|
||||||
container_name: moraworld-api
|
container_name: moraworld-api
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- coolify
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- PORT=3001
|
- PORT=3001
|
||||||
@@ -24,7 +30,7 @@ services:
|
|||||||
- S3_PUBLIC_URL=${S3_PUBLIC_URL}
|
- S3_PUBLIC_URL=${S3_PUBLIC_URL}
|
||||||
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
|
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "-qO-", "http://localhost:3001/api/health"]
|
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3001/api/health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -49,13 +55,16 @@ services:
|
|||||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
|
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
|
||||||
container_name: moraworld-web
|
container_name: moraworld-web
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- coolify
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- PORT=3000
|
- PORT=3000
|
||||||
|
- HOSTNAME=0.0.0.0
|
||||||
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
||||||
- NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL}
|
- NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "-qO-", "http://localhost:3000/status"]
|
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/status"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
+73
-19
@@ -5,6 +5,11 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="description" content="Moraworld Imports — Tu casillero en New Jersey. Compra en Amazon, eBay y más. Enviamos a Ecuador con declaración aduanera incluida." />
|
<meta name="description" content="Moraworld Imports — Tu casillero en New Jersey. Compra en Amazon, eBay y más. Enviamos a Ecuador con declaración aduanera incluida." />
|
||||||
<title>Moraworld Imports — Casillero en EE.UU. para Ecuador</title>
|
<title>Moraworld Imports — Casillero en EE.UU. para Ecuador</title>
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📦</text></svg>" />
|
||||||
|
<meta property="og:title" content="Moraworld Imports — Casillero en EE.UU. para Ecuador" />
|
||||||
|
<meta property="og:description" content="Tu casillero en New Jersey. Compra en Amazon, eBay y más. Enviamos a Ecuador con declaración SENAE incluida." />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta name="theme-color" content="#0057FF" />
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
|
||||||
@@ -470,7 +475,7 @@
|
|||||||
.footer-bottom {
|
.footer-bottom {
|
||||||
border-top: 1px solid rgba(255,255,255,.06);
|
border-top: 1px solid rgba(255,255,255,.06);
|
||||||
padding-top: 28px; display: flex; justify-content: space-between;
|
padding-top: 28px; display: flex; justify-content: space-between;
|
||||||
align-items: center; flex-wrap: gap;
|
align-items: center; flex-wrap: wrap; gap: 16px;
|
||||||
}
|
}
|
||||||
.footer-bottom p { font-size: .82rem; }
|
.footer-bottom p { font-size: .82rem; }
|
||||||
.footer-badges { display: flex; gap: 12px; }
|
.footer-badges { display: flex; gap: 12px; }
|
||||||
@@ -480,6 +485,24 @@
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── MOBILE MENU ── */
|
||||||
|
.mobile-menu {
|
||||||
|
display: none;
|
||||||
|
position: fixed; top: 64px; left: 0; right: 0; z-index: 99;
|
||||||
|
background: var(--white); border-bottom: 1px solid var(--gray-200);
|
||||||
|
padding: 16px 24px 24px; box-shadow: 0 8px 32px rgba(0,0,0,.12);
|
||||||
|
}
|
||||||
|
.mobile-menu.open { display: block; }
|
||||||
|
.mobile-nav-links { display: flex; flex-direction: column; }
|
||||||
|
.mobile-nav-links a { padding: 13px 0; border-bottom: 1px solid var(--gray-100); font-size: .95rem; font-weight: 500; color: var(--gray-700); display: block; }
|
||||||
|
.mobile-nav-links a:last-child { border-bottom: none; }
|
||||||
|
.mobile-nav-links a:hover { color: var(--primary); }
|
||||||
|
.mobile-nav-cta { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
|
||||||
|
.mobile-nav-cta .btn { justify-content: center; width: 100%; }
|
||||||
|
.hamburger.active span:nth-child(1) { transform: rotate(45deg) translate(5px, 5px); }
|
||||||
|
.hamburger.active span:nth-child(2) { opacity: 0; }
|
||||||
|
.hamburger.active span:nth-child(3) { transform: rotate(-45deg) translate(5px, -5px); }
|
||||||
|
|
||||||
/* ── WHATSAPP FLOAT ── */
|
/* ── WHATSAPP FLOAT ── */
|
||||||
.wa-float {
|
.wa-float {
|
||||||
position: fixed; bottom: 28px; right: 28px; z-index: 999;
|
position: fixed; bottom: 28px; right: 28px; z-index: 999;
|
||||||
@@ -543,7 +566,7 @@
|
|||||||
<a href="#como-funciona">Cómo funciona</a>
|
<a href="#como-funciona">Cómo funciona</a>
|
||||||
<a href="#calculadora">Calculadora</a>
|
<a href="#calculadora">Calculadora</a>
|
||||||
<a href="#tracking">Tracking</a>
|
<a href="#tracking">Tracking</a>
|
||||||
<a href="#carga-pesada">Carga Pesada</a>
|
<a href="#cotizacion">Carga Pesada</a>
|
||||||
<a href="#nosotros">Nosotros</a>
|
<a href="#nosotros">Nosotros</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-cta">
|
<div class="nav-cta">
|
||||||
@@ -556,6 +579,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
<!-- ─────────────────── MOBILE MENU ─────────────────── -->
|
||||||
|
<div class="mobile-menu" id="mobile-menu">
|
||||||
|
<div class="mobile-nav-links">
|
||||||
|
<a href="#servicios" onclick="closeMobileMenu()">Servicios</a>
|
||||||
|
<a href="#como-funciona" onclick="closeMobileMenu()">Cómo funciona</a>
|
||||||
|
<a href="#calculadora" onclick="closeMobileMenu()">Calculadora</a>
|
||||||
|
<a href="#tracking" onclick="closeMobileMenu()">Tracking</a>
|
||||||
|
<a href="#cotizacion" onclick="closeMobileMenu()">Carga Pesada</a>
|
||||||
|
<a href="#nosotros" onclick="closeMobileMenu()">Nosotros</a>
|
||||||
|
<a href="#contacto" onclick="closeMobileMenu()">Contacto</a>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-nav-cta">
|
||||||
|
<a href="login.html" class="btn btn-outline">Iniciar sesión</a>
|
||||||
|
<a href="registro.html" class="btn btn-primary">Abrir casillero gratis →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- ─────────────────── HERO ─────────────────── -->
|
<!-- ─────────────────── HERO ─────────────────── -->
|
||||||
<section class="hero">
|
<section class="hero">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -572,8 +612,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="hero-stats">
|
<div class="hero-stats">
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<div class="stat-num">150 N</div>
|
<div class="stat-num">$3.50</div>
|
||||||
<div class="stat-label">Day St, Orange NJ</div>
|
<div class="stat-label">por libra (flete)</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<div class="stat-num">24/7</div>
|
<div class="stat-num">24/7</div>
|
||||||
@@ -982,7 +1022,7 @@
|
|||||||
<input type="file" id="factura-upload" style="display:none;" accept=".pdf,image/*" />
|
<input type="file" id="factura-upload" style="display:none;" accept=".pdf,image/*" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="calc-btn">Registrar pre-alerta →</button>
|
<button class="calc-btn" onclick="submitPrealertaLanding()">Registrar pre-alerta →</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1252,7 +1292,7 @@
|
|||||||
<h3>Moraworld<span>.</span>Imports</h3>
|
<h3>Moraworld<span>.</span>Imports</h3>
|
||||||
<p>Conectamos el mercado americano con los consumidores ecuatorianos. Bodega en New Jersey, representación legal en Cuenca, Ecuador.</p>
|
<p>Conectamos el mercado americano con los consumidores ecuatorianos. Bodega en New Jersey, representación legal en Cuenca, Ecuador.</p>
|
||||||
<p style="margin-top:12px; font-size:.8rem;">
|
<p style="margin-top:12px; font-size:.8rem;">
|
||||||
📍 150 N Day St, Suite EC-, City of Orange, NJ 07050<br/>
|
📍 150 N Day St, City of Orange, NJ 07050<br/>
|
||||||
📍 Cuenca, Ecuador
|
📍 Cuenca, Ecuador
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -1260,7 +1300,7 @@
|
|||||||
<h4>Servicios</h4>
|
<h4>Servicios</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#servicios">Casillero Personal</a></li>
|
<li><a href="#servicios">Casillero Personal</a></li>
|
||||||
<li><a href="#carga-pesada">Carga Pesada</a></li>
|
<li><a href="#cotizacion">Carga Pesada</a></li>
|
||||||
<li><a href="#calculadora">Calculadora</a></li>
|
<li><a href="#calculadora">Calculadora</a></li>
|
||||||
<li><a href="#tracking">Tracking</a></li>
|
<li><a href="#tracking">Tracking</a></li>
|
||||||
<li><a href="#prealerta">Pre-alerta</a></li>
|
<li><a href="#prealerta">Pre-alerta</a></li>
|
||||||
@@ -1324,9 +1364,26 @@
|
|||||||
function toggleWa(){
|
function toggleWa(){
|
||||||
document.getElementById('wa-float').classList.toggle('open');
|
document.getElementById('wa-float').classList.toggle('open');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mobile menu */
|
||||||
|
function closeMobileMenu(){
|
||||||
|
document.getElementById('mobile-menu').classList.remove('open');
|
||||||
|
document.getElementById('hamburger').classList.remove('active');
|
||||||
|
}
|
||||||
|
document.getElementById('hamburger').addEventListener('click', function(){
|
||||||
|
this.classList.toggle('active');
|
||||||
|
document.getElementById('mobile-menu').classList.toggle('open');
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Close menus when clicking outside */
|
||||||
document.addEventListener('click', function(e){
|
document.addEventListener('click', function(e){
|
||||||
const wf = document.getElementById('wa-float');
|
const wf = document.getElementById('wa-float');
|
||||||
if(!wf.contains(e.target)) wf.classList.remove('open');
|
if(!wf.contains(e.target)) wf.classList.remove('open');
|
||||||
|
const menu = document.getElementById('mobile-menu');
|
||||||
|
const hamburger = document.getElementById('hamburger');
|
||||||
|
if(menu.classList.contains('open') && !menu.contains(e.target) && !hamburger.contains(e.target)){
|
||||||
|
closeMobileMenu();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* FAQ accordion */
|
/* FAQ accordion */
|
||||||
@@ -1346,15 +1403,11 @@
|
|||||||
const valor = parseFloat(document.getElementById('c-value').value) || 0;
|
const valor = parseFloat(document.getElementById('c-value').value) || 0;
|
||||||
const cat = document.getElementById('c-cat').value;
|
const cat = document.getElementById('c-cat').value;
|
||||||
|
|
||||||
// Peso volumétrico (cm³ / 139 = lbs volumétricas aprox)
|
|
||||||
const volWeight = (largo * ancho * alto) / 139;
|
const volWeight = (largo * ancho * alto) / 139;
|
||||||
const pesoFinal = Math.max(weight, volWeight);
|
const pesoFinal = Math.max(weight, volWeight);
|
||||||
|
|
||||||
// Tarifas arancel
|
|
||||||
const aranceles = { '4x4': 0, 'B': 0.10, 'C': 0.20, 'D': 0.10 };
|
const aranceles = { '4x4': 0, 'B': 0.10, 'C': 0.20, 'D': 0.10 };
|
||||||
const tarifaFlete = 3.50; // USD / lb
|
const flete = pesoFinal * 3.50;
|
||||||
|
|
||||||
const flete = pesoFinal * tarifaFlete;
|
|
||||||
const seguro = valor * 0.02;
|
const seguro = valor * 0.02;
|
||||||
const fodinfa = valor * 0.005;
|
const fodinfa = valor * 0.005;
|
||||||
const arancel = valor * (aranceles[cat] || 0);
|
const arancel = valor * (aranceles[cat] || 0);
|
||||||
@@ -1366,8 +1419,8 @@
|
|||||||
document.getElementById('r-peso').textContent = pesoFinal.toFixed(2) + ' lbs';
|
document.getElementById('r-peso').textContent = pesoFinal.toFixed(2) + ' lbs';
|
||||||
document.getElementById('r-flete').textContent = fmt(flete);
|
document.getElementById('r-flete').textContent = fmt(flete);
|
||||||
document.getElementById('r-seguro').textContent = fmt(seguro);
|
document.getElementById('r-seguro').textContent = fmt(seguro);
|
||||||
document.getElementById('r-fodinfa').textContent= fmt(fodinfa);
|
document.getElementById('r-fodinfa').textContent = fmt(fodinfa);
|
||||||
document.getElementById('r-arancel').textContent= fmt(arancel) + (cat === '4x4' ? ' (exento)' : '');
|
document.getElementById('r-arancel').textContent = fmt(arancel) + (cat === '4x4' ? ' (exento)' : '');
|
||||||
document.getElementById('r-iva').textContent = fmt(iva);
|
document.getElementById('r-iva').textContent = fmt(iva);
|
||||||
document.getElementById('r-total').textContent = fmt(total);
|
document.getElementById('r-total').textContent = fmt(total);
|
||||||
}
|
}
|
||||||
@@ -1380,11 +1433,12 @@
|
|||||||
document.getElementById('tracking-result').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
document.getElementById('tracking-result').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hamburger menu (mobile) */
|
/* Pre-alerta landing */
|
||||||
document.getElementById('hamburger').addEventListener('click', function(){
|
function submitPrealertaLanding(){
|
||||||
// Simple toggle — en producción se expandiría el menú móvil
|
const tracking = document.querySelector('.prealerta-form input[type=text]').value.trim();
|
||||||
this.classList.toggle('active');
|
if(!tracking){ alert('Ingresa el número de tracking del vendedor.'); return; }
|
||||||
});
|
alert('✅ Pre-alerta registrada. El equipo de bodega en NJ estará atento a la llegada de tu paquete. ¡Gracias!');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>Iniciar sesión — Moraworld Imports</title>
|
<title>Iniciar sesión — Moraworld Imports</title>
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📦</text></svg>" />
|
||||||
|
<meta name="theme-color" content="#0057FF" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||||
<style>
|
<style>
|
||||||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>Mi Casillero — Moraworld Imports</title>
|
<title>Mi Casillero — Moraworld Imports</title>
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📦</text></svg>" />
|
||||||
|
<meta name="theme-color" content="#0057FF" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet"/>
|
||||||
<style>
|
<style>
|
||||||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>Crear cuenta — Moraworld Imports</title>
|
<title>Crear cuenta — Moraworld Imports</title>
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📦</text></svg>" />
|
||||||
|
<meta name="theme-color" content="#0057FF" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||||
<style>
|
<style>
|
||||||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
||||||
|
|||||||
Reference in New Issue
Block a user