/* ==========================================================================
   Mt. Zion Haven - main stylesheet
   Order: reset, base, layout, components, sections, utilities, responsive.
   ========================================================================== */

/* -------------------------------------------------------------- 1. reset */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/* Lenis owns scrolling in Hi-Fi. Native smooth would fight it. */
html.lenis,
html[data-motion='lo'] {
  scroll-behavior: auto;
}

/* The four rules Lenis needs, inlined instead of pulling its stylesheet as a
   second CDN request. From lenis/dist/lenis.css. */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  color: var(--text);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img,
svg,
video,
canvas {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: none;
  cursor: pointer;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

/* --------------------------------------------------------------- 2. base */

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 400;
  font-optical-sizing: auto;
  line-height: var(--lh-tight);
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h1 {
  font-size: var(--fs-3xl);
}
h2 {
  font-size: var(--fs-2xl);
}
h3 {
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
}
h4 {
  font-size: var(--fs-md);
  line-height: var(--lh-snug);
}

p {
  text-wrap: pretty;
}

::selection {
  background: var(--brass-400);
  color: var(--ink-900);
}

/* One focus treatment for the whole site. Always visible, never removed. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: var(--sp-4);
  z-index: calc(var(--z-loader) + 1);
  padding: var(--sp-3) var(--sp-5);
  background: var(--ink-800);
  color: var(--bone-200);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: 500;
  transform: translateY(-160%);
  transition: transform var(--dur) var(--ease);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------- 3. layout */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.wrap--wide {
  max-width: var(--wrap-wide);
}

.wrap--narrow {
  max-width: var(--wrap-narrow);
}

.section {
  padding-block: var(--section-y);
}

.section--sunken {
  background-color: var(--bg-sunken);
}

.section--ink {
  background-color: var(--bg-dark);
  color: var(--text-on-dark);
}

.section--ink h1,
.section--ink h2,
.section--ink h3,
.section--ink h4 {
  color: var(--bone-100);
}

.section--sage {
  background-color: var(--sage-600);
  color: var(--bone-100);
}

.section--sage h2,
.section--sage h3 {
  color: var(--bone-100);
}

/* The craquelure. It only reads as material if it has something plain to sit
   against, so it goes on every other band rather than on every surface: the
   sunken sections on the bone grounds, the ink sections on the dark. Left out
   on purpose: the photo-backed hero, the page-title heroes, the closing CTA
   band and the footer. */
.section--sunken {
  background-image: var(--ceramic);
}

.section--ink {
  background-image: var(--ceramic-dark);
}

/* Two textured bands in a row would read as one long pattern, which is the
   thing this is meant to avoid. If one stacks straight on another, the second
   goes plain. */
.section--sunken + .section--ink {
  background-image: none;
}

.stack > * + * {
  margin-top: var(--sp-4);
}

.lede {
  font-size: var(--fs-md);
  color: var(--text-muted);
  max-width: 62ch;
}

.section--ink .lede,
.section--sage .lede {
  color: var(--text-on-dark-muted);
}

.section--sage .lede {
  color: rgba(250, 247, 241, 0.82);
}

/* ---------------------------------------------------------- 4. eyebrow */

.eyebrow {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--brass-text);
  margin-bottom: var(--sp-4);
}

.eyebrow::before {
  content: '';
  width: 28px;
  height: 1px;
  background: var(--brass-500);
  flex: none;
}

.section--ink .eyebrow,
.section--sage .eyebrow,
.hero .eyebrow {
  color: var(--brass-400);
}

.eyebrow--center {
  justify-content: center;
}

.section-head {
  max-width: min(100%, 52rem);
  margin-bottom: var(--sp-7);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}

.section-head--center .eyebrow {
  justify-content: center;
}

/* --------------------------------------------------------- 5. buttons */

.btn {
  --btn-bg: var(--brass-500);
  --btn-fg: var(--ink-900);
  --btn-border: var(--brass-500);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  padding: 0.9rem 1.6rem;
  min-height: 48px;
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0.03em;
  text-decoration: none;
  border: 1px solid var(--btn-border);
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease), transform var(--dur-fast) var(--ease);
}

.btn .icon {
  width: 18px;
  height: 18px;
  flex: none;
  transition: transform var(--dur) var(--ease-out);
}

.btn:hover {
  --btn-bg: var(--brass-400);
  --btn-border: var(--brass-400);
}

.btn:active {
  --btn-bg: var(--brass-600);
  --btn-border: var(--brass-600);
  transform: translateY(1px);
}

.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* Secondary: outline. Adapts to whichever ground it sits on. */
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  --btn-border: var(--border-strong);
}

.btn--ghost:hover {
  --btn-bg: transparent;
  --btn-fg: var(--ink-900);
  --btn-border: var(--brass-500);
}

.btn--ghost:active {
  --btn-bg: rgba(176, 139, 79, 0.1);
  --btn-border: var(--brass-600);
}

.section--ink .btn--ghost,
.section--sage .btn--ghost,
.hero .btn--ghost,
.page-hero .btn--ghost,
.footer .btn--ghost {
  --btn-fg: var(--bone-200);
  --btn-border: var(--border-on-dark-strong);
}

.section--ink .btn--ghost:hover,
.hero .btn--ghost:hover,
.page-hero .btn--ghost:hover,
.footer .btn--ghost:hover {
  --btn-fg: var(--bone-100);
  --btn-border: var(--brass-400);
}

/* On sage the brass hover would sit too close in value. Go to bone instead. */
.section--sage .btn--ghost {
  --btn-border: rgba(250, 247, 241, 0.42);
}

.section--sage .btn--ghost:hover {
  --btn-fg: var(--sage-600);
  --btn-bg: var(--bone-100);
  --btn-border: var(--bone-100);
}

.btn--sage {
  --btn-bg: var(--sage-500);
  --btn-fg: var(--bone-100);
  --btn-border: var(--sage-500);
}

.btn--sage:hover {
  --btn-bg: var(--sage-400);
  --btn-border: var(--sage-400);
  --btn-fg: var(--ink-900);
}

.btn--sage:active {
  --btn-bg: var(--sage-600);
  --btn-border: var(--sage-600);
}

.btn--sm {
  padding: 0.6rem 1.15rem;
  min-height: 40px;
  font-size: var(--fs-xs);
}

.btn--lg {
  padding: 1.05rem 2rem;
  min-height: 56px;
  font-size: var(--fs-base);
}

.btn--block {
  width: 100%;
}

/* Loading state. The label hides, a brass ring spins in its place. */
.btn[data-loading='true'] {
  color: transparent;
  pointer-events: none;
}

.btn[data-loading='true']::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 20px;
  height: 20px;
  border: 2px solid rgba(12, 16, 21, 0.25);
  border-top-color: var(--ink-900);
  border-radius: 50%;
  animation: spin 720ms linear infinite;
}

