/* ==========================================================================
   THE GROVE ESSIPONG BEACH RESORT — Design System
   Inspired by the restrained luxury language of fourseasons.com:
   editorial serif display type, generous negative space, full-bleed imagery,
   a single bronze accent, and quiet, confident interaction states.
   No frameworks, no build step — plain CSS custom properties + utilities.
   ========================================================================== */

:root{
  --ink:#12170f;
  --forest:#1f2a24;
  --forest-700:#2b3a31;
  --forest-500:#3f5346;
  --moss:#65735d;
  /* Bronze is used as a text colour on light surfaces (eyebrows, links, badges), not only as
     decoration, so it has to carry contrast there: #846a3b measures 4.58:1 on the sand
     background and 5.11:1 with white text on top of it. The lighter #b08d4f scored 2.78 and
     3.10 — a luxury palette that a guest cannot read is not a luxury palette. Light accents
     on dark panels are --bronze-soft and --bronze-light, which this does not touch. */
  --focus-ring:var(--bronze);
  --bronze:#846a3b;
  --bronze-soft:#c9a86a;
  --bronze-light:#e8dcc6;
  --sand:#f6f2ea;
  --ivory:#fbf9f5;
  --paper:#ffffff;
  --line:#e3ded2;
  --line-dark:rgba(255,255,255,.18);
  --muted:#6a6f68;
  --muted-dark:rgba(255,255,255,.72);
  --danger:#a4402f;
  --success:#3f6b4a;
  --warning:#9b6d27;

  --font-display:ui-serif,"Iowan Old Style","Palatino Linotype","Book Antiqua",Georgia,"Times New Roman",serif;
  --font-body:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;

  --step--1:clamp(.75rem,.72rem + .1vw,.82rem);
  --step-0:clamp(.94rem,.9rem + .18vw,1rem);
  --step-1:clamp(1.1rem,1rem + .5vw,1.35rem);
  --step-2:clamp(1.4rem,1.15rem + 1.1vw,2.05rem);
  --step-3:clamp(1.85rem,1.3rem + 2.2vw,3rem);
  --step-4:clamp(2.4rem,1.4rem + 4vw,4.6rem);

  --gutter:clamp(1.15rem,4vw,4.5rem);
  --section:clamp(3.5rem,7vw,7.5rem);
  --radius:2px;
  --shadow:0 24px 60px -30px rgba(18,23,15,.45);
  --shadow-soft:0 14px 40px -26px rgba(18,23,15,.4);
  --ease:cubic-bezier(.22,.61,.36,1);
  --max:1440px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;background:var(--ivory);color:var(--ink);
  font-family:var(--font-body);font-size:var(--step-0);line-height:1.65;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,svg,video{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit}
h1,h2,h3,h4{font-family:var(--font-display);font-weight:400;line-height:1.12;margin:0 0 .6em;letter-spacing:.005em}
h1{font-size:var(--step-4)}
h2{font-size:var(--step-3)}
h3{font-size:var(--step-2)}
h4{font-size:var(--step-1)}
p{margin:0 0 1.1em}
/* The focus ring is a token for the same reason the accent is: bronze reads on paper (5.0:1) and
   does not read on forest (2.9:1), so the dark surfaces restate it once, below, rather than every
   rule choosing for itself. Measured by `composer focus`, which scores every indicator against the
   surface it is drawn on. */
:focus-visible{outline:2px solid var(--focus-ring);outline-offset:3px}
::selection{background:var(--bronze-light);color:var(--ink)}

/* Every surface that paints itself forest. A focus ring is only an indicator if it can be seen
   against the thing it is drawn on — bronze on forest is 2.9:1, which is below the 3:1 floor. */
.section--forest,.topbar,.qr-head,.portal-side,.admin__side,.kpi--accent,.playwright,.footer{
  --focus-ring:var(--bronze-soft)
}

/* Controls sitting over a photograph get a two-tone ring: no single colour can be relied on over an
   image, and the light ring alone disappears on a bright sky. The tool cannot score these — it says
   so and counts them rather than guessing — so the rule is deliberate rather than measured. */
.hero :focus-visible,.page-hero :focus-visible{
  outline:2px solid #fff;box-shadow:0 0 0 4px rgba(10,16,13,.7)
}

/* ---------- Layout ---------- */
.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gutter)}
.narrow{max-width:820px;margin-inline:auto}
.wide{max-width:1680px}
.section{padding-block:var(--section)}
.section--tight{padding-block:clamp(2.25rem,4vw,4rem)}
.section--sand{background:var(--sand)}
.section--forest{background:var(--forest);color:var(--ivory)}
.section--paper{background:var(--paper)}
.center{text-align:center}
.stack>*+*{margin-top:1rem}
.grid{display:grid;gap:clamp(1.25rem,2.5vw,2.5rem)}
.grid--2{grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr))}
.grid--3{grid-template-columns:repeat(auto-fit,minmax(min(100%,290px),1fr))}
.grid--4{grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr))}
.split{display:grid;gap:clamp(1.5rem,4vw,4rem);grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr));align-items:center}
/* A form with a summary beside it — the booking flow's shape. This lives here rather than in an
   inline `style` on each page, which is where it was: an inline declaration cannot be overridden by
   a media query, so all seven booking pages kept a `minmax(0,1fr) 340px` grid at every width and
   their forms rendered 42 px wide on a phone. Below 900 px the two columns simply stack. */
.split--aside{align-items:start;grid-template-columns:minmax(0,1fr) var(--aside,340px);
  gap:clamp(1.5rem,3vw,2.5rem)}
@media(max-width:900px){.split--aside{grid-template-columns:minmax(0,1fr)}}
.flex{display:flex;gap:1rem;flex-wrap:wrap;align-items:center}
.between{display:flex;gap:1rem;flex-wrap:wrap;align-items:center;justify-content:space-between}
.divider{height:1px;background:var(--line);border:0;margin:0}

/* ---------- Eyebrow / headings ---------- */
.eyebrow{
  font-size:var(--step--1);letter-spacing:.32em;text-transform:uppercase;
  color:var(--bronze);font-weight:600;margin:0 0 1rem;display:block;
  line-height:1.7;text-wrap:balance;
}
.eyebrow--ink{color:var(--moss)}
.eyebrow--light{color:var(--bronze-soft)}
/* Over photography, the eyebrow goes light and calm. The bronze accent keeps its role on
   paper and on the dark forest panels, where it has contrast to spare. */
