/* ── Chrome ─────────────────────────────────────────────────────────────
   Everything that is not the room itself: the mark, the depth meter, the
   affordance that says "there is further in", and the skip link.
   All of it sits above the copy layer.
*/

/* Visible to screen readers only. The depth rungs are 2px lines — they
   need a real label that assistive tech can read. */
.sr-only{
  position:absolute;
  width:1px; height:1px;
  margin:-1px; padding:0;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}

/* ── Skip link — first tab stop, for keyboard and screen readers ────── */
.skip{
  position:absolute; z-index:20;
  inset-inline-start:var(--pad);
  inset-block-start:-100px;
  padding:10px 16px;
  border-radius:var(--r-row);
  background:var(--accent);
  color:var(--accent-ink);
  font-family:var(--font-mono);
  font-size:12px;
  transition:inset-block-start .15s ease;
}
.skip:focus{inset-block-start:var(--pad)}

/* ── The mark ───────────────────────────────────────────────────────── */
.mark{
  position:absolute; z-index:10;
  inset-block-start:var(--pad);
  inset-inline-start:var(--pad);
  display:flex; align-items:center; gap:9px;
  font-family:var(--font-mono);
  font-size:11px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--ink-2);
}
.mark .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none}

/* ── Depth meter ────────────────────────────────────────────────────────
   Real links to real pages, not buttons: this is how the other five rooms
   are discovered by crawlers, and how the site stays navigable with
   JavaScript off. app.js intercepts the clicks to play the transition.   */
.depth{
  position:absolute; z-index:10;
  inset-block-start:50%;
  inset-inline-end:var(--pad);
  transform:translateY(-50%);
}
.depth ul{
  display:grid; gap:14px;
  margin:0; padding:0;
  list-style:none;
}
.depth a{
  display:block;
  width:44px; height:44px;   /* touch target — iron rule #6 */
  position:relative;
}
/* The visible rung is drawn inside the 44px target, not instead of it.
   It is sized once at its longest and scaled down, rather than animating
   width: same picture on a 2px bar, no layout on every hover. `translate`
   is a separate property from `transform`, so the vertical centring and
   the scale compose without fighting. */
.depth a::before{
  content:"";
  position:absolute;
  inset-block-start:50%;
  inset-inline-end:0;
  translate:0 -50%;
  width:34px; height:2px;
  transform:scaleX(.529);          /* 18 of 34 */
  transform-origin:right center;
  background:var(--ink-3);
  opacity:.5;
  transition:transform .22s var(--ease), background-color .22s ease, opacity .22s ease;
}
.depth a:hover::before{transform:scaleX(.765);opacity:.9}  /* 26 of 34 */
.depth a[aria-current="true"]::before{
  transform:scaleX(1);
  background:var(--accent);
  opacity:1;
}
.depth .d-name{
  position:absolute;
  inset-block-start:50%;
  inset-inline-end:30px;
  translate:0 -50%;
  white-space:nowrap;
  font-family:var(--font-mono);
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-2);
  opacity:0;
  transition:opacity .2s ease;
  pointer-events:none;
}
.depth a:hover .d-name,
.depth a:focus-visible .d-name{opacity:1}

/* ── Go-deeper affordance ───────────────────────────────────────────── */
.deeper{
  position:absolute; z-index:10;
  inset-block-end:max(var(--pad), env(safe-area-inset-bottom));
  inset-inline-start:50%;
  translate:-50% 0;
  display:grid; justify-items:center; gap:8px;
  min-width:44px; min-height:44px;
  padding:8px 16px;
  border:0;
  background:none;
  color:var(--ink-2);
  font-family:var(--font-mono);
  font-size:10px;
  letter-spacing:.16em;
  text-transform:uppercase;
  cursor:pointer;
}
.deeper:hover{color:var(--ink)}
.deeper .arrow{
  display:block;
  width:1px; height:20px;
  background:linear-gradient(to bottom,transparent,var(--accent));
  animation:drift 1.9s var(--ease) infinite;
}
@keyframes drift{
  0%,100%{transform:translateY(0);opacity:.45}
  50%    {transform:translateY(5px);opacity:1}
}
/* Nothing deeper than the last room — the control hides rather than lies. */
.deeper[hidden]{display:none}

/* ── Legal footer ───────────────────────────────────────────────────────
   Small enough to stay out of the photograph, complete enough that every
   room exposes the same legal and privacy controls. */
.site-footer{
  position:absolute; z-index:10;
  inset-inline-start:var(--pad);
  inset-block-end:max(12px,env(safe-area-inset-bottom));
  max-width:calc(50vw - 70px);
  display:flex; align-items:center; flex-wrap:wrap; gap:6px 14px;
  color:var(--ink-3);
  font-family:var(--font-mono);
  font-size:9px;
  line-height:1.35;
  letter-spacing:.08em;
  text-transform:uppercase;
}
.site-footer nav{display:flex;align-items:center;flex-wrap:wrap;gap:5px 12px}
.site-footer a,.site-footer button{
  border:0; padding:2px 0; background:none; color:var(--ink-2);
  font:inherit; letter-spacing:inherit; text-transform:inherit; cursor:pointer;
}
.site-footer a:hover,.site-footer button:hover{color:var(--ink)}

