/* ==========================================================================
   Site chrome — header, menu and footer.

   Geometry measured off the live site at 1440 / 810 / 390, 2026-09-23.
   Colour comes from role tokens and type from role classes; the numbers here
   are box metrics, which is the one thing a token cannot carry.

   One header component (inc/header.php): a primary bar with an optional
   secondary-nav slot flush beneath it. The row is the menu button, the
   switcher (property pages), the wordmark and Book now; the sub-nav shows
   where the page has one. The shell clearance is set by --vv-shell-top.
   ========================================================================== */

/* ---------- Shared ----------
   An icon is a glyph that reads at the scale of the text beside it, so it
   sizes from the font by default. Without a default the SVG stretches to fill
   whatever box it lands in — the nav chevron rendered at 95px and pushed the
   whole nav row out of the header. Standalone controls set their own size. */
.vv-icon {
  display: block;
  flex: none;
  width: 1em;
  height: 1em;
}

/* ---------- Footer ---------- */
/* The footer ground is its own navy (#15304A), a shade darker than the
   emphasised band's Prime-blue. Measured off the live footer, 2026-09-21. */

.vv-skip-link {
  position: absolute;
  inset-block-start: var(--vv-gap-10);
  inset-inline-start: var(--vv-gap-10);
  z-index: 100;
  translate: 0 -200%;
}
.vv-skip-link:focus { translate: none; }

/* ---------- Shared chrome pieces ---------- */

.vv-logo-text {   /* type: heading-4 (inc/chrome.php) */
  width: auto;
  white-space: nowrap;
}

/* ---------- Property footer (inc/footer.php) ----------
   The live Alleppey and Kodungallur footer, measured off the Kodungallur
   Overview at 1440, 810 and 390, 2026-09-24 (Alleppey's live footer is a
   one-column stack; ours is Kodungallur's on both, #24). Type: the
   eyebrow, body, text-cta and body-small-sans roles (vv-type.css); their
   states are at the end of this file.

   40 above and below, rows 40 apart: the two contact groups (a 2-column
   grid, 80 apart), a rule, the mark and address beside Follow us on, a
   rule, the link columns (3 tracks on desktop and tablet), the
   copyright and legal links. Every row 40 apart; live's extra empty rows
   (under the columns, and under Follow us on on a phone) are gone (user,
   2026-10-11). */

footer.vv-footer-p {
  padding-inline: var(--vv-gutter);
  background-color: var(--vv-color-background-footer);
}

.vv-footer-p :where(p, ul, address, hr) { margin: 0; padding: 0; }
.vv-footer-p ul { list-style: none; }
.vv-footer-p li { display: flex; }   /* no inherited line box round a link */

.vv-footer-p__inner {
  display: flex;
  flex-direction: column;
  gap: var(--vv-gap-40);
  box-sizing: border-box;
  max-width: var(--vv-container);
  margin-inline: auto;
  padding-block: var(--vv-gap-40);
}

.vv-footer-p__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--vv-gap-40) 80px;
}
/* The identity row shares the link columns' three tracks: the property spans
   two, Follow us takes the third, over the last column (principles §133). */