.btn--ghost[data-loading='true']::after {
  border-color: rgba(232, 226, 214, 0.25);
  border-top-color: var(--bone-200);
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn[data-loading='true']::after {
    animation-duration: 1800ms;
  }
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
}

/* Inline text link with a brass underline that grows on hover. */
.link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 500;
  color: var(--brass-text);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid rgba(176, 139, 79, 0.4);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.link:hover {
  color: var(--ink-800);
  border-bottom-color: var(--brass-500);
}

.link .icon {
  width: 16px;
  height: 16px;
  transition: transform var(--dur) var(--ease);
}

.link:hover .icon {
  transform: translateX(3px);
}

.section--ink .link,
.footer .link {
  color: var(--brass-400);
  border-bottom-color: rgba(201, 167, 106, 0.4);
}

.section--ink .link:hover,
.footer .link:hover {
  color: var(--bone-100);
  border-bottom-color: var(--brass-400);
}

/* ---------------------------------------------------------- 6. header */

.header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: height var(--dur) var(--ease), background var(--dur) var(--ease),
    border-color var(--dur) var(--ease), backdrop-filter var(--dur) var(--ease);
}

/* Pages that do not open on a dark hero need the solid bar immediately. */
body:not(.has-dark-hero) .header,
.header[data-condensed='true'] {
  background: rgba(12, 16, 21, 0.92);
  backdrop-filter: blur(10px);
  border-bottom-color: var(--border-on-dark);
}

.header[data-condensed='true'] {
  height: 62px;
}

.header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  width: 100%;
  max-width: var(--wrap-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  text-decoration: none;
  color: var(--bone-100);
  flex: none;
}

/* The venue's logo image (MT. ZION CAMP). Transparent ground, so it sits on the
   transparent header over the hero and on the condensed ink bar without a box.
   The mark is white and green, so it needs a dark backdrop to read: header and
   footer are both ink. Height-driven; width follows the aspect ratio, and the
   img carries width/height attrs so there is no layout shift before it loads. */
.brand__logo {
  display: block;
  height: 42px;
  width: auto;
  transition: transform var(--dur-slow) var(--ease-out);
}

.brand:hover .brand__logo {
  transform: translateY(-2px);
}

@media (max-width: 400px) {
  .brand__logo {
    height: 34px;
  }
}

.nav {
  margin-left: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 0.1rem + 1.1vw, 1.5rem);
}

.nav__link {
  position: relative;
  display: block;
  white-space: nowrap;
  padding: var(--sp-2) var(--sp-2);
  font-size: var(--fs-sm);
  color: rgba(244, 240, 232, 0.78);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.nav__link::after {
  content: '';
  position: absolute;
  left: var(--sp-2);
  right: var(--sp-2);
  bottom: 0;
  height: 1px;
  background: var(--brass-400);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}

.nav__link:hover {
  color: var(--bone-100);
}

.nav__link:hover::after {
  transform: scaleX(1);
}

.nav__link[aria-current='page'] {
  color: var(--bone-100);
}

.nav__link[aria-current='page']::after {
  transform: scaleX(1);
}

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex: none;
}

/* The CTA lives in the header bar on desktop and inside the panel on mobile.
   Only one of the two is ever visible. */
.nav__cta {
  display: none;
}

/* Hi-Fi / Lo-Fi switch. Persistent and discoverable, never a hidden toggle. */
.fi-toggle {
  display: inline-flex;
  align-items: center;
  padding: 3px;
  border: 1px solid var(--border-on-dark-strong);
  border-radius: var(--r-pill);
  background: rgba(12, 16, 21, 0.5);
}

.fi-toggle__btn {
  padding: 0.34rem 0.72rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(244, 240, 232, 0.62);
  border-radius: var(--r-pill);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.fi-toggle__btn:hover {
  color: var(--bone-100);
}

.fi-toggle__btn[aria-pressed='true'] {
  background: var(--brass-500);
  color: var(--ink-900);
}

.fi-toggle__btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.fi-toggle__btn:disabled:hover {
  color: rgba(244, 240, 232, 0.62);
}

.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  color: var(--bone-100);
  border: 1px solid var(--border-on-dark-strong);
  border-radius: var(--r-md);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.nav-toggle:hover {
  border-color: var(--brass-400);
}

.nav-toggle .icon {
  width: 22px;
  height: 22px;
}

.nav-toggle__close {
  display: none;
}

.nav-toggle[aria-expanded='true'] .nav-toggle__open {
  display: none;
}

.nav-toggle[aria-expanded='true'] .nav-toggle__close {
  display: block;
}

/* ------------------------------------------------------------- 7. hero */

.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 100svh;
  padding-top: calc(var(--header-h) + var(--sp-6));
  padding-bottom: clamp(3rem, 2rem + 5vw, 7rem);
  background: var(--ink-900);
  color: var(--bone-200);
  overflow: hidden;
  isolation: isolate;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -3;
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.55;
}

/* Flat scrim, not a gradient. Keeps the headline readable over any photo. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -2;
  background: rgba(12, 16, 21, 0.58);
}

/* width and height are explicit on purpose: an absolutely positioned replaced
   element ignores `right`/`bottom` and falls back to its intrinsic 300x150,
   so `inset: 0` alone leaves the canvas tiny. */
.hero__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
}

.hero__inner {
  width: 100%;
  max-width: var(--wrap-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.hero__content {
  max-width: min(100%, 62rem);
}

/* The measure has to be set on the heading itself, in em, so it scales with
   the display size. A ch limit on the wrapper resolves against the body font
   and crushes a 100px headline into a narrow column. */
.hero__title {
  font-size: var(--fs-hero);
  line-height: 0.96;
  letter-spacing: -0.03em;
  color: var(--bone-100);
  max-width: 8.5em;
}

.hero__title em {
  font-style: italic;
  color: var(--brass-400);
}

.hero__tagline {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-style: italic;
  color: rgba(244, 240, 232, 0.86);
  max-width: 26ch;
  margin-top: var(--sp-5);
  line-height: var(--lh-snug);
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--text-on-dark-muted);
}

.hero__meta .icon {
  width: 16px;
  height: 16px;
  color: var(--brass-400);
}

.hero .btn-row {
  margin-top: var(--sp-6);
}

/* On a phone the copy and two full-width buttons fill the hero, and the cue
   ran through the second button. Touch users scroll without being told. */
@media (max-width: 599px) {
  .hero .hero__cue {
    display: none;
  }
}

.hero__cue {
  position: absolute;
  left: 50%;
  bottom: var(--sp-5);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: rgba(244, 240, 232, 0.5);
}

.hero__cue-line {
  width: 1px;
  height: 42px;
  background: rgba(201, 167, 106, 0.5);
  overflow: hidden;
  position: relative;
}

.hero__cue-line::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  top: -100%;
  height: 100%;
  background: var(--brass-400);
  animation: cue 2.4s var(--ease) infinite;
}

@keyframes cue {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(200%);
  }
}

