/* Howard Hall - site styles
   Brand: Heritage Blue (#355C7D) + Antique Brass (#A88443) on Soft Daylight, the client's
   "Version 3" palette (July 2026), replacing the original forest green + gold on cream.
   Self-hosted display font (Playfair Display), no CDNs. */

@font-face{
  font-family:"Playfair Display";
  src:url("fonts/playfair-display-latin.woff2") format("woff2");
  font-weight:400 900;font-style:normal;font-display:swap;
}

:root{
  /* Heritage Blue palette, the client's "Version 3" (July 2026). The variable NAMES are
     deliberately kept from the original green scheme so the rest of the stylesheet does
     not have to change; only the values differ. --heading is new: headings and the
     header/footer used to share one colour, and the client wants them different. */
  --green:#355C7D;        /* Heritage Blue: header, footer, page heroes, primary buttons */
  --green-dark:#274762;   /* Deep Heritage Blue: button hover, hero gradient dark end */
  --green-mid:#3f6b90;    /* mid blue: hero gradient light end, links, small icons */
  --heading:#243746;      /* Rich Charcoal: all headings */
  --gold:#A88443;         /* Antique Brass: accent */
  --gold-dark:#7d6130;    /* darker brass, for accent text that must meet contrast */
  --gold-lt:#e0cfa8;      /* light brass, for accents sitting on dark backgrounds */
  /* Layered surfaces, lightest on top: page (shaded) < secondary surfaces < cards.
     With the alternating bands gone the page needed its own tone, otherwise everything
     sat at near-white and nothing had definition. Kevin's Soft Daylight moves to the
     secondary surfaces and the cooler shade becomes the page itself. */
  --cream:#F7F8F7;        /* Soft Daylight: raised surfaces (trust strip, callouts, pills) */
  --cream-2:#EDF1F3;      /* shaded page background */
  --paper:#FDFCF8;        /* Soft Ivory: cards */
  --ink:#4E5A64;          /* Soft Charcoal: body text */
  --muted:#646e77;        /* Mid Grey: secondary text */
  --line:#E2E5E7;         /* Soft Stone: borders */
  --shadow:0 6px 22px rgba(28,45,60,.10);
  --serif:Georgia,"Times New Roman",Cambria,serif;
  --display:"Playfair Display",Georgia,"Times New Roman",serif;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --wrap:1120px;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  font-family:var(--sans);
  color:var(--ink);
  background:var(--cream-2);
  line-height:1.6;
  font-size:17px;
  /* Sticky footer. Without this a page whose content is shorter than the viewport leaves the
     footer stranded half way up the screen with bare background beneath it. Reported by Sean on
     2026-09-09 for Request a New Booking, which became short when Kevin's review removed its
     Please note box, but the same was already true of 404, error and thank-you. <main> takes the
     slack, so nothing moves on a page that already filled the screen. */
  min-height:100vh;
  display:flex;
  flex-direction:column;
}
body > main{flex:1 0 auto}
h1,h2,h3,h4{font-family:var(--display);font-weight:700;line-height:1.14;color:var(--heading);margin:0 0 .5em;letter-spacing:.004em}
h1{font-size:clamp(2rem,5vw,3.1rem)}
h2{font-size:clamp(1.5rem,3.4vw,2.2rem)}
h3{font-size:1.25rem}
p{margin:0 0 1rem}
a{color:var(--green-mid);text-decoration:underline;text-underline-offset:2px}
a:hover{color:var(--gold-dark)}
img{max-width:100%;display:block}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 20px}
.center{text-align:center}
.muted{color:var(--muted)}
.small{font-size:.9rem}

.skip{position:absolute;left:-999px;top:0;background:var(--gold);color:var(--green-dark);padding:10px 16px;z-index:200;border-radius:0 0 8px 0}
.skip:focus{left:0}

/* ---------- Header ---------- */
/* Solid Heritage Blue header with white navigation. This was the client's main objection
   to the earlier options: every one of them kept a light header, and he wants the header
   and footer to frame the page in the same blue. */
.site-header{position:sticky;top:0;z-index:100;background:var(--green);border-bottom:1px solid rgba(255,255,255,.12)}
.nav{display:flex;align-items:center;gap:21px;padding:21px 20px;max-width:var(--wrap);margin:0 auto}
.brand{display:flex;align-items:center;gap:12px;text-decoration:none}

