/* ===========================================================================
   The Kingdom Club & Resort
   ---------------------------------------------------------------------------
   Design direction: the mark is heraldic — a shield, a crown, laurel branches,
   a forest inside the arms — and the group is four destinations across two
   countries. So the site is a realm with territories, not a chain with
   locations.

   The shield silhouette from the logo is the one signature shape. It frames
   the destination roll and nothing else, so it stays a signature rather than
   becoming wallpaper. Everything around it is deliberately quiet: real
   photography, generous air, gold used as a hairline rather than a fill.

   Palette is the brand's own, taken from the mark.
   =========================================================================== */

/* ------------------------------------------------------------------ tokens */
:root {
    /* Brand greens. The deepest is the ink — never pure black. */
    --ink:          #0d321b;
    --ink-deep:     #081f11;
    --green:        #174d2b;
    --green-light:  #28613a;
    --green-mist:   #e9efea;

    /* Gold. --gold is the mark, --gold-deep is the one that passes contrast on
       cream — so gold *rules* use the mark and gold *text* uses deep. */
    --gold:         #c9a227;
    --gold-deep:    #9c7a15;
    --gold-pale:    #e2c86a;
    --gold-wash:    #fbf6e8;

    /* Grounds. Cream here is cool and near-white, which keeps the greens
       reading as forest rather than olive. */
    --cream:        #fbfcfb;
    --parchment:    #f4f2ea;
    --white:        #ffffff;

    --muted:        #5f6d65;
    --muted-light:  #8a958e;
    --line:         rgba(13, 50, 27, 0.10);
    --line-soft:    rgba(13, 50, 27, 0.06);
    --line-gold:    rgba(201, 162, 39, 0.32);

    /* ONE typeface across the entire site, as specified by the client:
       Georgia with the Times fallbacks. These are installed system faces, not
       webfonts, so nothing is downloaded and the text paints on the first
       frame with no swap flash. The role aliases below all resolve to it, so
       each rule still names the job it is doing. */
    --font:         Georgia, "Times New Roman", Times, serif;
    --font-display: var(--font);
    --font-caps:    var(--font);
    --font-ui:      var(--font);
    --font-mono:    var(--font);

    --shell:        1280px;
    --gutter:       clamp(20px, 5vw, 60px);

    --r-sm:         6px;
    --r-md:         12px;
    --r-lg:         18px;

    /* Shadows are green-tinted, never neutral grey — a grey shadow on a warm
       cream ground reads as dirt. */
    --shadow-xs:    0 1px 2px rgba(13, 50, 27, .05);
    --shadow-sm:    0 2px 8px rgba(13, 50, 27, .06);
    --shadow-md:    0 12px 32px rgba(13, 50, 27, .09);
    --shadow-lg:    0 28px 64px rgba(13, 50, 27, .14);

    --ease:         cubic-bezier(.22, .61, .36, 1);
    --ease-out:     cubic-bezier(.16, 1, .3, 1);
}

/* ------------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
    font-family: var(--font-ui);
    font-size: 16.5px;
    font-weight: 400;
    line-height: 1.72;
    color: var(--ink);
    background: var(--cream);
    overflow-x: hidden;
}

img, svg, video, iframe { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
ul, ol { list-style: none; }

:focus-visible {
    outline: 2px solid var(--gold-deep);
    outline-offset: 3px;
    border-radius: 3px;
}
.on-dark :focus-visible { outline-color: var(--gold-pale); }
::selection { background: var(--gold); color: var(--ink); }

/* -------------------------------------------------------------------- type */
/* Georgia only ships regular and bold, so a 600 heading renders as full bold —
   heavy at display size. Headings are set in the regular weight instead, which
   in a serif already carries plenty of presence, and the negative tracking is
   removed because Georgia is drawn wide on purpose. */
h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 400;
    line-height: 1.2;
    letter-spacing: 0;
    color: var(--ink);
    text-wrap: balance;
}

h1 { font-size: clamp(2.2rem, 4.8vw, 3.7rem); }
h2 { font-size: clamp(1.8rem, 3.5vw, 2.75rem); }
h3 { font-size: clamp(1.2rem, 1.8vw, 1.5rem); }
h4 { font-size: 1.08rem; }

p { color: var(--muted); }
p + p { margin-top: 1em; }

/* The eyebrow is inscriptional — spaced capitals with a short gold rule. It
   names the section rather than decorating it. */
.eyebrow {
    font-family: var(--font-caps);
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: 0.01em;
    color: var(--gold-deep);
    display: inline-flex;
    align-items: center;
    gap: 14px;
    white-space: nowrap;
}
.eyebrow::before {
    content: '';
    width: 28px; height: 1px;
    background: var(--gold);
    flex: none;
}
.eyebrow.is-centred::after {
    content: '';
    width: 28px; height: 1px;
    background: var(--gold);
    flex: none;
}
.on-dark .eyebrow { color: var(--gold-pale); }

.lede {
    font-size: 1.05rem;
    font-weight: 400;
    line-height: 1.8;
    color: var(--muted);
    max-width: 60ch;
}
.on-dark .lede { color: rgba(255, 255, 255, .78); }

.on-dark, .on-dark h1, .on-dark h2, .on-dark h3, .on-dark h4 { color: var(--white); }
.on-dark p { color: rgba(255, 255, 255, .72); }

/* ------------------------------------------------------------------ layout */
.shell {
    width: 100%;
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

section { padding-block: clamp(72px, 9vw, 136px); }
.band-parchment { background: var(--parchment); }
.band-mist      { background: var(--green-mist); }
.band-forest    { background: var(--ink); }
.band-tight     { padding-block: clamp(52px, 6vw, 88px); }

.section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 30px;
    flex-wrap: wrap;
    margin-bottom: clamp(38px, 4.5vw, 64px);
}
.section-head > div { max-width: 60ch; }
.section-head h2 { margin-top: 16px; }
.section-head .lede { margin-top: 16px; }
.section-head.is-centred {
    flex-direction: column;
    align-items: center;
    text-align: center;
}
.section-head.is-centred .lede { margin-inline: auto; }

.grid { display: grid; gap: clamp(18px, 2.2vw, 30px); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 980px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- ornament */
/* A gold rule meeting at a lozenge, echoing the divider under the wordmark. */
.rule {
    display: flex;
    align-items: center;
    gap: 12px;
    justify-content: center;
    margin-block: 22px;
}
.rule::before, .rule::after {
    content: '';
    height: 1px;
    width: clamp(38px, 8vw, 90px);
    background: linear-gradient(90deg, transparent, var(--gold));
}
.rule::after { background: linear-gradient(90deg, var(--gold), transparent); }
.rule i {
    width: 6px; height: 6px;
    background: var(--gold);
    transform: rotate(45deg);
    flex: none;
}
.rule.is-left { justify-content: flex-start; }
.rule.is-left::before { display: none; }

/* ----------------------------------------------------------------- buttons */
/* One button across the entire site. Every variant is the same pill, the same
   type and the same motion — only the colour role changes.

   The hover is a fill that wipes in from the left rather than a colour swap.
   It is drawn by ::before at z-index -1, which in the CSS painting order sits
   above the button's own background but below its text, so the label needs no
   wrapper element and the markup stays plain.                                */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    padding: 14px 30px;
    font-family: var(--font);
    font-size: .95rem;
    font-weight: 700;
    letter-spacing: .01em;
    line-height: 1.2;
    text-transform: none;
    border: 1px solid transparent;
    border-radius: 999px;
    cursor: pointer;
    white-space: nowrap;
    position: relative;
    z-index: 0;
    overflow: hidden;
    isolation: isolate;
    transition: color .35s var(--ease), border-color .35s var(--ease),
                box-shadow .4s var(--ease), transform .3s var(--ease);
}
.btn::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    transform: translateX(-101%);
    transition: transform .45s var(--ease-out);
}
.btn:hover::before,
.btn:focus-visible::before { transform: translateX(0); }

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); transition-duration: .08s; }

/* The icon leans into the direction of travel on hover. */
.btn .ico { flex: none; transition: transform .35s var(--ease); }
.btn:hover .ico { transform: translateX(3px); }
.btn .ico:first-child { transition: transform .35s var(--ease); }
.btn:hover .ico:first-child:last-of-type { transform: translateX(3px); }

/* --- colour roles ------------------------------------------------------- */
.btn-gold {
    background: var(--gold);
    color: var(--ink);
    border-color: var(--gold);
    box-shadow: 0 4px 16px rgba(201, 162, 39, .26);
}
.btn-gold::before { background: var(--ink); }
.btn-gold:hover { color: var(--white); border-color: var(--ink); box-shadow: 0 10px 26px rgba(13, 50, 27, .22); }

.btn-green {
    background: var(--green);
    color: var(--white);
    border-color: var(--green);
}
.btn-green::before { background: var(--gold); }
.btn-green:hover { color: var(--ink); border-color: var(--gold); box-shadow: 0 10px 26px rgba(201, 162, 39, .28); }

.btn-ghost {
    background: transparent;
    color: var(--ink);
    border-color: var(--line-gold);
}
.btn-ghost::before { background: var(--ink); }
.btn-ghost:hover { color: var(--white); border-color: var(--ink); box-shadow: var(--shadow-md); }

