/* ═══════════════════════════════════════════════════════════════════
   PURANI DHUN — on the dark
   ─────────────────────────────────────────────────────────────────
   This file is the main site's half of the design. Everything it does
   NOT say is said by loha.css, which is now the system for both pages:
   the tokens, the corridor layers, the plate keys, the chips, the door,
   the rack. Load loha.css first, then this.

   What is different here, and only here:

     · the transport. Two reels and the tape between them, in the middle
       of the page, turning while the song does. It replaced a generated
       rangoli — powder on cement, which is what the old pale board was
       made of and the last thing on the site still speaking that
       language. The room's LIFTED pigment (PIGMENT_GLOW in rooms.js)
       lights the hub and the head.

     · nothing bilingual. The page used to print the Devanagari title
       big and the Latin transliteration small underneath it, and the
       room plates carried both names too — so every label on the page
       said itself twice, and only 253 of the 369 records had a
       Devanagari title to say it with. It is Latin now, once, like the
       two gym pages. The catalogue keeps its `d` field because search
       still reads it.

     · nine rooms instead of four decks, so the rail scrolls rather than
       fitting, and the current room is walked into view.
   ─────────────────────────────────────────────────────────────────
   1  the transport
   2  the room rail
   3  now playing
   4  the transport
   5  narrow screens
   6  reduced motion
   ═══════════════════════════════════════════════════════════════════ */

/* ── 1  the transport ──────────────────────────────────────────── */
#record{
  /*  The machine is 2:1, so in a short wide slot it is the HEIGHT that
      decides how big it gets — `flex:1` alone left it about a third of
      the width it had room for.
      This has to be a PREFERRED height and not a floor. `min-height` was
      the obvious first try and it was wrong: a two-line Devanagari title
      then pushed the whole column past the viewport and the play key
      landed on top of the rack. So the height is the flex basis, shrink
      is left on, and `min-height:0` lets it give the space back to the
      type on the songs with long names. */
  flex:1 1 auto;height:clamp(7rem, 27vh, 15rem);min-height:0;width:100%;
  display:flex;align-items:center;justify-content:center;
  position:relative;
}
#reels{
  width:100%;max-width:min(120vh, 52rem);height:100%;
  overflow:visible;
  /*  Lit, not printed. The dark shadow lifts the machine off the
      corridor; the coloured one is the light the room is throwing on it. */
  filter:drop-shadow(0 0 18px rgba(0,0,0,.92))
         drop-shadow(0 0 26px color-mix(in srgb, var(--haz) 22%, transparent));
}

/*  The well is the hole in the shell the reel sits in — a touch lighter
    than the void so there is something for the pack to sit against. */

/*  Tape is not black. Ferric oxide is a dark red-brown, and against a
    neutral dark corridor that difference is most of what makes this read
    as tape rather than as a hole. */
