/* ============================================================
   TOBIRA Live Gallery — signature landing sequence
   Loaded FIRST in <head> of index.html / auth.html / account.html
   Beats: PROMPT typed → AI THINKING (archive converges) →
          DELIVERY seam flare + door split → 点灯 tile boot (in-page)
   ============================================================ */

/* ---------- OVERLAY (beats 1–3) ---------- */

#tobira-loader {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: transparent; /* the two door panels carry the black */
  color: #f2efe9;
  overflow: hidden;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans JP", sans-serif;
  -webkit-font-smoothing: antialiased;
  will-change: transform, opacity;
}

/* the doors — two half panels; seamless until beat 3 (tiny overlap) */
#tobira-loader .tl-door {
  position: absolute;
  left: 0;
  width: 100%;
  height: 50.5%;
  background: #0a0a0a;
  transition: transform 750ms cubic-bezier(.34, 1.56, .64, 1);
  will-change: transform;
}
#tobira-loader .tl-door-top { top: 0; }
#tobira-loader .tl-door-bottom { bottom: 0; }

#tobira-loader .tl-stage {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 0 24px;
}

/* ---- BEAT 1: THE PROMPT ---- */

#tobira-loader .tl-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .2em;
  color: #ff5b3d;
  opacity: 0;
  animation: tl-fade-in 360ms ease 60ms forwards;
}
@keyframes tl-fade-in {
  to { opacity: 1; }
}

#tobira-loader .tl-capsule {
  display: flex;
  align-items: center;
  width: min(680px, 88vw);
  min-height: 52px;
  padding: 14px 22px;
  border: 1px solid rgba(242, 239, 233, .26);
  border-radius: 999px;
  background: rgba(242, 239, 233, .03);
  opacity: 0;
  transform: translateY(10px);
  animation: tl-capsule-in 420ms cubic-bezier(.22, 1, .36, 1) 60ms forwards;
}
@keyframes tl-capsule-in {
  to { opacity: 1; transform: translateY(0); }
}
#tobira-loader .tl-typed {
  font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, Menlo, monospace;
  font-size: 12.5px;
  line-height: 1.5;
  letter-spacing: .01em;
  color: rgba(242, 239, 233, .92);
  white-space: pre-wrap;
  word-break: break-word;
}
#tobira-loader .tl-caret {
  flex: none;
  width: 1.5px;
  height: 16px;
  margin-left: 3px;
  background: #ff5b3d;
  animation: tl-caret-blink 1s steps(2, jump-none) infinite;
}
@keyframes tl-caret-blink {
  50% { opacity: 0; }
}

/* Enter — the capsule pulses once */
#tobira-loader .tl-capsule.tl-enter-flash {
  animation: tl-enter-pulse 220ms ease-out forwards;
}
@keyframes tl-enter-pulse {
  0%   { opacity: 1; transform: translateY(0) scale(1);     border-color: rgba(242, 239, 233, .26); box-shadow: none; }
  40%  { opacity: 1; transform: translateY(0) scale(1.015); border-color: #ff5b3d; box-shadow: 0 0 0 1px rgba(255, 91, 61, .7), 0 0 30px rgba(255, 91, 61, .35); }
  100% { opacity: 1; transform: translateY(0) scale(1);     border-color: rgba(255, 91, 61, .55); box-shadow: 0 0 18px rgba(255, 91, 61, .18); }
}

/* phase 2: the prompt collapses / floats up */
#tobira-loader.tl-phase2 .tl-prompt-stage {
  opacity: 0;
  transform: translateY(-30px) scale(.98);
  transition: opacity 280ms ease, transform 320ms cubic-bezier(.22, 1, .36, 1);
  pointer-events: none;
}

/* ---- BEAT 2: THE THINKING ---- */

#tobira-loader .tl-think-stage {
  gap: 22px;
  opacity: 0;
  transform: scale(.96);
  pointer-events: none;
}
#tobira-loader.tl-phase2 .tl-think-stage {
  opacity: 1;
  transform: scale(1);
  transition: opacity 320ms ease 120ms, transform 420ms cubic-bezier(.22, 1, .36, 1) 120ms;
}

/* the vermilion orb — the AI, digesting */
#tobira-loader .tl-orb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ff5b3d;
  box-shadow: 0 0 18px rgba(255, 91, 61, .9), 0 0 60px rgba(255, 91, 61, .4);
  animation: tl-orb-pulse 900ms ease-in-out infinite;
  will-change: transform;
}
@keyframes tl-orb-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.35); }
}

#tobira-loader .tl-status {
  min-height: 1.6em;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .06em;
  color: rgba(242, 239, 233, .8);
  font-feature-settings: "palt";
  opacity: 1;
  transition: opacity 120ms ease;
}