.on-dark .btn-ghost { color: var(--white); border-color: rgba(255,255,255,.36); }
.on-dark .btn-ghost::before { background: var(--white); }
.on-dark .btn-ghost:hover { color: var(--ink); border-color: var(--white); }

.btn-sm { padding: 10px 20px; font-size: .86rem; gap: 7px; }
.btn-sm .ico { width: 15px; height: 15px; }

.btn[disabled], .btn:disabled { opacity: .55; cursor: not-allowed; transform: none; }
.btn[disabled]::before { transform: translateX(-101%); }

/* A text link that grows a gold underline. Title case, like everything else. */
.link-gold {
    font-family: var(--font);
    font-size: .92rem;
    font-weight: 700;
    letter-spacing: .01em;
    text-transform: none;
    color: var(--gold-deep);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding-bottom: 5px;
    position: relative;
}
.link-gold::after {
    content: "";
    position: absolute;
    left: 0; bottom: 0;
    height: 1px; width: 0;
    background: var(--gold);
    transition: width .4s var(--ease);
}
.link-gold:hover::after { width: 100%; }
.link-gold .ico { transition: transform .35s var(--ease); }
.link-gold:hover .ico { transform: translateX(5px); }
.on-dark .link-gold { color: var(--gold-pale); }

/* ------------------------------------------------------------------ header */
/* A white bar with the logo set into a plinth — a white plaque that starts at
   the top of the bar and overhangs its bottom edge on rounded corners. That
   overhang is the header's signature: the silhouette is no longer a plain
   rectangle, and it reads as an escutcheon, which is what the mark itself is.
   Everything else stays quiet — a gold hairline instead of a grey border, and
   navigation set in title case rather than tracked-out capitals.

   The navigation is distributed with space-between across the whole run
   between the plinth and the button, so the empty gap that used to sit next to
   the logo becomes even air between the items instead.

   Widths were measured against real Georgia metrics rather than guessed.
   Title case is 23% narrower than capitals, which is what lets a 1366 laptop
   keep the full menu.                                                        */
.site-header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 100;
    padding-block: 12px;
    background: var(--white);
    font-family: var(--font);
}

/* A gold hairline that fades at both ends, rather than a hard grey rule. */
.site-header::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent, var(--line-gold) 18%, var(--line-gold) 82%, transparent);
}

.site-header .shell {
    max-width: 1480px;
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 0;
}

/* ------------------------------------------------------------- logo plinth */
.brand {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    background: var(--white);
    padding: 12px 20px 22px;
    margin-block: -12px -30px;
    border-radius: 0 0 var(--r-lg) var(--r-lg);
    box-shadow: 0 12px 26px rgba(13, 50, 27, .10);
}
.brand img {
    width: auto;
    flex: none;
    object-fit: contain;
}
.brand-crest { aspect-ratio: 1; }

/* Two crops of the same artwork. The stacked lockup needs ~70px of height
   before the wordmark stops being a smudge — fine on a laptop, far too tall on
   a phone — so below 700px the crest carries the brand and stays crisp. */
.brand-crest  { height: 44px; }
.brand-lockup { display: none; }

@media (min-width: 700px) {
    .brand-crest  { display: none; }
    .brand-lockup { display: block; height: clamp(64px, 5vw, 76px); }
}

/* -------------------------------------------------------------- navigation */
.nav {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    min-width: 0;
}

/* Only ever seen inside the drawer; the desktop bar carries its own mark. */
.nav-brand { display: none; }

/* space-between spreads the items across the full run, so the gap that used to
   pool beside the logo becomes even space between every item. The `gap` is the
   floor, not the actual spacing. */
.nav-list {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* The gap and the side padding came down to pay for the larger type —
       measured against real Georgia metrics, the ten labels at .96rem need
       every pixel the row can spare at 1340. */
    gap: 13px;
    padding-inline: 16px;
    min-width: 0;
    position: relative;
}
.nav-list > li { position: relative; flex: 0 0 auto; }

.nav-list > li > a {
    font-family: var(--font);
    font-size: .96rem;
    font-weight: 400;
    letter-spacing: .005em;
    text-transform: none;          /* title case, as the labels are written */
    color: var(--ink);
    padding: 12px 2px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    position: relative;
    transition: color .3s var(--ease);
}
.nav-list > li > a:hover,
.nav-list > li.is-active > a { color: var(--gold-deep); }

/* The underline belongs to the link itself rather than to a single bar that
   JS moves around. The current page therefore always shows one — it cannot go
   missing because a script did not run, it is correct at every width, and it
   moves between pages on its own because .is-active moves. Hovering grows the
   same rule from the left. */
.nav-list > li > a::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 1px;
    height: 2px;
    border-radius: 2px;
    background: var(--gold);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .38s var(--ease-out);
}
.nav-list > li > a:hover::after,
.nav-list > li > a:focus-visible::after,
.nav-list > li.is-active > a::after { transform: scaleX(1); }



.nav-list .caret { width: 8px; height: 8px; opacity: .6; flex: none; }

/* The header button is a pill in title case — the site's tracked-out capital
   buttons are right in a hero and wrong in a 44px bar. */
.nav-cta { flex: 0 0 auto; }
.site-header .btn {
    font-family: var(--font);
    text-transform: none;
    letter-spacing: .01em;
    font-weight: 700;
    font-size: .9rem;
    border-radius: 999px;
    padding: 11px 20px;
}

.submenu {
    position: absolute;
    top: calc(100% + 10px);
    left: -18px;
    min-width: 230px;
    background: var(--white);
    border: 1px solid var(--line-soft);
    border-top: 2px solid var(--gold);
    border-radius: 0 0 var(--r-md) var(--r-md);
    box-shadow: var(--shadow-md);
    padding: 8px 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: opacity .3s var(--ease), transform .3s var(--ease), visibility .3s;
}
.nav-list > li:hover > .submenu,
.nav-list > li:focus-within > .submenu { opacity: 1; visibility: visible; transform: translateY(0); }
.submenu a {
    display: block;
    padding: 10px 22px;
    font-size: .96rem;
    color: var(--ink);
    transition: background .22s, color .22s, padding-left .28s var(--ease);
}
.submenu a:hover { background: var(--gold-wash); color: var(--gold-deep); padding-left: 28px; }

/* ------------------------------------------- more room on wider desktops */
@media (min-width: 1440px) {
    .nav-list { gap: 15px; padding-inline: clamp(20px, 2vw, 26px); }
    .nav-list > li > a { font-size: .99rem; }
}

/* --------------------------------------------------------- the menu button */
.nav-toggle {
    display: none;
    width: 44px; height: 44px;
    flex: none;
    margin-left: auto;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 999px;
    cursor: pointer;
    position: relative;
    z-index: 3;
}
.nav-toggle span {
    position: absolute; left: 13px; right: 13px;
    height: 1.6px; background: var(--ink);
    border-radius: 2px;
    transition: transform .32s var(--ease), opacity .2s, background .3s;
}
.nav-toggle span:nth-child(1) { top: 15px; }
.nav-toggle span:nth-child(2) { top: 21px; }
.nav-toggle span:nth-child(3) { top: 27px; }
.nav-toggle.is-open span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle.is-open span:nth-child(2) { opacity: 0; }
.nav-toggle.is-open span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Open, the button sits over the dark drawer, so it is forced light. */
.site-header .nav-toggle.is-open { border-color: rgba(255,255,255,.45); }
.site-header .nav-toggle.is-open span { background: var(--white); }

/* ------------------------------------------------------ drawer below 1320 */
@media (max-width: 1339px) {
    .nav-toggle { display: block; }
    .nav {
        position: fixed;
        inset: 0 0 0 auto;
        width: min(348px, 86vw);
        background: var(--ink);
        flex-direction: column;
        align-items: stretch;
        justify-content: flex-start;
        gap: 0;
        padding: 112px 30px 40px;
        transform: translateX(100%);
        transition: transform .42s var(--ease-out);
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        z-index: 95;
    }
    .nav.is-open { transform: translateX(0); }

    /* The open menu leads with the lockup. The artwork is green and gold on a
       transparent ground, so on the dark drawer it is knocked out to cream —
       the same treatment the footer uses, rather than a second asset to keep
       in step. */
    .nav-brand {
        display: block;
        width: 158px;
        margin: 0 auto 20px;
        padding-bottom: 18px;
        border-bottom: 1px solid rgba(255, 255, 255, .12);
    }
    .nav-brand img {
        width: 100%;
        height: auto;
        filter: brightness(0) invert(1) opacity(.92);
    }

    .nav-list {
        flex: 0 0 auto;
        flex-direction: column;
        align-items: stretch;
        justify-content: flex-start;
        gap: 0;
        padding-inline: 0;
        width: 100%;
    }
    .nav-list > li { width: 100%; border-bottom: 1px solid rgba(255,255,255,.09); }
    .nav-list > li > a {
        color: var(--white);
        padding: 15px 0;
        font-size: 1.02rem;
        justify-content: space-between;
        width: 100%;
    }
    .nav-list > li > a::after { display: none; }
    .nav-list > li > a:hover,
    .nav-list > li.is-active > a { color: var(--gold-pale); }
    /* A full-width underline reads as a divider in a stacked menu, so the
       current page is marked down the side instead. */
    .nav-list > li.is-active { box-shadow: inset 3px 0 0 var(--gold); }
    .nav-list > li.is-active > a { padding-left: 14px; }
    .submenu {
        position: static; opacity: 1; visibility: visible; transform: none;
        background: transparent; border: 0; box-shadow: none;
        padding: 0 0 12px 14px; min-width: 0;
    }
    .submenu a { color: rgba(255,255,255,.66); padding: 9px 0; font-size: .94rem; }
    .submenu a:hover { background: transparent; color: var(--gold-pale); padding-left: 6px; }
    .nav-cta { margin-top: 26px; width: 100%; }
    .site-header .btn { width: 100%; padding-block: 14px; }
}

