/* =========================================================
   HIDDEN KEY MOTION — FIRST-VISIT ENTRANCE (state layer)
   Owns only state-dependent presentation: layering, open/exit
   states, poster/video/reveal crossfades, hero handoff.
   Core owns the panel, fields and typography.
   Transform + opacity only — no animated blur/filter.
   ========================================================= */

.hk-entry {
  position: fixed;
  inset: 0;
  z-index: 2147483001;
  display: grid;
  /* Desktop: door ~60%, form ~40%. */
  grid-template-columns: 60fr 40fr;
  align-items: center;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;
  min-height: var(--hk-entry-vh, 100dvh);
  background: #070505;
  opacity: 1;
  transition: opacity .5s ease;
  contain: layout paint;
  overscroll-behavior: none;
  touch-action: none;
}

.hk-entry.is-complete {
  opacity: 0;
  pointer-events: none;
}


/* Returning visitors replay the full-screen movie without reopening the form. */
.hk-entry.is-returning-visitor { display: block; }
.hk-entry.is-returning-visitor .hk-entry-side { display: none; }
.hk-entry.is-returning-visitor .hk-entry-scrim {
  opacity: .18;
  background: linear-gradient(180deg, rgba(5, 3, 3, .12), rgba(5, 3, 3, .3));
}

.hk-entry.is-webkit {
  contain: layout;
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
}

.hk-entry.is-webkit .hk-entry-video {
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
  -webkit-perspective: 1000;
  perspective: 1000px;
}
.hk-entry.is-webkit .hk-entry-poster,
.hk-entry.is-webkit .hk-entry-reveal-img {
  -webkit-transform: translate3d(0, 0, 1px);
  transform: translate3d(0, 0, 1px);
}

/* ---------- Stage (door / video / reveal) ---------- */
.hk-entry-stage {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.hk-entry-poster,
.hk-entry-reveal-img {
  position: absolute;
  inset: 0;
  display: block;
}

.hk-entry-poster img,
.hk-entry-reveal-img,
.hk-entry-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Poster, video and reveal share identical fit so nothing shifts. */
  object-fit: cover;
  object-position: center center;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
}

.hk-entry-poster {
  z-index: 2;
  opacity: 1;
  transition: opacity .55s ease, transform .95s cubic-bezier(.2,.8,.2,1);
}

.hk-entry-video {
  z-index: 1;
  /* Keep media fully present to WebKit. The poster covers it visually until
     real playback starts, instead of hiding the video with near-zero opacity. */
  opacity: 1;
  visibility: visible;
  pointer-events: none;
  transition: opacity .45s ease;
}

.hk-entry-video::-webkit-media-controls,
.hk-entry-video::-webkit-media-controls-panel,
.hk-entry-video::-webkit-media-controls-start-playback-button {
  display: none !important;
  -webkit-appearance: none;
}

.hk-entry-reveal-img {
  z-index: 3;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform: translateZ(0) scale(1.018);
  transition: opacity .65s ease, transform 1s cubic-bezier(.2,.8,.2,1);
}

/* Hard access gate. While the form has not been successfully submitted,
   no media/reveal frame may become visible even if a browser starts a
   preloaded video element independently. */
.hk-entry.is-access-locked .hk-entry-poster {
  opacity: 1 !important;
  transform: translateZ(0) scale(1) !important;
}
.hk-entry.is-access-locked .hk-entry-video,
.hk-entry.is-access-locked .hk-entry-reveal-img {
  opacity: 0 !important;
}

/* Poster → video crossfade. */
.hk-entry.is-video-active .hk-entry-video { opacity: 1; }
.hk-entry.is-video-active .hk-entry-poster { opacity: 0; pointer-events: none; }