.vv-footer-p__row--identity { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.vv-footer-p__row--identity > .vv-footer-p__identity { grid-column: span 2; }

/* Contacts: a label 10 over a line padded 8 above and below. Links and
   separators sit 15 apart; the WhatsApp line and the front office 10. */
.vv-footer-p__group {
  display: flex;
  flex-direction: column;
  gap: var(--vv-gap-10);
}
.vv-footer-p__line {
  display: flex;
  align-items: center;
  gap: var(--vv-gap-15);
}
.vv-footer-p__group > .vv-footer-p__line,
.vv-footer-p__stack { padding-block: 8px; }
.vv-footer-p__stack {
  display: flex;
  flex-direction: column;
  gap: var(--vv-gap-15);
}
.vv-footer-p__stack > .vv-footer-p__line { gap: var(--vv-gap-10); }

.vv-footer-p__contact {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.vv-footer-p__icon { flex: none; width: 20px; height: 20px; }

/* A header or menu line that is a phone, WhatsApp or email: the shared contact icon, then the text. */
.vv-header-contact { display: inline-flex; align-items: center; gap: var(--vv-gap-10); }
.vv-header-contact-icon { flex: none; width: 20px; height: 20px; }

/* Live draws each separator as a 1px line, 20 tall, inside a 3 by 22 box. */
.vv-footer-p__sep {
  flex: none;
  width: 3px;
  height: 22px;
  background: linear-gradient(var(--vv-color-text-default), var(--vv-color-text-default)) 1px 1px / 1px 20px no-repeat;
}

/* A 1px rule inside a 3px box, the content's full width. */
.vv-footer-p__rule {
  height: 3px;
  border: 0;
  background: linear-gradient(var(--vv-color-footer-rule), var(--vv-color-footer-rule)) 0 1px / 100% 1px no-repeat;
}

/* The property: its mark 20 from the name, the address 5 under the name,
   centred on the Follow us on block beside it. */
.vv-footer-p__identity {
  display: flex;
  align-items: center;
  gap: var(--vv-gap-20);
}
.vv-footer-p__mark { flex: none; width: 69px; height: 50px; color: var(--vv-color-text-default); }
.vv-footer-p__name {
  display: flex;
  flex-direction: column;
  gap: var(--vv-gap-5);
}

.vv-footer-p__follow {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
}
/* The glyph sits about 5 inside its 32px hit box: pulled out so it lines up with the label. */
.vv-footer-p__social { display: flex; gap: var(--vv-gap-20); margin-inline-start: calc(var(--vv-gap-5) * -1); }
.vv-footer-p__social a {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  color: var(--vv-color-text-default);
  transition: color var(--vv-motion-hover-duration) var(--vv-motion-hover-easing);
}
/* Dims with the footer's text links (white 70%, user 2026-10-11). */
.vv-footer-p__social a:is(:hover, :active) { color: var(--vv-color-footer-text-subtle); }
.vv-footer-p__social-icon { width: 27px; height: 27px; }

/* Link columns, on three tracks: heading 20 over the list; items 25 tall,
   10 apart. The legal row follows 40 down, like every other row. */
.vv-footer-p__cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--vv-gap-40) 80px;
}
.vv-footer-p__col {
  display: flex;
  flex-direction: column;
  gap: var(--vv-gap-20);
}
.vv-footer-p__links {
  display: flex;
  flex-direction: column;
  gap: var(--vv-gap-10);
}
.vv-footer-p__links li { display: flex; align-items: center; min-height: 25px; }

.vv-footer-p__legal,
.vv-footer-p__legal-links {
  display: flex;
  align-items: baseline;   /* the 12px copyright on the 15px links' baseline */
  gap: var(--vv-gap-40);
}

.vv-footer-p a:focus-visible,
.vv-footer-p__consent:focus-visible {
  outline: 2px solid var(--vv-color-focus);
  outline-offset: 2px;
}

/* Tablet: one 700px column; the groups stack 40 apart, the link columns stay. */
@media (max-width: 1200.98px) {
  .vv-footer-p__row { grid-template-columns: minmax(0, 1fr); }
  /* Live keeps the two contact groups' rows equal on a tablet only. */
  .vv-footer-p__row--contact { grid-auto-rows: 1fr; }
  .vv-footer-p__follow { min-height: 72px; }
  .vv-footer-p__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .vv-footer-p__row--identity > .vv-footer-p__identity { grid-column: auto; }
}

/* Phone: everything stacks. */
@media (max-width: 809.98px) {
  .vv-footer-p__line {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--vv-gap-15);
  }
  .vv-footer-p__stack > .vv-footer-p__line { gap: var(--vv-gap-15); }
  .vv-footer-p__sep { display: none; }
  .vv-footer-p__identity {
    flex-direction: column;
    align-items: flex-start;
  }
  .vv-footer-p__row--contact { grid-auto-rows: auto; }
  .vv-footer-p__cols { grid-template-columns: minmax(0, 1fr); }
  .vv-footer-p__legal {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--vv-gap-20);
  }
  .vv-footer-p__legal-links { gap: var(--vv-gap-20); }
}

