/* Base styles, phase 0 through phase 3 (scaffold, operational pages,
   admin). Phase 4 (below) adds the public site's layout, brand colours and
   components without changing any of this. */

/* --- The design system ----------------------------------------------------
   Every colour, corner, type size and spacing step on this site is named
   here, and nothing outside this block invents its own. That rule is what
   makes the pages look designed rather than assembled: the same button on
   the home page, the FAQ and the admin screens is the same button, not three
   that happen to resemble one another.

   It holds for every surface — the public pages, the booking flow, the
   receipt pages and admin. A component may depart from a token only when a
   contrasting surface forces it, and then the reason is written next to it.

   Settled on 2026-09-17, after an audit found 33 distinct colours where the
   palette has nine, three near-identical navies used as overlays, sixteen
   different clamp() expressions, and .button defined twice in two places. */

:root {
  color-scheme: light;

  /* Brand colours, measured from VM LOG.png (CLAUDE.md, "Notes"). Contrast
     rules recorded there and followed throughout this file:
       - crimson on white: 7.0:1 — fine as text.
       - teal on white: 3.5:1 — large text only (headings), never body text.
       - gold on white: 1.7:1 — never as text on white; background only,
         with dark text on top.
       - body text on a teal background must stay dark (black on teal is
         6.0:1; white on teal is only 3.5:1). */
  --color-teal: #009999;
  --color-gold: #ffbf00;
  --color-gold-strong: #e6ac00; /* gold, one step down: button hover only */
  --color-crimson: #ab2330;

  /* Neutrals. */
  --color-ink: #1a1a1a;
  --color-ink-rgb: 26 26 26;
  --color-muted: #5a5a5a; /* 7.0:1 on white; the only grey for text */
  --color-background: #ffffff;
  --color-border: #d9d9d9;
  --color-neutral: #f0f0f0; /* the quietest filled surface: calendar days */
  --color-text: var(--color-ink);

  /* Dark surfaces. One navy, not three. The overlays used to be
     rgba(4,20,33), rgba(7,30,48) and rgba(11,39,66) — three colours nobody
     could tell apart, in three places. They are all this one now, at
     whatever alpha the surface needs. */
  --color-deep: #0b2742;
  --color-deep-rgb: 11 39 66;
  --color-surface: #fffaf2; /* the warm off-white: text on deep, soft panels */
  --color-surface-rgb: 255 250 242;

  /* The one warm accent, and the ink that is legible on it. */
  --color-accent: #f0784d;
  --color-on-accent: #30150d;
  --color-info: #176ca5;

  /* Message surfaces. */
  --color-notice: #fff3cd;
  --color-notice-soft: #fff8e1;
  --color-notice-border: #d9a441;
  --color-unavailable: #fdecea;

  /* Corners. Two of them: controls are nearly square, images are rounder.
     The pill and the circle exist for the two shapes that are neither. */
  --radius-control: 4px;
  --radius-image: 8px;
  --radius-pill: 999px;
  --radius-round: 50%;

  --motion-standard: 220ms ease;
  --motion-image: 500ms ease;

  /* The widest file of the photo open in the gallery lightbox. No cap by
     default; public/gallery.js sets it on the lightbox image per photo so
     that nothing is shown larger than its largest file. */
  --lightbox-file-width: 100vw;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--color-text);
  background: var(--color-background);
  line-height: 1.5;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Design round bug fix (2026-09-16): scoped away from .site-main below, so
   the public content pages can go full-bleed while the booking-flow and
   admin pages this same rule still targets (they render a plain <main>
   with no class) keep the exact narrow column they always had. */
main:not(.site-main) {
  padding: 1rem;
  max-width: 60rem;
  margin: 0 auto;
}

/* Phase 3: functional styling only for the operational pages (owner
   decision, fake checkout, admin) — not a design pass. Widened main for
   admin's tables via the .admin-nav presence is intentionally skipped;
   tables scroll horizontally on narrow screens instead. */

.admin-nav {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--color-border);
}

table {
  border-collapse: collapse;
  width: 100%;
  margin: 1rem 0;
  display: block;
  overflow-x: auto;
}

th,
td {
  border: 1px solid var(--color-border);
  padding: 0.4rem 0.6rem;
  text-align: left;
  vertical-align: top;
}

.banner {
  background: var(--color-notice);
  border: 1px solid var(--color-notice-border);
  padding: 0.75rem 1rem;
  border-radius: 4px;
  margin: 1rem 0;
}

form {
  margin: 0.5rem 0;
}

label {
  display: block;
  margin: 0.4rem 0;
}

details {
  margin: 0.5rem 0;
}

dt {
  font-weight: 700;
  margin-top: 0.5rem;
}

dd {
  margin-left: 0;
}

/* =======================================================================
   Phase 4 design round (2026-09-16): the public site. Mobile-first — every
   rule below applies from the narrowest screen up; @media (min-width)
   blocks only add layout for wider screens. Nothing here sets a fixed
   pixel width wider than 360px outside a media query, and the gallery band
   is the only element meant to scroll sideways (public/styles.css review,
   380px check — see the design round's report).
   ======================================================================= */

/* --- Self-hosted fonts ---------------------------------------------------
   @fontsource/cormorant-garamond and @fontsource/inter 5.3.0, copied to
   public/fonts/. Nothing here ever requests a font or stylesheet from an
   external host.

   Each weight is two files, as fontsource ships them: "latin" (a-z, and
   Latin-1, which holds æ ø å ç ö ü) and "latin-ext" (ğ ş ı İ and the rest).
   The unicode-range on each face tells the browser which file a character
   comes from, and it downloads only the files a page uses.

   Until 2026-11-05 only the latin-ext files were here, with no
   unicode-range. They hold no a-z, so every letter on the site fell back to
   Georgia and system-ui: Chromium reported 3 of the 19 characters in "What
   our guests say" from Cormorant Garamond (the spaces). `npm run
   check:design` now reads the files themselves and fails when a family and
   weight cannot draw the letters the site uses. */

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/cormorant-garamond-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/cormorant-garamond-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/cormorant-garamond-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/cormorant-garamond-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/inter-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/inter-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/inter-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/inter-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --font-serif: "Cormorant Garamond", Georgia, serif;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Five fixed type sizes, and three that scale with the viewport. Nothing
     on the site sets a font-size that is not one of these eight. */
  --fs-1: 0.875rem; /* 14px — small print, facts labels, nav */
  --fs-2: 1rem; /* 16px — body text, buttons, form fields */
  --fs-3: 1.25rem; /* 20px — sub-headings, card titles, facts values */
  --fs-4: 1.75rem; /* 28px — section headings (h2) */
  --fs-5: 2.75rem; /* 44px — page heading / hero name (h1) */

  /* Fluid sizes, for the display type the design round introduced. There
     were six slightly different clamp() expressions doing this work; three
     of them differed by a tenth of a rem, which nobody can see and everybody
     has to maintain. */
  --fs-lead: clamp(1.05rem, 1.6vw, 1.35rem); /* the sentence under a heading */
  --fs-display: clamp(2rem, 3.2vw, 4rem); /* large section headings */
  --fs-display-xl: clamp(3rem, 7vw, 7.5rem); /* the hero's own name */

  /* Air, in fixed steps: 56px on phones, 96px on wide screens. */
  --space-section: 56px;
  --content-max: 68ch;

  /* Fluid steps, for the full-bleed bands. The five gutters that used to be
     written out separately — clamp(1rem,7vw,8rem), clamp(1.5rem,8vw,9rem),
     clamp(2rem,7vw,8rem), clamp(2rem,7vw,7rem), clamp(2.5rem,7vw,6rem) —
     are these two. */
  --space-gutter: clamp(1.5rem, 8vw, 9rem); /* side padding on a wide band */
  --space-band: clamp(2rem, 7vw, 8rem); /* the air inside a band */
  --space-band-tall: clamp(3.5rem, 9vw, 9rem); /* the tallest band */
  --space-inset: clamp(1.5rem, 3vw, 3rem); /* padding inside a panel, not a band */
  --space-nav: 0.75rem; /* compact controls inside the navigation bar */
  --border-subtle: 1px solid var(--color-border);
}