/* ------------------------------------------------------- tablet and phone */
/* ------------------------------------------------------------ phone brand */
/* On a phone the plinth has nothing left to do. The shape only reads when it
   overhangs the bar, and at this size it cleared it by 1-6px while still
   painting a 26px shadow across a white header — a smudge around the crest
   rather than a plaque under it. The asymmetric padding was also pushing the
   crest 2px above the centre line of the menu button beside it.

   So below 700 the plinth is dropped entirely: the crest sits directly on the
   bar, and with no padding or negative margins it centres itself against the
   button automatically at every width. */
@media (max-width: 699px) {
    /* The header is shallower here, so the drawer can start its content higher
       and the lockup steps down to match. */
    .nav { padding-top: 92px; }
    .nav-brand { width: 140px; margin-bottom: 16px; padding-bottom: 14px; }

    .brand {
        background: none;
        box-shadow: none;
        border-radius: 0;
        padding: 0;
        margin-block: 0;
    }
    .brand-crest { height: 46px; }
}

/* Small phones: a touch smaller so the bar stays shallow beside the button. */
@media (max-width: 380px) {
    .brand-crest { height: 40px; }
}

.nav-scrim {
    position: fixed; inset: 0;
    background: rgba(8, 31, 17, .6);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    opacity: 0; visibility: hidden;
    transition: opacity .35s, visibility .35s;
    z-index: 94;
}
.nav-scrim.is-open { opacity: 1; visibility: visible; }

/* ------------------------------------------------------------ hero slider */
/* Slides cross-fade rather than slide sideways. With full-bleed media a
   horizontal track means every frame is decoded and laid out at once, and any
   video that is off-screen still paints; stacking them and fading means only
   the visible slide does work, and the transition suits the material better.

   Height is deliberately shorter than the old full-viewport hero: 62vh with a
   floor and a ceiling. The ceiling stops it becoming a letterbox on a tall
   desktop, the floor keeps the copy readable on a short laptop. */
.hero {
    position: relative;
    min-height: clamp(660px, 94vh, 1040px);
    display: grid;
    grid-template-rows: 1fr;      /* the track fills the hero, never part of it */
    text-align: center;
    color: var(--white);
    overflow: hidden;

    /* The hero is a <section>, and the global section rule gives every section
       136px of vertical padding. That padding was the dark band above and
       below the picture: the slide sits in the hero CONTENT box, so the media
       stopped at the padding edge and the hero background showed through it.

       Before the slider the media was a direct child of .hero, where inset:0
       resolves against the PADDING box and covered it — so the bands only
       appeared when the markup gained the track/slide wrappers. The hero owns
       its own spacing through .hero-inner, so the section padding goes. */
    padding: 0;

    /* Now genuinely never visible — the media covers the whole box — but a
       brand green is the right thing to show in the instant before the first
       photograph paints. */
    background: var(--ink-deep);
}

.hero-track { display: grid; grid-template-areas: "slide"; min-height: 100%; }

.hero-slide {
    grid-area: slide;
    position: relative;
    display: grid;
    place-items: center;
    min-height: 100%;
    opacity: 0;
    visibility: hidden;
    transition: opacity .9s var(--ease), visibility .9s;
}
.hero-slide.is-on { opacity: 1; visibility: visible; }

/* --------------------------------------------------------------- media */
.hero-media { position: absolute; inset: 0; overflow: hidden; }

/* --focal is set per slide from the admin, so a crop keeps the part of the
   picture the client chose rather than always the middle. */
.hero-media img,
.hero-media video,
.hero-media iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--focal, center center);
    border: 0;
}

/* The poster sits under an embed so there is never a black hole while an
   iframe negotiates; the iframe paints over it once it loads. */
.hero-media .hero-poster { z-index: 0; }
.hero-media iframe { z-index: 1; pointer-events: none; }

/* A very slow push-in on the active slide only. It is the one piece of ambient
   motion on the site, and at this rate it reads as depth, not animation. */
.hero-slide.is-on .hero-media img:not(.hero-poster) {
    animation: heroDrift 22s ease-out forwards;
}
@keyframes heroDrift {
    from { transform: scale(1.05); }
    to   { transform: scale(1); }
}

/* An embedded player has a fixed 16:9 frame, so to fill a wider box it has to
   be scaled up and centred — otherwise YouTube letterboxes itself in black. */
.hero-slide[data-kind="embed"] .hero-media iframe {
    width: 100vw;
    height: 56.25vw;          /* 16:9 */
    min-height: 100%;
    min-width: 177.78vh;      /* 16:9 the other way */
    top: 50%; left: 50%;
    inset: auto;
    transform: translate(-50%, -50%);
}

/* The scrim exists only so white copy stays readable on a bright photograph.
   It used to be heavy and green — 70% ink at the top, 84% at the bottom —
   because the header was transparent back then and needed something dark
   underneath it. The header is solid white now, and the hero is 62vh rather
   than full height, so those stops compressed into hard green bars across the
   top and bottom of the picture.

   It is now neutral and light: black rather than ink, so there is no colour
   cast on the photograph, weighted to the floor where the buttons sit. */
.hero-media::after {
    content: '';
    position: absolute; inset: 0;
    z-index: 2;
    background:
        /* A soft pool of shade behind the copy. Darkening the edges would be
           backwards — the copy is in the middle, and the photograph is the
           point, so it stays bright where there is nothing written over it. */
        radial-gradient(62% 66% at 50% 50%,
            rgba(0,0,0,.46) 0%, rgba(0,0,0,.18) 62%, rgba(0,0,0,0) 100%),
        /* A light floor so the buttons and the dots keep their edge. */
        linear-gradient(180deg, rgba(0,0,0,0) 52%, rgba(0,0,0,.38) 100%);
}

/* ---------------------------------------------------------------- copy */
.hero-inner {
    position: relative;
    z-index: 3;
    padding: clamp(96px, 10vw, 124px) var(--gutter) clamp(72px, 8vw, 92px);
    max-width: 940px;
}
.hero h1 {
    color: var(--white);
    text-shadow: 0 2px 26px rgba(0,0,0,.55), 0 1px 3px rgba(0,0,0,.35);
    letter-spacing: -0.02em;
}
.hero h1 em {
    font-style: italic;
    font-weight: 400;
    color: var(--gold-pale);
    display: block;
}
.hero .lede {
    margin-inline: auto;
    color: rgba(255,255,255,.92);
    font-size: 1.08rem;
    text-shadow: 0 1px 16px rgba(0,0,0,.55);
}

.hero-tagline {
    font-family: var(--font-caps);
    font-weight: 700;
    font-size: clamp(.86rem, 1.5vw, .98rem);
    letter-spacing: 0.06em;
    color: var(--gold-pale);
    margin-bottom: 24px;
    text-shadow: 0 1px 14px rgba(0,0,0,.5);
}
.hero-actions {
    display: flex;
    gap: 14px;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 34px;
}
.hero-crown { width: 50px; margin: 0 auto 18px; opacity: .95; }

/* ------------------------------------------------------------ controls */
.hero-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 4;
    width: 52px; height: 52px;
    display: grid; place-items: center;
    background: rgba(255,255,255,.10);
    border: 1px solid rgba(255,255,255,.30);
    border-radius: 999px;
    color: var(--white);
    cursor: pointer;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    transition: background .3s var(--ease), border-color .3s var(--ease),
                color .3s var(--ease), opacity .3s var(--ease);
    opacity: 0;
}
.hero:hover .hero-arrow,
.hero-arrow:focus-visible { opacity: 1; }
.hero-arrow:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.hero-arrow svg { width: 20px; height: 20px; }
.hero-prev { left: clamp(12px, 2.5vw, 34px); }
.hero-next { right: clamp(12px, 2.5vw, 34px); }

/* Touch has no hover, so the arrows are always visible there. */
@media (hover: none) {
    .hero-arrow { opacity: 1; width: 44px; height: 44px; }
    .hero-arrow svg { width: 17px; height: 17px; }
}