/* the archive converging — chips absorbed into the orb */
#tobira-loader .tl-chips {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 0;
  pointer-events: none;
}
#tobira-loader .tl-chip {
  position: absolute;
  left: 0;
  top: 0;
  width: 90px;
  height: auto;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) translate(var(--tx, 0px), var(--ty, 0px)) rotate(var(--rot, 0deg));
  will-change: transform, opacity;
}
#tobira-loader.tl-phase2 .tl-chip {
  animation: tl-chip-absorb 760ms cubic-bezier(.5, .05, .7, .4) both;
  /* per-chip stagger (i * 70ms) set inline by loader.js */
}
@keyframes tl-chip-absorb {
  0%   { opacity: 0; transform: translate(-50%, -50%) translate(var(--tx, 0px), var(--ty, 0px)) rotate(var(--rot, 0deg)) scale(1); }
  14%  { opacity: .95; }
  80%  { opacity: .85; }
  100% { opacity: 0; transform: translate(-50%, -50%) translate(0px, 0px) rotate(0deg) scale(.26); }
}

/* ---- BEAT 3: THE DELIVERY ---- */

#tobira-loader .tl-deliver-line {
  display: none;
  font-size: clamp(20px, 4vw, 34px);
  font-weight: 900;
  letter-spacing: .01em;
  line-height: 1.4;
  color: #f2efe9;
  font-feature-settings: "palt";
  text-align: center;
}
#tobira-loader .tl-maru { color: #ff5b3d; }

#tobira-loader.tl-deliver .tl-status,
#tobira-loader.tl-deliver .tl-chip { display: none; }
#tobira-loader.tl-deliver .tl-orb {
  animation: none;
  transform: scale(.8);
  opacity: .9;
}
#tobira-loader.tl-deliver .tl-deliver-line {
  display: block;
  animation: tl-deliver-in 240ms cubic-bezier(.22, 1, .36, 1) both;
}
@keyframes tl-deliver-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* the door seam — 1px vermilion hairline beneath the message (B3-B) */
#tobira-loader .tl-seam {
  display: none;
  width: min(360px, 60vw);
  height: 1px;
  background: rgba(255, 91, 61, .5);
  will-change: opacity, filter;
}
#tobira-loader.tl-deliver .tl-seam {
  display: block;
  opacity: 0;
  animation: tl-fade-in 240ms ease 120ms forwards;
}
/* ... the seam flares: brightness pulse, glow widens ... */
#tobira-loader.tl-flare .tl-seam {
  animation: tl-seam-flare 300ms ease-out forwards;
}
@keyframes tl-seam-flare {
  0%   { opacity: 1; box-shadow: none; background: rgba(255, 91, 61, .5); }
  50%  { opacity: 1; box-shadow: 0 0 24px 3px rgba(255, 91, 61, .85); background: #ff5b3d; }
  100% { opacity: 1; box-shadow: 0 0 10px 1px rgba(255, 91, 61, .5); background: #ff5b3d; }
}

/* ... then the overlay splits along the seam, door-style */
#tobira-loader.tl-open { pointer-events: none; }
#tobira-loader.tl-open .tl-door-top { transform: translateY(-101%); }
#tobira-loader.tl-open .tl-door-bottom { transform: translateY(101%); }
#tobira-loader.tl-open .tl-think-stage {
  opacity: 0;
  transition: opacity 200ms ease;
}

/* reduced motion: plain fade, no beats */
#tobira-loader.tl-fade-out { opacity: 0; transition: opacity 320ms ease; }
@media (prefers-reduced-motion: reduce) {
  #tobira-loader { background: #0a0a0a; }
  #tobira-loader .tl-door { display: none; }
  #tobira-loader .tl-stage * { animation: none !important; }
  #tobira-loader .tl-chips { display: none; }
  #tobira-loader .tl-label, #tobira-loader .tl-capsule { opacity: 1; transform: none; }
  #tobira-loader .tl-think-stage { display: none; }
}

/* ---------- BEAT 4 点灯 — in-page power-on (hero boots like Times Square)
   Scoped to html.entrance-* only: the page is 100% normal when the
   entrance never runs (JS off, repeat logic skipped, reduced motion).
   Classes are added by loader.js pre-reveal and self-clear after. ---------- */

html.entrance-play { --tl-gap: 90ms; --tl-copy-delay: 640ms; --tl-ticker-delay: 900ms; }
html.entrance-fast { --tl-gap: 40ms; --tl-copy-delay: 0ms;   --tl-ticker-delay: 80ms; }

/* boot order (not DOM order — reads as a cascade across the wall) */
html.entrance-play #b23-hero .lead      { --tl-d: 0; }
html.entrance-play #b23-hero .tall      { --tl-d: 1; }
html.entrance-play #b23-hero .secondary { --tl-d: 2; }
html.entrance-play #b23-hero .art       { --tl-d: 3; }
html.entrance-play #b23-hero .cosmic    { --tl-d: 4; }
html.entrance-play #b23-hero .dream     { --tl-d: 5; }
html.entrance-play #b23-hero .urban     { --tl-d: 6; }

/* pre-reveal hold: everything dark / tucked (only while JS says pending) */
html.entrance-pending #b23-hero .tile      { filter: brightness(0); transform: scale(.97); }
html.entrance-pending #b23-hero .rank      { opacity: 0; }
html.entrance-pending #b23-hero .hero-copy { opacity: 0; transform: translateY(26px); }
html.entrance-pending #b23-hero .ticker    { opacity: 0; transform: translateY(100%); }

/* screens flicker on: dark → flash → dark → settle (2-step boot) */
html.entrance-play #b23-hero .tile {
  animation: tl-ent-boot 560ms cubic-bezier(.22, 1, .36, 1) both;
  animation-delay: calc(var(--tl-d, 0) * var(--tl-gap, 90ms));
  will-change: filter, transform;
}
@keyframes tl-ent-boot {
  0%, 6%   { filter: brightness(0);    transform: scale(.97); }
  7%, 16%  { filter: brightness(1.55) saturate(1.15); transform: scale(.984); }
  17%, 27% { filter: brightness(.18);  transform: scale(.984); }
  28%      { filter: brightness(1.25); transform: scale(.99); }
  100%     { filter: brightness(1);    transform: scale(1); }
}

