本页出处
设计风格资料库
内容来自 luckymaomi 的 UI 风格库(复刻版),以 MIT 许可 提供。本站镜像收录,仅作学习参考;这一页的原始地址是 原站页面。
← 回到导览访问原站仓库
返回模板目录
ecommerceapple-style

房产列表

房产展示页面,支持网格/列表视图、价格筛选、户型参数和地图标注。

独立打开

完整模板源代码

查看 1839 行代码
"use client";

export const dynamic = "force-static";

import { useState } from "react";
import {
  ArrowRight,
  ArrowUpRight,
  Bath,
  Bed,
  Bookmark,
  ChevronDown,
  Mail,
  MapPin,
  Menu,
  Phone,
  Ruler,
  Search,
  X,
} from "@/components/IconShim";
import {
  Archivo,
  IBM_Plex_Mono,
  Libre_Caslon_Text,
} from "@/components/templates/FontShim";
import { TemplateBackLink } from "@/components/templates/TemplateBackLink";

const archivo = Archivo({
  subsets: ["latin"],
  weight: ["400", "500", "600", "700", "800"],
});
const serif = Libre_Caslon_Text({ subsets: ["latin"], weight: ["400", "700"] });
const serifItalic = Libre_Caslon_Text({
  subsets: ["latin"],
  weight: "400",
  style: "italic",
});
const mono = IBM_Plex_Mono({ subsets: ["latin"], weight: ["400", "500"] });

/* ------------------------------------------------------------------ */
/* Types                                                               */
/* ------------------------------------------------------------------ */

type FacadeVariant =
  "villa" | "gable" | "warehouse" | "courtyard" | "shed" | "colonnade";
type PaletteName = "dawn" | "dusk" | "sand" | "slate" | "clay" | "sage";

interface Palette {
  sky: string;
  wall: string;
  wallShade: string;
  window: string;
  ink: string;
  glow: string;
  ground: string;
}

interface Property {
  name: string;
  region: string;
  neighborhood: string;
  address: string;
  kind: string;
  era: string;
  price: number;
  beds: number;
  baths: number;
  sqft: number;
  caption: string;
  facade: FacadeVariant;
  palette: PaletteName;
}

/* ------------------------------------------------------------------ */
/* Content                                                             */
/* ------------------------------------------------------------------ */

const NAV_LINKS = ["Listings", "Neighborhoods", "Selling", "The Firm"];

const LOCATIONS = [
  "All areas",
  "Marin County",
  "Hudson Valley",
  "Providence",
  "East Hampton",
  "Bend",
  "Savannah",
];
const KINDS = [
  "All types",
  "Modernist",
  "New Build",
  "Conversion",
  "Coastal",
  "Historic",
];
const PRICES = ["Any price", "Under $1M", "$1M - $2M", "$2M - $3M", "$3M+"];

const PALETTES: Record<PaletteName, Palette> = {
  dawn: {
    sky: "#EBE4DB",
    wall: "#DBD3C6",
    wallShade: "#C9C0B0",
    window: "#A7ADAE",
    ink: "#4A4438",
    glow: "#C9754E",
    ground: "#D7CFC1",
  },
  dusk: {
    sky: "#CBD3DA",
    wall: "#AEB7C1",
    wallShade: "#99A4B0",
    window: "#5F6E7C",
    ink: "#2C333C",
    glow: "#C9754E",
    ground: "#B4BCC4",
  },
  sand: {
    sky: "#EEE4D2",
    wall: "#E1D3BA",
    wallShade: "#D0C0A2",
    window: "#AD9C7E",
    ink: "#574A34",
    glow: "#B4552D",
    ground: "#DDCFB4",
  },
  slate: {
    sky: "#DEDED9",
    wall: "#C6C6C0",
    wallShade: "#B0B0A9",
    window: "#83837C",
    ink: "#3B3B35",
    glow: "#C9754E",
    ground: "#CBCBC4",
  },
  clay: {
    sky: "#ECE0D5",
    wall: "#DEC8B6",
    wallShade: "#CAB29B",
    window: "#9C8875",
    ink: "#4E3A2B",
    glow: "#B4552D",
    ground: "#DBC7B6",
  },
  sage: {
    sky: "#E0E4DA",
    wall: "#C8CFBE",
    wallShade: "#B4BCA9",
    window: "#7E8874",
    ink: "#3A4133",
    glow: "#C9754E",
    ground: "#CFD4C6",
  },
};

const HERO: Palette = {
  sky: "#F1EADF",
  wall: "#DDD3C4",
  wallShade: "#CFC4B2",
  window: "#8E9AA1",
  ink: "#2C2A24",
  glow: "#C9754E",
  ground: "#E6D6C1",
};

const PROPERTIES: Property[] = [
  {
    name: "The Ridgeline House",
    region: "Marin County",
    neighborhood: "Sausalito Hills",
    address: "44 Overlook Path, Sausalito, CA",
    kind: "Modernist",
    era: "Built 1971 · Restored 2023",
    price: 2150000,
    beds: 4,
    baths: 3,
    sqft: 3120,
    caption:
      "A hillside modernist brought back to its bones — clerestory light, terrazzo underfoot, and a living room that cantilevers over the eucalyptus.",
    facade: "villa",
    palette: "dusk",
  },
  {
    name: "Slatewood Residence",
    region: "Hudson Valley",
    neighborhood: "Rhinebeck",
    address: "1207 Kingfisher Lane, Rhinebeck, NY",
    kind: "New Build",
    era: "Completed 2022",
    price: 1395000,
    beds: 3,
    baths: 2,
    sqft: 2480,
    caption:
      "Black-stained cedar under a steep gable, sited to catch the morning field. A wood-burning core, radiant concrete, and glass that opens the whole south wall.",
    facade: "gable",
    palette: "dawn",
  },
  {
    name: "The Foundry Loft",
    region: "Providence",
    neighborhood: "Jewelry District",
    address: "88 Carver Street, Unit 4, Providence, RI",
    kind: "Conversion",
    era: "Brass works, 1908 · Converted 2016",
    price: 845000,
    beds: 2,
    baths: 2,
    sqft: 1760,
    caption:
      "A former brass-works floor turned open loft. Steel-sash windows, exposed trusses, and twelve-foot ceilings that keep their old factory hush.",
    facade: "warehouse",
    palette: "slate",
  },
  {
    name: "Dune Court",
    region: "East Hampton",
    neighborhood: "Amagansett",
    address: "3 Marram Way, Amagansett, NY",
    kind: "Coastal",
    era: "Completed 2019",
    price: 3480000,
    beds: 5,
    baths: 4,
    sqft: 4050,
    caption:
      "Two cedar volumes turned inward around a sheltered court, braced against the Atlantic wind. Ipe decks, an outdoor hearth, and dune grass to the sand.",
    facade: "courtyard",
    palette: "sand",
  },
  {
    name: "The Shed House",
    region: "Bend",
    neighborhood: "Old Mill",
    address: "512 Alder Grade, Bend, OR",
    kind: "New Build",
    era: "Completed 2021",
    price: 720000,
    beds: 3,
    baths: 2,
    sqft: 1940,
    caption:
      "One sweeping mono-pitch roof over an open plan, glazed to the ponderosa. Built for snow load and warmed by a river-rock flue that anchors the room.",
    facade: "shed",
    palette: "sage",
  },
  {
    name: "Colonnade Twelve",
    region: "Savannah",
    neighborhood: "Historic District",
    address: "12 Ashby Row, Savannah, GA",
    kind: "Historic",
    era: "Greek Revival, 1854 · Restored 2020",
    price: 1180000,
    beds: 4,
    baths: 3,
    sqft: 2900,
    caption:
      "A restored Revival townhouse on a live-oak square. Heart-pine floors, a double parlor, and a columned porch that has watched the district for a century.",
    facade: "colonnade",
    palette: "clay",
  },
];