/* Optional analytics never loads before consent. This compact panel is a
   real dialog rather than a decorative toast, and can be reopened from every
   footer so withdrawing consent is as easy as granting it. */
.consent-banner{
  position:fixed; z-index:100;
  inset-inline-end:20px;
  inset-block-end:max(20px,env(safe-area-inset-bottom));
  width:min(420px,calc(100% - 40px));
  padding:20px;
  border:1px solid var(--line);
  border-radius:var(--r-card);
  background:rgba(27,21,18,.98);
  box-shadow:0 22px 70px rgba(0,0,0,.48);
  color:var(--ink-2);
}
.consent-banner[hidden]{display:none}
.consent-banner h2{
  margin:0 0 8px;
  color:var(--ink);
  font-family:var(--font-display);
  font-size:28px;
  font-weight:400;
}
.consent-banner p{margin:0;font-size:14px;line-height:1.55}
.consent-banner p a{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
.consent-actions{display:flex;justify-content:flex-end;flex-wrap:wrap;gap:10px;margin-block-start:16px}
.consent-actions button{
  min-height:44px;
  padding:10px 15px;
  border:1px solid var(--line);
  border-radius:999px;
  background:var(--surface);
  color:var(--ink);
  font-family:var(--font-ui);
  font-size:14px;
  cursor:pointer;
}
.consent-actions button[data-consent="grant"]{background:var(--accent);color:var(--accent-ink);border-color:transparent}

@media (prefers-reduced-motion:reduce){
  .deeper .arrow{animation:none;opacity:.9}
  .skip,.depth a::before,.d-name{transition-duration:.01ms}
}

/* ── Small screens ──────────────────────────────────────────────────────
   The depth meter moves to the bottom edge and lies flat; at that size a
   vertical rail on the right fights the thumb and the copy block.        */
@media (max-width:719px){
  .depth{
    inset-block-start:auto;
    inset-block-end:max(calc(var(--pad) + 98px), calc(env(safe-area-inset-bottom) + 98px));
    inset-inline-end:auto;
    inset-inline-start:50%;
    transform:translateX(-50%);
    grid-auto-flow:column;
    gap:4px;
  }
  .depth a::before{
    inset-block-start:auto;
    inset-block-end:12px;
    inset-inline-end:50%;
    translate:50% 0;
    width:22px; height:2px;
    transform:scaleX(.636);        /* 14 of 22 */
    transform-origin:center;       /* centred rail: grow from the middle */
  }
  .depth a:hover::before{transform:scaleX(.636)}
  .depth a[aria-current="true"]::before{transform:scaleX(1)}
  .depth .d-name{display:none}
  .deeper{inset-block-end:max(calc(var(--pad) + 38px), calc(env(safe-area-inset-bottom) + 38px))}
  .copy{padding-block-end:max(calc(var(--pad) + 164px), calc(env(safe-area-inset-bottom) + 164px))}
  /* Mobile: top mark clears the status bar */
  .mark{top:max(var(--pad), 48px)}
  /* Mobile: CTA centres for thumb reach */
  .cta{margin-inline:auto; display:flex; justify-content:center; max-width:fit-content}
  .site-footer{
    inset-inline:var(--pad);
    inset-block-end:max(7px,env(safe-area-inset-bottom));
    max-width:none;
    justify-content:center;
    gap:3px 10px;
    text-align:center;
    font-size:8px;
  }
  .site-footer>span{flex-basis:100%}
  .site-footer nav{justify-content:center;gap:3px 10px}
  .consent-banner{inset-inline:12px;inset-block-end:max(12px,env(safe-area-inset-bottom));width:auto}
  .consent-actions{display:grid;grid-template-columns:1fr 1fr}
}

/* ── No-JS ──────────────────────────────────────────────────────────────
   Without JS there is no state machine, so the stage would be one frozen
   room with dead controls. Say so, and keep the room readable.           */
.noscript{
  position:absolute; z-index:12;
  inset-block-end:0; inset-inline:0;
  padding:12px var(--pad);
  background:var(--ground-2);
  color:var(--ink-2);
  border-block-start:1px solid var(--line);
  font-family:var(--font-mono);
  font-size:12px;
  text-align:center;
}

/* ── "Thinking" indicator ───────────────────────────────────────────────
   Shown only while the next room's media is still being fetched. A hairline
   sweep rather than a spinner: the wait is usually a few hundred ms, and a
   spinner that appears and vanishes that fast is itself the flash it was
   meant to cover. app.js only raises it if the wait actually exceeds the
   delay below, so a cached room shows nothing at all. */
.thinking{
  position:absolute; z-index:12;
  inset-block-start:0; inset-inline:0;
  height:2px;
  opacity:0;
  transition:opacity .18s ease;
  pointer-events:none;
  background:linear-gradient(90deg,
    transparent 0%, var(--accent) 45%, var(--accent) 55%, transparent 100%);
  background-size:38% 100%;
  background-repeat:no-repeat;
}
.stage[data-busy="1"] .thinking{
  opacity:1;
  animation:sweep 900ms linear infinite;
}
@keyframes sweep{
  from{background-position:-38% 0}
  to  {background-position:138% 0}
}
@media (prefers-reduced-motion:reduce){
  .stage[data-busy="1"] .thinking{animation:none;background-position:50% 0}
}