/* Reveal arms underneath during the final frames, then takes over. */
.hk-entry.is-reveal-armed .hk-entry-reveal-img { opacity: 1; }
.hk-entry.is-reveal-active .hk-entry-reveal-img { opacity: 1; transform: translateZ(0) scale(1); }
.hk-entry.is-reveal-active .hk-entry-video,
.hk-entry.is-hero-handoff .hk-entry-video,
.hk-entry.is-complete .hk-entry-video { opacity: 0; }
.hk-entry.is-reveal-active .hk-entry-poster { opacity: 0; }

/* Automatic iPhone/Safari fallback: the visitor still gets deliberate motion
   instead of a player prompt or a frozen door. */
.hk-entry.is-media-fallback .hk-entry-poster {
  opacity: 0;
  transform: translateZ(0) scale(1.035);
}
.hk-entry.is-media-fallback .hk-entry-reveal-img {
  opacity: 1;
  transform: translateZ(0) scale(1);
}
.hk-entry.is-media-fallback .hk-entry-scrim { opacity: .04; }

/*
 * Reveal → homepage handoff.
 *
 * The last frame stays FULLY VISIBLE and the entire entrance layer fades out
 * over the homepage instead. Because the hero background is the same file with
 * the same treatment, this is a single invisible cross-dissolve.
 *
 * Fading the reveal itself (the previous approach) exposed the entrance root's
 * opaque #070505 background for half a second — a black flash between the
 * lounge and the homepage.
 */
.hk-entry.is-hero-handoff {
  opacity: 0;
  transition: opacity .75s cubic-bezier(.3, 0, .3, 1);
}

.hk-entry.is-hero-handoff .hk-entry-reveal-img { opacity: 1; }

/* The form-side scrim clears while the last frame is still held, so the
   composition matches the hero before the dissolve begins. */
.hk-entry.is-reveal-active .hk-entry-scrim,
.hk-entry.is-hero-handoff .hk-entry-scrim { opacity: 0; }

.hk-entry-scrim {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 1;
  background:
    linear-gradient(90deg, rgba(5, 3, 3, .18) 0%, rgba(5, 3, 3, .55) 52%, rgba(5, 3, 3, .88) 100%);
  transition: opacity .5s ease;
}


/* ---------- Persistent video buffering / autoplay unlock ---------- */
.hk-entry-buffer {
  position: absolute;
  left: 50%;
  bottom: max(78px, calc(env(safe-area-inset-bottom) + 70px));
  z-index: 9;
  display: none;
  align-items: center;
  gap: 11px;
  min-height: 44px;
  max-width: calc(100% - 32px);
  padding: 11px 17px;
  border: 1px solid rgba(226, 170, 76, .36);
  border-radius: 999px;
  color: #f7dfae;
  background: linear-gradient(180deg, rgba(28, 13, 16, .94), rgba(10, 6, 7, .96));
  box-shadow: 0 18px 44px rgba(0,0,0,.38), inset 0 0 0 1px rgba(255,225,160,.08);
  transform: translateX(-50%);
  font-family: Inter, ui-sans-serif, sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  line-height: 1.3;
  text-align: center;
  text-transform: uppercase;
}
.hk-entry-buffer__spinner { display: none; }

@keyframes hk-entry-buffer-spin { to { transform: rotate(360deg); } }

/* ---------- Form side ---------- */
.hk-entry-side {
  position: relative;
  z-index: 6;
  grid-column: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  height: 100svh;
  height: var(--hk-entry-vh, 100dvh);
  padding: clamp(20px, 2.4vw, 48px);
}

.hk-entry-panel {
  opacity: 0;
  transform: translate3d(28px, 0, 0);
  transition: opacity .6s cubic-bezier(.2, .8, .2, 1), transform .6s cubic-bezier(.2, .8, .2, 1);
}

