/* screens/title.css: the title (SPEC 3.2, intro 4.4) and the shared logo lockup (.lockup--xl here, .lockup--lg in the
   loading card at 55%). Everything inside the lockup is sized in --lk units (1rem / .55rem), so one drawing serves
   both sizes.

   The lockup is one emblem, the owner's drawing (img/brand/aisu-hero-logo@*.webp, original in
   docs/assets-originales/aisu-hero-logo.png): the taiko drum head with AISU across it (the flame is the I's dot), HERO
   on the cobalt ribbon and the red AI SU seal. Box: 34 x 22 lk; the drawing is 30 lk wide, centred.

   Title layout, one column (lx .. lx + 34rem, every item centred on lx + 17rem): emblem, tagline tape, Press Enter,
   the alt line. At Aisu's feet (right edge = the title safe line) the now-playing card: the jacket with its record
   sliding out (it spins while the music plays), the song, its meta and the sound state; the bichito sits on its top
   edge. Footer chips bottom left, on the same lx. Nothing reaches the MV (x >= 50vw - 10.8vh, y <= 54vh) or Aisu.

   #title[data-sound] = off | on (title-view.js): off shows "Click or press any key for sound"; on runs the record and
   the EQ (scaleY written by title-view.eq() from the music analyser, only when it changes).

   Intro: title-view.js sets #title[data-intro="full" | "short"] and --t0 (the camera's --move-at, in ms) on every
   entry, in the same task as ui.show(). Every entrance is `from`-only with fill backwards and a delay of --t0 + its
   time, so the settled screen is the base style. Reduced motion: motion.css turns every --anim into a 120ms fade and
   every --loop off. Only transform / opacity (and the individual scale / translate / rotate) animate. */

/* ============================================================================================ keyframes */
@keyframes wp5-unfurl  { from { opacity: 0; transform: scaleX(.15); } 35% { opacity: 1; } }
@keyframes wp5-drop    { from { opacity: 0; transform: translateY(-110%); } 30% { opacity: 1; } }
@keyframes wp5-tape    { from { opacity: 0; transform: translateX(-1.2rem) scaleX(.85); } }
@keyframes wp5-crowd   { from { opacity: 0; transform: translateY(45%); } }
@keyframes wp5-breathe { from { scale: 1; } to { scale: 1.035; } }
@keyframes wp5-glow    { from { opacity: 0; transform: scale(.6); } }
@keyframes wp5-rays    { from { opacity: 0; transform: scale(.55) rotate(-28deg); } 40% { opacity: 1; } }
@keyframes wp5-shine   { from { opacity: 1; transform: translateX(-120%) skewX(-20deg); } to { opacity: 1; transform: translateX(260%) skewX(-20deg); } }
@keyframes wp5-twinkle { 0% { opacity: 0; transform: scale(.2) rotate(-45deg); } 45% { opacity: 1; transform: scale(1.25) rotate(8deg); } 100% { opacity: 1; transform: none; } }
@keyframes tt-drum     { 0% { opacity: 0; transform: scale(.3) rotate(-50deg); } 30% { opacity: 1; } 100% { transform: none; } }
@keyframes tt-card     { from { opacity: 0; transform: translateY(2.4rem) rotate(4deg); } 30% { opacity: 1; } }
@keyframes tt-vinyl    { from { transform: translateX(-2.6rem) rotate(-120deg); } }
@keyframes tt-rays     { to { transform: rotate(360deg); } }
@keyframes tt-hint     { from { opacity: .55; } to { opacity: 1; } }
@keyframes tt-logo     { from { transform: none; } to { transform: scale(1.025) rotate(-.6deg); } }

/* ============================================================================================ the lockup */
@property --lk { syntax: '<length>'; inherits: true; initial-value: 16px; }
:is(.lockup--xl, .lockup--lg) { display: block; isolation: isolate; line-height: 1; width: calc(34 * var(--lk)); height: calc(22 * var(--lk)); }
.lockup--xl { --lk: 1rem; }
.lockup--lg { --lk: .55rem; position: relative; }