.hero-dots {
    position: absolute;
    left: 0; right: 0;
    bottom: clamp(20px, 3.4vw, 34px);
    z-index: 4;
    display: flex;
    justify-content: center;
    gap: 10px;
}
.hero-dots button {
    width: 30px; height: 20px;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
    display: grid;
    place-items: center;
}
/* The hit area is 30x20 for thumbs; the mark itself is a 3px bar. */
.hero-dots button i {
    display: block;
    width: 26px; height: 3px;
    border-radius: 2px;
    background: rgba(255,255,255,.4);
    transition: background .3s var(--ease), width .35s var(--ease);
}
.hero-dots button:hover i { background: rgba(255,255,255,.72); }
.hero-dots button.is-on i { background: var(--gold); width: 40px; }

.hero-cue {
    position: absolute;
    bottom: 26px; left: 50%;
    transform: translateX(-50%);
    z-index: 3;
    font-size: .78rem;
    letter-spacing: .04em;
    color: rgba(255,255,255,.62);
    display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.hero-cue i {
    width: 1px; height: 40px;
    background: linear-gradient(180deg, var(--gold), transparent);
}
/* With dots present the scroll cue would collide with them. */
.hero:has(.hero-dots) .hero-cue { display: none; }

@media (max-width: 900px) {
    .hero { min-height: clamp(600px, 86vh, 840px); }
    .hero-cue { display: none; }
}
@media (max-width: 560px) {
    .hero { min-height: clamp(540px, 80vh, 740px); }
    .hero-inner { padding-top: clamp(108px, 26vw, 140px); }
    .hero-arrow { width: 38px; height: 38px; }
    .hero-prev { left: 8px; }
    .hero-next { right: 8px; }
}

/* A slide that arrives while the visitor asked for less motion simply appears. */
@media (prefers-reduced-motion: reduce) {
    .hero-slide { transition: none; }
    .hero-slide.is-on .hero-media img:not(.hero-poster) { animation: none; transform: none; }
}

/* Page banner — the compact hero every inner page uses. */
.page-banner {
    position: relative;
    padding: clamp(124px, 17vw, 196px) var(--gutter) clamp(52px, 8vw, 88px);
    text-align: center;
    color: var(--white);
    background: var(--ink);
    overflow: hidden;
}
.page-banner-media { position: absolute; inset: 0; }
.page-banner-media img { width: 100%; height: 100%; object-fit: cover; opacity: .5; }
.page-banner-media::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(8,31,17,.88) 0%, rgba(8,31,17,.58) 60%, rgba(8,31,17,.78) 100%);
}
.page-banner .inner { position: relative; z-index: 2; }
.page-banner h1 { color: var(--white); font-size: clamp(2.3rem, 4.8vw, 3.7rem); }

.crumbs {
    margin-top: 20px;
    font-size: .88rem;
    letter-spacing: .01em;
    color: rgba(255,255,255,.66);
    display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
}
.crumbs a { transition: color .25s; }
.crumbs a:hover { color: var(--gold-pale); }
.crumbs span[aria-current] { color: var(--gold-pale); }

/* ============= SIGNATURE: the shield frame ================================
   Only the destination roll uses it. The path is defined once in the layout. */
.shield {
    position: relative;
    aspect-ratio: .78;
    overflow: hidden;
    clip-path: url(#kingdom-shield);
    background: var(--green);
}
.shield img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform 1.1s var(--ease-out);
}
.shield::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(8,31,17,.04) 38%, rgba(8,31,17,.82) 100%);
}
@supports not (clip-path: url(#kingdom-shield)) {
    .shield { clip-path: none; border-radius: 170px 170px var(--r-md) var(--r-md); }
}

.roll { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(16px, 2.2vw, 36px); }
@media (max-width: 1024px) { .roll { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px)  { .roll { grid-template-columns: 1fr; max-width: 340px; margin-inline: auto; } }

.roll-item { text-align: center; }
.roll-item:hover .shield img { transform: scale(1.07); }

.roll-item .shield-caption {
    position: absolute;
    left: 0; right: 0; bottom: 38px;
    z-index: 2;
    color: var(--white);
    padding-inline: 12px;
}
.roll-item .shield-caption b {
    font-family: var(--font-caps);
    font-size: 1.12rem;
    font-weight: 700;
    letter-spacing: .01em;
    display: block;
}
/* The region under each name is real information — the group spans two
   countries — so it earns its place. */
.roll-item .shield-caption small {
    font-size: .82rem;
    letter-spacing: .02em;
    color: var(--gold-pale);
}
.roll-item .roll-link { margin-top: 20px; display: inline-flex; }

/* ------------------------------------------------------ the lead destination */
/* The first destination is given the floor: a large crest beside its own copy,
   above the row of the others. Which property leads is not decided here — it
   is whichever comes first, so the client keeps control of it from the admin. */
.roll-lead {
    display: grid;
    grid-template-columns: minmax(260px, 340px) 1fr;
    align-items: center;
    gap: clamp(28px, 4.5vw, 70px);
    margin-bottom: clamp(38px, 5vw, 66px);
    padding-bottom: clamp(38px, 5vw, 66px);
    border-bottom: 1px solid var(--line);
}

/* A gold edge that follows the crest silhouette. A border cannot — the shield
   is a clip-path, so the box it would draw on is not the shape you see.
   Stacked drop-shadows are filtered through the same clip, so they trace the
   outline exactly, and the last one adds the glow. */
.roll-item.is-lead .shield {
    filter:
        drop-shadow(1.5px 0 0 var(--gold)) drop-shadow(-1.5px 0 0 var(--gold))
        drop-shadow(0 1.5px 0 var(--gold)) drop-shadow(0 -1.5px 0 var(--gold))
        drop-shadow(0 22px 46px rgba(201, 162, 39, .30));
}
.roll-item.is-lead .shield-caption b { font-size: 1.24rem; }
.roll-item.is-lead .shield-caption small { font-size: .88rem; }

.lead-body { min-width: 0; }

.lead-tag {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 15px;
    border-radius: 999px;
    background: var(--gold-wash);
    border: 1px solid var(--line-gold);
    color: var(--gold-deep);
    font-size: .84rem;
    font-weight: 700;
    letter-spacing: .01em;
}
.lead-tag .ico { color: var(--gold); }

.lead-country { display: flex; margin-top: 18px; }
.lead-body h3 {
    font-size: clamp(1.7rem, 3vw, 2.5rem);
    margin-top: 10px;
}
.lead-body h3 a { transition: color .3s var(--ease); }
.lead-body h3 a:hover { color: var(--gold-deep); }
.lead-place { margin-top: 12px; }
.lead-body .lede { margin-top: 14px; }
.lead-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* The remaining three sit in their own row rather than a four-up grid. */
.roll-rest { grid-template-columns: repeat(3, 1fr); }

@media (max-width: 1024px) {
    .roll-rest { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 860px) {
    .roll-lead {
        grid-template-columns: 1fr;
        justify-items: center;
        text-align: center;
        gap: clamp(24px, 5vw, 36px);
    }
    .roll-item.is-lead { max-width: 300px; }
    .lead-country, .lead-place, .lead-actions { justify-content: center; }
    .lead-body .lede { margin-inline: auto; }
    .roll-rest { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 620px) {
    .roll-rest { grid-template-columns: 1fr; max-width: 330px; margin-inline: auto; }
    .roll-item.is-lead { max-width: 260px; }
}

@media (prefers-reduced-motion: reduce) {
    .roll-item.is-lead .shield { filter: none; }
}

/* ------------------------------------------------------------------- cards */
.card {
    background: var(--white);
    border-radius: var(--r-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: var(--shadow-xs);
    transition: transform .5s var(--ease-out), box-shadow .5s var(--ease-out);
}
.card:hover { transform: translateY(-7px); box-shadow: var(--shadow-md); }

.card-media {
    position: relative;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: var(--green-mist);
    display: block;
}
.card-media img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform .9s var(--ease-out);
}
.card:hover .card-media img { transform: scale(1.06); }

/* A soft ink wash from the foot of the image, so a white caption block never
   meets a bright photo edge-on. */
.card-media::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(180deg, transparent 58%, rgba(8,31,17,.34));
    opacity: 0;
    transition: opacity .5s var(--ease);
}
.card:hover .card-media::after { opacity: 1; }

.card-body {
    padding: 26px 26px 28px;
    display: flex;
    flex-direction: column;
    flex: 1;
    gap: 10px;
}
.card-body h3 { font-size: 1.42rem; letter-spacing: -0.01em; }
.card-body h3 a { transition: color .3s; }
.card-body h3 a:hover { color: var(--gold-deep); }
.card-body p { font-size: .92rem; line-height: 1.68; }
.card-body .link-gold { margin-top: auto; padding-top: 16px; align-self: flex-start; }

.card-place {
    font-size: .86rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--gold-deep);
    display: flex; align-items: center; gap: 7px;
    font-weight: 500;
}
.card-place svg { width: 12px; height: 12px; flex: none; }

.tag {
    position: absolute;
    top: 16px; left: 16px;
    z-index: 2;
    background: var(--gold);
    color: var(--ink);
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .01em;
    padding: 6px 14px;
    border-radius: 100px;
    box-shadow: 0 3px 10px rgba(8,31,17,.18);
}
.tag-green { background: var(--green); color: var(--white); }
.tag-ink {
    background: rgba(8,31,17,.62);
    color: var(--white);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

/* -------------------------------------------------------- featured / split */
.feature {
    display: grid;
    grid-template-columns: 1.02fr 1fr;
    align-items: center;
    gap: clamp(30px, 5.5vw, 84px);
}
.feature.is-flipped .feature-media { order: 2; }
@media (max-width: 900px) {
    .feature, .feature.is-flipped { grid-template-columns: 1fr; }
    .feature.is-flipped .feature-media { order: 0; }
}

/* No overflow:hidden here — the gold frame below deliberately sits outside the
   box, and clipping the parent would hide it entirely. The image is rounded on
   itself instead. */
.feature-media {
    position: relative;
    aspect-ratio: 5 / 4;
    border-radius: var(--r-lg);
    z-index: 1;
}
.media-frame {
    display: block;
    position: relative;
    width: 100%; height: 100%;
    border-radius: var(--r-lg);
    overflow: hidden;                       /* lets the picture zoom without escaping */
    box-shadow: var(--shadow-md);
    transition: box-shadow .55s var(--ease-out);
}
.feature-media img {
    display: block;
    width: 100%; height: 100%;
    object-fit: cover;
    border-radius: var(--r-lg);
    transition: transform .8s var(--ease-out), filter .55s var(--ease-out);
}

/* A gold frame offset behind the image — a restrained nod to a plaque. */
.feature-media::before {
    content: '';
    position: absolute;
    inset: 22px -22px -22px 22px;
    border: 1px solid var(--gold);
    border-radius: var(--r-lg);
    z-index: -1;
}

/* A single light sweep across the picture on hover. It is decorative only and
   never sits under text, so it stays out of pointer events. */
.media-frame::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.22) 50%, transparent 62%);
    transform: translateX(-120%);
    opacity: 0;
    pointer-events: none;
}
@keyframes media-sheen {
    0%   { transform: translateX(-120%); opacity: 0; }
    16%  { opacity: 1; }
    100% { transform: translateX(120%);  opacity: 0; }
}