/* ---------- Brand footer (inc/footer.php, brand pages) ----------
   Measured off the live homepage at 1440, 810 and 390, 2026-09-24. The
   property footer's pieces, arranged its own way: the reservations line,
   then — 80 below — four columns 20 apart (Follow us on the fourth; three
   and a wrap on a tablet, one on a phone), links 20 tall and 16 apart, an
   empty 40 row under them, the copyright 27 below that. No rules. */

footer.vv-footer-p--brand { background-color: var(--vv-color-background-footer-brand); }
.vv-footer-p--brand .vv-footer-p__inner { gap: 0; }
.vv-footer-p--brand .vv-footer-p__reach { margin-block-end: 39px; }
/* The hairline under the reservations: 1px of white at 10%, the container's
   full width on desktop and the screen's below it, the columns 40 under. */
.vv-footer-p__hairline {
  height: 1px;
  margin: 0 calc(var(--vv-gutter) * -1) 40px;
  border: 0;
  background-color: var(--vv-color-footer-hairline);
}
.vv-footer-p--brand .vv-footer-p__cols { gap: 50px 20px; }
.vv-footer-p--brand .vv-footer-p__cols { grid-template-columns: repeat(4, minmax(0, 1fr)); }   /* three link columns and Follow us */
.vv-footer-p__col--follow { padding-inline-end: 24px; }
.vv-footer-p--brand .vv-footer-p__legal { margin-block-start: var(--vv-gap-40); }
/* On desktop the content runs the container's width, aligned with the page
   above (principles §132); so does the hairline. */
@media (min-width: 1201px) {
  .vv-footer-p__hairline { margin-inline: 0; }
}

@media (max-width: 1200.98px) {
  .vv-footer-p--brand .vv-footer-p__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--vv-gap-40); }
  .vv-footer-p--brand .vv-footer-p__col--follow { min-height: 72px; }
}
@media (max-width: 809.98px) {
  .vv-footer-p--brand .vv-footer-p__line { gap: var(--vv-gap-20); }
  .vv-footer-p--brand .vv-footer-p__cols { grid-template-columns: minmax(0, 1fr); }
  .vv-footer-p--brand .vv-footer-p__reach { gap: var(--vv-gap-20); }
}

/* The careers footer (every /career page, measured 2026-10-03): the brand
   footer with HR's line and the corporate office side by side in place of
   the reservations line — the office 80 across on desktop, 72 under HR on a
   tablet. The address lines sit 3 apart, padded like a contact line. */
.vv-footer-p__office {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding-block: 8px;
  font-style: normal;
}
.vv-footer-p__office p { margin: 0; }
@media (max-width: 1200.98px) {
  .vv-footer-p--career .vv-footer-p__reach { row-gap: 71px; }
}
/* Phone: live tucks the address up under its label (15 from the label's
   top) and leaves 13 under it. */
@media (max-width: 809.98px) {
  .vv-footer-p--career .vv-footer-p__reach { row-gap: 42px; }
  .vv-footer-p--career .vv-footer-p__group > .vv-footer-p__line { padding-block-start: 10px; }
  .vv-footer-p--career .vv-footer-p__reach .vv-footer-p__group:has(.vv-footer-p__office) { gap: 0; }
  .vv-footer-p__office { margin-block-start: -1px; padding-block: 0 13px; }
}

/* ==========================================================================
   Property header — Alleppey and Kodungallur (inc/header.php).

   Measured off the live Overviews at 1440 / 810 / 390, 2026-09-24,
   Kodungallur's where the two differ (#25). The live insets are 40 (20 on a
   phone); ours are the normalised gutter (#5). Type from the header roles in
   vv-type.css; Book now is the primary button (design-principles.md §7a).
   ========================================================================== */

.vv-ph {
  position: fixed;
  inset: 0 0 auto;
  z-index: 12;
  background-color: var(--vv-color-surface);
}
.admin-bar .vv-ph { top: 32px; }

/* A hairline under the header, full width (user, 2026-10-18): under the
   sub-nav where it shows, else under the bar. A shadow, not a border, so the
   bar keeps its height and the sub-nav still sits flush. */