/* warm backlight and slow fire rays behind the drum, both kept inside the box (the MV starts right of it) */
.lockup--xl::before {
  content: ''; position: absolute; z-index: -3; left: 0; top: calc(-3 * var(--lk)); width: 100%; height: calc(26 * var(--lk));
  pointer-events: none;
  background: radial-gradient(closest-side at 50% 48%, rgb(255 120 45 / .5), rgb(232 32 47 / .28) 52%, rgb(165 15 31 / .1) 76%, transparent);
}
#title-logo .lockup__rays {
  left: calc(-1 * var(--lk)); top: calc(-8.5 * var(--lk)); width: calc(36 * var(--lk)); height: calc(36 * var(--lk));
  z-index: -2; overflow: hidden; border-radius: 50%;
  -webkit-mask: radial-gradient(closest-side, #000 30%, rgb(0 0 0 / .45) 62%, transparent 100%);
  mask: radial-gradient(closest-side, #000 30%, rgb(0 0 0 / .45) 62%, transparent 100%);
}
#title-logo .lockup__rays::before {
  content: ''; position: absolute; inset: 0;
  background: repeating-conic-gradient(from 3deg, rgb(255 160 50 / .2) 0 6deg, transparent 6deg 15deg);
  --loop: tt-rays 90s linear infinite; animation: var(--loop);
}

/* twinkles around the drum (one pseudo, several layers), inside the box */
.lockup--xl::after {
  content: ''; position: absolute; z-index: 3; pointer-events: none; inset: calc(-1 * var(--lk)) 0 0;
  background:
    url(../../img/svg/twinkle.svg) 92% 8% / calc(1.6 * var(--lk)) no-repeat,
    url(../../img/svg/twinkle.svg) 99% 30% / calc(.9 * var(--lk)) no-repeat,
    url(../../img/svg/twinkle.svg) 3% 14% / calc(1.3 * var(--lk)) no-repeat,
    url(../../img/svg/twinkle.svg) 9% 4% / calc(.8 * var(--lk)) no-repeat,
    url(../../img/svg/twinkle.svg) 1% 58% / calc(.9 * var(--lk)) no-repeat;
}

/* the emblem: one drawing; it lands like a stamp in the intro and then breathes with the beat */
:is(.lockup--xl, .lockup--lg) .lockup__img {
  position: absolute; left: calc(2 * var(--lk)); top: calc(-.4 * var(--lk)); width: calc(30 * var(--lk)); height: auto;
  transform-origin: 50% 55%; user-select: none; -webkit-user-drag: none;
  animation: var(--anim, none), var(--loop, none);
}
#title-logo .lockup__img { --loop: tt-logo 1.6s ease-in-out calc(var(--t0, 0ms) + 1200ms) infinite alternate; }

/* ============================================================================================ title layout */
#title { --t0: 0ms; }

/* tagline: red torn tape under the emblem, centred on the column (ink copy underneath as its drop) */
#title .tagline {
  display: block; width: max-content; min-height: 0; padding: .45rem 1.5rem .5rem 2.8rem; isolation: isolate;
  font: 700 1.25rem/1.2 var(--font-display); font-stretch: 85%; letter-spacing: .03em; text-transform: none; color: var(--ivory);
  -webkit-text-stroke: max(1.5px, .12em) var(--ink); paint-order: stroke fill; white-space: nowrap;
  rotate: -2deg;
}
#title .tagline :where(b) { color: var(--f2); font-weight: inherit; }
#title .tagline::before, #title .tagline::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  -webkit-mask: url(../../img/svg/tape-torn.svg) 0 0 / 100% 100%; mask: url(../../img/svg/tape-torn.svg) 0 0 / 100% 100%;
}
#title .tagline::before { z-index: -2; background: var(--ink); translate: .2rem .3rem; }
#title .tagline::after {
  z-index: -1;
  background:
    url(../../img/svg/flame-ember-rim.svg) .95rem 50% / auto 1.45rem no-repeat,
    repeating-linear-gradient(90deg, rgb(255 255 255 / .07) 0 2px, transparent 2px 5px),
    linear-gradient(180deg, var(--red-hi), var(--red) 45%, #C8162A);
}