.brand-text{font-family:var(--serif);line-height:1.05}
.brand-text .n1{display:block;font-size:1.15rem;font-weight:700;letter-spacing:.06em;color:#fff}
.brand-text .n2{display:block;font-size:.62rem;letter-spacing:.04em;color:rgba(255,255,255,.72)}
.menu{display:flex;flex:1;align-items:center;justify-content:space-between;gap:20px;margin:0 0 0 44px;padding:0;list-style:none}
.menu a{color:#fff;text-decoration:none;font-weight:600;font-size:.98rem;padding:6px 2px;border-bottom:2px solid transparent}
.menu a:hover{color:var(--gold-lt)}
.menu a.active{border-bottom-color:var(--gold-lt)}
.nav-cta{white-space:nowrap}
.hamburger{display:none;background:none;border:0;cursor:pointer;padding:8px;margin-left:4px}
.hamburger span{display:block;width:24px;height:2px;background:#fff;margin:5px 0;transition:.2s}

/* ---------- Buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:9px;font-family:var(--sans);font-weight:700;
  font-size:1rem;padding:13px 22px;border-radius:8px;border:2px solid transparent;cursor:pointer;text-decoration:none;transition:.15s}
.btn svg{width:18px;height:18px}
/* Sean, 2026-09-03: every button on every page is now the blue (Heritage Blue) type. The
   three class names are kept in the markup so this is one CSS change rather than an edit to
   26 call sites, and so it reverts in one commit; .btn-gold and .btn-ghost simply render the
   same as .btn-green. The shimmer sweep (.btn::after), the hover lift and the shadow are
   untouched. NOTE this removes the primary/secondary distinction the three variants carried,
   so a row of three buttons now reads as three equal choices. */
.btn-green,.btn-gold,.btn-ghost{background:var(--green);color:#fff;border-color:var(--green)}
/* Sean, 2026-09-03: "Request a booking" is the one action the whole site funnels towards, so it
   needs to lead without breaking the all-blue rule above. Same Heritage Blue fill, but ringed in
   Antique Brass and sat on a warm shadow, so it reads as primary on the dark hero image AND on a
   light page. Only the four buttons that actually open the MyHallWizard form carry this. */
.btn-primary{background:var(--green);color:#fff;border-color:var(--gold);
  box-shadow:0 4px 14px rgba(168,132,67,.34)}
.btn-primary:hover{background:var(--green-dark);color:#fff;border-color:var(--gold-lt);
  box-shadow:0 10px 24px rgba(168,132,67,.46)}
.btn-green:hover,.btn-gold:hover,.btn-ghost:hover{background:var(--green-dark);color:#fff;border-color:var(--green-dark)}
.btn-block{width:100%;justify-content:center}

/* ---------- Hero ---------- */
.hero{position:relative;background:linear-gradient(135deg,var(--green-dark),var(--green-mid));color:#fff;overflow:hidden}
.hero::after{content:"";position:absolute;inset:0;background:radial-gradient(1200px 400px at 78% -10%,rgba(168,132,67,.28),transparent 60%);pointer-events:none}
/* JS-00497: base (tall-viewport) hero padding cut from 70/64. The three max-height
   tiers below (760/620/470px) are deliberately NOT touched: they are load-bearing for the
   short-viewport defect fixed on 2026-07-20 (GO-LIVE §11.1), and cutting the base makes
   their absolute heights shorter for free. */
.hero-inner{position:relative;z-index:1;max-width:var(--wrap);margin:0 auto;padding:60px 20px 55px}
.hero h1{color:#fff}
.hero p.lead{font-size:1.15rem;max-width:46ch;color:#e8edf1}
/* The three gaps inside the hero (eyebrow to title, title to strapline, strapline to buttons)
   are Kevin's 17 Sep 2026 separations. THEY ARE SET IN FOUR PLACES AND THIS ONE REACHES THE
   FEWEST SCREENS: the max-height 820/620/470 tiers below each override all three absolutely,
   and a phone lands in the 820 tier by HEIGHT, so editing only these values leaves every
   handset on the old spacing. Change them together. */
.hero .cta-row{display:flex;flex-wrap:wrap;gap:14px;margin-top:38px}
/* --gold-lt, not --gold: this pill sits on a dark photograph, and the palette reserves the
   lighter brass for exactly that. Bolder and larger at Kevin's request, 17 Sep 2026. */
.hero-tag{display:inline-block;font-size:.95rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--gold-lt);border:1px solid rgba(224,207,168,.62);padding:7px 16px;border-radius:20px;margin-bottom:26px}
.page-hero{background:var(--green);color:#fff;text-align:center;padding:52px 20px}
.page-hero h1{color:#fff}
.page-hero p{max-width:60ch;margin:0 auto;color:#e6ecf1}
/* Intro paragraph(s) moved out of the hero into the readable column (Kevin's change).
   Always a wrapper div around one or more <p>. Full content width, matching the copy
   around it (no narrow measure). */
.page-lead{font-size:1.08rem;color:var(--ink);margin:0 0 1.3rem}
.page-lead p{margin:0 0 .8rem}
.page-lead p:last-child{margin-bottom:0}

/* ---------- Sections ---------- */
section{padding:38px 0}
/* One continuous page background. The alternating cream bands were a leftover from the
   original green scheme and duplicated the job of the ornament dividers, which is what
   made the divider land exactly on a background seam. The dividers now separate content
   on their own, matching the client's own reference designs. */
section.alt{background:transparent}
.section-head{text-align:center;max-width:60ch;margin:0 auto 34px}
.section-head p{color:var(--muted)}

/* ---------- Trust strip ---------- */
.trust{background:transparent}
/* 170px keeps all four across on desktop with room to spare (the track is 837px, and
   4x190+gaps came to 838, missing by a single pixel), while still dropping to 3 then 2
   as the strip narrows. */
.trust-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,170px),1fr));gap:26px;padding:26px 0}
.trust-item{display:flex;gap:12px;align-items:flex-start}
.trust-item svg{width:26px;height:26px;flex:none;color:var(--green-mid)}
.trust-item .trust-h{margin:.1em 0 .1em;font-family:var(--sans);font-size:1rem;font-weight:700}
.trust-item p{margin:0;font-size:.86rem;color:var(--muted)}

/* ---------- Cards / grids ---------- */
.grid{display:grid;gap:24px}
/* Fluid grids: "fit as many columns as comfortably fit" rather than fixed counts that
   snap at breakpoints. The min values are chosen to keep the desktop column counts
   identical while letting mid widths (scaled desktops, tablets) flow instead of collapsing. */
.grid-4{grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr))}
.grid-3{grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
/* NOT fluid, deliberately. The room-page gallery is the only user of .grid-2 and it sits
   inside a half-width column (523px), where an auto-fit minimum wide enough for full-width
   use silently collapsed it to a single column and stacked the two small photos. Left as a
   fixed two-up, exactly as it was, collapsing to one column on small screens. */
.grid-2{grid-template-columns:repeat(2,1fr)}
.card{background:var(--paper);border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:var(--shadow);display:flex;flex-direction:column}
.card .body{padding:18px 20px 22px;display:flex;flex-direction:column;flex:1}
.card h3{margin-bottom:.3em}
.card .meta{display:flex;flex-wrap:wrap;gap:16px;font-size:.85rem;color:var(--muted);margin:2px 0 10px}
.card .meta span{display:inline-flex;align-items:center;gap:6px}
.card .meta svg{width:15px;height:15px;color:var(--green-mid)}
.card .more{margin-top:auto;padding-top:10px;font-weight:700;color:var(--green-mid);text-decoration:none}
.card .more:hover{color:var(--gold-dark)}

/* ---------- Image placeholders ---------- */
.ph{background:linear-gradient(135deg,#2f5470,#22405a);color:#cbb68f;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:8px;aspect-ratio:16/10;text-align:center;padding:14px}
.ph svg{width:34px;height:34px;opacity:.85}
.ph span{font-size:.8rem;letter-spacing:.04em;opacity:.9}
.ph.tall{aspect-ratio:4/5}
.ph.wide{aspect-ratio:21/9}

/* ---------- CTA cards (booking) ---------- */
.cta-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,400px),1fr));gap:24px}
.cta-card{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:26px;box-shadow:var(--shadow);text-align:center}
.cta-card .ic{width:44px;height:44px;color:var(--green-mid);margin:0 auto 10px}
.cta-card p{color:var(--muted);font-size:.95rem}

/* ---------- History band ---------- */
.history{background:var(--cream);display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr));gap:40px;align-items:center}
.history .ph{border-radius:12px}

/* ---------- Doc / link lists ---------- */
.doc-list{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.doc-list li{background:var(--paper);border:1px solid var(--line);border-radius:10px;padding:14px 16px;display:flex;gap:14px;align-items:center}
.doc-list li svg{width:22px;height:22px;color:var(--green-mid);flex:none}
.doc-list .t{font-weight:700;color:var(--green-dark)}
.doc-list .d{font-size:.85rem;color:var(--muted)}
.doc-list .dl{margin-left:auto;white-space:nowrap;font-weight:700;text-decoration:none;color:var(--green-mid)}
.pill{display:inline-block;font-size:.7rem;background:var(--cream);border:1px solid var(--line);border-radius:20px;padding:2px 10px;color:var(--muted);margin-left:8px;vertical-align:middle}

/* ---------- Activities ---------- */
/* Daytime Activities: compact tile grid; each tile's full blurb opens in a popup (app.js) */
.act-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr));gap:20px}
.act-tile{background:var(--paper);border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:var(--shadow);cursor:pointer;display:flex;flex-direction:column;text-align:left}
/* No photo on the card face: where one exists it stays in the DOM (hidden) purely so the
   pop-up can clone it. Activities without a photo carry no placeholder at all. */