html[data-motion='lo'] .hero__cue-line::after {
  animation: none;
  top: 0;
}

@media (prefers-reduced-motion: reduce) {
  .hero__cue-line::after {
    animation: none;
    top: 0;
  }
}

/* Compact hero for interior pages. */
.page-hero {
  position: relative;
  padding-top: calc(var(--header-h) + clamp(3rem, 2rem + 4vw, 5.5rem));
  padding-bottom: clamp(2.5rem, 1.8rem + 3.5vw, 4.5rem);
  background-color: var(--ink-800);
  color: var(--text-on-dark);
  overflow: hidden;
}

.page-hero::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 1px;
  background: var(--border-on-dark);
}

.page-hero h1 {
  color: var(--bone-100);
  max-width: 18ch;
}

.page-hero .lede {
  margin-top: var(--sp-5);
  color: var(--text-on-dark-muted);
}

/* ------------------------------------------------- 8. breadcrumb + cards */

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(244, 240, 232, 0.55);
  margin-bottom: var(--sp-5);
}

.crumbs a {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.crumbs a:hover {
  color: var(--brass-400);
}

.crumbs .icon {
  width: 13px;
  height: 13px;
  opacity: 0.6;
}

.grid {
  display: grid;
  gap: var(--sp-5);
}

.grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-6);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}

.card p {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  color: var(--brass-text);
  margin-bottom: var(--sp-2);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.card__icon .icon {
  width: 22px;
  height: 22px;
}

a.card:hover {
  border-color: var(--brass-500);
  box-shadow: var(--shadow-md);
  transform: translateY(-3px);
}

a.card:hover .card__icon {
  border-color: var(--brass-500);
  color: var(--brass-600);
}

a.card {
  text-decoration: none;
  color: inherit;
}

.section--ink .card {
  background: var(--bg-dark-raised);
  border-color: var(--border-on-dark);
}

.section--ink .card p {
  color: var(--text-on-dark-muted);
}

.section--ink .card__icon {
  border-color: var(--border-on-dark-strong);
  color: var(--brass-400);
}

.section--ink a.card:hover {
  border-color: var(--brass-500);
  box-shadow: none;
}

/* Numbered step / feature list used on the interior pages. */
.feature-list {
  display: grid;
  gap: var(--sp-5);
}

.feature-list li {
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
}

.feature-list .icon {
  width: 20px;
  height: 20px;
  flex: none;
  margin-top: 3px;
  color: var(--brass-text);
}

.section--ink .feature-list .icon {
  color: var(--brass-400);
}

.feature-list h4 {
  margin-bottom: var(--sp-1);
}

.feature-list p {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.section--ink .feature-list p {
  color: var(--text-on-dark-muted);
}

/* ------------------------------------------------------ 9. media panels */

/* Layered panel: the image sits over an offset brass outline. Tasteful,
   cheap, and it reads as designed rather than as a bare rectangle. */
.media {
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-sunken);
}

.media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.media--framed {
  overflow: visible;
}

.media--framed::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid var(--brass-500);
  border-radius: var(--r-lg);
  transform: translate(var(--frame, 18px), var(--frame, 18px));
  z-index: 0;
  pointer-events: none;
}

.media--framed img {
  position: relative;
  z-index: 1;
  border-radius: var(--r-lg);
}

.split {
  display: grid;
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: 1fr 1fr;
  }

  .split--media-first .split__media {
    order: -1;
  }

  /* For blocks whose markup already leads with the image but which need it on
     the right, so a run of sections keeps alternating sides. */
  .split--media-last .split__media {
    order: 1;
  }

  .split--wide-text {
    grid-template-columns: 1.15fr 1fr;
  }
}

.split__media img {
  aspect-ratio: 4 / 3;
}

/* --------------------------------------------------------- 10. the view */

/* The pinned scrub section. In Lo-Fi it degrades to a tall static band with
   the same content, still legible, nothing hidden. */
.view {
  position: relative;
  background: var(--ink-900);
  color: var(--bone-200);
  overflow: hidden;
}

.view__stage {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding-block: var(--section-y);
}

.view__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.view__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.6;
  will-change: transform;
}

.view__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(12, 16, 21, 0.55);
}

.view__content {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: min(100%, 56rem);
  padding-inline: var(--gutter);
}

/* Same rule as the hero: measure in em on the heading, not ch on the box. */
.view__title {
  font-size: var(--fs-3xl);
  color: var(--bone-100);
  max-width: 11em;
  margin-inline: auto;
}

.view__title em {
  font-style: italic;
  color: var(--brass-400);
}

.view__body {
  margin-top: var(--sp-5);
  color: rgba(244, 240, 232, 0.82);
  font-size: var(--fs-md);
}

.view__stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-6);
  margin-top: var(--sp-7);
}

.view__stat {
  min-width: 8rem;
}

.view__stat dt {
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--brass-400);
}

.view__stat dd {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  color: var(--bone-100);
  margin-top: var(--sp-2);
}

/* ------------------------------------------------------ 11. testimonials */

.quotes {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}

.quote {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-6);
  border: 1px solid var(--border-on-dark);
  border-radius: var(--r-lg);
  background: var(--ink-700);
}

.quote__mark {
  width: 26px;
  height: 26px;
  color: var(--brass-400);
}

.quote blockquote {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  line-height: 1.5;
  color: var(--bone-100);
}

.quote figcaption {
  font-size: var(--fs-sm);
  color: var(--text-on-dark-muted);
  margin-top: auto;
}

.quote cite {
  font-style: normal;
  font-weight: 500;
  color: var(--bone-200);
  display: block;
}

/* --- live Google reviews (reviews.js) --- */

.reviews__summary {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  margin-top: var(--sp-5);
  color: var(--bone-200);
  font-size: var(--fs-sm);
}

.reviews__stars {
  color: var(--brass-400);
  letter-spacing: 0.08em;
}

/* Google's attribution text: Roboto, never localized, kept visibly apart
   from the venue's own type. */
.reviews__gmaps {
  font-family: Roboto, Arial, sans-serif;
  font-weight: 500;
  color: var(--bone-100);
  white-space: nowrap;
}

.reviews__foot {
  display: grid;
  justify-items: center;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
  text-align: center;
}

/* No review cards (no key, cap reached, nothing recent): the section head's
   own bottom margin is gap enough. */
.quotes[hidden] + .reviews__foot {
  margin-top: 0;
}

.reviews__note {
  max-width: 44rem;
  font-size: var(--fs-xs);
  color: var(--text-on-dark-muted);
}

.quote--live {
  animation: vt-in var(--dur-enter) var(--ease-out) both;
}

.quote--live blockquote {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 8;
  overflow: hidden;
}

.quote__by {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.quote__avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
}

.quote__who {
  display: grid;
}

.quote__who a,
.quote__who cite {
  font-style: normal;
  font-weight: 500;
  color: var(--bone-200);
}