/* the prompt: Primary L, fire, ivory label, two flame tips, a warm glow; breathes on the beat after the intro */
#btn-start.prompt {
  width: 23rem; min-height: 4.4rem; height: 4.4rem; gap: .55rem; padding-inline: 1.6rem;
  font-size: 1.6rem; letter-spacing: .02em;
  box-shadow:
    inset 0 .22rem 0 rgb(255 255 255 / .32), inset 0 -.32rem 0 rgb(80 0 10 / .3),
    0 var(--btn-drop) 0 var(--ink),
    0 .4rem 2.2rem .2rem rgb(255 90 31 / .45);
  --loop: wp5-breathe calc(var(--beat) * 2) ease-in-out calc(var(--t0) + 2000ms) infinite alternate;
  animation: var(--anim, none), var(--loop, none);
}
#btn-start.prompt :where(kbd) { font-size: 1rem; height: 1.85rem; min-width: 3.6rem; margin-inline: .15rem; }
#btn-start.prompt::before { right: 1.1rem; top: -1.55rem; width: 2.8rem; height: 2.1rem; background-size: auto 2.1rem, auto 1.45rem; }
#title .prompt-alt {
  width: 23rem; text-align: center;
  font: 900 var(--fs-small)/1.2 var(--font-body); letter-spacing: .14em; text-transform: uppercase; color: var(--ivory-2);
  text-shadow: var(--hint-shadow);
}

/* ---------------------------------------------------------------- now-playing card (at Aisu's feet)
   ivory ticket, ink rim, cobalt plate. Left: the jacket and its record (half out to the right, spinning with the
   music). Right: kicker with the EQ, the song (#title-song), meta, the sound state. */
#title .np {
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr); align-items: center; column-gap: .9rem;
  height: 7.8rem; padding: .7rem 1.1rem .7rem .8rem; color: var(--ink);
  background: url(../../img/svg/paper-grain.webp) 0 0 / 16rem, var(--grad-ivory);
  border: var(--ow) solid var(--ink); border-radius: var(--r-m);
  box-shadow: .45rem .55rem 0 0 var(--cobalt), .45rem .55rem 0 var(--ow) var(--ink), var(--float);
  rotate: -1.5deg; transform-origin: 30% 100%;
}
#title .np::after {                                        /* perforation between the jacket and the text */
  content: ''; position: absolute; left: 9.65rem; top: .7rem; bottom: .7rem; width: 0; pointer-events: none;
  border-left: .14rem dashed rgb(44 15 21 / .28);
}
#title .np__disc { position: relative; width: 6rem; height: 6rem; }
#title .np__cover {
  position: relative; z-index: 1; display: block; width: 6rem; height: 6rem; object-fit: cover;
  border: var(--ow) solid var(--ink); border-radius: var(--r-s); background: var(--night-2);
  box-shadow: .2rem .25rem 0 rgb(44 15 21 / .45);
}
#title .np__vinyl {                                        /* the record: grooves, red label with the flame, a glint */
  position: absolute; left: 2.75rem; top: .4rem; width: 5.2rem; height: 5.2rem; border-radius: 50%;
  background:
    radial-gradient(circle, var(--ink) 0 6%, transparent 6.5%),
    url(../../img/mascot/flame-mono.svg) 50% 50% / 22% auto no-repeat,
    radial-gradient(circle, var(--red) 0 30%, var(--ink) 31% 33%, transparent 34%),
    conic-gradient(from 20deg, rgb(255 255 255 / .16) 0 8deg, transparent 8deg 172deg, rgb(255 255 255 / .12) 172deg 182deg, transparent 182deg),
    repeating-radial-gradient(circle, #17131c 0 .14rem, #261f2c .14rem .2rem),
    #17131c;
  box-shadow: 0 0 0 var(--ow-s) var(--ink), .15rem .2rem 0 var(--ow-s) rgb(44 15 21 / .4);
  animation: var(--anim, none), var(--loop, none);
}
#title[data-sound="on"] .np__vinyl { --loop: ff-spin 1.8s linear infinite; }
#title .np__body { display: grid; align-content: center; gap: .18rem; min-width: 0; }
#title .np__kicker {
  display: flex; align-items: flex-end; gap: .45rem; margin: 0;
  font: 900 var(--fs-small)/1 var(--font-body); letter-spacing: .16em; text-transform: uppercase; color: var(--red);
}
#title .np__eq { display: inline-flex; align-items: flex-end; gap: .14rem; height: .95rem; }
#title .np__eq i {
  display: block; width: .22rem; height: 100%; border-radius: .11rem; transform-origin: 50% 100%; scale: 1 .25;
  background: linear-gradient(0deg, var(--red) 0%, var(--f3) 60%, var(--f2) 100%);
}
#title .np__song {
  margin: 0; font: 700 1.35rem/1.05 var(--font-display); font-stretch: 85%; letter-spacing: .01em; color: var(--ink);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