.hero .eyebrow,.page-hero .eyebrow{color:rgba(255,255,255,.92);text-shadow:0 1px 18px rgba(0,0,0,.35)}
.lede{font-size:var(--step-1);color:var(--muted);max-width:62ch;line-height:1.6}
.section--forest .lede{color:var(--muted-dark)}
.rule{width:56px;height:1px;background:var(--bronze);margin:1.5rem 0}
.rule--center{margin-inline:auto}
.muted{color:var(--muted)}
.tiny{font-size:var(--step--1)}
.serif{font-family:var(--font-display)}

/* ---------- Buttons ---------- */
.btn{
  --btn-bg:var(--forest);--btn-fg:var(--ivory);--btn-bd:var(--forest);
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  padding:.95rem 2rem;background:var(--btn-bg);color:var(--btn-fg);
  border:1px solid var(--btn-bd);border-radius:var(--radius);
  font-size:var(--step--1);letter-spacing:.16em;text-transform:uppercase;font-weight:600;
  cursor:pointer;transition:all .35s var(--ease);
}
.btn:hover{--btn-bg:var(--bronze);--btn-bd:var(--bronze);--btn-fg:#fff;transform:translateY(-1px)}
.btn--gold{--btn-bg:var(--bronze);--btn-bd:var(--bronze);--btn-fg:#fff}
.btn--gold:hover{--btn-bg:var(--forest);--btn-bd:var(--forest)}
.btn--ghost{--btn-bg:transparent;--btn-fg:var(--forest);--btn-bd:var(--forest)}
.btn--ghost:hover{--btn-bg:var(--forest);--btn-fg:var(--ivory)}
.btn--onDark{--btn-bg:transparent;--btn-fg:#fff;--btn-bd:rgba(255,255,255,.55)}
.btn--onDark:hover{--btn-bg:#fff;--btn-fg:var(--ink);--btn-bd:#fff}
.btn--solidLight{--btn-bg:var(--ivory);--btn-fg:var(--ink);--btn-bd:var(--ivory)}
.btn--solidLight:hover{--btn-bg:var(--bronze);--btn-fg:#fff;--btn-bd:var(--bronze)}
.btn--sm{padding:.6rem 1.15rem;font-size:.7rem}
.btn--block{width:100%}
.btn[disabled],.btn.is-disabled{opacity:.45;pointer-events:none}
.link-more{
  display:inline-flex;align-items:center;gap:.5rem;font-size:var(--step--1);
  letter-spacing:.18em;text-transform:uppercase;font-weight:600;color:var(--forest);
  border-bottom:1px solid var(--bronze);padding-bottom:.35rem;transition:gap .3s var(--ease),color .3s;
}
.link-more:hover{gap:.9rem;color:var(--bronze)}

/* ---------- Header ---------- */
.topbar{
  background:var(--forest);color:var(--muted-dark);font-size:var(--step--1);
  letter-spacing:.06em;
}
.topbar a:hover{color:#fff}
.topbar__inner{display:flex;justify-content:space-between;gap:1rem;align-items:center;min-height:42px;flex-wrap:wrap}
.header{position:sticky;top:0;z-index:60;background:rgba(251,249,245,.94);backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}
.header__inner{display:flex;align-items:center;justify-content:space-between;gap:1.5rem;min-height:var(--header-h,92px)}
.brand{display:flex;align-items:center;gap:.85rem}
.brand__mark{width:46px;height:46px;flex:0 0 auto}
.brand__name{font-family:var(--font-display);font-size:clamp(1.05rem,1.6vw,1.4rem);line-height:1.05;letter-spacing:.02em}
.brand__sub{font-size:.6rem;letter-spacing:.34em;text-transform:uppercase;color:var(--bronze);display:block;font-weight:600}
.nav{display:flex;align-items:center;gap:clamp(1rem,1.9vw,2.1rem)}
.nav__link{
  font-size:var(--step--1);letter-spacing:.15em;text-transform:uppercase;font-weight:600;
  color:var(--forest);padding:.5rem 0;position:relative;white-space:nowrap;
}
.nav__link::after{content:"";position:absolute;left:0;bottom:0;width:0;height:1px;background:var(--bronze);transition:width .35s var(--ease)}
.nav__link:hover::after,.nav__link[aria-current="page"]::after{width:100%}
.nav__link--cta{color:var(--bronze)}
.nav-toggle{display:none;background:none;border:1px solid var(--line);width:46px;height:46px;
  /* `flex:0 0 auto` because a menu button squeezed to 40 px by a tight header is a smaller target
     precisely on the narrowest screen, which is where it matters most. It measured 40×46 at 320 px. */
  flex:0 0 auto;align-items:center;justify-content:center;border-radius:var(--radius)}
.nav-toggle span{display:block;width:20px;height:1px;background:var(--forest);position:relative}
.nav-toggle span::before,.nav-toggle span::after{content:"";position:absolute;left:0;width:20px;height:1px;background:var(--forest)}
.nav-toggle span::before{top:-6px}.nav-toggle span::after{top:6px}
@media(max-width:1100px){
  .nav-toggle{display:inline-flex}
  /* Only the primary menu becomes a drawer. `.nav` is also used by the booking flow's header —
     two links and no toggle — and unscoped drawer styles made those links `visibility:hidden` at
     phone width with nothing to open them: a phone number and a portal link, deleted by a rule
     meant for a different menu. */
  .nav--drawer{
    position:fixed;inset:0 0 0 auto;width:min(88vw,400px);background:var(--ivory);
    flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:0;
    padding:6.5rem 2rem 2rem;transform:translateX(100%);box-shadow:var(--shadow);overflow-y:auto;
    /* `visibility` is part of the transition on purpose. Sliding the panel off the right-hand edge
       hides it from the eye and from nothing else: its eight links stayed in the tab order and in
       the accessibility tree, so a keyboard user tabbed into a menu the button said was closed, and
       a screen reader read it out after the page. Visibility is discrete, so it flips to `visible`
       the moment the drawer starts opening and to `hidden` only once it has finished closing. */
    visibility:hidden;transition:transform .45s var(--ease),visibility .45s var(--ease);
  }
  .nav--drawer.is-open{transform:none;visibility:visible}
  .nav--drawer .nav__link{width:100%;padding:1rem 0;border-bottom:1px solid var(--line);font-size:.85rem}

  /* The booking header keeps its two links and puts them on their own line. It has no toggle, so
     hiding them is not an option, and the phone number is the one thing a guest mid-checkout may
     actually need. */
  .header--booking .header__inner{flex-wrap:wrap;padding-block:.7rem}
  .header--booking .nav{width:100%;justify-content:space-between;gap:1rem;padding-top:.7rem;border-top:1px solid var(--line)}
  /* The base link is sized for a wide header with a pointer; on its own line, under a thumb, it
     needs the same 44 px floor every other control on the site is held to. The sweep caught these
     two at 36 px the moment the links came back into view. */
  .header--booking .nav__link{padding-block:.75rem}
}

/* ---------- Hero ---------- */
.hero{position:relative;min-height:clamp(560px,86vh,900px);display:flex;align-items:flex-end;color:#fff;overflow:hidden}
.hero__media{position:absolute;inset:0}
.hero__media img{width:100%;height:100%;object-fit:cover;transform:scale(1.02)}
.hero__media::after{
  content:"";position:absolute;inset:0;
  /* The ramp is deliberately strong through the lower two-thirds: that is where the words
     are, and the photographs' brightest sky is exactly where a weak scrim loses the text.
     At these stops, white clears 4.5:1 from 55% height down (measured on the brightest
     pixel of the current hero — see docs/verification). */
  background:linear-gradient(180deg,rgba(18,23,15,.52) 0%,rgba(18,23,15,.12) 28%,rgba(18,23,15,.60) 60%,rgba(18,23,15,.88) 100%);
}
.hero__inner{position:relative;z-index:2;width:100%;padding-block:clamp(2.5rem,6vw,5rem)}
.hero h1{max-width:22ch;text-shadow:0 2px 30px rgba(0,0,0,.35)}
.hero .lede{color:rgba(255,255,255,.9);max-width:52ch}
.hero--compact{min-height:clamp(360px,52vh,560px)}
.hero__scroll{display:inline-flex;flex-direction:column;align-items:center;gap:.5rem;font-size:.62rem;letter-spacing:.3em;text-transform:uppercase;color:rgba(255,255,255,.75);margin-top:2rem}
.hero__scroll i{width:1px;height:44px;background:linear-gradient(180deg,rgba(255,255,255,.7),transparent);display:block;animation:slide 2.4s infinite}
@keyframes slide{0%{opacity:0;transform:translateY(-10px)}50%{opacity:1}100%{opacity:0;transform:translateY(10px)}}
.page-hero{position:relative;min-height:clamp(340px,46vh,520px);display:flex;align-items:flex-end;color:#fff;overflow:hidden}
.page-hero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.page-hero::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(18,23,15,.38) 0%,rgba(18,23,15,.55) 55%,rgba(18,23,15,.86) 100%)}
.page-hero__inner{position:relative;z-index:2;padding-block:clamp(2.5rem,5vw,4rem);width:100%}
.breadcrumb{font-size:.68rem;letter-spacing:.24em;text-transform:uppercase;color:rgba(255,255,255,.75);margin-bottom:1rem;display:flex;gap:.75rem;flex-wrap:wrap}
.breadcrumb a:hover{color:#fff}

/* ---------- Booking bar ---------- */
.bookbar{position:relative;z-index:30;margin-top:-3.25rem}
.bookbar__panel{background:var(--paper);box-shadow:var(--shadow);border:1px solid var(--line);padding:clamp(1.25rem,2vw,1.75rem)}
.bookbar__grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,155px),1fr)) auto;align-items:end}
.field{display:flex;flex-direction:column;gap:.45rem;min-width:0}
.field label,.label{font-size:.66rem;letter-spacing:.22em;text-transform:uppercase;font-weight:700;color:var(--moss)}
.input,input[type=text],input[type=email],input[type=tel],input[type=password],input[type=date],input[type=time],input[type=number],input[type=search],select,textarea{
  width:100%;padding:.8rem .9rem;border:1px solid var(--line);background:var(--paper);color:var(--ink);
  border-radius:var(--radius);font:inherit;font-size:.92rem;transition:border-color .25s,box-shadow .25s;
}
.input:focus,select:focus,textarea:focus{border-color:var(--bronze);box-shadow:0 0 0 3px rgba(132,106,59,.3)}
/* `outline:none` used to sit on the rule above. Removing it matters more than it looks: it took the
   global focus ring off every field on the site, leaving a 3 px ring at 16% opacity as the only
   sign of where the keyboard was — which is a change of 1.2:1 against the page, and unreadable. */
select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--moss) 50%),linear-gradient(135deg,var(--moss) 50%,transparent 50%);background-position:calc(100% - 18px) 52%,calc(100% - 13px) 52%;background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:2.4rem}
textarea{min-height:132px;resize:vertical}
.checkline{display:flex;gap:.7rem;align-items:flex-start;font-size:.86rem;color:var(--muted)}
.checkline input{width:auto;margin-top:.2rem}
.field__hint{font-size:.72rem;color:var(--muted)}
.field__error{font-size:.75rem;color:var(--danger);font-weight:600}