.vv-ph,
.vv-ph__subnav { box-shadow: 0 1px 0 var(--vv-color-line); }
.vv-ph-wrap:has(> .vv-ph__subnav) .vv-ph { box-shadow: none; }
@media (max-width: 1200.98px) {
  .vv-ph-wrap.vv-ph--property:has(> .vv-ph__subnav) .vv-ph { box-shadow: 0 1px 0 var(--vv-color-line); }
}
@media (max-width: 809.98px) {
  .vv-ph-wrap.vv-ph--brand:has(> .vv-ph__subnav) .vv-ph { box-shadow: 0 1px 0 var(--vv-color-line); }
}

/* One row: the lead group and Book now take equal shares either side, so
   the wordmark sits on the centre line, 40 clear of each. */
.vv-ph__bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  column-gap: 40px;
  box-sizing: border-box;
  height: var(--vv-pheader-h);
  padding: 20px var(--vv-gutter);
}

.vv-ph__lead {
  display: flex;
  align-items: center;
  gap: 20px;
  min-width: 0;
}

.vv-ph__end {
  display: flex;
  justify-content: flex-end;
  min-width: 0;
}

.vv-ph__logo { display: block; color: var(--vv-color-logo); }
/* Every logo link dims gently on hover: opacity, never colour. Its colour
   holds, so the theme's link hover never greys it (user, 2026-10-13). */
:is(.vv-ph__logo, .vv-pmenu__logo) { transition: opacity var(--vv-motion-hover-duration) var(--vv-motion-hover-easing); }
:is(.vv-ph__logo, .vv-pmenu__logo):is(:hover, :focus, :active) { color: var(--vv-color-logo); }
:is(.vv-ph__logo, .vv-pmenu__logo):hover { opacity: 0.7; }
.vv-ph__logo svg {
  display: block;
  width: auto;
  height: var(--vv-brand-logo-h);
}

/* The menu button: two grey bars, 10 apart, in a 40px box. It becomes a
   cross in the menu — the same bars, 30 long, crossed. Instant, as live. */
.vv-ph__burger {
  position: relative;
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.vv-ph__burger span {
  position: absolute;
  left: 4px;
  width: 32px;
  height: 2px;
  border-radius: 10px;
  background-color: var(--vv-color-icon-quiet);
}
.vv-ph__burger span:first-child { top: 14px; }
.vv-ph__burger span:last-child { top: 24px; }
.vv-ph__burger--close span:is(:first-child, :last-child) {
  top: 19px;
  left: 5px;
  width: 30px;
}
.vv-ph__burger--close span:first-child { transform: rotate(-45deg); }
.vv-ph__burger--close span:last-child { transform: rotate(45deg); }

/* ---------- Trail: Home / the property switcher ----------
   Home and the switcher share the button's 8px pad, so the two read as
   one line; the slash sits between them, quieter. */

.vv-ph__trail {
  display: flex;
  align-items: center;
  min-width: 0;
}
.vv-ph__trail .vv-ph__trail-sep,
.vv-ph__trail .vv-ph__trail-sep:hover { color: var(--vv-color-text-default); }   /* a divider, not a control */

.vv-ph__switch { position: relative; }

.vv-ph__switch-button,
.vv-ph__trail-home {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 8px;
  border: 0;
  border-radius: var(--vv-radius-sm);
  background: none;
  white-space: nowrap;
  cursor: pointer;
}

/* An up chevron turned down; it turns back up while the list is open. */
.vv-ph__switch-chevron {
  flex: none;
  transform: rotate(180deg);
  transition: transform var(--vv-motion-toggle-duration) var(--vv-motion-toggle-easing);   /* live 250ms ease */
}
.vv-ph__switch-button[aria-expanded="true"] .vv-ph__switch-chevron { transform: none; }

.vv-ph__switch-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 2;
  width: 200px;
  margin: 0;
  padding: 8px 0;
  list-style: none;
  background-color: var(--vv-color-background-highlight);
  border-radius: var(--vv-radius-sm);
  box-shadow: var(--vv-shadow-dropdown);
}
.vv-ph__switch-list[hidden] { display: none; }
.vv-ph__switch-list a {
  display: block;
  padding: 8px 16px;
}