.quote__when {
  font-size: var(--fs-xs);
}

/* Each review links to itself on Google Maps, as the policy requires. 44px
   tall so it is a real touch target, not a line of small print. */
.quote__source {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--fs-xs);
  color: var(--brass-300);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Placeholder marker. Deliberately visible so the client knows to replace. */
.ph {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.12em 0.55em;
  font-family: var(--font-body);
  font-size: 0.82em;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--brass-text);
  background: rgba(176, 139, 79, 0.12);
  border: 1px dashed rgba(176, 139, 79, 0.55);
  border-radius: var(--r-sm);
  white-space: nowrap;
}

.section--ink .ph,
.footer .ph,
.hero .ph,
.page-hero .ph {
  color: var(--brass-400);
  background: rgba(201, 167, 106, 0.12);
  border-color: rgba(201, 167, 106, 0.5);
}

.ph-note {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  font-style: italic;
}

.section--ink .ph-note {
  color: var(--text-on-dark-muted);
}

/* ------------------------------------------------------- 12. cta band */

.cta-band {
  position: relative;
  text-align: center;
}

.cta-band .btn-row {
  justify-content: center;
  margin-top: var(--sp-6);
}

.cta-band h2 {
  max-width: 20ch;
  margin-inline: auto;
}

.cta-band .lede {
  margin-inline: auto;
  margin-top: var(--sp-4);
}

/* ------------------------------------------------------- 13. packages */

/* Six package cards need explicit columns. The auto-fit grids fit four across
   at desktop width, which would strand the last two on their own row. */
.grid--pkg {
  grid-template-columns: 1fr;
}

@media (min-width: 700px) {
  .grid--pkg {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1100px) {
  .grid--pkg {
    grid-template-columns: repeat(3, 1fr);
  }
}

.pkg {
  display: flex;
  flex-direction: column;
  padding: var(--sp-6);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.pkg:hover {
  border-color: var(--brass-500);
  box-shadow: var(--shadow-md);
}

.pkg--featured {
  border-color: var(--brass-500);
  border-width: 1px;
  box-shadow: var(--shadow-md);
}

.pkg__flag {
  align-self: flex-start;
  padding: 0.2rem 0.7rem;
  margin-bottom: var(--sp-4);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-900);
  background: var(--brass-400);
  border-radius: var(--r-pill);
}

.pkg__title {
  font-size: var(--fs-xl);
}

.pkg__for {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: var(--sp-2);
}

.pkg__price {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding-block: var(--sp-5);
  margin-block: var(--sp-5);
  border-block: 1px solid var(--border);
}

.pkg__price-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.pkg__list {
  display: grid;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}

.pkg__list li {
  display: flex;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.pkg__list .icon {
  width: 17px;
  height: 17px;
  flex: none;
  margin-top: 4px;
  color: var(--sage-500);
}

.pkg .btn {
  margin-top: auto;
}

/* ------------------------------------------------------- 14. gallery */

.gallery-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}

.chip {
  padding: 0.5rem 1.05rem;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.chip:hover {
  color: var(--text);
  border-color: var(--brass-500);
}

.chip:active {
  background: rgba(176, 139, 79, 0.12);
}

.chip[aria-pressed='true'] {
  color: var(--ink-900);
  background: var(--brass-400);
  border-color: var(--brass-400);
}

.chip:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.chip:disabled:hover {
  color: var(--text-muted);
  border-color: var(--border-strong);
}

/* Masonry via CSS columns: no JS layout pass, reflows for free. */
.masonry {
  columns: 3;
  column-gap: var(--sp-5);
}

@media (max-width: 900px) {
  .masonry {
    columns: 2;
  }
}

@media (max-width: 560px) {
  .masonry {
    columns: 1;
  }
}

@media (min-width: 1500px) {
  .masonry {
    columns: 4;
  }
}

.masonry__item {
  break-inside: avoid;
  margin-bottom: var(--sp-5);
}

.tile {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-sunken);
  cursor: zoom-in;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.tile img {
  width: 100%;
  transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur) var(--ease);
}

.tile:hover {
  border-color: var(--brass-500);
  box-shadow: var(--shadow-md);
}

.tile:hover img {
  transform: scale(1.03);
}

.tile__caption {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  padding: var(--sp-4);
  font-size: var(--fs-xs);
  text-align: left;
  color: var(--bone-100);
  background: rgba(12, 16, 21, 0.82);
  opacity: 0;
  transform: translateY(100%);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.tile:hover .tile__caption,
.tile:focus-visible .tile__caption {
  opacity: 1;
  transform: translateY(0);
}

/* Skeletons. Real boxes at the right aspect, not a bare spinner. */
.skeleton {
  position: relative;
  border-radius: var(--r-md);
  background: var(--bone-300);
  overflow: hidden;
}

.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--bone-400);
  opacity: 0;
  animation: pulse 1.4s var(--ease) infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 0;
  }
  50% {
    opacity: 0.7;
  }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton::after {
    animation: none;
    opacity: 0.35;
  }
}

html[data-motion='lo'] .skeleton::after {
  animation: none;
  opacity: 0.35;
}

/* A tile keeps its skeleton until the file paints, then fades the photo in. */
.tile.skeleton {
  min-height: 220px;
}

.tile img {
  transition: transform var(--dur-slow) var(--ease-out), opacity 420ms var(--ease);
}

.tile--broken {
  border-style: dashed;
  border-color: var(--danger);
}

/* Static skeletons in the HTML, so something calm is on screen before the
   manifest module has even parsed. */
.skeleton-tile {
  height: var(--sk-h, 260px);
}

/* Gallery strip on the home page. */
.strip {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(240px, 1fr);
  gap: var(--sp-4);
  overflow-x: auto;
  padding-bottom: var(--sp-4);
  /* Proximity, not mandatory: mandatory fights the wheel handler's incremental
     scrollLeft writes and makes the strip feel like it is sticking. Touch
     swipes still snap. */
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}

.strip > * {
  scroll-snap-align: start;
}

/* Strip tiles link through to the gallery, they do not open a lightbox, so
   the zoom cursor would promise the wrong thing. */
.strip .tile {
  cursor: pointer;
}

.strip img {
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

/* Written empty state. Every filtered view has one. */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-8) var(--sp-5);
  text-align: center;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
  color: var(--text-muted);
}

.empty .icon {
  width: 30px;
  height: 30px;
  color: var(--brass-500);
}

.empty h3 {
  color: var(--text);
}

.empty p {
  max-width: 44ch;
  font-size: var(--fs-sm);
}

.empty--error {
  border-color: rgba(168, 68, 58, 0.5);
  background: var(--danger-bg);
}

.empty--error .icon {
  color: var(--danger);
}

/* ------------------------------------------------------ 15. lightbox */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: grid;
  grid-template-rows: auto 1fr auto;
  padding: var(--sp-4);
  background: rgba(12, 16, 21, 0.96);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility var(--dur) var(--ease);
}

