diff --git a/eslint.config.mjs b/eslint.config.mjs
index ab69a31..3cfa335 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -12,9 +12,8 @@ const compat = new FlatCompat({
const config = [
...compat.extends('next/core-web-vitals'),
{
- ignores: ['.next/**', 'node_modules/**'],
+ ignores: ['.next/**', 'node_modules/**', '.trash/**', '.openclaw/**'],
},
];
export default config;
-
diff --git a/src/app/api/booking/search/route.ts b/src/app/api/booking/search/route.ts
new file mode 100644
index 0000000..01e7099
--- /dev/null
+++ b/src/app/api/booking/search/route.ts
@@ -0,0 +1,23 @@
+import { NextResponse } from 'next/server';
+import { searchBookings } from '@/lib/booking';
+
+function parseNumber(value: string | null, fallback: number) {
+ if (value === null || value === '') return fallback;
+ const parsed = Number(value);
+ return Number.isFinite(parsed) ? parsed : fallback;
+}
+
+export function GET(request: Request) {
+ const url = new URL(request.url);
+ const result = searchBookings({
+ arrivalDate: url.searchParams.get('arrivalDate') ?? undefined,
+ departureDate: url.searchParams.get('departureDate') ?? undefined,
+ adults: parseNumber(url.searchParams.get('adults'), 2),
+ children: parseNumber(url.searchParams.get('children'), 0),
+ pets: parseNumber(url.searchParams.get('pets'), 0),
+ location: url.searchParams.get('location') ?? undefined,
+ propertySlug: url.searchParams.get('propertySlug') ?? undefined,
+ });
+
+ return NextResponse.json(result);
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index d08ce50..b980b88 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,5 +1,4 @@
import type { Metadata } from 'next';
-import './globals.scss';
import { SiteFooter } from '@/components/SiteFooter';
import { SiteHeader } from '@/components/SiteHeader';
import { site } from '@/lib/site';
@@ -9,6 +8,669 @@ export const metadata: Metadata = {
description: site.description,
};
+const globalStyles = String.raw`
+:root {
+ --shell-bg: #f4efe7;
+ --panel-bg: rgba(255, 255, 255, 0.72);
+ --panel-border: rgba(26, 23, 20, 0.08);
+ --accent: #7a543d;
+ --accent-2: #2e6661;
+ --text-muted: #63594f;
+ --shadow: 0 24px 80px rgba(23, 19, 14, 0.12);
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ min-height: 100vh;
+ margin: 0;
+ background:
+ radial-gradient(circle at top left, rgba(122, 84, 61, 0.18), transparent 30%),
+ radial-gradient(circle at 80% 10%, rgba(46, 102, 97, 0.18), transparent 24%),
+ var(--shell-bg);
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+button,
+.btn {
+ font: inherit;
+}
+
+button {
+ border: 0;
+}
+
+.btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.35rem;
+ padding: 0.7rem 1rem;
+ border: 1px solid transparent;
+ border-radius: 999px;
+ cursor: pointer;
+ line-height: 1.1;
+ transition:
+ transform 160ms ease,
+ background-color 160ms ease,
+ border-color 160ms ease,
+ color 160ms ease;
+}
+
+.btn:hover,
+.btn:focus-visible {
+ transform: translateY(-1px);
+}
+
+.btn-primary {
+ background: var(--accent);
+ border-color: var(--accent);
+ color: #fff;
+}
+
+.btn-primary:hover,
+.btn-primary:focus-visible {
+ background: #6a4732;
+ border-color: #6a4732;
+ color: #fff;
+}
+
+.btn-outline-dark {
+ background: transparent;
+ border-color: rgba(26, 23, 20, 0.18);
+ color: #1a1714;
+}
+
+.btn-outline-dark:hover,
+.btn-outline-dark:focus-visible {
+ background: rgba(255, 255, 255, 0.86);
+ border-color: rgba(26, 23, 20, 0.28);
+ color: #1a1714;
+}
+
+.btn-dark {
+ background: #1a1714;
+ border-color: #1a1714;
+ color: #fff;
+}
+
+.btn-dark:hover,
+.btn-dark:focus-visible {
+ background: #2a241f;
+ border-color: #2a241f;
+ color: #fff;
+}
+
+.text-body-secondary,
+.mb-0 {
+ color: var(--text-muted);
+}
+
+.mb-0 {
+ margin-bottom: 0 !important;
+}
+
+main {
+ position: relative;
+}
+
+.app-shell {
+ min-height: 100vh;
+ padding: 1.25rem;
+}
+
+.surface {
+ max-width: 1180px;
+ margin: 0 auto;
+ border: 1px solid var(--panel-border);
+ border-radius: 1.75rem;
+ background: var(--panel-bg);
+ box-shadow: var(--shadow);
+ backdrop-filter: blur(18px);
+}
+
+.site-header,
+.site-footer,
+.hero,
+.section-shell {
+ padding: 1.5rem;
+}
+
+.site-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ border-bottom: 1px solid var(--panel-border);
+}
+
+.brand-lockup {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+.brand-mark {
+ display: inline-grid;
+ place-items: center;
+ width: 3rem;
+ height: 3rem;
+ border-radius: 999px;
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
+ color: #fff;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+}
+
+.brand-kicker,
+.footer-label,
+.section-eyebrow {
+ margin: 0 0 0.25rem;
+ font-size: 0.72rem;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--text-muted);
+}
+
+.brand-lockup h1 {
+ margin: 0;
+ font-size: 1.05rem;
+}
+
+.site-nav {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+}
+
+.site-nav a {
+ padding: 0.55rem 0.85rem;
+ border: 1px solid rgba(26, 23, 20, 0.12);
+ border-radius: 999px;
+ font-size: 0.92rem;
+ color: var(--text-muted);
+ transition:
+ transform 160ms ease,
+ border-color 160ms ease,
+ background-color 160ms ease;
+}
+
+.site-nav a:hover,
+.site-nav a:focus-visible {
+ transform: translateY(-1px);
+ border-color: rgba(122, 84, 61, 0.35);
+ background: rgba(255, 255, 255, 0.8);
+ color: #1a1714;
+}
+
+.hero {
+ display: grid;
+ grid-template-columns: 1.5fr 1fr;
+ gap: 1.5rem;
+ align-items: stretch;
+}
+
+.hero-copy,
+.hero-panel,
+.info-card,
+.phase-card,
+.data-card {
+ border: 1px solid var(--panel-border);
+ border-radius: 1.5rem;
+ background: rgba(255, 255, 255, 0.78);
+}
+
+.hero-copy {
+ padding: 2rem;
+}
+
+.hero-copy h2 {
+ margin: 0 0 1rem;
+ font-size: clamp(2.2rem, 4vw, 4.2rem);
+ line-height: 0.95;
+ letter-spacing: -0.04em;
+}
+
+.hero-copy p {
+ max-width: 60ch;
+ color: var(--text-muted);
+ font-size: 1.06rem;
+}
+
+.hero-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+ margin-top: 1.5rem;
+}
+
+.hero-actions .btn {
+ border-radius: 999px;
+ padding-inline: 1.1rem;
+}
+
+.hero-points {
+ display: grid;
+ gap: 0.55rem;
+ margin: 1.5rem 0 0;
+ padding-left: 1.1rem;
+ color: var(--text-muted);
+}
+
+.hero-panel {
+ display: grid;
+ gap: 1rem;
+ padding: 1.5rem;
+}
+
+.search-panel {
+ display: grid;
+ gap: 0.85rem;
+ padding: 1rem;
+ border-radius: 1.25rem;
+ background: rgba(255, 255, 255, 0.9);
+ border: 1px solid rgba(26, 23, 20, 0.08);
+}
+
+.search-field {
+ display: grid;
+ gap: 0.35rem;
+ color: var(--text-muted);
+ font-size: 0.92rem;
+}
+
+.search-field input,
+.contact-form input,
+.contact-form textarea {
+ width: 100%;
+ border: 1px solid rgba(26, 23, 20, 0.14);
+ border-radius: 0.9rem;
+ padding: 0.8rem 0.95rem;
+ background: rgba(255, 255, 255, 0.94);
+ color: #1a1714;
+}
+
+.search-field input:focus,
+.contact-form input:focus,
+.contact-form textarea:focus {
+ outline: 2px solid rgba(122, 84, 61, 0.28);
+ outline-offset: 2px;
+}
+
+.quote-panel {
+ display: grid;
+ gap: 0.65rem;
+ padding: 1rem;
+ border-radius: 1.25rem;
+ border: 1px solid rgba(46, 102, 97, 0.18);
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(241, 248, 247, 0.92));
+}
+
+.availability-pill {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: fit-content;
+ padding: 0.35rem 0.7rem;
+ border-radius: 999px;
+ font-size: 0.78rem;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+}
+
+.availability-pill.is-available {
+ background: rgba(46, 102, 97, 0.12);
+ color: var(--accent-2);
+}
+
+.availability-pill.is-unavailable {
+ background: rgba(122, 84, 61, 0.12);
+ color: var(--accent);
+}
+
+.quote-heading {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 1rem;
+}
+
+.quote-heading h3 {
+ margin: 0;
+}
+
+.quote-heading strong {
+ font-size: 1.5rem;
+ white-space: nowrap;
+}
+
+.info-card,
+.phase-card,
+.data-card,
+.content-card,
+.property-card,
+.testimonial-card {
+ padding: 1rem;
+}
+
+.metric-grid,
+.phase-grid,
+.data-grid,
+.property-grid,
+.content-grid,
+.testimonial-grid,
+.card-stack,
+.content-stack {
+ display: grid;
+ gap: 1rem;
+}
+
+.metric-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.metric {
+ padding: 1rem;
+ border-radius: 1rem;
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(246, 240, 231, 0.9));
+}
+
+.metric strong {
+ display: block;
+ margin-bottom: 0.3rem;
+ font-size: 1.6rem;
+}
+
+.section-heading h2 {
+ margin: 0;
+ font-size: clamp(1.5rem, 2vw, 2.1rem);
+}
+
+.section-description {
+ max-width: 65ch;
+ margin: 0.5rem 0 0;
+ color: var(--text-muted);
+}
+
+.phase-grid {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.phase-card h3,
+.data-card h3 {
+ margin-top: 0;
+ font-size: 1.05rem;
+}
+
+.phase-card ul,
+.data-card ul {
+ margin: 0.75rem 0 0;
+ padding-left: 1.1rem;
+ color: var(--text-muted);
+}
+
+.data-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.property-grid {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.property-card {
+ display: grid;
+ gap: 0.9rem;
+ border: 1px solid var(--panel-border);
+ border-radius: 1.35rem;
+ background: rgba(255, 255, 255, 0.82);
+}
+
+.property-card-top {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 1rem;
+}
+
+.property-card h3,
+.content-card h3,
+.testimonial-card strong {
+ margin: 0;
+}
+
+.property-price {
+ display: inline-flex;
+ align-items: center;
+ padding: 0.35rem 0.7rem;
+ border-radius: 999px;
+ background: rgba(46, 102, 97, 0.12);
+ color: var(--accent-2);
+ font-size: 0.85rem;
+ white-space: nowrap;
+}
+
+.property-metrics {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 0.75rem;
+ margin: 0;
+}
+
+.property-metrics div {
+ padding: 0.75rem;
+ border-radius: 0.95rem;
+ background: rgba(244, 239, 231, 0.88);
+}
+
+.property-metrics dt {
+ color: var(--text-muted);
+ font-size: 0.78rem;
+ text-transform: uppercase;
+ letter-spacing: 0.14em;
+}
+
+.property-metrics dd {
+ margin: 0.25rem 0 0;
+ font-size: 1rem;
+ font-weight: 700;
+}
+
+.tag-list,
+.link-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.tag-list li {
+ padding: 0.32rem 0.62rem;
+ border-radius: 999px;
+ background: rgba(122, 84, 61, 0.12);
+ color: var(--accent);
+ font-size: 0.82rem;
+}
+
+.content-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.content-grid-tight {
+ align-items: flex-start;
+}
+
+.content-card,
+.testimonial-card {
+ border: 1px solid var(--panel-border);
+ border-radius: 1.35rem;
+ background: rgba(255, 255, 255, 0.82);
+}
+
+.content-card p:last-child,
+.testimonial-card p:last-child {
+ margin-bottom: 0;
+}
+
+.inline-link {
+ color: var(--accent-2);
+ text-decoration: underline;
+ text-underline-offset: 0.2em;
+}
+
+.testimonial-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.testimonial-card {
+ display: grid;
+ gap: 1rem;
+}
+
+.testimonial-card footer {
+ display: grid;
+ gap: 0.15rem;
+ color: var(--text-muted);
+}
+
+.cta-band,
+.page-hero {
+ border: 1px solid var(--panel-border);
+ border-radius: 1.5rem;
+ background: rgba(255, 255, 255, 0.82);
+}
+
+.cta-band {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ padding: 1.1rem 1.25rem;
+}
+
+.page-hero {
+ margin: 1.5rem;
+ padding: 1.5rem;
+}
+
+.page-hero h2 {
+ margin: 0 0 0.6rem;
+ font-size: clamp(2rem, 4vw, 3.5rem);
+ line-height: 0.98;
+ letter-spacing: -0.04em;
+}
+
+.page-layout {
+ display: grid;
+ grid-template-columns: minmax(0, 1.4fr) minmax(300px, 0.75fr);
+ gap: 0.5rem;
+}
+
+.page-layout .section-shell {
+ padding-top: 0;
+}
+
+.contact-form {
+ display: grid;
+ gap: 0.9rem;
+}
+
+.contact-form label {
+ display: grid;
+ gap: 0.35rem;
+ color: var(--text-muted);
+}
+
+.contact-form-message {
+ grid-column: 1 / -1;
+}
+
+.contact-aside {
+ display: grid;
+ gap: 1rem;
+ align-content: start;
+ padding: 1.5rem 1.5rem 1.5rem 0;
+}
+
+.content-sidebar {
+ display: grid;
+ gap: 1rem;
+ align-content: start;
+}
+
+.site-footer {
+ display: flex;
+ justify-content: space-between;
+ gap: 1rem;
+ border-top: 1px solid var(--panel-border);
+ color: var(--text-muted);
+}
+
+.site-footer p {
+ margin: 0;
+}
+
+@media (max-width: 900px) {
+ .hero,
+ .phase-grid,
+ .data-grid,
+ .property-grid,
+ .content-grid,
+ .testimonial-grid,
+ .page-layout {
+ grid-template-columns: 1fr;
+ }
+
+ .site-header,
+ .site-footer,
+ .cta-band {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+
+ .contact-aside {
+ padding: 0 1.5rem 1.5rem;
+ }
+}
+
+@media (max-width: 640px) {
+ .app-shell {
+ padding: 0.75rem;
+ }
+
+ .site-header,
+ .hero,
+ .section-shell,
+ .site-footer {
+ padding: 1rem;
+ }
+
+ .page-hero {
+ margin: 0.75rem;
+ padding: 1rem;
+ }
+
+ .metric-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .property-metrics {
+ grid-template-columns: 1fr;
+ }
+}
+`;
+
export default function RootLayout({
children,
}: Readonly<{
@@ -24,8 +686,8 @@ export default function RootLayout({
+