/* ---------- Center stack: name, portrait, verse ---------- */
.center-stack {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(0.9rem, 2.4vh, 1.6rem);
  /* bottom padding clears the action buttons even on short windows */
  padding: 2vh 1rem max(16vh, 122px);
  pointer-events: none;
}

.masthead {
  flex-shrink: 0;
  text-align: center;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.9), 0 0 6px rgba(0, 0, 0, 0.8);
}

.masthead .pre {
  font-style: italic;
  font-size: 0.9rem;
  letter-spacing: 0.18em;
  color: var(--ink-dim);
}

.masthead h1 {
  font-size: clamp(1.5rem, 4.5vw, 2.5rem);
  font-weight: normal;
  letter-spacing: 0.06em;
  color: #eceef0;
  margin: 0.3rem 0 0.35rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
}

.rank {
  height: 1.3em;
  width: auto;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.7));
}

.rank[hidden] { display: none; }

.masthead .dates {
  font-size: 0.95rem;
  letter-spacing: 0.06em;   /* spoken dates, not a serial number — gentle tracking */
  color: var(--ink-dim);
}

.masthead .unit {
  margin-top: 0.25rem;
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  color: var(--ink-faint);
}

/* Portrait — the flexible element: on short windows the photo shrinks (never
   the buttons' clearance), so it can't collide with the actions bar. */
.portrait {
  pointer-events: auto;
  cursor: pointer;
  flex: 0 1 clamp(220px, 42vh, 480px);
  min-height: 130px;
  display: flex;
  justify-content: center;
}

/* The portrait is a doorway: the framed photo swings open toward you on a left
   hinge, and beyond it the stairwell stands at a distance. The scene holds the
   3D perspective and the sizing the frame used to own; the frame is the leaf. */
.portrait-scene {
  position: relative;
  height: 100%;
  aspect-ratio: 4 / 5;
  max-width: 82vw;
  perspective: 1500px;
  perspective-origin: 50% 45%;
}

/* The offering bowl at the portrait's foot — a quiet link for supporting the
   family. It sits beside the door, not on it, so it holds its place while the
   portrait swings open. Hidden until boot.js fills the href (server-fed, like
   the name — the destination never appears in the public files). */
.offering-bowl {
  position: absolute;
  left: -7%;
  bottom: -2%;
  width: 26%;
  z-index: 3;
  filter: drop-shadow(0 7px 12px rgba(0, 0, 0, 0.55));
  transition: transform 0.25s ease, filter 0.25s ease, opacity 0.35s ease;
}
.offering-bowl[hidden] { display: none; }
/* Steps aside with the rest of the chrome while any full-screen layer is up
   (compose, viewer, lightbox, placement, the climb) — modes.js toggles it. */
.offering-bowl.chrome-hidden { opacity: 0; pointer-events: none; }
.offering-bowl img { width: 100%; display: block; }
.offering-bowl:hover, .offering-bowl:focus-visible {
  transform: translateY(-3px);
  filter: drop-shadow(0 9px 15px rgba(0, 0, 0, 0.6))
          drop-shadow(0 0 14px rgba(255, 205, 120, 0.4));
}

/* the door slab: a real 3D box with thickness, hinged on the left. The frame
   is now just the pivoting box; the faces below give it its front, back and
   sides. --door-thick is how deep the slab is. */
.frame {
  position: absolute;
  inset: 0;
  --door-thick: 22px;
  transform-origin: left center;                 /* the hinge */
  transform: rotateY(0deg);
  transform-style: preserve-3d;
  transition: transform 1.2s cubic-bezier(0.34, 0.02, 0.2, 1);
  will-change: transform;
}

/* the face you see at rest — his photo in a beveled slate molding. The inset
   highlight (top-left) and shadow (bottom-right) shape the molding's profile;
   the photo sits recessed inside it. */