.hk-entry.is-open .hk-entry-panel {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* Submission: fields lock visually. */
.hk-entry.is-submitting .hk-entry-form { pointer-events: none; }
.hk-entry.is-submitting .gform_wrapper { opacity: .82; transition: opacity .25s ease; }

/* Unlock: the key lifts, then the panel clears the door. */
.hk-entry.is-unlocking .hkm-key-submit,
.hk-entry.is-unlocking .gform_button {
  transform: translateY(-2px) scale(1.02);
  box-shadow: 0 20px 46px rgba(0, 0, 0, .5), 0 0 44px rgba(242, 198, 111, .5);
}

.hk-entry.is-form-gone .hk-entry-panel {
  opacity: 0;
  transform: translate3d(34px, 0, 0);
  pointer-events: none;
}
.hk-entry.is-form-gone .hk-entry-scrim { opacity: .45; }

/* ---------- Skip control ---------- */

/* =========================================================
   MOBILE — portrait composition, never a squeezed desktop
   ========================================================= */
@media (max-width: 1024px) {
  .hk-entry {
    display: block;
    /* Follow the visual viewport on iOS. `--hk-entry-vh` is already keyboard
       reduced, so the keyboard height must never be subtracted a second time. */
    inset: auto 0 auto 0;
    top: var(--hk-entry-vv-top, 0px);
    width: 100%;
    touch-action: pan-y;
    height: 100vh;
    height: 100svh;
    height: var(--hk-entry-vh, 100dvh);
  }

  .hk-entry-stage { position: fixed; inset: 0; }

  .hk-entry-scrim {
    background: linear-gradient(180deg, rgba(5, 3, 3, .35) 0%, rgba(5, 3, 3, .62) 42%, rgba(5, 3, 3, .92) 100%);
  }

  .hk-entry-side {
    position: relative;
    grid-column: auto;
    width: 100%;
    height: 100%;
    align-items: flex-end;
    padding:
      max(10px, env(safe-area-inset-top)) 14px
      max(12px, env(safe-area-inset-bottom)) 14px;
    transition: padding .2s ease;
  }

  .hk-entry-panel {
    width: min(560px, 100%);
    margin-inline: auto;
    /* One subtraction only: spacing around the actual visible viewport. */
    max-height: calc(var(--hk-entry-vh, 100dvh) - 24px);
    transform: translate3d(0, 28px, 0);
  }

  .hk-entry.is-open .hk-entry-panel { transform: translate3d(0, 0, 0); }
  .hk-entry.is-form-gone .hk-entry-panel { transform: translate3d(0, 34px, 0); }

  .hk-entry-panel__scroll {
    max-height: 100%;
    touch-action: pan-y;
    scroll-padding-block: 14px 92px;
  }

  /* Keyboard mode becomes a compact, nearly full-height sheet. This keeps the
     focused field and sticky submit in the visual viewport instead of forcing
     the visitor to fight Safari's keyboard + browser chrome. */
  .hk-entry.is-keyboard-open .hk-entry-side {
    align-items: flex-start;
    padding: 4px 8px max(4px, env(safe-area-inset-bottom));
  }
  .hk-entry.is-keyboard-open .hk-entry-panel {
    width: 100%;
    max-height: calc(var(--hk-entry-vh, 100dvh) - 8px);
    border-radius: 16px;
  }
  .hk-entry.is-keyboard-open .hk-entry-panel__logo,
  .hk-entry.is-keyboard-open .hk-entry-panel__intro,
  .hk-entry.is-keyboard-open .hk-entry-panel__secure { display: none; }
  .hk-entry.is-keyboard-open .hk-entry-panel__title {
    margin-bottom: 8px;
    font-size: 20px;
    line-height: 1.05;
  }

  .hk-entry-buffer {
    bottom: calc(max(72px, env(safe-area-inset-bottom) + 66px));
    width: max-content;
    max-width: calc(100vw - 36px);
  }
}

/* Landscape phones: compact scrollable layout, never a cropped door. */
@media (max-width: 1024px) and (orientation: landscape) and (max-height: 560px) {
  .hk-entry-side { align-items: center; padding: 4px 8px; }
  .hk-entry-panel { max-height: calc(var(--hk-entry-vh, 100dvh) - 8px); }
  .hk-entry-panel__logo,
  .hk-entry-panel__intro { display: none; }
}

/* =========================================================
   HOMEPAGE COVER / HANDOFF
   ========================================================= */
html.hk-entry-required body > *:not(.hk-entry):not(#hk-site-header) {
  /* The homepage is present but visually covered and inert. */
  visibility: hidden;
}
html.hk-entry-required #hk-site-header { opacity: 0; pointer-events: none; }

/*
 * Staggered handoff. hk-entry-handoff makes the homepage visible (hero banner
 * image) while the video's last frame is still held over it. hk-entry-hero-in
 * then brings the hero text, header and reservation form in on their own
 * timelines. The reveal only fades after this, so nothing is ever caught
 * half-built.
 */
html.hk-entry-handoff body > *:not(.hk-entry) { visibility: visible; }

/* Step 1: hero banner image only — copy and chrome still held back. */
html.hk-entry-handoff #hk-site-header { opacity: 0; pointer-events: none; }
html.hk-entry-handoff #hk-homepage .hk-hero-copy,
html.hk-entry-handoff #hk-homepage .hk-reservation-card,
html.hk-entry-handoff #hk-homepage .hk-hero-benefits,
html.hk-entry-handoff #hk-homepage .hk-trust-strip {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}

/* Step 2: hero text, reservation form and header enter, each on its own delay. */
html.hk-entry-hero-in #hk-site-header {
  opacity: 1;
  pointer-events: auto;
  transition: opacity .75s ease .34s;
}
html.hk-entry-hero-in #hk-homepage .hk-hero-copy,
html.hk-entry-hero-in #hk-homepage .hk-reservation-card,
html.hk-entry-hero-in #hk-homepage .hk-hero-benefits,
html.hk-entry-hero-in #hk-homepage .hk-trust-strip {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity .8s cubic-bezier(.2, .8, .2, 1), transform .8s cubic-bezier(.2, .8, .2, 1);
}
html.hk-entry-hero-in #hk-homepage .hk-hero-copy { transition-delay: .06s; }
html.hk-entry-hero-in #hk-homepage .hk-reservation-card { transition-delay: .2s; }
html.hk-entry-hero-in #hk-homepage .hk-hero-benefits { transition-delay: .32s; }
html.hk-entry-hero-in #hk-homepage .hk-trust-strip { transition-delay: .42s; }