/* ---------- Sub-nav (Kodungallur, desktop) ----------
   A white row under the header, fixed: it stays in place on scroll
   (user, 2026-10-04). Kept low: 10 above and below the links. */

.vv-ph__subnav {
  position: fixed;
  top: var(--vv-pheader-h);
  inset-inline: 0;
  z-index: 11;
  padding: 0 var(--vv-gap-20);
  background-color: var(--vv-color-surface);
}
.admin-bar .vv-ph__subnav { top: calc(32px + var(--vv-pheader-h)); }
.vv-ph__subnav > ul {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.vv-ph__subnav > ul > li > a {
  display: block;
  padding: 10px;
}
/* 40 tall (design principles §2): the label role's 25 leading is centred in
   a fixed row, so the padding no longer sets the height (type v5). */
.vv-ph__subnav > ul > li > a,
.vv-ph__subnav .vv-ph__drop-button {
  display: flex;
  align-items: center;
  block-size: 40px;
  padding-block: 0;
}

/* ---------- Menu (<dialog id="vv-pmenu">) ----------
   Slides in from the left over the dimmed page and is only as wide as its
   columns: the first holds the pages and the reservations; a page with a
   list (the rooms) opens it as a second column beside a hairline, and the
   other pages dim. On a phone it fills the screen and a list opens as a
   level of its own; the pages keep the desktop's left-aligned column, no
   hairlines (user, 2026-10-08). Closes at once. */

.vv-pmenu {
  box-sizing: border-box;
  inset: 0 auto 0 0;
  width: max-content;
  max-width: 100%;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0 var(--vv-gutter) var(--vv-gap-40);
  border: 0;
  overflow-y: auto;
  background-color: var(--vv-color-surface);
  color: var(--vv-color-text-default);
  transform: translateX(-100%);
}
.vv-pmenu[open] {
  display: flex;
  flex-direction: column;
}
.vv-pmenu.is-open {
  transform: none;
  transition: transform var(--vv-motion-surface-duration) var(--vv-motion-surface-easing);
}
.vv-pmenu::backdrop { background-color: var(--vv-color-overlay-panel); }
html:has(.vv-pmenu[open]) { overflow: hidden; }
/* Hiding the overflow takes away a classic (always-shown) scrollbar, and the
   page under the menu or booking panel jumped sideways by its width. The
   gutter is kept reserved, so the page stays put (user, 2026-10-13). */
html { scrollbar-gutter: stable; }

/* The wordmark at the left, the close at the right. */
.vv-pmenu__head {
  display: flex;
  flex: none;
  flex-direction: row-reverse;
  align-items: center;
  justify-content: space-between;
  gap: var(--vv-gap-40);
  height: var(--vv-pheader-h);
}
.vv-pmenu__logo { display: block; color: var(--vv-color-logo); }
.vv-pmenu__logo svg {
  display: block;
  width: auto;
  height: var(--vv-brand-logo-h);
}

.vv-pmenu__switch-row {
  display: flex;
  flex: none;
  padding-block: var(--vv-gap-10);
}
.vv-pmenu__name { display: none; }

.vv-pmenu__body {
  display: flex;
  flex: 1 0 auto;
  align-items: stretch;
  padding-top: var(--vv-gap-40);
}

/* Each column is as wide as its longest line (the first at least 270,
   the reservations email included), 50 clear of the hairline. */
.vv-pmenu__root {
  flex: none;
  box-sizing: border-box;
  width: max-content;
  min-width: 270px;
  padding-right: var(--vv-gap-50);
}

.vv-pmenu__links,
.vv-pmenu__sub-links {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}
.vv-pmenu__links { gap: var(--vv-gap-5); }

.vv-pmenu__link,
.vv-pmenu__sub-link,
.vv-pmenu__back {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vv-gap-10);
  box-sizing: border-box;
  width: 100%;
  padding-inline: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}
.vv-pmenu__link { padding-block: var(--vv-gap-10); }
.vv-pmenu__sub-link { padding-block: var(--vv-gap-10); }

/* An open list keeps its page at full strength; the others dim to the dim
   text colour (5.5:1, AA; user 2026-10-18; was 50% opacity, 2.7:1) and still
   turn terracotta on hover. */
