/* hero9.css — LPI v2 hero refinement (PREVIEW). Loads after sm-components.css / blog-tokens.css.
   One design language, three densities via [data-hero9="full|standard|compact"] on section#hero.
   Only existing tokens are used. The :not(#_):not(#_) chain lifts specificity above the blog-tokens
   duplicate hero rules (body:is(.wp-theme-lpi-blog,.error404):not(#lpi-v2) #hero …) without !important. */

/* ----- heading face: Cabinet Grotesk Extrabold (Indian Type Foundry, ITF Free Font License v2.0, 17 Aug 2026).
   Self-hosted Official Version from the Fontshare download, byte-for-byte (FFL §01 permits self-hosting via
   @font-face; FFL §02 forbids subsetting/format conversion/metadata edits, so the file is NOT subset).
   Licence text ships next to the file: /_sm/fonts/CabinetGrotesk-FFL.txt. One weight only. NOT preloaded and requested
   with no query: the site's one font preload is Archivo and forms-e2e (rc9) wants every woff2 URL query-free, fetched once.
   The file is immutable under FFL §02, so it needs no cache key. */
@font-face {
  font-family: 'Cabinet Grotesk';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('/_sm/fonts/CabinetGrotesk-Extrabold.woff2') format('woff2');
}
/* metric-matched fallback (measured against Arial Bold with fontTools: avg advance 0.441em vs 0.466em) so the
   swap moves no line: CLS stays 0 */
@font-face {
  font-family: 'Cabinet Fallback';
  font-style: normal;
  font-weight: 800;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Helvetica Neue Bold'), local('Arial');
  size-adjust: 94.71%;
  ascent-override: 91.86%;
  descent-override: 29.56%;
  line-gap-override: 9.5%;
}

#hero[data-hero9]:not(#_):not(#_) {
  /* local scale: H1 34→50px, compact H1 rides the h2 ramp */
  --h9-h1: clamp(2.125rem, 1.4rem + 1.9vw, 3rem);
  --h9-h1-compact: var(--t-h2);
  --h9-plate-w: min(50%, 700px);
  --h9-band-h: 200px;
  display: grid;
  align-content: center;
  padding: var(--hero-top) 0 var(--s8);
  min-height: clamp(560px, 78svh, 760px);
}
#hero[data-hero9="full"]:not(#_):not(#_) { min-height: clamp(640px, 92svh, 900px); }
#hero[data-hero9="compact"]:not(#_):not(#_) { min-height: 0; padding-bottom: var(--s7); --h9-plate-w: min(42%, 560px); --h9-band-h: 140px; }

/* ----- layout ----- */
#hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) {
  grid-template-columns: minmax(0, 1.6fr) minmax(300px, 1fr);
  gap: var(--s8);
  align-items: start;
}
#hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > * { max-width: 40rem; }

/* v2 defect carried into every hero: the review link is inline-flex, which eats the spaces in
   "Rated 5.0★ · 72 Google reviews"; inline restores them. Count/rating hooks untouched. */
#hero[data-hero9]:not(#_):not(#_) div:has(> div > svg) a[href*="reviews"] { display: inline; }

/* ----- type ----- */
#hero[data-hero9]:not(#_):not(#_) h1 {
  /* !important only because blog-tokens pins the blog-post H1 face with !important; the rule is scoped to #hero */
  font-family: 'Cabinet Grotesk', 'Cabinet Fallback', var(--font-display) !important;
  font-weight: 800 !important;
  font-size: var(--h9-h1);
  line-height: 1.04;
  letter-spacing: -.015em;
  max-width: 16em;
  margin-bottom: var(--s5);
  text-wrap: balance;
}
/* blog-tokens sets the blog H1 size with !important; the compact ramp has to match that weight */
#hero[data-hero9="compact"]:not(#_):not(#_):not(#_) h1 { font-size: var(--h9-h1-compact) !important; line-height: 1.08 !important; max-width: 44rem; margin-bottom: var(--s4); }
#hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div:first-child > p:not(:has(> span)),
#hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > p:not(:has(> span:only-child)):not(:has(> a[href*="reviews"])) {
  font-size: var(--t-lead);
  line-height: var(--lh-lead);
  max-width: 34em;
  padding-left: var(--s4);
  border-left: 3px solid var(--gold);
}
#hero[data-hero9]:not(#_):not(#_) dt { font-size: var(--t-meta); color: var(--on-navy-2); } /* polish P22: labels on --on-navy-2 */
#hero[data-hero9]:not(#_):not(#_) dd { font-size: var(--t-body); }
#hero[data-hero9]:not(#_):not(#_) nav.sm-nav { margin-bottom: var(--s3); }