.lightbox[data-open='true'] {
  opacity: 1;
  visibility: visible;
}

.lightbox__bar {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
}

.lightbox__stage {
  position: relative;
  min-height: 0;
  overflow: hidden; /* a zoomed image is clipped to the stage, not the bar/foot */
}

/* Absolute centering with inset + margin:auto reliably fits the photo to BOTH
   the stage width and height, whatever its resolution. (max-height:100% on a
   grid item does not constrain a tall image, which was letting portraits
   overflow and clip, the inconsistent sizing.) Every photo now opens fitted
   to the same box; zoom is a transform on top, set from JS. */
.lightbox__stage img {
  position: absolute;
  inset: 0;
  margin: auto;
  max-width: calc(100% - 2.5rem);
  max-height: calc(100% - 2.5rem);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--r-md);
  transform-origin: center center;
  transition: transform 0.12s ease-out;
  touch-action: none;
  cursor: zoom-in;
  will-change: transform;
}

.lightbox__stage img[data-zoomed='true'] {
  cursor: grab;
}

.lightbox__stage img[data-panning='true'] {
  cursor: grabbing;
  transition: none; /* follow the finger with no lag while dragging */
}

.lightbox__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-2);
  color: var(--text-on-dark-muted);
  font-size: var(--fs-sm);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  color: var(--bone-200);
  border: 1px solid var(--border-on-dark-strong);
  border-radius: var(--r-pill);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.icon-btn .icon {
  width: 20px;
  height: 20px;
}

.icon-btn:hover {
  border-color: var(--brass-400);
  color: var(--brass-400);
}

.icon-btn:active {
  background: rgba(201, 167, 106, 0.15);
}

.icon-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.icon-btn:disabled:hover {
  border-color: var(--border-on-dark-strong);
  color: var(--bone-200);
}

/* --------------------------------------------------------- 16. forms */

.form {
  display: grid;
  gap: var(--sp-5);
}

.field {
  display: grid;
  gap: var(--sp-2);
}

@media (min-width: 700px) {
  .form--two-col {
    grid-template-columns: 1fr 1fr;
  }

  .field--full {
    grid-column: 1 / -1;
  }
}

.label {
  font-size: var(--fs-sm);
  font-weight: 500;
}

.label .req {
  color: var(--brass-text);
  margin-left: 2px;
}

.hint {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.input,
.select,
.textarea {
  width: 100%;
  padding: 0.8rem 1rem;
  min-height: 48px;
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--bone-100);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.textarea {
  min-height: 140px;
  resize: vertical;
  line-height: var(--lh-body);
}

.select {
  appearance: none;
  padding-right: 2.75rem;
  /* Chevron drawn as an inline SVG data URI. No gradient, no image request. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%235a6068' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
}

.input:hover,
.select:hover,
.textarea:hover {
  border-color: var(--grey-300);
}

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--brass-500);
  box-shadow: 0 0 0 3px rgba(176, 139, 79, 0.22);
}

.input:disabled,
.select:disabled,
.textarea:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background: var(--bone-300);
}

.input[aria-invalid='true'],
.select[aria-invalid='true'],
.textarea[aria-invalid='true'] {
  border-color: var(--danger);
}

.input[aria-invalid='true']:focus,
.select[aria-invalid='true']:focus,
.textarea[aria-invalid='true']:focus {
  box-shadow: 0 0 0 3px rgba(168, 68, 58, 0.2);
}

.error {
  display: none;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--danger);
}

.error .icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.error[data-show='true'] {
  display: flex;
}

/* Honeypot. Hidden from people, reachable by bots. Never display:none only,
   some bots skip those, so it is moved off-screen and taken out of the tab
   order as well. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}

.form-note {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}

.form-note .icon {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 3px;
  color: var(--brass-text);
}

/* --------------------------------------------------------- 17. toasts */

/* Toasts sit bottom-LEFT so they never collide with the chat launcher, which
   owns the bottom-right corner. */
.toasts {
  position: fixed;
  left: var(--sp-5);
  bottom: var(--sp-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  width: min(calc(100vw - 2 * var(--sp-5)), 380px);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  background: var(--bone-100);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--sage-500);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  animation: toast-in var(--dur) var(--ease-out) both;
}

.toast[data-tone='success'] {
  border-left-color: var(--success);
}

.toast[data-tone='error'] {
  border-left-color: var(--danger);
}

.toast__icon {
  width: 20px;
  height: 20px;
  flex: none;
  margin-top: 2px;
  color: var(--sage-500);
}

.toast[data-tone='success'] .toast__icon {
  color: var(--success);
}

.toast[data-tone='error'] .toast__icon {
  color: var(--danger);
}

.toast__body {
  flex: 1;
  min-width: 0;
}

.toast__title {
  font-weight: 600;
  font-size: var(--fs-sm);
}

.toast__msg {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: 2px;
}

.toast__close {
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  color: var(--text-muted);
  border-radius: var(--r-sm);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.toast__close:hover {
  color: var(--text);
  background: var(--bone-300);
}

.toast__close .icon {
  width: 15px;
  height: 15px;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.toast[data-leaving='true'] {
  animation: toast-out var(--dur) var(--ease) both;
}

@keyframes toast-out {
  to {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* -------------------------------------------------------- 18. loader */

/* Masks first-paint lag. It is removed on load, and a hard timeout in JS
   removes it regardless, so it can never trap anyone. */
.loader {
  position: fixed;
  inset: 0;
  z-index: var(--z-loader);
  display: grid;
  place-items: center;
  background: var(--ink-900);
  /* Exit is a curtain lift, not a fade: the page is revealed from the top,
     the same direction the hero copy then rises in. */
  transition: transform var(--dur-exit) cubic-bezier(0.7, 0, 0.84, 0), visibility 0s linear var(--dur-exit);
}

.loader[data-done='true'] {
  transform: translateY(-100%);
  visibility: hidden;
  pointer-events: none;
}

.loader__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-5);
  animation: loader-in var(--dur-enter) var(--ease-out) both;
}

.loader[data-done='true'] .loader__inner {
  opacity: 0;
  transform: translateY(-24px);
  transition: opacity calc(var(--dur-exit) * 0.6) var(--ease), transform var(--dur-exit) var(--ease);
}

.loader__logo {
  width: min(220px, 56vw);
  height: auto;
}

@keyframes loader-in {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.96);
  }
}

.loader__bar {
  width: 140px;
  height: 2px;
  background: rgba(201, 167, 106, 0.22);
  overflow: hidden;
}

.loader__bar span {
  display: block;
  width: 40%;
  height: 100%;
  background: var(--brass-400);
  animation: load 1.1s var(--ease) infinite;
}

@keyframes load {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(350%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .loader__bar span {
    animation: none;
    width: 100%;
  }

  .loader__inner {
    animation: none;
  }
}

/* Not shown at all on repeat navigations within the session. */
html[data-loaded='true'] .loader {
  display: none;
}

/* -------------------------------------------------------- 19. footer */

.footer {
  background-color: var(--ink-900);
  color: var(--text-on-dark-muted);
  padding-top: var(--sp-8);
  padding-bottom: var(--sp-5);
  font-size: var(--fs-sm);
}

.footer__grid {
  display: grid;
  gap: var(--sp-7);
  grid-template-columns: 1fr;
  padding-bottom: var(--sp-7);
  border-bottom: 1px solid var(--border-on-dark);
}

@media (min-width: 720px) {
  .footer__grid {
    grid-template-columns: 1.6fr 1fr 1fr;
  }
}

@media (min-width: 1040px) {
  .footer__grid {
    grid-template-columns: 1.8fr 1fr 1fr 1.2fr;
  }
}

.footer__about p {
  max-width: 38ch;
  margin-top: var(--sp-4);
}

.footer h3 {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--bone-200);
  margin-bottom: var(--sp-4);
}

.footer__links {
  display: grid;
  gap: var(--sp-3);
}

.footer__links a {
  color: var(--text-on-dark-muted);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.footer__links a:hover {
  color: var(--brass-400);
}

.footer__contact {
  display: grid;
  gap: var(--sp-3);
}

.footer__contact li {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
}

.footer__contact .icon {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 4px;
  color: var(--brass-400);
}

/* The contact list is reused inside a light card on the Contact page, so the
   dark-ground colours are scoped to the footer only. */
.footer__contact a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(176, 139, 79, 0.45);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.footer__contact a:hover {
  color: var(--brass-text);
  border-bottom-color: var(--brass-500);
}

.footer .footer__contact a {
  color: var(--text-on-dark-muted);
  border-bottom-color: rgba(201, 167, 106, 0.4);
}

.footer .footer__contact a:hover {
  color: var(--brass-400);
  border-bottom-color: var(--brass-400);
}

.socials {
  display: flex;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}

.social {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  color: var(--text-on-dark-muted);
  border: 1px solid var(--border-on-dark);
  border-radius: var(--r-pill);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.social .icon {
  width: 18px;
  height: 18px;
}

.social:hover {
  color: var(--brass-400);
  border-color: var(--brass-400);
}

.social[aria-disabled='true'] {
  opacity: 0.4;
  cursor: not-allowed;
}

.social[aria-disabled='true']:hover {
  color: var(--text-on-dark-muted);
  border-color: var(--border-on-dark);
}

.footer__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-5);
  font-size: var(--fs-xs);
}

.footer__bar a {
  color: var(--text-on-dark-muted);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.footer__bar a:hover {
  color: var(--brass-400);
}

.footer__credit {
  border-bottom: 1px solid rgba(201, 167, 106, 0.35);
  padding-bottom: 1px;
}

.footer__credit:hover {
  color: var(--brass-400);
  border-bottom-color: var(--brass-400);
}

/* --------------------------------------------------------- 20. misc */

.map-frame {
  position: relative;
  aspect-ratio: 16 / 11;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-sunken);
}

.map-frame iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.accordion {
  display: grid;
  gap: var(--sp-3);
}

.acc {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-raised);
  transition: border-color var(--dur) var(--ease);
}

.acc:hover {
  border-color: var(--border-strong);
}

.acc[open] {
  border-color: var(--brass-500);
}

.acc summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-5);
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}

