/* One sheet of the player's design system (tickets/T19-room-for-two.md).
   style.css keeps the fonts, the tokens and the reset; every area has its
   own file from there, linked in index.html in this order — the cascade is
   the order of the <link>s, not of a bundler. A ticket works in its sheet.
   No @import: it serialises the requests, which is the cost being avoided. */

/* ---------- Volume: a scale, a rail of ticks, a cursor ---------- */
/* 20 between the rows: the grab overhangs the rail by 13.5 on each side (T64).
   Above the keys, at the foot of the page, with the keys (T45): the stage takes
   whatever the window has spare, and this margin is what it can never take —
   the least room there is between the record and the controls. No word under
   it any more: a graduated rail with a grab on it says what it is. */
.volume { order: 2; display: grid; row-gap: 20px; margin-top: 48px; }
.scale {
  font-size: 10px;
  line-height: 16px;
  text-transform: uppercase;
}
/* The rail is a texture — a tick every 7px, whole ticks only, so nothing is
   cut on the right when the window is resized. The grab is a small secondary
   key riding on it, 28×48 — the small key's width, the keys' height; it was
   25×40, two sizes of its own (tickets/T64-les-controles.md) — and it shows the
   value only while in hand (hover, drag, keyboard). */
/* The graduation sits on the cursor's course, not on the rail's width: the
   native thumb is 28 wide and travels (100% - 28), its centre 14 further in.
   In space-between, "20" landed at 20 % of the width less its own label — the
   two only ever met at 0 and at 100. Each mark is now centred on the very
   place the cursor stops at that value. */
.scale { position: relative; height: 7px; }   /* the figures' cap band, as the frame counts its gap to the rail — not the 16 line box */
.scale span { position: absolute; left: calc(var(--p) / 100 * (100% - 28px) + 14px); transform: translateX(-50%); }
/* --tick / --pitch: 3 every 7, which large.css scales and deck.js reads back. */
@property --tick { syntax: "<length>"; inherits: true; initial-value: 3px; }    /* registered: read back as px, not as calc() text */
@property --pitch { syntax: "<length>"; inherits: true; initial-value: 7px; }
.rail { --level: 100; --tick: 3px; --pitch: 7px; position: relative; height: 21px; }
.rail::before {
  content: "";
  position: absolute;
  inset: 0;
  width: calc(round(down, 100% + var(--pitch) - var(--tick), var(--pitch)) - var(--pitch) + var(--tick));
  background: repeating-linear-gradient(to right, var(--control) 0 var(--tick), transparent var(--tick) var(--pitch));
}
/* The same ticks, doubling as a meter: each one filled from the bottom by what
   is coming out of the stream. Same geometry as the rail above it — 3 wide,
   4 of gap, whole ticks only — so the two layers land on each other exactly.
   Built by app.js on the first press; without it the rail is just the rail. */
/* A canvas (T127): deck.js paints the ticks, 3 px every 7, in this `color`. */
.meter {
  position: absolute;
  inset: 0;
  display: block;
  width: calc(round(down, 100% + var(--pitch) - var(--tick), var(--pitch)) - var(--pitch) + var(--tick));
  height: 100%;
  color: var(--ink);   /* ponytail: white in dark, ink in light — one token, both modes */
  pointer-events: none;
}

#volume {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  display: block;
  width: 100%;
  height: 48px;         /* the 21px rail with 13.5px of grab above and below: the grab's own 48 (T64) */
  margin: -13.5px 0;
  background: none;
  cursor: grab;
}
#volume:active { cursor: grabbing; }
#volume::-webkit-slider-runnable-track { height: 21px; background: none; }
#volume::-moz-range-track { height: 21px; background: none; }
#volume::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 28px; height: 48px; margin-top: -13.5px; border: 0; background: none; }
#volume::-moz-range-thumb { width: 28px; height: 48px; border: 0; background: none; }
.grab {
  --plinth-ink: rgba(0, 0, 0, 0.16);
  position: absolute;
  top: 50%;
  left: calc(var(--level) / 100 * (100% - 28px));   /* the native thumb's travel */
  width: 28px;
  height: 48px;
  transform: translateY(-50%);
  pointer-events: none;
  font-size: 12px;   /* a key's figure, Body/UI Small, as on every other key (T64) */
  background: var(--control);
  color: var(--ink);
}
.grab__value { margin-bottom: 4px; opacity: 0; transition: opacity 120ms ease, transform 80ms ease; }   /* the plinth is 4 tall: the figure centres in the face above it, not in the box */
.rail:active .grab__value, .rail:has(:focus-visible) .grab__value { opacity: 1; }
@media (hover: hover) {
  /* …and anywhere on the component, since the wheel sets the level from there
     too (tickets/T14). Behind the query with the rest: a finger that taps the
     rail leaves the figure showing until the next tap otherwise. */
  .volume:hover .grab__value { opacity: 1; }
  .rail:hover .grab::after { transform: scaleY(1); }
  .rail:hover .grab { box-shadow: 0 8px 10px rgba(0, 0, 0, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.5); }
  .rail:hover .grab::before { background: rgba(255, 255, 255, 0.06); }
}
.rail:active .grab::after { transform: scaleY(0.167); }
.rail:active .grab > * { transform: translateY(3px); }
.rail:active .grab { box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08), inset 0 2px 4px rgba(0, 0, 0, 0.18); }
.rail:active .grab::before { background: rgba(0, 0, 0, 0.08); }

/* iOS will not let a page lower the stream, only mute it (tickets/T50): no
   fader there, no figures, no presets, no ticks at rest. What stays is the
   meter, standing only while the music plays — the rail keeps its height, so
   nothing moves when it does. */
.no-fader .scale, .no-fader .rail::before, .no-fader #volume, .no-fader .grab { visibility: hidden; }
.no-fader .steps { display: none; }   /* in the bar, the presets give their room back */

/* A phone (T146): the rail gives the sleeve its room back. Ticks of 14 and a
   grab of 32 — the small key's height — 9 over the rail on each side, so 14
   between the rows clears it. The finger keeps its 48: the input still spans
   it, overhanging the 14 by 17 each way. */
@media (max-width: 640px) {
  .volume { row-gap: 14px; }
  .rail { height: 14px; }
  #volume { margin: -17px 0; }
  #volume::-webkit-slider-runnable-track { height: 14px; }
  #volume::-moz-range-track { height: 14px; }
  #volume::-webkit-slider-thumb { margin-top: -17px; }
  .grab { height: 32px; }
}