/* Every standalone picture on the site is a .feature-media — the Who We Are
   image on the homepage and About, and the lead image on the property,
   experience, dining, event and offer pages. One rule covers all seven.

   The picture zooms inside .media-frame rather than in .feature-media itself:
   the gold plate is a ::before on .feature-media and sits OUTSIDE that box on
   purpose, so clipping there would cut the plate off. The frame clips, the
   plate stays free. */
.feature-media { transition: transform .55s var(--ease-out); }
.feature-media::before {
    transition: inset .55s var(--ease-out), border-color .55s var(--ease-out);
}

.feature-media:hover { transform: translateY(-7px); }
.feature-media:hover .media-frame { box-shadow: var(--shadow-lg); }
.feature-media:hover .media-frame::after { animation: media-sheen .9s var(--ease-out); }
.feature-media:hover img {
    transform: scale(1.06);
    filter: saturate(1.06) contrast(1.02);
}
.feature-media:hover::before {
    inset: 28px -28px -28px 28px;
    border-color: var(--gold-pale);
}

/* Touch has no hover, and a phone hides the plate anyway, so nothing here
   fires where it cannot be seen — and a zoom left stuck on after a tap is
   exactly the sort of thing that reads as a bug on mobile. */
@media (hover: none) {
    .feature-media:hover { transform: none; }
    .feature-media:hover img { transform: none; filter: none; }
    .feature-media:hover .media-frame { box-shadow: var(--shadow-md); }
    .feature-media:hover .media-frame::after { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
    .feature-media, .feature-media img, .feature-media::before, .media-frame { transition: none; }
    .feature-media:hover { transform: none; }
    .feature-media:hover img { transform: none; }
    .feature-media:hover .media-frame::after { animation: none; }
}

/* On narrow screens the offset frame would push past the gutter, so it goes. */
@media (max-width: 620px) {
    .feature-media::before { display: none; }
}

.feature-body h2 { margin-block: 16px 20px; }
.feature-actions { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 34px; }

.stat-row { display: flex; gap: clamp(24px, 4vw, 54px); flex-wrap: wrap; margin-top: 34px; }
.stat b {
    font-family: var(--font-display);
    font-size: 2.15rem;
    font-weight: 400;
    letter-spacing: 0;
    line-height: 1;
    color: var(--gold-deep);
    display: block;
}
.stat span {
    font-size: .88rem;
    letter-spacing: .01em;
    color: var(--muted);
    font-weight: 400;
}
.on-dark .stat b { color: var(--gold-pale); }
.on-dark .stat span { color: rgba(255,255,255,.6); }

/* --------------------------------------------------------------- amenities */
.amenity-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(172px, 1fr));
    gap: 1px;
    background: var(--line-soft);
    border: 1px solid var(--line-soft);
    border-radius: var(--r-md);
    overflow: hidden;
}
.amenity {
    background: var(--cream);
    padding: 34px 18px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    transition: background .4s var(--ease), transform .4s var(--ease);
}
.amenity:hover { background: var(--white); transform: translateY(-3px); }
.amenity-icon {
    width: 38px; height: 38px;
    color: var(--gold-deep);
    display: grid; place-items: center;
    transition: transform .4s var(--ease);
}
.amenity:hover .amenity-icon { transform: scale(1.12); }
.amenity-icon svg, .amenity-icon img { width: 100%; height: 100%; object-fit: contain; }
.amenity b {
    font-family: var(--font-caps);
    font-weight: 700;
    font-size: .92rem;
    letter-spacing: .01em;
}
.band-parchment .amenity { background: var(--parchment); }
.band-parchment .amenity:hover { background: var(--white); }

/* ------------------------------------------------------------ testimonials */
.quote { text-align: center; max-width: 880px; margin-inline: auto; }
.quote-text {
    font-family: var(--font-display);
    font-size: clamp(1.2rem, 2.1vw, 1.7rem);
    font-style: italic;
    font-weight: 400;
    letter-spacing: 0;
    line-height: 1.6;
    color: var(--ink);
    text-wrap: balance;
}
.on-dark .quote-text { color: var(--white); }
/* stars() emits five SVGs; this sizes and colours them. */
.quote-stars {
    color: var(--gold);
    margin-top: 26px;
    display: flex;
    justify-content: center;
    gap: 6px;
}
.quote-stars svg { width: 19px; height: 19px; flex: none; }
.quote-who { margin-top: 16px; }
.quote-who b {
    font-family: var(--font-caps);
    font-weight: 700;
    letter-spacing: .01em;
    font-size: 1rem;
    display: block;
}
.quote-who small {
    font-size: .86rem; letter-spacing: .01em; color: var(--muted);
}
.on-dark .quote-who small { color: rgba(255,255,255,.55); }

.quote-dots { display: flex; gap: 10px; justify-content: center; margin-top: 36px; }
.quote-dots button {
    width: 7px; height: 7px;
    border-radius: 50%;
    border: 1px solid var(--gold);
    background: transparent;
    cursor: pointer; padding: 0;
    transition: background .3s, transform .3s, width .3s;
}
.quote-dots button.is-on { background: var(--gold); width: 22px; border-radius: 4px; }

.quote-slide { display: none; }
.quote-slide.is-on { display: block; animation: fadeUp .6s var(--ease-out) both; }

/* ----------------------------------------------------------------- gallery */
.masonry { columns: 3 268px; column-gap: clamp(12px, 1.6vw, 20px); }
.masonry > * { break-inside: avoid; margin-bottom: clamp(12px, 1.6vw, 20px); }

.shot {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: var(--r-md);
    background: var(--green-mist);
    cursor: zoom-in;
    box-shadow: var(--shadow-xs);
}
.shot img { width: 100%; height: auto; transition: transform .9s var(--ease-out); }
.shot::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(180deg, transparent 50%, rgba(8,31,17,.78));
    opacity: 0;
    transition: opacity .45s var(--ease);
}
.shot:hover img { transform: scale(1.06); }
.shot:hover::after { opacity: 1; }
.shot figcaption {
    position: absolute;
    left: 20px; right: 20px; bottom: 18px;
    z-index: 2;
    color: var(--white);
    font-size: .8rem;
    letter-spacing: .06em;
    opacity: 0;
    transform: translateY(10px);
    transition: opacity .45s var(--ease), transform .45s var(--ease);
}
.shot:hover figcaption { opacity: 1; transform: translateY(0); }

.lightbox {
    position: fixed; inset: 0;
    z-index: 200;
    background: rgba(6, 22, 12, .96);
    backdrop-filter: blur(6px);
    display: none;
    place-items: center;
    padding: 40px 20px;
}
.lightbox.is-open { display: grid; animation: fadeIn .3s ease both; }
.lightbox img {
    max-width: min(1140px, 94vw);
    max-height: 86vh;
    object-fit: contain;
    border-radius: var(--r-sm);
    box-shadow: 0 40px 100px rgba(0,0,0,.5);
}
.lightbox-close, .lightbox-prev, .lightbox-next {
    position: absolute;
    background: rgba(255,255,255,.06);
    border: 1px solid rgba(255,255,255,.24);
    color: var(--white);
    width: 48px; height: 48px;
    border-radius: 50%;
    cursor: pointer;
    display: grid; place-items: center;
    transition: background .3s, border-color .3s, transform .3s;
}
.lightbox-close:hover, .lightbox-prev:hover, .lightbox-next:hover {
    background: var(--gold); border-color: var(--gold); color: var(--ink); transform: scale(1.06);
}
.lightbox-close { top: 24px; right: 24px; }
.lightbox-prev { left: 24px; top: 50%; transform: translateY(-50%); }
.lightbox-next { right: 24px; top: 50%; transform: translateY(-50%); }
.lightbox-prev:hover { transform: translateY(-50%) scale(1.06); }
.lightbox-next:hover { transform: translateY(-50%) scale(1.06); }