const NEIGHBORHOODS = [
  {
    name: "Sausalito Hills",
    place: "Marin County, CA",
    count: 18,
    note: "Hillside modernism above the bay.",
  },
  {
    name: "Rhinebeck",
    place: "Hudson Valley, NY",
    count: 11,
    note: "Field houses and barn conversions.",
  },
  {
    name: "Jewelry District",
    place: "Providence, RI",
    count: 24,
    note: "Loft floors in the old brass works.",
  },
  {
    name: "Old Mill",
    place: "Bend, OR",
    count: 9,
    note: "Timber-frame along the river bend.",
  },
  {
    name: "Historic District",
    place: "Savannah, GA",
    count: 15,
    note: "Revival townhouses on the squares.",
  },
];

const STEPS = [
  {
    no: "01",
    title: "Brief",
    body: "Tell us how you actually live. We translate light, rooms, and commute into a working shortlist — usually inside a week.",
  },
  {
    no: "02",
    title: "Tour",
    body: "Walk the shortlist with an agent who reads the drawings, not just the listing sheet. We note the bones and the honest compromises.",
  },
  {
    no: "03",
    title: "Offer",
    body: "We price against the block, structure the terms, and go in with the survey already in hand. No guessing, no theatre.",
  },
  {
    no: "04",
    title: "Keys",
    body: "Inspection, closing, and handover are coordinated end to end — so the only thing you carry across the threshold is a box.",
  },
];

const AGENTS = [
  {
    name: "Marguerite Vance",
    role: "Principal Broker",
    area: "West Coast",
    note: "Two decades placing modernist and mid-century houses across Northern California.",
  },
  {
    name: "Theo Okonkwo",
    role: "Partner, Northeast",
    area: "Northeast",
    note: "Loft conversions and new-build timber from Providence to the Hudson Valley.",
  },
  {
    name: "Camille Aldous",
    role: "Partner, Southeast",
    area: "Southeast",
    note: "Historic restorations and coastal courtyards from Savannah to the barrier islands.",
  },
];

const STATS = [
  {
    value: "$1.2B",
    label: "in homes placed since the firm opened its doors in 2011",
  },
  { value: "31", label: "median days from first tour to an accepted offer" },
  { value: "98%", label: "of list price achieved across last year's closings" },
  { value: "4.9", label: "average client rating, out of five, over 600 sales" },
];

const PULL_QUOTE = {
  quote:
    "We came in with a vague idea of something with light and left with a house we cannot picture leaving. HAUS read the plans better than we could, and never once showed us a place that was not right.",
  name: "The Merriweathers",
  detail: "Buyers · The Ridgeline House, Marin County",
};

const FOOTER_COLS = [
  {
    title: "Buy",
    links: ["Listings", "Neighborhoods", "New developments", "Private sales"],
  },
  {
    title: "Sell",
    links: ["List with HAUS", "Valuation", "Marketing", "Our process"],
  },
  { title: "Firm", links: ["About", "Agents", "Careers", "Journal"] },
  {
    title: "Visit",
    links: ["Sausalito studio", "By appointment", "Contact", "Press"],
  },
];

/* ------------------------------------------------------------------ */
/* Helpers                                                             */
/* ------------------------------------------------------------------ */

const usd = (n: number) => `$${n.toLocaleString("en-US")}`;

const initials = (name: string) =>
  name
    .split(" ")
    .map((w) => w[0])
    .join("")
    .slice(0, 2);

function priceMatch(price: number, bracket: string): boolean {
  switch (bracket) {
    case "Under $1M":
      return price < 1000000;
    case "$1M - $2M":
      return price >= 1000000 && price < 2000000;
    case "$2M - $3M":
      return price >= 2000000 && price < 3000000;
    case "$3M+":
      return price >= 3000000;
    default:
      return true;
  }
}

/* ------------------------------------------------------------------ */
/* Architectural elevations — pure inline SVG                          */
/* ------------------------------------------------------------------ */

function WindowGrid({
  x,
  y,
  w,
  h,
  cols,
  rows,
  palette,
  lit,
}: {
  x: number;
  y: number;
  w: number;
  h: number;
  cols: number;
  rows: number;
  palette: Palette;
  lit?: string[];
}) {
  const gap = Math.min(6, w / (cols * 3));
  const cw = (w - gap * (cols - 1)) / cols;
  const ch = (h - gap * (rows - 1)) / rows;
  return (
    <g>
      {Array.from({ length: rows }).map((_, r) =>
        Array.from({ length: cols }).map((_, c) => {
          const isLit = lit?.includes(`${r}-${c}`) ?? false;
          return (
            <rect
              key={`${r}-${c}`}
              x={x + c * (cw + gap)}
              y={y + r * (ch + gap)}
              width={cw}
              height={ch}
              fill={isLit ? palette.glow : palette.window}
              className={isLit ? "haus-lit" : undefined}
              stroke={palette.ink}
              strokeOpacity={0.22}
              strokeWidth={1}
            />
          );
        }),
      )}
    </g>
  );
}

function Ground({ palette: p }: { palette: Palette }) {
  return (
    <g>
      <rect x="0" y="258" width="400" height="42" fill={p.ground} />
      <line
        x1="0"
        y1="258"
        x2="400"
        y2="258"
        stroke={p.ink}
        strokeOpacity={0.2}
        strokeWidth={1}
      />
    </g>
  );
}

function VillaFacade({ palette: p }: { palette: Palette }) {
  return (
    <g>
      <Ground palette={p} />
      <rect x="40" y="150" width="322" height="108" fill={p.wall} />
      <rect x="356" y="154" width="5" height="104" fill={p.wallShade} />
      <rect x="372" y="154" width="5" height="104" fill={p.wallShade} />
      <rect x="150" y="98" width="235" height="56" fill={p.wallShade} />
      <rect x="144" y="92" width="247" height="7" fill={p.ink} opacity={0.85} />
      <WindowGrid
        x={60}
        y={172}
        w={188}
        h={34}
        cols={6}
        rows={1}
        palette={p}
        lit={["0-1", "0-2"]}
      />
      <rect x="286" y="196" width="34" height="62" fill={p.ink} opacity={0.8} />
      <line
        x1="313"
        y1="220"
        x2="313"
        y2="238"
        stroke={p.wall}
        strokeWidth={1.5}
      />
      <WindowGrid
        x={168}
        y={110}
        w={200}
        h={32}
        cols={6}
        rows={1}
        palette={p}
        lit={["0-3", "0-4"]}
      />
      <line
        x1="40"
        y1="150"
        x2="362"
        y2="150"
        stroke={p.ink}
        strokeOpacity={0.18}
        strokeWidth={1}
      />
    </g>
  );
}