/* ----- CTAs + proof -----
   One button spec on every hero density and on the CTA bands: the home hero's weight, size, tracking,
   48px target, and the same five states (rest / hover / focus-visible / active / disabled).
   Text and hrefs are untouched: the rules address `.sm-cta`, never its content. */
#hero[data-hero9]:not(#_):not(#_) div:has(> a.sm-cta) { gap: var(--s3); margin-bottom: var(--s5); }
#hero[data-hero9]:not(#_):not(#_) a.sm-cta,
body:has(#hero[data-hero9]):not(#_):not(#_) .sm-band a.sm-cta {
  min-height: var(--tap);
  padding-inline: var(--s5);
  font-weight: var(--w-bold);
  font-size: var(--t-ui);
  letter-spacing: var(--ls-ui);
  line-height: var(--lh-ui);
}
#hero[data-hero9]:not(#_):not(#_) a.sm-cta ~ a.sm-cta,
body:has(#hero[data-hero9]):not(#_):not(#_) .sm-band a.sm-cta ~ a.sm-cta {
  background: transparent;
  border: 2px solid color-mix(in srgb, var(--on-navy) 78%, transparent);
}
#hero[data-hero9]:not(#_):not(#_) a.sm-cta ~ a.sm-cta:hover,
body:has(#hero[data-hero9]):not(#_):not(#_) .sm-band a.sm-cta ~ a.sm-cta:hover { background: var(--glass); border-color: var(--on-navy); }
/* focus ring on navy: the site's --focus-ring (#1C5078) is 1.9:1 against navy; the gold on-navy token is 9.7:1 */
#hero[data-hero9]:not(#_):not(#_) a.sm-cta:focus-visible,
body:has(#hero[data-hero9]):not(#_):not(#_) .sm-band a.sm-cta:focus-visible { outline: 3px solid var(--focus-on-navy); outline-offset: 3px; }
#hero[data-hero9]:not(#_):not(#_) a.sm-cta:active,
body:has(#hero[data-hero9]):not(#_):not(#_) .sm-band a.sm-cta:active { filter: brightness(.94); }
#hero[data-hero9]:not(#_):not(#_) a.sm-cta[aria-disabled="true"],
body:has(#hero[data-hero9]):not(#_):not(#_) .sm-band a.sm-cta[aria-disabled="true"] { opacity: .55; pointer-events: none; filter: none; }
#hero[data-hero9]:not(#_):not(#_) div:has(> div > svg) { min-height: var(--tap-min); }

/* ----- 404 (the one page whose markup hero9_apply.py generates; compact hero shell + a "where to next" grid) ----- */
body.error404 #hero[data-hero9="compact"]:not(#_):not(#_) h1 { max-width: 20ch; }
.h9-next ul { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: var(--s4); }
.h9-next li { margin: 0; display: grid; } /* tiles in a row share a height */
.h9-next a.h9-tile { height: 100%; }
.h9-next a.h9-tile {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  column-gap: var(--s4);
  row-gap: var(--s1);
  align-items: center;
  min-height: var(--tap);
  padding: var(--s5);
  background: var(--surface);
  background-image: var(--grad-card-warm);
  border: 1px solid var(--border);
  border-radius: var(--rad-card);
  box-shadow: var(--shadow-sm);
  color: var(--body);
  text-decoration: none;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.h9-next a.h9-tile strong { grid-column: 1; font-weight: var(--w-bold); font-size: var(--t-body); line-height: var(--lh-ui); color: var(--navy); }
.h9-next a.h9-tile span { grid-column: 1; color: var(--secondary); font-size: var(--t-small); line-height: var(--lh-small); }
.h9-next a.h9-tile::after {
  content: "";
  grid-column: 2;
  grid-row: 1 / span 2;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--navy) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / 16px no-repeat;
  transition: background-color var(--dur) var(--ease);
}
.h9-next a.h9-tile:hover { border-color: var(--gold); box-shadow: var(--shadow-card-hover); }
.h9-next a.h9-tile:hover::after { background-color: var(--gold); }
.h9-next a.h9-tile:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; }
.h9-next a.h9-tile:active { box-shadow: var(--shadow-sm); transform: none; }
.h9-next p.h9-call { text-align: center; margin: var(--s6) 0 0; color: var(--secondary); }
.h9-next p.h9-call a { display: inline-flex; align-items: center; min-height: var(--tap-min); color: var(--navy); font-weight: var(--w-bold); text-decoration: underline; text-underline-offset: 3px; }
.h9-next p.h9-call a:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; border-radius: 4px; }
@media (prefers-reduced-motion: no-preference) {
  .h9-next a.h9-tile:hover { transform: translateY(-2px); }
}

/* ----- plate (the water image): same picture, refined crop, tone and mask ----- */
#hero[data-hero9]:not(#_):not(#_) > figure {
  width: var(--h9-plate-w);
  opacity: 1;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 44%), linear-gradient(180deg, #000 58%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg, transparent 0, #000 44%), linear-gradient(180deg, #000 58%, transparent 100%);
  mask-composite: intersect;
}
#hero[data-hero9]:not(#_):not(#_) > figure img {
  object-position: 62% 45%;
  filter: grayscale(.3) brightness(.74) contrast(1.14) saturate(1.15);
}
#hero[data-hero9]:not(#_):not(#_) > figure::after {
  opacity: .36;
  background: linear-gradient(160deg, var(--navy-deep), rgba(28, 80, 120, .9));
}