/* -------------------------------------------------------------------- tabs */
.tabs {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    border-bottom: 1px solid var(--line);
    margin-bottom: 42px;
}
.tabs button {
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 14px 22px;
    font-size: .98rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--muted);
    cursor: pointer;
    transition: color .3s, border-color .3s;
    margin-bottom: -1px;
}
.tabs button:hover { color: var(--ink); }
.tabs button.is-on { color: var(--gold-deep); border-bottom-color: var(--gold); }

.tab-panel { display: none; }
.tab-panel.is-on { display: block; animation: fadeUp .5s var(--ease-out) both; }

.pills { display: flex; gap: 9px; flex-wrap: wrap; justify-content: center; margin-bottom: 48px; }
.pills a {
    padding: 10px 22px;
    border: 1px solid var(--line);
    border-radius: 100px;
    font-size: .9rem;
    letter-spacing: .01em;
    color: var(--muted);
    font-weight: 700;
    transition: all .3s var(--ease);
}
.pills a:hover { border-color: var(--gold); color: var(--gold-deep); background: var(--gold-wash); }
.pills a.is-on { background: var(--ink); border-color: var(--ink); color: var(--white); }

/* ------------------------------------------------------------------- forms */
.field { display: flex; flex-direction: column; gap: 8px; }
.field label {
    font-size: .92rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--muted);
}
.field .req { color: var(--gold-deep); }

.field input, .field select, .field textarea {
    padding: 15px 17px;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    font-size: .95rem;
    width: 100%;
    transition: border-color .3s, box-shadow .3s, background .3s;
}
.field textarea { resize: vertical; min-height: 138px; }
.field input:focus, .field select:focus, .field textarea:focus {
    outline: none;
    border-color: var(--gold);
    box-shadow: 0 0 0 4px rgba(201, 162, 39, .13);
}
.field .hint { font-size: .76rem; color: var(--muted-light); letter-spacing: 0; text-transform: none; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.form-grid .full { grid-column: 1 / -1; }
@media (max-width: 680px) { .form-grid { grid-template-columns: 1fr; } }

/* A card the enquiry form sits in, so it reads as a considered panel rather
   than fields loose on the page. */
.form-card {
    background: var(--white);
    border-radius: var(--r-lg);
    padding: clamp(22px, 2.6vw, 30px);
    box-shadow: var(--shadow-sm);
}
/* The contact page is a form and a list of numbers — it does not need the
   full section rhythm the marketing pages use. */
.contact-section { padding-block: clamp(44px, 5vw, 74px); }
.contact-section .form-grid { gap: 14px; }
.contact-section .field input,
.contact-section .field select { padding: 11px 14px; }
.contact-section .field textarea { padding: 11px 14px; min-height: 104px; }
.contact-section .field { gap: 5px; }
.contact-section .info-list { gap: 14px; }
.contact-section .info-list .ico { width: 40px; height: 40px; }
.contact-section h2 { margin-bottom: 18px !important; }
.contact-section .map-frame, .contact-section .map-frame iframe { min-height: 280px; }

.note {
    padding: 16px 19px;
    border-radius: var(--r-sm);
    font-size: .88rem;
    border-left: 3px solid;
    margin-bottom: 24px;
}
.note-success { background: rgba(23, 77, 43, .06); border-color: var(--green); color: var(--green); }
.note-error   { background: rgba(176, 42, 42, .06); border-color: #b02a2a; color: #8e2020; }

.hp { position: absolute !important; left: -9999px !important; opacity: 0; height: 0; width: 0; }

/* --------------------------------------------------------------- info list */
.info-list { display: flex; flex-direction: column; gap: 22px; }
.site-footer .info-list { gap: 14px; }
.site-footer .info-list .ico { width: 38px; height: 38px; }
.info-list li { display: flex; gap: 16px; align-items: flex-start; }
.info-list .ico {
    width: 44px; height: 44px;
    flex: none;
    border: 1px solid var(--line-gold);
    border-radius: 50%;
    display: grid; place-items: center;
    color: var(--gold-deep);
    transition: background .3s, color .3s, border-color .3s;
}
.info-list li:hover .ico { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.info-list .ico svg { width: 17px; height: 17px; }
.info-list b {
    font-family: var(--font-caps);
    font-weight: 700;
    font-size: .88rem;
    letter-spacing: .01em;
    color: var(--muted);
    display: block;
    margin-bottom: 3px;
}
.info-list a, .info-list span { color: var(--ink); }
.info-list a:hover { color: var(--gold-deep); }
.on-dark .info-list a, .on-dark .info-list span { color: var(--white); }
.on-dark .info-list .ico { border-color: rgba(255,255,255,.22); color: var(--gold-pale); }

.ticks { display: grid; grid-template-columns: repeat(auto-fill, minmax(212px, 1fr)); gap: 12px 24px; }
.ticks li { display: flex; gap: 10px; align-items: center; font-size: .94rem; }
.ticks li::before {
    content: ''; width: 6px; height: 6px;
    background: var(--gold); transform: rotate(45deg); flex: none;
}

/* ------------------------------------------------------------------- prose */
.prose { max-width: 76ch; }
.prose h2 { font-size: clamp(1.6rem, 2.9vw, 2.2rem); margin: 1.7em 0 .55em; }
.prose h3 { font-size: 1.32rem; margin: 1.5em 0 .5em; }
.prose p, .prose ul, .prose ol, .prose blockquote, .prose table { margin-bottom: 1.2em; color: var(--muted); }
.prose ul, .prose ol { padding-left: 1.3em; list-style: revert; }
.prose li { margin-bottom: .45em; }
.prose a { color: var(--gold-deep); text-decoration: underline; text-underline-offset: 3px; }
.prose img { border-radius: var(--r-md); margin-block: 1.7em; box-shadow: var(--shadow-sm); }
.prose blockquote {
    border-left: 2px solid var(--gold);
    padding: 8px 0 8px 26px;
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-style: italic;
    font-weight: 400;
    color: var(--ink);
}
/* The editor allows <pre> and <code>, and without this they would fall back to
   the browser's default monospace — the one place on the site that would not be
   a Google Font. */
.prose code, .prose pre, code, pre {
    font-family: var(--font-mono);
    font-size: .88em;
}
.prose code {
    background: var(--gold-wash);
    border: 1px solid var(--line-gold);
    border-radius: 4px;
    padding: .12em .4em;
    color: var(--ink);
}
.prose pre {
    background: var(--ink);
    color: rgba(255, 255, 255, .9);
    padding: 20px 22px;
    border-radius: var(--r-md);
    overflow-x: auto;
    margin-bottom: 1.2em;
    line-height: 1.65;
}
.prose pre code { background: none; border: 0; padding: 0; color: inherit; }

.prose table { width: 100%; border-collapse: collapse; font-size: .93rem; }
.prose th, .prose td { border: 1px solid var(--line); padding: 11px 15px; text-align: left; }
.prose th { background: var(--parchment); font-family: var(--font-caps); font-weight: 700; letter-spacing: 0; }
.prose .table-scroll { overflow-x: auto; }

/* -------------------------------------------------------------------- misc */
.map-frame {
    position: relative;
    border-radius: var(--r-lg);
    overflow: hidden;
    border: 1px solid var(--line-soft);
    min-height: 360px;
    background: var(--green-mist);
    box-shadow: var(--shadow-xs);
}
.map-frame iframe { width: 100%; height: 100%; min-height: 360px; border: 0; }
.band-tight .map-frame, .band-tight .map-frame iframe { min-height: 300px; }

.socials { display: flex; gap: 10px; }
.socials a {
    width: 40px; height: 40px;
    border: 1px solid var(--line-gold);
    border-radius: 50%;
    display: grid; place-items: center;
    color: var(--gold-deep);
    transition: all .35s var(--ease);
}
.socials a:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); transform: translateY(-3px); }
.on-dark .socials a { border-color: rgba(255,255,255,.2); color: rgba(255,255,255,.82); }
.on-dark .socials a:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.socials svg { width: 15px; height: 15px; }

.empty {
    text-align: center;
    padding: 76px 24px;
    border: 1px dashed var(--line-gold);
    border-radius: var(--r-lg);
    color: var(--muted);
    background: var(--white);
}
.empty b {
    font-family: var(--font-caps);
    font-weight: 700;
    display: block; margin-bottom: 8px;
    color: var(--ink); letter-spacing: .01em; font-size: 1.05rem;
}

.pager { display: flex; gap: 8px; justify-content: center; margin-top: 58px; }
.pager a, .pager span {
    min-width: 44px; height: 44px;
    display: grid; place-items: center;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    font-size: .84rem;
    padding-inline: 13px;
    transition: all .3s;
}
.pager a:hover { border-color: var(--gold); color: var(--gold-deep); }
.pager .is-on { background: var(--ink); border-color: var(--ink); color: var(--white); }

/* The closing band is a heading and one button — it does not need the full
   section rhythm the content sections use. */
.cta-band { position: relative; overflow: hidden; padding-block: clamp(44px, 5vw, 76px); }
.cta-band .bg { position: absolute; inset: 0; }
.cta-band .bg img { width: 100%; height: 100%; object-fit: cover; opacity: .34; }
.cta-band .bg::after { content: ''; position: absolute; inset: 0; background: rgba(8,31,17,.76); }
.cta-band .shell { position: relative; z-index: 2; text-align: center; }

.wa-float {
    position: fixed;
    right: 22px; bottom: 22px;
    z-index: 80;
    width: 54px; height: 54px;
    border-radius: 50%;
    background: #25d366;
    color: var(--white);
    display: grid; place-items: center;
    box-shadow: 0 10px 30px rgba(37, 211, 102, .38);
    transition: transform .35s var(--ease);
}
.wa-float:hover { transform: scale(1.09); }
.wa-float svg { width: 27px; height: 27px; }

/* ------------------------------------------------------------------ footer */
.site-footer { background: var(--ink); color: rgba(255,255,255,.66); padding-top: clamp(46px, 5vw, 70px); }
.footer-grid {
    display: grid;
    grid-template-columns: 1.5fr 1fr 1fr 1.25fr;
    gap: clamp(24px, 3vw, 44px);
    padding-bottom: 38px;
}
@media (max-width: 940px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
/* Below 560 the footer is one column, and a single centred column reads far
   better than four left-aligned blocks stacked. Desktop and the two-column
   tablet layout are untouched. */
@media (max-width: 560px) {
    .footer-grid { grid-template-columns: 1fr; text-align: center; gap: 30px; }
    .footer-logo { margin-inline: auto; }
    .site-footer .socials { justify-content: center; }
    .site-footer h4 { margin-bottom: 12px; }
    .footer-links { align-items: center; }
    /* The hover nudge slides text off-centre, so it goes here. */
    .footer-links a:hover { padding-left: 0; }
    .site-footer .info-list li {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 8px;
    }
    .site-footer .btn { margin-inline: auto; }
    .footer-bottom { justify-content: center; text-align: center; gap: 10px; }
}

/* The footer has room for the full lockup, so the wordmark is legible here.
   The artwork's white ground is knocked out to alpha, so this flat knockout to
   cream sits correctly on the dark green rather than showing a white box. */
.footer-logo {
    width: 196px; max-width: 100%; height: auto;
    margin-bottom: 16px;
    filter: brightness(0) invert(1) opacity(.92);
}
.site-footer h4 {
    font-family: var(--font-caps);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--gold-pale);
    margin-bottom: 14px;
}
.footer-links { display: flex; flex-direction: column; gap: 9px; }
.footer-links a { font-size: .9rem; transition: color .3s, padding-left .3s var(--ease); }
.footer-links a:hover { color: var(--gold-pale); padding-left: 6px; }

.footer-bottom {
    border-top: 1px solid rgba(255,255,255,.09);
    padding-block: 16px 20px;
    display: flex; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    font-size: .8rem;
}
.footer-bottom a:hover { color: var(--gold-pale); }


/* ------------------------------------------------- hero buttons on any slide */
/* The hero is dark but is not marked .on-dark — the slide behind it is a
   photograph, and which photograph is up to the client. So the secondary
   button is pinned to a light treatment with a frosted ground, which stays
   legible over a bright sky and a dark forest alike. */
.hero .btn-ghost {
    color: var(--white);
    border-color: rgba(255, 255, 255, .58);
    background: rgba(255, 255, 255, .10);
    backdrop-filter: blur(10px) saturate(140%);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    text-shadow: 0 1px 12px rgba(8, 31, 17, .45);
}
.hero .btn-ghost::before { background: var(--white); }
.hero .btn-ghost:hover {
    color: var(--ink);
    border-color: var(--white);
    text-shadow: none;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .28);
}
.hero .btn-gold { box-shadow: 0 6px 22px rgba(8, 31, 17, .34); }