function GableFacade({ palette: p }: { palette: Palette }) {
  return (
    <g>
      <Ground palette={p} />
      <rect x="112" y="150" width="176" height="108" fill={p.wall} />
      <polygon points="200,72 100,152 300,152" fill={p.wallShade} />
      <polygon
        points="200,72 100,152 300,152"
        fill="none"
        stroke={p.ink}
        strokeOpacity={0.28}
        strokeWidth={1.5}
      />
      <polygon points="200,72 200,152 300,152" fill={p.ink} opacity={0.06} />
      <rect x="246" y="86" width="16" height="42" fill={p.wallShade} />
      <rect x="243" y="82" width="22" height="6" fill={p.ink} opacity={0.7} />
      <circle
        cx="200"
        cy="118"
        r="11"
        fill={p.window}
        stroke={p.ink}
        strokeOpacity={0.3}
        strokeWidth={1}
      />
      <line
        x1="200"
        y1="107"
        x2="200"
        y2="129"
        stroke={p.ink}
        strokeOpacity={0.25}
        strokeWidth={1}
      />
      <line
        x1="189"
        y1="118"
        x2="211"
        y2="118"
        stroke={p.ink}
        strokeOpacity={0.25}
        strokeWidth={1}
      />
      <WindowGrid
        x={132}
        y={166}
        w={136}
        h={30}
        cols={2}
        rows={1}
        palette={p}
        lit={["0-1"]}
      />
      <WindowGrid x={132} y={206} w={46} h={46} cols={1} rows={1} palette={p} />
      <WindowGrid
        x={222}
        y={206}
        w={46}
        h={46}
        cols={1}
        rows={1}
        palette={p}
        lit={["0-0"]}
      />
      <rect
        x="186"
        y="210"
        width="28"
        height="48"
        fill={p.ink}
        opacity={0.82}
      />
      <line
        x1="208"
        y1="230"
        x2="208"
        y2="240"
        stroke={p.wall}
        strokeWidth={1.5}
      />
    </g>
  );
}

function WarehouseFacade({ palette: p }: { palette: Palette }) {
  return (
    <g>
      <Ground palette={p} />
      <rect x="48" y="108" width="304" height="150" fill={p.wall} />
      <rect x="42" y="102" width="316" height="8" fill={p.wallShade} />
      <line
        x1="48"
        y1="150"
        x2="352"
        y2="150"
        stroke={p.ink}
        strokeOpacity={0.14}
        strokeWidth={1}
      />
      <WindowGrid
        x={66}
        y={122}
        w={80}
        h={92}
        cols={3}
        rows={5}
        palette={p}
        lit={["1-1", "3-2"]}
      />
      <WindowGrid
        x={160}
        y={122}
        w={80}
        h={92}
        cols={3}
        rows={5}
        palette={p}
        lit={["0-0", "2-1"]}
      />
      <WindowGrid
        x={254}
        y={122}
        w={80}
        h={92}
        cols={3}
        rows={5}
        palette={p}
        lit={["4-2"]}
      />
      <rect x="150" y="214" width="100" height="44" fill={p.wallShade} />
      {Array.from({ length: 7 }).map((_, i) => (
        <line
          key={i}
          x1={162 + i * 13}
          y1="216"
          x2={162 + i * 13}
          y2="256"
          stroke={p.ink}
          strokeOpacity={0.18}
          strokeWidth={1}
        />
      ))}
      <rect
        x="150"
        y="214"
        width="100"
        height="44"
        fill="none"
        stroke={p.ink}
        strokeOpacity={0.3}
        strokeWidth={1.5}
      />
    </g>
  );
}

function CourtyardFacade({ palette: p }: { palette: Palette }) {
  return (
    <g>
      <Ground palette={p} />
      <rect x="40" y="146" width="128" height="112" fill={p.wall} />
      {Array.from({ length: 11 }).map((_, i) => (
        <line
          key={i}
          x1="40"
          y1={156 + i * 9}
          x2="168"
          y2={156 + i * 9}
          stroke={p.ink}
          strokeOpacity={0.08}
          strokeWidth={1}
        />
      ))}
      <rect x="36" y="140" width="136" height="7" fill={p.wallShade} />
      <rect x="250" y="120" width="120" height="138" fill={p.wallShade} />
      <rect x="246" y="114" width="128" height="7" fill={p.ink} opacity={0.8} />
      <rect x="168" y="196" width="82" height="62" fill={p.wall} />
      <rect x="196" y="212" width="26" height="46" fill={p.ink} opacity={0.8} />
      <line
        x1="150"
        y1="196"
        x2="150"
        y2="150"
        stroke={p.ink}
        strokeOpacity={0.4}
        strokeWidth={2}
      />
      <circle cx="150" cy="142" r="15" fill={p.wallShade} opacity={0.7} />
      <WindowGrid
        x={58}
        y={162}
        w={92}
        h={30}
        cols={3}
        rows={1}
        palette={p}
        lit={["0-1"]}
      />
      <WindowGrid x={58} y={206} w={40} h={44} cols={1} rows={1} palette={p} />
      <WindowGrid
        x={268}
        y={138}
        w={84}
        h={96}
        cols={2}
        rows={3}
        palette={p}
        lit={["0-1", "2-0"]}
      />
    </g>
  );
}

function ShedFacade({ palette: p }: { palette: Palette }) {
  return (
    <g>
      <Ground palette={p} />
      <polygon points="70,258 70,150 330,104 330,258" fill={p.wall} />
      <polygon
        points="66,150 334,104 338,113 70,159"
        fill={p.ink}
        opacity={0.82}
      />
      <WindowGrid
        x={90}
        y={168}
        w={150}
        h={72}
        cols={3}
        rows={2}
        palette={p}
        lit={["1-0", "0-2"]}
      />
      <WindowGrid
        x={274}
        y={130}
        w={44}
        h={104}
        cols={1}
        rows={4}
        palette={p}
        lit={["1-0"]}
      />
      <line
        x1="256"
        y1="120"
        x2="256"
        y2="258"
        stroke={p.ink}
        strokeOpacity={0.15}
        strokeWidth={1}
      />
      <rect x="240" y="212" width="16" height="46" fill={p.ink} opacity={0.7} />
    </g>
  );
}