#title .np__song[data-len="m"] { font-size: 1.2rem; }
#title .np__song[data-len="l"] { font-size: 1.05rem; font-stretch: 75%; }
#title .np__meta { margin: 0; font: 900 var(--fs-small)/1.2 var(--font-body); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); }
#title .np__sound {
  display: flex; align-items: center; gap: .4rem; margin: .2rem 0 0; min-height: 1.45rem;
  font: 900 var(--fs-small)/1.15 var(--font-body); color: var(--ink);
}
#title .np__sound::before {                                /* speaker icon (muted / on) */
  content: ''; flex: none; width: 1.3rem; height: 1.3rem; border-radius: 50%;
  background: url(../../img/svg/sound-off.svg) 50% 50% / 70% no-repeat, var(--ivory-2);
  box-shadow: 0 0 0 var(--ow-s) var(--ink);
}
#title[data-sound="on"] .np__sound::before { background: url(../../img/svg/sound-on.svg) 50% 50% / 70% no-repeat, var(--f2); }
#title .np__sound-on { display: none; }
#title[data-sound="on"] .np__sound-on { display: inline; }
#title[data-sound="on"] .np__sound-off { display: none; }
#title[data-sound="off"] .np__sound { --loop: tt-hint calc(var(--beat) * 2) ease-in-out infinite alternate; animation: var(--loop); }

/* footer chips: night pills with a small icon; the offline chip (ember) replaces v1.0 */
.title-foot { align-items: center; gap: .35rem; max-width: min(30rem, calc(var(--safe-title-r) - 26.5rem - var(--lx))); } /* ends 1rem left of the card */
.title-foot__chip {
  display: inline-flex; align-items: center; gap: .34rem; min-height: 1.75rem; padding: .1rem .55rem .12rem .45rem;
  border: max(1.5px, .1rem) solid rgb(246 240 228 / .3); border-radius: var(--r-pill);
  background: rgb(13 11 22 / .88); box-shadow: 0 .16rem 0 var(--ink);
  color: var(--ivory-2); font: 900 var(--fs-small)/1 var(--font-body); letter-spacing: .01em; white-space: nowrap;
}
.title-foot__chip::before {
  content: ''; width: .5rem; height: .5rem; border-radius: 50%; background: var(--f3); box-shadow: 0 0 0 .1rem var(--ink);
}
.title-foot__guitar::before { background: var(--cobalt-hi); }
.title-foot__ver { color: var(--gold); }
.title-foot__ver::before { background: var(--gold); }
.title-foot__offline { background: var(--ember); color: var(--ink); border-color: var(--ink); }
.title-foot__offline::before { background: var(--ink); box-shadow: none; }

/* lanterns: a shallow sag, so they hang above the logo's flame */
#title .title-lanterns { --lantern-sag: 1.4; }

/* ============================================================================================ intro (SPEC 4.4)
   full = first boot (under the opening curtain, 80 -> 780ms), short = every return. Times are ms after --t0.
     300 lanterns drop · 420 crowd rises · 440 the emblem stamps in + glow + rays (lands ~700, it breathes from 1200)
     1100 card slides up (record rolls out 1250) · 1180 tagline tape · 1250 prompt pops (breathes from 2000)
     1450 alt line · 1500 chips
   The prompt keeps 1250 (the cursor lands on it at 1350, cursor.js). title-view.js plays the matching cues. */