/* ----- motion: one entrance, nothing else; honours reduced motion ----- */
@media (prefers-reduced-motion: no-preference) {
  @keyframes hero9-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
  @keyframes hero9-plate { from { opacity: 0; } to { opacity: 1; } }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]) { animation: hero9-in .45s cubic-bezier(.2, .7, .2, 1) both; }
  #hero[data-hero9]:not(#_):not(#_) > figure { animation: hero9-plate .9s ease-out both; }
}

/* ----- mobile / narrow: plate becomes an in-flow band under the content, CTAs full width ----- */
@media (max-width: 960px) {
  #hero[data-hero9]:not(#_):not(#_) { min-height: 0; padding-bottom: 0; }
  #hero[data-hero9]:not(#_):not(#_) h1 { font-size: var(--t-h1); max-width: none; }
  #hero[data-hero9="compact"]:not(#_):not(#_) h1 { font-size: var(--t-h2) !important; }
}
@media (max-width: 360px) {
  #hero[data-hero9]:not(#_):not(#_) h1 { font-size: var(--t-h2); } /* polish P28: one rung down at the 320px fold */
}
@media (max-width: 960px) {
  #hero[data-hero9]:not(#_):not(#_) { --h9-band-h: 160px; }
  #hero[data-hero9="compact"]:not(#_):not(#_) { --h9-band-h: 120px; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) { grid-template-columns: minmax(0, 1fr); gap: var(--s6); }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div:first-child > p:not(:has(> span)),
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > p:not(:has(> span:only-child)):not(:has(> a[href*="reviews"])) { font-size: var(--t-body); line-height: var(--lh-body); }
  #hero[data-hero9]:not(#_):not(#_) > figure {
    position: relative;
    inset: auto;
    width: 100%;
    height: var(--h9-band-h);
    margin-top: var(--s7);
    opacity: 1;
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 55%);
    -webkit-mask-composite: source-over;
    mask-image: linear-gradient(180deg, transparent 0, #000 55%);
    mask-composite: add;
  }
  #hero[data-hero9]:not(#_):not(#_) > figure img { object-position: 50% 55%; }
  #hero[data-hero9]:not(#_):not(#_) div:has(> a.sm-cta) { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
  #hero[data-hero9]:not(#_):not(#_) div:has(> a.sm-cta) > a { width: 100%; justify-content: center; }
  /* ----- mobile fold: booking CTA inside 390×844 at scroll 0, clear of the fixed call bar -----
     CSS-only reorder: DOM, text order and links are untouched (verifier (c)/(d) unchanged).
     Note: tab order still follows the DOM (phone → book after the lede); visual order is what moves. */
  /* FULL (home): the two columns dissolve (display:contents) so their children become items of the
     one-column hero grid and can be ordered; the dl takes the card look the dissolved column had. */
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) { gap: 0; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div { display: contents; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div > * { order: 10; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div > p:has(> span:only-child) { order: 1; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div > h1 { order: 2; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div > div:has(> a.sm-cta) { order: 3; margin-bottom: var(--s6); }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div > p:not(:has(> span)) { order: 4; margin-bottom: var(--s6); }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div > dl { order: 5; background: var(--scrim-navy); border-radius: var(--rad-card); padding: var(--s5); margin: 0 0 var(--s5); }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):has(> div > h1) > div > div:has(> div > svg) { order: 6; }
  /* STANDARD + COMPACT (single column): the column becomes a one-column grid; items keep their margins. */
  /* flex column, as polish P28 (rc19 A5) lays the 320px fold out; `order` behaves the same as in the grid it replaces */
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) { display: flex; flex-direction: column; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > * { order: 10; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > nav { order: 1; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > div:has(+ h1) { order: 2; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > h1 { order: 3; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > .blog-meta { order: 4; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > div:has(> a.sm-cta) { order: 5; margin-bottom: var(--s6); }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > p:not(:has(> a[href*="reviews"])) { order: 6; margin-bottom: var(--s6); }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > dl { order: 7; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > div:has(> div > svg) { order: 8; }
  #hero[data-hero9]:not(#_):not(#_) > div:not([aria-hidden]):not(:has(> div > h1)) > p:has(> a[href*="reviews"]) { order: 9; }
  /* ----- breadcrumb on narrow screens: wraps (the base rule). An earlier one-line/ellipsis variant was removed on
     2026-11-10: tests/polish/gutter.mjs measures every text node's client rects, and clipped crumb text still
     extends past the viewport edge, so nothing in the hero may be truncated. Polish P28 tightens the row at <= 360px. */

  /* ----- chip-row nav: stays a scroller (six chips need ~420px; a second row would add ~52px and push the hero
     below --hero-top, so wrapping is out). Two cues make the cut-off chip read as "more": the row fades out at the
     right edge (mask, works over any hero background) and a fixed chevron sits over the fade. The chevron is a body
     pseudo-element, outside the masked box, and fades away as the row reaches its end (scroll-driven animation;
     browsers without it keep the chevron, which is still true until the last chip is in view). */
  body:has(#hero[data-hero9]):not(#_):not(#_) > div[role=navigation] {
    -webkit-mask-image: linear-gradient(90deg, #000 78%, rgba(0, 0, 0, .35) 92%, transparent 100%);
    mask-image: linear-gradient(90deg, #000 78%, rgba(0, 0, 0, .35) 92%, transparent 100%);
    padding-right: var(--s8);
    scroll-timeline: --h9-chips inline;
  }
  body:has(#hero[data-hero9]):not(#_):not(#_) { timeline-scope: --h9-chips; }
  body:has(#hero[data-hero9]):not(#_):not(#_)::before {
    content: "";
    position: absolute;
    z-index: 39;
    top: calc(68px + var(--s2) + (var(--tap-min) - 28px) / 2);
    right: var(--gutter);
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 1px solid var(--line-on-navy);
    background: var(--scrim-navy) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E") center / 14px no-repeat;
    pointer-events: none;
    animation: h9-chip-end linear both;
    animation-timeline: --h9-chips;
    animation-range: 60% 100%;
  }
  @keyframes h9-chip-end { to { opacity: 0; } }
}