/* Completed: clear every temporary state so nothing is left inline. */
html.hk-entry-complete body > * { visibility: visible; }
html.hk-entry-complete #hk-homepage .hk-hero-copy,
html.hk-entry-complete #hk-homepage .hk-reservation-card,
html.hk-entry-complete #hk-homepage .hk-hero-benefits,
html.hk-entry-complete #hk-homepage .hk-trust-strip {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html.hk-entry-hero-in #hk-homepage .hk-hero-copy,
  html.hk-entry-hero-in #hk-homepage .hk-reservation-card,
  html.hk-entry-hero-in #hk-homepage .hk-hero-benefits,
  html.hk-entry-hero-in #hk-homepage .hk-trust-strip {
    transform: none;
    transition-delay: 0s;
  }
}

/* =========================================================
   REDUCED MOTION
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  .hk-entry,
  .hk-entry-panel,
  .hk-entry-poster,
  .hk-entry-video,
  .hk-entry-reveal-img,
  .hk-entry-scrim {
    transition-duration: .18s !important;
  }
  .hk-entry-panel { transform: none !important; }
}

/* =========================================================
   PRELOADER
   In the first parsed HTML so the visitor never sees a blank
   or black screen while the poster decodes, Gravity Forms
   renders and the video buffers.
   ========================================================= */