@media (min-width: 900px) {
  :root {
    --space-section: 96px;
  }
}

body {
  font-family: var(--font-sans);
  font-size: var(--fs-2);
}

h1,
h2,
h3 {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 1.15;
  margin: 0 0 0.6em;
}

h1 {
  font-size: var(--fs-5);
  font-weight: 700;
  color: var(--color-teal); /* large text — headings only, never body copy */
}

h2 {
  font-size: var(--fs-4);
  color: var(--color-teal); /* large text (28px) — safe per the contrast note above */
}

h3 {
  font-size: var(--fs-3);
  color: var(--color-text); /* 20px semibold is borderline "large text"; kept dark rather than teal to stay unambiguously AA */
}

p {
  margin: 0 0 1em;
}

a {
  color: var(--color-crimson);
}

.tbd {
  color: var(--color-muted);
  font-size: var(--fs-1);
  font-style: italic;
}

.note {
  color: var(--color-muted);
  font-size: var(--fs-1);
}

.text-column {
  max-width: var(--content-max);
}

/* --- Public main: full-bleed, not a centred column ------------------------
   Bug fix (2026-09-16): the public content pages (Home, the villas index,
   each villa page, Location) render <main class="site-main"> (Layout.tsx,
   publicSite prop). .site-main itself carries no padding or max-width, so
   a full-bleed section (.hero, .full-bleed, .section-bleed) is already the
   full viewport width with nothing to escape. Every other top-level
   section gets the old 60rem/1rem-padding treatment at the section level
   instead of the <main> level, so it still reads as a centred column with
   a gutter, exactly as before — the constraint moved, it did not
   disappear. */

.site-main {
  padding: 0;
  margin: 0 auto;
  max-width: none;
}

.site-main > section {
  max-width: 60rem;
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
}

.site-main > section.hero,
.site-main > section.home-hero,
.site-main > section.page-hero,
.site-main > section.page-content-section,
.site-main > section.page-accent-section,
.site-main > section.full-bleed,
.site-main > section.section-bleed,
.site-main > section.three-keys,
.site-main > section.three-keys-summer,
.site-main > section.three-keys-action {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.site-main > .page-hero + .page-content-section,
.site-main > .page-content-section + .page-accent-section,
.site-main > .page-accent-section + .page-content-section {
  margin-top: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Home hero ------------------------------------------------------------ */

.home-hero {
  min-height: min(78svh, 48rem);
  position: relative;
  display: flex;
  align-items: end;
  overflow: hidden;
  isolation: isolate;
  color: var(--color-surface);
}

.home-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgb(var(--color-deep-rgb) / 0.78), rgb(var(--color-deep-rgb) / 0.14) 70%);
}

.home-hero-image {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.home-hero-copy {
  max-width: 42rem;
  padding: var(--space-band);
}

.home-hero-copy > p:first-child {
  margin: 0 0 1.1rem;
  font-size: var(--fs-1);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.home-hero-copy h1 {
  color: inherit;
  font-size: var(--fs-display-xl);
  line-height: 0.8;
  margin: 0 0 1.25rem;
}

.home-hero-copy > p:last-child {
  font-size: var(--fs-lead);
  margin: 0;
  max-width: 32rem;
}

.home-mobile-nav {
  display: none;
}

/* --- Home: Three keys -----------------------------------------------------
   The building reads as three distinct, full-height entrances. Each panel
   contains its own label and action; there is deliberately no central copy
   layered across the three villas. */

.three-keys {
  background: var(--color-deep);
  color: var(--color-surface);
}

.three-keys-panels {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  min-height: min(100svh, 58rem);
}

.three-keys-panel {
  position: relative;
  min-height: min(100svh, 58rem);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
  border-right: 1px solid rgb(var(--color-surface-rgb) / 0.38);
}

.three-keys-panel:last-child {
  border-right: 0;
}

.three-keys-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgb(var(--color-deep-rgb) / 0.08) 25%, rgb(var(--color-deep-rgb) / 0.82) 100%);
}

.three-keys-image {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms ease;
}

.three-keys-panel:hover .three-keys-image,
.three-keys-panel:focus-within .three-keys-image {
  transform: scale(1.04);
}

.three-keys-panel-copy {
  width: 100%;
  padding: var(--space-inset);
}

.three-keys-panel-copy h3 {
  color: inherit;
  font-size: var(--fs-display);
  line-height: 0.95;
  margin: 0 0 0.7rem;
}

.three-keys-panel-copy > p:not(.three-keys-floor) {
  margin: 0 0 1.2rem;
  font-size: var(--fs-1);
}

.three-keys-floor {
  margin: 0 0 4rem;
  font-size: var(--fs-1);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.three-keys-link {
  color: inherit;
  font-weight: 700;
  text-underline-offset: 0.25em;
}

.three-keys-link:focus-visible {
  outline: 3px solid var(--color-surface);
  outline-offset: 4px;
}

.site-main > section.three-keys-summer {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(14rem, 0.65fr);
  gap: var(--space-band);
  align-items: end;
  padding: var(--space-band-tall) var(--space-gutter);
  background: var(--color-info);
  color: var(--color-surface);
}

.three-keys-summer h2 {
  color: inherit;
  font-size: var(--fs-display-xl);
  line-height: 0.88;
  max-width: 18ch; /* the motto on two or three lines, not five */
  text-wrap: balance; /* no single word left alone on the last line */
  margin: 0 0 1.25rem;
}

.three-keys-summer p {
  max-width: 38rem;
  margin: 0;
  font-size: var(--fs-lead);
}

.three-keys-direct {
  border-top: 2px solid currentColor;
  padding-top: 1rem;
  font-weight: 700;
}

.site-main > section.three-keys-action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding: 1.1rem var(--space-gutter);
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-size: var(--fs-lead);
  font-weight: 700;
}

/* The sentence takes the room the link leaves, and the link moves to its
   own line when there is less than 14rem left. Before 2026-11-05 the band
   stacked only at 380px and below, through a rule whose selector lost to
   the one above, so from 381px to about 500px "Find dates for your stay."
   stood one word per line beside the link. */
.three-keys-action > span {
  flex: 1 1 14rem;
}

/* The blue band and the orange one are one statement; the section rhythm
   left a white strip between them. */
.site-main > .three-keys-summer + .three-keys-action {
  margin-top: 0;
}

.three-keys-action a {
  color: inherit;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.22em;
  white-space: nowrap;
}

.three-keys-action a span {
  display: inline-block;
  margin-left: 0.4rem;
  transition: transform 200ms ease;
}

.three-keys-action a:hover span,
.three-keys-action a:focus-visible span {
  transform: translateX(0.3rem);
}

