/* vishome.css — page 8 lower half, Vis's home (js/sections/vishome.js). */

/* the curtain is the page colour; only its shadow separates it from the house */
.vishome {
  --curtain-shadow-1: rgb(0 0 0 / 0.95);
  --curtain-shadow-2: rgb(0 0 0 / 0.75);
}

:root[data-theme='light'] .vishome {
  --curtain-shadow-1: rgb(0 0 0 / 0.38);
  --curtain-shadow-2: rgb(0 0 0 / 0.22);
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) .vishome {
    --curtain-shadow-1: rgb(0 0 0 / 0.38);
    --curtain-shadow-2: rgb(0 0 0 / 0.22);
  }
}

.vishome__pin {
  height: 260vh;
}

.vishome__stage {
  --reveal: 0;
}

/* ── curtain ── */

.vishome__curtain {
  position: absolute;
  inset: 0 0 -8% 0;
  z-index: 6;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 18px;
  padding-inline: var(--gutter);
  text-align: center;
  color: var(--fg);
  /* The shape is drawn by ::before (clip-path would clip a box-shadow), and
     drop-shadow on this element follows that slanted shape: a tight dark
     contact shadow plus a deep, wide one, stacked so the curtain reads as a
     thick sheet hanging above the house. */
  filter: drop-shadow(0 10px 8px var(--curtain-shadow-1)) drop-shadow(0 44px 46px var(--curtain-shadow-2));
  will-change: transform;
}

.vishome__curtain::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--bg);
  /* slanted lower edge: higher on the left, lower on the right */
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 72%);
}