.rl-pack{fill:#1a1310}
.rl-edge{fill:none;stroke:rgba(255,255,255,.16);stroke-width:1.5}
.rl-ring{fill:none;stroke:#d8c4b0;stroke-width:1.1}
.rl-flaw{stroke:#e6d4c2;stroke-width:2.2;stroke-linecap:round}
/*  One bright mark from hub to edge. Without it a pack turning slowly is
    ambiguous, and the eye needs something to lock onto. */
.rl-leader{stroke:var(--haz);stroke-width:2.6;opacity:.62;stroke-linecap:round}

/*  The room lights the machine, it does not paint it. At full accent the
    six prongs read as a glowing asterisk floating in the middle of the
    reel rather than as a part the tape is wound onto. */
.rl-hub-well{fill:#0b0c0e}
.rl-teeth{fill:color-mix(in srgb, var(--haz) 44%, #93a1ad)}
.rl-spindle{fill:none;stroke:rgba(0,0,0,.85);stroke-width:5}
.rl-well{fill:rgba(255,255,255,.022);stroke:var(--edge);stroke-width:1.2;opacity:.62}

/*  Two strokes, one path: a wide one for the tape and a hairline on top
    for the light running along its edge. The tape has to be lighter than
    the wound pack — at pack colour it vanished into the corridor and the
    two reels read as unconnected discs, which is the one thing a
    transport must not do. */
.rl-tape{
  fill:none;stroke:#3a2a20;stroke-width:11;
  stroke-linecap:round;stroke-linejoin:round;
}
.rl-tape-sheen{
  fill:none;stroke:color-mix(in srgb, var(--haz) 58%, transparent);
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
}

.rl-head-body{fill:#2b3138;stroke:var(--edge);stroke-width:1.5}
.rl-head-gap{fill:var(--haz)}
.rl-roller-o{fill:#14171c;stroke:var(--edge);stroke-width:1.5}
.rl-roller-i{fill:none;stroke:rgba(255,255,255,.2);stroke-width:2}

/*  The machine breathes on the beat rather than on a loop of its own —
    app.js writes --pulse every frame, so the transport is on the same
    clock as the corridor and the shake. It is a smaller figure than the
    rangoli was and sits nearer the type, so the throw is smaller too. */
#reels{transform:scale(calc(1 + var(--pulse, 0) * 0.014));transform-origin:50% 50%}
/* the head is the one part that takes the hit properly */
.rl-head-gap{filter:drop-shadow(0 0 calc(2px + var(--pulse, 0) * 7px) var(--haz))}

/*  Loading: the head gap is the only thing that moves, because the reels
    genuinely are not turning yet and animating them would be a lie. */
[data-loading] .rl-head-gap{animation:headpulse .9s ease-in-out infinite}
@keyframes headpulse{50%{opacity:.25}}

/* a new tape drops in */
.is-drawn #reels{animation:load .5s var(--pop) backwards}
@keyframes load{from{opacity:0;transform:scale(.955)}}

/* ── 2  the rooms ──────────────────────────────────────────────── */
/*  These used to be a rail across the top: nine plates, always there,
    scrolling sideways on a phone. It cost a full row of height on every
    screen for ever, to show you the eight rooms you were NOT in — and on
    the page where the title is two lines of Devanagari at 5rem, that row
    was the difference between fitting and not.

    So the rail is gone and the plates live behind the room name that was
    already on screen above the song. The affordance is where the
    information was; nothing new was added to the page to carry it. */
#picker{
  position:fixed;inset:0;z-index:45;
  display:grid;place-items:center;padding:var(--shell);
  background:rgba(5,6,8,.94);
  opacity:0;transition:opacity .22s var(--ease);
}
#picker[data-open]{opacity:1}
.picker__in{
  width:100%;max-width:46rem;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:1.15rem;
}
.picker__kick{
  font-weight:600;font-size:.72rem;letter-spacing:.42em;
  text-transform:uppercase;color:var(--chalk-3);padding-left:.42em;
}
/*  A grid, not a rail. Nine things in three rows read at a glance; nine
    things in one scrolling line do not, and never did on a phone. */
#rooms-list{
  display:grid;width:100%;gap:.5rem;
  grid-template-columns:repeat(3, minmax(0, 1fr));
}
.room-btn{
  border:1px solid var(--edge);background:rgba(12,14,18,.7);
  color:var(--chalk-2);cursor:pointer;min-height:56px;
  padding:.6rem .5rem .55rem;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.06rem;
  backdrop-filter:blur(3px);
  transition:color .14s var(--ease), border-color .14s var(--ease),
             background .14s var(--ease), transform .07s var(--ease);
}
.room-btn__dial{
  font-weight:700;font-size:.82rem;letter-spacing:.13em;
  text-transform:uppercase;line-height:1.15;
}

.room-btn:hover{color:var(--chalk);border-color:var(--chalk-3)}
.room-btn:active{transform:translateY(2px)}
.room-btn[aria-current="true"]{
  background:var(--haz);border-color:var(--haz);color:#000;
}


/* ── 3  now playing ─────────────────────────────────────────────── */
/*  One title, in Latin, in the sign face — the same rule the two gym
    pages already followed. This page used to set the Devanagari big and
    the Latin small underneath it, so every song said itself twice. */
.now__title{
  font-weight:700;line-height:.94;
  font-size:clamp(1.9rem,6.4vw,4.4rem);
  letter-spacing:-.012em;text-transform:uppercase;color:var(--chalk);
  /*  One line, never two. The `ch` cap and text-wrap:balance were what
      broke a long title across two lines; app.js measures instead and
      scales the type down to fit. Ellipsis is the backstop for a title
      long enough to hit the size floor. */
  /*  min-width:0 is load-bearing. A flex item defaults to
      min-width:auto, which for nowrap text is the min-content width —
      the whole title. That silently overrode max-width and let the box
      grow to 862px inside a 320px screen, so the measuring code saw a
      box that already fitted and never shrank anything. */
  white-space:nowrap;max-width:100%;min-width:0;
  overflow:hidden;text-overflow:ellipsis;
  text-shadow:
    calc(var(--split) * -1) 0 rgba(255,59,45,.8),
    var(--split) 0 rgba(140,233,255,.7);
}

.now__room{
  /*  This is the door to the nine rooms now, so it is a button — but it
      must still read as the label it always was. The chrome only shows
      up on hover and focus; a permanent border here would just be the
      rail again, one row lower. */
  border:1px solid transparent;background:none;cursor:pointer;
  display:flex;gap:.5rem;justify-content:center;align-items:center;
  margin:0 auto;padding:.3rem .7rem .26rem;
  font-family:inherit;
  font-weight:700;font-size:.72rem;letter-spacing:.34em;
  text-transform:uppercase;color:var(--haz);
  transition:border-color .14s var(--ease), background .14s var(--ease);
}
.now__room:hover,.now__room[aria-expanded="true"]{
  border-color:color-mix(in srgb, var(--haz) 40%, transparent);
  background:rgba(12,14,18,.55);
}
.now__caret{
  width:.85em;height:.85em;flex:none;fill:none;
  stroke:currentColor;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;
  opacity:.6;transition:transform .18s var(--ease);
}
.now__room:hover .now__caret{opacity:1}

/* ── 4  the transport ───────────────────────────────────────────── */
/* the seek rail here is a tape counter, not a plate stack */
.bar__fill{
  background-image:none;
  background:linear-gradient(90deg, var(--haz), color-mix(in srgb, var(--haz) 55%, #fff));
}

/* ── 5  narrow screens ──────────────────────────────────────────── */
@media (max-width:760px){
  /*  Two columns rather than three. Three fits, but the Devanagari
      second line starts wrapping and a wrapped plate label is worse
      than a taller grid. */
  #rooms-list{grid-template-columns:repeat(2, minmax(0, 1fr));gap:.4rem}
  .room-btn{min-height:52px;padding:.5rem .4rem .45rem}
  .room-btn__dial{font-size:.74rem;letter-spacing:.08em}
  .now__title{font-size:clamp(1.5rem,6.6vw,2.4rem)}
  #reels{max-width:min(96vh,30rem)}
}
/*  Short screens — a phone on its side, or a laptop with the window
    dragged down. The title here is Devanagari at up to 5rem and it can
    run to two lines, which is a good deal taller than the gym page ever
    gets, so this page needs its own retreat.

    This was already broken before the transport went in: at 1100x560 and
    at 740x420 the play keys landed on top of the control rack, and the
    landscape phone overflowed by 60px. Losing the room rail bought back
    a row, and the rest is taken out of the type and the machine — in
    that order, because the title is what you are here to read. */
@media (max-height:620px){
  #deck{gap:.3rem}
  .now__title{font-size:clamp(1.4rem,4.8vw,2.2rem)}
  #reels{max-width:min(70vh,20rem)}
  #record{height:clamp(4rem, 17vh, 8rem)}
}
@media (max-height:560px){
  /*  This line used to be free to hide on a short screen. It is the only
      way into the rooms now, so it shrinks instead — and the Devanagari
      half is the part that goes. */
  .now__room{padding:.14rem .5rem .1rem;letter-spacing:.24em}
  .now__title{font-size:clamp(1.25rem,4vw,1.8rem)}
  .tags{font-size:.66rem}
}
/*  Below this there is genuinely no room for all of it, and the machine
    is the part that can go: the seek bar already says everything it says.
    Hiding the title instead would be hiding the point of the page. */
@media (max-height:470px){
  #record{display:none}
  #deck{gap:.2rem}
  .now__title{font-size:clamp(1.15rem,3.6vw,1.6rem)}
}

/* ── 6  reduced motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  /*  The reels still turn under reduced motion — that is the readout,
      and removing it would remove information rather than decoration.
      What goes is the beat scaling and the loading flash. */
  #reels{transform:none !important;animation:none !important}
  [data-loading] .rl-head-gap{animation:none !important}
  .now__title{text-shadow:none}
}

/* ── 7  what this page adds to the system ───────────────────────── */
:root{
  /*  The site sets every wordmark and every title once, in Latin, so
      there is no second face to name any more. Khand does all of it. */
  --pop:cubic-bezier(.34,1.42,.64,1);
}

/* the transport behind the loading screen: a halo, not a backdrop */
.boot__art{
  position:absolute;inset:0;display:grid;place-items:center;
  pointer-events:none;opacity:.5;
  /*  Clear enough of the middle that the wordmark sits on open ground.
      At 20% the inner rings still ran under the Latin line. */
  -webkit-mask-image:radial-gradient(ellipse 62% 54% at 50% 50%,
    transparent 34%, #000 58%, transparent 88%);
  mask-image:radial-gradient(ellipse 62% 54% at 50% 50%,
    transparent 34%, #000 58%, transparent 88%);
}
.boot__art svg{width:min(150vh,150vw);height:auto}

/* the filter chips live in the rack, above the rows */
.ix__filters{
  display:flex;flex-wrap:wrap;gap:.35rem;
  padding:0 var(--shell) .8rem;
}
.ix__filters .chip{padding:.32rem .6rem .28rem;font-size:.74rem;letter-spacing:.09em}

/*  artist · film · year. The system sets .tags as a flex row, which is
    right for two short chips and wrong here: "Lata Mangeshkar · M. G.
    Sreekumar" wraps inside its own item and leaves the film stranded
    across a flex gap. As a block it wraps like the prose it is. */
.tags{display:block;max-width:48ch;margin-inline:auto;line-height:1.45}
.tags span{display:inline}
/*  A general sibling, not an adjacent one. Adjacent gets it wrong twice:
    with `span + span` an empty artist leaves a leading "· " on the film,
    and with `span:not(:empty) + span` an empty FILM swallows the
    separator between artist and year. `~` asks only whether some
    non-empty field came before, which is the actual question. */
.tags span:not(:empty) ~ span:not(:empty)::before{content:' · ';opacity:.5}

@media (prefers-reduced-motion:reduce){
  .boot__art svg{animation:none}
}

/*  On a narrow screen the title is allowed past the shell's side padding.
    It is the one element on the page long enough to need it, and at 320px
    those two gutters are about a tenth of the usable width — the
    difference between a title fitting and being ellipsised. */
@media (max-width:480px){
  .now__title{
    width:calc(100% + var(--shell) * 2);
    max-width:calc(100% + var(--shell) * 2);
    margin-inline:calc(var(--shell) * -1);
  }
}