.acc summary::-webkit-details-marker {
  display: none;
}

.acc summary .icon {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--brass-text);
  transition: transform var(--dur) var(--ease);
}

.acc[open] summary .icon {
  transform: rotate(45deg);
}

.acc__body {
  padding: 0 var(--sp-5) var(--sp-5);
  color: var(--text-muted);
  font-size: var(--fs-sm);
  max-width: var(--measure);
}

.acc__body > * + * {
  margin-top: var(--sp-3);
}

/* Long-form legal and FAQ copy. */
/* Numbered house rules. Same flex shape as .feature-list, but the icon slot
   holds a counter instead: the sprite has no flame, hammer, or recycle symbol,
   and the numbering is what people actually reference ("rule 4"). The numbers
   match the printed poster at the venue, so keep the order. */
.rules {
  display: grid;
  gap: var(--sp-5);
  list-style: none;
  counter-reset: rule;
}

.rules li {
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
  counter-increment: rule;
}

.rules li::before {
  content: counter(rule);
  flex: none;
  min-width: 1.9em;
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-variant-numeric: tabular-nums;
  line-height: 1.35;
  color: var(--brass-text);
  border-top: 1px solid var(--border);
  padding-top: var(--sp-1);
}

.rules h3 {
  font-size: var(--fs-md);
  line-height: var(--lh-snug);
  margin-bottom: var(--sp-1);
}

.rules p {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.prose {
  max-width: var(--measure);
}

.prose > * + * {
  margin-top: var(--sp-4);
}

.prose h2 {
  font-size: var(--fs-xl);
  margin-top: var(--sp-7);
}

.prose h3 {
  margin-top: var(--sp-6);
}

.prose p,
.prose li {
  color: var(--text-muted);
}

.prose ul {
  display: grid;
  gap: var(--sp-2);
  padding-left: var(--sp-5);
  list-style: disc;
}

.prose a {
  color: var(--brass-text);
  font-weight: 500;
}

.prose strong {
  color: var(--text);
  font-weight: 600;
}

.divider {
  height: 1px;
  background: var(--border);
  border: 0;
}

.section--ink .divider {
  background: var(--border-on-dark);
}

.note-card {
  display: flex;
  gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brass-500);
  border-radius: var(--r-md);
}

.note-card .icon {
  width: 20px;
  height: 20px;
  flex: none;
  margin-top: 3px;
  color: var(--brass-text);
}

.note-card p {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.icon {
  stroke-width: 1.6;
}

/* ----------------------------------------------- 21. reveal animation */

/* The only rule that hides content. It is opt-in per element, it is removed
   the moment JS runs, and if JS never runs the no-js fallback below restores
   everything. Nothing essential can be lost. */
html.js [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
}

html.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-enter) var(--ease-out), transform var(--dur-enter) var(--ease-out);
}

/* Word masks for split headings (Hi-Fi only; main.js builds and removes them).
   Each word rises out of its own clipped line box. The padding and matching
   negative margin give descenders and italic overhang room inside the clip. */
.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding: 0.06em 0.04em 0.12em;
  margin: -0.06em -0.04em -0.12em;
}

.w__i {
  display: inline-block;
  will-change: transform;
}

/* A forward arrow nudges forward on hover: the button says where it goes. */
.btn:hover .icon:has(use[href$='#arrow-right']) {
  transform: translateX(3px);
}

/* Page to page: the browser cross-fades documents natively (no library). The
   header is named so it holds still while the page under it changes. Old page
   leaves faster than the new one arrives. Lo-Fi and reduced motion zero the
   duration tokens, which turns this into an instant swap. */