.vishome__title {
  font-size: clamp(40px, 6vw, 104px);
  background: linear-gradient(100deg, var(--fg) 0%, var(--fg) 40%, var(--fg-faint) 52%, var(--fg) 64%, var(--fg-muted) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  will-change: transform;
}

.vishome__lede {
  max-width: 56ch;
  color: var(--fg-muted);
  font-size: clamp(14px, 1.15vw, 18px);
  will-change: transform;
}

/* ── scene + danmaku layers: back bubbles · canvas · front bubbles ── */

.vishome__scene {
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: calc(0.2 + var(--reveal) * 0.8);
}

.vishome__gl {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.vishome__loading {
  position: absolute;
  left: 50%;
  top: 58%;
  transform: translateX(-50%);
  color: var(--fg-faint);
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  animation: vh-pulse 1.6s ease-in-out infinite;
}

@keyframes vh-pulse {
  50% {
    opacity: 0.35;
  }
}

.vishome__scene.is-fallback {
  background: url('/assets/shots/vis-home-overview.webp') center / contain no-repeat;
}

.vishome__danmaku {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: var(--reveal);
}

.vishome__danmaku--back {
  z-index: 1;
}

.vishome__danmaku--front {
  z-index: 3;
}

.dm {
  position: absolute;
  left: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  white-space: nowrap;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  will-change: transform;
}

.dm--l {
  animation-name: dm-left;
}

.dm--r {
  animation-name: dm-right;
}

@keyframes dm-left {
  from {
    transform: translateX(100vw);
  }

  to {
    transform: translateX(-100%);
  }
}

@keyframes dm-right {
  from {
    transform: translateX(-100%);
  }

  to {
    transform: translateX(100vw);
  }
}

.dm__avatar {
  flex: none;
  width: 52px;
  height: auto;
}

.dm__text {
  position: relative;
  padding: 8px 18px;
  border-radius: 6px;
  background: #fff;
  color: #222;
  font-size: 22px;
  line-height: 1.25;
}

/* speech-bubble tail pointing at the avatar */
.dm__text::before {
  content: '';
  position: absolute;
  left: -7px;
  top: 50%;
  border: 7px solid transparent;
  border-left: 0;
  border-right-color: inherit;
  border-right-color: #fff;
  transform: translateY(-50%);
}

.dm--back {
  opacity: 0.45;
  filter: blur(1.6px);
}

.dm--back .dm__avatar {
  width: 36px;
}

.dm--back .dm__text {
  padding: 4px 14px;
  font-size: 16px;
  background: #6b6b70;
  color: #e4e4e7;
}

.dm--back .dm__text::before {
  border-right-color: #6b6b70;
}

/* ── dial ── */

.vishome__dial {
  --night: 0;
  position: absolute;
  z-index: 4;
  right: clamp(16px, 5vw, 96px);
  top: 50%;
  width: clamp(110px, 11vw, 176px);
  aspect-ratio: 1;
  transform: translateY(-50%);
  touch-action: none;
  cursor: grab;
  opacity: var(--reveal);
  color: var(--fg);
  border-radius: 50%;
}

.vishome__dial.is-dragging {
  cursor: grabbing;
}

.dial__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/*
 * The ring is a still day↔night gradient — bright at the lower left where day
 * sits, dim at the upper right where night does — and it does not change with
 * the time: the knob is the only thing that moves. (It used to grow a brighter
 * arc on the travelled side — `.dial__fill`, since removed — which read as two
 * different rings.)
 *
 * The stroke *is* that gradient, set inline by vishome.js, so there is
 * deliberately no `stroke` here — a declaration in this file would win over it.
 */
.dial__track {
  stroke-width: 2.5;
}

.dial__ring--day {
  stop-color: currentColor;
  stop-opacity: 1;
}

.dial__ring--night {
  stop-color: currentColor;
  stop-opacity: 0.2;
}

/* the hole punched in the band, so the knob rides clear of it */
.dial__gap {
  fill: #000;
}

/*
 * The knob rides on the ring, with the gap above keeping it clear of the band.
 * Both radii are in viewBox units (see R/KNOB in vishome.js), so the gap holds
 * at every dial size. The knob's size is deliberately not animated on hover —
 * growing it would close that gap; the glow carries the hover instead.
 */
.dial__knob {
  fill: currentColor;
  filter: drop-shadow(0 0 6px color-mix(in srgb, currentColor 60%, transparent));
}

.vishome__dial:hover .dial__knob,
.vishome__dial:focus-visible .dial__knob {
  filter: drop-shadow(0 0 11px currentColor);
}

/* sun ↔ moon: a dark disc slides over the sun to bite out a crescent */
.dial__icon {
  position: absolute;
  inset: 28%;
}

.dial__icon svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.dial__sun {
  fill: currentColor;
  transform-origin: 12px 12px;
  transform: scale(calc(1 + var(--night) * 0.55));
}

.dial__rays {
  stroke: currentColor;
  stroke-width: 1.6;
  transform-origin: 12px 12px;
  opacity: calc(1 - var(--night) * 2);
  transform: rotate(calc(var(--night) * 90deg)) scale(calc(1 - var(--night) * 0.4));
}

.dial__bite {
  fill: var(--bg);
  transform: translate(calc(14px - var(--night) * 9px), calc(var(--night) * -3.2px)) scale(calc(0.6 + var(--night) * 0.75));
  transform-origin: 12px 12px;
  opacity: calc(var(--night) * 1.6);
}

.dial__label {
  position: absolute;
  left: 50%;
  top: 100%;
  margin-top: 10px;
  transform: translateX(-50%);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

/* ── notes ── */

.vishome__notes {
  display: grid;
  gap: clamp(72px, 16vh, 180px);
  max-width: 980px;
  padding-block: clamp(80px, 14vh, 160px);
}

.vis-note {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.8s ease, transform 1s var(--ease-brand);
}

.vis-note.is-in {
  opacity: 1;
  transform: none;
}

.vis-note__title {
  margin-bottom: 18px;
  font-size: clamp(20px, 1.8vw, 26px);
  font-weight: 600;
}

html:not(.js) .vis-note {
  opacity: 1;
  transform: none;
}

html:not(.js) .vishome__pin {
  height: auto;
}

html:not(.js) .vishome__stage {
  position: static;
  height: auto;
}

html:not(.js) .vishome__curtain {
  position: static;
  clip-path: none;
  padding-block: 120px;
}

@media (max-width: 720px) {
  .dm__text {
    font-size: 15px;
    padding: 6px 12px;
  }

  .dm__avatar {
    width: 36px;
  }

  .vishome__dial {
    top: auto;
    bottom: 64px;
    transform: none;
    width: 110px;
  }
}