function ColonnadeFacade({ palette: p }: { palette: Palette }) {
  const columns = [78, 128, 178, 228, 278];
  return (
    <g>
      <Ground palette={p} />
      <rect
        x="70"
        y="150"
        width="260"
        height="100"
        fill={p.window}
        opacity={0.55}
      />
      <rect x="70" y="140" width="260" height="10" fill={p.wallShade} />
      <rect x="184" y="196" width="32" height="54" fill={p.ink} opacity={0.8} />
      {columns.map((cx) => (
        <g key={cx}>
          <rect x={cx} y="150" width="14" height="100" fill={p.wall} />
          <rect x={cx - 2} y="148" width="18" height="5" fill={p.wallShade} />
          <rect x={cx - 2} y="250" width="18" height="5" fill={p.wallShade} />
          <line
            x1={cx + 7}
            y1="153"
            x2={cx + 7}
            y2="248"
            stroke={p.ink}
            strokeOpacity={0.12}
            strokeWidth={1}
          />
        </g>
      ))}
      <rect x="58" y="132" width="284" height="12" fill={p.wallShade} />
      <line
        x1="58"
        y1="132"
        x2="342"
        y2="132"
        stroke={p.ink}
        strokeOpacity={0.25}
        strokeWidth={1}
      />
      <polygon points="52,132 200,90 348,132" fill={p.wall} />
      <polygon
        points="52,132 200,90 348,132"
        fill="none"
        stroke={p.ink}
        strokeOpacity={0.25}
        strokeWidth={1.5}
      />
      <rect x="66" y="250" width="268" height="5" fill={p.wallShade} />
      <rect x="74" y="255" width="252" height="5" fill={p.ink} opacity={0.12} />
    </g>
  );
}

function Facade({
  variant,
  palette,
}: {
  variant: FacadeVariant;
  palette: Palette;
}) {
  return (
    <svg
      viewBox="0 0 400 300"
      className="h-full w-full"
      preserveAspectRatio="xMidYMid slice"
      role="img"
      aria-label="Architectural elevation drawing"
    >
      <rect x="0" y="0" width="400" height="300" fill={palette.sky} />
      {variant === "villa" && <VillaFacade palette={palette} />}
      {variant === "gable" && <GableFacade palette={palette} />}
      {variant === "warehouse" && <WarehouseFacade palette={palette} />}
      {variant === "courtyard" && <CourtyardFacade palette={palette} />}
      {variant === "shed" && <ShedFacade palette={palette} />}
      {variant === "colonnade" && <ColonnadeFacade palette={palette} />}
    </svg>
  );
}

function HeroIllustration() {
  const p = HERO;
  return (
    <svg
      viewBox="0 0 600 470"
      className="h-full w-full"
      preserveAspectRatio="xMidYMid slice"
      role="img"
      aria-label="A modernist house at dusk, drawn as an architectural elevation"
    >
      <defs>
        <linearGradient id="hausSky" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#F3ECE1" />
          <stop offset="0.68" stopColor="#EFE1CF" />
          <stop offset="1" stopColor="#E9D4BC" />
        </linearGradient>
        <filter id="hausGlow" x="-60%" y="-60%" width="220%" height="220%">
          <feGaussianBlur stdDeviation="14" />
        </filter>
      </defs>
      <rect x="0" y="0" width="600" height="470" fill="url(#hausSky)" />
      <circle
        cx="452"
        cy="250"
        r="70"
        fill="#C9754E"
        opacity={0.28}
        filter="url(#hausGlow)"
      />
      <circle cx="452" cy="250" r="46" fill="#C9754E" className="haus-sun" />
      <rect
        x="70"
        y="92"
        width="150"
        height="14"
        rx="7"
        fill="#FBF3E7"
        opacity={0.7}
        className="haus-drift"
      />
      <rect
        x="122"
        y="120"
        width="90"
        height="10"
        rx="5"
        fill="#FBF3E7"
        opacity={0.5}
        className="haus-drift"
      />
      <rect
        x="20"
        y="300"
        width="90"
        height="60"
        fill={p.wallShade}
        opacity={0.4}
      />
      <polygon
        points="20,300 65,276 110,300"
        fill={p.wallShade}
        opacity={0.4}
      />
      <rect x="0" y="360" width="600" height="110" fill={p.ground} />
      <line
        x1="0"
        y1="360"
        x2="600"
        y2="360"
        stroke={p.ink}
        strokeOpacity={0.18}
        strokeWidth={1}
      />
      <ellipse cx="300" cy="368" rx="230" ry="10" fill={p.ink} opacity={0.08} />
      <rect x="70" y="250" width="360" height="110" fill={p.wall} />
      <rect x="200" y="196" width="300" height="56" fill={p.wallShade} />
      <rect
        x="192"
        y="189"
        width="316"
        height="8"
        fill={p.ink}
        opacity={0.85}
      />
      <rect x="470" y="252" width="6" height="108" fill={p.wallShade} />
      <rect x="486" y="252" width="6" height="108" fill={p.wallShade} />
      <WindowGrid
        x={92}
        y={270}
        w={150}
        h={74}
        cols={4}
        rows={2}
        palette={p}
        lit={["0-0", "1-1", "0-3"]}
      />
      <rect x="300" y="300" width="36" height="60" fill={p.ink} opacity={0.8} />
      <line
        x1="330"
        y1="326"
        x2="330"
        y2="344"
        stroke={p.wall}
        strokeWidth={2}
      />
      <WindowGrid
        x={220}
        y={208}
        w={262}
        h={32}
        cols={9}
        rows={1}
        palette={p}
        lit={["0-2", "0-5", "0-6"]}
      />
      <line
        x1="70"
        y1="250"
        x2="430"
        y2="250"
        stroke={p.ink}
        strokeOpacity={0.15}
        strokeWidth={1}
      />
      <line
        x1="524"
        y1="360"
        x2="524"
        y2="300"
        stroke={p.ink}
        strokeOpacity={0.5}
        strokeWidth={2}
      />
      <ellipse cx="524" cy="292" rx="18" ry="24" fill="#9BA487" opacity={0.7} />
      <line
        x1="556"
        y1="360"
        x2="556"
        y2="316"
        stroke={p.ink}
        strokeOpacity={0.45}
        strokeWidth={2}
      />
      <ellipse cx="556" cy="310" rx="13" ry="18" fill="#9BA487" opacity={0.6} />
      {Array.from({ length: 7 }).map((_, i) => (
        <path
          key={i}
          d={`M ${40 + i * 12} 400 q 4 -18 -2 -34`}
          fill="none"
          stroke="#9BA487"
          strokeOpacity={0.6}
          strokeWidth={1.5}
        />
      ))}
    </svg>
  );
}

/* ------------------------------------------------------------------ */
/* Small UI                                                            */
/* ------------------------------------------------------------------ */

function Wordmark({ tone = "ink" }: { tone?: "ink" | "light" }) {
  return (
    <span
      className={`${archivo.className} text-xl font-extrabold tracking-tight ${tone === "light" ? "text-[#F7F6F3]" : "text-[#1A1712]"}`}
    >
      HAUS<span className="text-[#B4552D]">.</span>
    </span>
  );
}