.vv-pmenu__links:has([aria-expanded="true"]) .vv-pmenu__link:not([aria-expanded="true"], :hover) { color: var(--vv-color-text-dim); }

.vv-pmenu__chevron,
.vv-pmenu__back-chevron { flex: none; }
.vv-pmenu__chevron { transform: rotate(90deg); }
.vv-pmenu__back-chevron { transform: rotate(-90deg); }

/* The second column, behind a hairline that runs to the foot. */
.vv-pmenu__sub {
  flex: none;
  box-sizing: border-box;
  width: max-content;
  padding-inline: var(--vv-gap-50);
  border-left: 1px solid var(--vv-color-line);
}
.vv-pmenu__sub[hidden] { display: none; }
.vv-pmenu__back { display: none; }

.vv-pmenu__contact {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: var(--vv-gap-50);
}
.vv-pmenu__contact p {
  display: flex;   /* the line box is the link's own 20px, not the body's */
  margin: 0;
}
.vv-pmenu__contact-label { padding-bottom: var(--vv-gap-15); }
.vv-pmenu__contact p + p { padding-block: 10px; }

/* GeneratePress fills every button on hover and focus. These stay bare, in
   their role's colour unless a state sets another. */
:is(.vv-ph, .vv-ph__subnav, .vv-pmenu) button:not(.vv-button):is(:hover, :focus, :active) { background-color: transparent; }   /* the shared button keeps its own states */
.vv-ph__drop-button:focus:not(:hover, [aria-expanded="true"]) { color: var(--vv-color-text-default); }
.vv-ph__switch-button:focus:not(:hover, [aria-expanded="true"]) { color: var(--vv-color-text-default); }
button:is(.vv-pmenu__link, .vv-pmenu__back):focus:not(:hover, [aria-expanded="true"]) { color: var(--vv-color-text-default); }

:is(.vv-ph, .vv-ph__subnav, .vv-pmenu) :is(a, button):focus-visible {
  outline: 2px solid var(--vv-color-focus);
  outline-offset: 2px;
}

/* Tablet: the sub-nav goes. */
@media (max-width: 1200.98px) {
  .vv-ph__subnav { display: none; }

  /* Below desktop the trail leaves the bar; the menu carries it at every
     width: beside the menu button it would crowd the wordmark (user,
     2026-10-07). */
  .vv-ph__bar .vv-ph__trail { display: none; }
}

/* Phone: the menu fills the screen, the close at the left and the
   wordmark centred over a hairline; the pages as on desktop, left-aligned
   with no hairlines (user, 2026-10-08); a list replaces them, headed by a
   row back. */
@media (max-width: 809.98px) {
  .vv-ph__bar {
    grid-template-columns: auto auto minmax(0, 1fr);
    column-gap: var(--vv-gap-20);   /* 20 clear on a phone, so the brand logo fits (user, 2026-10-10) */
  }
  .vv-ph__lead { gap: 0; }

  .vv-pmenu { width: 100%; }
  .vv-pmenu__head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    border-bottom: 1px solid var(--vv-color-line);
  }
  /* The two levels move as Aman's menu does (user, 2026-11-11): going in,
     the pages vanish at once and the list slides in from the right; going
     back, the list vanishes at once and the pages drift in from the left
     as they fade up. Both stay rendered in one cell, so each can animate;
     only the arriving one has a transition. The header stays still. */
  .vv-pmenu__body {
    display: grid;
    padding-top: var(--vv-gap-20);   /* 20 under Home / Property, not 40 (user, 2026-11-11) */
    overflow: clip;   /* never scrolled, even by a focus moving to the list */
  }
  .vv-pmenu__root,
  .vv-pmenu__sub,
  .vv-pmenu__sub[hidden] {
    display: block;
    grid-area: 1 / 1;
    min-width: 0;
  }
  .vv-pmenu__root {
    max-width: 100%;   /* the desktop column, as wide as its longest line */
    padding-right: 0;
    transition:
      transform var(--vv-motion-sheet-duration) var(--vv-motion-sheet-easing),
      opacity var(--vv-motion-sheet-duration) var(--vv-motion-sheet-easing);
  }
  .vv-pmenu__body:has(.vv-pmenu__sub:not([hidden])) .vv-pmenu__root {
    opacity: 0;
    visibility: hidden;
    transform: translateX(-2rem);
    transition: none;
  }
  .vv-pmenu__sub {
    width: auto;
    padding-inline: 0;
    border-left: 0;
    transition: transform var(--vv-motion-sheet-duration) var(--vv-motion-sheet-easing);
  }
  .vv-pmenu__sub[hidden] {
    visibility: hidden;
    transform: translateX(100%);
    transition: none;
  }
  .vv-pmenu__back {
    display: flex;
    justify-content: flex-start;
    gap: var(--vv-gap-5);
    padding-block: var(--vv-gap-10);
  }
}