@view-transition {
  navigation: auto;
}

.header {
  view-transition-name: site-header;
}

::view-transition-old(root) {
  animation: vt-out calc(var(--dur-exit) * 0.5) var(--ease) both;
}

::view-transition-new(root) {
  animation: vt-in calc(var(--dur-enter) * 0.6) var(--ease-out) both;
}

@keyframes vt-out {
  to {
    opacity: 0;
    transform: translateY(-10px);
  }
}

@keyframes vt-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

/* Gallery filtering: tiles get a name only for the length of the swap, so a
   photo that stays visible glides to its new slot instead of blinking. */
.masonry.is-filtering .masonry__item {
  view-transition-name: var(--vt);
}

/* The brass offset frame behind framed photos reads its offset from here, so
   the scroll reveal can slide it into place. */
.media--framed {
  --frame: 18px;
}

html[data-motion='lo'] [data-reveal],
html[data-reveal-safe] [data-reveal],
html:not(.js) [data-reveal] {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal] {
    opacity: 1;
    transform: none;
  }
}

/* ------------------------------------------------------ 22. responsive */

/* 1160px, not 1040: eight links plus the logo, the motion toggle and the
   booking button measure ~1163px at the shortest sensible labels. Below
   that the bar cannot hold them, and the hamburger is a better answer than
   a squeezed row. Kept in step with the matchMedia in main.js. */
@media (max-width: 1160px) {
  /* Anchored to the header itself rather than to a fixed offset, so the panel
     stays flush when the bar condenses from 76px to 62px on scroll. */
  .nav {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    margin-left: 0;
    padding: var(--sp-5) var(--gutter) var(--sp-7);
    background: rgba(12, 16, 21, 0.98);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border-on-dark);
    transform: translateY(-120%);
    visibility: hidden;
    transition: transform var(--dur) var(--ease), visibility var(--dur) var(--ease);
  }

  .nav[data-open='true'] {
    transform: translateY(0);
    visibility: visible;
  }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .nav__link {
    padding: var(--sp-4) 0;
    font-size: var(--fs-md);
    border-bottom: 1px solid var(--border-on-dark);
  }

  .nav__link::after {
    display: none;
  }

  .nav-toggle {
    display: inline-flex;
    order: 3;
  }

  .header__actions {
    margin-left: auto;
  }

  .header__actions .btn {
    display: none;
  }

  .nav__cta {
    display: block;
    margin-top: var(--sp-5);
  }

  .nav__cta .btn {
    width: 100%;
    min-height: 48px;
    font-size: var(--fs-sm);
  }
}

@media (max-width: 620px) {
  .hero__content {
    max-width: 100%;
  }

  .hero .btn-row .btn {
    width: 100%;
  }

  .toasts {
    right: var(--sp-4);
    left: var(--sp-4);
    /* Clear the chat launcher, which sits bottom-right on mobile too. */
    bottom: calc(var(--sp-4) + 66px);
    width: auto;
  }

  .fi-toggle__btn {
    padding: 0.3rem 0.55rem;
  }

  .view__stats {
    gap: var(--sp-5);
  }
}

/* Ultrawide: the hero content must not strand itself in the far corner. */
@media (min-width: 1800px) {
  :root {
    --wrap-wide: 1720px;
  }

  /* Hold the hero copy to the left half rather than letting it drift into
     the middle of a very wide frame. */
  .hero__content {
    max-width: 56%;
  }
}

@media print {
  .header,
  .footer,
  .loader,
  .toasts,
  .hero__canvas,
  .fi-toggle {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }
}

/* ===================================================== 23. chat helper */

/* "Zia", the floating AI helper. The build includes it only on opted-in
   visitor-information pages. Kept below the lightbox and loader, above the header. */
.chat {
  position: fixed;
  right: max(var(--sp-5), env(safe-area-inset-right));
  bottom: max(var(--sp-5), env(safe-area-inset-bottom));
  z-index: 190;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-3);
}

/* The whole widget stays hidden until chat.js is ready. A class rule beats the
   bare [hidden] UA rule, so
   this has to be stated explicitly. */
.chat[hidden] {
  display: none !important;
}

/* Never a nuisance: step out of the way when the mobile menu or the lightbox
   is open. :has is well supported in current browsers; where it is not, the
   chat simply stays, which is harmless. */
body:has(#nav[data-open='true']) .chat,
body:has(#lightbox[data-open='true']) .chat {
  display: none;
}

/* ---- launcher ---- */
.chat__launcher {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 54px;
  padding: 0 1.15rem;
  background: var(--brass-500);
  color: var(--ink-900);
  border: 1px solid var(--brass-500);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-lg);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) var(--ease), transform var(--dur-fast) var(--ease);
}

.chat__launcher:hover {
  background: var(--brass-400);
}

.chat__launcher:active {
  transform: translateY(1px);
}

.chat__launcher:focus-visible,
.chat__send:focus-visible,
.chat__faq button:focus-visible,
.chat__action-link:focus-visible,
.chat__crisis-actions a:focus-visible {
  outline: 3px solid var(--sage-400);
  outline-offset: 3px;
}

.chat__launcher .icon {
  width: 22px;
  height: 22px;
  flex: none;
}

.chat__ico-close {
  display: none;
}

.chat[data-open='true'] .chat__ico-open {
  display: none;
}

.chat[data-open='true'] .chat__ico-close {
  display: block;
}

.chat[data-open='true'] .chat__launcher-label {
  display: none;
}

.chat[data-open='true'] .chat__launcher {
  width: 54px;
  padding: 0;
  justify-content: center;
}

/* ---- panel ---- */
/* Visibility is driven ONLY by the launcher state, so the panel is closed by
   default and opens when .chat[data-open="true"]. This is the fix for the
   panel being stuck open: a bare [hidden] attribute could not beat the class
   rule below, so display is now controlled by the data-open state instead. */
.chat__panel {
  position: relative;
  display: none;
  width: min(370px, calc(100vw - 2 * var(--sp-5)));
  height: min(560px, calc(100dvh - 7rem));
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  overscroll-behavior: contain;
  transform-origin: bottom right;
}

.chat__skeleton {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 2;
  flex-direction: column;
  background: var(--bg-raised);
}

.chat__panel[data-loading='cold'] > :not(.chat__skeleton) {
  visibility: hidden;
}

.chat__panel[data-loading='cold'] .chat__skeleton {
  display: flex;
}

.chat__skeleton-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 67px;
  padding: var(--sp-4) var(--sp-5);
  background: var(--ink-800);
}

.chat__skeleton-avatar,
.chat__skeleton-title,
.chat__skeleton-log span,
.chat__skeleton-composer {
  display: block;
  background: var(--grey-300);
  animation: chat-skeleton-pulse 900ms var(--ease) infinite alternate;
}

.chat__skeleton-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(232, 226, 214, 0.24);
}

