/* ==========================================================================
   Palace Group One — components.css
   Reusable UI shared across every page: header, mobile drawer, buttons,
   cards, brand strip, stats, footer.
   Each block below maps to one CMS partial / template part.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Buttons
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;gap:13px;
  font-family:var(--sans);font-size:var(--label);font-weight:600;
  letter-spacing:var(--label-track);text-transform:uppercase;
  padding:18px 38px;border:1px solid var(--text);color:var(--text);
  background:transparent;position:relative;overflow:hidden;
  transition:color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease);
}
.btn::before{
  content:'';position:absolute;inset:0;background:var(--gold);z-index:0;
  transform:translateY(101%);transition:transform var(--t-mid) var(--ease);
}
.btn:hover::before{transform:translateY(0)}
.btn > *{position:relative;z-index:1}
.btn .ar{transition:transform var(--t-fast) var(--ease)}
.btn:hover .ar{transform:translateX(6px)}

/* The hover fills used to go DARK, because the page was light. Inverted for
   the re-skin: on a dark page the fill has to be the amber (or white) and the
   label has to go dark with it, or the button just dims on hover. */
.btn:hover{color:var(--on-gold);border-color:var(--gold)}

.btn--gold{border-color:var(--gold);color:var(--on-gold);background:var(--gold)}
.btn--gold::before{background:#fff}
.btn--gold:hover{color:var(--on-gold);border-color:#fff}

.btn--light{border-color:rgba(255,255,255,.45);color:#fff}
.btn--light::before{background:#fff}
.btn--light:hover{color:var(--on-gold);border-color:#fff}

.btn--sm{padding:13px 24px}

/* text link with animated gold underline */
.link-u{
  display:inline-flex;align-items:center;gap:10px;position:relative;
  font-size:var(--label);font-weight:600;letter-spacing:var(--label-track);text-transform:uppercase;
  color:var(--text);padding-bottom:7px;
}
.link-u::after{content:'';position:absolute;left:0;bottom:0;height:1px;width:100%;
  background:var(--gold);transform:scaleX(0);transform-origin:right;
  transition:transform var(--t-mid) var(--ease)}
.link-u:hover::after{transform:scaleX(1);transform-origin:left}
.link-u .ar{transition:transform var(--t-fast) var(--ease)}
.link-u:hover .ar{transform:translateX(6px)}
.link-u--light{color:#fff}

/* --------------------------------------------------------------------------
   2. Site header  →  CMS partial: includes/header
   -------------------------------------------------------------------------- */
/* A SOLID bar sitting over the slider, not a transparent one that fills in on
   scroll. The reference is solid from the first pixel of scroll, and the amber
   block on its right edge only reads as a block if it has a bar to sit in. */
.site-header{
  position:fixed;inset:0 0 auto 0;z-index:100;
  background:var(--ink);
  transition:box-shadow var(--t-mid) var(--ease);
}
/* the old top scrim existed to lift white type off the photograph; a solid bar
   does that job, so it would only darken the bar's own top edge */
.site-header::before{display:none}
.site-header.is-solid{box-shadow:var(--shadow-sm)}

/* Logo dead centre of the PAGE, amber toggle block flush to the right edge.

   Three tracks, and column 1 is an empty spacer exactly as wide as the toggle
   in column 3 — that mirror is the only thing that puts the logo on the true
   centre rather than the centre of what is left over. Do not remove it.

   The bar is full-bleed: .wrap's max-width and gutter are overridden here, so
   the amber block reaches the viewport edge instead of stopping at the 1280px
   measure. That is why the toggle needs no absolute positioning. */
.site-header__inner{
  max-width:none;padding-inline:0;
  display:grid;grid-template-columns:var(--hdr-cta) minmax(0,1fr) var(--hdr-cta);
  align-items:center;min-height:var(--hdr-h);
}
.site-header__inner .logo{grid-column:2;grid-row:1;justify-self:center;min-width:0}
.site-header__inner .burger{grid-column:3;grid-row:1}

/* logo lockup — mark + wordmark */
.logo{display:flex;align-items:center;gap:13px;color:#fff;transition:color var(--t-mid) var(--ease)}
.logo__mark{
  width:46px;height:46px;flex:0 0 auto;
  background:url('../img/logo/logo-light.png') center/contain no-repeat;
  transition:width var(--t-mid) var(--ease),height var(--t-mid) var(--ease);
}
/* 700, and a size that fits beside a full nav rather than owning the centre */
.logo__text{font-family:var(--display);font-weight:700;font-size:21px;
  line-height:1.06;letter-spacing:0;white-space:nowrap}
.logo__text small{
  display:block;font-family:var(--sans);font-size:9px;font-weight:600;
  letter-spacing:.24em;text-transform:uppercase;opacity:.66;margin-top:5px;
}
/* The solid header is now DARK, so the dark-artwork logo would disappear into
   it. Both states use the light cut, and the mark no longer resizes on scroll. */
.site-header.is-solid .logo{color:#fff}
.site-header.is-solid .logo__mark{background-image:url('../img/logo/logo-light.png')}

/* Hidden below the desktop breakpoint, where the overlay behind the amber
   toggle carries all six links. The markup stays in the DOM so crawlers and a
   no-JS visitor still see the navigation; only the display is switched off.
   Both selectors, because `.has-js .nav` is (0,2,0) and would otherwise win. */
.nav,.has-js .nav{display:none}
html:not(.has-js) .nav{
  display:flex;align-items:center;justify-content:center;gap:18px;
  grid-column:1 / -1;grid-row:2;padding:0 var(--gutter) 12px;
}
html:not(.has-js) .nav__group{display:contents}
html:not(.has-js) .nav a{
  font-size:12px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:#fff;
}

/* --------------------------------------------------------------------------
   2b. Desktop header — three links, the logo, three links

   Requested 10 Oct 2026. Below this width nothing changes: the bar keeps the
   centred logo and the amber toggle, which is what tablets and phones get.

   display:contents on the <nav> is what makes this work with ONE navigation
   landmark. The two halves have to be grid items of .site-header__inner so
   they can take columns 1 and 3 around the logo — but wrapping them in two
   separate <nav> elements would announce two navigations to a screen reader,
   and there is only one. Dissolving the nav box lets its children become grid
   items while the element itself still carries aria-label="Primary".

   1024.02px, not 1025px. A viewport reports 1024.33 on a scaled display and
   `min-width:1025px` does not match it, so the pair 1024/1025 leaves a gap
   where neither layout applies — the same trap the header's old 900/901 pair
   had. Everything below is the default, so one query covers it.
   -------------------------------------------------------------------------- */
@media (min-width:1024.02px){
  /* The full-bleed override is undone — there is no amber block to reach the
     viewport edge any more.

     1560px, not --wrap's 1280px: the bar is a full-width dark band, and
     holding its contents to the page measure left a wide empty margin at each
     end while the links huddled against the logo. 1560 is the value already
     in the system as .wrap--wide, so this is not a number invented here. */
  .site-header__inner{
    max-width:1560px;
    padding-inline:var(--gutter);
    grid-template-columns:1fr auto 1fr;
  }

  .nav,.has-js .nav{display:contents}

  /* CENTRED in its half, not pushed against the logo.
     space-between was the other option and it is wrong here: at 1920px it
     would fling the three links 170px apart and they would stop reading as
     one group. Centring keeps the trio together and puts equal air on both
     sides of it, which is what balances the centred lockup. */
  .nav__group{
    display:flex;align-items:center;justify-content:center;grid-row:1;
    gap:clamp(20px,2.4vw,42px);
  }
  .nav__group--left {grid-column:1}
  .nav__group--right{grid-column:3}

  .site-header__inner .logo{grid-column:2;justify-self:center}

  .nav a{
    font-family:var(--sans);font-weight:500;
    font-size:clamp(16px,1.15vw,19px);
    color:rgba(255,255,255,.88);white-space:nowrap;
    transition:color var(--t-fast) var(--ease);
  }
  .nav a:hover,.nav a[aria-current]{color:var(--gold)}

  /*
   * The toggle and its overlay are a phone and tablet affordance now.
   *
   * Scoped to .site-header__inner — (0,2,0) — on purpose. The base
   * `.burger{display:flex}` lives further down the file in the drawer
   * section, so an unscoped `.burger{display:none}` here is the same
   * specificity and LOSES on source order: the amber block stayed on screen
   * stacked over the right-hand links, both claiming grid column 3.
   */
  .site-header__inner .burger{display:none}
}

/* --------------------------------------------------------------------------
   3. Mobile drawer
   -------------------------------------------------------------------------- */
/* THE TOGGLE IS THE AMBER BLOCK. In the reference that block is a "Get In
   Touch" button; here it is the menu control, because the brief is a centred
   logo with the toggle on the right. It fills its grid column edge to edge and
   runs the full height of the bar, so it reads as part of the bar rather than
   a button floating inside it.

   Present at EVERY width — there is no inline nav to replace it, so there is
   no breakpoint at which it should disappear. */
.burger{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  width:100%;height:var(--hdr-h);padding:0;
  background:var(--gold);position:relative;z-index:102;
  transition:filter var(--t-fast) var(--ease);
}
.burger:hover{filter:brightness(1.07)}
.burger:focus-visible{outline:2px solid #fff;outline-offset:-4px}
/* dark bars, because they sit on amber now and not on a photograph */
.burger span{display:block;width:clamp(20px,2.2vw,26px);height:2px;background:var(--on-gold);
  transition:transform var(--t-fast) var(--ease),opacity .25s var(--ease)}
.site-header.is-menu-open .burger span:nth-child(1){transform:translateY(8px) rotate(45deg)}
.site-header.is-menu-open .burger span:nth-child(2){opacity:0}
.site-header.is-menu-open .burger span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
/* The bar used to go transparent while the menu was open, because the overlay
   was the whole surface. It stays solid now — the amber block IS the close
   button and has to remain visible and legible on top of the overlay. */
.site-header.is-menu-open{box-shadow:none}
.site-header.is-menu-open .logo{color:#fff}

/* z-index 101 puts the overlay ABOVE the fixed header (100) so the wordmark
   cannot print through the menu. The toggle sits at 102 and stays clickable.
   Top padding clears the header band, so the first link can never slide
   underneath the logo. */
/* NOT justify-content:center — when the list is taller than the window, centring
   overflows equally at both ends, pushing the first link up under the header and
   out of reach. Auto margins centre the same way but collapse to zero once space
   runs out, so the content then starts cleanly at the top padding and scrolls. */
.drawer{
  position:fixed;inset:0;z-index:101;background:var(--ink);
  display:flex;flex-direction:column;justify-content:flex-start;
  padding-inline:clamp(24px,7vw,56px);
  /* derived from the bar height rather than guessed — the first link can never
     slide under the logo, whatever --hdr-h is set to */
  padding-block:calc(var(--hdr-h) + clamp(34px,6vh,66px)) clamp(60px,8vh,92px);
  overflow-y:auto;overscroll-behavior:contain;
  transform:translateX(100%);visibility:hidden;
  transition:transform var(--t-mid) var(--ease),visibility var(--t-mid);
}
.drawer a:first-of-type{margin-top:auto}
/* The header is position:fixed with a z-index, so it forms its own stacking
   context — raising the toggle or the logo INSIDE it cannot lift them above the
   overlay. The whole header has to move above the drawer instead, otherwise the
   close button is buried and unclickable. */
.site-header.is-menu-open{z-index:102}
.drawer.is-open{transform:none;visibility:visible}
.drawer a{
  font-family:var(--display);font-size:clamp(27px,7.5vw,38px);color:#fff;
  padding-block:15px;border-bottom:1px solid var(--line-light);
  opacity:0;transform:translateY(20px);
  transition:opacity var(--t-mid) var(--ease),transform var(--t-mid) var(--ease),color var(--t-fast);
}
.drawer a:hover{color:var(--gold-soft)}
.drawer.is-open a{opacity:1;transform:none}
.drawer.is-open a:nth-child(1){transition-delay:.16s}
.drawer.is-open a:nth-child(2){transition-delay:.22s}
.drawer.is-open a:nth-child(3){transition-delay:.28s}
.drawer.is-open a:nth-child(4){transition-delay:.34s}
.drawer.is-open a:nth-child(5){transition-delay:.40s}
.drawer.is-open a:nth-child(6){transition-delay:.46s}
/* in the flow, not absolute — an absolutely-placed footer collided with the last
   link once the list grew tall enough to fill the overlay */
.drawer__foot{
  margin-top:auto;padding-top:26px;
  font-size:var(--label);letter-spacing:var(--label-track);text-transform:uppercase;color:rgba(255,255,255,.4);
}
body.is-locked{overflow:hidden}

/* On wider screens the overlay is the whole navigation, so it is centred and
   given room rather than hugging the left edge as it does on a phone.
   Sizing uses vh as well as vw: six links at a vw-only size overflow a short
   laptop window. */
@media (min-width:760.02px){
  .drawer{align-items:center;text-align:center}
  .drawer a{
    font-size:min(4vw,6.2vh,48px);padding-block:min(1.1vh,12px);border-bottom:0;
    width:min(520px,60vw);
  }
  .drawer a + a{border-top:1px solid var(--line-light)}
  .drawer__foot{text-align:center;white-space:nowrap}
}

/* --------------------------------------------------------------------------
   4. Brand strip — infinite marquee  →  CMS: repeatable "Brand partners" field

   Markup: .brands__marquee > .brands__track > two identical .brands__set lists.
   The track animates to translateX(-50%), which is exactly one set's width, so
   the loop is seamless. The second set is aria-hidden — it is a visual duplicate
   and must never be announced twice.

   Adding or removing a brand? Edit BOTH sets so they stay identical in width.
   -------------------------------------------------------------------------- */
/* Bounded on BOTH edges. It only had a border-bottom, so on the About page —
   where it follows the core-values block rather than a photograph — the strip
   ran straight on from the copy above it with nothing to separate them.
   Same token as the bottom edge, so the two hairlines match. */
.brands{border-block:1px solid var(--line);background:var(--paper);overflow:hidden}
.brands__inner{
  display:flex;align-items:center;gap:clamp(20px,3vw,44px);padding-block:28px;
}
.brands__label{
  font-size:var(--label);font-weight:600;letter-spacing:var(--label-track);text-transform:uppercase;
  color:var(--body);opacity:.6;flex:0 0 auto;white-space:nowrap;
}

.brands__marquee{
  flex:1 1 auto;min-width:0;overflow:hidden;position:relative;
  /* soften both edges so items enter and leave instead of being chopped */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
}
.brands__track{
  display:flex;width:max-content;
  animation:brand-marquee 34s linear infinite;
  will-change:transform;
}
.brands__marquee:hover .brands__track{animation-play-state:paused}

.brands__set{
  display:flex;align-items:center;flex:none;
  gap:clamp(26px,3.2vw,52px);padding-right:clamp(26px,3.2vw,52px);
}
.brands__item{
  display:inline-flex;align-items:center;gap:clamp(26px,3.2vw,52px);
  font-family:var(--display);font-size:clamp(16px,1.5vw,23px);color:var(--text);
  opacity:.38;white-space:nowrap;transition:opacity var(--t-fast) var(--ease);
}
.brands__item:hover{opacity:1}
/* gold dot between brands, keeps the rhythm even while scrolling */
.brands__item::after{
  content:'';flex:none;width:4px;height:4px;border-radius:50%;
  background:var(--gold);opacity:.55;
}

/* --- real brand marks -----------------------------------------------------
   Supplied logos arrive with different backgrounds and wildly different aspect
   ratios, so they are pre-cut to transparent monochrome and then sized one by
   one. Matching their WIDTHS would make the tall stacked lockups (IHG, Choice)
   tiny and the wide ones (Wyndham) enormous — heights are tuned by eye instead. */
/* Full colour: these are the brand owners' own marks, and their guidelines
   generally require the official colourway rather than a recolour.

   Every logo gets an IDENTICAL box and is contained inside it. Sizing them by
   height alone produced widths from 55px to 125px, because the lockups differ
   so much — Wyndham and Marriott are wordmarks, IHG and Choice stack a mark
   above text. One shared box is what makes the row read as evenly weighted, and
   it holds at any browser zoom because every value scales together. */
.brands__logo{
  width:134px;height:62px;flex:0 0 auto;
  object-fit:contain;object-position:center;
  opacity:.9;
  transition:opacity var(--t-fast) var(--ease),transform var(--t-fast) var(--ease);
}
.brands__logo:hover{opacity:1;transform:translateY(-2px)}

@media (max-width:760px){
  .brands__logo{width:104px;height:48px}
}

@keyframes brand-marquee{
  from{transform:translateX(0)}
  to  {transform:translateX(-50%)}
}

/* No motion: drop the animation and let the row scroll by hand instead. */
@media (prefers-reduced-motion:reduce){
  .brands__track{animation:none}
  .brands__marquee{overflow-x:auto;-webkit-mask-image:none;mask-image:none}
  .brands__set:last-child{display:none}
}

/* --------------------------------------------------------------------------
   5. Pillar cards (3-up image cards)  →  CMS: "Homepage pillars" repeater
   -------------------------------------------------------------------------- */
.pillars{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,24px)}
.pillar{position:relative;display:block;aspect-ratio:3/3.7;overflow:hidden;background:var(--ink)}
.pillar picture{display:block;position:absolute;inset:0}
.pillar img,
.pillar .ph{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform 1.3s var(--ease-out)}
.pillar:hover img,
.pillar:hover .ph{transform:scale(1.07)}
.pillar__veil{position:absolute;inset:0;z-index:2;
  background:linear-gradient(to top,rgba(14,17,22,.9) 4%,rgba(14,17,22,.15) 58%)}
.pillar__body{position:absolute;left:0;right:0;bottom:0;z-index:3;padding:26px 26px}
.pillar__num{font-family:var(--display);font-size:12px;letter-spacing:.14em;
  color:var(--gold-soft);display:block;margin-bottom:10px}
.pillar h3{color:#fff}
.pillar__text{
  color:rgba(255,255,255,.72);font-size:var(--copy);line-height:1.7;margin-top:10px;
  max-height:0;opacity:0;overflow:hidden;
  transition:max-height var(--t-mid) var(--ease),opacity var(--t-mid) var(--ease),
             margin-top var(--t-mid) var(--ease);
}
.pillar:hover .pillar__text{max-height:120px;opacity:1}
.pillar__rule{width:32px;height:1px;background:var(--gold);margin-top:20px;
  transform-origin:left;transform:scaleX(0);transition:transform var(--t-mid) var(--ease)}
.pillar:hover .pillar__rule{transform:scaleX(1)}

/* --------------------------------------------------------------------------
   5b. Property card  →  CMS: CPT `property` archive item
   Used on the portfolio listing and in "related properties" on a detail page.
   -------------------------------------------------------------------------- */
.property-card{
  position:relative;display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--line);
  transition:border-color var(--t-mid) var(--ease),box-shadow var(--t-mid) var(--ease),
             transform var(--t-mid) var(--ease);
}
.property-card:hover{border-color:transparent;box-shadow:var(--shadow-md);transform:translateY(-5px)}

.property-card__media{position:relative;aspect-ratio:4/3;overflow:hidden;background:var(--ink)}
.property-card__media picture{display:block;position:absolute;inset:0}
.property-card__media img,
.property-card__media .ph{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform 1.2s var(--ease-out)}
.property-card:hover .property-card__media img,
.property-card:hover .property-card__media .ph{transform:scale(1.06)}

.property-card__flag{
  position:absolute;top:0;left:0;z-index:3;
  background:var(--ink);color:#fff;font-size:var(--label);font-weight:600;
  letter-spacing:var(--label-track);text-transform:uppercase;padding:8px 14px;
}
.property-card__tag{
  position:absolute;top:0;right:0;z-index:3;
  background:var(--gold);color:var(--on-gold);font-size:var(--label);font-weight:700;
  letter-spacing:var(--label-track);text-transform:uppercase;padding:8px 14px;
}

.property-card__body{padding:24px 24px 26px;display:flex;flex-direction:column;flex:1}
.property-card__body h3{font-size:clamp(18px,1.35vw,21px);line-height:1.25}
.property-card__addr{
  font-size:var(--copy);line-height:1.65;color:var(--body);margin-top:10px;flex:1;
}
.property-card__more{
  display:inline-flex;align-items:center;gap:9px;margin-top:18px;
  font-size:var(--label);font-weight:600;letter-spacing:var(--label-track);text-transform:uppercase;
  color:var(--text);
}
.property-card__more .ar{transition:transform var(--t-fast) var(--ease)}
.property-card:hover .property-card__more{color:var(--gold-deep)}
.property-card:hover .property-card__more .ar{transform:translateX(5px)}
/* the whole card is clickable, but only the title is a real link (a11y) */
.property-card__link::after{content:'';position:absolute;inset:0;z-index:4}

/* Book Now  →  CMS: a `booking_url` field on the `property` CPT.
   The URL is per-property and brand-operated, so it must be editable content,
   never hardcoded in the template.

   Solid amber, same language as the header toggle and the primary CTA: on a
   card whose only action this is, an outline button would under-sell it. The
   address above has flex:1, so this is pushed to the bottom of the card and
   the buttons line up across a row whatever the names and addresses wrap to.

   The "Coming Soon" card deliberately has none — there is nothing to book. */
.property-card__book{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  align-self:flex-start;margin-top:18px;
  font-family:var(--sans);font-size:var(--label);font-weight:600;
  letter-spacing:var(--label-track);text-transform:uppercase;
  color:var(--on-gold);background:var(--gold);
  padding:13px 22px;white-space:nowrap;
  transition:filter var(--t-fast) var(--ease);
}
.property-card__book:hover{filter:brightness(1.08)}
.property-card__book:focus-visible{outline:2px solid #fff;outline-offset:3px}
.property-card__book .ar{transition:transform var(--t-fast) var(--ease)}
.property-card__book:hover .ar{transform:translateX(5px)}
/* One card per row on a phone, so the button gets the full width and a
   comfortable tap target rather than hugging the left edge. */
@media (max-width:640px){
  .property-card__book{align-self:stretch;padding-block:15px}
}

/* --static: no detail page exists yet, so the CARD must not look interactive.
   Hover lift and image zoom are suppressed — an affordance with nowhere to go
   is worse than none. The Book Now link is a real control and is unaffected.
   Remove this modifier once property.html is built. */
.property-card--static{cursor:default}
.property-card--static:hover{transform:none;box-shadow:none;border-color:var(--line)}
.property-card--static:hover .property-card__media img,
.property-card--static:hover .property-card__media .ph{transform:none}

/* --------------------------------------------------------------------------
   5c. Value card  →  CMS: "Core values" repeater
   -------------------------------------------------------------------------- */
/* Was four bordered cards in a row, each with a small outline icon in a boxed
   square. Three problems: the uniform-card pattern the client has rejected
   elsewhere, icons that read as filler, and — once body copy went to 21px — a
   quarter-width column turning each value into an eight-line ribbon.

   Two columns give the copy a readable measure; the border, the hover lift and
   the icon are gone. A short gold rule opens each value instead. */
.values{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(30px,3.6vw,64px) clamp(34px,5vw,96px);
}
.value__rule{
  display:block;width:34px;height:2px;background:var(--gold);
  margin-bottom:clamp(16px,1.8vw,24px);
}
.value h3{font-size:clamp(21px,1.9vw,27px);line-height:1.2;margin-bottom:12px}
.value p{font-size:var(--copy);line-height:1.7;color:var(--body);max-width:46ch}

/* the band that replaced the icons — one wide photograph carrying the section */
.values-band{margin:0 0 clamp(34px,4.2vw,64px)}
.values-band picture{display:block}
.values-band img{width:100%;height:auto}

/* --------------------------------------------------------------------------
   5d. Form  →  CMS: contact + careers forms
   Shared by the Contact and Careers pages. Labels are visible rather than
   placeholder-only: placeholders vanish on focus and fail screen readers.
   -------------------------------------------------------------------------- */
.form{display:grid;grid-template-columns:1fr 1fr;gap:22px 24px}
.field{display:flex;flex-direction:column;gap:7px}
.field--full{grid-column:1/-1}
.field label{
  font-size:var(--label);font-weight:600;letter-spacing:var(--label-track);text-transform:uppercase;
  color:var(--body);
}
.field label .req{color:var(--gold-deep)}
.field input,.field select,.field textarea{
  width:100%;padding:12px 0;border:0;border-bottom:1px solid var(--line);
  background:transparent;font-family:var(--sans);font-size:15px;color:var(--text);
  border-radius:0;transition:border-color var(--t-fast) var(--ease);
}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:0;border-bottom-color:var(--gold);
}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--gold);outline-offset:3px;
}
.field textarea{resize:vertical;min-height:92px}
.field select{appearance:none;cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,var(--body) 50%),
                   linear-gradient(135deg,var(--body) 50%,transparent 50%);
  background-position:right 8px center,right 3px center;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:22px}
/* Custom dropdown (built by main.js from the native <select>).

   Chrome on Windows paints the select popup with an OS widget and ignores any
   padding set on <option>, so the list cannot be styled natively. main.js keeps
   the real <select> in the DOM — invisible but focusable, so `required` and the
   browser's own validation bubble still work — and renders this UI over it.
   With JavaScript off the native select is untouched and fully usable. */
.cselect{position:relative}
/* two classes, so this beats `.field select` and the padding really is zeroed */
.cselect .cselect__native{
  position:absolute;left:0;bottom:0;width:100%;height:1px;
  opacity:0;pointer-events:none;border:0;padding:0;margin:0;
}
.cselect__btn{
  width:100%;text-align:left;padding:12px 24px 12px 0;
  border:0;border-bottom:1px solid var(--line);background:transparent;
  font-family:var(--sans);font-size:15px;color:var(--text);cursor:pointer;
  transition:border-color var(--t-fast) var(--ease);
}
.cselect__btn::after{
  content:'';position:absolute;right:4px;top:50%;width:7px;height:7px;
  border-right:1px solid var(--body);border-bottom:1px solid var(--body);
  transform:translateY(-70%) rotate(45deg);
  transition:transform var(--t-fast) var(--ease),border-color var(--t-fast);
  pointer-events:none;
}
.cselect.is-open .cselect__btn{border-bottom-color:var(--gold)}
.cselect.is-open .cselect__btn::after{transform:translateY(-30%) rotate(225deg);border-color:var(--gold)}
.cselect__btn:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
.cselect__value.is-placeholder{color:#a4a8ad}

.cselect__list{
  position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:30;
  list-style:none;margin:0;padding:6px 0;
  background:var(--card);border:1px solid var(--line);box-shadow:var(--shadow-md);
  max-height:264px;overflow-y:auto;
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity var(--t-fast) var(--ease),transform var(--t-fast) var(--ease),
             visibility var(--t-fast);
}
.cselect.is-open .cselect__list{opacity:1;visibility:visible;transform:none}

.cselect__opt{
  padding:12px 18px;font-size:14.5px;line-height:1.45;color:var(--text);cursor:pointer;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
.cselect__opt.is-active{background:var(--gold);color:var(--on-gold)}
.cselect__opt[aria-selected="true"]{position:relative;font-weight:600}
.cselect__opt[aria-selected="true"]::before{
  content:'';position:absolute;left:7px;top:50%;width:4px;height:4px;
  border-radius:50%;background:var(--gold);transform:translateY(-50%);
}
/* file input — the browser button cannot be restyled, so we frame it instead */
.field input[type="file"]{
  padding:12px 14px;font-size:13.5px;color:var(--body);
  border:1px dashed var(--line);border-bottom:1px dashed var(--line);
  cursor:pointer;transition:border-color var(--t-fast) var(--ease),background var(--t-fast);
}
.field input[type="file"]:hover{border-color:var(--gold);background:var(--paper-warm)}
.field input[type="file"]::file-selector-button{
  margin-right:14px;padding:8px 16px;border:1px solid var(--ink);background:transparent;
  font-family:var(--sans);font-size:var(--label);font-weight:600;letter-spacing:var(--label-track);
  text-transform:uppercase;color:var(--text);cursor:pointer;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
.field input[type="file"]:hover::file-selector-button{background:var(--gold);color:var(--on-gold)}
.field__hint{font-size:12.5px;color:var(--body);opacity:.85}
/* was #B3261E, a dark red chosen for a white page; 2.4:1 on the navy. */
.field__error{font-size:12px;color:#FF7A70;display:none}
.field__error.is-shown{display:block}

.form__note{grid-column:1/-1;font-size:12.5px;line-height:1.7;color:var(--body)}
.form .btn{justify-content:center}

/* submitted state — replaces the form until the page is reloaded */
.form-done{
  border:1px solid var(--gold);background:var(--paper-warm);
  padding:34px 30px;display:none;
}
.form-done.is-shown{display:block}
.form-done h3{font-size:22px;margin-bottom:10px}
.form-done p{font-size:var(--copy);color:var(--body)}


/* --------------------------------------------------------------------------
   6. Stats band  →  CMS: "Key metrics" repeater
   -------------------------------------------------------------------------- */
/* Solid band, no photograph — the same treatment Five Star Group uses for its
   key-metrics strip. A stock interior shot behind the numbers read as filler and
   fought with the figures for attention. Two soft radials stop it going flat.
   To put an image back: add <picture> + .metrics__veil and the rules below
   already handle it. */
.metrics{
  position:relative;overflow:hidden;background:var(--ink);
  background-image:
    radial-gradient(80% 120% at 12% 0%, rgba(249,190,60,.13), transparent 60%),
    radial-gradient(70% 110% at 92% 100%, rgba(52,78,110,.55), transparent 62%);
}
.metrics picture{display:block;position:absolute;inset:0}
.metrics img,
.metrics .ph{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.metrics__veil{position:absolute;inset:0;background:rgba(20,41,59,.86)}
.metrics__inner{position:relative;z-index:2;
  display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(24px,3vw,40px)}
.metric{text-align:center;position:relative}
.metric__rule{margin-block:14px}
.metric + .metric::before{content:'';position:absolute;left:calc(-1 * clamp(12px,1.5vw,20px));
  top:14%;bottom:14%;width:1px;background:var(--line-light)}
.metric__num{font-family:var(--display);font-size:clamp(42px,5.2vw,72px);
  line-height:1;color:#fff;display:block}
.metric__rule{width:26px;height:1px;background:var(--gold);margin:20px auto}
.metric__label{font-size:var(--label);font-weight:600;letter-spacing:var(--label-track);
  text-transform:uppercase;color:rgba(255,255,255,.62)}

/* --------------------------------------------------------------------------
   7. Footer  →  CMS partial: includes/footer
   -------------------------------------------------------------------------- */
.site-footer{background:var(--ink);color:rgba(255,255,255,.7);padding-top:clamp(38px,3.8vw,58px)}
.site-footer .logo{color:#fff;margin-bottom:16px}
.site-footer .logo__mark{width:54px;height:54px}
.site-footer .logo__text{font-size:25px}
.site-footer .logo__text small{font-size:9px;letter-spacing:.28em}
.site-footer__top{
  display:grid;grid-template-columns:1.7fr 1fr 1fr 1.2fr;
  gap:clamp(26px,3vw,42px);padding-bottom:clamp(26px,2.8vw,40px);
}
.site-footer__blurb{font-size:var(--copy);line-height:1.75;max-width:34ch}
/* The column headings carry the same short amber rule the rest of the site
   uses to open a block — .flourish, .value__rule, .exit-group__rule and
   .disc__rule are all 34x2 in --gold. Reusing it here makes the footer read
   as part of the same design rather than introducing a new underline style
   that exists in one place only.

   An ::after rather than border-bottom: h4 is a block, so a border would run
   the full width of the column and read as a divider between the heading and
   its links instead of a mark belonging to the heading. */
.site-footer h3{
  font-family:var(--sans);font-size:var(--label);font-weight:600;letter-spacing:var(--label-track);
  text-transform:uppercase;color:#fff;margin-bottom:16px;
}
.site-footer h3::after{
  content:'';display:block;width:34px;height:2px;
  background:var(--gold);margin-top:11px;
}
.site-footer ul{display:grid;gap:10px}
.site-footer ul a{font-size:var(--copy);transition:color var(--t-fast),padding-left var(--t-fast)}
.site-footer ul a:hover{color:var(--gold-soft);padding-left:6px}
.socials{display:flex;gap:11px;margin-top:18px}
.socials a{
  width:42px;height:42px;display:grid;place-items:center;
  border:1px solid var(--line-light);font-size:12.5px;font-weight:600;
  transition:background var(--t-fast),color var(--t-fast),border-color var(--t-fast);
}
.socials a:hover{background:var(--gold);border-color:var(--gold);color:var(--on-gold)}
.site-footer__bottom{
  border-top:1px solid var(--line-light);padding-block:18px;
  display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
  font-size:14.5px;opacity:.7;
}
.is-pending{color:var(--gold-soft);opacity:.85}

/* --------------------------------------------------------------------------
   8. Responsive
   -------------------------------------------------------------------------- */
@media (max-width:1024px){
  .pillars{grid-template-columns:1fr;gap:16px}
  .pillar{aspect-ratio:16/9}
  .metrics__inner{grid-template-columns:repeat(2,1fr);row-gap:44px}
  .metric:nth-child(3)::before{display:none}
  .site-footer__top{grid-template-columns:1fr 1fr}
}
@media (max-width:760px){
  /* Fixed outer tracks on a phone: the burger's own 44px on the left and an
     equal empty track on the right, so the logo keeps the true centre.

     minmax(0,1fr) is load-bearing. A plain 1fr floors at min-content, and the
     wordmark is white-space:nowrap — so on a narrow screen the middle track
     refused to shrink, pushed the right-hand track off the end of the grid and
     dragged the logo ~11px right of centre. Allowing the track to go below
     min-content lets justify-self:center overflow it symmetrically instead. */
  .logo__text{font-size:18px}
  .logo__text small{font-size:7.5px;letter-spacing:.2em}
  /* The footer lockup needs its OWN entry at this width. Its base rules are
     `.site-footer .logo__text` — specificity (0,2,0) — so the (0,1,0) rules
     just above cannot reach it, and it kept its 25px desktop size on a phone.
     At 320px that pushed it 8px past the page edge. */
  .site-footer .logo__mark{width:44px;height:44px}
  .site-footer .logo__text{font-size:18px}
  .site-footer .logo__text small{font-size:7.5px;letter-spacing:.2em}
  /* stack the label so the marquee gets the full width instead of ~200px */
  /* the two value columns stack */
  .values{grid-template-columns:1fr}
  .form{grid-template-columns:1fr}
  .brands__inner{flex-direction:column;align-items:flex-start;gap:16px;padding-block:30px}
  .brands__marquee{width:100%;flex:0 0 auto}
  .brands__track{animation-duration:26s}
  .metric + .metric::before{display:none}
  .site-footer__top{grid-template-columns:1fr;gap:36px}
  .site-footer__bottom{flex-direction:column;gap:10px}
}

/* Narrow phones (SE-class, 320-400px). The header is now just the toggle and a
   centred lockup, so the lockup has to fit between the burger and the mirrored
   empty track — otherwise it overlaps the toggle. Shrink the mark, the wordmark
   and the header gap together. */
@media (max-width:400px){
  .logo{gap:9px}
  .logo__mark{width:38px;height:38px}
  .logo__text{font-size:15px}
  .logo__text small{font-size:6.5px;letter-spacing:.16em;margin-top:4px}
  /* Two changes, both about the centred lockup fitting between the mirrored
     spacer and the toggle.

     The sub-line goes first: "HOSPITALITY MANAGEMENT" measured 147px against a
     130px wordmark, so IT was what pushed the lockup into the toggle column,
     not the name. Dropped in the header only — the footer has room for it.

     Then the name is allowed to wrap. white-space:nowrap is what made this a
     hand-tuned width problem in the first place: it stops the lockup shrinking
     to its track, so every fix was another guess at a font size. Letting it
     wrap means the track decides, and it only ever breaks when it has to —
     one line at 360px and above, two at 320. */
  .site-header .logo__text small{display:none}
  .site-header .logo__text{white-space:normal;line-height:1.15;text-wrap:balance}
  .site-footer .logo__mark{width:38px;height:38px}
  .site-footer .logo__text{font-size:16px}
  .site-footer .logo__text small{font-size:6.5px;letter-spacing:.16em}
}

/* Honeypot. Positioned off-screen rather than display:none or
   visibility:hidden — many bots skip anything the CSS has plainly hidden,
   and the whole point is that they fill it in. aria-hidden plus tabindex=-1
   on the input keep it away from screen readers and the keyboard. */
.hp{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}

/* ===========================================================================
   COOKIE NOTICE
   ---------------------------------------------------------------------------
   A bar at the foot of the screen, not a modal. A consent dialogue that traps
   focus or dims the page is a worse accessibility problem than the cookies it
   is asking about, and it is the first thing a screen-reader user hits.

   It is [hidden] in the markup and shown by script, so a visitor who has
   already answered never sees it flash on the way past.
   ========================================================================= */
.cookie{
  position:fixed;left:0;right:0;bottom:0;z-index:70;
  background:var(--card);
  border-top:1px solid var(--line);
  box-shadow:0 -10px 30px rgba(0,0,0,.28);
  padding:16px var(--gutter);
  /* Clear of the home indicator on a phone. */
  padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));
}
.cookie[hidden]{display:none}

.cookie__inner{
  max-width:1560px;margin-inline:auto;
  display:flex;align-items:center;gap:clamp(14px,2.4vw,34px);
  flex-wrap:wrap;
}

.cookie__text{
  flex:1 1 420px;min-width:0;      /* minmax(0) equivalent: let it actually shrink */
  margin:0;font-size:14.5px;line-height:1.6;color:var(--body);
}
.cookie__text a{color:var(--gold);text-underline-offset:3px}

.cookie__actions{display:flex;gap:10px;flex-wrap:wrap}

.cookie__btn{
  font:inherit;font-weight:600;font-size:14.5px;
  padding:11px 22px;border-radius:4px;cursor:pointer;
  background:var(--gold);color:var(--on-gold);border:1px solid var(--gold);
  /* 44px of touch target, which is the WCAG 2.2 target-size minimum. */
  min-height:44px;
}
.cookie__btn--ghost{
  background:transparent;color:var(--text);border-color:var(--line);
}
.cookie__btn:hover{filter:brightness(1.06)}
.cookie__btn--ghost:hover{border-color:var(--gold);color:var(--gold);filter:none}

/* The focus ring must survive on both button styles — this is the keyboard
   user's only indication of where they are. */
.cookie__btn:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

@media (max-width:620px){
  .cookie__inner{flex-direction:column;align-items:stretch}
  .cookie__actions{justify-content:stretch}
  .cookie__btn{flex:1 1 auto}
}

/* ===========================================================================
   ACCESSIBILITY
   ========================================================================= */

/* Skip link (WCAG 2.4.1). Off-screen until focused — moved with top, not
   display:none, because a hidden element cannot receive focus at all. */
.skip-link{
  position:fixed;top:-100px;left:var(--gutter);z-index:200;
  padding:12px 20px;border-radius:0 0 4px 4px;
  background:var(--gold);color:var(--on-gold);
  font-family:var(--sans);font-weight:700;font-size:15px;
  text-decoration:none;
  transition:top .15s ease;
}
.skip-link:focus{top:0}

/* The target must not draw a ring when focus is moved there programmatically
   — it is a scroll destination, not a control. */
main:focus{outline:none}

/* WCAG 2.2 target size (2.5.8): the footer's legal links were 20px tall.
   Padding rather than a bigger font, so the footer looks unchanged. */
.site-footer__bottom a{
  display:inline-block;padding-block:6px;
}

/* Visually hidden, still announced. The clip-path + 1px box is the version
   that survives: display:none and visibility:hidden remove it from the
   accessibility tree entirely, and a bare text-indent breaks in RTL. */
.vh{
  position:absolute !important;
  width:1px;height:1px;
  margin:-1px;padding:0;border:0;
  overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);
  white-space:nowrap;
}


/* The accessibility widget sits bottom-right, which is where the cookie
   notice also is. While the bar is up the widget is lifted clear of it —
   two overlapping floating controls in the same corner is exactly the kind
   of thing an accessibility widget should not be doing.
   .userway_buttons_wrapper is the element that is actually positioned: the
   .uwy parent is a zero-size container, so moving that did nothing. This is
   third-party markup, not ours, and !important is needed because the widget
   sets its own inline styles. If UserWay renames the class the rule stops
   applying and the two overlap again — visibly, rather than silently.
   The offset comes from --pg1-cookie-h, which main.js sets to the bar's
   measured height. The bar is around 80px on a desktop and several hundred
   on a phone, where the text wraps and the buttons stack, so a fixed number
   was correct in one case and wrong in the other. */
.has-cookie-bar .userway_buttons_wrapper{
  bottom:calc(var(--pg1-cookie-h, 90px) + 24px) !important;
  transition:bottom .2s ease;
}