function SelectField({
  label,
  value,
  options,
  onChange,
}: {
  label: string;
  value: string;
  options: string[];
  onChange: (value: string) => void;
}) {
  return (
    <label className="block cursor-pointer">
      <span
        className={`${mono.className} mb-1.5 block text-[10px] tracking-[0.22em] text-[#1A1712]/45`}
      >
        {label}
      </span>
      <div className="relative">
        <select
          value={value}
          onChange={(e) => onChange(e.target.value)}
          className="w-full appearance-none bg-transparent pr-6 text-[15px] font-medium text-[#1A1712] outline-none"
        >
          {options.map((option) => (
            <option key={option} value={option}>
              {option}
            </option>
          ))}
        </select>
        <ChevronDown className="pointer-events-none absolute right-0 top-1/2 h-4 w-4 -translate-y-1/2 text-[#1A1712]/40" />
      </div>
    </label>
  );
}

function PropertyCard({
  property,
  index,
  saved,
  onToggle,
}: {
  property: Property;
  index: number;
  saved: boolean;
  onToggle: () => void;
}) {
  const pal = PALETTES[property.palette];
  return (
    <article
      className="haus-rise group flex flex-col border border-[#1A1712]/12 bg-[#FBFAF7] transition-all duration-300 hover:-translate-y-0.5 hover:border-[#1A1712]/35"
      style={{ animationDelay: `${index * 70}ms` }}
    >
      <div
        className="relative overflow-hidden"
        style={{ backgroundColor: pal.sky }}
      >
        <div className="aspect-[4/3] w-full">
          <Facade variant={property.facade} palette={pal} />
        </div>
        <span
          className={`${mono.className} absolute left-3 top-3 text-[10px] tracking-[0.18em]`}
          style={{ color: pal.ink }}
        >
          {property.kind.toUpperCase()}
        </span>
        <button
          type="button"
          onClick={onToggle}
          aria-label={saved ? "Remove from saved homes" : "Save this home"}
          aria-pressed={saved}
          className="absolute right-3 top-3 grid h-8 w-8 place-items-center rounded-full border transition-colors"
          style={{
            borderColor: saved ? "#B4552D" : `${pal.ink}44`,
            backgroundColor: saved ? "#B4552D" : "rgba(247,246,243,0.65)",
          }}
        >
          <Bookmark
            className="h-4 w-4"
            style={{ color: saved ? "#F7F6F3" : pal.ink }}
            fill={saved ? "#F7F6F3" : "none"}
          />
        </button>
      </div>
      <div className="flex flex-1 flex-col p-5">
        <div className="flex items-start justify-between gap-3">
          <h3 className="text-[17px] font-semibold leading-snug text-[#1A1712]">
            {property.name}
          </h3>
          <span
            className={`${mono.className} shrink-0 text-[15px] text-[#B4552D]`}
          >
            {usd(property.price)}
          </span>
        </div>
        <p
          className={`${mono.className} mt-1.5 flex items-center gap-1.5 text-[11px] text-[#1A1712]/50`}
        >
          <MapPin className="h-3 w-3 shrink-0" />
          <span className="truncate">{property.address}</span>
        </p>
        <p
          className={`${serifItalic.className} mt-4 text-[15px] leading-relaxed text-[#1A1712]/70`}
        >
          {property.caption}
        </p>
        <div className="mt-auto pt-5">
          <div
            className={`${mono.className} flex items-center gap-4 border border-[#1A1712]/12 pt-4 text-[12px] text-[#1A1712]/70`}
          >
            <span className="flex items-center gap-1.5">
              <Bed className="h-3.5 w-3.5" />
              {property.beds} bd
            </span>
            <span className="flex items-center gap-1.5">
              <Bath className="h-3.5 w-3.5" />
              {property.baths} ba
            </span>
            <span className="flex items-center gap-1.5">
              <Ruler className="h-3.5 w-3.5" />
              {property.sqft.toLocaleString("en-US")} sqft
            </span>
          </div>
          <p
            className={`${mono.className} mt-3 text-[10px] tracking-[0.14em] text-[#1A1712]/40`}
          >
            {property.era.toUpperCase()}
          </p>
        </div>
      </div>
    </article>
  );
}

/* ------------------------------------------------------------------ */
/* Page                                                                */
/* ------------------------------------------------------------------ */

