/* ==================================================
   frankie.co — responsive homepage stage contract
   Keeps the living F, its navigation, the walking character,
   the fixed header, and the audio bars inside one safe viewport.
   ================================================== */

:root {
  /* Preserve the full-size audio field on tall desktop screens. */
  --home-audio-h: clamp(92px, 17svh, 160px);

  /* The Hello navigation sits slightly above the SVG silhouette, so the
     stage needs more than the visible header height as top clearance. */
  --home-stage-top-safe: max(calc(env(safe-area-inset-top, 0px) + 84px), 8.5svh);

  /* Contact hangs close to the bottom of the F. Keep a real visual gutter
     above the audio field instead of allowing the label to disappear in it. */
  --home-stage-bottom-safe: calc(
    var(--home-audio-h) +
    max(24px, 2.5svh) +
    env(safe-area-inset-bottom, 0px)
  );

  /* The character stays readable on a laptop without becoming oversized
     on a large monitor. Mobile and short-landscape overrides live below. */
  --char-w: clamp(42px, 5vmin, 52px);
}

.audio-bars {
  height: var(--home-audio-h);
}

/* Height drives the desktop/laptop stage. The 100:160 aspect ratio then
   calculates the width automatically, so a shorter browser can never crop
   the top or bottom of the F. Auto block margins center the stage between
   the protected header and audio regions. */
.stage {
  left: 50%;
  top: var(--home-stage-top-safe);
  bottom: var(--home-stage-bottom-safe);
  width: auto;
  height: min(
    calc(100svh - var(--home-stage-top-safe) - var(--home-stage-bottom-safe)),
    800px
  );
  max-width: none;
  margin-block: auto;
  transform: translateX(-50%);
}

/* MacBook-class and other compact-height desktop windows need a shorter
   audio field so the logo remains substantial rather than being squeezed. */
@media (min-width: 641px) and (max-height: 980px) {
  :root {
    --home-audio-h: clamp(78px, 12.5svh, 122px);
    --char-w: clamp(42px, 5.2vmin, 50px);
  }
}

/* Keep the established desktop panel behavior while removing the old
   vertical translate that assumed the stage was centered on the full page. */
@media (min-width: 880px) {
  .panel.open ~ main.stage,
  body:has(.panel.open) .stage {
    transform: translateX(calc(-50% - 210px));
  }
}

/* Phones remain width-driven. This preserves the strong mobile scale that
   already worked, while centering the complete F inside the safe vertical
   area and maintaining space above the sound bars. */
@media (max-width: 640px) {
  :root {
    --home-audio-h: clamp(64px, 10svh, 92px);
    --home-stage-top-safe: max(calc(env(safe-area-inset-top, 0px) + 68px), 72px);
    --home-stage-bottom-safe: calc(
      var(--home-audio-h) +
      24px +
      env(safe-area-inset-bottom, 0px)
    );
    --char-w: clamp(34px, 9.4vw, 40px);
  }

  .stage {
    width: min(76vw, 340px);
    height: auto;
    max-height: calc(100svh - var(--home-stage-top-safe) - var(--home-stage-bottom-safe));
  }
}

/* Very short landscape screens require a separate height-driven mode.
   This prevents the character from becoming larger than the F itself and
   keeps both navigation extremes reachable without browser-edge clipping. */
@media (max-height: 600px) and (orientation: landscape) {
  :root {
    --home-audio-h: clamp(54px, 10svh, 72px);
    --home-stage-top-safe: max(calc(env(safe-area-inset-top, 0px) + 54px), 58px);
    --home-stage-bottom-safe: calc(
      var(--home-audio-h) +
      18px +
      env(safe-area-inset-bottom, 0px)
    );
    --char-w: clamp(28px, 7.2svh, 36px);
  }

  .stage {
    width: auto;
    height: min(
      calc(100svh - var(--home-stage-top-safe) - var(--home-stage-bottom-safe)),
      360px
    );
    max-height: none;
  }
}