/* ---------- Cards ---------- */
.card{background:var(--paper);border:1px solid var(--line);overflow:hidden;transition:transform .4s var(--ease),box-shadow .4s var(--ease);display:flex;flex-direction:column}
.card:hover{transform:translateY(-4px);box-shadow:var(--shadow-soft)}
.card__media{position:relative;overflow:hidden;aspect-ratio:4/3;background:var(--sand)}
.card__media img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--ease)}
.card:hover .card__media img{transform:scale(1.06)}
.card__body{padding:clamp(1.1rem,1.8vw,1.6rem);display:flex;flex-direction:column;gap:.6rem;flex:1}
.card__title{font-size:var(--step-1);margin:0}
.card__price{font-family:var(--font-display);font-size:1.15rem;color:var(--forest)}
.card__meta{display:flex;gap:1rem;flex-wrap:wrap;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--moss)}
.card__foot{margin-top:auto;padding-top:1rem;display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap}
.badge{
  display:inline-block;padding:.34rem .7rem;background:var(--bronze);color:#fff;
  font-size:.6rem;letter-spacing:.2em;text-transform:uppercase;font-weight:700;border-radius:var(--radius);
}
.badge--forest{background:var(--forest)}
.badge--light{background:var(--bronze-light);color:var(--forest)}
.badge--danger{background:var(--danger)}
.badge--success{background:var(--success)}
.badge--info{background:var(--forest-500)}
.badge--neutral{background:#e7e4dc;color:var(--ink)}
.badge--warning{background:var(--warning)}
.badge--onMedia{position:absolute;top:1rem;left:1rem;z-index:3}
.tags{display:flex;gap:.4rem;flex-wrap:wrap}
.tag{font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;color:var(--moss);border:1px solid var(--line);padding:.3rem .6rem;border-radius:var(--radius)}

/* ---------- Feature / editorial blocks ---------- */
.feature{display:grid;gap:clamp(1.5rem,4vw,3.5rem);grid-template-columns:repeat(auto-fit,minmax(min(100%,380px),1fr));align-items:center}
.feature--reverse>*:first-child{order:2}
@media(max-width:820px){.feature--reverse>*:first-child{order:0}}
.feature__media{position:relative;overflow:hidden}
.feature__media img{width:100%;aspect-ratio:5/4;object-fit:cover}
.feature__media--tall img{aspect-ratio:4/5}
.plate{
  position:absolute;right:clamp(-1rem,-2vw,-2rem);bottom:clamp(-1rem,-2vw,-2rem);
  background:var(--ivory);border:1px solid var(--line);padding:1.35rem 1.5rem;max-width:260px;box-shadow:var(--shadow-soft)
}
.plate strong{display:block;font-family:var(--font-display);font-size:1.5rem;color:var(--forest)}
.quote{font-family:var(--font-display);font-size:var(--step-2);line-height:1.4;font-style:italic}
.quote__mark{font-family:var(--font-display);font-size:4rem;color:var(--bronze-light);line-height:.6;display:block}
.stars{color:var(--bronze);letter-spacing:.28em;font-size:.9rem}

/* ---------- Stats ---------- */
.stat{border-top:1px solid var(--line);padding-top:1.1rem}
.section--forest .stat{border-color:var(--line-dark)}
.stat__value{font-family:var(--font-display);font-size:clamp(1.8rem,3vw,2.6rem);line-height:1;color:var(--forest)}
.section--forest .stat__value{color:#fff}
.stat__label{font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin-top:.5rem;display:block}
.section--forest .stat__label{color:var(--muted-dark)}

/* ---------- Gallery ---------- */
.gallery{display:grid;gap:.6rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr))}
.gallery__item{position:relative;overflow:hidden;aspect-ratio:3/4;background:var(--sand)}
.gallery__item:nth-child(4n+1){grid-row:span 1}
.gallery__item img{width:100%;height:100%;object-fit:cover;transition:transform 1.2s var(--ease)}
.gallery__item:hover img{transform:scale(1.07)}
.gallery__cap{position:absolute;inset:auto 0 0 0;padding:1.1rem;color:#fff;background:linear-gradient(0deg,rgba(18,23,15,.82),transparent);font-size:.78rem;opacity:0;transform:translateY(8px);transition:.4s var(--ease)}
.gallery__item:hover .gallery__cap{opacity:1;transform:none}
.filters{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:2rem}
.filters button{background:none;border:1px solid var(--line);padding:.6rem 1.1rem;font-size:.68rem;letter-spacing:.18em;text-transform:uppercase;cursor:pointer;transition:.3s;font-weight:600}
.filters button:hover{border-color:var(--bronze);color:var(--bronze)}
.filters button.is-active{background:var(--forest);border-color:var(--forest);color:#fff}

/* ---------- Accordion ---------- */
.acc{border-top:1px solid var(--line)}
.acc__item{border-bottom:1px solid var(--line)}
.acc__trigger{width:100%;background:none;border:0;text-align:left;padding:1.35rem 2.5rem 1.35rem 0;cursor:pointer;font-family:var(--font-display);font-size:var(--step-1);position:relative;color:var(--forest)}
.acc__trigger::after{content:"+";position:absolute;right:0;top:50%;transform:translateY(-50%);color:var(--bronze);font-size:1.4rem;transition:transform .3s}
.acc__item.is-open .acc__trigger::after{content:"–"}
.acc__panel{max-height:0;overflow:hidden;transition:max-height .4s var(--ease)}
.acc__panel-inner{padding:0 0 1.5rem;color:var(--muted);max-width:80ch}

/* ---------- Tables ---------- */
.table-wrap{overflow-x:auto;border:1px solid var(--line);background:var(--paper)}
table.data{width:100%;border-collapse:collapse;font-size:.88rem}
table.data th{
  text-align:left;font-size:.64rem;letter-spacing:.18em;text-transform:uppercase;color:var(--moss);
  padding:.85rem 1rem;border-bottom:1px solid var(--line);background:var(--sand);white-space:nowrap;font-weight:700
}
table.data td{padding:.85rem 1rem;border-bottom:1px solid var(--line);vertical-align:middle}
table.data tr:last-child td{border-bottom:0}
table.data tr:hover td{background:rgba(246,242,234,.6)}
table.data td.num,table.data th.num{text-align:right;font-variant-numeric:tabular-nums}
.rowlink{cursor:pointer}
.pagination{padding:1rem;display:flex;gap:.5rem}

/* ---------- Booking summary / folio ---------- */
.summary{background:var(--paper);border:1px solid var(--line);padding:clamp(1.25rem,2vw,1.9rem)}
.summary__line{display:flex;justify-content:space-between;gap:1rem;padding:.5rem 0;font-size:.92rem}
.summary__line--muted{color:var(--muted);font-size:.85rem}
.summary__total{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;border-top:1px solid var(--line);margin-top:.75rem;padding-top:1rem;font-family:var(--font-display);font-size:var(--step-1)}
.summary__total strong{font-size:var(--step-2);color:var(--forest)}
.night-row{display:flex;justify-content:space-between;font-size:.85rem;padding:.4rem 0;border-bottom:1px dashed var(--line)}
.night-row:last-child{border-bottom:0}

/* ---------- Steps indicator ---------- */
.steps{display:flex;gap:0;flex-wrap:wrap;counter-reset:s;margin-bottom:2.5rem}
.steps li{list-style:none;display:flex;align-items:center;gap:.7rem;padding:0 1.4rem 0 0;font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-weight:600}
.steps li::before{counter-increment:s;content:counter(s);width:28px;height:28px;border:1px solid var(--line);display:grid;place-items:center;border-radius:50%;font-size:.7rem}
.steps li.is-done::before{background:var(--forest);border-color:var(--forest);color:#fff}
.steps li.is-current{color:var(--forest)}
.steps li.is-current::before{border-color:var(--bronze);color:var(--bronze)}

/* ---------- Alerts ---------- */
.alert{padding:1rem 1.15rem;border-left:3px solid var(--forest);background:var(--sand);margin-bottom:1.25rem;font-size:.9rem}
.alert--success{border-color:var(--success);background:rgba(63,107,74,.08)}
.alert--error{border-color:var(--danger);background:rgba(164,64,47,.07)}
.alert--warning{border-color:var(--warning);background:rgba(169,119,42,.09)}
.alert strong{display:block;margin-bottom:.2rem}

/* ---------- QR ordering ---------- */
.qr-shell{max-width:720px;margin-inline:auto}
.qr-head{background:var(--forest);color:#fff;padding:1.5rem;text-align:center}
.qr-head__table{font-family:var(--font-display);font-size:var(--step-2);margin:0;line-height:1.15}
.menu-cat{margin-bottom:2.5rem}
.menu-cat__title{display:flex;align-items:center;gap:1rem;font-family:var(--font-display);font-size:var(--step-2);margin-bottom:1.25rem}
.menu-cat__title::after{content:"";flex:1;height:1px;background:var(--line)}
.dish{display:grid;grid-template-columns:1fr auto;gap:1rem;padding:1.1rem;border:1px solid var(--line);background:var(--paper);margin-bottom:.7rem;align-items:start}
.dish__name{font-family:var(--font-display);font-size:1.08rem;margin:0 0 .3rem}
.dish__desc{font-size:.85rem;color:var(--muted);margin:0 0 .5rem;max-width:56ch}
.dish__price{font-variant-numeric:tabular-nums;font-weight:600;color:var(--forest)}
.dish.is-unavailable{opacity:.5}
.qty{display:inline-flex;align-items:center;border:1px solid var(--line)}
.qty button{width:36px;height:36px;background:none;border:0;cursor:pointer;font-size:1.1rem;color:var(--forest)}
.qty button:hover{background:var(--sand)}
.qty input{width:46px;text-align:center;border:0;padding:.4rem 0}
.qr-cart{position:sticky;bottom:0;background:var(--paper);border-top:2px solid var(--forest);padding:1rem;box-shadow:0 -18px 40px -30px rgba(0,0,0,.5)}
.status-track{display:flex;gap:.4rem;margin:1.5rem 0}
.status-track__step{flex:1;text-align:center;font-size:.6rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);padding-top:.9rem;border-top:3px solid var(--line)}
.status-track__step.is-done{border-color:var(--bronze);color:var(--forest);font-weight:700}
.pulse{display:inline-block;width:8px;height:8px;background:var(--bronze);border-radius:50%;animation:pulse 1.6s infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}

/* ---------- Booking engine extras ---------- */
.rate-row{display:grid;grid-template-columns:1fr auto;gap:1rem;align-items:center;padding:1.1rem;border:1px solid var(--line);background:var(--paper);margin-bottom:.7rem;cursor:pointer;transition:.3s}
.rate-row:hover{border-color:var(--bronze);box-shadow:var(--shadow-soft)}
.rate-row.is-selected{border-color:var(--bronze);background:rgba(132,106,59,.07)}
.slot-grid{display:grid;gap:.5rem;grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}
.slot{border:1px solid var(--line);padding:.75rem;text-align:center;cursor:pointer;background:var(--paper);font-size:.85rem;transition:.25s}
.slot:hover{border-color:var(--bronze)}
.slot.is-selected{background:var(--forest);color:#fff;border-color:var(--forest)}
.slot.is-full{opacity:.4;cursor:not-allowed;text-decoration:line-through}
.slot small{display:block;font-size:.66rem;color:var(--moss);letter-spacing:.08em}
.slot.is-selected small{color:rgba(255,255,255,.75)}
.countdown{font-variant-numeric:tabular-nums;font-weight:700;color:var(--danger)}
.money{font-variant-numeric:tabular-nums}

/* ---------- Portal ---------- */
.portal-shell{display:grid;grid-template-columns:260px 1fr;gap:0;min-height:70vh}
.portal-side{background:var(--forest);color:var(--ivory);padding:2.5rem 1.5rem}
.portal-side a{display:block;padding:.75rem 0;font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-dark);border-bottom:1px solid var(--line-dark)}
.portal-side a:hover,.portal-side a[aria-current="page"]{color:#fff}
.portal-side a[aria-current="page"]{border-bottom-color:var(--bronze)}
.portal-main{padding:clamp(1.5rem,4vw,3.5rem)}
@media(max-width:900px){.portal-shell{grid-template-columns:1fr}.portal-side{padding:1.5rem}}
.tier-card{background:linear-gradient(135deg,var(--forest),var(--forest-700));color:#fff;padding:1.75rem;position:relative;overflow:hidden}
.tier-card::after{content:"";position:absolute;right:-40px;top:-40px;width:180px;height:180px;border:1px solid rgba(255,255,255,.16);border-radius:50%}
.progress{height:6px;background:rgba(255,255,255,.2);margin-top:1rem;position:relative}
.progress span{position:absolute;inset:0 auto 0 0;background:var(--bronze-soft)}

/* ---------- Admin console ---------- */
.admin{display:grid;grid-template-columns:264px 1fr;min-height:100vh;background:#f4f5f2}
.admin__side{background:var(--forest);color:var(--ivory);padding:1.5rem 0;position:sticky;top:0;height:100vh;overflow-y:auto}
.admin__brand{padding:0 1.5rem 1.5rem;border-bottom:1px solid var(--line-dark);margin-bottom:1rem}
.admin__group{padding:1.15rem 1.5rem .4rem;font-size:.6rem;letter-spacing:.24em;text-transform:uppercase;color:rgba(255,255,255,.62);font-weight:700}
.admin__link{display:flex;align-items:center;gap:.7rem;padding:.62rem 1.5rem;font-size:.83rem;color:var(--muted-dark);border-left:2px solid transparent}
.admin__link:hover{background:rgba(255,255,255,.05);color:#fff}
.admin__link.is-active{background:rgba(255,255,255,.07);color:#fff;border-left-color:var(--bronze)}
.admin__link .count{margin-left:auto;background:var(--bronze);color:#fff;font-size:.62rem;padding:.1rem .4rem;border-radius:10px;font-weight:700}
.admin__main{min-width:0}
.admin__top{background:var(--paper);border-bottom:1px solid var(--line);padding:1rem clamp(1rem,3vw,2.25rem);display:flex;align-items:center;gap:1rem;justify-content:space-between;position:sticky;top:0;z-index:40;flex-wrap:wrap}
.admin__body{padding:clamp(1rem,3vw,2.25rem)}
/* The console search reads as one control. As a wrapping flex row the input grew until the
   button dropped onto a second line, which made the whole header look broken. */
.admin__search{display:flex;flex-wrap:nowrap;gap:.5rem;align-items:center;flex:1 1 320px;max-width:560px}
.admin__search input{flex:1 1 auto;min-width:0}
.admin__search .btn{flex:0 0 auto;white-space:nowrap}
.kpi{background:var(--paper);border:1px solid var(--line);padding:1.25rem;position:relative;overflow:hidden}
.kpi__label{font-size:.62rem;letter-spacing:.2em;text-transform:uppercase;color:var(--moss);font-weight:700}
.kpi__value{font-family:var(--font-display);font-size:clamp(1.6rem,2.6vw,2.2rem);line-height:1;margin-top:.6rem;color:var(--forest)}
.kpi__foot{font-size:.74rem;color:var(--muted);margin-top:.6rem}
.kpi--accent{background:var(--forest);color:#fff;border-color:var(--forest)}
.kpi--accent .kpi__label,.kpi--accent .kpi__foot{color:var(--muted-dark)}
.kpi--accent .kpi__value{color:#fff}
.panel{background:var(--paper);border:1px solid var(--line);margin-bottom:1.5rem}
.panel__head{padding:1rem 1.25rem;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.panel__head h2,.panel__head h3{margin:0;font-size:1.15rem}
.panel__body{padding:1.25rem}
.spark{display:flex;align-items:flex-end;gap:3px;height:64px}
.spark span{flex:1;background:linear-gradient(180deg,var(--bronze-soft),var(--bronze));min-height:3px;border-radius:1px 1px 0 0}
.board{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr))}
.ticket{background:var(--paper);border:1px solid var(--line);border-left:4px solid var(--bronze);padding:1rem}
.ticket--new{border-left-color:var(--warning)}
.ticket--ready{border-left-color:var(--success)}
.ticket__head{display:flex;justify-content:space-between;gap:.5rem;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--moss)}
.ticket__items{list-style:none;padding:0;margin:.75rem 0;font-size:.9rem}
.ticket__items li{padding:.25rem 0;border-bottom:1px dashed var(--line)}
.ticket__foot{display:flex;gap:.4rem;flex-wrap:wrap}
.btn-row{display:flex;gap:.4rem;flex-wrap:wrap}
.btn-row form{display:inline}
.chip{display:inline-flex;align-items:center;gap:.4rem;background:var(--sand);border:1px solid var(--line);padding:.3rem .65rem;font-size:.72rem;border-radius:20px}
.dl{display:grid;grid-template-columns:auto 1fr;gap:.4rem 1.25rem;font-size:.88rem}
.dl dt{color:var(--moss);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;padding-top:.2rem}
.dl dd{margin:0;font-weight:600}
.tabs{display:flex;gap:0;border-bottom:1px solid var(--line);margin-bottom:1.5rem;overflow-x:auto}
.tabs button{background:none;border:0;border-bottom:2px solid transparent;padding:.9rem 1.25rem;font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;cursor:pointer;color:var(--muted);white-space:nowrap;font-weight:600}
.tabs button.is-active{color:var(--forest);border-bottom-color:var(--bronze)}
.tab-panel{display:none}.tab-panel.is-active{display:block}
.empty{padding:3rem 1.5rem;text-align:center;color:var(--muted)}
.empty strong{display:block;font-family:var(--font-display);font-size:var(--step-1);color:var(--forest);margin-bottom:.4rem}
.playwright{background:var(--forest);color:#fff;padding:1rem 1.25rem;display:flex;gap:1rem;align-items:center;flex-wrap:wrap;font-size:.8rem}

/* ---------- Footer ---------- */
.footer{background:var(--forest);color:var(--muted-dark);padding-block:clamp(3rem,6vw,5rem) 2rem;font-size:.88rem}
.footer h3,.footer h4{color:#fff;font-size:1rem;margin-bottom:1rem}
.footer a{color:var(--muted-dark)}
.footer a:hover{color:#fff}
.footer__grid{display:grid;gap:2.5rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));margin-bottom:3rem}
.footer__bottom{border-top:1px solid var(--line-dark);padding-top:1.75rem;display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;font-size:.78rem}
.newsletter{display:flex;gap:.5rem}
.newsletter input{background:rgba(255,255,255,.06);border-color:var(--line-dark);color:#fff}
.newsletter input::placeholder{color:rgba(255,255,255,.5)}
.socials{display:flex;gap:.6rem}
.socials a{width:38px;height:38px;border:1px solid var(--line-dark);display:grid;place-items:center;border-radius:50%;transition:.3s}
.socials a:hover{background:var(--bronze);border-color:var(--bronze);color:#fff}

/* ---------- Touch targets ----------
   Standalone links (utility bar, card titles) rendered about 20px tall, under the 24×24 CSS px
   minimum that WCAG 2.5.8 asks for. Padding on an inline element does not extend its hit area,
   so these become inline-block and gain a little vertical padding; the spacing around them
   already absorbs it, so nothing moves on screen. */
.topbar a,.card__title a{display:inline-block;padding-block:.3rem}
/* Breadcrumb and detail-list links are standalone links too, not words inside a sentence. */
.breadcrumb a,.dl a{display:inline-block;padding-block:.25rem}

/* ---------- The accent, on dark surfaces ----------
   Gold has to be one value for text on paper and another for text on forest: the deep gold
   that reads on cream scores 2.9:1 on the dark panels, and the light gold that reads on
   forest scores 3.0:1 on cream. Rather than scatter the choice through every rule, the dark
   containers restate it once — and a new dark section inherits the right tone by being one. */
.footer .brand__sub,.footer .stars,.section--forest .brand__sub,.section--forest .stars,
.hero--compact .brand__sub{color:var(--bronze-soft)}
.footer .eyebrow,.section--forest .eyebrow,.admin__brand .brand__sub{color:var(--bronze-soft)}

/* ---------- Utilities ---------- */
.mt-0{margin-top:0}.mt-1{margin-top:.5rem}.mt-2{margin-top:1rem}.mt-3{margin-top:1.75rem}.mt-4{margin-top:2.5rem}
.mb-0{margin-bottom:0}.mb-1{margin-bottom:.5rem}.mb-2{margin-bottom:1rem}.mb-3{margin-bottom:1.75rem}
.hide{display:none!important}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.sr-only:focus-visible{position:fixed;top:.6rem;left:.6rem;z-index:1000;width:auto;height:auto;margin:0;clip:auto;clip-path:none;white-space:normal;overflow:visible;background:var(--paper);color:var(--forest);border:1px solid var(--line);border-radius:999px;padding:.6rem 1.1rem;font-size:.8rem;letter-spacing:.06em;text-transform:uppercase;text-decoration:none;box-shadow:0 10px 30px rgba(0,0,0,.14)}
.nowrap{white-space:nowrap}
/* Scroll reveals are an enhancement, never a requirement: the `.js` class is set by an
   inline script in the layout head, so if JavaScript never runs the content simply shows.
   Never hide .fade-up unconditionally — that turns a failed script into a blank page. */
.js .fade-up{opacity:0;transform:translateY(18px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.js .fade-up.is-visible{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important}.js .fade-up{opacity:1;transform:none}}

/* ---------- Print (QR sheets & folios) ---------- */
@media print{
  .header,.footer,.topbar,.no-print,.admin__side{display:none!important}
  body{background:#fff}
  .qr-card{break-inside:avoid;border:1px solid #ccc;padding:1rem;text-align:center}
  .print-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:1rem}
  .admin{display:block}
}
/* ---------- Touch targets ----------
   Measured with `composer taps` at 390 px: every interactive control, on every page. The console
   was the worst of it — 27 to 36 of its roughly 40 controls were under 44 px tall, and its sidebar
   stacked thirty 30 px rows above the content on a phone, which is both a small target and a
   screen and a half of scrolling before a member of staff reaches the page they asked for.

   44 px is the iOS and Material touch guidance; 24 px is the WCAG 2.5.8 (AA) floor this site is
   audited against. Nothing here was below the floor — this is about a control being comfortable
   rather than merely legal. The desktop layout is untouched: everything below lives inside a
   small-screen media query, because a mouse does not have this problem. */
@media(max-width:900px){
  .admin{grid-template-columns:1fr}

  /* The console navigation becomes a horizontally scrolling strip of full-height targets. The
     group headings ("Operations", "Revenue") label a vertical list; in a strip they are noise,
     and the active underline says where you are instead. */
  .admin__side{position:static;height:auto;padding:.85rem 0}
  .admin__brand{padding:0 1rem .85rem;margin-bottom:0;border-bottom:0}
  .admin__side nav{display:flex;gap:.3rem;overflow-x:auto;padding:.15rem .85rem .35rem;
    -webkit-overflow-scrolling:touch;scrollbar-width:thin}
  .admin__group{display:none}
  .admin__link{flex:0 0 auto;min-height:44px;padding:.5rem 1rem;border-left:0;
    border-bottom:2px solid transparent;white-space:nowrap}
  .admin__link.is-active{border-left-color:transparent;border-bottom-color:var(--bronze)}

  /* A data table cannot be read on a phone. It is wider than the screen by construction, so the
     columns a manager needs — the status, what is still owed — sit off the right edge behind a
     sideways swipe. (The phone capture of the reservations list showed exactly two columns:
     Reference and Guest. Everything that told you whether to act was invisible.)

     So on a phone each row of an opted-in table becomes a card: the header row goes, every cell
     becomes a labelled line, and nothing overlaps or clips. The label comes from the cell's own
     `data-label`, so it is opt-in twice over — the table carries `.cards` and its cells carry the
     header text. The other 40-odd console tables are left exactly as they were; hiding a header
     without a label would replace a clipped column with an ambiguous one. */
  @media(max-width:640px){
    .table-wrap{overflow-x:visible;border:0;background:none}
    table.data.cards{display:block}
    table.data.cards thead{display:none}
    table.data.cards tbody{display:block}
    table.data.cards tr{
      display:block;border:1px solid var(--line);background:var(--paper);
      padding:.9rem 1rem;margin-bottom:.65rem;
    }
    table.data.cards tr:hover td{background:none}
    table.data.cards td{
      display:block;padding:.18rem 0;border:0;text-align:left!important;
      font-variant-numeric:tabular-nums;overflow-wrap:anywhere;
    }
    table.data.cards td[data-label]::before{
      content:attr(data-label);display:block;
      font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
      margin-bottom:.1rem;
    }
    /* The card's first line carries the row's own link — the booking reference, the order number.
       As inline text it is a 16 px-tall target, under the 24 px floor and well under the 44 px one,
       so the link gets a block of its own to fill. */
    table.data.cards td:first-child a{display:block;min-height:44px}
    /* The row's own link and the Open button belong at the foot of the card, not in the middle. */
    table.data.cards td:last-child{margin-top:.6rem}
    table.data.cards td:last-child .btn{width:100%;justify-content:center}
  }

  /* Small buttons and filter chips reach the guidance too. `min-height` rather than padding, so a
     label that wraps to two lines grows instead of being clipped. */
  .btn--sm,.chip,.tab,.filters button,.qty button{min-height:44px}
  .qty button{min-width:44px}
  .chip,.tab{align-items:center}
  .link-more{display:inline-flex;align-items:center;min-height:44px}

  /* Standalone links that were sized for a mouse: the telephone number and email address in the
     header, the breadcrumb, room-card titles, the detail lists on the contact page, and the
     "back to the resort" links. They are links a thumb is expected to hit, not words inside a
     sentence, so they get the same floor as the buttons. */
  /* `:not(.hide-sm)` keeps this rule from fighting the one utility in the sheet: elements marked
     for wide screens only must not be given a size here. (They were not the only reason those two
     header items showed on a phone — see the note on `.hide-sm` below — but a touch-target rule has
     no business re-displaying them either way.) */
  .topbar a:not(.hide-sm),.topbar button,.card__title a,.breadcrumb a,.dl a{min-height:44px;display:inline-flex;align-items:center}
  /* A one-word breadcrumb ("Home") is narrower than it is tall, so it gets a floor in both
     directions rather than one. The extra few pixels read as spacing around the divider. */
  .breadcrumb a{min-width:44px}
  /* The logo is the way home from every page; it keeps its own layout and just grows. */
  .brand{min-height:44px}
}

/* ==========================================================================
   Supplement — availability calendar, misc utilities
   (added alongside the console views)
   ========================================================================== */
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:.4rem}
.cal-cell{background:var(--paper);border:1px solid var(--line);padding:.65rem;min-height:96px;display:flex;flex-direction:column;gap:.35rem}
.cal-cell--head{background:transparent;border:0;min-height:0;font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);padding:.2rem}
.cal-cell.is-today{border-color:var(--bronze);box-shadow:inset 0 0 0 1px var(--bronze)}
.cal-bar{height:6px;background:var(--sand);margin-top:auto;position:relative;overflow:hidden}
.cal-bar span{position:absolute;inset:0 auto 0 0;background:var(--forest)}
.my-2{margin-block:.5rem}
.my-3{margin-block:1rem}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
/* `.hide-sm` means "wide screens only". It carries two very different things: the little header
   items, which want flex alignment while they are visible, and — since the console tables learned
   to drop columns on a phone — `<th>`/`<td>` elements. A bare `display:inline-flex` is fine on a
   link and ruinous on a table cell: it takes the cell out of the table, and the header collapses
   into columns drawn on top of one another. So the display help is scoped to the header, and cells
   get nothing from this utility but the promise. */
.topbar .hide-sm{display:inline-flex;align-items:center}
@media (max-width:760px){.cal-grid{grid-template-columns:repeat(3,1fr)}}
/* `.hide-sm` has to win outright, and `!important` is warranted for the same reason the print block
   above uses it: it is a utility, and a utility is a promise that nothing else in the stylesheet
   will argue with. It lost that argument. `.topbar a` — added to give the header links a bigger tap
   area — is more specific than a bare class, so `display:none` never applied to the two header
   elements that carry it, and the phone header has shown a full-width email address and a Concierge
   link ever since. The CSS comment beside this rule has always said "one line of utility text
   instead of three"; for as long as the rule was defeated, it was three. */
@media (max-width:640px){.hide-sm{display:none!important}}

/* ---------- Phones ---------- */
@media (max-width:640px){
  /* Stack the hero call-to-action buttons and make them the same width: side by side they
     were ragged, with the outline button wider than the filled one, which reads as a mistake
     rather than a choice. Full-width stacked buttons are also a bigger tap target. */
  .hero__actions{display:grid;gap:.6rem}
  .hero__actions .btn{width:100%}

  /* The scroll cue overlaps the booking card on a phone (the hero is short and the card
     follows it closely), and a phone has no need for a hint to scroll. */
  .hero__scroll{display:none}

  /* One line of utility text instead of three, so the hero is not pushed off the screen. */
  .topbar__inner{justify-content:center;min-height:38px;gap:.75rem}
  .topbar{text-align:center}
}

/* ==========================================================================
   Console utilities — kitchen board, QR console, compact tables
   Added after the console views were written; keeps admin markup tidy.
   ========================================================================== */

.panel__head--row { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.panel__title { font-family: var(--font-serif); font-size: 1.15rem; margin: 0; color: var(--forest); }
.panel__sub { margin: .15rem 0 0; font-size: .8rem; color: var(--muted); }

.btn-row { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.btn-row--tight { gap: .3rem; }
.btn--xs { padding: .3rem .65rem; font-size: .72rem; letter-spacing: .04em; }
.btn--quiet {
  background: transparent;
  border-color: transparent;
  color: var(--forest);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.btn--quiet:hover { background: var(--sand); border-color: transparent; }

.alert--danger { border-left-color: var(--danger); background: #fdf3f2; color: #7a2a22; }

.right { text-align: right; }
.small { font-size: .82rem; }
.ml-1 { margin-left: .35rem; }
.prose p { margin: 0 0 .7rem; }
.prose p:last-child { margin-bottom: 0; }

/* Kitchen / bar board ---------------------------------------------------- */
.board {
  display: grid;
  grid-template-columns: repeat(4, minmax(240px, 1fr));
  gap: 1rem;
  align-items: start;
}
@media (max-width: 1100px) { .board { grid-template-columns: repeat(2, minmax(220px, 1fr)); } }
@media (max-width: 640px) { .board { grid-template-columns: 1fr; } }

.board__col {
  background: var(--sand);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .75rem;
  min-height: 120px;
}
.board__col-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: .65rem;
}
.board__col-head strong { font-family: var(--font-serif); font-size: 1rem; letter-spacing: 0; color: var(--forest); }

.board__cards { display: grid; gap: .65rem; }
.board__card {
  background: #fff;
  border: 1px solid var(--line);
  border-left: 3px solid var(--bronze);
  border-radius: 6px;
  padding: .7rem .8rem;
  box-shadow: 0 1px 2px rgba(31, 42, 36, .04);
  font-size: .85rem;
}
.board__card.is-late { border-left-color: var(--danger); background: #fffaf9; }
.board__card.is-late::after {
  content: "running late";
  display: inline-block;
  margin-top: .35rem;
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--danger);
}
.board__items { list-style: none; margin: .45rem 0 0; padding: 0; font-size: .82rem; }
.board__items li { padding: .12rem 0; border-bottom: 1px dotted var(--line); }
.board__items li:last-child { border-bottom: 0; }
.board__note {
  margin-top: .5rem;
  padding: .4rem .55rem;
  background: #fff8e6;
  border-left: 2px solid var(--bronze);
  font-size: .76rem;
  color: #6b5a2a;
}

@media print {
  .board { grid-template-columns: repeat(2, 1fr); }
  .board__card { break-inside: avoid; }
}