/* ---------- Brand pages ----------
   The same row without a switcher, 70 tall below desktop; the sub-nav shows
   on tablet too, its row 90 from the top at both widths, and opens with
   Destinations — the menu-link style, where the rest take the sub-nav's. */

.vv-ph--brand {
  --vv-brand-bar-h: var(--vv-pheader-h);
  --vv-brand-bar-pad: 20px;
}
.vv-ph--brand .vv-ph__bar {
  height: var(--vv-brand-bar-h);
  padding-block: var(--vv-brand-bar-pad);
}
.vv-ph--brand .vv-ph__subnav {
  top: var(--vv-brand-bar-h);
  padding: 0 var(--vv-gap-20);
}
.admin-bar .vv-ph--brand .vv-ph__subnav { top: calc(32px + var(--vv-brand-bar-h)); }
.vv-ph--brand .vv-ph__subnav > ul { align-items: center; }
/* Items never wrap: at 810 the row is a touch wider than its padded box and
   overflows both sides evenly, running edge to edge as live. */
.vv-ph__subnav > ul > li { flex: none; }
.vv-ph__subnav a { white-space: nowrap; }

.vv-ph__drop { position: relative; }
.vv-ph__drop-button {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: var(--vv-gap-10);
  border: 0;
  background: none;
  white-space: nowrap;
  cursor: pointer;
}
.vv-ph__drop-button[aria-expanded="true"] .vv-ph__switch-chevron { transform: none; }
.vv-ph__drop-list {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 200px;
  margin: 0;
  padding: 6px 0;
  list-style: none;
  background-color: var(--vv-color-background-highlight);
}
.vv-ph__drop-list[hidden] { display: none; }
.vv-ph__drop-list a {
  display: block;
  padding: 8px 16px;
}

@media (max-width: 1200.98px) {
  .vv-ph--brand {
    --vv-brand-bar-h: 70px;
    --vv-brand-bar-pad: 15px;
  }
  .vv-ph--brand .vv-ph__subnav { display: block; }
}
@media (max-width: 809.98px) {
  .vv-ph--brand .vv-ph__subnav { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .vv-pmenu.is-open { transition: none; }
}
/* Live, Destinations' chevron stays grey while its label turns red. */
.vv-ph__drop-button .vv-ph__switch-chevron { color: var(--vv-color-text-default); }

/* ---------- Booking panel (<dialog id="vv-book-modal">, inc/dialogs.php) ----------
   Measured off the live homepage 2026-09-24: 377 wide on the right at every
   width, full height, padded 40 / 20, the heading beside a 32px close, the
   widget 20 below; a 60% black overlay. Opens at once, as live. */
.vv-bookpanel {
  box-sizing: border-box;
  width: 377px;
  max-width: 100%;
  height: 100%;
  max-height: none;
  margin: 0 0 0 auto;
  padding: 40px 20px;
  border: 0;
  overflow-y: auto;
  background-color: var(--vv-color-background-panel);
}
.vv-bookpanel::backdrop { background-color: var(--vv-color-overlay-panel); }
html:has(.vv-bookpanel[open]) { overflow: hidden; }
.vv-bookpanel__head {
  display: flex;
  align-items: flex-start;
  margin-bottom: var(--vv-gap-20);
}
.vv-bookpanel__title { flex: 1; margin: 0; }
.vv-bookpanel__title:focus { outline: none; }
.vv-bookpanel__close {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--vv-color-text-default);
  cursor: pointer;
}
.vv-bookpanel__close:is(:hover, :focus, :active) { background: none; color: var(--vv-color-text-default); }
.vv-bookpanel__close:focus-visible { outline: 2px solid var(--vv-color-focus); outline-offset: 2px; }
.vv-bookpanel__close-icon { width: 32px; height: 32px; }