/* ------------------------------------------------------ property showcase */
/* One full-width row per property on Hotels & Resorts. The layout alternates,
   and so does the ground it sits on — cream, parchment, cream, parchment — so
   consecutive rows never read as a repeated card.

   The gold frame behind the picture flips to the OUTER corner of whichever
   side the picture is on, so it always opens away from the text rather than
   colliding with it. That single rule is what keeps the alternation feeling
   designed rather than mirrored. */
.prop-row { padding-block: clamp(56px, 7vw, 104px); overflow: hidden; }

.prop-grid {
    display: grid;
    grid-template-columns: 1.02fr 1fr;
    align-items: center;
    gap: clamp(30px, 5vw, 78px);
}
.prop-row.is-flipped .prop-media { order: 2; }

/* ------------------------------------------------------------------ picture */
.prop-media { position: relative; z-index: 1; }

.prop-frame {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: var(--shadow-md);
    transition: box-shadow .6s var(--ease-out), transform .6s var(--ease-out);
}
.prop-frame img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform 1.1s var(--ease-out);
}
.prop-frame::after {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(180deg, transparent 58%, rgba(8, 31, 17, .34));
    opacity: 0;
    transition: opacity .55s var(--ease);
}
.prop-frame:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }
.prop-frame:hover img { transform: scale(1.06); }
.prop-frame:hover::after { opacity: 1; }

/* The offset gold plate. It sits behind the picture and opens outward. */
.prop-media::before {
    content: "";
    position: absolute;
    inset: 24px -24px -24px 24px;      /* picture on the left: opens right */
    border: 1px solid var(--gold);
    border-radius: var(--r-lg);
    z-index: -1;
    transition: inset .6s var(--ease-out);
}
.prop-row.is-flipped .prop-media::before {
    inset: 24px 24px -24px -24px;      /* picture on the right: opens left */
}
.prop-media:hover::before { inset: 30px -30px -30px 30px; }
.prop-row.is-flipped .prop-media:hover::before { inset: 30px 30px -30px -30px; }

/* ------------------------------------------------------------------ content */
.prop-body h2 { margin-block: 14px 0; }
.prop-body h2 a { transition: color .3s var(--ease); }
.prop-body h2 a:hover { color: var(--gold-deep); }

.prop-place { margin-top: 12px; }
.prop-body .lede { margin-top: 16px; }

/* A short strip of that property's own numbers. */
.prop-facts {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(20px, 3vw, 40px);
    margin-top: 26px;
    padding-top: 22px;
    border-top: 1px solid var(--line);
}
.prop-facts li { display: flex; flex-direction: column; gap: 2px; }
.prop-facts b {
    font-family: var(--font-display);
    font-size: 1.75rem;
    font-weight: 400;
    line-height: 1;
    color: var(--gold-deep);
}
.prop-facts span { font-size: .86rem; color: var(--muted); }

/* Amenity chips, drawn from what the property actually offers. */
.prop-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 22px;
}
.prop-chips li {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px 7px 10px;
    font-size: .84rem;
    color: var(--muted);
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: 999px;
    transition: border-color .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.prop-chips li:hover {
    border-color: var(--gold);
    color: var(--ink);
    transform: translateY(-2px);
}
.chip-ico { width: 17px; height: 17px; color: var(--gold-deep); flex: none; }
.chip-ico svg { width: 100%; height: 100%; }
.band-parchment .prop-chips li { background: var(--cream); }

.prop-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }

/* --------------------------------------------------------------- responsive */
@media (max-width: 900px) {
    /* One column, picture first every time — alternating sides is meaningless
       in a stack, and leading with the photograph is the stronger order. */
    .prop-grid { grid-template-columns: 1fr; gap: clamp(24px, 5vw, 38px); }
    .prop-row.is-flipped .prop-media { order: 0; }
    .prop-frame { aspect-ratio: 16 / 10; }
    .prop-media::before,
    .prop-row.is-flipped .prop-media::before { inset: 16px -16px -16px 16px; }
}

