/* ---------- loader ---------- */
body.is-loading { overflow: hidden; }

.loader {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
}
.loader__half {
  position: absolute;
  left: 0; right: 0;
  height: 50.5%;
  background: var(--bg);
}
.loader__half--t { top: 0; }
.loader__half--b { bottom: 0; }
.loader__inner {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 22px;
}
.loader__mark { width: 64px; height: 64px; opacity: 0.92; }
.loader__bar {
  width: min(240px, 44vw);
  height: 1px;
  background: var(--line-2);
  overflow: hidden;
}
.loader__bar span {
  display: block;
  height: 100%;
  background: var(--grad);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.loader__count {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3em;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* ---------- film grain ---------- */
/* Drifts via background-position, not transform — an oversized fixed
   layer widens the mobile layout viewport and breaks the fixed UI. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 80;
  pointer-events: none;
  opacity: 0.3;
  mix-blend-mode: overlay;
  background-repeat: repeat;
  animation: grain 1.1s steps(6) infinite;
}
@keyframes grain {
  0%   { background-position:   0px   0px; }
  20%  { background-position: -13px   9px; }
  40%  { background-position:  10px -15px; }
  60%  { background-position: -17px  -7px; }
  80%  { background-position:  15px  11px; }
  100% { background-position:   0px   0px; }
}

/* ---------- the cursor ---------- */
.cursor {
  position: fixed;
  top: 0; left: 0;
  z-index: 95;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  /* A soft frosted disc rather than a ring — it sits over imagery
     without drawing a hard edge on it. */
  background: rgba(200, 200, 210, 0.16);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  pointer-events: none;
  transition: width 360ms var(--ease), height 360ms var(--ease),
              margin 360ms var(--ease), background 360ms var(--ease);
}
.cursor.is-big {
  width: 70px;
  height: 70px;
  margin: -35px 0 0 -35px;
  background: rgba(200, 200, 210, 0.22);
}
/* Named state: the disc grows and says what a click does. */
.cursor.is-labelled {
  width: 84px;
  height: 84px;
  margin: -42px 0 0 -42px;
  background: rgba(200, 200, 210, 0.26);
}
.cursor__label {
  font-family: var(--font);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--white);
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 240ms var(--ease), transform 340ms var(--ease);
}
.cursor.is-labelled .cursor__label { opacity: 1; transform: none; }

/* ---------- hover text roll ---------- */
.roll {
  display: inline-block;
  overflow: hidden;
  height: 1.12em;
  vertical-align: bottom;
}
.roll__i {
  display: block;
  height: 1.12em;
  line-height: 1.12;
  transition: transform 460ms var(--ease);
}
a:hover .roll__i,
button:hover .roll__i,
.dindex__row:hover .roll__i { transform: translateY(-100%); }

/* ---------- masked line reveals ---------- */
.ln { display: block; overflow: hidden; }
.ln__i { display: block; will-change: transform; }
.chapter__title .t1,
.chapter__title .t2 { display: block; }

.stage__fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  color: var(--text-3);
}

@media (prefers-reduced-motion: reduce) {
  .grain { display: none; }
  .cursor { display: none; }
  .ln__i { transform: none !important; }
}

/* ---------- AR brief ---------- */
/* Sits under the AR stage and belongs to whichever piece is selected. */
.arbrief {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr) auto;
  align-items: start;
  gap: clamp(24px, 4vw, 64px);
  margin: clamp(28px, 4vh, 48px) var(--gutter) 0;
}
.arbrief__copy {
  margin: 12px 0 0;
  max-width: 46ch;
  color: var(--text-2);
}
.arbrief__go {
  display: grid;
  justify-items: start;
  align-content: start;
  gap: 20px;
}
/* The scanner is the point of this panel — give it real size and sit the
   caption beside it rather than letting it float. */
.arbrief .qr {
  margin: 0;
  align-items: center;
  gap: 18px;
}
.arbrief .qr img { width: 168px; height: 168px; padding: 14px; }
.arbrief .qr figcaption { max-width: 14ch; line-height: 1.5; }
.arbrief .ar__steps { margin: 0; }

@media (max-width: 1024px) {
  .arbrief { grid-template-columns: 1fr; }
}
