/* ─────────────────────────────────────────────────────────────
   ABRALUNA ARCHIVES · archive.css
   The institution's hand. Inherited by every room.
   Two voices only. Two scales only. Darkness as material.
   ───────────────────────────────────────────────────────────── */

:root {
  /* — Palette. Never pure black; never pure white. Aged. — */
  --void:        #040404;   /* the dark of the building        */
  --void-deep:   #000000;   /* the dark beneath the dark        */
  --bone:        #ece7dd;   /* the white of the caps, aged      */
  --bone-dim:    #b9b4a9;
  --ash:         #6f6d67;   /* the grey of the glyphs           */
  --ash-faint:   #3a3936;
  --moon:        #cfd6dc;   /* cold light. never depicted.      */

  /* — The two voices — */
  --voice-inscription: "Didot", "Bodoni 72", "Bodoni MT",
                        "Big Caslon", "Playfair Display", Georgia, serif;
  --voice-institution: "Helvetica Neue", "Inter", "Arial", sans-serif;

  /* — Cadence. Nothing moves quickly here. — */
  --breath:   1200ms;
  --settle:   2400ms;
  --ease:     cubic-bezier(0.22, 0.61, 0.36, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  background: var(--void-deep);
  color: var(--bone);
  font-family: var(--voice-inscription);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

/* ── The two scales. Monumental, and near-invisible. Nothing between. ── */

.inscription {
  font-family: var(--voice-inscription);
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1.05;
}

.institution {
  font-family: var(--voice-institution);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.34em;
  font-size: 0.66rem;
  color: var(--bone-dim);
}

/* ── Grain. The surface of a real building, whispered. ── */
.grain {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.045;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ═══════════════════════════════════════════════════════════════
   THE THRESHOLD · Cls. 0 · the point of becoming a holding
   ═══════════════════════════════════════════════════════════════ */

.threshold {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(2.6rem, 6vh, 4.6rem);
  cursor: default;
}

/* The cold, off-center light of the building. Felt, never drawn.
   Moonlight as the quality of the light — not an image of the moon. */
.threshold::before {
  content: "";
  position: fixed;
  inset: -20%;
  z-index: 0;
  background:
    radial-gradient(38vmax 38vmax at 62% 30%,
      color-mix(in srgb, var(--moon) 9%, transparent) 0%,
      transparent 62%);
  opacity: 0;
  transition: opacity var(--settle) var(--ease);
}
.threshold.awake::before { opacity: 1; }

/* Attention is the only light. Where the visitor looks, the dark yields. */
.attention {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--settle) var(--ease);
  background:
    radial-gradient(26vmax 26vmax at var(--mx, 50%) var(--my, 50%),
      color-mix(in srgb, var(--moon) 7%, transparent) 0%,
      transparent 60%);
}
.threshold.awake .attention { opacity: 1; }

/* ── The inscription that resolves out of the dark ── */
.threshold__word {
  position: relative;
  z-index: 3;
  text-align: center;
  padding: 0 8vw;
}

.threshold__name {
  font-size: clamp(3.4rem, 12vw, 9rem);
  color: var(--bone);
  opacity: 0;
  transform: translateY(0.4rem);
  transition: opacity var(--settle) var(--ease),
              transform var(--settle) var(--ease);
  text-shadow: 0 0 60px color-mix(in srgb, var(--moon) 14%, transparent);
}

.threshold__note {
  display: block;
  margin-top: 2.4rem;
  opacity: 0;
  transition: opacity var(--settle) var(--ease) 600ms;
}

.threshold.spoken .threshold__name { opacity: 1; transform: none; }
.threshold.spoken .threshold__note { opacity: 1; }

/* ── The door. It stands in the dark and opens slowly onto the light.
      Arched — like the entries in the archive's own wall. Approach it
      and it breathes ajar; cross it and it swings fully open. ── */
/* Dust in moonlight, drawn on canvas. Behind the door; above the dark.
   It fades in only once ignited — after the visitor has landed. */
.motes {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 2200ms var(--ease);
}
.motes.lit { opacity: 1; }

.portal {
  position: relative;
  z-index: 2;              /* the door stands above the drifting dust */
  width: clamp(118px, 13vw, 184px);
  height: clamp(228px, 38vh, 396px);
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
  perspective: 1500px;
  opacity: 0;
  transition: opacity var(--settle) var(--ease);
}
.threshold.open .portal { opacity: 1; }

.portal__void,
.portal__panel {
  position: absolute;
  inset: 0;
  border-radius: 48% 48% 5px 5px / 30% 30% 1% 1%;
}

/* A breathing halo behind the door — alive, and brighter as you near. */
.portal::after {
  content: "";
  position: absolute;
  inset: -18%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(58% 58% at 50% 52%,
    color-mix(in srgb, var(--moon) calc(7% + var(--near, 0) * 20%), transparent) 0%,
    transparent 70%);
  animation: breathe 5600ms var(--ease) infinite;
}

/* the light that glows within the door — cool silver moonlight, never
   white. It swells as the door breathes open, sinks as it closes. */
.portal__void {
  background:
    radial-gradient(110% 82% at 50% 42%,
      color-mix(in srgb, var(--moon) 68%, transparent) 0%,
      color-mix(in srgb, var(--moon) 30%, transparent) 46%,
      transparent 78%);
  opacity: 0.12;
  animation: beckonLight 5200ms var(--ease) infinite;
  transition: opacity 900ms var(--ease);
}

/* the door itself — a dark slab, edged with a faint rim of light. On its
   own it breathes ajar and eases shut, over and over: an invitation. */
.portal__panel {
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--bone) 5%, var(--void)) 0%,
    var(--void-deep) 70%);
  border: 1px solid color-mix(in srgb, var(--bone) 12%, transparent);
  box-shadow:
    inset 0 0 46px rgba(0, 0, 0, 0.85),
    0 0 calc(20px + var(--near, 0) * 34px)
        color-mix(in srgb, var(--moon) calc(8% + var(--near, 0) * 24%), transparent);
  transform-origin: left center;
  transform: rotateY(-3deg);
  animation: beckon 5200ms var(--ease) infinite;
  transition: box-shadow 500ms var(--ease);
  backface-visibility: hidden;
}