.chat__skeleton-title {
  width: 112px;
  height: 13px;
  border-radius: var(--r-pill);
  background: rgba(232, 226, 214, 0.3);
}

.chat__skeleton-log {
  flex: 1;
  padding: var(--sp-5);
  background: var(--bg-sunken);
}

.chat__skeleton-log span {
  width: 78%;
  height: 42px;
  margin-bottom: var(--sp-3);
  border-radius: var(--r-md);
}

.chat__skeleton-log span:nth-child(2) {
  width: 58%;
  margin-left: auto;
  animation-delay: 120ms;
}

.chat__skeleton-log span:nth-child(3) {
  width: 68%;
  animation-delay: 240ms;
}

.chat__skeleton-composer {
  height: 46px;
  margin: var(--sp-3);
  border-radius: var(--r-md);
}

@keyframes chat-skeleton-pulse {
  from { opacity: 0.45; }
  to { opacity: 0.9; }
}

.chat[data-open='true'] .chat__panel {
  display: flex;
  animation: chat-in var(--dur) var(--ease-out);
}

@keyframes chat-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .chat__panel { animation: none; }
}

.chat__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  background: var(--ink-800);
  color: var(--bone-100);
  flex: none;
}

.chat__avatar {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: var(--r-pill);
  background: rgba(201, 167, 106, 0.16);
  color: var(--brass-400);
}

.chat__avatar .icon {
  width: 18px;
  height: 18px;
}

.chat__head-text {
  flex: 1;
  min-width: 0;
}

.chat__title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  line-height: 1.1;
  color: var(--bone-100);
}

.chat__sub {
  font-size: var(--fs-xs);
  color: var(--text-on-dark-muted);
  margin-top: 1px;
}

/* ---- log ---- */
.chat__log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  background: var(--bg-sunken);
  scrollbar-width: thin;
}

.chat__log:focus-visible {
  outline: 3px solid var(--sage-400);
  outline-offset: -3px;
}

.chat__msg {
  max-width: 85%;
  padding: 0.62rem 0.85rem;
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.chat__msg--zia {
  align-self: flex-start;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  color: var(--text);
  border-bottom-left-radius: 3px;
}

.chat__msg--you {
  align-self: flex-end;
  background: var(--brass-500);
  color: var(--ink-900);
  border-bottom-right-radius: 3px;
}

/* typing dots */
.chat__msg--typing {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}

.chat__msg--typing span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--grey-500);
  animation: chat-dot 1s var(--ease) infinite;
}

.chat__msg--typing span:nth-child(2) { animation-delay: 0.15s; }
.chat__msg--typing span:nth-child(3) { animation-delay: 0.3s; }

@keyframes chat-dot {
  0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

@media (prefers-reduced-motion: reduce) {
  .chat__msg--typing span,
  .chat__skeleton-avatar,
  .chat__skeleton-title,
  .chat__skeleton-log span,
  .chat__skeleton-composer { animation: none; opacity: 0.65; }
}

/* ---- trusted actions and common questions ---- */
.chat__faq {
  flex: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-sunken);
  border-top: 1px solid var(--border);
}

.chat__faq[hidden] {
  display: none;
}

.chat__faq button {
  min-height: 44px;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--bg-raised);
  color: var(--text);
  font-size: 0.72rem;
  line-height: 1.25;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.chat__faq button:hover {
  border-color: var(--brass-500);
  background: var(--bone-100);
}

.chat__action,
.chat__crisis-actions {
  align-self: flex-start;
}

.chat__action-link,
.chat__crisis-actions a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.52rem 0.75rem;
  border: 1px solid var(--brass-500);
  border-radius: var(--r-pill);
  color: var(--brass-text);
  background: var(--bg-raised);
  font-size: var(--fs-xs);
  font-weight: 600;
  text-decoration: none;
}

.chat__crisis-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* ---- form ---- */
.chat__form {
  flex: none;
  display: block;
  padding: var(--sp-3) var(--sp-3) var(--sp-2);
  background: var(--bg-raised);
  border-top: 1px solid var(--border);
  position: relative;
}

.chat__composer {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-2);
  min-width: 0;
}

.chat__turnstile {
  position: absolute;
  inset: auto 0 100%;
  display: flex;
  justify-content: center;
}

.chat__input {
  flex: 1;
  width: 100%;
  min-width: 0;
  min-height: 44px;
  resize: none;
  max-height: 104px;
  padding: 0.68rem 0.78rem;
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--text);
  background: var(--bone-100);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.chat__input::placeholder {
  color: var(--grey-600);
  opacity: 1;
  white-space: normal;
}

.chat__input:focus {
  outline: none;
  border-color: var(--brass-500);
  box-shadow: 0 0 0 3px rgba(176, 139, 79, 0.22);
}

.chat__input:disabled {
  opacity: 0.7;
}

.chat__send {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: var(--brass-500);
  color: var(--ink-900);
  border-radius: var(--r-md);
  transition: background var(--dur) var(--ease);
}

.chat__send:hover {
  background: var(--brass-400);
}

.chat__send:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.chat__send .icon {
  width: 18px;
  height: 18px;
}

/* ---- note ---- */
.chat__note {
  flex: none;
  padding: var(--sp-2) var(--sp-4) var(--sp-3);
  font-size: 0.68rem;
  line-height: 1.42;
  color: var(--text-muted);
  background: var(--bg-raised);
}

.chat__note a {
  color: var(--brass-text);
  font-weight: 500;
}

@media (max-width: 620px) {
  .chat {
    right: max(var(--sp-4), env(safe-area-inset-right));
    bottom: max(var(--sp-4), env(safe-area-inset-bottom));
  }

  /* Circle-only launcher on small screens to save room. */
  .chat__launcher-label {
    display: none;
  }

  .chat__launcher {
    width: 54px;
    padding: 0;
    justify-content: center;
  }

  .chat__panel {
    width: min(390px, calc(100vw - 2 * var(--sp-4)));
    height: min(75dvh, calc(var(--zia-viewport-height, 100dvh) - 5.5rem - env(safe-area-inset-bottom)));
    border-radius: var(--r-md);
  }

  .chat__head {
    padding: var(--sp-3) var(--sp-4);
  }

  .chat__log {
    padding: var(--sp-3);
  }

  .chat__msg {
    max-width: 90%;
  }
}

@media (max-width: 350px) {
  .chat {
    right: max(var(--sp-3), env(safe-area-inset-right));
    bottom: max(var(--sp-3), env(safe-area-inset-bottom));
  }

  .chat__panel {
    width: calc(100vw - 2 * var(--sp-3));
  }

  .chat__faq {
    gap: 4px;
    padding-inline: var(--sp-2);
  }

  .chat__faq button {
    padding-inline: 0.45rem;
    font-size: 0.68rem;
  }

  .chat__note {
    padding-inline: var(--sp-3);
    font-size: 0.64rem;
  }
}
