/* Sonic_Gio: page shell layout. Phase 2. */

html, body {
  height: 100%;
}

body {
  position: relative;
  min-height: 100dvh;
  overflow: hidden;
}

/* Layers, back to front */
.embers,
#embers,
.veil,
.app {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100dvh;
}

.embers {
  background: var(--embers);
  z-index: 0;
}

#embers {
  z-index: 0;
  opacity: 0;
  transition: opacity 1.2s ease;
  pointer-events: none;
}

#embers.is-on {
  opacity: 1;
}

.veil {
  z-index: 0;
  background: var(--veil-page);
  pointer-events: none;
  transition: background var(--t-view) ease;
}

html[data-view="home"] .veil { background: var(--veil-home); }
html[data-view="play"] .veil { background: var(--veil-play); }

/* Photos: the DJ, top right, emerging from the dark on Home (a short clip, then its last frame),
   Info and Mission; Listen has none (no second picture). One panel per view, above the veil, with
   its own soft mask, so the rest of the page is untouched and body text never sits on a bright
   area (the suite samples the pixels under every text run). Phones: the panel spans the width
   under the header, dimmer, behind the title only. */
.photos {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.photo {
  --photo-opacity: .55;
  --photo-w: clamp(520px, 52vw, 1600px);
  --photo-max-h: 340px;
  position: absolute;
  top: 0;
  right: 0;
  /* The panel scales with the browser: 52% of the viewport width on every view. Its height is
     16:9 up to a cap, so on wide screens it becomes a wide band and the photo is cropped to its
     upper part (object-position): Listen and Info keep their list and form clear below 340px,
     Home has room down to half the height. The height is computed here, not left to
     aspect-ratio + max-height, which WebKit resolves by shrinking the width instead. */
  width: var(--photo-w);
  height: min(calc(var(--photo-w) * 9 / 16), var(--photo-max-h));
  opacity: 0;
  transition: opacity var(--t-view) ease;
  /* The mask reaches zero before every edge of the panel, so the photo is never cut */
  -webkit-mask-image: radial-gradient(58% 60% at 56% 45%, #000 18%, transparent 72%);
  mask-image: radial-gradient(58% 60% at 56% 45%, #000 18%, transparent 72%);
}

.photo--home {
  --photo-max-h: 48vh;
}

/* Info: a large image behind the letter, which sits on a frosted sheet (css/views.css .letter) */
.photo--info {
  --photo-max-h: 56vh;
  --photo-opacity: .62;
}

/* Mission's text never goes past 960px from the left, so its panel takes the whole free right
   side, from the header to the bottom bar, and the photo fills it (cropped around the figure) */
.photo--mission {
  --photo-w: clamp(340px, calc(100vw - 960px), 1600px);
  top: 66px;
  bottom: 72px;
  height: auto;
}

.photo--mission .photo__img {
  object-position: 50% 35%;
}

.photo__img,
.photo__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 18%; /* when the band is cropped, keep the head in it */
}

html[data-view="home"] .photo--home,
html[data-view="info"] .photo--info,
html[data-view="mission"] .photo--mission {
  opacity: var(--photo-opacity);
}

/* Home: the poster shows first; the clip fades in while it plays; its last frame holds */
.photo__video,
.photo__end {
  opacity: 0;
  transition: opacity .6s ease;
}

.photo--home.is-playing .photo__video {
  opacity: 1;
}

.photo--home.is-ended .photo__end {
  opacity: 1;
}

@media (max-width: 760px) {
  .photo,
  .photo--mission {
    --photo-opacity: .22;
    --photo-w: 100vw;
    --photo-max-h: 9999px; /* no cap: the full 16:9 band */
    top: 66px; /* under the header */
    bottom: auto;
    height: min(calc(var(--photo-w) * 9 / 16), var(--photo-max-h));
  }
}

.app {
  z-index: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Header */
.site-header {
  flex: none;
  display: flex;
  justify-content: center;
  padding: 14px 24px 8px;
  background: linear-gradient(to bottom, rgba(18, 16, 14, .8) 50px, transparent);
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  min-height: 44px;
  padding: 0 .3em;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(17px, 1.9vw, 22px);
  letter-spacing: .22em;
  color: var(--cream);
  text-decoration: none;
}

.logo:hover {
  color: var(--cream);
}

.logo__word--gio {
  color: var(--orange-hover);
}

.logo__heart {
  width: 26px;
  height: 23px;
  flex: none;
  fill: none;
  stroke: var(--orange);
  stroke-width: 2.6;
  stroke-linejoin: round;
  stroke-linecap: round;
  transform-origin: 50% 55%;
  filter: drop-shadow(0 0 5px var(--glow)); /* the still glow; also the reduced-motion state */
  animation: heartbeat 3.2s ease-in-out infinite;
}

/* One beat: it swells, the glow widens, and the stroke warms from orange through the
   GIO yellow to cream at the peak, then back. Subtle, 3.2 s per cycle. */
@keyframes heartbeat {
  0%, 100% { transform: scale(1); stroke: var(--orange); filter: drop-shadow(0 0 4px rgba(232, 96, 28, .55)); }
  25%, 75% { stroke: var(--orange-hover); }
  50% { transform: scale(1.07); stroke: var(--cream); filter: drop-shadow(0 0 9px rgba(232, 96, 28, .9)); }
}

/* Main and views */
main {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
}

.view {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
}

/* With JavaScript, only the current view shows */
html.js .view {
  display: none;
}

html.js .view.is-current {
  display: flex;
}

/* The Play view is never display:none: it is laid out out of sight and hidden from assistive
   tech. (The SoundCloud widget iframe used to live here; it now sits in #sc-slot, below.) */
html.js .view--play:not(.is-current) {
  display: flex;
  position: absolute;
  inset: 0;
  visibility: hidden;
  pointer-events: none;
}

html.js .view.is-entering {
  animation: view-in var(--t-view) ease both;
}

@keyframes view-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Without JavaScript, views stack and the page scrolls */
html:not(.js) body { overflow: auto; }
html:not(.js) .app { position: relative; height: auto; min-height: 100dvh; }
html:not(.js) .embers,
html:not(.js) .veil { position: fixed; }
html:not(.js) .view { overflow: visible; padding-bottom: 48px; }

/* Bottom bar */
.bottom-bar {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 6px clamp(12px, 5vw, 56px) 8px;
  padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line-soft);
  background: rgba(18, 16, 14, .86);
}

.mini-player-slot {
  flex: 0 1 560px;
  min-width: 0;
}

.mini-player-slot:empty {
  min-height: 48px;
}

.mini-player-slot[hidden] {
  display: block;
  visibility: hidden;
  min-height: 48px;
}

/* Instagram link: takes the mini player's spot on the Listen and Play views.
   The logo and the handle, centred on each other, no underline. */
.bottom-bar__ig {
  display: none;
  align-items: center;
  gap: 9px;
  flex: 0 1 560px;
  min-width: 0;
  min-height: 48px;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  color: var(--cream);
  text-decoration: none;
}

.bottom-bar__ig span {
  display: block;
  line-height: 1;
  padding-top: 1px; /* optical: the x-height sits a hair low against the glyph's centre */
}

.bottom-bar__ig:hover {
  color: var(--orange-hover);
}

/* Small logos next to link words (Instagram, SoundCloud) */
.ico {
  flex: none;
  width: 18px;
  height: 18px;
}

.bottom-bar__ig .ico {
  width: 20px;
  height: 20px;
}

html[data-view="play"] .bottom-bar__ig,
html[data-view="listen"] .bottom-bar__ig {
  display: inline-flex;
}

html[data-view="play"] .mini-player-slot,
html[data-view="listen"] .mini-player-slot {
  display: none;
}

/* The SoundCloud widget iframe: laid out with a real size, out of sight. The widget breaks
   inside display:none (canvas of width 0), so this slot hides with visibility only. */
.sc-slot {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 320px;
  height: 20px;
  visibility: hidden;
  pointer-events: none;
  z-index: 0;
}

.sc-slot[hidden] {
  display: none; /* only before the iframe exists */
}

.sc-widget {
  width: 100%;
  height: 20px;
  border: 0;
}

.menu {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}

.menu__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 8px;
  font-size: var(--fs-menu);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--menu-tracking);
  color: var(--cream);
  text-decoration: none;
  text-underline-offset: 6px;
  text-decoration-thickness: 2px;
}

.menu__link:hover {
  color: var(--orange-hover);
}

.menu__link[aria-current="page"] {
  text-decoration: underline;
  text-decoration-color: var(--orange);
}

@media (max-width: 760px) {
  .bottom-bar {
    justify-content: center;
  }

  .mini-player-slot {
    flex: 1 1 100%;
  }

  /* The player row keeps its space on every view, so the bar never jumps */
  .mini-player-slot:empty,
  .mini-player-slot[hidden] {
    display: block;
    visibility: hidden;
    min-height: 48px;
  }

  html[data-view="play"] .mini-player-slot,
  html[data-view="listen"] .mini-player-slot {
    display: none;
  }

  /* On the Listen and Play views the Instagram link is that row, left-aligned */
  .bottom-bar__ig {
    flex: 1 1 100%;
    justify-content: flex-start;
  }

  .menu {
    margin-left: 0;
    justify-content: center;
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .logo__heart {
    animation: none;
  }

  html.js .view.is-entering {
    animation: none;
  }

  .veil,
  #embers {
    transition: none;
  }
}