#title[data-intro="full"] .title-lanterns { --anim: wp5-drop 700ms var(--spring-soft) calc(var(--t0) + 300ms) backwards; animation: var(--anim); }
#title[data-intro="full"] .title-crowd    { --anim: wp5-crowd 900ms var(--ease-out) calc(var(--t0) + 420ms) backwards; animation: var(--anim); }
#title[data-intro="full"] #title-logo::before { --anim: wp5-glow 900ms var(--ease-out) calc(var(--t0) + 440ms) backwards; animation: var(--anim); }
#title[data-intro="full"] #title-logo .lockup__rays { --anim: wp5-rays 1100ms var(--ease-out-expo) calc(var(--t0) + 440ms) backwards; animation: var(--anim); }
#title[data-intro="full"] #title-logo .lockup__img { --anim: ff-stamp 640ms var(--spring-stamp) calc(var(--t0) + 440ms) backwards; }
#title[data-intro="full"] #title-logo::after { --anim: wp5-twinkle 520ms var(--ease-out) calc(var(--t0) + 1150ms) backwards; animation: var(--anim); }
#title[data-intro="full"] .np         { --anim: tt-card 560ms var(--spring-soft) calc(var(--t0) + 1100ms) backwards; animation: var(--anim); }
#title[data-intro="full"] .np__vinyl  { --anim: tt-vinyl 700ms var(--ease-out) calc(var(--t0) + 1250ms) backwards; }
#title[data-intro="full"] .tagline    { --anim: wp5-tape 320ms var(--ease-out) calc(var(--t0) + 1180ms) backwards; animation: var(--anim); }
#title[data-intro="full"] #btn-start  { --anim: ff-pop 420ms var(--spring-pop) calc(var(--t0) + 1250ms) backwards; }
#title[data-intro="full"] .prompt-alt { --anim: ff-fade 300ms linear calc(var(--t0) + 1450ms) backwards; animation: var(--anim); }
#title[data-intro="full"] .title-foot__chip { --anim: ff-rise-in 380ms var(--ease-out) calc(var(--t0) + 1500ms) backwards; animation: var(--anim); }
#title[data-intro="full"] .title-foot__chip:nth-child(2) { --anim: ff-rise-in 380ms var(--ease-out) calc(var(--t0) + 1560ms) backwards; }
#title[data-intro="full"] .title-foot__chip:nth-child(n+3) { --anim: ff-rise-in 380ms var(--ease-out) calc(var(--t0) + 1620ms) backwards; }

/* short version: lockup 0, tagline 30, card 40, prompt 80, footer 100 (the bichito and the cursor are timed by
   mascot.js / cursor.js) */
#title[data-intro="short"] #title-logo { --anim: ff-pop 380ms var(--spring-pop) var(--t0) backwards; animation: var(--anim); transform-origin: 50% 45%; }
#title[data-intro="short"] .tagline    { --anim: wp5-tape 300ms var(--ease-out) calc(var(--t0) + 30ms) backwards; animation: var(--anim); }
#title[data-intro="short"] .np         { --anim: tt-card 420ms var(--spring-soft) calc(var(--t0) + 40ms) backwards; animation: var(--anim); }
#title[data-intro="short"] #btn-start  { --anim: ff-pop 380ms var(--spring-pop) calc(var(--t0) + 80ms) backwards; --loop: wp5-breathe calc(var(--beat) * 2) ease-in-out calc(var(--t0) + 600ms) infinite alternate; }
#title[data-intro="short"] .prompt-alt { --anim: ff-fade 220ms linear calc(var(--t0) + 120ms) backwards; animation: var(--anim); }
#title[data-intro="short"] .title-foot { --anim: ff-rise-in 300ms var(--ease-out) calc(var(--t0) + 100ms) backwards; animation: var(--anim); }
#title[data-intro="short"] #title-logo .lockup__img { --loop: tt-logo 1.6s ease-in-out calc(var(--t0) + 400ms) infinite alternate; }

/* ============================================================================================ responsive
   16:9 and 16:10 keep every rem size (the emblem ends left of the MV at 16:10, the tightest). Narrow (aspect < 1.3):
   the card rises above the footer chips (they would meet under it). */
@media (max-aspect-ratio: 1299/1000) {
  #title .np { bottom: calc(2.5vh + 2.6rem); }
  .title-foot { max-width: 30rem; }
  #title .mascot-anchor { bottom: calc(2.5vh + 2.6rem + 7.4rem); }
}