@media (max-width: 899px) {
  .home-hero {
    min-height: 82svh;
  }

  .three-keys-panels {
    grid-template-columns: 1fr;
  }

  .three-keys-panel {
    min-height: 38rem;
    border-right: 0;
    border-bottom: 1px solid rgb(var(--color-surface-rgb) / 0.38);
  }

  .three-keys-panel:last-child {
    border-bottom: 0;
  }

  .site-main > section.three-keys-summer {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 380px) {
  .home-hero-copy {
    padding: 1.25rem;
  }

  .three-keys-panel {
    min-height: 31rem;
  }

  .three-keys-panel-copy {
    padding: 1.15rem;
  }

  .three-keys-floor {
    margin-bottom: 2.5rem;
  }

  .site-main > section.three-keys-summer {
    padding: 3.5rem 1rem;
  }
}

/* Used inside a full-bleed (.section-bleed) section for the parts that do
   need the ordinary gutter and centred width — typically its heading and
   intro text, sitting above a gallery band that itself bleeds to the
   edge. */
/* The heading that introduces a full-bleed band. It used to centre itself in
   a 60rem column, which at 1440px put it 148px to the right of every other
   heading on the same page: "Photos" on a villa page and "The area" on the
   home page both started at 249px while the rest started at 101px. It uses
   the same gutter as every other section now, so the left edge is one line
   down the page. */
.section-inner {
  padding: 0 var(--space-band);
}

/* A text column inside that band must not centre itself again: .villa-page
   .text-column gives it auto margins and a 76rem cap, which left the heading
   4px right of every other heading. The band has already set the gutter. */
.site-main .section-inner > .text-column {
  margin-inline: 0;
}

/* One consistent vertical rhythm between every top-level section on a
   public page, regardless of what each section contains. */
.site-main > section + section {
  margin-top: var(--space-section);
}

body.has-sticky-cta {
  padding-bottom: 0;
}

@media (max-width: 899.98px) {
  /* Keeps the fixed sticky bar clear of the footer by padding the whole
     page, not by changing the footer itself. */
  body.has-sticky-cta {
    padding-bottom: 4.75rem;
  }
}

/* --- Motion: fade + rise once, on scroll into view (public/reveal.js) ----
   [data-reveal] is fully visible by default. The script adds
   "reveal-pending" only when JavaScript runs and prefers-reduced-motion is
   not set, so a no-JS visitor and a reduced-motion visitor both see every
   section immediately. */

[data-reveal] {
  transition: opacity 400ms ease, transform 400ms ease;
}

[data-reveal].reveal-pending {
  opacity: 0;
  transform: translateY(14px);
}

/* --- Header ------------------------------------------------------------ */

.site-header {
  border-bottom: 1px solid var(--color-border);
  background: var(--color-background);
  position: relative;
  z-index: 40;
}

.site-header-overlay {
  background: transparent;
  border-color: transparent;
  color: var(--color-surface);
  left: 0;
  position: fixed;
  right: 0;
  top: 0;
  transition: background-color var(--motion-standard), border-color var(--motion-standard), color var(--motion-standard);
}

.site-header-overlay.is-scrolled,
.site-header.is-menu-open {
  background: var(--color-background);
  border-color: var(--color-border);
  color: var(--color-text);
}

.site-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-nav);
  padding: var(--space-nav) var(--space-band);
  max-width: 76rem;
  margin: 0 auto;
}

.site-logo img {
  height: 48px;
  width: auto;
}

.site-logo {
  align-items: center;
  color: inherit;
  display: flex;
  gap: var(--space-nav);
  text-decoration: none;
}

.site-logo-wordmark {
  font-family: var(--font-serif);
  font-size: var(--fs-3);
  font-weight: 700;
}

.site-menu-toggle {
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  font-size: var(--fs-1);
  font-weight: 700;
  letter-spacing: 0.14em;
  padding: var(--space-nav);
  position: relative;
  text-transform: uppercase;
  z-index: 1;
}

.site-menu-icon {
  display: grid;
  gap: var(--radius-control);
  width: var(--fs-3);
}

.site-menu-icon span {
  background: currentColor;
  height: var(--radius-control);
  width: 100%;
}

.site-nav {
  display: none;
}

.site-nav a {
  text-decoration: none;
  color: inherit;
  font-weight: 600;
  padding: var(--space-nav);
}

.site-nav a:hover,
.site-nav a:focus-visible,
.site-nav a[aria-current="page"] {
  color: var(--color-crimson);
}

.site-nav a[aria-current="page"] {
  box-shadow: inset 0 -0.18rem 0 var(--color-crimson);
  font-weight: 700;
}

.site-header-overlay:not(.is-scrolled):not(.is-menu-open) .site-nav a[aria-current="page"] {
  color: var(--color-surface);
  box-shadow: inset 0 -0.18rem 0 var(--color-surface);
  text-decoration: none;
}

/* Header booking button (content round, 2026-09-16): "Check dates" on a
   villa page, "See the villas" elsewhere — the wide-screen equivalent of
   the phone's fixed .sticky-cta bar below. Hidden below 900px on purpose:
   .sticky-cta already covers phones, from the exact same breakpoint, so
   the two never show on screen at the same time. */
/* Scoped to .site-header so source order cannot decide this. The button
   component further down also sets display, at the same specificity, so a
   bare .header-cta rule here lost to it and the phone showed the header
   button and the fixed bottom bar at the same time — the exact thing the
   note above says must never happen. */
.site-header .header-cta {
  display: none;
  flex-shrink: 0;
}

@media (min-width: 900px) {
  .site-menu-toggle {
    display: none;
  }

  .site-nav {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    font-size: var(--fs-1);
    gap: var(--space-nav);
    justify-content: center;
  }

  .site-nav {
    flex-wrap: nowrap;
  }

  .site-header .header-cta {
    display: inline-block;
  }
}

@media (max-width: 899px) {
  .site-header.is-menu-open .site-nav {
    align-items: center;
    background: var(--color-deep);
    display: flex;
    flex-direction: column;
    gap: var(--space-inset);
    inset: 0;
    justify-content: center;
    min-height: 100svh;
    padding: var(--space-band);
    position: fixed;
  }

  .site-header.is-menu-open .site-nav a {
    color: var(--color-surface);
    font-size: var(--fs-display);
    line-height: 1;
  }

  .site-header.is-menu-open .site-menu-toggle {
    color: var(--color-surface);
  }
}

/* --- Buttons -------------------------------------------------------------
   Defined once, here. There used to be two .button blocks several hundred
   lines apart, one setting the fill and one setting the border, so answering
   "what does a button look like" meant reading both.

   Three variants, and no more:
     .button-primary    gold fill — the one action a page is asking for
     .button-secondary  teal fill — an alternative, equal-weight action
     .button-transparent  crimson outline — quiet, or destructive

   .button on its own is the primary, so existing markup keeps working, and
   a bare <button type="submit"> is a primary too: on a form, submitting is
   the action being asked for. */

.button,
.button-primary,
.button-secondary,
.button-transparent,
button[type="submit"] {
  display: inline-block;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  font-family: var(--font-sans);
  font-size: var(--fs-2);
  font-weight: 600;
  padding: 0.75rem 1.5rem;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--motion-standard),
    border-color var(--motion-standard),
    color var(--motion-standard),
    transform var(--motion-standard);
}

.button,
.button-primary,
button[type="submit"] {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-ink); /* dark text on gold: safe contrast, see :root */
}

.button-secondary {
  background: var(--color-teal);
  border-color: var(--color-teal);
  color: var(--color-ink); /* dark text on teal, per the contrast rule */
}

.button-transparent {
  background: transparent;
  border-color: currentColor;
  color: var(--color-crimson);
}

/* `button[type="submit"]` above is an element-plus-attribute selector, which
   outranks a single class, so every submit button came out gold whatever
   variant it asked for — the decline, cancel and regenerate-token buttons all
   looked like the primary action of their page. These restate the variant at
   a specificity that wins. */
button[type="submit"].button-secondary {
  background: var(--color-teal);
  border-color: var(--color-teal);
  color: var(--color-ink);
}

button[type="submit"].button-transparent {
  background: transparent;
  border-color: currentColor;
  color: var(--color-crimson);
}

.button:hover,
.button:focus-visible,
.button-primary:hover,
.button-primary:focus-visible,
button[type="submit"]:hover,
button[type="submit"]:focus-visible {
  background: var(--color-gold-strong);
  border-color: var(--color-gold-strong);
}

.button-secondary:hover,
.button-secondary:focus-visible {
  background: var(--color-teal);
  border-color: var(--color-ink);
}

.button-transparent:hover,
.button-transparent:focus-visible {
  background: var(--color-crimson);
  color: var(--color-background);
  text-decoration: none;
}

.button:hover,
.button:focus-visible,
.button-primary:hover,
.button-primary:focus-visible,
.button-secondary:hover,
.button-secondary:focus-visible,
.button-transparent:hover,
.button-transparent:focus-visible,
button[type="submit"]:hover,
button[type="submit"]:focus-visible {
  transform: translateY(-1px);
}

/* --- Hero (Home and each villa page) -------------------------------------
   Phones: the image on top at about 58vh, text underneath. Wide screens: a
   split hero, image at about 55%, text at 45%, at least 100svh capped
   around 900px. Full-bleed comes from .site-main > section.hero above
   (zero padding, no max-width) — .hero itself needs no width rule of its
   own here. */

.hero {
  display: flex;
  flex-direction: column;
}

.hero-media {
  height: 58vh;
  overflow: hidden;
}