/* Large desktops retain presence without letting the character balloon. */
@media (min-width: 1600px) and (min-height: 1000px) {
  :root {
    --char-w: clamp(48px, 3.5vmin, 54px);
  }
}

/* ==================================================
   FIRST-PAINT ENTRANCE SEQUENCE
   The production HTML loads this stylesheet in <head>, so the browser never
   paints the character on top of the logo before the deferred walking engine
   moves it to the drop position. The existing drop remains the only character
   entrance; these states only reveal it at the correct moment.
   ================================================== */
html:not(.fc-home-logo-revealing):not(.fc-home-logo-ready):not(.fc-home-character-entering):not(.fc-home-entry-ready):not(.from-inside) .big-f,
html:not(.fc-home-logo-revealing):not(.fc-home-logo-ready):not(.fc-home-character-entering):not(.fc-home-entry-ready):not(.from-inside) .character,
html:not(.fc-home-logo-revealing):not(.fc-home-logo-ready):not(.fc-home-character-entering):not(.fc-home-entry-ready):not(.from-inside) .hotspot,
html:not(.fc-home-logo-revealing):not(.fc-home-logo-ready):not(.fc-home-character-entering):not(.fc-home-entry-ready):not(.from-inside) .inside-hotspot {
  opacity: 0 !important;
  visibility: hidden !important;
}

html:not(.fc-home-entry-ready):not(.from-inside) .stage {
  pointer-events: none;
}

html.fc-home-logo-revealing .big-f {
  visibility: visible !important;
  animation: fc-home-logo-fade-in 820ms cubic-bezier(.22,.7,.2,1) both;
}

html.fc-home-logo-revealing .character,
html.fc-home-logo-ready .character,
html.fc-home-logo-revealing .hotspot,
html.fc-home-logo-ready .hotspot,
html.fc-home-logo-revealing .inside-hotspot,
html.fc-home-logo-ready .inside-hotspot {
  opacity: 0 !important;
  visibility: hidden !important;
}

html.fc-home-logo-ready .big-f,
html.fc-home-character-entering .big-f,
html.fc-home-entry-ready .big-f {
  opacity: 1 !important;
  visibility: visible !important;
}

html.fc-home-character-entering .character,
html.fc-home-entry-ready .character {
  opacity: 1 !important;
  visibility: visible !important;
}

html.fc-home-character-entering .character {
  animation: fc-home-character-appear 160ms ease-out both;
}

html.fc-home-character-entering .hotspot,
html.fc-home-character-entering .inside-hotspot {
  opacity: 0 !important;
  visibility: hidden !important;
}

html.fc-home-entry-ready .hotspot,
html.fc-home-entry-ready .inside-hotspot {
  visibility: visible !important;
  animation: fc-home-controls-fade-in 360ms ease-out both;
}

/* The outgoing page is covered instead of repositioning the character.
   This prevents transformed-stage coordinate recalculation from creating a
   visible left-edge jump during refresh or navigation teardown. */
html.fc-home-unloading .stage {
  pointer-events: none !important;
}

html.fc-home-unloading .character {
  opacity: 0 !important;
  visibility: hidden !important;
  transition: none !important;
}

html.fc-home-unloading body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 2147483647;
  background: var(--paper);
  opacity: 1;
  pointer-events: auto;
}

@keyframes fc-home-logo-fade-in {
  from { opacity: 0; filter: blur(5px); }
  to { opacity: 1; filter: blur(0); }
}

@keyframes fc-home-character-appear {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fc-home-controls-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  html.fc-home-logo-revealing .big-f,
  html.fc-home-character-entering .character,
  html.fc-home-entry-ready .hotspot,
  html.fc-home-entry-ready .inside-hotspot {
    animation: none !important;
  }
}

/* Production refresh marker: 2026-07-13 / homepage-entry-sequence-c */