export default function RealEstateTemplate() {
  const [menuOpen, setMenuOpen] = useState(false);
  const [location, setLocation] = useState("All areas");
  const [homeType, setHomeType] = useState("All types");
  const [price, setPrice] = useState("Any price");
  const [saved, setSaved] = useState<string[]>(["The Ridgeline House"]);

  const toggleSave = (name: string) =>
    setSaved((prev) =>
      prev.includes(name) ? prev.filter((n) => n !== name) : [...prev, name],
    );

  const filtered = PROPERTIES.filter(
    (p) =>
      (location === "All areas" || p.region === location) &&
      (homeType === "All types" || p.kind === homeType) &&
      priceMatch(p.price, price),
  );

  const activeFilters: { label: string; clear: () => void }[] = [];
  if (location !== "All areas")
    activeFilters.push({
      label: location,
      clear: () => setLocation("All areas"),
    });
  if (homeType !== "All types")
    activeFilters.push({
      label: homeType,
      clear: () => setHomeType("All types"),
    });
  if (price !== "Any price")
    activeFilters.push({ label: price, clear: () => setPrice("Any price") });

  const clearAll = () => {
    setLocation("All areas");
    setHomeType("All types");
    setPrice("Any price");
  };

  return (
    <div
      className={`${archivo.className} min-h-screen bg-[#F7F6F3] text-[#1A1712] antialiased selection:bg-[#B4552D] selection:text-[#F7F6F3]`}
    >
      <TemplateBackLink />
      <style>{`
        @keyframes haus-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
        @keyframes haus-lit { 0%, 100% { opacity: 1; } 50% { opacity: 0.72; } }
        @keyframes haus-sun { 0%, 100% { opacity: 1; } 50% { opacity: 0.72; } }
        @keyframes haus-drift { from { transform: translateX(-8px); } to { transform: translateX(8px); } }
        .haus-rise { opacity: 0; animation: haus-rise 0.8s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
        .haus-lit { animation: haus-lit 4s ease-in-out infinite; }
        .haus-sun { animation: haus-sun 6s ease-in-out infinite; }
        .haus-drift { animation: haus-drift 14s ease-in-out infinite alternate; }
        @media (prefers-reduced-motion: reduce) {
          .haus-rise, .haus-lit, .haus-sun, .haus-drift { animation: none; opacity: 1; }
        }
      `}</style>

      {/* Drafting-paper grid atmosphere */}
      <div
        aria-hidden
        className="pointer-events-none fixed inset-0 z-0"
        style={{
          backgroundImage:
            "linear-gradient(#1A1712 1px, transparent 1px), linear-gradient(90deg, #1A1712 1px, transparent 1px)",
          backgroundSize: "44px 44px",
          opacity: 0.03,
          maskImage:
            "radial-gradient(ellipse 100% 70% at 50% 0%, black 40%, transparent 82%)",
          WebkitMaskImage:
            "radial-gradient(ellipse 100% 70% at 50% 0%, black 40%, transparent 82%)",
        }}
      />

      {/* ── Nav ─────────────────────────────────────────────────── */}
      <header className="sticky top-0 z-40 border border-[#1A1712]/12 bg-[#F7F6F3]/85 backdrop-blur-md">
        <div className="mx-auto flex h-16 max-w-6xl items-center justify-between px-5 md:px-8">
          <a href="#" className="flex items-center">
            <Wordmark />
          </a>

          <nav className="hidden items-center gap-8 md:flex">
            {NAV_LINKS.map((link) => (
              <a
                key={link}
                href="#"
                className={`${archivo.className} text-[11px] uppercase tracking-[0.18em] text-[#1A1712]/60 transition-colors hover:text-[#1A1712]`}
              >
                {link}
              </a>
            ))}
          </nav>

          <div className="hidden items-center gap-5 md:flex">
            <a
              href="#"
              className={`${mono.className} text-[13px] text-[#1A1712]/70 transition-colors hover:text-[#1A1712]`}
            >
              (415) 555-0170
            </a>
            <a
              href="#listings"
              className="bg-[#B4552D] px-4 py-2 text-sm font-semibold text-[#F7F6F3] transition-colors hover:bg-[#9C4423]"
            >
              Book a tour
            </a>
          </div>

          <button
            type="button"
            onClick={() => setMenuOpen(!menuOpen)}
            aria-label="Toggle menu"
            className="md:hidden"
          >
            {menuOpen ? (
              <X className="h-5 w-5" />
            ) : (
              <Menu className="h-5 w-5" />
            )}
          </button>
        </div>

        {menuOpen && (
          <nav className="border border-[#1A1712]/12 px-5 py-4 md:hidden">
            {NAV_LINKS.map((link) => (
              <a
                key={link}
                href="#"
                className={`${archivo.className} block py-2.5 text-[13px] uppercase tracking-[0.16em] text-[#1A1712]/70`}
              >
                {link}
              </a>
            ))}
            <a
              href="#listings"
              onClick={() => setMenuOpen(false)}
              className="mt-3 block bg-[#B4552D] px-4 py-2.5 text-center text-sm font-semibold text-[#F7F6F3]"
            >
              Book a tour
            </a>
          </nav>
        )}
      </header>

      {/* ── Hero ────────────────────────────────────────────────── */}
      <section className="relative z-10">
        <div className="mx-auto grid max-w-6xl gap-12 px-5 pb-16 pt-14 md:grid-cols-[1.02fr_0.98fr] md:items-center md:gap-16 md:px-8 md:pb-24 md:pt-20">
          <div>
            <p
              className={`${mono.className} haus-rise mb-6 flex items-center gap-2.5 text-[11px] tracking-[0.24em] text-[#B4552D]`}
            >
              <span className="inline-block h-2 w-2 bg-[#B4552D]" />
              ARCHITECTURAL BROKERAGE — SINCE 2011
            </p>
            <h1
              className={`${archivo.className} haus-rise text-[2.7rem] font-extrabold uppercase leading-[0.98] tracking-[-0.02em] text-[#1A1712] md:text-[4.1rem]`}
              style={{ animationDelay: "80ms" }}
            >
              Houses with
              <br />
              <span
                className={`${serifItalic.className} font-normal normal-case text-[#B4552D]`}
              >
                good bones,
              </span>
              <br />
              sold plainly.
            </h1>
            <p
              className="haus-rise mt-7 max-w-md text-base leading-relaxed text-[#1A1712]/65 md:text-lg"
              style={{ animationDelay: "160ms" }}
            >
              HAUS is an architectural brokerage for modern homes — modernist
              landmarks, warehouse conversions, and newly drawn houses. We only
              list places worth the walk-through.
            </p>

            <div
              className="haus-rise mt-9 border border-[#1A1712]/15 bg-[#FBFAF7]"
              style={{ animationDelay: "240ms" }}
            >
              <div className="grid grid-cols-1 sm:grid-cols-[1fr_1fr_1fr_auto]">
                <div className="px-4 py-3">
                  <SelectField
                    label="LOCATION"
                    value={location}
                    options={LOCATIONS}
                    onChange={setLocation}
                  />
                </div>
                <div className="border border-[#1A1712]/12 px-4 py-3 sm:border sm:border-0">
                  <SelectField
                    label="TYPE"
                    value={homeType}
                    options={KINDS}
                    onChange={setHomeType}
                  />
                </div>
                <div className="border border-[#1A1712]/12 px-4 py-3 sm:border sm:border-0">
                  <SelectField
                    label="PRICE"
                    value={price}
                    options={PRICES}
                    onChange={setPrice}
                  />
                </div>
                <a
                  href="#listings"
                  className="flex items-center justify-center gap-2 bg-[#B4552D] px-6 py-4 text-sm font-semibold text-[#F7F6F3] transition-colors hover:bg-[#9C4423]"
                >
                  <Search className="h-4 w-4" />
                  Search homes
                </a>
              </div>
            </div>

            <p
              className={`${mono.className} haus-rise mt-7 text-[11px] tracking-[0.16em] text-[#1A1712]/40`}
              style={{ animationDelay: "320ms" }}
            >
              410 HOMES PLACED · MARIN TO SAVANNAH · BY APPOINTMENT
            </p>
          </div>

          {/* Hero architectural illustration */}
          <div className="haus-rise" style={{ animationDelay: "200ms" }}>
            <div className="border border-[#1A1712]/12 bg-[#F1EADF]">
              <div className="w-full" style={{ aspectRatio: "600 / 470" }}>
                <HeroIllustration />
              </div>
              <div className="flex items-center justify-between border border-[#1A1712]/12 px-4 py-3">
                <span
                  className={`${mono.className} text-[10px] tracking-[0.24em] text-[#1A1712]/45`}
                >
                  HAUS NO. 01
                </span>
                <span
                  className={`${serifItalic.className} text-sm text-[#1A1712]/70`}
                >
                  The Ridgeline House, Marin County
                </span>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* ── Listings ────────────────────────────────────────────── */}
      <section
        id="listings"
        className="relative z-10 border border-[#1A1712]/12"
      >
        <div className="mx-auto max-w-6xl px-5 py-20 md:px-8 md:py-28">
          <div className="mb-10 flex flex-wrap items-end justify-between gap-6">
            <div>
              <p
                className={`${mono.className} mb-4 text-[11px] tracking-[0.24em] text-[#B4552D]`}
              >
                SELECTED LISTINGS
              </p>
              <h2
                className={`${archivo.className} text-3xl font-semibold leading-[1.05] tracking-[-0.01em] md:text-[2.6rem]`}
              >
                Currently on the{" "}
                <span
                  className={`${serifItalic.className} font-normal text-[#B4552D]`}
                >
                  market
                </span>
                .
              </h2>
            </div>
            <p className={`${mono.className} text-[13px] text-[#1A1712]/50`}>
              {filtered.length} of {PROPERTIES.length} homes
            </p>
          </div>

          {activeFilters.length > 0 && (
            <div className="mb-8 flex flex-wrap items-center gap-2">
              <span
                className={`${mono.className} mr-1 text-[10px] tracking-[0.22em] text-[#1A1712]/40`}
              >
                FILTERED BY
              </span>
              {activeFilters.map((filter) => (
                <button
                  key={filter.label}
                  type="button"
                  onClick={filter.clear}
                  className="flex items-center gap-1.5 border border-[#1A1712]/20 px-3 py-1 text-sm text-[#1A1712]/80 transition-colors hover:border-[#B4552D] hover:text-[#B4552D]"
                >
                  {filter.label}
                  <X className="h-3 w-3" />
                </button>
              ))}
              <button
                type="button"
                onClick={clearAll}
                className={`${mono.className} ml-1 text-[11px] tracking-[0.14em] text-[#B4552D] underline-offset-4 hover:underline`}
              >
                CLEAR ALL
              </button>
            </div>
          )}

          {filtered.length > 0 ? (
            <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
              {filtered.map((property, i) => (
                <PropertyCard
                  key={property.name}
                  property={property}
                  index={i}
                  saved={saved.includes(property.name)}
                  onToggle={() => toggleSave(property.name)}
                />
              ))}
            </div>
          ) : (
            <div className="border border-[#1A1712]/15 bg-[#FBFAF7] px-6 py-20 text-center">
              <p
                className={`${serifItalic.className} text-2xl text-[#1A1712]/70`}
              >
                No homes match this search just yet.
              </p>
              <p
                className={`${mono.className} mx-auto mt-3 max-w-sm text-[12px] leading-relaxed text-[#1A1712]/45`}
              >
                Try widening the price or area — new listings post to the studio
                every Thursday.
              </p>
              <button
                type="button"
                onClick={clearAll}
                className="mt-7 inline-flex items-center gap-2 bg-[#B4552D] px-5 py-2.5 text-sm font-semibold text-[#F7F6F3] transition-colors hover:bg-[#9C4423]"
              >
                Clear filters
              </button>
            </div>
          )}
        </div>
      </section>

      {/* ── Neighborhoods ───────────────────────────────────────── */}
      <section className="relative z-10 border border-[#1A1712]/12 bg-[#F2EFE8]">
        <div className="mx-auto max-w-6xl px-5 py-20 md:px-8 md:py-28">
          <div className="mb-12 flex flex-wrap items-end justify-between gap-6">
            <div>
              <p
                className={`${mono.className} mb-4 text-[11px] tracking-[0.24em] text-[#B4552D]`}
              >
                WHERE WE WORK
              </p>
              <h2
                className={`${archivo.className} text-3xl font-semibold leading-[1.05] tracking-[-0.01em] md:text-[2.6rem]`}
              >
                Browse by{" "}
                <span
                  className={`${serifItalic.className} font-normal text-[#B4552D]`}
                >
                  neighborhood
                </span>
                .
              </h2>
            </div>
            <p className="max-w-xs text-sm leading-relaxed text-[#1A1712]/55">
              Six markets, one bench of agents who live in them. Every listing
              is walked before it is written up.
            </p>
          </div>

          <div className="grid gap-px border border-[#1A1712]/12 bg-[#1A1712]/12 sm:grid-cols-2 lg:grid-cols-5">
            {NEIGHBORHOODS.map((n) => (
              <a
                key={n.name}
                href="#listings"
                className="group flex flex-col bg-[#F2EFE8] p-6 transition-colors hover:bg-[#F7F6F3]"
              >
                <div className="flex items-start justify-between">
                  <p className={`${mono.className} text-3xl text-[#1A1712]`}>
                    {n.count}
                    <span className="text-base text-[#1A1712]/40"> homes</span>
                  </p>
                  <ArrowUpRight className="h-4 w-4 text-[#1A1712]/30 transition-colors group-hover:text-[#B4552D]" />
                </div>
                <h3 className="mt-6 text-lg font-semibold">{n.name}</h3>
                <p
                  className={`${mono.className} mt-1 text-[11px] tracking-[0.12em] text-[#1A1712]/45`}
                >
                  {n.place}
                </p>
                <p
                  className={`${serifItalic.className} mt-4 text-[15px] leading-relaxed text-[#1A1712]/65`}
                >
                  {n.note}
                </p>
              </a>
            ))}
          </div>
        </div>
      </section>

      {/* ── Process ─────────────────────────────────────────────── */}
      <section className="relative z-10 border border-[#1A1712]/12">
        <div className="mx-auto grid max-w-6xl gap-12 px-5 py-20 md:grid-cols-[0.8fr_1.2fr] md:gap-16 md:px-8 md:py-28">
          <div>
            <p
              className={`${mono.className} mb-4 text-[11px] tracking-[0.24em] text-[#B4552D]`}
            >
              THE PROCESS
            </p>
            <h2
              className={`${archivo.className} text-3xl font-semibold leading-[1.05] tracking-[-0.01em] md:text-[2.6rem]`}
            >
              How a HAUS{" "}
              <span
                className={`${serifItalic.className} font-normal text-[#B4552D]`}
              >
                purchase
              </span>{" "}
              goes.
            </h2>
            <p className="mt-6 max-w-sm text-base leading-relaxed text-[#1A1712]/65">
              From first brief to keys in hand, four steps and a single point of
              contact. No handoffs, no surprises at the closing table.
            </p>
            <a
              href="#listings"
              className={`${mono.className} mt-8 inline-flex items-center gap-2 border border-[#1A1712]/30 pb-1 text-[13px] tracking-[0.12em] text-[#1A1712]/70 transition-colors hover:border-[#B4552D] hover:text-[#B4552D]`}
            >
              START WITH THE LISTINGS
              <ArrowRight className="h-3.5 w-3.5" />
            </a>
          </div>

          <div className="divide-y divide-[#1A1712]/12 border-y border-[#1A1712]/12">
            {STEPS.map((step) => (
              <div key={step.no} className="flex gap-6 py-7">
                <span
                  className={`${mono.className} shrink-0 text-2xl text-[#B4552D]`}
                >
                  {step.no}
                </span>
                <div>
                  <h3 className="text-lg font-semibold">{step.title}</h3>
                  <p className="mt-2 text-[15px] leading-relaxed text-[#1A1712]/60">
                    {step.body}
                  </p>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* ── Stats band ──────────────────────────────────────────── */}
      <section className="relative z-10 bg-[#1A1712] text-[#F7F6F3]">
        <div className="mx-auto max-w-6xl px-5 py-16 md:px-8 md:py-20">
          <p
            className={`${mono.className} mb-10 text-[11px] tracking-[0.24em] text-[#C9754E]`}
          >
            BY THE NUMBERS
          </p>
          <div className="grid gap-px sm:grid-cols-2 lg:grid-cols-4">
            {STATS.map((stat) => (
              <div
                key={stat.value}
                className="border border-[#F7F6F3]/15 pl-5 pr-4"
              >
                <p
                  className={`${mono.className} text-4xl tracking-tight text-[#C9754E] md:text-5xl`}
                >
                  {stat.value}
                </p>
                <p className="mt-3 text-[13px] leading-snug text-[#F7F6F3]/55">
                  {stat.label}
                </p>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* ── Agents ──────────────────────────────────────────────── */}
      <section className="relative z-10 border border-[#1A1712]/12">
        <div className="mx-auto max-w-6xl px-5 py-20 md:px-8 md:py-28">
          <div className="mb-12 flex flex-wrap items-end justify-between gap-6">
            <div>
              <p
                className={`${mono.className} mb-4 text-[11px] tracking-[0.24em] text-[#B4552D]`}
              >
                THE AGENTS
              </p>
              <h2
                className={`${archivo.className} text-3xl font-semibold leading-[1.05] tracking-[-0.01em] md:text-[2.6rem]`}
              >
                People who read the{" "}
                <span
                  className={`${serifItalic.className} font-normal text-[#B4552D]`}
                >
                  drawings
                </span>
                .
              </h2>
            </div>
            <p className="max-w-xs text-sm leading-relaxed text-[#1A1712]/55">
              Small by design. Three partners, each anchored in one region, each
              with a decade of closings behind them.
            </p>
          </div>

          <div className="grid gap-px border border-[#1A1712]/12 bg-[#1A1712]/12 md:grid-cols-3">
            {AGENTS.map((agent) => (
              <div key={agent.name} className="flex flex-col bg-[#F7F6F3] p-7">
                <div className="flex items-center gap-4">
                  <span
                    className={`${archivo.className} grid h-14 w-14 place-items-center border border-[#1A1712]/20 text-lg font-semibold tracking-tight text-[#1A1712]`}
                  >
                    {initials(agent.name)}
                  </span>
                  <div>
                    <h3 className="text-lg font-semibold leading-tight">
                      {agent.name}
                    </h3>
                    <p
                      className={`${mono.className} mt-1 text-[11px] tracking-[0.12em] text-[#1A1712]/50`}
                    >
                      {agent.role}
                    </p>
                  </div>
                </div>
                <p
                  className={`${serifItalic.className} mt-5 text-[15px] leading-relaxed text-[#1A1712]/70`}
                >
                  {agent.note}
                </p>
                <div className="mt-auto flex items-center gap-4 pt-6">
                  <span
                    className={`${mono.className} text-[10px] tracking-[0.2em] text-[#1A1712]/40`}
                  >
                    {agent.area.toUpperCase()}
                  </span>
                  <a
                    href="#"
                    aria-label={`Call ${agent.name}`}
                    className="ml-auto text-[#1A1712]/50 transition-colors hover:text-[#B4552D]"
                  >
                    <Phone className="h-4 w-4" />
                  </a>
                  <a
                    href="#"
                    aria-label={`Email ${agent.name}`}
                    className="text-[#1A1712]/50 transition-colors hover:text-[#B4552D]"
                  >
                    <Mail className="h-4 w-4" />
                  </a>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* ── Testimonial ─────────────────────────────────────────── */}
      <section className="relative z-10 border border-[#1A1712]/12 bg-[#F2EFE8]">
        <div className="mx-auto max-w-4xl px-5 py-24 text-center md:px-8 md:py-32">
          <p
            className={`${serif.className} mb-4 text-5xl leading-none text-[#B4552D]`}
          >
            &ldquo;
          </p>
          <blockquote
            className={`${serif.className} text-2xl leading-[1.4] text-[#1A1712]/90 md:text-[2rem]`}
          >
            {PULL_QUOTE.quote}
          </blockquote>
          <figcaption className="mt-8">
            <p className="text-sm font-semibold">{PULL_QUOTE.name}</p>
            <p
              className={`${mono.className} mt-1.5 text-[11px] tracking-[0.14em] text-[#1A1712]/45`}
            >
              {PULL_QUOTE.detail}
            </p>
          </figcaption>
        </div>
      </section>

      {/* ── CTA ─────────────────────────────────────────────────── */}
      <section className="relative z-10 bg-[#B4552D] text-[#F7F6F3]">
        <div className="mx-auto max-w-6xl px-5 py-20 text-center md:px-8 md:py-28">
          <p
            className={`${mono.className} mb-6 text-[11px] tracking-[0.24em] text-[#F7F6F3]/70`}
          >
            START THE SEARCH
          </p>
          <h2
            className={`${archivo.className} mx-auto max-w-3xl text-4xl font-extrabold uppercase leading-[0.98] tracking-[-0.02em] md:text-6xl`}
          >
            Find the house
            <br />
            <span
              className={`${serifItalic.className} font-normal normal-case`}
            >
              that was drawn
            </span>
            <br />
            for you.
          </h2>
          <div className="mt-10 flex flex-wrap items-center justify-center gap-5">
            <a
              href="#listings"
              className="group inline-flex items-center gap-2 bg-[#F7F6F3] px-7 py-4 text-sm font-semibold text-[#1A1712] transition-transform hover:-translate-y-0.5"
            >
              Book a private tour
              <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
            </a>
            <span
              className={`${mono.className} text-[13px] tracking-[0.12em] text-[#F7F6F3]/80`}
            >
              (415) 555-0170
            </span>
          </div>
        </div>
      </section>

      {/* ── Footer ──────────────────────────────────────────────── */}
      <footer className="relative z-10 bg-[#17150F] text-[#F7F6F3]">
        <div className="mx-auto max-w-6xl px-5 py-16 md:px-8">
          <div className="grid gap-10 md:grid-cols-[1.3fr_repeat(4,0.7fr)]">
            <div>
              <Wordmark tone="light" />
              <p className="mt-5 max-w-[17rem] text-sm leading-relaxed text-[#F7F6F3]/45">
                An architectural brokerage for modern homes. Modernist,
                converted, and newly drawn — from Marin County to Savannah.
              </p>
            </div>
            {FOOTER_COLS.map((col) => (
              <nav key={col.title}>
                <p
                  className={`${mono.className} mb-4 text-[11px] tracking-[0.2em] text-[#F7F6F3]/35`}
                >
                  {col.title.toUpperCase()}
                </p>
                {col.links.map((link) => (
                  <a
                    key={link}
                    href="#"
                    className="block py-1.5 text-sm text-[#F7F6F3]/55 transition-colors hover:text-[#F7F6F3]"
                  >
                    {link}
                  </a>
                ))}
              </nav>
            ))}
          </div>
          <div className="mt-14 flex flex-wrap items-center justify-between gap-4 border border-[#F7F6F3]/10 pt-6">
            <p className={`${mono.className} text-[11px] text-[#F7F6F3]/35`}>
              &copy; 2026 HAUS PROPERTY, LLC.
            </p>
            <p
              className={`${mono.className} text-[11px] tracking-[0.16em] text-[#F7F6F3]/35`}
            >
              BY APPOINTMENT · CA DRE #01998271
            </p>
          </div>
        </div>
      </footer>
    </div>
  );
}

查看关联风格