@media (max-width: 560px) {
    .prop-row { padding-block: clamp(44px, 9vw, 64px); }
    .prop-frame { aspect-ratio: 4 / 3; }
    /* The offset plate would push past the gutter on a phone. */
    .prop-media::before,
    .prop-row.is-flipped .prop-media::before { display: none; }
    .prop-facts { gap: 18px; margin-top: 22px; padding-top: 18px; }
    .prop-facts b { font-size: 1.5rem; }
    .prop-actions .btn { flex: 1 1 auto; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
    .prop-frame, .prop-frame img, .prop-media::before { transition: none; }
}

/* ---------------------------------------------------------------- blog row */
/* Four across on a desktop. The shared .grid-4 drops straight from four to two
   at 980px, which leaves a lot of air on a laptop — these cards step down
   through three instead. Placed after .grid-4 so source order wins. */
@media (max-width: 1180px) and (min-width: 861px) {
    .blog-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 860px) and (min-width: 541px) {
    .blog-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 540px) {
    .blog-grid { grid-template-columns: 1fr; }
}

/* At a quarter of the row the card body needs to give the words more of the
   space and the padding less. */
.blog-grid .card-body { padding: 20px 20px 22px; gap: 8px; }
.blog-grid .card-body h3 { font-size: clamp(1.05rem, 1.25vw, 1.2rem); line-height: 1.3; }
.blog-grid .card-body p { font-size: .88rem; }
.blog-grid .card-place { font-size: .8rem; }
.blog-grid .link-gold { font-size: .84rem; padding-top: 12px; }
.blog-grid .card-media { aspect-ratio: 16 / 10; }

/* ------------------------------------------------------------------ motion */
@keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ---------------------------------------------------------- scroll reveal */
/* One system, several entrances. Elements only start hidden when JS is present
   to reveal them — .js is set on <html> by an inline script, so a visitor
   without JavaScript gets the whole page rather than an empty one.

   The delay is a custom property rather than a JS timer, so a stagger is one
   transition-delay instead of a queue of setTimeouts that drift under load. */
.js [data-reveal] {
    opacity: 0;
    transition:
        opacity 0.9s var(--ease-out) var(--d, 0ms),
        transform 1s var(--ease-out) var(--d, 0ms),
        clip-path 1.1s var(--ease-out) var(--d, 0ms);
}
.js [data-reveal="up"],
.js [data-reveal=""]      { transform: translateY(24px); }
.js [data-reveal="rise"]  { transform: translateY(38px) scale(.985); }
.js [data-reveal="left"]  { transform: translateX(-30px); }
.js [data-reveal="right"] { transform: translateX(30px); }
.js [data-reveal="fade"]  { transform: none; }

/* A heading that wipes up from its own baseline, rather than sliding in as a
   block. Used sparingly — section titles only. */
.js [data-reveal="mask"] {
    clip-path: inset(0 0 104% 0);
    transform: translateY(8px);
}

/* An image that settles rather than arrives: it starts slightly overscaled and
   cropped in, and relaxes to its true frame. */
.js [data-reveal="zoom"] {
    clip-path: inset(7% 5%);
    transform: scale(1.06);
}

.js [data-reveal].is-in { opacity: 1; transform: none; }
.js [data-reveal="mask"].is-in,
.js [data-reveal="zoom"].is-in { clip-path: inset(0 0 0 0); }

/* ------------------------------------------------------------- parallax */
/* --py is written by JS from scroll position. Only two layers get it — the
   hero backdrop and the closing band — because parallax on many elements at
   once is what makes a page feel cheap and janky rather than deep. */
[data-parallax] { will-change: transform; }
@media (min-width: 900px) {
    [data-parallax] { transform: translate3d(0, var(--py, 0px), 0); }
}

/* ------------------------------------------- the destination roll (signature) */
/* Each shield is uncovered by a curtain that drops away inside the crest
   silhouette, while the photograph behind it settles from a slight overscale.
   The caption follows a beat later, so the name lands after the picture.

   The curtain is a pseudo-element rather than a clip-path because .shield is
   already clipped to the crest, and an element can only carry one clip-path. */
.roll-item .shield::before {
    content: "";
    position: absolute;
    inset: -1px;
    z-index: 3;
    background: var(--ink);
    transform: translateY(0);
    transition: transform 1.05s var(--ease-out) var(--d, 0ms);
}
.roll-item.is-in .shield::before { transform: translateY(101%); }

.roll-item .shield img {
    transform: scale(1.16);
    transition: transform 1.4s var(--ease-out) var(--d, 0ms);
}
.roll-item.is-in .shield img { transform: scale(1); }
.roll-item.is-in:hover .shield img { transform: scale(1.07); transition-duration: .9s; }

.roll-item .shield-caption,
.roll-item .roll-link {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
    transition-delay: calc(var(--d, 0ms) + 620ms);
}
.roll-item.is-in .shield-caption,
.roll-item.is-in .roll-link { opacity: 1; transform: none; }
.roll-item .roll-link { transition-delay: calc(var(--d, 0ms) + 760ms); }

/* The crest lifts a little on hover, and its gold caption rule widens. */
.roll-item > a { transition: transform .6s var(--ease-out); display: block; }
.roll-item.is-in:hover > a { transform: translateY(-8px); }

/* ------------------------------------- "At every property" — the drawn grid */
/* The icons draw themselves. Every amenity glyph is a stroked path, so its
   outline can be dashed to its own length and that dash offset animated to
   zero — the line is genuinely drawn rather than faded in. JS measures each
   path with getTotalLength() and gives every tile a delay from its row PLUS
   its column, so the wave crosses the grid on the diagonal instead of
   marching left to right.

   The order within a tile is deliberate: the tile arrives, the icon draws,
   then the label lands. */
.js .amenity-grid .amenity { opacity: 0; transform: translateY(20px); }
.js .amenity-grid.is-in .amenity {
    opacity: 1;
    transform: none;
    transition: opacity .7s var(--ease-out) var(--dly, 0ms),
                transform .75s var(--ease-out) var(--dly, 0ms),
                background .35s var(--ease);
}

.js .amenity-grid .amenity-icon [data-draw] {
    stroke-dasharray: var(--len, 0);
    stroke-dashoffset: var(--len, 0);
}
.js .amenity-grid.is-in .amenity-icon [data-draw] {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 1.15s var(--ease-out) calc(var(--dly, 0ms) + 140ms);
}

.js .amenity-grid .amenity b { opacity: 0; transform: translateY(7px); }
.js .amenity-grid.is-in .amenity b {
    opacity: 1;
    transform: none;
    transition: opacity .6s var(--ease-out) calc(var(--dly, 0ms) + 480ms),
                transform .6s var(--ease-out) calc(var(--dly, 0ms) + 480ms);
}

/* On hover a gold rule draws out from the centre of the tile. */
.amenity { position: relative; overflow: hidden; }
.amenity::after {
    content: "";
    position: absolute;
    left: 50%; right: 50%; bottom: 0;
    height: 2px;
    background: var(--gold);
    transition: left .45s var(--ease), right .45s var(--ease);
}
.amenity:hover::after { left: 0; right: 0; }
.amenity:hover .amenity-icon { color: var(--gold); }

/* ------------------------------------------------------------ gallery tiles */
.js .masonry.is-in .shot {
    animation: fadeUp .8s var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 70ms);
}
.js .masonry:not(.is-in) .shot { opacity: 0; }

/* --------------------------------------------------------------- stat count */
/* The number is swapped by JS while counting; this keeps it from reflowing the
   row as the digits change width. */
.stat b { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ slide entrance */
/* Keyed to .is-on so it replays each time a slide comes round, and so the
   slides waiting behind do not animate while invisible. */
.hero-slide [data-seq] { opacity: 0; }
.hero-slide.is-on [data-seq] { animation: fadeUp .9s var(--ease-out) forwards; }
.hero-slide.is-on [data-seq="1"] { animation-delay: .15s; }
.hero-slide.is-on [data-seq="2"] { animation-delay: .28s; }
.hero-slide.is-on [data-seq="3"] { animation-delay: .41s; }
.hero-slide.is-on [data-seq="4"] { animation-delay: .54s; }
.hero-slide.is-on [data-seq="5"] { animation-delay: .67s; }

/* --------------------------------------------------------- reduced motion */
/* Everything above collapses to a plain, instant page. Nothing is left hidden:
   each starting state has to be undone explicitly, or a reader who asked for
   less motion would get a blank screen instead of a still one. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    .js [data-reveal],
    .js [data-reveal].is-in {
        opacity: 1;
        transform: none;
        clip-path: none;
    }
    .js .amenity-grid .amenity,
    .js .amenity-grid .amenity b,
    .js .masonry:not(.is-in) .shot { opacity: 1; transform: none; }
    .js .amenity-grid .amenity-icon [data-draw] {
        stroke-dasharray: none;
        stroke-dashoffset: 0;
    }
    .roll-item .shield::before { display: none; }
    .roll-item .shield img { transform: none; }
    .roll-item .shield-caption,
    .roll-item .roll-link { opacity: 1; transform: none; }
    .hero-slide [data-seq] { opacity: 1; animation: none; }
    .hero-media img { animation: none; transform: none; }
    [data-parallax] { transform: none !important; }
}

@media print {
    .site-header, .site-footer, .wa-float, .hero-cue, .btn { display: none !important; }
    body { background: #fff; }
    .js [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}

/* Recent-post thumbnails in the journal sidebar. The box is 74x64, so the
   zoom is proportionally small - anything more just blurs at that size. */
.thumb-mini img { transition: transform .5s var(--ease-out); }
.thumb-mini:hover img { transform: scale(1.09); }
@media (hover: none) { .thumb-mini:hover img { transform: none; } }
@media (prefers-reduced-motion: reduce) {
    .thumb-mini img { transition: none; }
    .thumb-mini:hover img { transform: none; }
}