/* The shared contact icon in the legacy contact lines: inline with the text, text colour. */
.vv-contact-icon { width: 20px; height: 20px; margin-inline-end: var(--vv-gap-10); vertical-align: -4px; }

/* ---------- Link states (type v5: the old header/menu/footer roles' states) ----------
   The roles set the type and the colour at rest; these are the states.
   The property header's own controls (switcher, menu) turn Text-CTA on
   hover, when open or current; the sub-nav and the menu's contacts dim. */
.vv-ph__trail-home,
.vv-ph__switch-button,
.vv-ph__switch-link,
.vv-ph__drop-button,
.vv-ph__drop-link {
  text-decoration: none;
  transition: color var(--vv-motion-hover-duration) var(--vv-motion-hover-easing), opacity var(--vv-motion-hover-duration) var(--vv-motion-hover-easing);
}
:is(.vv-ph__trail-home, .vv-ph__switch-button, .vv-ph__switch-link, .vv-ph__drop-button, .vv-ph__drop-link):is(:hover, [aria-expanded="true"], [aria-current]) { color: var(--vv-color-text-cta); }
.vv-ph__subnav-link,
.vv-header-contact { transition: color var(--vv-motion-hover-duration) var(--vv-motion-hover-easing); }
.vv-ph__subnav-link { text-decoration: none; }
.vv-header-contact { text-decoration: none; }   /* a contact line is a plain link, no underline (user, 2026-10-13) */
/* One hover in the header: Rust Brown, as the trail, switcher and menu (user,
   2026-10-18; was the dim grey). The current page is rust with a 2px rust
   bar under it on the sub-nav's edge, over the hairline, so it differs from
   a hovered link by more than colour. */
.vv-ph__subnav-link:is(:hover, [aria-current]),
.vv-header-contact:hover { color: var(--vv-color-text-cta); }
.vv-ph__subnav > ul > li > [aria-current] { position: relative; }
.vv-ph__subnav > ul > li > [aria-current]::after {
  content: "";
  position: absolute;
  inset-inline: var(--vv-gap-10);
  bottom: -1px;
  block-size: 2px;
  background-color: var(--vv-color-text-cta);
}

/* The menu: links that turn terracotta on hover, when open or current; the
   other pages dim while a list is open (above). */
.vv-pmenu__link,
.vv-pmenu__back,
.vv-pmenu__sub-link {
  text-decoration: none;
  transition: color var(--vv-motion-hover-duration) var(--vv-motion-hover-easing), opacity var(--vv-motion-toggle-duration) var(--vv-motion-toggle-easing);
}
:is(.vv-pmenu__link, .vv-pmenu__back, .vv-pmenu__sub-link):is(:hover, [aria-expanded="true"], [aria-current]) { color: var(--vv-color-text-cta); }

/* Footers: quiet links, no underline at rest. The site footer's links turn
   Text-CTA on hover; the property footer's, sans 15 (text-cta role), turn
   white 70% on hover, press and the current page, and its group labels sit
   at white 70% (user, 2026-10-11). The property name stays full white. */
.vv-footer__link,
.vv-footer-p__link,
.vv-footer-p__contact {
  text-decoration: none;
  transition: color var(--vv-motion-hover-duration) var(--vv-motion-hover-easing);
}
.vv-footer__link:hover { color: var(--vv-color-text-cta); }
/* "Cookie settings" is a button (it reopens the banner; inc/consent.php)
   dressed as the legal links beside it. */
.vv-footer-p__consent {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.vv-footer-p__link:is(:hover, :active, [aria-current]) { color: var(--vv-color-footer-text-subtle); }
.vv-footer-p .vv-role-eyebrow:not(.vv-footer-p__name > *) { color: var(--vv-color-footer-text-subtle); }
.vv-footer__name { color: var(--vv-color-text-cta); }