.door-front {
  position: absolute;
  inset: 0;
  border-radius: 3px;
  background: linear-gradient(158deg, #3d3f45 0%, #232529 55%, #2e3036 100%);
  box-shadow:
    inset 1.6px 1.6px 2px rgba(255, 255, 255, 0.14),   /* molding highlight (raised) */
    inset -2px -2px 4px rgba(0, 0, 0, 0.5),             /* molding shadow */
    inset 0 0 0 1px rgba(0, 0, 0, 0.28),                /* thin outer line */
    0 16px 40px rgba(0, 0, 0, 0.62);                    /* the portrait floats off the vigil */
  backface-visibility: hidden;
}

/* the inlay: a recessed liner around the photo so it sits deeper in the frame.
   Its dark floor shows as a thin band between the molding and the photo, and the
   shadow at the top-left inner edge reads as the wall of the recess. */
.door-front::before {
  content: '';
  position: absolute;
  inset: 8%;
  border-radius: 2px;
  pointer-events: none;
  background: linear-gradient(150deg, #212329, #14151a);
  box-shadow:
    inset 3px 4px 7px rgba(0, 0, 0, 0.72),           /* the recess wall, top-left */
    inset -2px -2px 4px rgba(255, 255, 255, 0.05),   /* faint light on the far wall */
    0 0 0 1px rgba(255, 255, 255, 0.05);             /* a lit lip where the molding steps down */
}

/* the dark backing of the framed photo, one thickness behind the front */
.door-back {
  position: absolute;
  inset: 0;
  border-radius: 3px;
  background: linear-gradient(160deg, #202127, #141519);
  transform: translateZ(calc(-1 * var(--door-thick)));
}

/* the four sides connect front to back — the visible thickness as it swings */
.door-edge { position: absolute; background: linear-gradient(150deg, #3c3e44, #202128); }
.edge-right  { top: 0; bottom: 0; right: 0; width: var(--door-thick);
  transform-origin: right center;  transform: rotateY(-90deg); }
.edge-left   { top: 0; bottom: 0; left: 0;  width: var(--door-thick);
  transform-origin: left center;   transform: rotateY(90deg); }
.edge-top    { left: 0; right: 0; top: 0;    height: var(--door-thick);
  transform-origin: center top;    transform: rotateX(-90deg); }
.edge-bottom { left: 0; right: 0; bottom: 0; height: var(--door-thick);
  transform-origin: center bottom; transform: rotateX(90deg); }

/* Read swings the door fully open — a whole 180°, so the leaf folds right out
   of the doorway (to the left of the hinge) and leaves the opening clear. */
#portrait.opening .frame { transform: rotateY(-180deg); }

.frame img {
  /* recessed 10% inside the molding (the rabbet) */
  position: absolute;
  top: 10%; left: 10%;
  width: 80%; height: 80%;
  object-fit: cover;
  /* crop anchored near the top: portraits keep the head, whatever the photo's shape */
  object-position: 50% 12%;
  display: block;
  background: #101114;
  border-radius: 1px;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.6),            /* thin dark line at the photo's edge */
    inset 3px 4px 9px rgba(0, 0, 0, 0.55);   /* deep: the photo sits at the bottom of the recess */
  /* fade in once the portrait has decoded, rather than popping in */
  opacity: 0;
  transition: opacity 0.7s ease;
}

.frame img.loaded { opacity: 1; }

.portrait-fallback {
  position: absolute;
  inset: 10%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  background: linear-gradient(to bottom, #1d1f24, #141519);
  border: 1px solid rgba(0, 0, 0, 0.6);
}

.portrait-fallback[hidden] { display: none; }

.fallback-cross { font-size: 3rem; color: #8b8f96; opacity: 0.9; }

.fallback-note {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  text-align: center;
  line-height: 1.5;
}

.frame-hint {
  position: absolute;
  left: 10%; right: 10%; bottom: 10%;
  padding: 0.5rem 0;
  text-align: center;
  font-size: 0.74rem;
  font-style: italic;
  letter-spacing: 0.1em;
  color: var(--ink);
  background: linear-gradient(to top, rgba(8, 9, 11, 0.85), rgba(8, 9, 11, 0));
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.portrait:hover .frame-hint, .portrait:focus-visible .frame-hint { opacity: 1; }

.verse {
  flex-shrink: 0;
  max-width: min(560px, 88vw);
  text-align: center;
  font-style: italic;
  font-size: clamp(0.74rem, 1.7vw, 0.9rem);
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.95), 0 0 4px rgba(0, 0, 0, 0.85), 0 0 14px rgba(0, 0, 0, 0.6);
}

