feat: improve seo, trust signals, and performance

This commit is contained in:
Manuel
2026-07-20 12:07:23 +02:00
parent 49f391ee49
commit faed590a66
27 changed files with 1444 additions and 153 deletions
+42 -71
View File
@@ -1,81 +1,52 @@
# AGENTS.md # AGENTS.md
## Stack ## Stack and runtime
- Astro 5 SSR with `@astrojs/node` in `standalone` mode.
- Production entrypoint is `node ./dist/server/entry.mjs`.
- Runtime target is Node 20 (`Dockerfile` and `nixpacks.toml` both pin Node 20).
- TypeScript extends `astro/tsconfigs/strict`.
- **Framework:** Astro 5 ## Verified commands
- **Adapter:** `@astrojs/node` - Install deps: `npm install` or `npm ci`
- **Rendering mode:** SSR - Dev server: `npm run dev`
- **Runtime target:** Node standalone en VPS con Dokploy - Type/content check: `npm run check`
- **Styling:** CSS custom con variables CSS - Build: `npm run build`
- **Responsive approach:** mobile-first - Local preview: `npm run preview`
- Production start: `npm run start`
## Arquitectura del producto Recommended verification after UI/content changes:
1. `npm run check`
2. `npm run build`
Sitio institucional multipágina enfocado en **captación de leads por WhatsApp**. There are currently no repo scripts for linting, formatting, or tests, and no CI workflows to rely on.
Páginas aprobadas: ## Real app structure
- File-based routes live in `src/pages/`.
- Main public routes: `index.astro`, `nosotros.astro`, `bodas-reales.astro`, `corporativo-business.astro`, `reuniones-familiares.astro`, `contacto.astro`.
- Legal routes are part of the real surface area: `cookies.astro` and `privacidad.astro`.
- Shared shell is `src/layouts/MainLayout.astro`.
- Shared UI lives in `src/components/`.
- Global styling is split across `src/styles/tokens.css`, `base.css`, `layout.css`, `components.css`, `utilities.css`, and `animations.css`.
- Home ## Important implementation facts
- Nosotros - `MainLayout.astro` is the real wiring point: it imports all global CSS and mounts `SiteHeader`, `SiteFooter`, `WhatsAppButton`, and `CookieBanner` on every page.
- Bodas Reales - `MainLayout.astro` also owns global client behavior: reveal-on-scroll, scroll progress bar, reduced-motion handling, and internal-link fade transitions.
- Corporativo & Business - This is a marketing site optimized for WhatsApp lead capture. Keep WhatsApp as the primary CTA and treat the contact form as secondary.
- Reuniones Familiares - The contact form in `src/pages/contacto.astro` is presentational only (`method="dialog"`); do not describe or treat it as a working backend submission flow.
- Contacto - The WhatsApp destination is hardcoded in multiple places (`+34 678 17 15 13` / `34678171513`). If lead routing changes, search for all occurrences instead of updating a single component and assuming coverage.
## Comandos ## Content and design constraints
- Keep the mobile-first approach in base styles and layout decisions.
- Use CSS variables/tokens instead of introducing utility CSS frameworks.
- Keep service pages structurally consistent, but do not clone copy blindly: adapt CTA, gallery, and messaging per service.
- Galleries belong inside each service page, not as a separate gallery page.
- Preserve the premium editorial tone from `DESIGN.md`; gold is an accent, not a dominant fill color.
Comandos esperados para la implementación del proyecto: ## Deployment notes
- Docker and Nixpacks both expect a built SSR app and start with `node ./dist/server/entry.mjs`.
- Runtime env defaults used by deploy config: `HOST=0.0.0.0`, `PORT=4321`, `NODE_ENV=production`.
| Acción | Comando | ## Repo-specific gotchas
| --- | --- | - Ignore generated/build output: `.astro/` and `dist/`.
| Instalar dependencias | `npm install` | - `.gitignore` also excludes `.opencode/`, `.worktrees/`, and local planning artifacts under `docs/plans/`.
| Desarrollo | `npm run dev` | - Read `DESIGN.md` before making visual changes; it contains the project’s visual system and tone constraints.
| Build | `npm run build` |
| Preview / ejecución standalone | `node ./dist/server/entry.mjs` |
## Convenciones
1. Priorizar claridad comercial y conversión por WhatsApp.
2. Mantener arquitectura mobile-first desde el CSS base.
3. Usar variables CSS para tokens de color, spacing, tipografía, radios y sombras.
4. Evitar frameworks de utilidades si no aportan valor claro al sistema visual.
5. Mantener consistencia estructural entre páginas de servicio.
6. Las galerías deben vivir dentro de cada servicio, no como página independiente.
7. El formulario de contacto debe ser secundario respecto a WhatsApp.
## Don'ts
- No usar `@astrojs/cloudflare` para este proyecto: el deployment objetivo es Dokploy sobre VPS.
- No diseñar desktop-first.
- No mezclar estilos premium editoriales con componentes visualmente ruidosos.
- No usar dorado como color masivo de relleno; usarlo como acento.
- No construir páginas de servicio genéricas copiadas una de otra sin adaptar copy, CTA y galería.
## Estructura CSS recomendada
- `src/styles/tokens.css`
- `src/styles/base.css`
- `src/styles/layout.css`
- `src/styles/components.css`
- `src/styles/utilities.css`
## Skills
Habilidades especialmente relevantes para este proyecto:
- `project-docs`
- `brainstorming`
- `responsive-design`
- `visual-design-foundations`
- `interface-design`
- `accessibility-compliance`
## Nota para futuros agentes
Antes de implementar:
1. Leer `README.md`
2. Leer este `AGENTS.md`
3. Leer `DESIGN.md`
4. Respetar el enfoque comercial: WhatsApp primero
5. Respetar el enfoque visual: claro editorial premium
+7
View File
@@ -1,9 +1,16 @@
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import node from '@astrojs/node'; import node from '@astrojs/node';
import sitemap from '@astrojs/sitemap';
export default defineConfig({ export default defineConfig({
site: 'https://mnq.elkazurrotaberna.es',
output: 'server', output: 'server',
adapter: node({ adapter: node({
mode: 'standalone', mode: 'standalone',
}), }),
integrations: [
sitemap({
filter: (page) => !page.endsWith('/cookies/') && !page.endsWith('/privacidad/'),
}),
],
}); });
@@ -0,0 +1,347 @@
# Combined SEO priority roadmap
This document combines two sources reviewed on July 19, 2026:
- PageSpeed Insights desktop report for `https://mnq.elkazurrotaberna.es/`
- `docs/seo-audit/Google-SEO-Report-mnq.elkazurrotaberna.es-full.pdf`
It is intentionally split into:
- **Repo-verified issues**: confirmed from the current codebase
- **Production-only checks**: reported by the PDF/PageSpeed but require live-environment validation
---
## Current headline picture
- Performance: **80**
- Accessibility: **96**
- Best Practices: **100**
- SEO: **100**
- External full SEO PDF health score: **39/100**
Interpretation:
- Lighthouse says the site is technically decent at baseline.
- The PDF surfaces bigger **search readiness / local SEO / entity trust** gaps that Lighthouse does not score deeply.
---
## Tier 1 — Critical fixes
### 1. Add crawl and discovery files
**Status:** repo-verified missing
**Missing**
- `robots.txt`
- `sitemap.xml`
- `llms.txt`
**Why this is critical**
- Search engines and AI crawlers lack explicit discovery and policy signals.
- This is one of the highest-leverage technical SEO fixes on a small site.
**Files to add / touch**
- `public/robots.txt`
- sitemap generation setup in Astro
- `public/llms.txt`
**Recommended action**
- Add `robots.txt` with a `Sitemap:` directive.
- Generate a sitemap from the real route set.
- Add a concise `llms.txt` with business summary, services, contact, and canonical domain.
---
### 2. Add missing `<head>` SEO signals sitewide
**Status:** repo-verified missing
**Missing**
- canonical tags
- Open Graph tags
- explicit meta robots tags
- JSON-LD / structured data
**Why this is critical**
- The site currently has content, but weak machine-readable identity.
- Canonicalization and entity markup matter more here than another visual polish pass.
**Files to touch**
- `src/layouts/MainLayout.astro`
- possibly shared helpers/components if you extract metadata/schema logic
**Recommended action**
- Add self-referencing canonical tags.
- Add base OG tags (`og:title`, `og:description`, `og:type`, `og:url`, `og:image`).
- Add explicit `meta name="robots"` defaults, with special handling for legal pages if desired.
- Add sitewide JSON-LD for the business plus page-specific schema later.
---
### 3. Fix language/market mismatch
**Status:** repo-verified
**Current code**
- `src/layouts/MainLayout.astro` uses `lang="es-AR"`
**Why this is critical**
- The site targets Spain signals (`+34`, RGPD/legal context), not Argentina.
- This mismatch hurts consistency for SEO, accessibility, and AI interpretation.
**Files to touch**
- `src/layouts/MainLayout.astro`
- any copy using inconsistent register
**Recommended action**
- Change sitewide language to `es-ES`.
- Standardize tone/register across pages.
---
### 4. Fix the business identity trust gap
**Status:** partially repo-verified
**Repo-verified issues**
- `eventos@mnqcatering.com` appears in:
- `src/pages/contacto.astro`
- `src/pages/cookies.astro`
- `src/pages/privacidad.astro`
- Corporate client names in `src/pages/corporativo-business.astro` look like placeholders:
- `LUMINA`
- `Nordic Corp`
- `Apex Sol.`
**Why this is critical**
- A dead email domain or invented-looking client proof is poison for conversions and trust.
- This is not cosmetic. This is credibility.
**Files to touch**
- `src/pages/contacto.astro`
- `src/pages/cookies.astro`
- `src/pages/privacidad.astro`
- `src/pages/corporativo-business.astro`
**Recommended action**
- Verify the real contact domain and replace broken email references if needed.
- Remove fabricated-looking client names unless they are real and permissioned.
- Replace them with real logos, real brands, or no claim at all.
---
### 5. Add service-area and local intent signals
**Status:** repo gap strongly supported by PDF; should be treated as high-priority content work
**Why this is critical**
- The site needs explicit geography/service area to compete for local intent.
- Right now the strongest geo signal appears to be the phone prefix.
**Recommended action**
- Add a visible service-area section on homepage and contact page.
- Mention real cities/regions served.
- Reflect the same area in JSON-LD (`areaServed`).
**Likely files to touch**
- `src/pages/index.astro`
- `src/pages/contacto.astro`
- service pages under `src/pages/`
---
## Tier 2 — High-impact SEO and conversion improvements
### 6. Add `tel:` links and strengthen contact usability
**Status:** repo-verified missing
**Why**
- The PDF correctly flags phone numbers as plain text.
- Click-to-call is basic conversion hygiene.
**Files to touch**
- `src/pages/contacto.astro`
- `src/components/SiteFooter.astro`
- any page/header component showing the phone number
**Recommended action**
- Wrap visible phone numbers in `tel:` links.
- Keep formatting human-readable while normalizing href values.
---
### 7. Add FAQ and schema-backed informational sections
**Status:** supported by PDF; not yet implemented in repo
**Why**
- The site is heavily CTA-driven but thin on concrete buyer-answer content.
- FAQ helps SEO, AI retrieval, and lead qualification.
**Recommended action**
- Add short FAQ blocks on main commercial pages.
- Add FAQPage schema only for visible questions/answers.
**Likely files to touch**
- `src/pages/bodas-reales.astro`
- `src/pages/corporativo-business.astro`
- `src/pages/reuniones-familiares.astro`
- `src/pages/contacto.astro`
---
### 8. Add concrete facts: pricing, capacity, coverage, lead time
**Status:** supported by PDF; likely real gap
**Why**
- Premium tone without specifics creates trust friction.
- Visitors need qualifying information before filling a form or opening WhatsApp.
**Recommended action**
- Add readable prose covering:
- capacity ranges
- indicative pricing approach or starting-tier language
- coverage area
- booking lead time
**Most important page**
- `src/pages/reuniones-familiares.astro` appears weakest per the PDF.
---
## Tier 3 — Performance fixes with clear Lighthouse payoff
### 9. Remove or reduce render-blocking font requests
**Status:** repo-verified + PageSpeed-supported
**Files**
- `src/layouts/MainLayout.astro`
**Current issues**
- external Google Fonts stylesheet request
- external Material Symbols stylesheet request
**Recommended action**
- reduce font families/weights
- replace icon font with local/inline SVGs if feasible
- self-host fonts if the project keeps them
**Why**
- Lighthouse reports render-blocking request savings around **1380 ms**.
---
### 10. Fix image delivery and explicit dimensions
**Status:** repo-verified + PageSpeed-supported
**Files**
- `src/pages/index.astro`
- `src/pages/bodas-reales.astro`
- `src/pages/corporativo-business.astro`
- review also `src/pages/contacto.astro`, `src/pages/nosotros.astro`, `src/pages/reuniones-familiares.astro`
**Recommended action**
- add explicit `width` and `height`
- make sure above-the-fold assets are not oversized
- keep optimized formats consistent
- use lazy loading for non-hero images
**Why**
- Lighthouse reports image savings around **1423 KiB**.
- It also flags missing image dimensions.
---
### 11. Recompress and rationalize `public/images/`
**Status:** repo-verified
**Hotspots**
- several large `.png` files in `public/images/`
- oversized footer/logo assets relative to rendered size
**Recommended action**
- replace or recompress large PNGs
- prefer lighter WebP variants where acceptable
- remove duplicates not used in production
**Folders**
- `public/images/`
- `public/images/generated/`
---
### 12. Fix footer contrast
**Status:** repo-verified + Lighthouse-supported
**Files**
- `src/components/SiteFooter.astro`
- `src/styles/components.css`
**Current issue**
- footer text uses muted color plus low opacity
**Recommended action**
- increase contrast on footer copy
- reduce/remove low-opacity muted treatment
---
### 13. Normalize duplicated WhatsApp link labels
**Status:** repo-verified via Lighthouse finding
**Files**
- `src/components/SiteHeader.astro`
- `src/components/SiteFooter.astro`
**Recommended action**
- keep the same accessible purpose for identical WhatsApp destinations
- use `aria-label` if visible text differs by context
---
### 14. Replace width animation on the progress bar
**Status:** repo-verified + Lighthouse-supported
**Files**
- `src/styles/animations.css`
- `src/layouts/MainLayout.astro`
**Recommended action**
- stop animating `width`
- use `transform: scaleX(...)` with `transform-origin: left`
---
## Tier 4 — Production-only checks to verify before coding against them
These came from the PDF/PageSpeed/live-site observations but are **not provable from the repo alone**.
### Validate on production
- `www` behavior, redirects, and TLS coverage
- security headers (`HSTS`, `X-Content-Type-Options`, `X-Frame-Options`, `CSP`)
- gzip/brotli compression on HTML/CSS
- cookie banner overlapping the floating WhatsApp CTA
- broken/bleeding UI element near the top-left viewport
- live caching policy for `/images/*`
- whether the contact email domain truly fails resolution
- whether the unrelated parent domain relationship must be clarified publicly
These should be treated as a separate verification pass against the deployed site.
---
## Suggested implementation order
1. crawl/discovery files (`robots.txt`, sitemap, `llms.txt`)
2. canonical + OG + robots + base JSON-LD in `MainLayout.astro`
3. `lang` correction to `es-ES`
4. email/domain trust fix and corporate-proof cleanup
5. service-area content and `tel:` links
6. FAQ / concrete fact sections on service pages
7. font and image performance fixes
8. footer contrast and smaller accessibility cleanups
9. production header/caching/compression validation
---
## Minimum verification after each implementation batch
1. `npm run check`
2. `npm run build`
3. re-run desktop PageSpeed
4. manually inspect live `<head>` output and generated crawl files
---
## Related files already present
- `docs/seo-audit/Google-SEO-Report-mnq.elkazurrotaberna.es-full.pdf`
- `docs/seo-audit/pagespeed-priority-list.md`
+133
View File
@@ -0,0 +1,133 @@
# PageSpeed priority list
Source reviewed:
- PageSpeed Insights desktop report for `https://mnq.elkazurrotaberna.es/`
- Existing audit artifact: `Google-SEO-Report-mnq.elkazurrotaberna.es-full.pdf`
## Scores
- Performance: 80
- Accessibility: 96
- Best Practices: 100
- SEO: 100
## Fix first
### 1. Remove or reduce render-blocking font requests
**Files**
- `src/layouts/MainLayout.astro`
**Change**
- Reduce Google Fonts weights/families.
- Replace Material Symbols webfont with inline/local SVGs if possible.
- Keep `preconnect` only if those remote font requests remain.
- Re-evaluate the global body fade if it delays perceived first paint.
**Why**
- Lighthouse reports render-blocking requests with ~1380 ms potential savings.
---
### 2. Add explicit image dimensions and tighten image delivery
**Files**
- `src/pages/index.astro`
- `src/pages/bodas-reales.astro`
- `src/pages/corporativo-business.astro`
- Review also: `src/pages/contacto.astro`, `src/pages/nosotros.astro`, `src/pages/reuniones-familiares.astro`
**Change**
- Add `width` and `height` to page images.
- Verify above-the-fold images are not larger than their rendered size.
- Keep optimized formats consistent.
- Do not rely on CSS sizing alone for layout stability.
**Why**
- Lighthouse reports ~1423 KiB image savings.
- It also flags missing explicit image dimensions.
---
### 3. Shrink heavy assets in `public/images/`
**Files / folders**
- `public/images/`
- `public/images/generated/`
**Change**
- Replace or recompress large `.png` assets where a lighter format is acceptable.
- Prefer existing `.webp` variants where possible.
- Remove unused duplicates.
- Audit especially the heavier files such as `foto-corporativo.png`, `foto-bodas.png`, `foto-canapes.png`, `foto-plato-mnq.png`, and oversized logo assets.
**Why**
- The current image payload is a major part of the desktop performance loss.
---
### 4. Fix footer contrast
**Files**
- `src/components/SiteFooter.astro`
- `src/styles/components.css`
**Change**
- Increase footer text contrast.
- Reduce or remove low-opacity muted text in the footer.
- Review `.footer-bottom p`, `.footer-brand p`, and any `text-muted` + `opacity` combinations.
**Why**
- Lighthouse flags footer contrast issues.
---
### 5. Make WhatsApp links use the same accessible purpose
**Files**
- `src/components/SiteHeader.astro`
- `src/components/SiteFooter.astro`
**Change**
- Ensure identical WhatsApp destinations use a consistent accessible label.
- If visible text differs by context, normalize it with `aria-label`.
**Why**
- Lighthouse flags identical links with mismatched purpose/description.
---
### 6. Replace progress bar width animation with transform animation
**Files**
- `src/styles/animations.css`
- related update logic in `src/layouts/MainLayout.astro`
**Change**
- Stop animating `width` on `.scroll-progress`.
- Use `transform: scaleX(...)` with `transform-origin: left` instead.
**Why**
- Lighthouse flags non-composited animations.
---
### 7. Trim unused CSS
**Files**
- `src/styles/components.css`
- `src/styles/utilities.css`
- `src/styles/animations.css`
- `src/styles/layout.css`
**Change**
- Remove unused helpers, stale animations, and dead selectors.
**Why**
- Lighthouse reports unused CSS, but this is lower priority than fonts and images.
## Recommended implementation order
1. `src/layouts/MainLayout.astro`
2. image dimensions in page files
3. asset optimization in `public/images/`
4. footer contrast
5. WhatsApp link labeling
6. scroll progress animation
7. CSS cleanup
## Validation after each batch
1. `npm run check`
2. `npm run build`
3. Re-run desktop PageSpeed
+76
View File
@@ -9,6 +9,7 @@
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@astrojs/node": "^9.5.5", "@astrojs/node": "^9.5.5",
"@astrojs/sitemap": "^3.7.3",
"astro": "^5.18.1" "astro": "^5.18.1"
}, },
"devDependencies": { "devDependencies": {
@@ -184,6 +185,26 @@
"node": "18.20.8 || ^20.3.0 || >=22.0.0" "node": "18.20.8 || ^20.3.0 || >=22.0.0"
} }
}, },
"node_modules/@astrojs/sitemap": {
"version": "3.7.3",
"resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.3.tgz",
"integrity": "sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA==",
"license": "MIT",
"dependencies": {
"sitemap": "^9.0.0",
"stream-replace-string": "^2.0.0",
"zod": "^4.3.6"
}
},
"node_modules/@astrojs/sitemap/node_modules/zod": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/@astrojs/telemetry": { "node_modules/@astrojs/telemetry": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz",
@@ -1704,6 +1725,24 @@
"@types/unist": "*" "@types/unist": "*"
} }
}, },
"node_modules/@types/node": {
"version": "24.13.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz",
"integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.18.0"
}
},
"node_modules/@types/sax": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
"integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/unist": { "node_modules/@types/unist": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -1957,6 +1996,12 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
"license": "MIT"
},
"node_modules/argparse": { "node_modules/argparse": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -4976,6 +5021,25 @@
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/sitemap": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz",
"integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==",
"license": "MIT",
"dependencies": {
"@types/node": "^24.9.2",
"@types/sax": "^1.2.1",
"arg": "^5.0.0",
"sax": "^1.4.1"
},
"bin": {
"sitemap": "dist/esm/cli.js"
},
"engines": {
"node": ">=20.19.5",
"npm": ">=10.8.2"
}
},
"node_modules/smol-toml": { "node_modules/smol-toml": {
"version": "1.6.1", "version": "1.6.1",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz",
@@ -5016,6 +5080,12 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/stream-replace-string": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz",
"integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==",
"license": "MIT"
},
"node_modules/string-width": { "node_modules/string-width": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
@@ -5234,6 +5304,12 @@
"integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/undici-types": {
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"license": "MIT"
},
"node_modules/unified": { "node_modules/unified": {
"version": "11.0.5", "version": "11.0.5",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
+1
View File
@@ -13,6 +13,7 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@astrojs/node": "^9.5.5", "@astrojs/node": "^9.5.5",
"@astrojs/sitemap": "^3.7.3",
"astro": "^5.18.1" "astro": "^5.18.1"
}, },
"devDependencies": { "devDependencies": {
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

+7
View File
@@ -0,0 +1,7 @@
MNQ Catering y Evento
- Canonical domain: https://mnq.elkazurrotaberna.es
- Business type: Premium catering service
- Services: Bodas, eventos corporativos, reuniones familiares
- Primary contact channels: WhatsApp (+34 678 17 15 13), phone (+34 678 17 15 13)
- Key pages: /, /nosotros, /bodas-reales, /corporativo-business, /reuniones-familiares, /contacto
+4
View File
@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://mnq.elkazurrotaberna.es/sitemap-index.xml
+88
View File
@@ -0,0 +1,88 @@
---
interface Props {
name:
| 'architecture'
| 'arrow-forward'
| 'auto-awesome'
| 'call'
| 'chat'
| 'history-edu'
| 'language'
| 'local-florist'
| 'restaurant-menu'
| 'verified';
class?: string;
size?: number;
}
const { name, class: className, size = 20 } = Astro.props;
const icons: Record<Props['name'], { viewBox: string; markup: string }> = {
architecture: {
viewBox: '0 0 24 24',
markup:
'<path d="M3 21h18" /><path d="M5 21V9" /><path d="M19 21V9" /><path d="M8 21v-5" /><path d="M12 21v-5" /><path d="M16 21v-5" /><path d="M4 9h16" /><path d="M12 3 3 9h18L12 3Z" />',
},
'arrow-forward': {
viewBox: '0 0 24 24',
markup: '<path d="M5 12h14" /><path d="m13 6 6 6-6 6" />',
},
'auto-awesome': {
viewBox: '0 0 24 24',
markup:
'<path d="m12 3 1.6 4.4L18 9l-4.4 1.6L12 15l-1.6-4.4L6 9l4.4-1.6L12 3Z" /><path d="m19 14 .8 2.2L22 17l-2.2.8L19 20l-.8-2.2L16 17l2.2-.8L19 14Z" /><path d="m5 14 .8 2.2L8 17l-2.2.8L5 20l-.8-2.2L2 17l2.2-.8L5 14Z" />',
},
call: {
viewBox: '0 0 24 24',
markup:
'<path d="M4.5 6.8c0 7 5.7 12.7 12.7 12.7h1.9a1.4 1.4 0 0 0 1.4-1.4v-2.4a1.4 1.4 0 0 0-1.2-1.4l-3.2-.4a1.4 1.4 0 0 0-1.4.8l-.7 1.4a11.4 11.4 0 0 1-6.1-6.1l1.4-.7a1.4 1.4 0 0 0 .8-1.4l-.4-3.2A1.4 1.4 0 0 0 8.3 3.5H5.9A1.4 1.4 0 0 0 4.5 4.9v1.9Z" />',
},
chat: {
viewBox: '0 0 24 24',
markup:
'<path d="M7 18H4a1 1 0 0 1-1-1V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4v6a4 4 0 0 1-4 4H9l-4 4v-3Z" /><path d="M8 9h8" /><path d="M8 13h5" />',
},
'history-edu': {
viewBox: '0 0 24 24',
markup:
'<path d="M4 5.5A2.5 2.5 0 0 1 6.5 3H20v16H6.5A2.5 2.5 0 0 0 4 21.5V5.5Z" /><path d="M8 7h7" /><path d="M8 11h8" /><path d="M8 15h5" /><path d="M4 21.5A2.5 2.5 0 0 1 6.5 19" />',
},
language: {
viewBox: '0 0 24 24',
markup:
'<path d="M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Z" /><path d="M3 12h18" /><path d="M12 3a14.5 14.5 0 0 1 0 18" /><path d="M12 3a14.5 14.5 0 0 0 0 18" />',
},
'local-florist': {
viewBox: '0 0 24 24',
markup:
'<path d="M12 13.5c1.8-2.1 4.5-2.7 5.8-1.4 1.3 1.3.7 4-1.4 5.8-2.1 1.8-4.8 2.2-6.1.9-1.3-1.3-.9-4 .9-6.1.2-.2.5-.5.8-.7Z" /><path d="M12 13.5c-1.8-2.1-4.5-2.7-5.8-1.4-1.3 1.3-.7 4 1.4 5.8 2.1 1.8 4.8 2.2 6.1.9 1.3-1.3.9-4-.9-6.1-.2-.2-.5-.5-.8-.7Z" /><path d="M12 13.5c2.7-.8 4.4-2.9 3.8-4.7-.6-1.8-3.4-2.5-6.1-1.7-2.7.8-4.4 2.9-3.8 4.7.6 1.8 3.4 2.5 6.1 1.7Z" /><path d="M12 13.5V21" /><path d="M10 21h4" />',
},
'restaurant-menu': {
viewBox: '0 0 24 24',
markup:
'<path d="M6 3v7" /><path d="M9 3v7" /><path d="M6 7h3" /><path d="M7.5 10v11" /><path d="M15 3c1.7 2 2.5 4.1 2.5 6.3V21" /><path d="M15 10.5c-1.4 0-2.5-1.1-2.5-2.5S13.6 5.5 15 5.5" />',
},
verified: {
viewBox: '0 0 24 24',
markup:
'<path d="m9 12 2 2 4-4" /><path d="M12 3.5 14.6 5l3-.2 1 2.8 2.4 1.8-1 2.8 1 2.8-2.4 1.8-1 2.8-3-.2-2.6 1.5-2.6-1.5-3 .2-1-2.8L3 15.9l1-2.8-1-2.8 2.4-1.8 1-2.8 3 .2L12 3.5Z" />',
},
};
const icon = icons[name];
---
<svg
class:list={['icon', className]}
style={`--icon-size:${size}px;`}
viewBox={icon.viewBox}
fill="none"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
focusable="false"
set:html={icon.markup}
/>
+13 -2
View File
@@ -1,3 +1,7 @@
---
const whatsappAriaLabel = 'Contactar con MNQ por WhatsApp';
---
<footer class="site-footer"> <footer class="site-footer">
<div class="page-wrap"> <div class="page-wrap">
<div class="footer-inner"> <div class="footer-inner">
@@ -5,12 +9,18 @@
<div class="footer-brand"> <div class="footer-brand">
<a href="/" aria-label="MNQ Catering y Eventos"> <a href="/" aria-label="MNQ Catering y Eventos">
<img <img
src="/images/logo-secondary.png" src="/images/logo-secondary.webp"
alt="MNQ Catering y Eventos" alt="MNQ Catering y Eventos"
width="224"
height="224"
style="height: 3.5rem; width: auto; mix-blend-mode: multiply; margin-bottom: 1rem;" style="height: 3.5rem; width: auto; mix-blend-mode: multiply; margin-bottom: 1rem;"
/> />
</a> </a>
<p>© 2025 MNQ Catering y Evento. Excelencia culinaria para los momentos más importantes de su vida.</p> <p>© 2025 MNQ Catering y Evento. Excelencia culinaria para los momentos más importantes de su vida.</p>
<div style="display:flex;flex-direction:column;gap:0.35rem;margin-top:var(--space-4);">
<a href="tel:+34678171513" class="footer-link" style="width:fit-content;">+34 678 17 15 13</a>
<a href="https://mnq.elkazurrotaberna.es" class="footer-link" style="width:fit-content;">mnq.elkazurrotaberna.es</a>
</div>
</div> </div>
<div class="footer-links"> <div class="footer-links">
@@ -29,6 +39,7 @@
class="footer-link" class="footer-link"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
>WhatsApp</a> >WhatsApp</a>
<a href="/privacidad" class="footer-link">Privacidad</a> <a href="/privacidad" class="footer-link">Privacidad</a>
<a href="/cookies" class="footer-link">Cookies</a> <a href="/cookies" class="footer-link">Cookies</a>
@@ -38,7 +49,7 @@
</div> </div>
<div class="footer-bottom"> <div class="footer-bottom">
<p class="text-body-sm text-muted opacity-60"> <p class="text-body-sm">
Excelencia culinaria · Diseño de eventos · Gastronomía de autor Excelencia culinaria · Diseño de eventos · Gastronomía de autor
</p> </p>
</div> </div>
+5 -2
View File
@@ -3,6 +3,7 @@ interface Props {
activeNav?: string; activeNav?: string;
} }
const { activeNav } = Astro.props; const { activeNav } = Astro.props;
const whatsappAriaLabel = 'Contactar con MNQ por WhatsApp';
const links = [ const links = [
{ href: '/bodas-reales', label: 'Bodas', key: 'bodas' }, { href: '/bodas-reales', label: 'Bodas', key: 'bodas' },
@@ -21,8 +22,8 @@ const links = [
src="/images/logo-nav-dark.webp" src="/images/logo-nav-dark.webp"
alt="MNQ Catering y Eventos" alt="MNQ Catering y Eventos"
class="site-logo-banner" class="site-logo-banner"
width="220" width="600"
height="85" height="232"
/> />
</a> </a>
@@ -42,6 +43,7 @@ const links = [
class="btn btn-pill nav-wa" class="btn btn-pill nav-wa"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
> >
WhatsApp WhatsApp
</a> </a>
@@ -69,6 +71,7 @@ const links = [
class="btn btn-primary mobile-wa" class="btn btn-primary mobile-wa"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
style="width: 100%; justify-content: center; margin-top: 0.5rem;" style="width: 100%; justify-content: center; margin-top: 0.5rem;"
> >
Consultar por WhatsApp Consultar por WhatsApp
+7 -3
View File
@@ -1,12 +1,16 @@
---
import Icon from './Icon.astro';
---
<a <a
class="whatsapp-float" class="whatsapp-float"
href="https://wa.me/34678171513?text=Hola%20MNQ%2C%20quiero%20cotizar%20mi%20evento" href="https://wa.me/34678171513?text=Hola%20MNQ%2C%20quiero%20cotizar%20mi%20evento"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label="Consultar por WhatsApp" aria-label="Contactar con MNQ por WhatsApp"
> >
<span>Consultar via WhatsApp</span> <span>Contactar por WhatsApp</span>
<span class="whatsapp-float-icon" aria-hidden="true"> <span class="whatsapp-float-icon" aria-hidden="true">
<span class="material-symbols-outlined" style="font-variation-settings: 'FILL' 1;">chat</span> <Icon name="chat" size={18} />
</span> </span>
</a> </a>
+62 -7
View File
@@ -14,33 +14,83 @@ interface Props {
title: string; title: string;
description?: string; description?: string;
activeNav?: string; activeNav?: string;
canonical?: string;
ogImage?: string;
robots?: string;
structuredData?: Record<string, unknown> | Array<Record<string, unknown>>;
} }
const { const {
title, title,
description = 'MNQ Catering y Evento · Experiencias gastronómicas premium para bodas, eventos corporativos y celebraciones familiares.', description = 'MNQ Catering y Evento · Experiencias gastronómicas premium para bodas, eventos corporativos y celebraciones familiares.',
activeNav, activeNav,
canonical,
ogImage = '/images/foto-bodas.jpg',
robots = 'index,follow',
structuredData,
} = Astro.props; } = Astro.props;
const site = Astro.site ?? new URL('https://mnq.elkazurrotaberna.es');
const canonicalUrl = new URL(canonical ?? Astro.url.pathname, site).toString();
const ogImageUrl = new URL(ogImage, site).toString();
const baseStructuredData = {
'@context': 'https://schema.org',
'@type': 'CateringService',
name: 'MNQ Catering y Evento',
url: site.origin,
description:
'Servicio de catering para bodas, eventos corporativos y reuniones familiares con enfoque premium.',
telephone: '+34 678 17 15 13',
serviceType: ['Bodas', 'Eventos corporativos', 'Reuniones familiares'],
contactPoint: {
'@type': 'ContactPoint',
contactType: 'customer service',
telephone: '+34 678 17 15 13',
availableLanguage: ['es'],
},
};
const structuredDataScripts = [
baseStructuredData,
...((Array.isArray(structuredData)
? structuredData
: structuredData
? [structuredData]
: []) as Array<Record<string, unknown>>),
];
--- ---
<!doctype html> <!doctype html>
<html lang="es-AR"> <html lang="es-ES">
<head> <head>
<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>{title}</title> <title>{title}</title>
<meta name="description" content={description} /> <meta name="description" content={description} />
<meta name="robots" content={robots} />
<link rel="canonical" href={canonicalUrl} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta property="og:url" content={canonicalUrl} />
<meta property="og:image" content={ogImageUrl} />
<meta property="og:site_name" content="MNQ Catering y Evento" />
<meta property="og:locale" content="es_ES" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={ogImageUrl} />
<link rel="icon" type="image/png" href="/images/logo-ojo-transparent.webp" /> <link rel="icon" type="image/png" href="/images/logo-ojo-transparent.webp" />
<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 <link
href="https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400&family=Inter:wght@400;500;600&display=swap" href="https://fonts.googleapis.com/css2?family=Noto+Serif:ital@0;1&family=Inter:wght@400;500;600&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap"
rel="stylesheet" rel="stylesheet"
/> />
{
structuredDataScripts.map((schema) => (
<script is:inline type="application/ld+json" set:html={JSON.stringify(schema)} />
))
}
</head> </head>
<body class="page-ready"> <body class="page-ready">
@@ -83,7 +133,7 @@ const {
const scrollTop = window.scrollY; const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight - window.innerHeight; const docHeight = document.documentElement.scrollHeight - window.innerHeight;
const progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0; const progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
progressBar.style.width = `${progress}%`; progressBar.style.transform = `scaleX(${progress / 100})`;
progressBar.setAttribute('aria-valuenow', String(Math.round(progress))); progressBar.setAttribute('aria-valuenow', String(Math.round(progress)));
}; };
window.addEventListener('scroll', updateProgress, { passive: true }); window.addEventListener('scroll', updateProgress, { passive: true });
@@ -96,6 +146,8 @@ const {
// Fade OUT: intercept internal navigation links // Fade OUT: intercept internal navigation links
const handleNavClick = (e: MouseEvent) => { const handleNavClick = (e: MouseEvent) => {
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
const target = e.target as HTMLElement; const target = e.target as HTMLElement;
const anchor = target.closest('a'); const anchor = target.closest('a');
if (!anchor) return; if (!anchor) return;
@@ -114,6 +166,9 @@ const {
} else { } else {
// Reduced motion: show immediately, no transitions // Reduced motion: show immediately, no transitions
document.querySelectorAll('.reveal, .reveal-left, .reveal-scale, .gold-line, .section-eyebrow, .value-card-animate').forEach((el) => {
el.classList.add('visible');
});
document.body.classList.add('page-ready'); document.body.classList.add('page-ready');
} }
</script> </script>
+112 -5
View File
@@ -1,11 +1,46 @@
--- ---
import MainLayout from '../layouts/MainLayout.astro'; import MainLayout from '../layouts/MainLayout.astro';
import Icon from '../components/Icon.astro';
const weddingFaqs = [
{
question: '¿Cómo se construye una propuesta de boda?',
answer:
'Partimos de la fecha, el lugar, el número estimado de invitados y el tipo de servicio deseado para plantear una propuesta personalizada.',
},
{
question: '¿El presupuesto incluye solo comida?',
answer:
'La propuesta puede contemplar cocina, servicio, menaje y necesidades de montaje, según lo que requiera la celebración.',
},
{
question: '¿Cuándo se confirma la viabilidad del evento?',
answer:
'Después de revisar disponibilidad de fecha, condiciones del espacio y necesidades logísticas del servicio.',
},
];
const weddingStructuredData = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: weddingFaqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
};
const whatsappAriaLabel = 'Contactar con MNQ por WhatsApp';
--- ---
<MainLayout <MainLayout
title="Bodas Reales | MNQ Catering y Evento" title="Bodas Reales | MNQ Catering y Evento"
description="Creamos banquetes de boda inolvidables. Menú de autor, ambientación gastronómica y servicio impecable para el día más especial de su vida." description="Creamos banquetes de boda inolvidables. Menú de autor, ambientación gastronómica y servicio impecable para el día más especial de su vida."
activeNav="bodas" activeNav="bodas"
structuredData={weddingStructuredData}
> >
<!-- ─── HERO ─── --> <!-- ─── HERO ─── -->
@@ -15,6 +50,8 @@ import MainLayout from '../layouts/MainLayout.astro';
alt="Bodas Reales — MNQ Catering" alt="Bodas Reales — MNQ Catering"
class="hero-bg" class="hero-bg"
style="object-position: center 40%;" style="object-position: center 40%;"
width="1264"
height="848"
loading="eager" loading="eager"
fetchpriority="high" fetchpriority="high"
/> />
@@ -27,6 +64,27 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
</section> </section>
<section class="section-pad-sm bg-container-low">
<div class="page-wrap">
<div class="wedding-detail-grid">
<div>
<span class="section-eyebrow">Planificación</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);">Una boda cuidada también necesita información concreta</h2>
</div>
<div class="stack-6">
<p class="text-muted" style="line-height:1.8;">
Para diseñar una propuesta coherente revisamos fecha, espacio, número aproximado de invitados, secuencia del servicio y necesidades reales de montaje. Así evitamos presupuestos genéricos y trabajamos una propuesta que responda al ritmo de la celebración.
</p>
<ul class="wedding-facts">
<li><strong>Formato:</strong> cóctel, banquete, recena o una combinación adaptada al desarrollo de la boda.</li>
<li><strong>Propuesta económica:</strong> se calcula según menú, servicio, menaje, tiempos y desplazamiento.</li>
<li><strong>Viabilidad:</strong> la confirmamos tras revisar disponibilidad y condiciones del espacio.</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ─── NARRATIVA ─── --> <!-- ─── NARRATIVA ─── -->
<section class="section-pad"> <section class="section-pad">
<div class="page-wrap"> <div class="page-wrap">
@@ -59,7 +117,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/foto-bodas.jpg" src="/images/foto-bodas.jpg"
alt="Salón de bodas dorado — MNQ" alt="Salón de bodas dorado — MNQ"
width="1264"
height="848"
style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 40%;" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 40%;"
loading="lazy"
decoding="async"
/> />
<div class="bento-card-overlay"></div> <div class="bento-card-overlay"></div>
<div class="bento-card-body"> <div class="bento-card-body">
@@ -73,7 +135,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/gallery-4.webp" src="/images/generated/gallery-4.webp"
alt="Mesa de boda con flores" alt="Mesa de boda con flores"
width="1024"
height="1024"
style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;"
loading="lazy"
decoding="async"
/> />
<div style="position:absolute;inset:0;background:linear-gradient(to top,rgb(0 0 0/55%),transparent);"></div> <div style="position:absolute;inset:0;background:linear-gradient(to top,rgb(0 0 0/55%),transparent);"></div>
<div class="bento-card-body"><span class="label-caps text-white">Detalles Florales</span></div> <div class="bento-card-body"><span class="label-caps text-white">Detalles Florales</span></div>
@@ -83,7 +149,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/gallery-1.webp" src="/images/generated/gallery-1.webp"
alt="Postre de autor" alt="Postre de autor"
width="1024"
height="1024"
style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;"
loading="lazy"
decoding="async"
/> />
<div style="position:absolute;inset:0;background:linear-gradient(to top,rgb(0 0 0/55%),transparent);"></div> <div style="position:absolute;inset:0;background:linear-gradient(to top,rgb(0 0 0/55%),transparent);"></div>
<div class="bento-card-body"><span class="label-caps text-white">Pastelería de Autor</span></div> <div class="bento-card-body"><span class="label-caps text-white">Pastelería de Autor</span></div>
@@ -106,7 +176,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<div class="grid-3 arte-mesa-grid" style="align-items: start;"> <div class="grid-3 arte-mesa-grid" style="align-items: start;">
<div style="text-align: center;"> <div style="text-align: center;">
<div class="img-zoom overflow-hidden rounded-lg reveal reveal-scale" style="--reveal-delay: 100; aspect-ratio:4/5;margin-bottom:var(--space-6);"> <div class="img-zoom overflow-hidden rounded-lg reveal reveal-scale" style="--reveal-delay: 100; aspect-ratio:4/5;margin-bottom:var(--space-6);">
<img src="/images/generated/gallery-4.webp" alt="Texturas nobles" style="width:100%;height:100%;object-fit:cover;" loading="lazy" /> <img src="/images/generated/gallery-4.webp" alt="Texturas nobles" style="width:100%;height:100%;object-fit:cover;" width="1024" height="1024" loading="lazy" decoding="async" />
</div> </div>
<h4 class="text-headline-md" style="margin-bottom:var(--space-2);">Texturas Nobles</h4> <h4 class="text-headline-md" style="margin-bottom:var(--space-2);">Texturas Nobles</h4>
<p class="text-body-sm text-muted">Linos y sedas seleccionados por su caída y tacto excepcional.</p> <p class="text-body-sm text-muted">Linos y sedas seleccionados por su caída y tacto excepcional.</p>
@@ -114,7 +184,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<div class="arte-stagger" style="text-align: center;"> <div class="arte-stagger" style="text-align: center;">
<div class="img-zoom overflow-hidden rounded-lg reveal reveal-scale" style="--reveal-delay: 250; aspect-ratio:4/5;margin-bottom:var(--space-6);"> <div class="img-zoom overflow-hidden rounded-lg reveal reveal-scale" style="--reveal-delay: 250; aspect-ratio:4/5;margin-bottom:var(--space-6);">
<img src="/images/foto-canapes.jpg" alt="Canapés premium" style="width:100%;height:100%;object-fit:cover;" loading="lazy" /> <img src="/images/foto-canapes.jpg" alt="Canapés premium" style="width:100%;height:100%;object-fit:cover;" width="1264" height="848" loading="lazy" decoding="async" />
</div> </div>
<h4 class="text-headline-md" style="margin-bottom:var(--space-2);">Cristal &amp; Oro</h4> <h4 class="text-headline-md" style="margin-bottom:var(--space-2);">Cristal &amp; Oro</h4>
<p class="text-body-sm text-muted">Detalles metálicos que aportan un brillo atemporal a su celebración.</p> <p class="text-body-sm text-muted">Detalles metálicos que aportan un brillo atemporal a su celebración.</p>
@@ -122,7 +192,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<div class="arte-stagger-2" style="text-align: center;"> <div class="arte-stagger-2" style="text-align: center;">
<div class="img-zoom overflow-hidden rounded-lg reveal reveal-scale" style="--reveal-delay: 400; aspect-ratio:4/5;margin-bottom:var(--space-6);"> <div class="img-zoom overflow-hidden rounded-lg reveal reveal-scale" style="--reveal-delay: 400; aspect-ratio:4/5;margin-bottom:var(--space-6);">
<img src="/images/generated/gallery-3.webp" alt="Platos de autor" style="width:100%;height:100%;object-fit:cover;" loading="lazy" /> <img src="/images/generated/gallery-3.webp" alt="Platos de autor" style="width:100%;height:100%;object-fit:cover;" width="1024" height="1024" loading="lazy" decoding="async" />
</div> </div>
<h4 class="text-headline-md" style="margin-bottom:var(--space-2);">Platos de Autor</h4> <h4 class="text-headline-md" style="margin-bottom:var(--space-2);">Platos de Autor</h4>
<p class="text-body-sm text-muted">Cada ingrediente es una nota en nuestra composición gastronómica.</p> <p class="text-body-sm text-muted">Cada ingrediente es una nota en nuestra composición gastronómica.</p>
@@ -176,8 +246,8 @@ import MainLayout from '../layouts/MainLayout.astro';
<div style="position:relative;z-index:10;"> <div style="position:relative;z-index:10;">
<h2 class="text-display" style="color:var(--color-inverse-on-surface);margin-bottom:var(--space-8);">¿Comenzamos a planear su gran día?</h2> <h2 class="text-display" style="color:var(--color-inverse-on-surface);margin-bottom:var(--space-8);">¿Comenzamos a planear su gran día?</h2>
<p style="color:rgb(248 240 226/80%);margin-bottom:var(--space-12);max-width:36rem;margin-inline:auto;">Solicite una asesoría personalizada y reciba un presupuesto a medida para su boda exclusiva.</p> <p style="color:rgb(248 240 226/80%);margin-bottom:var(--space-12);max-width:36rem;margin-inline:auto;">Solicite una asesoría personalizada y reciba un presupuesto a medida para su boda exclusiva.</p>
<a href="https://wa.me/34678171513?text=Hola%20MNQ%2C%20quiero%20cotizar%20una%20boda" class="btn btn-dark" target="_blank" rel="noreferrer"> <a href="https://wa.me/34678171513?text=Hola%20MNQ%2C%20quiero%20cotizar%20una%20boda" class="btn btn-dark" target="_blank" rel="noreferrer" aria-label={whatsappAriaLabel}>
<span class="material-symbols-outlined">chat</span> <Icon name="chat" />
Consultar por WhatsApp Consultar por WhatsApp
</a> </a>
</div> </div>
@@ -185,9 +255,40 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
</section> </section>
<section class="section-pad-sm">
<div class="page-wrap" style="max-width:52rem;">
<div style="margin-bottom:var(--space-8);">
<span class="section-eyebrow">Preguntas frecuentes</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);">Dudas habituales antes de solicitar una propuesta de boda</h2>
</div>
<div class="faq-list">
{weddingFaqs.map((faq) => (
<article class="faq-item">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">{faq.question}</h3>
<p class="text-muted" style="line-height:1.75;">{faq.answer}</p>
</article>
))}
</div>
</div>
</section>
</MainLayout> </MainLayout>
<style> <style>
.wedding-detail-grid,
.faq-list {
display: grid;
gap: var(--space-8);
}
.wedding-facts {
display: grid;
gap: var(--space-4);
padding-left: var(--space-6);
color: var(--color-on-surface-variant);
line-height: 1.75;
}
.bento-grid { .bento-grid {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
@@ -214,6 +315,12 @@ import MainLayout from '../layouts/MainLayout.astro';
} }
@media (min-width: 48rem) { @media (min-width: 48rem) {
.wedding-detail-grid {
grid-template-columns: 5fr 7fr;
align-items: start;
gap: var(--space-12);
}
.bento-grid { .bento-grid {
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto auto; grid-template-rows: auto auto;
+108 -7
View File
@@ -1,11 +1,46 @@
--- ---
import MainLayout from '../layouts/MainLayout.astro'; import MainLayout from '../layouts/MainLayout.astro';
import Icon from '../components/Icon.astro';
const contactFaqs = [
{
question: '¿Qué datos conviene enviar para pedir una propuesta?',
answer:
'Fecha estimada, lugar del evento, número aproximado de asistentes y el tipo de servicio que necesita.',
},
{
question: '¿Atienden bodas, eventos de empresa y celebraciones familiares?',
answer:
'Sí. Trabajamos propuestas a medida para bodas, formatos corporativos y encuentros familiares con necesidades distintas de servicio y montaje.',
},
{
question: '¿Cómo se confirma la cobertura de un evento?',
answer:
'La revisamos caso a caso según fecha, desplazamiento, formato del servicio y necesidades logísticas del espacio.',
},
];
const contactStructuredData = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: contactFaqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
};
const whatsappAriaLabel = 'Contactar con MNQ por WhatsApp';
--- ---
<MainLayout <MainLayout
title="Contacto | MNQ Catering y Evento" title="Contacto | MNQ Catering y Evento"
description="Hablemos de su próximo evento. Diseñamos experiencias gastronómicas a medida para bodas, corporativos y celebraciones familiares." description="Hablemos de su próximo evento. Diseñamos experiencias gastronómicas a medida para bodas, corporativos y celebraciones familiares."
activeNav="contacto" activeNav="contacto"
structuredData={contactStructuredData}
> >
<!-- ─── HERO ─── --> <!-- ─── HERO ─── -->
@@ -21,12 +56,17 @@ import MainLayout from '../layouts/MainLayout.astro';
<p class="text-muted" style="line-height: 1.7; max-width: 32rem;"> <p class="text-muted" style="line-height: 1.7; max-width: 32rem;">
Diseñamos experiencias gastronómicas a medida. Permítanos conocer sus necesidades para crear una propuesta única y exclusiva. Diseñamos experiencias gastronómicas a medida. Permítanos conocer sus necesidades para crear una propuesta única y exclusiva.
</p> </p>
<p class="text-body-sm" style="margin-top:var(--space-6);max-width:34rem;color:var(--color-on-surface-variant);line-height:1.75;">
Atendemos cada solicitud con validación previa de fecha, formato del servicio y desplazamiento. Si comparte el lugar del evento y el número estimado de asistentes, podremos orientarle con más precisión desde el primer contacto.
</p>
</div> </div>
<div class="contacto-hero-img overflow-hidden rounded-lg"> <div class="contacto-hero-img overflow-hidden rounded-lg">
<img <img
src="/images/foto-bodas.jpg" src="/images/foto-bodas.jpg"
alt="MNQ Catering — salón de eventos premium" alt="MNQ Catering — salón de eventos premium"
width="1264"
height="848"
style="width:100%;height:100%;object-fit:cover;object-position:center 35%;" style="width:100%;height:100%;object-fit:cover;object-position:center 35%;"
loading="eager" loading="eager"
fetchpriority="high" fetchpriority="high"
@@ -48,23 +88,23 @@ import MainLayout from '../layouts/MainLayout.astro';
<div class="stack-4"> <div class="stack-4">
<span class="label-caps text-primary">Teléfono</span> <span class="label-caps text-primary">Teléfono</span>
<div style="display:flex;align-items:center;gap:var(--space-4);"> <div style="display:flex;align-items:center;gap:var(--space-4);">
<span class="material-symbols-outlined text-primary">call</span> <Icon name="call" class="text-primary" />
<p class="text-muted">+34 678 17 15 13</p> <a class="text-muted contact-link" href="tel:+34678171513">+34 678 17 15 13</a>
</div> </div>
</div> </div>
<div class="stack-4"> <div class="stack-4">
<span class="label-caps text-primary">Email</span> <span class="label-caps text-primary">Sitio web</span>
<div style="display:flex;align-items:center;gap:var(--space-4);"> <div style="display:flex;align-items:center;gap:var(--space-4);">
<span class="material-symbols-outlined text-primary">mail</span> <Icon name="language" class="text-primary" />
<p class="text-muted">eventos@mnqcatering.com</p> <a class="text-muted contact-link" href="https://mnq.elkazurrotaberna.es">mnq.elkazurrotaberna.es</a>
</div> </div>
</div> </div>
<div class="stack-4"> <div class="stack-4">
<span class="label-caps text-primary">WhatsApp</span> <span class="label-caps text-primary">WhatsApp</span>
<div style="display:flex;align-items:center;gap:var(--space-4);"> <div style="display:flex;align-items:center;gap:var(--space-4);">
<span class="material-symbols-outlined text-primary">chat</span> <Icon name="chat" class="text-primary" />
<p class="text-muted">Canal exclusivo de atención</p> <p class="text-muted">Canal exclusivo de atención</p>
</div> </div>
</div> </div>
@@ -80,6 +120,7 @@ import MainLayout from '../layouts/MainLayout.astro';
class="btn btn-primary" class="btn btn-primary"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
style="width:fit-content;" style="width:fit-content;"
> >
Iniciar por WhatsApp Iniciar por WhatsApp
@@ -131,7 +172,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<div class="form-span-full" style="display:flex;justify-content:flex-end;"> <div class="form-span-full" style="display:flex;justify-content:flex-end;">
<button type="submit" class="btn-underline" style="display:inline-flex;align-items:center;gap:var(--space-3);"> <button type="submit" class="btn-underline" style="display:inline-flex;align-items:center;gap:var(--space-3);">
Enviar Solicitud Enviar Solicitud
<span class="material-symbols-outlined">arrow_forward</span> <Icon name="arrow-forward" />
</button> </button>
</div> </div>
@@ -142,6 +183,49 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
</section> </section>
<section class="section-pad-sm bg-container-low">
<div class="page-wrap">
<div class="contact-detail-grid">
<div>
<span class="section-eyebrow">Cobertura y planificación</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);margin-bottom:var(--space-6);">Cómo confirmamos la viabilidad de cada evento</h2>
</div>
<div class="stack-6">
<p class="text-muted" style="line-height:1.8;">
No trabajamos con una cobertura automática ni con propuestas cerradas. Cada servicio se estudia según la ubicación del evento, la fecha disponible, el volumen de invitados y las necesidades reales de montaje o servicio.
</p>
<div class="grid-2" style="gap:var(--space-6);">
<div class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Qué necesitamos para orientarle</h3>
<p class="text-body-sm text-muted">Fecha estimada, lugar, horario, asistentes y tipo de servicio. Con esa base podemos indicarle el encaje del evento y el siguiente paso comercial.</p>
</div>
<div class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Cómo planteamos el presupuesto</h3>
<p class="text-body-sm text-muted">La propuesta se ajusta al formato gastronómico, personal necesario, menaje, tiempos de servicio y desplazamiento previsto para su celebración.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="section-pad-sm">
<div class="page-wrap" style="max-width:52rem;">
<div style="margin-bottom:var(--space-8);">
<span class="section-eyebrow">Preguntas frecuentes</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);">Información útil antes de escribirnos</h2>
</div>
<div class="faq-list">
{contactFaqs.map((faq) => (
<article class="faq-item">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">{faq.question}</h3>
<p class="text-muted" style="line-height:1.75;">{faq.answer}</p>
</article>
))}
</div>
</div>
</section>
</MainLayout> </MainLayout>
<style> <style>
@@ -172,6 +256,17 @@ import MainLayout from '../layouts/MainLayout.astro';
gap: var(--space-8); gap: var(--space-8);
} }
.contact-link {
text-decoration: underline;
text-underline-offset: 0.2em;
}
.contact-detail-grid,
.faq-list {
display: grid;
gap: var(--space-8);
}
@media (min-width: 48rem) { @media (min-width: 48rem) {
.contacto-hero { .contacto-hero {
padding-top: calc(var(--nav-h) + var(--space-section)); padding-top: calc(var(--nav-h) + var(--space-section));
@@ -189,5 +284,11 @@ import MainLayout from '../layouts/MainLayout.astro';
align-items: start; align-items: start;
gap: var(--space-16); gap: var(--space-16);
} }
.contact-detail-grid {
grid-template-columns: 5fr 7fr;
align-items: start;
gap: var(--space-12);
}
} }
</style> </style>
+2 -1
View File
@@ -5,6 +5,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<MainLayout <MainLayout
title="Política de Cookies | MNQ Catering y Evento" title="Política de Cookies | MNQ Catering y Evento"
description="Información sobre el uso de cookies en el sitio web de MNQ Catering y Evento." description="Información sobre el uso de cookies en el sitio web de MNQ Catering y Evento."
robots="noindex,follow"
> >
<section style="padding-top: calc(var(--nav-h) + var(--space-section)); padding-bottom: var(--space-section);"> <section style="padding-top: calc(var(--nav-h) + var(--space-section)); padding-bottom: var(--space-section);">
@@ -57,7 +58,7 @@ import MainLayout from '../layouts/MainLayout.astro';
</button> </button>
<h2>Más información</h2> <h2>Más información</h2>
<p>Para cualquier consulta sobre nuestra política de cookies, puede contactarnos en <strong>eventos@mnqcatering.com</strong>. Consulte también nuestra <a href="/privacidad">Política de Privacidad</a>.</p> <p>Para cualquier consulta sobre nuestra política de cookies, puede contactarnos por teléfono o WhatsApp en <a href="tel:+34678171513"><strong>+34 678 17 15 13</strong></a>. Consulte también nuestra <a href="/privacidad">Política de Privacidad</a> y la página de <a href="/contacto">Contacto</a>.</p>
</div> </div>
+135 -13
View File
@@ -1,11 +1,45 @@
--- ---
import MainLayout from '../layouts/MainLayout.astro'; import MainLayout from '../layouts/MainLayout.astro';
const whatsappAriaLabel = 'Contactar con MNQ por WhatsApp';
const corporateFaqs = [
{
question: '¿Qué información necesitan para preparar una propuesta corporativa?',
answer:
'Fecha, ubicación, horario, número estimado de asistentes y el formato previsto: coffee break, cóctel, comida o cena.',
},
{
question: '¿La propuesta se adapta a la imagen y al ritmo del evento?',
answer:
'Sí. Ajustamos servicio, montaje y secuencia gastronómica al objetivo del encuentro y a la dinámica de la jornada.',
},
{
question: '¿Cómo valoran la cobertura de un evento de empresa?',
answer:
'La confirmamos según disponibilidad de fecha, desplazamiento, complejidad logística del espacio y necesidades reales de producción.',
},
];
const corporateStructuredData = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: corporateFaqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
};
--- ---
<MainLayout <MainLayout
title="Corporativo & Business | MNQ Catering y Evento" title="Corporativo & Business | MNQ Catering y Evento"
description="Elevamos la imagen de su empresa a través de experiencias gastronómicas impecables. Lanzamientos, galas institucionales y coffee breaks premium." description="Elevamos la imagen de su empresa a través de experiencias gastronómicas impecables. Lanzamientos, galas institucionales y coffee breaks premium."
activeNav="corporativo" activeNav="corporativo"
structuredData={corporateStructuredData}
> >
<!-- ─── HERO ─── --> <!-- ─── HERO ─── -->
@@ -20,7 +54,7 @@ import MainLayout from '../layouts/MainLayout.astro';
Elevamos la imagen de su empresa a través de experiencias gastronómicas impecables. Desde lanzamientos de marca disruptivos hasta galas institucionales de alto nivel. Elevamos la imagen de su empresa a través de experiencias gastronómicas impecables. Desde lanzamientos de marca disruptivos hasta galas institucionales de alto nivel.
</p> </p>
<div class="corp-hero-actions"> <div class="corp-hero-actions">
<a href="https://wa.me/34678171513?text=Hola%20MNQ%2C%20quiero%20propuesta%20corporativa" class="btn btn-primary" target="_blank" rel="noreferrer">Solicitar Propuesta</a> <a href="https://wa.me/34678171513?text=Hola%20MNQ%2C%20quiero%20propuesta%20corporativa" class="btn btn-primary" target="_blank" rel="noreferrer" aria-label={whatsappAriaLabel}>Solicitar Propuesta</a>
<a href="#servicios" class="btn-underline">Ver Servicios</a> <a href="#servicios" class="btn-underline">Ver Servicios</a>
</div> </div>
</div> </div>
@@ -30,8 +64,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/foto-corporativo.jpg" src="/images/foto-corporativo.jpg"
alt="Eventos corporativos premium — MNQ" alt="Eventos corporativos premium — MNQ"
width="1264"
height="848"
style="width:100%;height:100%;object-fit:cover;object-position:center top;" style="width:100%;height:100%;object-fit:cover;object-position:center top;"
loading="eager" loading="eager"
fetchpriority="high"
/> />
</div> </div>
</div> </div>
@@ -51,7 +88,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<div class="corp-bento"> <div class="corp-bento">
<div class="bento-card corp-wide"> <div class="bento-card corp-wide">
<img src="/images/foto-corporativo.jpg" alt="Lanzamientos de marca" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 25%;" loading="lazy" /> <img src="/images/foto-corporativo.jpg" alt="Lanzamientos de marca" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 25%;" width="1264" height="848" loading="lazy" decoding="async" />
<div class="bento-card-overlay"></div> <div class="bento-card-overlay"></div>
<div class="bento-card-body"> <div class="bento-card-body">
<h3 class="text-headline-md" style="color:var(--color-on-surface);">Lanzamientos de Marca</h3> <h3 class="text-headline-md" style="color:var(--color-on-surface);">Lanzamientos de Marca</h3>
@@ -60,7 +97,7 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
<div class="bento-card corp-tall"> <div class="bento-card corp-tall">
<img src="/images/generated/gallery-2.webp" alt="Coffee Breaks Premium" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top;" loading="lazy" /> <img src="/images/generated/gallery-2.webp" alt="Coffee Breaks Premium" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top;" width="1024" height="1024" loading="lazy" decoding="async" />
<div class="bento-card-overlay"></div> <div class="bento-card-overlay"></div>
<div class="bento-card-body"> <div class="bento-card-body">
<h3 class="text-headline-md" style="color:var(--color-on-surface);">Coffee Breaks Premium</h3> <h3 class="text-headline-md" style="color:var(--color-on-surface);">Coffee Breaks Premium</h3>
@@ -69,7 +106,7 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
<div class="bento-card corp-wide"> <div class="bento-card corp-wide">
<img src="/images/foto-bodas.jpg" alt="Galas y Cenas Anuales" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 40%;" loading="lazy" /> <img src="/images/foto-bodas.jpg" alt="Galas y Cenas Anuales" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 40%;" width="1264" height="848" loading="lazy" decoding="async" />
<div class="bento-card-overlay"></div> <div class="bento-card-overlay"></div>
<div class="bento-card-body"> <div class="bento-card-body">
<h3 class="text-headline-md" style="color:var(--color-on-surface);">Galas &amp; Cenas Anuales</h3> <h3 class="text-headline-md" style="color:var(--color-on-surface);">Galas &amp; Cenas Anuales</h3>
@@ -81,16 +118,54 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
</section> </section>
<!-- ─── EMPRESAS ─── --> <!-- ─── PRUEBA OPERATIVA ─── -->
<section class="section-pad-sm bg-surface"> <section class="section-pad-sm bg-surface">
<div class="page-wrap" style="text-align:center;"> <div class="page-wrap">
<p class="label-caps text-muted" style="margin-bottom:var(--space-12);opacity:0.8;">Empresas que confían en nuestra visión</p> <div class="trust-grid">
<div style="display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:var(--space-16);opacity:0.4;filter:grayscale(1);"> <div>
<span style="font-size:1.5rem;font-weight:700;letter-spacing:0.2em;color:var(--color-on-surface-variant);">LUMINA</span> <p class="label-caps text-muted" style="margin-bottom:var(--space-4);opacity:0.8;">Coordinación corporativa</p>
<span style="font-size:1.5rem;font-style:italic;color:var(--color-on-surface-variant);">Vanguard</span> <h2 class="text-headline-lg">La confianza empieza por una ejecución clara</h2>
<span style="font-size:1.5rem;font-weight:900;text-transform:uppercase;color:var(--color-on-surface-variant);">Ethereal.</span> </div>
<span style="font-size:1.5rem;color:var(--color-on-surface-variant);">Nordic Corp</span> <div class="stack-6">
<span style="font-size:1.5rem;letter-spacing:-0.03em;color:var(--color-on-surface-variant);">Apex Sol.</span> <p class="text-muted" style="line-height:1.8;">
Cuando un evento representa a una marca, la propuesta gastronómica debe responder al briefing, al ritmo de la agenda y a las exigencias del espacio. Por eso priorizamos planificación, timing de servicio y una puesta en escena alineada con el contexto del encuentro.
</p>
<div class="trust-cards">
<article class="bg-container rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Briefing previo</h3>
<p class="text-body-sm text-muted">Revisamos formato, asistentes, horarios y expectativas de marca antes de emitir la propuesta.</p>
</article>
<article class="bg-container rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Servicio coordinado</h3>
<p class="text-body-sm text-muted">Ajustamos cocina, personal, menaje y secuencia de pases al ritmo real del evento.</p>
</article>
<article class="bg-container rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Cobertura confirmada</h3>
<p class="text-body-sm text-muted">La viabilidad final se valida según desplazamiento, montaje necesario y condicionantes del espacio.</p>
</article>
</div>
</div>
</div>
</div>
</section>
<section class="section-pad-sm bg-surface">
<div class="page-wrap">
<div class="trust-grid">
<div>
<span class="section-eyebrow">Qué puede esperar</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);">Propuestas pensadas para equipos, invitados y tiempos reales</h2>
</div>
<div class="stack-6">
<p class="text-muted" style="line-height:1.8;">
Diseñamos cada presupuesto según el formato de servicio, el número previsto de asistentes, la franja horaria, el personal necesario y la logística del venue. Esto nos permite presentar una propuesta coherente en lugar de una tarifa genérica que luego no encaja en producción.
</p>
<ul class="corp-facts">
<li><strong>Formatos habituales:</strong> coffee break, cóctel, comida de empresa, cena institucional y activaciones con servicio gastronómico.</li>
<li><strong>Presupuesto:</strong> siempre se calcula a medida según servicio, menaje, personal y desplazamiento.</li>
<li><strong>Planificación:</strong> cuanto más completo sea el briefing inicial, más afinada será la primera propuesta comercial.</li>
</ul>
</div>
</div> </div>
</div> </div>
</section> </section>
@@ -139,9 +214,45 @@ import MainLayout from '../layouts/MainLayout.astro';
<div style="position:absolute;top:0;right:-4rem;width:30%;height:100%;background:rgb(208 197 175/10%);transform:skewX(-10deg);pointer-events:none;"></div> <div style="position:absolute;top:0;right:-4rem;width:30%;height:100%;background:rgb(208 197 175/10%);transform:skewX(-10deg);pointer-events:none;"></div>
</section> </section>
<section class="section-pad-sm">
<div class="page-wrap" style="max-width:52rem;">
<div style="margin-bottom:var(--space-8);">
<span class="section-eyebrow">Preguntas frecuentes</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);">Dudas habituales en eventos de empresa</h2>
</div>
<div class="faq-list">
{corporateFaqs.map((faq) => (
<article class="faq-item">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">{faq.question}</h3>
<p class="text-muted" style="line-height:1.75;">{faq.answer}</p>
</article>
))}
</div>
</div>
</section>
</MainLayout> </MainLayout>
<style> <style>
.trust-grid,
.trust-cards,
.faq-list {
display: grid;
gap: var(--space-8);
}
.trust-cards {
grid-template-columns: 1fr;
}
.corp-facts {
display: grid;
gap: var(--space-4);
padding-left: var(--space-6);
color: var(--color-on-surface-variant);
line-height: 1.75;
}
.corp-bento { .corp-bento {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
@@ -165,6 +276,17 @@ import MainLayout from '../layouts/MainLayout.astro';
} }
@media (min-width: 48rem) { @media (min-width: 48rem) {
.trust-grid {
grid-template-columns: 5fr 7fr;
align-items: start;
gap: var(--space-12);
}
.trust-cards {
grid-template-columns: repeat(3, 1fr);
gap: var(--space-6);
}
.corp-bento { .corp-bento {
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
grid-template-rows: 22rem 22rem; grid-template-rows: 22rem 22rem;
+91 -17
View File
@@ -1,5 +1,8 @@
--- ---
import MainLayout from '../layouts/MainLayout.astro'; import MainLayout from '../layouts/MainLayout.astro';
import Icon from '../components/Icon.astro';
const whatsappAriaLabel = 'Contactar con MNQ por WhatsApp';
--- ---
<MainLayout title="MNQ Catering y Evento | Excelencia Culinaria"> <MainLayout title="MNQ Catering y Evento | Excelencia Culinaria">
@@ -11,6 +14,8 @@ import MainLayout from '../layouts/MainLayout.astro';
alt="MNQ Catering — salón de bodas premium" alt="MNQ Catering — salón de bodas premium"
class="hero-bg" class="hero-bg"
style="object-position: center 30%;" style="object-position: center 30%;"
width="1264"
height="848"
loading="eager" loading="eager"
fetchpriority="high" fetchpriority="high"
/> />
@@ -28,13 +33,44 @@ import MainLayout from '../layouts/MainLayout.astro';
class="btn btn-ghost hero-enter-3" class="btn btn-ghost hero-enter-3"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
> >
Explorar Servicios Consultar por WhatsApp
</a> </a>
</div> </div>
</div> </div>
</section> </section>
<section class="section-pad-sm bg-container-low">
<div class="page-wrap">
<div class="coverage-grid">
<div>
<span class="section-eyebrow reveal">Cobertura y propuesta</span>
<h2 class="text-headline-lg reveal" style="--reveal-delay:150;margin-top:var(--space-4);">Servicio planificado según ubicación, formato y ritmo del evento</h2>
</div>
<div class="stack-6 reveal" style="--reveal-delay:250;">
<p class="text-muted" style="line-height:1.8;">
Cada proyecto se valora de forma individual. Confirmamos la viabilidad según la fecha, el número de asistentes, el tipo de servicio y el desplazamiento necesario para ejecutar el evento con el nivel de detalle que exige MNQ.
</p>
<div class="coverage-cards">
<article class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Eventos a medida</h3>
<p class="text-body-sm text-muted">No trabajamos con paquetes cerrados. La propuesta nace del formato gastronómico, la logística y el tono de la celebración.</p>
</article>
<article class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Cobertura a confirmar</h3>
<p class="text-body-sm text-muted">La cobertura final se valida caso a caso para asegurar montaje, tiempos de servicio y desplazamiento coherentes con el evento.</p>
</article>
<article class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Respuesta comercial directa</h3>
<p class="text-body-sm text-muted">WhatsApp y teléfono siguen siendo el canal más rápido para contrastar disponibilidad y perfilar la solicitud inicial.</p>
</article>
</div>
</div>
</div>
</div>
</section>
<!-- ─── SERVICIOS EDITORIAL GRID ─── --> <!-- ─── SERVICIOS EDITORIAL GRID ─── -->
<section class="section-pad"> <section class="section-pad">
<div class="page-wrap"> <div class="page-wrap">
@@ -51,12 +87,15 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/hero-bodas-gen.webp" src="/images/generated/hero-bodas-gen.webp"
alt="Bodas Reales — MNQ Catering" alt="Bodas Reales — MNQ Catering"
width="1264"
height="848"
style="width:100%;height:100%;object-fit:cover;object-position:center top;transition:transform 700ms ease;" style="width:100%;height:100%;object-fit:cover;object-position:center top;transition:transform 700ms ease;"
loading="lazy"
onmouseenter="this.style.transform='scale(1.05)'" onmouseenter="this.style.transform='scale(1.05)'"
onmouseleave="this.style.transform='scale(1)'" onmouseleave="this.style.transform='scale(1)'"
/> />
</div> </div>
<div style="display: flex; flex-direction: column; gap: var(--space-3);" class="reveal" style="--reveal-delay: 300;"> <div class="reveal" style="display: flex; flex-direction: column; gap: var(--space-3); --reveal-delay: 300;">
<h3 class="text-headline-md">Bodas</h3> <h3 class="text-headline-md">Bodas</h3>
<p class="text-muted">El arte de celebrar el amor con un banquete inolvidable diseñado hasta el último detalle.</p> <p class="text-muted">El arte de celebrar el amor con un banquete inolvidable diseñado hasta el último detalle.</p>
<a href="/bodas-reales" class="btn-underline" style="width: fit-content;">Saber más</a> <a href="/bodas-reales" class="btn-underline" style="width: fit-content;">Saber más</a>
@@ -69,12 +108,15 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/foto-corporativo.jpg" src="/images/foto-corporativo.jpg"
alt="Corporativo — MNQ Catering" alt="Corporativo — MNQ Catering"
width="1264"
height="848"
style="width:100%;height:100%;object-fit:cover;object-position:center top;transition:transform 700ms ease;" style="width:100%;height:100%;object-fit:cover;object-position:center top;transition:transform 700ms ease;"
loading="lazy"
onmouseenter="this.style.transform='scale(1.05)'" onmouseenter="this.style.transform='scale(1.05)'"
onmouseleave="this.style.transform='scale(1)'" onmouseleave="this.style.transform='scale(1)'"
/> />
</div> </div>
<div style="display: flex; flex-direction: column; gap: var(--space-3);" class="reveal" style="--reveal-delay: 450;"> <div class="reveal" style="display: flex; flex-direction: column; gap: var(--space-3); --reveal-delay: 450;">
<h3 class="text-headline-md">Eventos Corporativos</h3> <h3 class="text-headline-md">Eventos Corporativos</h3>
<p class="text-muted">Reforzamos la identidad de su empresa a través de una propuesta culinaria de primer nivel.</p> <p class="text-muted">Reforzamos la identidad de su empresa a través de una propuesta culinaria de primer nivel.</p>
<a href="/corporativo-business" class="btn-underline" style="width: fit-content;">Saber más</a> <a href="/corporativo-business" class="btn-underline" style="width: fit-content;">Saber más</a>
@@ -87,12 +129,15 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/hero-familiares-gen.webp" src="/images/generated/hero-familiares-gen.webp"
alt="Reuniones Familiares — MNQ Catering" alt="Reuniones Familiares — MNQ Catering"
width="1376"
height="768"
style="width:100%;height:100%;object-fit:cover;object-position:center top;transition:transform 700ms ease;" style="width:100%;height:100%;object-fit:cover;object-position:center top;transition:transform 700ms ease;"
loading="lazy"
onmouseenter="this.style.transform='scale(1.05)'" onmouseenter="this.style.transform='scale(1.05)'"
onmouseleave="this.style.transform='scale(1)'" onmouseleave="this.style.transform='scale(1)'"
/> />
</div> </div>
<div style="display: flex; flex-direction: column; gap: var(--space-3);" class="reveal" style="--reveal-delay: 600;"> <div class="reveal" style="display: flex; flex-direction: column; gap: var(--space-3); --reveal-delay: 600;">
<h3 class="text-headline-md">Reuniones Familiares</h3> <h3 class="text-headline-md">Reuniones Familiares</h3>
<p class="text-muted">La calidez del hogar elevada por la excelencia de nuestra cocina de autor.</p> <p class="text-muted">La calidez del hogar elevada por la excelencia de nuestra cocina de autor.</p>
<a href="/reuniones-familiares" class="btn-underline" style="width: fit-content;">Saber más</a> <a href="/reuniones-familiares" class="btn-underline" style="width: fit-content;">Saber más</a>
@@ -117,12 +162,12 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
<div class="mosaic"> <div class="mosaic">
<img src="/images/generated/gallery-1.webp" alt="Postre de autor con oro" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 100;" loading="lazy" /> <img src="/images/generated/gallery-1.webp" alt="Postre de autor con oro" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 100;" width="1024" height="1024" loading="lazy" decoding="async" />
<img src="/images/foto-canapes.jpg" alt="Canapés premium" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 200;" loading="lazy" /> <img src="/images/foto-canapes.jpg" alt="Canapés premium" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 200;" width="1264" height="848" loading="lazy" decoding="async" />
<img src="/images/generated/gallery-3.webp" alt="Vieiras con azafrán" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 300;" loading="lazy" /> <img src="/images/generated/gallery-3.webp" alt="Vieiras con azafrán" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 300;" width="1024" height="1024" loading="lazy" decoding="async" />
<img src="/images/generated/gallery-4.webp" alt="Mesa de boda" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 400;" loading="lazy" /> <img src="/images/generated/gallery-4.webp" alt="Mesa de boda" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 400;" width="1024" height="1024" loading="lazy" decoding="async" />
<img src="/images/foto-plato-mnq.jpg" alt="Plato MNQ Catering" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 500;" loading="lazy" /> <img src="/images/foto-plato-mnq.jpg" alt="Plato MNQ Catering" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 500;" width="1200" height="805" loading="lazy" decoding="async" />
<img src="/images/generated/gallery-2.webp" alt="Bartender de coctelería" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 600;" loading="lazy" /> <img src="/images/generated/gallery-2.webp" alt="Bartender de coctelería" class="rounded-lg reveal-scale reveal" style="--reveal-delay: 600;" width="1024" height="1024" loading="lazy" decoding="async" />
</div> </div>
</div> </div>
</section> </section>
@@ -179,6 +224,8 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/logo-monograma.webp" src="/images/logo-monograma.webp"
alt="MNQ" alt="MNQ"
width="500"
height="188"
style="height: 5rem; width: auto; margin-inline: auto; display: block;" style="height: 5rem; width: auto; margin-inline: auto; display: block;"
/> />
</div> </div>
@@ -194,8 +241,9 @@ import MainLayout from '../layouts/MainLayout.astro';
class="btn btn-dark" class="btn btn-dark"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
> >
<span class="material-symbols-outlined">chat</span> <Icon name="chat" />
Consultar por WhatsApp Consultar por WhatsApp
</a> </a>
</div> </div>
@@ -206,7 +254,39 @@ import MainLayout from '../layouts/MainLayout.astro';
</MainLayout> </MainLayout>
<style> <style>
.coverage-grid,
.coverage-cards,
.services-grid {
display: grid;
}
.coverage-grid,
.coverage-cards {
gap: var(--space-8);
}
.coverage-cards {
grid-template-columns: 1fr;
}
.services-grid {
grid-template-columns: 1fr;
gap: var(--space-8);
align-items: start;
}
@media (min-width: 48rem) { @media (min-width: 48rem) {
.coverage-grid {
grid-template-columns: 5fr 7fr;
align-items: start;
gap: var(--space-12);
}
.coverage-cards {
grid-template-columns: repeat(3, 1fr);
gap: var(--space-6);
}
.services-grid { .services-grid {
display: grid !important; display: grid !important;
grid-template-columns: repeat(3, 1fr) !important; grid-template-columns: repeat(3, 1fr) !important;
@@ -214,10 +294,4 @@ import MainLayout from '../layouts/MainLayout.astro';
.col-stagger { margin-top: var(--space-24); } .col-stagger { margin-top: var(--space-24); }
#gallery-quote { display: block !important; } #gallery-quote { display: block !important; }
} }
.services-grid {
display: grid;
grid-template-columns: 1fr;
gap: var(--space-8);
align-items: start;
}
</style> </style>
+47 -9
View File
@@ -1,5 +1,42 @@
--- ---
import MainLayout from '../layouts/MainLayout.astro'; import MainLayout from '../layouts/MainLayout.astro';
import Icon from '../components/Icon.astro';
const teamMembers = [
{
nombre: 'Mateo Navarro',
rol: 'Director Ejecutivo',
src: '/images/generated/gallery-2.webp',
pos: 'center top',
width: 1024,
height: 1024,
},
{
nombre: 'Lucía Quintana',
rol: 'Chef Creativa',
src: '/images/generated/hero-nosotros-gen.webp',
pos: 'center top',
width: 1264,
height: 848,
},
{
nombre: 'Julián Marín',
rol: 'Head Sommelier',
src: '/images/foto-canapes.jpg',
pos: 'center 30%',
width: 1264,
height: 848,
},
{
nombre: 'Elena Soler',
rol: 'Diseño de Experiencias',
src: '/images/foto-plato-mnq.jpg',
pos: 'center top',
width: 1200,
height: 805,
},
];
--- ---
<MainLayout <MainLayout
@@ -26,8 +63,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/hero-nosotros-gen.webp" src="/images/generated/hero-nosotros-gen.webp"
alt="Chef ejecutiva MNQ — el arte de la hospitalidad" alt="Chef ejecutiva MNQ — el arte de la hospitalidad"
width="1264"
height="848"
style="width:100%;height:100%;object-fit:cover;object-position:center top;" style="width:100%;height:100%;object-fit:cover;object-position:center top;"
loading="eager" loading="eager"
fetchpriority="high"
/> />
</div> </div>
<div class="quote-card-desktop border-outline-soft" style="position:absolute;bottom:-2.5rem;left:-2.5rem;background:var(--color-surface-container);padding:var(--space-10);display:none;"> <div class="quote-card-desktop border-outline-soft" style="position:absolute;bottom:-2.5rem;left:-2.5rem;background:var(--color-surface-container);padding:var(--space-10);display:none;">
@@ -64,17 +104,17 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
<div class="grid-3"> <div class="grid-3">
<div class="value-card value-card-animate" data-value-delay="0"> <div class="value-card value-card-animate" data-value-delay="0">
<span class="material-symbols-outlined text-primary icon-lg">verified</span> <Icon name="verified" class="text-primary icon-lg" />
<h3 class="text-headline-md">Calidad</h3> <h3 class="text-headline-md">Calidad</h3>
<p class="text-body-sm text-muted leading-relaxed">Innegociable. Desde la frescura del producto hasta el último detalle del servicio de sala.</p> <p class="text-body-sm text-muted leading-relaxed">Innegociable. Desde la frescura del producto hasta el último detalle del servicio de sala.</p>
</div> </div>
<div class="value-card value-card-animate" data-value-delay="150"> <div class="value-card value-card-animate" data-value-delay="150">
<span class="material-symbols-outlined text-primary icon-lg">history_edu</span> <Icon name="history-edu" class="text-primary icon-lg" />
<h3 class="text-headline-md">Tradición</h3> <h3 class="text-headline-md">Tradición</h3>
<p class="text-body-sm text-muted leading-relaxed">Honramos las técnicas clásicas que han forjado la gran cocina, aplicándolas con respeto.</p> <p class="text-body-sm text-muted leading-relaxed">Honramos las técnicas clásicas que han forjado la gran cocina, aplicándolas con respeto.</p>
</div> </div>
<div class="value-card value-card-animate" data-value-delay="300"> <div class="value-card value-card-animate" data-value-delay="300">
<span class="material-symbols-outlined text-primary icon-lg">architecture</span> <Icon name="architecture" class="text-primary icon-lg" />
<h3 class="text-headline-md">Vanguardia</h3> <h3 class="text-headline-md">Vanguardia</h3>
<p class="text-body-sm text-muted leading-relaxed">Innovamos en presentaciones y texturas para sorprender a los paladares contemporáneos.</p> <p class="text-body-sm text-muted leading-relaxed">Innovamos en presentaciones y texturas para sorprender a los paladares contemporáneos.</p>
</div> </div>
@@ -94,19 +134,17 @@ import MainLayout from '../layouts/MainLayout.astro';
</div> </div>
<div class="grid-4"> <div class="grid-4">
{[ {teamMembers.map(({ nombre, rol, src, pos, width, height }) => (
{ nombre: 'Mateo Navarro', rol: 'Director Ejecutivo', src: '/images/generated/gallery-2.webp', pos: 'center top' },
{ nombre: 'Lucía Quintana', rol: 'Chef Creativa', src: '/images/generated/hero-nosotros-gen.webp', pos: 'center top' },
{ nombre: 'Julián Marín', rol: 'Head Sommelier', src: '/images/foto-canapes.jpg', pos: 'center 30%' },
{ nombre: 'Elena Soler', rol: 'Diseño de Experiencias', src: '/images/foto-plato-mnq.jpg', pos: 'center top' },
].map(({ nombre, rol, src, pos }) => (
<div style="display:flex;flex-direction:column;gap:var(--space-6);"> <div style="display:flex;flex-direction:column;gap:var(--space-6);">
<div class="overflow-hidden team-card" style="aspect-ratio:3/4;"> <div class="overflow-hidden team-card" style="aspect-ratio:3/4;">
<img <img
src={src} src={src}
alt={nombre} alt={nombre}
width={width}
height={height}
style={`width:100%;height:100%;object-fit:cover;object-position:${pos};filter:grayscale(1);transition:filter 700ms;`} style={`width:100%;height:100%;object-fit:cover;object-position:${pos};filter:grayscale(1);transition:filter 700ms;`}
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
<div> <div>
+4 -3
View File
@@ -5,6 +5,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<MainLayout <MainLayout
title="Política de Privacidad | MNQ Catering y Evento" title="Política de Privacidad | MNQ Catering y Evento"
description="Política de privacidad y protección de datos de MNQ Catering y Evento." description="Política de privacidad y protección de datos de MNQ Catering y Evento."
robots="noindex,follow"
> >
<section style="padding-top: calc(var(--nav-h) + var(--space-section)); padding-bottom: var(--space-section);"> <section style="padding-top: calc(var(--nav-h) + var(--space-section)); padding-bottom: var(--space-section);">
@@ -19,8 +20,8 @@ import MainLayout from '../layouts/MainLayout.astro';
<h2>1. Responsable del Tratamiento</h2> <h2>1. Responsable del Tratamiento</h2>
<p> <p>
<strong>MNQ Catering y Evento</strong><br /> <strong>MNQ Catering y Evento</strong><br />
Teléfono: +34 678 17 15 13<br /> Teléfono: <a href="tel:+34678171513">+34 678 17 15 13</a><br />
Email: eventos@mnqcatering.com Sitio web: <a href="https://mnq.elkazurrotaberna.es">mnq.elkazurrotaberna.es</a>
</p> </p>
<h2>2. Datos que Recopilamos</h2> <h2>2. Datos que Recopilamos</h2>
@@ -60,7 +61,7 @@ import MainLayout from '../layouts/MainLayout.astro';
<li><strong>Portabilidad:</strong> recibir sus datos en formato estructurado</li> <li><strong>Portabilidad:</strong> recibir sus datos en formato estructurado</li>
</ul> </ul>
<p> <p>
Para ejercer estos derechos, contacte con nosotros en <strong>eventos@mnqcatering.com</strong> o por WhatsApp al <strong>+34 678 17 15 13</strong>. Para ejercer estos derechos, contacte con nosotros por teléfono o WhatsApp en <a href="tel:+34678171513"><strong>+34 678 17 15 13</strong></a> o utilice la página de <a href="/contacto"><strong>Contacto</strong></a>.
También puede presentar una reclamación ante la <a href="https://www.aepd.es" target="_blank" rel="noreferrer">Agencia Española de Protección de Datos (AEPD)</a>. También puede presentar una reclamación ante la <a href="https://www.aepd.es" target="_blank" rel="noreferrer">Agencia Española de Protección de Datos (AEPD)</a>.
</p> </p>
+134 -4
View File
@@ -1,11 +1,46 @@
--- ---
import MainLayout from '../layouts/MainLayout.astro'; import MainLayout from '../layouts/MainLayout.astro';
import Icon from '../components/Icon.astro';
const familyFaqs = [
{
question: '¿Qué tipo de celebraciones familiares trabajan?',
answer:
'Bautizos, aniversarios, cenas privadas, comidas especiales y encuentros donde el servicio gastronómico requiera una propuesta cuidada.',
},
{
question: '¿Cómo se prepara el presupuesto?',
answer:
'Se ajusta al número estimado de invitados, al formato del servicio, al menaje necesario y al desplazamiento previsto.',
},
{
question: '¿Con cuánta información conviene contactar?',
answer:
'Lo ideal es compartir fecha aproximada, lugar, tipo de celebración y cualquier necesidad alimentaria o logística relevante.',
},
];
const familyStructuredData = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: familyFaqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
};
const whatsappAriaLabel = 'Contactar con MNQ por WhatsApp';
--- ---
<MainLayout <MainLayout
title="Reuniones Familiares | MNQ Catering y Evento" title="Reuniones Familiares | MNQ Catering y Evento"
description="Creamos experiencias culinarias íntimas donde cada detalle cuenta. Bautizos, aniversarios y cenas privadas con el sello de excelencia MNQ." description="Creamos experiencias culinarias íntimas donde cada detalle cuenta. Bautizos, aniversarios y cenas privadas con el sello de excelencia MNQ."
activeNav="social" activeNav="social"
structuredData={familyStructuredData}
> >
<!-- ─── HERO ─── --> <!-- ─── HERO ─── -->
@@ -15,6 +50,8 @@ import MainLayout from '../layouts/MainLayout.astro';
alt="Reuniones familiares — MNQ Catering" alt="Reuniones familiares — MNQ Catering"
class="hero-bg" class="hero-bg"
style="object-position: center 35%;" style="object-position: center 35%;"
width="1376"
height="768"
loading="eager" loading="eager"
fetchpriority="high" fetchpriority="high"
/> />
@@ -33,12 +70,43 @@ import MainLayout from '../layouts/MainLayout.astro';
class="btn btn-primary" class="btn btn-primary"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
>Reservar una Cita</a> >Reservar una Cita</a>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section class="section-pad-sm bg-container-low">
<div class="page-wrap">
<div class="detail-grid">
<div>
<span class="section-eyebrow">Antes de pedir propuesta</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);">Información clara para una celebración bien resuelta</h2>
</div>
<div class="stack-6">
<p class="text-muted" style="line-height:1.8;">
En reuniones familiares, el acierto suele estar en los matices: número real de invitados, duración del encuentro, necesidades de cocina o servicio en sala y el tipo de atmósfera que se quiere cuidar. Por eso estudiamos cada solicitud antes de confirmar cobertura y propuesta.
</p>
<div class="detail-cards">
<article class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Formato del servicio</h3>
<p class="text-body-sm text-muted">Brunch, comida sentada, cóctel, cena privada o una combinación adaptada al ritmo del encuentro.</p>
</article>
<article class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Presupuesto a medida</h3>
<p class="text-body-sm text-muted">La propuesta se calcula según invitados, personal, menaje, timing del servicio y desplazamiento necesario.</p>
</article>
<article class="bg-surface rounded-lg border-outline-soft" style="padding:var(--space-6);">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">Cobertura confirmada</h3>
<p class="text-body-sm text-muted">La viabilidad se revisa caso a caso para asegurar que el espacio y la logística estén alineados con la experiencia que promete MNQ.</p>
</article>
</div>
</div>
</div>
</div>
</section>
<!-- ─── SERVICIOS ─── --> <!-- ─── SERVICIOS ─── -->
<section class="section-pad"> <section class="section-pad">
<div class="page-wrap"> <div class="page-wrap">
@@ -58,8 +126,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/gallery-4.webp" src="/images/generated/gallery-4.webp"
alt="Bautizos — mesa de celebración" alt="Bautizos — mesa de celebración"
width="1024"
height="1024"
style="width:100%;height:100%;object-fit:cover;object-position:center top;" style="width:100%;height:100%;object-fit:cover;object-position:center top;"
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
<div> <div>
@@ -74,8 +145,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/hero-familiares-gen.webp" src="/images/generated/hero-familiares-gen.webp"
alt="Aniversarios — celebración familiar" alt="Aniversarios — celebración familiar"
width="1376"
height="768"
style="width:100%;height:100%;object-fit:cover;object-position:center 30%;" style="width:100%;height:100%;object-fit:cover;object-position:center 30%;"
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
<div> <div>
@@ -90,8 +164,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/hero-nosotros-gen.webp" src="/images/generated/hero-nosotros-gen.webp"
alt="Cenas privadas — chef ejecutiva" alt="Cenas privadas — chef ejecutiva"
width="1264"
height="848"
style="width:100%;height:100%;object-fit:cover;object-position:center top;" style="width:100%;height:100%;object-fit:cover;object-position:center top;"
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
<div> <div>
@@ -119,8 +196,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/gallery-3.webp" src="/images/generated/gallery-3.webp"
alt="Vieiras de la Costa con Azafrán" alt="Vieiras de la Costa con Azafrán"
width="1024"
height="1024"
style="width:100%;height:100%;object-fit:cover;" style="width:100%;height:100%;object-fit:cover;"
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
<div style="display:flex;justify-content:space-between;align-items:baseline;"> <div style="display:flex;justify-content:space-between;align-items:baseline;">
@@ -136,8 +216,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/foto-plato-mnq.jpg" src="/images/foto-plato-mnq.jpg"
alt="Postre de autor MNQ" alt="Postre de autor MNQ"
width="1200"
height="805"
style="width:100%;height:100%;object-fit:cover;object-position:center top;" style="width:100%;height:100%;object-fit:cover;object-position:center top;"
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
<h4 class="text-headline-md" style="margin-bottom:var(--space-1);">Postre de Autor</h4> <h4 class="text-headline-md" style="margin-bottom:var(--space-1);">Postre de Autor</h4>
@@ -148,8 +231,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/generated/gallery-1.webp" src="/images/generated/gallery-1.webp"
alt="Postre con láminas de oro" alt="Postre con láminas de oro"
width="1024"
height="1024"
style="width:100%;height:100%;object-fit:cover;" style="width:100%;height:100%;object-fit:cover;"
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
<h4 class="text-headline-md" style="margin-bottom:var(--space-1);">Repostería Dorada</h4> <h4 class="text-headline-md" style="margin-bottom:var(--space-1);">Repostería Dorada</h4>
@@ -169,8 +255,11 @@ import MainLayout from '../layouts/MainLayout.astro';
<img <img
src="/images/foto-canapes.jpg" src="/images/foto-canapes.jpg"
alt="Canapés premium para reuniones familiares" alt="Canapés premium para reuniones familiares"
width="1264"
height="848"
style="width:100%;height:100%;object-fit:cover;object-position:center top;" style="width:100%;height:100%;object-fit:cover;object-position:center top;"
loading="lazy" loading="lazy"
decoding="async"
/> />
</div> </div>
@@ -183,21 +272,21 @@ import MainLayout from '../layouts/MainLayout.astro';
</p> </p>
<ul style="display:flex;flex-direction:column;gap:var(--space-6);margin-bottom:var(--space-10);"> <ul style="display:flex;flex-direction:column;gap:var(--space-6);margin-bottom:var(--space-10);">
<li style="display:flex;align-items:flex-start;gap:var(--space-4);"> <li style="display:flex;align-items:flex-start;gap:var(--space-4);">
<span class="material-symbols-outlined text-primary">auto_awesome</span> <Icon name="auto-awesome" class="text-primary" />
<div> <div>
<h5 style="font-weight:600;margin-bottom:var(--space-1);">Consultoría Privada</h5> <h5 style="font-weight:600;margin-bottom:var(--space-1);">Consultoría Privada</h5>
<p class="text-body-sm text-muted">Reunión con nuestro Chef Ejecutivo para definir el concepto gastronómico.</p> <p class="text-body-sm text-muted">Reunión con nuestro Chef Ejecutivo para definir el concepto gastronómico.</p>
</div> </div>
</li> </li>
<li style="display:flex;align-items:flex-start;gap:var(--space-4);"> <li style="display:flex;align-items:flex-start;gap:var(--space-4);">
<span class="material-symbols-outlined text-primary">restaurant_menu</span> <Icon name="restaurant-menu" class="text-primary" />
<div> <div>
<h5 style="font-weight:600;margin-bottom:var(--space-1);">Prueba de Degustación</h5> <h5 style="font-weight:600;margin-bottom:var(--space-1);">Prueba de Degustación</h5>
<p class="text-body-sm text-muted">Sesión íntima para refinar sabores y presentaciones antes del gran día.</p> <p class="text-body-sm text-muted">Sesión íntima para refinar sabores y presentaciones antes del gran día.</p>
</div> </div>
</li> </li>
<li style="display:flex;align-items:flex-start;gap:var(--space-4);"> <li style="display:flex;align-items:flex-start;gap:var(--space-4);">
<span class="material-symbols-outlined text-primary">local_florist</span> <Icon name="local-florist" class="text-primary" />
<div> <div>
<h5 style="font-weight:600;margin-bottom:var(--space-1);">Armonía Visual</h5> <h5 style="font-weight:600;margin-bottom:var(--space-1);">Armonía Visual</h5>
<p class="text-body-sm text-muted">Coordinación de mantelería, vajilla y cristalería con el menú seleccionado.</p> <p class="text-body-sm text-muted">Coordinación de mantelería, vajilla y cristalería con el menú seleccionado.</p>
@@ -209,6 +298,7 @@ import MainLayout from '../layouts/MainLayout.astro';
class="btn btn-primary" class="btn btn-primary"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
>Consultar Disponibilidad</a> >Consultar Disponibilidad</a>
</div> </div>
@@ -229,16 +319,45 @@ import MainLayout from '../layouts/MainLayout.astro';
style="background:var(--color-surface);color:var(--color-primary);border-radius:var(--radius-md);padding:1rem 2.5rem;gap:var(--space-3);" style="background:var(--color-surface);color:var(--color-primary);border-radius:var(--radius-md);padding:1rem 2.5rem;gap:var(--space-3);"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
aria-label={whatsappAriaLabel}
> >
<span class="material-symbols-outlined">chat</span> <Icon name="chat" />
Contactar por WhatsApp Contactar por WhatsApp
</a> </a>
</div> </div>
</section> </section>
<section class="section-pad-sm">
<div class="page-wrap" style="max-width:52rem;">
<div style="margin-bottom:var(--space-8);">
<span class="section-eyebrow">Preguntas frecuentes</span>
<h2 class="text-headline-lg" style="margin-top:var(--space-4);">Respuestas útiles para organizar una reunión familiar</h2>
</div>
<div class="faq-list">
{familyFaqs.map((faq) => (
<article class="faq-item">
<h3 class="text-headline-md" style="margin-bottom:var(--space-3);">{faq.question}</h3>
<p class="text-muted" style="line-height:1.75;">{faq.answer}</p>
</article>
))}
</div>
</div>
</section>
</MainLayout> </MainLayout>
<style> <style>
.detail-grid,
.detail-cards,
.faq-list {
display: grid;
gap: var(--space-8);
}
.detail-cards {
grid-template-columns: 1fr;
}
.hero-card-glass { .hero-card-glass {
width: 100%; width: 100%;
background: rgb(255 248 240 / 95%); background: rgb(255 248 240 / 95%);
@@ -269,6 +388,17 @@ import MainLayout from '../layouts/MainLayout.astro';
} }
@media (min-width: 48rem) { @media (min-width: 48rem) {
.detail-grid {
grid-template-columns: 5fr 7fr;
align-items: start;
gap: var(--space-12);
}
.detail-cards {
grid-template-columns: repeat(3, 1fr);
gap: var(--space-6);
}
.hero-card-glass { .hero-card-glass {
padding: var(--space-12); padding: var(--space-12);
max-width: 36rem; max-width: 36rem;
+5 -2
View File
@@ -274,10 +274,13 @@ body.page-ready {
top: 0; top: 0;
left: 0; left: 0;
height: 2px; height: 2px;
width: 0%; width: 100%;
background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-primary-container) 100%); background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-primary-container) 100%);
z-index: 9999; z-index: 9999;
transition: width 100ms linear; transform: scaleX(0);
transform-origin: left center;
transition: transform 100ms linear;
will-change: transform;
} }
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
+4 -2
View File
@@ -48,9 +48,11 @@ ul, ol {
list-style: none; list-style: none;
} }
.material-symbols-outlined { .icon {
font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 24; width: var(--icon-size, 1.25rem);
height: var(--icon-size, 1.25rem);
display: inline-block; display: inline-block;
line-height: 1; line-height: 1;
vertical-align: middle; vertical-align: middle;
flex-shrink: 0;
} }
+8 -4
View File
@@ -549,6 +549,11 @@
flex-shrink: 0; flex-shrink: 0;
} }
.whatsapp-float-icon .icon {
width: 1.125rem;
height: 1.125rem;
}
.whatsapp-float span:first-child { .whatsapp-float span:first-child {
position: absolute; position: absolute;
width: 1px; width: 1px;
@@ -619,7 +624,7 @@
.footer-brand p { .footer-brand p {
font-size: var(--text-sm); font-size: var(--text-sm);
color: var(--color-on-surface-variant); color: var(--color-on-surface);
max-width: 100%; max-width: 100%;
line-height: 1.5; line-height: 1.5;
} }
@@ -649,7 +654,7 @@
.footer-link { .footer-link {
font-size: var(--text-sm); font-size: var(--text-sm);
color: var(--color-on-surface-variant); color: var(--color-on-surface);
transition: color 200ms; transition: color 200ms;
} }
@@ -668,8 +673,7 @@
.footer-bottom p { .footer-bottom p {
font-size: var(--text-sm); font-size: var(--text-sm);
color: var(--color-on-surface-variant); color: var(--color-on-surface);
opacity: 0.6;
line-height: 1.4; line-height: 1.4;
} }
+2 -1
View File
@@ -117,5 +117,6 @@
/* Icon size */ /* Icon size */
.icon-lg { .icon-lg {
font-size: 2.5rem; width: 2.5rem;
height: 2.5rem;
} }