.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-content {
  padding: 1.75rem 1.25rem 2.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.hero-content h1 {
  margin-bottom: 0.2em;
}

.hero-line {
  font-size: var(--fs-3);
  max-width: var(--content-max);
}

.hero-actions {
  margin: 0.25rem 0;
}

.hero-note {
  font-size: var(--fs-1);
  color: var(--color-muted);
  max-width: var(--content-max);
}

/* --- Editorial heroes for public information pages ---------------------- */

.page-hero {
  min-height: min(74svh, 48rem);
  overflow: hidden;
  position: relative;
}

.page-hero-image,
.page-hero-image img {
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  width: 100%;
}

.page-hero::after {
  background: linear-gradient(90deg, color-mix(in srgb, var(--color-deep) 78%, transparent), color-mix(in srgb, var(--color-deep) 24%, transparent));
  content: "";
  inset: 0;
  position: absolute;
}

.page-hero-overlay {
  color: var(--color-surface);
  display: flex;
  flex-direction: column;
  gap: var(--space-inset);
  justify-content: end;
  margin: 0 auto;
  min-height: min(74svh, 48rem);
  padding: var(--space-band);
  position: relative;
  z-index: 1;
}

.page-hero-overlay p {
  font-size: var(--fs-1);
  font-weight: 700;
  letter-spacing: 0.12em;
  margin: 0;
  text-transform: uppercase;
}

.page-hero-overlay h1 {
  font-size: var(--fs-display-xl);
  line-height: 0.9;
  margin: 0;
  max-width: 12ch;
}

.page-content-section {
  padding: var(--space-band) 0;
}

.page-accent-section {
  background: var(--color-teal);
  color: var(--color-ink);
  padding: var(--space-band) 0;
}

/* Headings are teal on white by default. A teal section changes that
   relationship, so headings must explicitly inherit its dark text colour.
   Without this override the question existed in the DOM but disappeared
   against the teal FAQ band. */
.page-accent-section h2 {
  color: var(--color-ink);
}

.page-accent-section h3 {
  color: var(--color-ink);
}

.page-content-grid {
  align-items: start;
  display: grid;
  gap: var(--space-section);
}

/* Text-led page intros otherwise leave a misleading empty column below short
   copy. Centre the copy against its accompanying image instead. */
.page-content-grid-balanced {
  align-items: center;
}

.page-content-grid > .picture,
.page-content-grid > picture,
.page-content-grid > img {
  border-radius: var(--radius-image);
  overflow: hidden;
}

.page-content-grid .picture img,
.page-content-grid picture img,
.page-content-grid > img {
  display: block;
  height: 100%;
  min-height: 20rem;
  object-fit: cover;
  width: 100%;
}

.page-section-heading {
  font-size: var(--fs-5);
  margin-top: 0;
}

.page-list {
  display: grid;
  gap: var(--space-inset);
}

.page-list > section {
  border-top: var(--border-subtle);
  padding-top: var(--space-inset);
}

.page-accent-section .page-list > section {
  border-color: color-mix(in srgb, var(--color-deep) 28%, transparent);
}

@media (min-width: 900px) {
  .page-content-grid {
    grid-template-columns: minmax(0, 1fr) minmax(20rem, 0.82fr);
  }
}

/* --- About page (rebuilt 2026-09-29) --------------------------------------
   Intro centred under the logo with one wide photo, then alternating
   text-and-photo sections, the area on teal, and a contact band over a
   photo. Every value comes from a token. */

.about-intro .section-inner {
  text-align: center;
}

.about-intro p {
  margin-inline: auto;
  max-width: var(--content-max);
}

.about-intro-logo {
  display: block;
  height: auto;
  margin: 0 auto var(--space-inset);
  width: 5rem;
}

/* Picture puts these classes on the <img> itself, not on a wrapper. */
.about-wide-image {
  border-radius: var(--radius-image);
  display: block;
  height: auto;
  margin: var(--space-section) auto 0;
  max-width: min(64rem, 100%);
  width: 100%;
}

.about-area-photos img {
  border-radius: var(--radius-image);
  display: block;
  height: auto;
  width: 100%;
}

.about-eyebrow {
  font-size: var(--fs-1);
  letter-spacing: 0.08em;
  margin: 0 0 0.25rem;
  text-transform: uppercase;
}

.about-distances {
  max-width: 32rem;
}

.about-area-photos {
  display: grid;
  gap: var(--space-inset);
  margin-top: var(--space-section);
}

/* About alternates white and teal sections, so no two white sections stack
   their padding into a wide white gap. The contact band sits flush against
   the teal footer below. */
body:has(.about-contact-band) .site-footer {
  margin-top: 0;
}

.about-contact-band {
  overflow: hidden;
  position: relative;
}

.about-contact-image,
.about-contact-image img {
  display: block;
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  width: 100%;
}

.about-contact-overlay {
  background: rgb(var(--color-deep-rgb) / 0.55);
  color: var(--color-surface);
  padding: var(--space-band);
  position: relative;
  text-align: center;
}

.about-contact-overlay h2 {
  color: var(--color-surface);
}

.about-contact-overlay a:not(.button) {
  color: var(--color-surface);
}

/* --- Home: the six most popular facilities (2026-09-30) ------------------ */

.site-main > section.home-highlights {
  max-width: none;
  padding: var(--space-inset) var(--space-gutter);
}

.site-main > .three-keys + .home-highlights,
.site-main > .home-highlights + section {
  margin-top: 0;
}

.home-highlights-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem var(--space-inset);
  justify-content: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.home-highlights-list li {
  align-items: center;
  display: flex;
  font-weight: 600;
  gap: 0.5rem;
}

.home-highlights-list li > span {
  color: var(--color-teal);
  font-size: var(--fs-3);
}

/* --- Guest reviews band (2026-09-30) ------------------------------------- */

.site-main > section.reviews-band {
  max-width: none;
  padding: var(--space-band) 0;
}

/* The band carries its own padding, so it needs no section margin on
   either side; otherwise the two stack into a wide white gap. */
.site-main > section + .reviews-band,
.site-main > .reviews-band + section {
  margin-top: 0;
}

.reviews-band-inner {
  align-items: center;
  display: grid;
  gap: var(--space-section);
}

/* The two links stack at one width, so they read as a pair rather than two
   buttons of whatever width their words gave them. */
.reviews-links {
  display: grid;
  gap: 0.75rem;
  max-width: 22rem;
}

.reviews-links a {
  text-align: center;
}

/* The award graphics are never cropped, and they are not the same shape
   (400x400 and 400x467), so at one width they stood at two heights. Each
   item is an equal share of the row and a size container; each graphic is
   as tall as its item is wide (100cqw) and as wide as its own proportions
   then make it, from its width and height attributes. A browser without
   container units keeps the old height: auto. */
.reviews-awards {
  display: flex;
  gap: var(--space-inset);
  list-style: none;
  margin: 0;
  max-width: 36rem;
  padding: 0;
}

.reviews-awards li {
  container-type: inline-size;
  flex: 1 1 0%;
  min-width: 0;
}

.reviews-awards img {
  border-radius: var(--radius-image);
  display: block;
  height: auto;
  max-width: 100%;
  width: 100%;
}

@supports (height: 1cqw) {
  .reviews-awards img {
    height: 100cqw;
    width: auto;
  }
}

/* Two equal columns. The awards column used to be "auto", which is as wide
   as both graphics at full size; from 900px to about 1100px that left the
   text 75-180px wide, 21 lines for one paragraph. */
@media (min-width: 900px) {
  .reviews-band-inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* --- Location: nearby places (2026-09-29) --------------------------------- */

.sight-cards {
  display: grid;
  gap: var(--space-inset);
  margin-top: var(--space-inset);
}

.sight-card {
  background: var(--color-surface);
  border-radius: var(--radius-image);
  color: var(--color-text);
  padding: var(--space-inset);
}

.sight-card h3 {
  font-size: var(--fs-3);
  margin: 0;
}

.sight-card p {
  margin: 0.5rem 0 0;
}

.sight-card .sight-distance {
  font-size: var(--fs-1);
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-top: 0.25rem;
  text-transform: uppercase;
}

.sights-footnote {
  margin-top: var(--space-inset);
}

@media (min-width: 700px) {
  .sight-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .sight-cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 900px) {
  .about-grid-reversed {
    grid-template-columns: minmax(20rem, 0.82fr) minmax(0, 1fr);
  }

  .about-area-photos {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 900px) {
  .hero {
    flex-direction: row;
    align-items: stretch;
    /* min-height wins over max-height whenever the two disagree, so the old
       pair — min-height: 100svh with max-height: 900px — meant the cap never
       applied and the hero grew with the window. On a tall screen the photo
       ran past 1500px with the text marooned in the middle of the empty
       half. min() states what was meant: full height, but never past 900. */
    min-height: min(100svh, 900px);
  }

  .hero-media {
    width: 55%;
    height: auto;
  }

  .hero-content {
    width: 45%;
    justify-content: center;
    padding: 3rem 3.5rem;
  }
}

/* --- Full-bleed image band (e.g. the hero crop, further down the home
       page) ------------------------------------------------------------- */

.full-bleed-image {
  width: 100%;
  height: auto;
}

@media (min-width: 900px) {
  .full-bleed {
    height: 420px;
  }

  .full-bleed-image {
    height: 100%;
    object-fit: cover;
  }
}

/* --- Facts strip: directly under every hero ------------------------------
   Plain numbers, not icons. Values use crimson, not teal — at this size
   and weight they would not reliably clear the "large text" contrast
   threshold (CLAUDE.md), and crimson is safe as text at any size. */

.facts-strip {
  list-style: none;
  margin: 0;
  padding: 1.25rem 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem 1.5rem;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.facts-strip li {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.facts-strip-value {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: var(--fs-3);
  color: var(--color-crimson);
}

.facts-strip-label {
  font-size: var(--fs-1);
  color: var(--color-muted);
}

/* Villa detail sections use small, plain visual cues rather than a remote
   icon library. The information remains text-first for guests and crawlers. */
.villa-details h2 {
  margin-bottom: 0.75rem;
}

.amenity-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.7rem 1.25rem;
}

.amenity-grid li {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

.amenity-grid li > :first-child {
  width: 1.25rem;
  flex: 0 0 1.25rem;
  color: var(--color-crimson);
  font-weight: 700;
  text-align: center;
}

.tag-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.tag-list li {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 0.35rem 0.7rem;
}

.distance-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.5rem 1rem;
  margin: 0;
}

.distance-list dt,
.distance-list dd {
  margin: 0;
}

.distance-list dd {
  color: var(--color-crimson);
  font-family: var(--font-serif);
  font-weight: 600;
}

.price-from-note {
  color: var(--color-muted);
  font-size: var(--fs-1);
}

@media (min-width: 640px) {
  .facts-strip {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* --- Shared design system -------------------------------------------------
   Public, booking-flow, and operational pages share these primitives. A
   component may override them only when a contrasting surface needs it. */

/* --- Images ---------------------------------------------------------------
   Every framed image on the site has the same corner and the same hover:
   a slow, small lift in scale and saturation, never a different one per
   component. Admin thumbnails are included on purpose — they are the same
   photographs, and there is no reason for them to be squarer. */

.site-main picture img,
.villa-card-image,
.admin-thumb {
  border-radius: var(--radius-image);
  transition: transform var(--motion-image), filter var(--motion-image);
}

a:hover picture img,
a:focus-visible picture img,
.gallery-trigger:hover img,
.gallery-trigger:focus-visible img {
  filter: saturate(1.08);
  transform: scale(1.015);
}

/* The exception, with its reason: an image that runs to the edge of the
   screen has no corners to round. Rounding them would leave four white
   notches against the viewport edge. */
.home-hero-image,
.three-keys-image,
.hero-media img {
  border-radius: 0;
}

/* A villa page keeps a normal header only when it has no hero overlay. */
@media (min-width: 900px) {
  .villa-page .site-header:not(.site-header-overlay) {
    position: static;
  }
}

.villa-page .site-main > section:not(.hero):not(.section-bleed) {
  max-width: none;
  padding-left: var(--space-band);
  padding-right: var(--space-band);
}

.villa-page .text-column {
  max-width: 76rem;
  margin-left: auto;
  margin-right: auto;
}

.villa-page .villa-details p {
  max-width: 72ch;
  font-size: var(--fs-3);
}

.location-map {
  display: block;
  margin-top: var(--space-inset);
  overflow: hidden;
  position: relative;
}

.location-map img {
  aspect-ratio: 2 / 1;
  object-fit: cover;
  width: 100%;
}

.location-map-marker,
.location-map-action {
  border-radius: var(--radius-control);
  color: var(--color-surface);
  font-size: var(--fs-1);
  font-weight: 700;
  padding: var(--space-inset);
  position: absolute;
}

.location-map-marker {
  background: var(--color-crimson);
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.location-map-action {
  background: var(--color-deep);
  right: var(--space-inset);
  top: var(--space-inset);
}

.location-map-attribution {
  color: var(--color-muted);
  font-size: var(--fs-1);
}

.location-distances-section {
  padding: var(--space-inset) 0;
}

.transfer-price {
  border-left: 3px solid var(--color-crimson);
  margin: var(--space-inset) 0 0;
  padding-left: var(--space-inset);
}

/* Villa pages use the same sequence of strong bands as the selected home
   direction: image, deep facts, white gallery, teal amenities, white story,
   and a deep booking surface. They intentionally do not use [data-reveal]:
   this is structural rhythm, not animation. */
.villa-page .site-main > section + section {
  margin-top: 0;
}

.villa-hero {
  background: var(--color-deep);
  color: var(--color-surface);
  min-height: min(100svh, 900px);
  overflow: hidden;
  position: relative;
}

.villa-hero .hero-media,
.villa-hero .hero-media img {
  height: 100%;
  width: 100%;
}

.villa-hero .hero-media {
  position: absolute;
  inset: 0;
}

.villa-hero .hero-media::after {
  background: linear-gradient(90deg, rgb(var(--color-deep-rgb) / 0.84), rgb(var(--color-deep-rgb) / 0.28));
  content: "";
  inset: 0;
  position: absolute;
}

.villa-hero-overlay {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  justify-content: end;
  min-height: min(100svh, 900px);
  padding: var(--space-band-tall) var(--space-gutter);
  position: relative;
  z-index: 1;
}

.villa-hero h1 {
  color: inherit;
  font-size: var(--fs-display-xl);
  line-height: 0.8;
  margin: 0;
  max-width: 10ch;
}

.villa-hero-eyebrow,
.villa-section-eyebrow {
  font-size: var(--fs-1);
  font-weight: 600;
  letter-spacing: 0.14em;
  margin: 0;
  text-transform: uppercase;
}

.villa-hero .hero-line,
.villa-hero .hero-note {
  color: inherit;
  max-width: 34rem;
}

.villa-facts-band {
  background: var(--color-deep);
  color: var(--color-surface);
  padding: var(--space-inset) var(--space-band);
}

.villa-facts-band .facts-strip {
  border-color: rgb(var(--color-surface-rgb) / 0.3);
  margin: 0 auto;
  max-width: 76rem;
}

.villa-facts-band .facts-strip-value,
.villa-facts-band .facts-strip-label {
  color: inherit;
}

.villa-gallery {
  background: var(--color-background);
  padding: var(--space-band-tall) 0;
}

.villa-gallery h2,
.villa-details h2,
.villa-booking-section h2 {
  font-size: var(--fs-display);
  line-height: 0.9;
}

.gallery-shell-villa .gallery-band {
  gap: var(--space-inset);
  padding: 0 var(--space-band);
}

.gallery-shell-villa .gallery-band-item {
  flex-basis: min(72vw, 58rem);
}

.gallery-shell-villa .gallery-band-item-lead {
  flex-basis: min(84vw, 70rem);
}

.gallery-shell-villa[data-gallery-count="1"] .gallery-band-item {
  flex-basis: 100%;
}

.gallery-shell-villa .gallery-band-item img {
  aspect-ratio: 3 / 2;
  object-fit: cover;
  width: 100%;
}

.villa-amenities {
  background: var(--color-teal);
  color: var(--color-ink);
  padding: var(--space-band-tall) var(--space-band);
}

.villa-amenities-inner,
.villa-details-inner {
  margin: 0 auto;
  max-width: 76rem;
}

.villa-amenities h2 {
  color: inherit;
  font-size: var(--fs-display);
  line-height: 0.9;
  margin: 0.3rem 0 1rem;
}

.villa-amenities-source {
  margin: 0 0 var(--space-inset);
  max-width: var(--content-max);
}

.villa-amenities-grid {
  display: grid;
  gap: var(--space-band);
}

.villa-amenities .amenity-grid li {
  background: transparent;
}

.villa-amenities .amenity-grid li > :first-child {
  color: var(--color-ink);
  font-size: var(--fs-3);
  width: 1.5rem;
  flex-basis: 1.5rem;
}

.villa-amenities .tag-list li {
  background: var(--color-surface);
  border-color: var(--color-ink);
}

.villa-amenities-aside h3 {
  margin-top: 0;
}

.villa-amenities-aside h3 + .tag-list,
.villa-amenities-aside h3 + .distance-list {
  margin-bottom: var(--space-inset);
}

/* Everything in the villa, grouped (2026-09-30). Dark text on teal, per the
   contrast rule in :root. */
.amenity-groups-heading {
  border-top: 1px solid var(--color-ink);
  margin: var(--space-section) 0 var(--space-inset);
  padding-top: var(--space-inset);
}

.amenity-groups {
  display: grid;
  gap: var(--space-inset);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.amenity-group h4 {
  font-size: var(--fs-3);
  margin: 0 0 0.5rem;
}

.amenity-group ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.amenity-group li {
  padding: 0.2rem 0;
}

.villa-details {
  background: var(--color-background);
  padding: var(--space-band-tall) var(--space-band);
}

.villa-details p {
  font-size: var(--fs-lead);
  margin-bottom: 0;
}

.villa-booking-section {
  background: var(--color-deep);
  color: var(--color-surface);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-inset);
  padding: var(--space-band-tall) var(--space-band);
}

.villa-booking-section h2 {
  color: inherit;
}

.villa-booking-section .booking-copy {
  margin: 0;
  max-width: var(--content-max);
}

.villa-booking-section .booking-calendar,
.villa-booking-section .booking-form {
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-image);
  color: var(--color-text);
  margin: 0;
  padding: var(--space-inset);
}

.villa-booking-section .direct-note {
  color: var(--color-text);
}

@media (min-width: 900px) {
  .villa-hero-overlay {
    justify-content: center;
    max-width: 52rem;
  }

  .villa-amenities-grid {
    grid-template-columns: minmax(0, 1.4fr) minmax(18rem, 0.6fr);
  }

}

.shared-villa-details {
  background: var(--color-teal);
  color: var(--color-ink);
  max-width: none !important;
  padding: var(--space-band) var(--space-band) !important;
}

.shared-villa-details h2,
.shared-villa-details h3 {
  color: var(--color-ink);
}

.shared-villa-details-inner {
  max-width: 76rem;
  margin: 0 auto;
}

.shared-villa-details-grid {
  display: grid;
  gap: 2rem 4rem;
}

.shared-rules {
  border-top: 1px solid var(--color-border);
  margin-top: 2rem;
  padding-top: 1.5rem;
}

@media (min-width: 900px) {
  .shared-villa-details-grid {
    grid-template-columns: minmax(0, 1.35fr) minmax(18rem, 0.65fr);
  }
}

/* Full-panel links preserve the original panel hierarchy while making image,
   copy, and action one large target. The edge gradient replaces hard dividers. */
.three-keys-panel {
  color: var(--color-surface);
  text-decoration: none;
  border: 0;
}

.three-keys-panel::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: clamp(1.5rem, 4vw, 4rem);
  background: linear-gradient(90deg, rgb(var(--color-deep-rgb) / 0.55), transparent);
  z-index: -1;
}

.three-keys-panel:first-child::before {
  display: none;
}

.three-keys-panel .button-transparent {
  color: var(--color-surface);
}

.three-keys-panel .button-transparent:hover,
.three-keys-panel:focus-visible .button-transparent {
  background: var(--color-surface);
  color: var(--color-deep);
}

.three-keys-panel:focus-visible {
  outline: 3px solid var(--color-gold);
  outline-offset: -6px;
}

.three-keys-action .button-transparent {
  color: var(--color-on-accent);
}

.three-keys-action .button-transparent:hover,
.three-keys-action .button-transparent:focus-visible {
  background: var(--color-on-accent);
  color: var(--color-surface);
}

/* Gallery controls are functional buttons, placed at the band's outer edge,
   never as text painted over one photograph. */
.gallery-shell {
  position: relative;
}

/* On the same gutter as the section's heading and text (.section-inner),
   as the photos below are. Until 2026-11-05 both used 1rem, so the button
   and the first photo sat 16px from the edge under text that started at
   32px or more. */
.gallery-controls {
  display: flex;
  justify-content: flex-end;
  margin: 0 var(--space-band) 0.65rem;
}

.gallery-trigger {
  appearance: none;
  background: none;
  border: 0;
  cursor: zoom-in;
  display: block;
  padding: 0;
  width: 100%;
}

.gallery-more {
  position: relative;
  z-index: 1;
}

.gallery-lightbox {
  background: rgb(var(--color-deep-rgb) / 0.97);
  border: 0;
  color: var(--color-surface);
  height: 100vh;
  max-height: none;
  max-width: none;
  padding: var(--space-inset);
  width: 100vw;
}

.gallery-lightbox::backdrop {
  background: rgb(var(--color-deep-rgb) / 0.8);
}

.gallery-lightbox figure {
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 100%;
  justify-content: center;
  margin: 0;
}

.gallery-lightbox img {
  border-radius: var(--radius-image);
  max-height: calc(100vh - 8rem);
  /* Never wider than the photo's largest file (set by public/gallery.js), so
     nothing is upscaled; on a phone it may run under the arrow buttons. */
  max-width: min(var(--lightbox-file-width), calc(100vw - 2rem));
  object-fit: contain;
}

@media (min-width: 900px) {
  .gallery-lightbox img {
    max-width: min(var(--lightbox-file-width), calc(100vw - 8rem));
  }
}

.gallery-lightbox figcaption {
  margin-top: 0.75rem;
}

.gallery-lightbox button {
  background: rgb(var(--color-surface-rgb) / 0.1);
  border: 1px solid rgb(var(--color-surface-rgb) / 0.75);
  border-radius: var(--radius-round);
  color: var(--color-surface);
  cursor: pointer;
  font-size: var(--fs-4);
  height: 2.75rem;
  line-height: 1;
  position: absolute;
  width: 2.75rem;
}

.gallery-lightbox-close { right: 1rem; top: 1rem; }
.gallery-lightbox-prev { left: 1rem; top: 50%; }
.gallery-lightbox-next { right: 1rem; top: 50%; }

@media (min-width: 900px) {
  .facts-strip {
    grid-template-columns: repeat(6, 1fr);
  }
}

/* --- Villa cards (Home and the villas index) ------------------------------ */

/* The villas index introduction, above the cards in the same section. */
.villas-lead {
  margin-bottom: 2.5rem;
  max-width: var(--content-max);
}

.villas-lead p {
  margin: 0 0 0.75rem;
}

.villas-lead .villas-lead-intro {
  font-size: var(--fs-3);
}

.villa-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

.villa-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-image);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.villa-card-image {
  width: 100%;
  height: auto;
}

.villa-card-body {
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
}

.villa-card-body h2,
.villa-card-body h3 {
  margin: 0;
}

.villa-card-body p {
  margin: 0;
}

.villa-card-body .button {
  align-self: flex-start;
  margin-top: 0.25rem;
}

@media (min-width: 640px) {
  .villa-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 900px) {
  .villa-cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* --- Gallery band: a horizontal, scroll-snapped band of large, mostly
       portrait photos (design round, pattern 4). The only element on the
       page meant to scroll sideways. ---------------------------------- */

.gallery-band {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Lives inside a full-bleed (.section-bleed) section with zero padding
     of its own, so the band supplies its own left/right gutter — the
     "side padding must survive" even though the band itself reaches the
     edges as you scroll it. */
  padding: 0.25rem var(--space-band) 0.75rem;
  scroll-padding-inline: var(--space-band);
  -webkit-overflow-scrolling: touch;
  position: relative;
}

/* The cropped next image alone was too ambiguous. This overlay states that
   the band can scroll without taking focus or intercepting a drag. */
.gallery-band::after {
  content: none;
}

/* A share of the band's content box, which is narrower since the band took
   the text's gutter (2026-11-05): 70% of it is what 62% of the old one was. */
.gallery-band-item {
  flex: 0 0 70%;
  scroll-snap-align: start;
  margin: 0;
  position: relative;
}

.gallery-band-item img {
  border-radius: var(--radius-image);
}

.gallery-band-item figcaption {
  background: rgb(var(--color-deep-rgb) / 0.88);
  bottom: 0;
  color: var(--color-surface);
  font-size: var(--fs-1);
  left: 0;
  letter-spacing: 0.04em;
  padding: 0.45rem 0.6rem;
  position: absolute;
  text-shadow: 0 1px 2px rgb(var(--color-ink-rgb) / 0.65);
  text-transform: uppercase;
}

.gallery-band-item-lead {
  flex-basis: 86%;
}

@media (min-width: 900px) {
  .gallery-band-item {
    flex-basis: 26%;
  }

  .gallery-band-item-lead {
    flex-basis: 44%;
  }
}

/* Older, uniform-grid gallery (still used nowhere after this round, kept
   in case a future page needs a plain grid instead of the band above). */
.gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
  margin: 1rem 0;
}

.gallery img {
  border-radius: var(--radius-control);
  aspect-ratio: 3 / 4;
  object-fit: cover;
  width: 100%;
}

@media (min-width: 640px) {
  .gallery {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 900px) {
  .gallery {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* --- Booking / contact forms ---------------------------------------------- */

.booking-section {
  padding-top: 0.5rem;
}

.booking-copy {
  margin-bottom: 1.25rem;
}

.direct-note {
  background: var(--color-notice-soft);
  border-left: 4px solid var(--color-gold);
  padding: 0.6rem 0.8rem;
  font-weight: 600;
}

.form-row {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.booking-form input[type="text"],
.booking-form input[type="email"],
.booking-form input[type="tel"],
.booking-form input[type="date"],
.booking-form input[type="number"],
.booking-form textarea,
.booking-form select,
.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form input[type="tel"],
.contact-form input[type="date"],
.contact-form input[type="time"],
.contact-form input[type="number"],
.contact-form textarea,
.contact-form select {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-control);
  font: inherit;
  margin-top: 0.25rem;
}

/* Country code and number (src/views/PhoneField.tsx), 2026-09-29. */
.phone-field {
  border: 0;
  display: grid;
  gap: 0 1rem;
  margin: 0.4rem 0;
  min-width: 0;
  padding: 0;
}

.phone-field legend {
  font-weight: 700;
  padding: 0;
}

/* The airport transfer form's groups (2026-09-29). */
.transfer-fieldset {
  border: 1px solid currentColor;
  border-radius: var(--radius-control);
  margin: 1rem 0;
  min-width: 0;
  padding: 0.5rem 1rem 0.75rem;
}

.transfer-fieldset legend {
  font-weight: 700;
  padding: 0 0.25rem;
}

.choice-label {
  align-items: center;
  display: flex;
  gap: 0.5rem;
}

.field-hint {
  font-size: var(--fs-1);
  margin: 0.25rem 0 0;
}

.consent-label {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}

.consent-label input[type="checkbox"] {
  margin-top: 0.3rem;
  flex-shrink: 0;
}

/* Honeypot: hidden from sighted users and keyboard tab order, but still a
   real field a scripted spam submission is likely to fill in (plan.md
   step C.1 / step 14). Not display:none / visibility:hidden, which some
   bots skip filling on purpose; off-screen positioning is harder to detect. */
.honeypot {
  /* Standard "visually hidden" clip pattern: stays within normal document
     flow (unlike a large negative left offset), so it can never widen the
     page's scrollable area at any viewport width. */
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.price-display {
  font-weight: 700;
  padding: 0.5rem 0;
}

/* --- Booking calendar widget (public/booking.js) -------------------------- */

.booking-calendar {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-image);
  padding: 0.75rem;
  margin-bottom: 1rem;
}

.booking-calendar:empty {
  display: none;
}

/* The month on its own line above the two buttons on a phone; one row from
   900px, where both months show. The buttons had no style of their own and
   wrapped "‹ Previous month" onto three lines below 600px. */
.calendar-header {
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-bottom: 0.5rem;
}

.calendar-header strong {
  grid-column: 1 / -1;
  grid-row: 1;
  text-align: center;
}

.calendar-header button {
  appearance: none;
  background: transparent;
  border: 1px solid currentColor;
  border-radius: var(--radius-control);
  color: var(--color-ink);
  cursor: pointer;
  font: inherit;
  font-size: var(--fs-1);
  padding: 0.45rem 0.8rem;
  white-space: nowrap;
}

.calendar-header button:hover,
.calendar-header button:focus-visible {
  background: var(--color-ink);
  color: var(--color-surface);
}

/* On a phone only the first month shows, so only its name does. */
.calendar-label-second {
  display: none;
}

@media (min-width: 900px) {
  .calendar-header {
    grid-template-columns: auto 1fr auto;
  }

  .calendar-header strong {
    grid-column: auto;
    grid-row: auto;
  }

  .calendar-label-second {
    display: inline;
  }
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  text-align: center;
  font-size: var(--fs-1);
}

.calendar-months {
  display: grid;
  gap: var(--space-inset);
}

.calendar-month + .calendar-month {
  display: none;
}

@media (min-width: 900px) {
  .calendar-months {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .calendar-month + .calendar-month {
    display: block;
  }
}

.calendar-day {
  padding: 0.4rem 0;
  border-radius: var(--radius-control);
  background: var(--color-neutral);
  cursor: pointer;
  border: none;
  font: inherit;
}

/* A closed villa's read-only calendar uses spans (public/booking.js). */
span.calendar-day {
  cursor: default;
  display: block;
  text-align: center;
}

.calendar-day[disabled],
.calendar-day.is-taken {
  background: var(--color-unavailable);
  color: var(--color-muted); /* darker than the minimum-AA grey (#767676) on this light background, plus strikethrough — not colour alone */
  text-decoration: line-through;
}

.calendar-day[disabled] {
  cursor: not-allowed;
}

.calendar-day.is-selected {
  background: var(--color-teal);
  color: var(--color-ink); /* dark text on teal (6.0:1) — white on teal (3.5:1) fails AA at this small size */
  font-weight: 700;
}

.calendar-legend {
  font-size: var(--fs-1);
  margin-top: 0.4rem;
  color: var(--color-muted);
}

/* --- Sticky action bar (phones only) ---------------------------------------
   Design round, pattern 3: one calm, constant action. Hidden on wide
   screens, where the in-hero button already does the same job. */

.sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  background: var(--color-background);
  border-top: 1px solid var(--color-border);
  padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
  display: flex;
  justify-content: center;
  box-shadow: 0 -2px 10px rgb(var(--color-ink-rgb) / 0.08);
}

.sticky-cta .button {
  width: 100%;
  max-width: 28rem;
  text-align: center;
}

@media (min-width: 900px) {
  .sticky-cta {
    display: none;
  }
}

/* --- Footer ---------------------------------------------------------------- */

.site-footer {
  margin-top: var(--space-section);
  background: var(--color-teal);
  color: var(--color-ink); /* dark text on teal, per the contrast rule in :root */
}

.site-footer-inner {
  max-width: 60rem;
  margin: 0 auto;
  padding: 1.5rem 1rem;
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

.site-footer h2 {
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-2);
  margin: 0 0 0.5rem;
}

.footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--fs-1);
}

.footer-links a {
  color: var(--color-ink);
  text-decoration: underline;
}

.site-footer-copyright {
  text-align: center;
  padding: 0.75rem 1rem 1.25rem;
  margin: 0;
  font-size: var(--fs-1);
}

/* --- Admin: photo review thumbnails ---------------------------------------- */

.admin-thumb {
  object-fit: cover;
  border-radius: var(--radius-control);
}

/* --- Admin: availability calendar ----------------------------------------- */

.admin-calendar-section { margin: var(--space-section) 0; }
.admin-calendar-controls { display: flex; align-items: center; justify-content: space-between; gap: var(--space-nav); }
.admin-calendar-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--space-nav); margin-top: var(--space-inset); }
.admin-calendar-weekday { font-size: var(--fs-1); font-weight: 700; text-align: center; }
.admin-calendar-day { min-height: 4.5rem; padding: var(--space-nav); text-align: left; overflow: hidden; }
.admin-calendar-event { display: block; margin-top: 2px; padding: 2px; font-size: var(--fs-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-calendar-event-booking { background: var(--color-ink); color: var(--color-background); }
.admin-calendar-event-external { background: var(--color-teal); color: var(--color-ink); }
.admin-calendar-event-manual { background: var(--color-gold); color: var(--color-ink); }

.admin-filters { display: flex; flex-wrap: wrap; gap: var(--space-nav); align-items: end; }
.outbox-booking, .outbox-enquiries { margin: var(--space-inset) 0; padding: var(--space-inset); border: 1px solid var(--color-ink); border-radius: var(--radius-control); }
.outbox-message { margin: var(--space-nav) 0; }
.outbox-message time { display: block; font-size: var(--fs-1); }
.outbox-recipient { display: inline-block; padding: 2px var(--space-nav); font-size: var(--fs-1); font-weight: 700; }
.outbox-recipient-guest { background: var(--color-gold); color: var(--color-ink); }
.outbox-recipient-owner { background: var(--color-teal); color: var(--color-ink); }

/* --- Admin design round -------------------------------------------------- */
.admin-shell { max-width: 78rem; margin: 0 auto; padding: var(--space-section) var(--space-inset); }
.admin-kicker { margin: 0 0 var(--space-nav); color: var(--color-muted); font-size: var(--fs-1); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.admin-topbar { display:flex; justify-content:space-between; align-items:center; padding-bottom:var(--space-nav); border-bottom:1px solid var(--color-border); }
.admin-topbar form { margin:0; }
.admin-nav { gap: 0; margin: 0; padding: 0; border: 0; flex-wrap: wrap; }
.admin-nav a { display: grid; gap: 2px; min-width: max-content; padding: .65rem .85rem; color: var(--color-ink); text-decoration: none; border-bottom: 3px solid transparent; font-weight: 700; }
.admin-nav a[aria-current="page"] { color: var(--color-crimson); border-bottom-color: var(--color-crimson); }
.admin-nav-attention { color: var(--color-muted); font-size: var(--fs-1); font-weight: 500; }
.admin-page-header { border-top: 1px solid var(--color-border); margin-top: var(--space-nav); padding-top: var(--space-inset); }
.admin-page-header h1 { margin: 0; }
.admin-panel { margin: var(--space-inset) 0; padding: var(--space-inset); border: 1px solid var(--color-border); border-radius: var(--radius-image); background: var(--color-background); }
.admin-panel-accent { background: var(--color-surface); border-color: var(--color-notice-border); }
.admin-summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--space-nav); margin: var(--space-inset) 0; }
.admin-summary-card { padding: var(--space-inset); background: var(--color-deep); color: var(--color-surface); border-radius: var(--radius-image); }
.admin-summary-card h2 { color: inherit; margin-top: 0; }
.admin-status { display: inline-block; padding: .15rem .5rem; border-radius: var(--radius-pill); background: var(--color-neutral); font-weight: 700; font-size: var(--fs-1); }
.admin-status-warning { background: var(--color-gold); color: var(--color-ink); }
.admin-stack { display: grid; gap: var(--space-nav); }
.admin-list-row { display: grid; gap: var(--space-nav); align-items: center; padding: var(--space-inset); border-top: 1px solid var(--color-border); }
.admin-list-row > * { min-width: 0; }
.admin-list-row h2, .admin-list-row h3, .admin-list-row h4, .admin-list-row p, .admin-list-row code { overflow-wrap: normal; word-break: normal; }
.admin-breakable, .admin-panel code { display: block; width: 100%; min-width: 0; max-width: 100%; overflow-wrap: anywhere !important; word-break: break-all; }
.admin-photo-row .admin-thumb { width: 160px; height: 214px; }
.admin-list-row:first-child { border-top: 0; }
.admin-reply-actions { display: grid; gap: var(--space-nav); justify-items: start; }
.admin-list-row h2, .admin-list-row p { margin: 0; }
.admin-form-grid { display: grid; gap: var(--space-nav); }
.admin-form-grid label { display: grid; gap: .3rem; font-weight: 700; }
/* A checkbox belongs beside its words, not above them: .admin-form-grid label
   is a grid, which stacked every one of them. Both selectors are needed —
   `.admin-form-grid label` is a class plus an element, so it outranks a lone
   class, the same trap the submit buttons fell into. */
.admin-checkbox,
.admin-form-grid label.admin-checkbox { display: flex; align-items: center; gap: .5rem; }
/* Two competing actions on one page: sized to their words rather than
   stretched across the grid, so neither shouts over the other. */
.admin-form-grid .admin-action { justify-self: start; }
/* The history table is 322 px wide at a 380 px viewport, and its parent
   clipped the last column rather than scrolling it: the page did not overflow,
   so nothing flagged it, but the Note column could not be read at all. */
.admin-table-scroll { overflow-x: auto; }
.admin-shell .admin-checkbox input { flex: 0 0 auto; }
.admin-reference { color: var(--color-muted); overflow-wrap: anywhere; }
.admin-page-lede { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; }
.admin-shell label { gap: .45rem; }
.admin-login-form label { display: grid; gap: .45rem; font-weight: 700; }
.admin-shell input, .admin-shell select, .admin-shell textarea { padding: .65rem; border: 1px solid var(--color-border); border-radius: var(--radius-control); font: inherit; }
.admin-calendar-controls button, .admin-calendar-day { border:1px solid var(--color-border); border-radius:var(--radius-control); background:var(--color-background); color:var(--color-ink); font:inherit; }
.outbox-message p, .outbox-message pre { white-space:pre-wrap; overflow-wrap:anywhere; word-break:break-word; }
.admin-danger-note { color: var(--color-crimson); font-weight: 700; }
.admin-villa-tabs { display:flex; flex-wrap:wrap; gap:var(--space-nav); margin:var(--space-inset) 0; }
.admin-villa-tabs a { padding:.55rem .8rem; border:1px solid var(--color-border); border-radius:var(--radius-control); color:var(--color-ink); text-decoration:none; font-weight:700; }
.admin-villa-tabs .admin-tab-active { background:var(--color-deep); color:var(--color-surface); border-color:var(--color-deep); }
.admin-booking-cards { display: none; }
@media (max-width: 699px) { .admin-bookings-table { display:none; } .admin-booking-cards { display:grid; gap:var(--space-nav); } .admin-booking-card { display:grid; gap:var(--space-nav); padding:var(--space-inset); border:1px solid var(--color-border); border-radius:var(--radius-control); } .admin-booking-card h3,.admin-booking-card p { margin:0; } }
table[hidden] { display: none; }
@media (min-width: 700px) { .admin-list-row { grid-template-columns: minmax(0, 1.5fr) minmax(13rem, 1fr) auto; } .admin-photo-row { grid-template-columns: 160px minmax(13rem, 1fr) minmax(18rem, 1fr); align-items:start; } .admin-form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .admin-form-grid .admin-form-wide { grid-column: 1 / -1; } }

/* --- Wider screens ---------------------------------------------------------- */

@media (min-width: 640px) {
  .form-row {
    flex-direction: row;
  }

  .form-row label {
    flex: 1;
  }

  .phone-field {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  }

  .phone-field .field-hint {
    grid-column: 1 / -1;
  }

  .site-footer-inner {
    grid-template-columns: repeat(3, 1fr);
  }
}