/* rank badges pop with overshoot once their screen is lit */
html.entrance-play #b23-hero .rank {
  animation: tl-ent-pop 380ms cubic-bezier(.34, 1.56, .64, 1) both;
  animation-delay: calc(var(--tl-d, 0) * var(--tl-gap, 90ms) + 300ms);
}
@keyframes tl-ent-pop {
  from { opacity: 0; transform: scale(.55); }
  to   { opacity: 1; transform: scale(1); }
}

/* the copy springs up from below */
html.entrance-play #b23-hero .hero-copy {
  animation: tl-ent-copy 540ms cubic-bezier(.34, 1.56, .64, 1) both;
  animation-delay: var(--tl-copy-delay, 640ms);
}
@keyframes tl-ent-copy {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* the ticker slides up from the bottom edge, last */
html.entrance-play #b23-hero .ticker {
  animation: tl-ent-ticker 460ms cubic-bezier(.22, 1, .36, 1) both;
  animation-delay: var(--tl-ticker-delay, 900ms);
}
@keyframes tl-ent-ticker {
  from { opacity: 0; transform: translateY(100%); }
  to   { opacity: 1; transform: translateY(0); }
}

/* reduced motion guard: even if classes ever land, hero stays visible */
@media (prefers-reduced-motion: reduce) {
  html.entrance-pending #b23-hero .tile,
  html.entrance-pending #b23-hero .rank,
  html.entrance-pending #b23-hero .hero-copy,
  html.entrance-pending #b23-hero .ticker,
  html.entrance-play #b23-hero .tile,
  html.entrance-play #b23-hero .rank,
  html.entrance-play #b23-hero .hero-copy,
  html.entrance-play #b23-hero .ticker {
    animation: none !important;
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }
}

/* ---------- CROSS-PAGE TRANSITIONS (MPA View Transitions) ---------- */

@supports (view-transition-name: root) {
  @view-transition {
    navigation: auto;
  }

  ::view-transition-old(root) {
    animation: tl-vt-out 280ms ease-in both;
  }
  ::view-transition-new(root) {
    animation: tl-vt-in 420ms cubic-bezier(.22, 1, .36, 1) both;
  }

  @keyframes tl-vt-out {
    to { opacity: 0; transform: scale(.985); }
  }
  @keyframes tl-vt-in {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: translateY(0); }
  }

  /* shared brand element — exactly one per page */
  a.brand {
    view-transition-name: site-brand;
  }

  @media (prefers-reduced-motion: reduce) {
    ::view-transition-old(root),
    ::view-transition-new(root),
    ::view-transition-old(site-brand),
    ::view-transition-new(site-brand) {
      animation: none;
    }
  }
}

/* ---------- JS FALLBACK (no cross-doc view transitions) ---------- */

html.tl-nav-exit body {
  opacity: 0;
  transform: scale(.985);
  transition: opacity 220ms ease-in, transform 220ms ease-in;
}
html.tl-nav-enter body {
  opacity: 0;
  transform: translateY(14px);
}
html.tl-nav-enter-active body {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 420ms cubic-bezier(.22, 1, .36, 1), transform 420ms cubic-bezier(.22, 1, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
  html.tl-nav-exit body,
  html.tl-nav-enter body,
  html.tl-nav-enter-active body {
    transform: none;
    transition: opacity 200ms ease;
  }
}