.act-tile>.ph{display:none}
.act-tile-body{padding:14px 16px 16px;display:flex;flex-direction:column;flex:1}
/* "Two lines of images": a slim strip of hall/activity photos above and below the tile grid. */
.act-band{display:grid;gap:16px;margin:26px 0}
.act-band .ph{aspect-ratio:3/2;border-radius:12px}
.act-band .ph.band-wide{aspect-ratio:2/1}
.act-band .ph.band-square{aspect-ratio:1/1}
.act-band-top{grid-template-columns:1fr 1fr}
.act-band-bottom{grid-template-columns:1fr 2fr 1fr;align-items:center}
@media(max-width:640px){.act-band-top,.act-band-bottom{grid-template-columns:1fr}}
.act-tile h2{margin:0;font-size:1.12rem;line-height:1.25}
.act-tile .when{font-size:.82rem;color:var(--gold-dark);font-weight:700;margin-top:3px}
.act-tile .when:empty{display:none}
.act-tile .when p{display:inline;margin:0}
.act-tile h2 p{display:inline;margin:0;font:inherit}
.act-cal-link{margin:14px 0 0;font-size:.92rem;font-weight:600}
.act-open{margin-top:auto;align-self:flex-start;background:none;border:0;color:var(--green-mid);font-weight:700;cursor:pointer;padding:10px 0 0;font-size:.92rem}
.act-open:hover{color:var(--gold-dark)}
.act-open:focus-visible{outline:3px solid var(--gold);outline-offset:2px;border-radius:2px}
/* activity popup */
.act-modal{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:22px;background:rgba(14,22,30,.86)}
.act-modal[hidden]{display:none}
.act-modal-inner{position:relative;background:var(--paper);width:100%;max-width:620px;max-height:90vh;overflow:auto;border-radius:14px;box-shadow:0 24px 60px rgba(0,0,0,.5)}
.act-modal-photo:empty{display:none}
.act-modal-photo .ph{aspect-ratio:16/9;border-radius:14px 14px 0 0}
.act-modal-body{padding:22px 26px 24px}
.act-modal-body>p:first-child{margin-top:.5em}
.act-modal-close{position:absolute;top:12px;right:14px;width:40px;height:40px;border:0;border-radius:50%;background:rgba(14,22,30,.55);color:#fff;font-size:1.6rem;line-height:1;cursor:pointer;z-index:2}
.act-modal-close:hover{background:rgba(14,22,30,.82)}
.act-modal-close:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
body.lb-open .act-modal-inner{animation:lbfade .2s ease}

/* Embedded location map (click-to-load, so no third-party cookies until asked) */
.map-embed{border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:var(--shadow);margin-top:14px}
.map-embed iframe{display:block;width:100%;height:300px;border:0}

/* Lightbox: click a photo to view it larger */
.ph.has-photo img.zoomable{cursor:zoom-in}
.lightbox{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(14,22,30,.88);cursor:zoom-out}
.lightbox[hidden]{display:none}
.lightbox-fig{margin:0;max-width:min(1100px,94vw);max-height:92vh;display:flex;flex-direction:column;align-items:center;gap:10px}
.lightbox-fig img{max-width:100%;max-height:86vh;width:auto;height:auto;border-radius:6px;box-shadow:0 24px 60px rgba(0,0,0,.55)}
.lightbox-fig figcaption{color:#eef1f4;font-size:.9rem;text-align:center;max-width:80ch;margin:0}
.lightbox-close{position:absolute;top:14px;right:18px;width:44px;height:44px;border:0;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;font-size:1.7rem;line-height:1;cursor:pointer}
.lightbox-close:hover{background:rgba(255,255,255,.30)}
.lightbox-close:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
body.lb-open{overflow:hidden}
.lightbox:not([hidden]){animation:lbfade .2s ease}
@keyframes lbfade{from{opacity:0}to{opacity:1}}

/* Return-to-top button: fixed bottom-right, appears once you scroll down */
.to-top{position:fixed;right:22px;bottom:22px;width:48px;height:48px;border-radius:50%;border:0;background:var(--green);color:#fff;display:grid;place-items:center;cursor:pointer;box-shadow:var(--shadow);opacity:0;visibility:hidden;transform:translateY(12px);transition:opacity .3s ease,transform .3s ease,background .2s ease;z-index:200}
.to-top.show{opacity:1;visibility:visible;transform:none}
.to-top:hover{background:var(--gold-dark)}
.to-top svg{width:22px;height:22px}
.to-top:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
@media(max-width:720px){.to-top{right:14px;bottom:14px;width:44px;height:44px}}

/* ---------- Forms ---------- */
.form{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:26px;box-shadow:var(--shadow);max-width:640px}
.field{margin-bottom:16px}
.field label{display:block;font-weight:600;margin-bottom:6px}
.field .req{color:#b23}
.field input,.field textarea,.field select{width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:8px;font:inherit;background:#fff}
.field input:focus,.field textarea:focus{outline:2px solid var(--green-mid);border-color:transparent}
/* Missing required field highlighting.
   JS path: app.js adds novalidate + marks each empty field with .is-invalid + an inline message.
   No-JS path: the browser's own required-field validation fires and :user-invalid gives the red
   border. Scoped to :not([novalidate]) so once JS takes over there is no double-marking. */
.field.is-invalid input,.field.is-invalid textarea,.field.is-invalid select,
.form:not([novalidate]) .field input:user-invalid,
.form:not([novalidate]) .field textarea:user-invalid,
.form:not([novalidate]) .field select:user-invalid{
  border-color:#c0392b;box-shadow:0 0 0 3px rgba(192,57,43,.15)}
.field.is-invalid .consent,
.form:not([novalidate]) .consent:has(input:user-invalid){color:#c0392b}
.field-error{color:#c0392b;font-size:.86rem;font-weight:600;margin:6px 0 0}
.radio-row{display:flex;gap:10px 22px;flex-wrap:wrap;align-items:center}
.radio-row label{font-weight:400;display:inline-flex;gap:8px;align-items:center;white-space:nowrap;margin:0}
.radio-row input{width:auto;flex:none;margin:0}
.embed{background:repeating-linear-gradient(45deg,#eee,#eee 12px,#e6e6e6 12px,#e6e6e6 24px);border:2px dashed #b9b2a0;border-radius:12px;min-height:420px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:#6b6459;text-align:center;padding:20px}
.embed svg{width:40px;height:40px;opacity:.6}

/* ---------- Notes / callouts ---------- */
.note{background:#fdf6e8;border:1px solid #e9d79a;border-left:4px solid var(--gold);border-radius:8px;padding:14px 16px;font-size:.92rem;color:#6b5a25}
/* FAQ accordion */
.faq-list{max-width:860px;margin:0 auto}
.faq-item{background:var(--paper);border:1px solid var(--line);border-radius:12px;margin-bottom:12px;box-shadow:var(--shadow)}
.faq-item>summary{cursor:pointer;padding:16px 20px;font-weight:700;font-size:1.06rem;color:var(--heading);list-style:none;display:flex;align-items:flex-start;gap:12px}
.faq-item>summary::-webkit-details-marker{display:none}
.faq-item>summary::before{content:"\25B8";color:var(--gold-dark);transition:transform .15s;flex:none;margin-top:2px}
.faq-item[open]>summary::before{transform:rotate(90deg)}
.faq-item>summary:hover{color:var(--green)}
.faq-a{padding:0 20px 18px 44px;line-height:1.65}
.faq-a p{margin:0}
.callout{background:var(--cream);border:1px solid var(--line);border-radius:12px;padding:22px 24px}
.callout h3 svg,.callout h2.callout-h svg{width:22px;height:22px;vertical-align:-4px;margin-right:6px}
/* A callout heading that has to be an <h2> for document structure but should still LOOK like
   the h3 callout headings elsewhere. Used where the callout is a page's only sub-heading, so an
   h3 would skip a level straight from the h1: About Us (after the duplicated "A Century of
   Service" heading was removed at Kevin's request, 8 Sep 2026) and Cancel or Change, which had
   the same gap already. Size matches h3 exactly, so nothing moves on the page. */
.callout h2.callout-h{font-size:1.25rem;line-height:1.35}

/* Contact-page triage: compact three-across signpost cards */
.triage .callout{padding:20px 22px}
.triage .tri-ic{width:32px;height:32px;color:var(--green-mid);margin-bottom:8px}
.triage .callout h2{font-size:1.05rem;line-height:1.3}
.triage .callout p{font-size:.93rem;color:var(--muted)}

/* ---------- Footer ---------- */
/* footer matches the header, so the blue frames the page top and bottom (client's brief) */
.site-footer{background:var(--green);color:#dbe4ec;padding:30px 0 14px;margin-top:10px}
.site-footer a{color:#e0cfa8;text-decoration:none}
/* the brand blurb and address carry a default 1rem bottom margin they do not need here */
.site-footer .foot-grid p{margin-bottom:0}
.site-footer .brand{margin-bottom:10px!important}
.site-footer a:hover{text-decoration:underline}
.foot-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr));gap:20px 26px;align-items:start}
.foot-grid .foot-h{color:#fff;font-family:var(--sans);font-size:.85rem;letter-spacing:.1em;text-transform:uppercase;font-weight:700;margin:0 0 9px}
.foot-row{display:flex;gap:10px;margin-bottom:7px;font-size:.92rem;align-items:flex-start;line-height:1.45}
.foot-row svg{width:17px;height:17px;flex:none;margin-top:3px;color:var(--gold-lt)}
.foot-links{list-style:none;margin:0;padding:0;display:grid;gap:9px;font-size:.92rem}
.foot-bottom{border-top:1px solid rgba(255,255,255,.14);margin-top:18px;padding-top:12px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;font-size:.82rem;color:#c2d2df}
.foot-bottom a{color:#c2d2df}

/* ---------- Breadcrumb ---------- */
.crumb{font-size:.85rem;color:var(--muted);padding:16px 0 0}
.crumb a{color:var(--green-mid)}
/* Option B: the breadcrumb relocated to the top of the first content section (inside a <section>)
   drops its own top padding (the section already provides the space) and adds a little below. */
/* Sean, 2026-09-03: the breadcrumb is now the last thing on the page, immediately above the
   footer, so it needs space below it rather than above and a light rule to separate it from
   the content it follows. */
.crumb-foot{border-top:1px solid var(--line);margin-top:8px}
.crumb-foot .crumb{padding:14px 0 26px;margin:0}

/* ---------- Utility spacing ---------- */
.mt0{margin-top:0}.mb0{margin-bottom:0}
.stack>*+*{margin-top:14px}
.two-col{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:34px}
.spec-table{width:100%;border-collapse:collapse;margin:8px 0 18px}
.spec-table th,.spec-table td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--line);font-size:.95rem}
.spec-table th{width:44%;color:var(--green-dark)}

/* ---------- Responsive ---------- */
/* The old fixed-count overrides here were removed: the grids above are now fluid
   (auto-fit + minmax), so they reflow continuously instead of snapping at 900 and 720. */
@media(max-width:720px){
  /* .grid-2 is fixed rather than fluid (see above), so it still needs its original
     collapse to a single column on small screens */
  .grid-2{grid-template-columns:1fr}
  section{padding:28px 0}
}

/* --- forms: honeypot, error banner, accessibility (added in build stage) --- */
.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;overflow:hidden}
.form-error{background:#fdecea;border:1px solid #f5c6c2;border-left:4px solid #c0392b;
  border-radius:8px;padding:14px 16px;margin-top:16px;color:#7a271f;font-size:.92rem}
.req{color:#c0392b}
/* Visible keyboard focus for links, buttons and controls */
a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible,
[tabindex]:focus-visible{outline:3px solid var(--gold);outline-offset:2px;border-radius:2px}

/* --- real photographs (added when client photos arrived) --- */
.ph.has-photo{padding:0;background:#24384a;overflow:hidden}
.ph.has-photo img{width:100%;height:100%;object-fit:cover;display:block}
/* Homepage hero with a photo background + green overlay for legible text */
.hero.has-bg{background-image:linear-gradient(180deg,rgba(28,45,60,.72),rgba(28,45,60,.82)),url('img/main-hall-01-1600.jpg');
  background-size:cover;background-position:center 42%}

/* --- MyHallWizard embedded calendar --- */
/* Calendar colour key (above the availability calendar): a coloured dot per room, room name
   as text so meaning never rests on colour alone. */
.cal-key{display:flex;flex-wrap:wrap;align-items:center;gap:8px 22px;margin:0 0 16px;font-size:.92rem}
.cal-key-item{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:var(--ink)}
.cal-dot{width:13px;height:13px;border-radius:50%;flex:none;box-shadow:0 0 0 1px rgba(0,0,0,.14)}
.cal-key-note{color:var(--muted)}
.calendar-embed{background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;min-height:640px}
#hw-calendar{width:100%;border:0;display:block;min-height:640px}

/* --- contact form extras: consent tick, optional label, contact list --- */
.optional{font-weight:400;color:var(--muted);font-size:.85rem}
.consent{display:flex!important;gap:10px;align-items:flex-start;font-weight:400;cursor:pointer}
.consent input{width:auto;flex:none;margin-top:3px}
.contact-list{list-style:none;margin:0;padding:0}
.contact-list li{display:flex;gap:12px;align-items:flex-start;margin-bottom:14px}
.contact-list li:last-child{margin-bottom:0}
.contact-list svg{width:20px;height:20px;color:var(--gold);flex:none;margin-top:2px}
.contact-list a{color:inherit}

/* --- mobile fixes (accessibility + responsive pass) --- */
@media(max-width:720px){
  html,body{overflow-x:hidden}
}
@media(max-width:520px){
  .hero .cta-row{flex-direction:column;align-items:stretch}
  .hero .cta-row .btn{width:100%;justify-content:center}
}

/* ===== motion / movement layer ===== */
/* cinematic cross-fading hero */
.hero.has-slides{position:relative;overflow:hidden}
.hero.has-slides .heroslide{position:absolute;inset:0;width:100%;height:112%;object-fit:cover;opacity:0;
  transition:opacity 1.4s ease;animation:hh-kb 12s ease-in-out infinite alternate;will-change:opacity,transform}
.hero.has-slides .heroslide.on{opacity:1}
/* Sean, 14 Sep 2026: start at scale(1), not 1.05. The cycle is `alternate` with no fill, so a
   1.05 start meant the slides oscillated 1.05 to 1.16 and were NEVER shown at their true size:
   the picture read as already zoomed in before any motion began, which is exactly what Sean
   reported. From 1 the first frame is the photo as framed, and the drift outwards is the whole
   of the effect rather than the top of it. Note the slide element is separately set to 112% of
   the hero height (see .heroslide above), so there is still a deliberate crop here; this change
   removes the transform's share of it, not that one. */
@keyframes hh-kb{from{transform:scale(1)}to{transform:scale(1.16) translate(-2%,-2%)}}
.hero.has-slides .hero-veil{position:absolute;inset:0;z-index:0;
  background:linear-gradient(180deg,rgba(28,45,60,.52),rgba(28,45,60,.72))}
.hero.has-slides .hero-inner{position:relative;z-index:1}
.hero.has-slides .hero-tag{animation:hh-rise .8s .15s both}
.hero.has-slides p.lead{animation:hh-rise .9s .55s both}
@keyframes hh-rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
/* scroll reveal */
.reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.2,1)}
.reveal.in{opacity:1;transform:none}
/* card hover motion */
.card{transition:transform .4s cubic-bezier(.2,.7,.2,1),box-shadow .4s}
.card:hover{transform:translateY(-7px);box-shadow:0 20px 44px rgba(28,45,60,.18)}
.card .ph.has-photo img{transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.card:hover .ph.has-photo img{transform:scale(1.07)}
.card .more{position:relative}
.card .more::after{content:"";position:absolute;left:0;bottom:-2px;width:100%;height:2px;background:var(--gold);
  transform:scaleX(0);transform-origin:left;transition:transform .35s}
.card:hover .more::after{transform:scaleX(1)}
/* header slims on scroll */
.site-header .nav{transition:padding .25s ease}
.site-header.shrink .nav{padding:12px 20px}
/* Motion is intentionally ALWAYS ON (client/design decision, 2026-07-11): animation is
   deliberately NOT gated on prefers-reduced-motion. See docs/luxe-visual-upgrade-plan.md. */

/* motion on interior pages: heading entrance + more hover */
.page-hero h1,.page-title h1{animation:hh-rise .8s .1s both}
.page-hero p,.page-title p{animation:hh-rise .85s .25s both}
.act-tile:hover{box-shadow:0 16px 36px rgba(28,45,60,.15)}
.act-tile .ph.has-photo img{transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.act-tile:hover .ph.has-photo img{transform:scale(1.06)}

/* ===== consistent hover vocabulary + title rise everywhere ===== */
/* every page's title rises in on load (hero/page-hero rules above keep their own timing) */
h1{animation:hh-rise .8s .1s both}
/* buttons lift on hover (so hover reads as motion, not just colour) */
.btn{transition:background .15s,color .15s,transform .2s cubic-bezier(.2,.7,.2,1),box-shadow .2s}
.btn:hover{transform:translateY(-2px);box-shadow:0 10px 22px rgba(28,45,60,.18)}
/* callouts + document rows lift like cards */
.callout{transition:transform .35s cubic-bezier(.2,.7,.2,1),box-shadow .35s}
.callout:hover{transform:translateY(-3px);box-shadow:0 14px 30px rgba(28,45,60,.10)}
.doc-list li{transition:transform .3s cubic-bezier(.2,.7,.2,1),box-shadow .3s,border-color .3s}
.doc-list li:hover{transform:translateY(-3px);box-shadow:0 12px 26px rgba(28,45,60,.12);border-color:var(--gold)}
/* any photo zooms when hovered directly (room galleries etc.) */
.ph.has-photo img{transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.ph.has-photo:hover img{transform:scale(1.06)}
/* animated gold underline for nav + footer links (inline text links keep their underline) */
.menu a,.foot-links a{position:relative}
.menu a::after,.foot-links a::after{content:"";position:absolute;left:0;bottom:-2px;height:2px;width:100%;
  background:var(--gold-lt);transform:scaleX(0);transform-origin:left;transition:transform .3s}
.menu a:hover::after,.foot-links a:hover::after{transform:scaleX(1)}

/* ===== dropdown navigation ===== */
.menu .has-sub{position:relative}
.sub-toggle{background:none;border:0;cursor:pointer;color:inherit;padding:6px 2px 6px 4px;display:inline-flex;align-items:center}
.sub-toggle::after{content:"";width:7px;height:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:translateY(-2px) rotate(45deg);opacity:.65}
.submenu{list-style:none;margin:0;padding:8px 0;position:absolute;top:calc(100% + 2px);left:0;min-width:224px;
  background:var(--paper);border:1px solid var(--line);border-radius:0 0 10px 10px;box-shadow:var(--shadow);
  opacity:0;visibility:hidden;transform:translateY(6px);transition:opacity .2s,transform .2s,visibility .2s;z-index:120}
.menu .has-sub:hover>.submenu,.menu .has-sub:focus-within>.submenu,.menu .has-sub.open>.submenu{opacity:1;visibility:visible;transform:none}
.submenu li{border:0}
/* the dropdown is a light panel under a dark header, so it needs its own text colour
   rather than inheriting the white used for the nav bar */
.submenu a{display:block;padding:9px 18px;font-weight:600;white-space:nowrap;border-bottom:0;color:var(--heading)}
.submenu a::after{display:none!important}
.submenu a:hover{background:rgba(168,132,67,.14);color:var(--gold-dark)}
.submenu a.active{color:var(--gold-dark);background:rgba(168,132,67,.10)}
/* Hamburger only where it is genuinely needed: real phones (700px and under), and
   TOUCH devices up to 1000px, where the hover dropdowns cannot be opened by tap.
   A mouse-driven screen between 701 and 1000 keeps the full horizontal menu (condensed
   to fit, see below). That band is exactly what a desktop at high Windows display
   scaling reports: 1920px at 250% scaling = 768 CSS px. Those users have a mouse and a
   big screen, so giving them a phone menu was wrong. */
/* JS-00536: 766, and every digit of it is measured. The plain threshold was 700px, which left
   a band where a MOUSE user kept the six-item horizontal menu at a width too narrow to hold it,
   so the nav wrapped to two rows and the STICKY header went 56px to 83px on every page at every
   scroll position, which is a third of the header's height given away at every width in the band.
   Measured with headless Chromium at 900px viewport height, forced to a genuine fine pointer
   (--blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,
   availablePointerTypes=4). 701 to 760 wrapped, 767 upwards was clean at 56px, so the hamburger
   now takes everything to 766 and the horizontal menu starts where it actually fits.
   WHAT THIS BUYS IS A SINGLE ROW, NOT A SHORTER HEADER. The band goes from 83px wrapped onto two
   rows to 85px on one row, which is the same 85px every hamburger width from 375px up already
   had. The gain is that the nav no longer visibly breaks when a desktop window is dragged through
   the band, and that this band now matches the phone layout instead of being its own third case.
   HOW TO RE-MEASURE THIS WITHOUT FOOLING YOURSELF, because two different tools got it wrong here.
   Below 768px a browser pane's device emulation forces a TOUCH profile, and headless Chromium
   defaults to a coarse pointer; either way (hover:none) matches, the hamburger appears for the
   wrong reason, and the band reports as healthy when it is not. Worse, with hover:none the
   condensing tiers below are inert too, so the header measures TALLER than a real mouse user
   would ever see. Force the pointer explicitly, and check the reading says it is fine. */
@media(max-width:766px), (max-width:1000px) and (hover:none){
  .menu{position:absolute;top:100%;left:0;right:0;flex:none;margin:0;justify-content:flex-start;
    background:var(--paper);flex-direction:column;align-items:stretch;gap:0;padding:6px 0;
    border-bottom:1px solid var(--line);box-shadow:var(--shadow);display:none}
  .menu.show{display:flex}
  .menu li{border-top:1px solid var(--line)}
  /* light drop-down panel, so override the white nav-bar text */
  .menu a{display:block;padding:14px 20px;color:var(--heading)}
  .menu a.active{border-bottom:0;color:var(--gold-dark)}
  .hamburger{display:block}
  .brand-text .n2{display:none}
  /* let the long wordmark wrap to two lines instead of overflowing/clipping the header */
  .brand{min-width:0}
  .brand-text .n1{font-size:.98rem;letter-spacing:.02em;line-height:1.12}
  .nav{gap:12px}
  .menu .has-sub{position:static}
  .sub-toggle{position:absolute;right:6px;top:6px;padding:12px}
  .submenu{position:static;opacity:1;visibility:visible;transform:none;display:none;box-shadow:none;border:0;
    border-radius:0;background:rgba(28,45,60,.04);padding:0;min-width:0}
  .menu .has-sub:hover>.submenu,.menu .has-sub:focus-within>.submenu{display:none}
  .menu .has-sub.open>.submenu{display:block}
  .submenu a{padding:12px 20px 12px 38px}
}

/* Condensed horizontal nav, so the full 6-item menu survives as far down as it fits on
   mouse-driven screens instead of collapsing. Scoped to hover/fine pointers so it never
   applies to the touch hamburger above.
   THE LOWER BOUND MUST TRACK THE HAMBURGER THRESHOLD, 767 against its 766. These tiers sit
   AFTER the hamburger block in the file, so anywhere both match, these win on the properties
   they share (.menu margin-left and gap, .menu a font-size). Before 17 Sep 2026 they could
   never overlap: the hamburger stopped at 700 and these started at 701. Raising the hamburger
   to 766 while these still started at 701 created a 66px band where a MOUSE user got the
   hamburger AND these rules, which inset the open dropdown panel by 8px and put a 6px gap
   between rows that are meant to sit flush against their border separators. Nothing looked
   broken until the menu was actually opened. If either number moves, move the other. */
@media (min-width:767px) and (max-width:1080px) and (hover:hover) and (pointer:fine){
  .nav{gap:12px}
  .menu{margin-left:24px;gap:12px}
  /* never let a label wrap: a second line silently makes the whole header taller */
  .menu a{font-size:.88rem;white-space:nowrap}
  
  .brand-text .n1{font-size:1.04rem}
  /* keep the strapline on one line, otherwise it wraps and the header grows taller */
  .brand-text .n2{font-size:.56rem;letter-spacing:.03em;white-space:nowrap}
}
@media (min-width:767px) and (max-width:950px) and (hover:hover) and (pointer:fine){
  .nav{gap:8px;padding:14px 16px}
  .menu{margin-left:12px;gap:7px}
  .menu a{font-size:.8rem}
  
  .brand-text .n1{font-size:.92rem;letter-spacing:.03em}
  .brand-text .n2{display:none}
}
/* JS-00536. A third step, and the measurement that produced it contradicts the ticket that
   raised it, so the reasoning is worth keeping.
   THE WORDMARK IS NOT THE MAIN CAUSE, which is what the ticket blamed. Between 735 and 766 the
   wordmark sits on ONE line and the header is still tall; what wraps is the MENU, its six items
   dropping to a second row and taking the <ul> from 27px to 54px. The wordmark only adds a second
   line at 730 and below, so it is a symptom near the bottom of the band, not the mechanism.
   THIS TIER BUYS 4px AND THAT IS ALL IT WAS KEPT FOR. Taking the width out of the wordmark rather
   than the link text (shrinking the links would put nav labels under 12px for an audience that
   skews older) moved the first healthy width from 771 to 767. An earlier attempt to fix the WHOLE
   band this way was wrong: a slack calculation at one width suggested about 40px of headroom and
   predicted the menu would survive down to 728, and a real fine-pointer sweep then showed it still
   wrapping at every width from 701 to 760. The flex box reports differently once space-between has
   distributed the slack, so do not size this tier by arithmetic; measure it.
   So the tier earns its place by making 767 to 820 fit, and the hamburger threshold above covers
   everything below that. */
@media (min-width:767px) and (max-width:820px) and (hover:hover) and (pointer:fine){
  .brand-text .n1{font-size:.8rem}
  .menu{margin-left:8px;gap:6px}
}

/* ======================================================================
   LUXE VISUAL LAYER (2026-07-11): Playfair headings, gold foil, cinematic
   hero, ornament dividers, linen texture, count-up stats, tilt cards + gold
   photo frames. Self-contained (no CDNs), CSP-safe. Motion always on.
   ====================================================================== */

/* gold foil headings: hero title, interior page-hero H1s, feature H2s */
.foil{color:var(--gold-dark)}
.foil,.page-hero h1,.page-title h1{
  background:linear-gradient(92deg,#7d6130 0%,#a88443 30%,#dcc79a 50%,#a88443 70%,#7d6130 100%);
  background-size:200% auto}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .foil{-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;animation:foil 9s linear infinite}
  .page-hero h1,.page-title h1{-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;animation:hh-rise .8s .1s both,foil 9s linear infinite}
}
@keyframes foil{to{background-position:200% center}}
.page-hero h1,.page-title h1{position:relative}
.page-hero h1::after,.page-title h1::after{content:"";display:block;width:72px;height:2px;margin:18px auto 0;
  background:linear-gradient(90deg,var(--gold),var(--gold-lt))}
/* room detail pages keep the photo-beside-title layout; gild the title in place */
.room-h1{position:relative}
.room-h1::after{content:"";display:block;width:72px;height:2px;margin:14px 0 2px;
  background:linear-gradient(90deg,var(--gold),var(--gold-lt))}

/* shine sweep on every button */
.btn{position:relative;overflow:hidden}
.btn::after{content:"";position:absolute;top:0;left:-140%;width:55%;height:100%;pointer-events:none;
  background:linear-gradient(120deg,transparent,rgba(255,255,255,.45),transparent);
  transform:skewX(-20deg);transition:left .6s ease}
.btn:hover::after{left:150%}

/* linen texture on the cream sections */
/* linen texture removed with the cream bands it was dressing */

/* ornament divider between major sections */
/* The divider sits BETWEEN two sections, so the space around it was the sum of the
   previous section's bottom padding, its last paragraph's trailing margin, the ornament's
   own padding and the next section's top padding: 55px above and 38px below. The ornament
   is its own separator, so the sections either side do not need their full padding too.
   Negative margin-top only pulls it up into the preceding section's existing padding (safe,
   nothing to overlap); the section AFTER is tightened with a sibling rule instead, so its
   background never rides up over the motif. */
.ornament{display:flex;align-items:center;justify-content:center;gap:14px;padding:0 20px;color:var(--gold)}
/* Tighten the sections either side rather than pulling the ornament with a negative
   margin, which made the following section's background ride up over the motif. */
section:has(+ .ornament){padding-bottom:22px}
.ornament + section{padding-top:22px}
/* Kevin, 13 Sep 2026: where he asked for the divider under a page title to go, the two sections'
   38px paddings were left stacked with nothing between them, 76px of empty space, while a page
   that kept its divider collapses the same join to the 22/22 above and reads much tighter. So the
   empty join now takes the identical rhythm. build.py adds .tight-join to the title block wherever
   the divider is suppressed. The noscript selector is for Daytime Activities, which parks its
   no-JS style shim in this join and would otherwise be the one page the rule missed. */
.page-title.tight-join{padding-bottom:22px}
.page-title.tight-join + section,
.page-title.tight-join + noscript + section{padding-top:22px}
/* Free Use and Our Rules run their opening sentence straight into the list below it ("...all of
   the following conditions are met:" and "So, Please:"), so those two close further, to about a
   single line space, and read as one block. Replaces a one-page free-use-conditions rule. */
/* JS-00707: these two did NOT match each other, 39px on Our Rules against 22px on Free Use, and
   the cause was inherited rather than ours. Our Rules opens its section with a bare <ul>, which
   keeps the browser's default ~1em top margin; .stack only sets >*+*, so it styles the gaps
   BETWEEN items and never resets the list itself. Free Use opens with a <div>, which has none.
   Resetting the first child is only half the fix: on its own it lands both at 22px, which is
   under one line of body copy (27.2px), so the padding goes back from 0 to 6px and both land on
   28px. The two halves have to move together or the pages simply drift apart the other way. */
.page-title.tight-join + .runs-on{padding-top:6px}
/* Follow the OPENING chain, not just the direct child. Our Rules opens with the list itself
   (.wrap > ul), but Free Use wraps its list in a two-column grid and a column div, so the list
   that actually opens the page sits three levels down and a direct-child reset misses it
   entirely: fixing only the top level left Our Rules at 28px and Free Use at 45px, which is the
   same defect with the pages swapped. Depth 3 covers both, and the selector says what is meant,
   that whatever OPENS a run-on section carries no inherited top margin. Both run-on sections hold
   exactly one list, so nothing further down the page is touched. */
.page-title.tight-join + .runs-on > .wrap > *:first-child,
.page-title.tight-join + .runs-on > .wrap > *:first-child > *:first-child,
.page-title.tight-join + .runs-on > .wrap > *:first-child > *:first-child > *:first-child{margin-top:0}
/* a section's own padding provides the breathing room; the last child's margin is doubling up */
section .wrap > *:last-child{margin-bottom:0}
.ornament::before,.ornament::after{content:"";height:1px;width:min(160px,22vw);background:linear-gradient(90deg,transparent,var(--gold))}
.ornament::after{background:linear-gradient(90deg,var(--gold),transparent)}
.ornament svg{width:40px;height:40px;flex:none}

/* cinematic hero extras: vignette, grain, foil title, tagline reveal, gold rule, scroll cue */
.hero.has-slides .hero-vignette{position:absolute;inset:0;z-index:0;pointer-events:none;box-shadow:inset 0 0 220px 60px rgba(9,16,23,.72)}
.hero.has-slides .hero-grain{position:absolute;inset:0;z-index:0;opacity:.06;pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
.hero-title{display:block;margin:0 0 6px;color:#fff;max-width:none}
.hero-title .tmain{display:block;font-size:clamp(3rem,8.5vw,6.4rem);line-height:1;font-weight:700;
  animation:hh-rise 1s .1s both,foil 9s linear infinite}
.hero-title .tsub{display:block;font-family:var(--display);font-weight:500;
  font-size:clamp(1.2rem,3vw,2.05rem);color:#e8dfc9;margin-top:22px;max-width:26ch}
.rw .w{display:inline-block;overflow:hidden;vertical-align:bottom}
.rw .w>span{display:inline-block;animation:hh-word .9s cubic-bezier(.2,.8,.2,1) both}
@keyframes hh-word{from{transform:translateY(115%)}to{transform:none}}
.scroll-cue{position:absolute;left:50%;bottom:22px;transform:translateX(-50%);z-index:2;color:var(--gold-lt);opacity:.85;animation:hh-bob 2s ease-in-out infinite}
.scroll-cue svg{width:26px;height:26px}
@keyframes hh-bob{50%{transform:translate(-50%,9px)}}

/* flanking count-up figures: bookending the Home trust strip and the About hero.
   Each number shows its final value and counts up on scroll (see app.js). */
/* The strip is wider than the standard 1120px content column so all six facilities fit
   in one row between the flanking figures. Capped (not truly edge-to-edge) so the icons
   do not drift apart on very wide monitors. */
.trust-wrap{display:flex;align-items:center;gap:28px;max-width:1460px}
.trust-wrap .trust-grid{flex:1}
.trust-stat{flex:none;text-align:center;min-width:76px}
.trust-stat .num{display:block;font-family:var(--display);font-weight:700;line-height:1;
  font-size:clamp(1.7rem,2.6vw,2.2rem);color:var(--gold-dark);
  background:linear-gradient(180deg,#8a6a34,#6b5028);-webkit-background-clip:text;background-clip:text}
.trust-stat .lab{display:block;margin-top:6px;font-size:.62rem;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
.page-hero .hero-flank{display:flex;align-items:center;justify-content:center;gap:44px}
.page-hero .hero-flank-mid{flex:0 1 auto}
.page-hero .hero-stat{flex:1;text-align:center}
.page-hero .hero-stat .num{display:block;font-family:var(--display);font-weight:700;line-height:1;
  font-size:clamp(2rem,4vw,3rem);color:#e0cfa8;
  background:linear-gradient(180deg,#e6d5ab,#a88443);-webkit-background-clip:text;background-clip:text}
.page-hero .hero-stat .lab{display:block;margin-top:8px;font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:#cdd9e3}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .trust-stat .num,.page-hero .hero-stat .num{-webkit-text-fill-color:transparent}
}
@media(max-width:900px){
  .trust-wrap{flex-wrap:wrap;justify-content:center;gap:6px 24px}
  .trust-wrap .trust-grid{flex-basis:100%;order:3}
  .trust-stat{order:1;flex:1;padding:14px 0 2px}
}
@media(max-width:720px){
  .page-hero .hero-flank{flex-wrap:wrap;gap:16px}
  .page-hero .hero-flank-mid{flex-basis:100%;order:1}
  .page-hero .hero-stat{flex:1;order:2}
}

/* JS-00502: five pages (Room Hire, Free Use, About Us, Our Rules, Contact) drop the coloured
   page-hero band. The H1 is NOT removed or hidden, it simply falls back to the normal site
   heading style on the page background. Only two things were styled specifically FOR the dark
   band and therefore need a light-background variant here: the intro paragraph's measure
   (.page-hero p had max-width:60ch, which stops the lead running the full column width), and
   the About page's flanking count-up figures, whose light-gold-on-dark gradient is illegible
   on the page background. The gradient below is the dark-gold pair already proven on
   .trust-stat, so this reuses an existing treatment rather than inventing one. */
/* The centring is for the TITLE only. Sean, 2026-09-03: it was catching the intro blurb
   underneath as well. The blurb reads as ordinary body copy: left-aligned and spanning the
   FULL content width. Do not put a max-width measure on it, that was tried and rejected. */
.page-title{text-align:center}
.page-title p{margin:0;text-align:left;font-size:1.08rem;color:var(--ink)}
/* Kevin, 9 Sep 2026: where the title block carries several separate statements, preserve
   their relationship but give each one a readable paragraph break. Scoped to the two pages
   he named rather than changing every title lead site-wide. */
.page-title .page-title-statements p + p{margin-top:.9rem}
.page-title .hero-flank{display:flex;align-items:center;justify-content:center;gap:44px}
.page-title .hero-flank-mid{flex:0 1 auto;text-align:center}
.page-title .hero-stat{flex:1;text-align:center}
.page-title .hero-stat .num{display:block;font-family:var(--display);font-weight:700;line-height:1;
  font-size:clamp(2rem,4vw,3rem);color:var(--gold-dark);
  background:linear-gradient(180deg,#8a6a34,#6b5028);-webkit-background-clip:text;background-clip:text}
.page-title .hero-stat .lab{display:block;margin-top:8px;font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .page-title .hero-stat .num{-webkit-text-fill-color:transparent}
}
@media(max-width:720px){
  .page-title .hero-flank{flex-wrap:wrap;gap:16px}
  .page-title .hero-flank-mid{flex-basis:100%;order:1}
  .page-title .hero-stat{flex:1;order:2}
}

/* subtle 3-D tilt on card-shaped blocks (JS adds the transform on mousemove) */
.act-tile{transition:transform .25s ease,box-shadow .4s;transform-style:preserve-3d;will-change:transform}
.triage .callout{transition:transform .25s ease,box-shadow .35s;transform-style:preserve-3d;will-change:transform}

/* gold corner frame on featured photos */
.ph.framed{position:relative}
.ph.framed::before,.ph.framed::after{content:"";position:absolute;top:10px;width:22px;height:22px;border:2px solid var(--gold);z-index:3;pointer-events:none}
.ph.framed::before{left:10px;border-right:0;border-bottom:0}
.ph.framed::after{right:10px;border-left:0;border-bottom:0}

/* ===== Hero cap (short viewports) =====
   High Windows display scaling and small laptops produce a very SHORT viewport as well as a
   narrow one: 1920x1080 at 250% scaling reports about 750x370. The hero is content-sized, so it
   used to fill that entire screen and visitors reasonably assumed the page ended there (this is
   exactly what the client reported). These rules scale the hero to the viewport HEIGHT so a slice
   of the next section is always visible, without hiding or clipping any content.
   The title uses min(vw, vh) so it shrinks on short screens while desktop stays unchanged:
   at 1440x900 the vh term is 108px, above the 6.4rem cap, so nothing changes there. */
.hero-title .tmain{font-size:clamp(2rem,min(8.5vw,12vh),6.4rem)}

/* JS-00497: threshold raised from 760px. At 761-820px of viewport height the tier had not
   engaged but the hero had not shrunk either, so it filled 86-89% of the screen and left only
   a ~30px sliver of the next section, which is the 2026-07-20 symptom in all but name. */
@media(max-height:820px){
  /* the hero is a <section>, so it carries the site-wide section padding (56px top and
     bottom) on TOP of .hero-inner's own padding. Trim the outer one too. */
  .hero{padding-top:16px;padding-bottom:16px}
  .hero-inner{padding:22px 20px 20px}
  .hero-tag{margin-bottom:14px;font-size:.78rem;padding:5px 13px}
  .hero-title .tsub{font-size:clamp(1.05rem,2.8vh,1.7rem);margin-top:10px}
  .hero p.lead{font-size:1.02rem;margin-bottom:.55rem}
  .hero .cta-row{margin-top:23px}
}
@media(max-height:620px){
  /* .hero-inner supplies all the breathing room at this height; the outer section
     padding is pure waste and costs 112px of a very short screen */
  .hero{padding-top:0;padding-bottom:0}
  /* the header is 77px by default, a big share of a short screen, so trim it too */
  .nav{padding:8px 20px}
  
  /* JS-00497: cut from 18px. NOTE these tier values are absolute overrides, they replace
     .hero-inner's base padding rather than adding to it, so cutting the base does NOT make
     them smaller and they have to be reduced here explicitly. */
  .hero-inner{padding:12px 20px 12px}
  /* the eyebrow now carries real copy ("Welcome to"), so shrink it rather than hide it */
  .hero-tag{margin-bottom:6px;font-size:.62rem;padding:3px 10px}
  .hero-title .tsub{font-size:1.05rem;margin-top:4px}
  .hero p.lead{font-size:.95rem;margin-bottom:.35rem}
  .hero .cta-row{margin-top:12px}
  .hero .cta-row .btn{padding:10px 16px;font-size:.94rem}
  /* purely decorative, and at this height it would collide with the buttons */
  .scroll-cue{display:none}
}
@media(max-height:470px){
  /* Very short, which is what high Windows scaling produces. Prioritise the title,
     tagline and the two calls to action so that a slice of the next section stays on
     screen and the page visibly continues. The lead sentence is not lost: the same
     wording appears immediately below in the page content. */
  .hero p.lead{display:none}
  .hero-title .tsub{font-size:1rem}
}

/* ---------------------------------------------------------------------------
   Kevin's site review, 8 September 2026.
   --------------------------------------------------------------------------- */

/* THE PAGE NAME, MADE LESS PROMINENT. "When you follow the drop-down menus through
   to a page, you are immediately confronted with the page name. To me, this looks a
   little superfluous. However, I take your point that Google likes these headings
   and that removing them could have an impact on SEO. Could we therefore change the
   font size and/or colour to make the page heading a little less prominent?"

   So the H1 is never removed, hidden, retagged or moved; only its size changes. It
   keeps the gold foil, the shimmer and the gold rule, because Kevin likes those and
   they are what makes it read as a Howard Hall heading rather than plain text.

   .quiet is applied by page() and is the DEFAULT. Three pages opt out and keep the
   full-size title: Frequently Asked Questions, Associated Organisations and the Privacy
   Notice. About joined the quiet set in Kevin's 9 September follow-up. Main Hall, Shirley Room and
   Temple pages are on .room-h1 and were never in scope.

   The clamp still scales with the viewport, so the heading stays responsive; it is
   the same shape as the default, about a third smaller at every width. */
.page-title.quiet h1{font-size:clamp(1.45rem,3.1vw,2rem)}
.page-title.quiet h1::after{width:52px;margin-top:12px}

/* Kevin, 9 Sep 2026: the Home SEO heading belongs to the facilities strip, inside its two
   ornaments, and uses the same restrained scale as the quiet page titles. */
/* Sean, 14 Sep 2026: "can we add some space between the Hero images and the Hire Howard Hall
   header, they feel too close together". They were 10px apart, and that was a knock-on from
   removing the ornament that used to sit here earlier the same day: the motif was 40px tall and
   was the only thing holding this heading off the hero, so taking the decoration away took its
   space with it and the heading slid up against a full-bleed photograph. Second instance of that
   trap in one day, the page-title joins being the first: ON THIS SITE, REMOVING A DIVIDER IS
   ALWAYS ALSO A SPACING DECISION, so check the gap whenever one comes out.
   38px is not an invented number, it is section{padding:38px 0}, so the heading now sits off the
   hero by the same distance every other section's content sits from its own boundary. */
.trust-heading-wrap{max-width:var(--wrap);margin:0 auto;padding:38px 20px 0;text-align:center}
/* matching the 28px that section padding drops to at this width */
@media(max-width:720px){.trust-heading-wrap{padding-top:28px}}
.trust-heading{font-size:clamp(1.45rem,3.1vw,2rem);margin:0}

/* The About page keeps "A Century..." as its H1 and restores "About Us" as a smaller
   subheading over the history. */
.quiet-subheading{font-size:clamp(1.25rem,2.5vw,1.65rem);margin-bottom:.7em}

/* GOLD BORDER ON THE HOME HERO'S SECOND BUTTON. "I like the gold border around the
   'Request a Booking' button... However, I think that over the image, and probably
   only over the image on the Home Page, the 'Check Availability' button also needs
   a gold border."

   Deliberately scoped to .hero, which only exists on the home page, so no other
   .btn-green anywhere on the site picks this up. The fill stays Heritage Blue, so
   this does not reopen the 3 September decision to make every button one colour;
   only the 1px border changes. */
.hero .cta-row .btn-green{border-color:var(--gold)}
.hero .cta-row .btn-green:hover{border-color:var(--gold-lt)}

/* THE FACILITIES STRIP now carries one statement per item instead of a heading plus
   a caption, so the statement is doing the whole job and needs room to breathe and
   to wrap onto a second line without crowding its neighbour. */
.trust-item .trust-h{margin:0;line-height:1.35}

/* Explicit column counts, replacing the auto-fit track sizing. With six longer
   statements auto-fit was landing on FIVE across with one orphan underneath at
   1440px, which reads as a mistake rather than a wrap. Fixed counts keep the strip
   balanced at every width: six across, then three and three, then two by three.
   The 900px rule above still hands the grid the full row width on the way down. */
.trust-grid{grid-template-columns:repeat(6,1fr);gap:20px}
@media(max-width:1180px){.trust-grid{grid-template-columns:repeat(3,1fr)}}
@media(max-width:560px){.trust-grid{grid-template-columns:repeat(2,1fr)}}