.hk-entry-loader {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 24px;
  background:
    radial-gradient(circle at 50% 42%, rgba(86, 20, 28, .42), transparent 58%),
    linear-gradient(180deg, #0a0607 0%, #070505 100%);
  opacity: 1;
  transition: opacity .55s ease;
}

.hk-entry-loader__logo {
  width: auto;
  height: clamp(46px, 5.2vw, 72px);
  object-fit: contain;
  animation: hk-entry-loader-breathe 3.2s ease-in-out infinite;
}

.hk-entry-loader__track {
  position: relative;
  display: block;
  width: min(210px, 54vw);
  height: 2px;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(201, 156, 67, .2);
}

.hk-entry-loader__bar {
  position: absolute;
  inset: 0 auto 0 0;
  display: block;
  width: 12%;
  border-radius: 2px;
  background: linear-gradient(90deg, #77501d, #f2c66f, #fff0c5);
  box-shadow: 0 0 14px rgba(242, 198, 111, .55);
  transition: width .45s cubic-bezier(.2, .8, .2, 1);
}

.hk-entry-loader__label {
  color: #cfc1b2;
  font-family: Inter, ui-sans-serif, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  text-align: center;
}

/* Released once the form is interactive. */
.hk-entry.is-loaded .hk-entry-loader {
  opacity: 0;
  pointer-events: none;
}

@keyframes hk-entry-loader-breathe {
  0%, 100% { opacity: .78; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.035); }
}

@media (prefers-reduced-motion: reduce) {
  .hk-entry-loader__logo,
  .hk-entry-buffer__spinner { animation: none; }
}

/* =========================================================
   HERO COVER
   A solid layer that stays behind the reveal image and only
   fades once the homepage hero is painted AND the scroll
   position is confirmed at the top. Guarantees the visitor
   never sees a partially-loaded page or a mid-page section.
   ========================================================= */
.hk-entry-herocover {
  position: fixed;
  inset: 0;
  z-index: 2147482999;
  pointer-events: none;
  opacity: 0;
  background: #070505;
  transition: opacity .5s ease;
}

html.hk-entry-settling .hk-entry-herocover { opacity: 1; }

/* =========================================================
   SEAMLESS HERO MATCH
   The homepage hero applies its own treatment to the same image
   (saturate .9 / contrast 1.08 / brightness .82, inset -2%,
   scale 1.02). The entrance video and reveal are untreated, so a
   straight crossfade would visibly "pop" in brightness and scale
   at the exact handoff moment.

   The reveal therefore starts untreated — matching the video's
   final frame perfectly — and eases into the hero's treatment
   during the handoff, so both layers are identical by the time
   the crossfade happens.
   ========================================================= */
.hk-entry-reveal-img {
  filter: none;
  transform: scale(1);
  transition:
    opacity .5s ease,
    filter .75s cubic-bezier(.2, .8, .2, 1),
    transform .75s cubic-bezier(.2, .8, .2, 1);
}

html.hk-entry-handoff .hk-entry-reveal-img {
  /* Matches #hk-homepage .hk-hero-visual img exactly. */
  filter: saturate(.9) contrast(1.08) brightness(.82);
  transform: scale(1.02);
}

@media (max-width: 1024px) {
  html.hk-entry-handoff .hk-entry-reveal-img {
    /* Mobile hero uses the same treatment at a smaller crop. */
    transform: scale(1.01);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hk-entry-reveal-img { transition-duration: .2s; }
}

/* =========================================================
   NO-POSTER FALLBACK
   If the entrance media has not been uploaded yet, the stage
   must still look deliberate. Previously a missing poster left
   an empty src, which paints a broken-image icon on black.
   ========================================================= */
.hk-entry-stage.is-no-poster {
  background:
    radial-gradient(ellipse at 50% 38%, rgba(120, 26, 36, .55), transparent 62%),
    radial-gradient(circle at 50% 100%, rgba(201, 156, 67, .16), transparent 55%),
    linear-gradient(180deg, #0d0709 0%, #070505 60%, #050303 100%);
}

.hk-entry-stage.is-no-poster::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, transparent 42%, rgba(201, 156, 67, .07) 50%, transparent 58%);
}

/* =========================================================
   REVEAL → HERO MORPH
   The last frame is clipped from full-bleed down to the hero
   card's exact rect and radius before the layers cross, so
   the two never swap between different shapes.
   ========================================================= */
.hk-entry-reveal-img {
  -webkit-clip-path: inset(0px 0px 0px 0px round 0px);
  clip-path: inset(0px 0px 0px 0px round 0px);
}

.hk-entry.is-morphing .hk-entry-reveal-img {
  will-change: -webkit-clip-path, clip-path, transform, filter;
}

/*
 * As the frame clips inward, whatever sits behind it becomes visible. The
 * entrance root has an opaque background, which would show as black around the
 * shrinking image — so from the moment the homepage is revealed underneath,
 * the entrance's own backgrounds go transparent and the real page shows
 * through instead. The lounge then appears to settle into the hero frame.
 */
html.hk-entry-handoff .hk-entry,
html.hk-entry-handoff .hk-entry-stage.is-no-poster {
  background: transparent;
}

html.hk-entry-handoff .hk-entry-poster,
html.hk-entry-handoff .hk-entry-scrim {
  opacity: 0;
}

/* The dissolve is short: by this point both layers are geometrically identical. */
.hk-entry.is-hero-handoff {
  transition: opacity .45s ease;
}

@media (prefers-reduced-motion: reduce) {
  .hk-entry.is-morphing .hk-entry-reveal-img { will-change: auto; }
}

/* =========================================================
   INNER-PAGE HANDOFF
   The entrance runs on any landing page. The staggered rules
   above target homepage blocks; on other pages the controller
   marks its chosen blocks instead, so the reveal still runs
   when GSAP is unavailable (phones without GSAP, reduced data).
   ========================================================= */
html.hk-entry-handoff [data-hk-entry-target] {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}

html.hk-entry-hero-in [data-hk-entry-target] {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity .8s cubic-bezier(.2, .8, .2, 1), transform .8s cubic-bezier(.2, .8, .2, 1);
}

html.hk-entry-hero-in [data-hk-entry-target="1"] { transition-delay: .06s; }
html.hk-entry-hero-in [data-hk-entry-target="2"] { transition-delay: .18s; }
html.hk-entry-hero-in [data-hk-entry-target="3"] { transition-delay: .3s; }
html.hk-entry-hero-in [data-hk-entry-target="4"] { transition-delay: .42s; }

html.hk-entry-complete [data-hk-entry-target] {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html.hk-entry-hero-in [data-hk-entry-target] {
    transform: none;
    transition-delay: 0s;
  }
}

/* =========================================================
   SILENT BUFFER STATUS
   Visitors never read internal diagnostics. With no message
   the pill collapses to a quiet spinner; wording appears only
   media diagnostics remain hidden from visitors.
   ========================================================= */
.hk-entry.is-status-silent [data-hk-entry-buffer-text],
.hk-entry.is-status-silent .hk-entry-buffer__text {
  display: none;
}

.hk-entry.is-status-silent .hk-entry-buffer,
.hk-entry.is-status-silent [data-hk-entry-buffer] {
  gap: 0;
  padding: 12px;
  border-radius: 999px;
}

/* =========================================================
   SLOW FORM
   A configured form that has not rendered yet. The door stays
   shut; the visitor gets an honest message instead of a silent
   spinner (and is never let through automatically).
   ========================================================= */
.hk-entry.is-form-slow .hk-entry-form::after {
  content: "Preparing your access form…";
  display: block;
  padding: 18px 4px 4px;
  color: var(--hke-ivory-muted, #cfc1b2);
  font-size: 13px;
  text-align: center;
}

.hk-entry.is-form-slow .hk-entry-form:has(.gform_wrapper form)::after {
  content: none;
}

/* v1.7.7: no visitor-facing media controls or buffering UI. */
.hk-entry [data-hk-entry-buffer] { display: none !important; }