/* light spilling from beneath the door, pooling on the floor */
.portal__spill {
  position: absolute;
  left: 50%;
  bottom: -7%;
  width: 190%;
  height: 64px;
  transform: translateX(-50%) scaleX(1);
  background: radial-gradient(50% 100% at 50% 0%,
    color-mix(in srgb, var(--moon) calc(30% + var(--near, 0) * 30%), transparent) 0%,
    transparent 72%);
  filter: blur(7px);
  opacity: calc(0.4 + var(--near, 0) * 0.55);
  pointer-events: none;
  animation: pool 5600ms var(--ease) infinite;
}

.portal:focus-visible { outline: none; }

/* the crossing — the door continues its swing (driven from JS, so it
   picks up from wherever it is) and its cool light fills the doorway. */
.portal.opening .portal__panel {
  animation: none;
}
.portal.opening .portal__void {
  animation: none;
  opacity: 0.9;
}

/* the door's slow invitation: ajar, then shut, then ajar again */
@keyframes beckon {
  0%, 100% { transform: rotateY(-3deg);  }
  50%      { transform: rotateY(-26deg); }
}
/* the light within, swelling as the door opens and sinking as it shuts */
@keyframes beckonLight {
  0%, 100% { opacity: 0.12; }
  50%      { opacity: 0.55; }
}

@keyframes breathe {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1;   }
}
@keyframes pool {
  0%, 100% { transform: translateX(-50%) scaleX(0.92); }
  50%      { transform: translateX(-50%) scaleX(1.06); }
}

/* ── The crossing fades into darkness, not light — into the dark of
      the room beyond. Never white. ── */
.rite__flood {
  position: fixed;
  inset: 0;
  z-index: 11;
  pointer-events: none;
  background: var(--void-deep);
  opacity: 0;
  visibility: hidden;
  transition: opacity 1700ms var(--ease);
}
.rite__flood.flood { opacity: 1; visibility: visible; }

/* ── Recognition. Shown only to those the archive already holds. ── */
.threshold__note--returned { color: var(--bone-dim); }

/* ── Restraint for those who ask for stillness ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 300ms !important;
    animation: none !important;
  }
  .attention { display: none; }
  /* With animations switched off (iPhone "Reduce Motion", some battery
     savers), nothing may wait on an animation to become visible: the black
     arrival cover would never lift — the page stays pitch black — and titles
     that fade in would never appear. So the cover is simply not there, and
     what fades in is simply shown. */
  .enter { display: none !important; }
  .holding, .sheet__head, .wall__head, .studio-note__trigger, .mark { opacity: 1 !important; }
  .hint { opacity: .78 !important; }
}
