/* nobody fm: the skeleton. layout only, no colour, no face, no glow: those belong to a theme (design 12.0),
   loaded after this file from themes/<name>/theme.css. a theme may override anything here. */

/* the column budget is the skeleton's: 100 columns on desktop, 40 on a phone; every layout decision in the JS reads it */
:root { --cols: 100; }
@media (max-width: 900px) {
  :root { --cols: 40; }
}

html, body { height: 100%; }
body { margin: 0; overflow: hidden; -webkit-text-size-adjust: 100%; }
[hidden] { display: none !important; }

pre {
  margin: 0;
  font: inherit;
  white-space: pre;
  overflow: hidden;
}
.row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  white-space: pre;
  min-height: var(--row);
  gap: 1ch;
  overflow: hidden;
}
.row > .left, .row > .right { white-space: pre; }
.row > .right { flex: 0 0 auto; }
.row > .left { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: clip; }

/* every [ bracket ] is a real button; the theme draws the brackets and the hover */
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  text-shadow: inherit;
  white-space: pre;
  line-height: inherit;
}
button:focus { outline: 0; }

.screen {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--gutter);
  box-sizing: border-box;
  scrollbar-width: none;
}
.screen::-webkit-scrollbar { display: none; }
#main {
  width: min(100%, calc(var(--cols) * 1ch));
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 2 * var(--gutter));
}
.band.footer { margin-top: auto; }
/* a theme that owns the browsing paradigm (design 12.0, the interface hooks, issue #53) gets the pointer where no card is: the
   glass lets it through to the scene and the cards take it back. only while such a theme is on; the other themes see no change. */
body[data-interface]:not([data-interface=""]) .glass { pointer-events: none; }
body[data-interface]:not([data-interface=""]) .glass .band, body[data-interface]:not([data-interface=""]) .glass .boot, body[data-interface]:not([data-interface=""]) .overlay { pointer-events: auto; }

/* boot */
.boot { width: min(100%, calc(var(--cols) * 1ch)); margin: 0 auto; min-height: calc(100vh - 2 * var(--gutter)); }
.boot-lines { min-height: calc(var(--row) * 9); }
.banner { margin-top: var(--row); padding-left: 8ch; min-height: calc(var(--row) * 5); white-space: pre; }
.boot-tag { padding-left: 8ch; margin-top: var(--row); }
.boot-wait { padding-left: 8ch; margin-top: var(--row); min-height: var(--row); white-space: pre; }
@media (max-width: 900px) {
  .banner, .boot-tag, .boot-wait { padding-left: 0; }
}

/* transmitter */
.transmitter { position: relative; }
/* the volume fader (design 12.0, controls): the word or glyph that mutes, a rail at least 160 px wide on desktop and the
   card's width on the phone, a 44 px hit area (the rail's ::before reaches 10 px above and below it), the handle, and the
   readout of the notch that appears while the control is touched (hover, focus, a drag). colour is the theme's. */
.transmitter > .row:first-child { align-items: center; overflow: visible; }
.vol { display: inline-flex; align-items: center; gap: 1ch; flex: 0 1 auto; min-width: 0; white-space: pre; }
.vol .vol-mute { display: inline-flex; align-items: center; gap: .5ch; flex: 0 0 auto; }
.vol .vol-word { letter-spacing: .08em; }
.vol .vol-spk { display: none; width: 20px; height: 20px; overflow: visible; }
.vol .vol-spk .spk-body { fill: currentColor; }
.vol .vol-spk .spk-waves, .vol .vol-spk .spk-cross { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.vol .vol-spk .spk-cross { display: none; }
.vol.muted .vol-spk .spk-waves { display: none; }
.vol.muted .vol-spk .spk-cross { display: block; }
.vol .vol-rail { position: relative; z-index: 1; flex: 1 1 200px; min-width: 160px; max-width: 280px; height: 24px; cursor: pointer; touch-action: none; user-select: none; -webkit-user-select: none; outline: 0; }
.vol .vol-rail::before { content: ""; position: absolute; left: 0; right: 0; top: -10px; bottom: -10px; }
.vol .vol-track { position: absolute; left: 0; right: 0; top: 50%; height: 6px; margin-top: -3px; border-radius: 3px; overflow: hidden; }
.vol .vol-fill { height: 100%; width: 70%; border-radius: 3px; }
.vol .vol-handle { position: absolute; top: 50%; left: 70%; width: 16px; height: 16px; margin: -8px 0 0 -8px; border-radius: 50%; pointer-events: none; }
.vol .vol-read { flex: 0 0 auto; width: 6ch; text-align: left; opacity: 0; transition: opacity .15s; }
.vol:hover .vol-read, .vol:focus-within .vol-read, .vol.dragging .vol-read { opacity: 1; }
.vol .vol-deco { display: inline-flex; align-items: center; flex: 0 0 auto; }
.vol .vol-deco:empty { display: none; }
@media (prefers-reduced-motion: reduce) { .vol .vol-read { transition: none; } }

/* MAKE A TRACK (design 12.0, controls): one input, [ request ] and [ remix what's playing ], one line of state under them */
.make-form { display: flex; align-items: center; flex-wrap: wrap; gap: 0 1ch; min-height: var(--row); white-space: pre; }
.make-form .make-mark { flex: 0 0 auto; }
.make-form #makeWords { font: inherit; background: none; border: 0; outline: 0; padding: 0; margin: 0; flex: 1 1 24ch; min-width: 14ch; line-height: inherit; }
.make-form .make-buttons { flex: 0 0 auto; white-space: pre; }
.make-line { min-height: var(--row); white-space: pre-wrap; overflow-wrap: anywhere; margin-top: calc(var(--row) * .2); }
.make-line .bk { white-space: pre; }
/* the widget slot (design 12.0, issue #28): a theme may mount one signature widget in the transmitter card
   (a cassette, a big scrubber); the skeleton only gives it a block and a top margin, the theme does the rest */
.tx-widget { display: block; margin-top: calc(var(--row) * .5); }
.np-row .meta { flex: 0 0 auto; }
/* the readout wraps the whole prompt; it is never truncated (issue #43) */
.readout {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  min-height: var(--row);
}
.progress { cursor: pointer; margin-top: calc(var(--row) * .5); }
.dial { margin-top: calc(var(--row) * .5); white-space: pre; }
#spectrum {
  display: block;
  width: 100%;
  height: calc(var(--row) * 5);
  margin-top: calc(var(--row) * .5);
  cursor: pointer;
}
#spectrum.scope5 { height: calc(var(--row) * 5); }
.baseline { white-space: pre; }
.scope { margin-top: calc(var(--row) * .5); white-space: pre; }
.scope.tall { white-space: pre; }
.deadair .deadair-text { margin: 0 0 calc(var(--row) * .5); white-space: pre-wrap; }
.tower-wrap { position: relative; height: calc(var(--row) * 12); overflow: hidden; }
.tower { position: absolute; inset: 0; display: flex; justify-content: center; align-items: center; }
.tower-static { position: absolute; inset: 0; margin: 0 auto; text-align: left; width: max-content; left: 50%; transform: translateX(-50%); }
.reread { position: absolute; right: 1ch; bottom: var(--row); }
.bed { margin-top: calc(var(--row) * .5); }
.fat { display: none; }

/* catalogue */
.cat-rows { max-height: calc(var(--row) * 7); overflow-y: auto; scrollbar-width: none; }
.cat-rows::-webkit-scrollbar { display: none; }
.cat-row {
  display: block;
  width: 100%;
  text-align: left;
  white-space: pre;
  overflow: hidden;
}
.cat-row.hidden-row { display: none; }
.cat-head .sort { cursor: pointer; }
/* the two affordances at the end of a row: + queues, remix goes to the MAKE A TRACK card (shown on hover, always on a phone) */
.cat-row .plus, .cat-row .rmx { cursor: pointer; }

/* terminal */
.terminal .log {
  height: calc(var(--row) * 6);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.log .line { min-height: var(--row); flex: 0 0 auto; }
.log .line.print { white-space: pre; overflow: hidden; }
.prompt-row { display: flex; align-items: baseline; white-space: pre; min-height: var(--row); cursor: text; }
#cmd {
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  outline: 0;
  caret-color: transparent;
  width: 1ch;
  min-width: 1ch;
  max-width: calc(100% - 10ch);
  line-height: inherit;
}
.hint-row .wire { flex: 0 0 auto; }

/* footer, odometer */
.footer .odo-row { justify-content: flex-start; align-items: center; gap: 2ch; padding: calc(var(--row) * .5) 0; }
.odometer { display: inline-flex; gap: 0; }
.drum {
  position: relative;
  width: 2.2ch;
  height: var(--row);
  overflow: hidden;
}
.drum .reel {
  position: absolute;
  left: 0; right: 0; top: 0;
  text-align: center;
  transition: transform 700ms cubic-bezier(.2, .9, .3, 1);
}
.drum .reel span { display: block; height: var(--row); line-height: var(--row); }
.footer .footer-buttons { padding: calc(var(--row) * .25) 0; }
.footer .licence { margin: calc(var(--row) * .5) 0 0; white-space: pre-wrap; }

/* pages */
.page { flex: 1 1 auto; overflow-y: auto; scrollbar-width: none; }
.page::-webkit-scrollbar { display: none; }
.page h2 { font: inherit; margin: var(--row) 0 0; text-transform: uppercase; display: flex; justify-content: space-between; white-space: pre; }
.page p { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.page .buttons { display: flex; flex-wrap: wrap; gap: 0 1ch; margin: calc(var(--row) * .5) 0; }
/* the action row (design 12.0, controls): play, remix this and take it home first and biggest; the copy actions smaller under them */
.page .buttons.primary { gap: .2em 1.5ch; margin-bottom: calc(var(--row) * .25); align-items: center; }
.page .buttons.primary .bk { font-size: calc(var(--fs) * 1.2); line-height: 1.4; }
.page .buttons.secondary { margin-top: 0; }
.page .tree .bk { white-space: pre; }
.page .lyrics { white-space: pre-wrap; }
.page table { border-collapse: collapse; white-space: pre; }
.page td { padding: 0 2ch 0 0; vertical-align: top; }
.page .numbers { display: flex; flex-wrap: wrap; gap: 0 3ch; white-space: pre; }
.page .tree { white-space: pre; }
.page .take-block { margin-top: calc(var(--row) * .25); }
.page .catview { white-space: pre-wrap; max-height: calc(var(--row) * 14); overflow: auto; padding-left: 1ch; margin-top: calc(var(--row) * .5); }
.gb-form .field { display: flex; white-space: pre; align-items: baseline; }
.gb-form input { font: inherit; background: none; border: 0; outline: 0; padding: 0; flex: 1 1 auto; min-width: 0; }
.gb-form .gb-buttons { display: flex; justify-content: flex-end; gap: 2ch; margin: calc(var(--row) * .25) 0 var(--row); }
.gb-entry { display: grid; grid-template-columns: 7ch 17ch 12ch 1fr auto; gap: 0 1ch; white-space: pre; overflow: hidden; }
.gb-entry .gb-line { white-space: pre-wrap; overflow-wrap: anywhere; }
.gb-more { margin-top: var(--row); }

/* help overlay */
.overlay {
  position: fixed;
  left: 50%;
  top: 8vh;
  transform: translateX(-50%);
  width: min(100vw - 2 * var(--gutter), calc(var(--cols) * 1ch));
  max-height: 84vh;
  overflow: auto;
  box-sizing: border-box;
  z-index: 40;
  scrollbar-width: none;
}
.overlay::-webkit-scrollbar { display: none; }
.help-body { margin-top: calc(var(--row) * .5); }
.help-body pre { white-space: pre; }
.help-body .help-list { display: flex; flex-wrap: wrap; gap: .5ch 1ch; }

/* phone (40 columns) */
@media (max-width: 900px) {
  .tagline-h, .header .up, #shuffleLabel { display: none; }
  .np-row { flex-direction: column; align-items: flex-start; gap: 0; }
  /* the fader takes the card's full width under the label; the hit area stays 44 px */
  .transmitter > .row:first-child { flex-wrap: wrap; }
  .vol { flex: 1 1 100%; }
  .vol .vol-rail { max-width: none; flex: 1 1 auto; }
  .make-form .make-buttons { flex: 1 1 100%; margin-top: calc(var(--row) * .2); }
  /* the page header at 390 px: `playing: <slug...>  <time>  [chip]`; the name and the small bar go, the slug gets an ellipsis, the chip is never overlapped (issue #43) */
  .header-page .left { white-space: pre; display: flex; align-items: baseline; min-width: 0; overflow: hidden; }
  .header-page .left > * { flex: 0 0 auto; }
  .header-page #stationName2, .header-page #hdrBar, .header-page #hdrBack { display: none; }
  .header-page #hdrSlug { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .footer-buttons { flex-wrap: wrap; }
  .footer-buttons .left { white-space: normal; flex: 1 1 100%; line-height: calc(var(--row) * 1.2); }
  .footer-buttons .right { flex: 1 1 100%; text-align: left; }
  .fat { display: flex; justify-content: space-around; padding: calc(var(--row) * .5) 0 calc(var(--row) * .25); margin-top: calc(var(--row) * .5); }
  .fat .bk { font-size: calc(var(--fs) * 1.1); padding: 0 1ch; min-width: 8ch; text-align: center; }
  #spectrum { height: calc(var(--row) * 4); }
  .terminal .log { height: calc(var(--row) * 3); }
  .cat-rows { max-height: none; }
  .hint-row .hints { display: none; }
  .gb-entry { grid-template-columns: 7ch 6ch 1fr; }
  .gb-entry .gb-line, .gb-entry .gb-tag { grid-column: 1 / -1; padding-left: 2ch; }
  .footer .odo-row { flex-wrap: wrap; }
  .overlay { top: 4vh; max-height: 92vh; }
  .page .numbers { display: block; }
  .page .numbers span { display: block; }
}

/* hidden mode (design 12.0, issue #52): body.ui-hidden fades the interface and leaves the theme's scene running. layout and timing
   only; a theme gives the ink (--hide-ink to --hide-ink2, bottom to top) and the title's face (--hide-face) */
.screen { transition: opacity 400ms ease-out, visibility 0s linear 0s; }
body.ui-hidden .screen, body.ui-hidden .overlay { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 400ms ease-out, visibility 0s linear 400ms; }
#hideViz { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; opacity: 0; transition: opacity 400ms ease-out; }
body.ui-hidden:not(.no-hideviz) #hideViz { opacity: 1; }
#hideTitle {
  position: fixed; left: 0; right: 0; bottom: 14vh; z-index: 3; padding: 0 var(--gutter, 24px);
  text-align: center; pointer-events: none; opacity: 0;
  font-family: var(--hide-face, inherit); font-size: clamp(18px, 3vw, 32px); letter-spacing: .12em; text-transform: uppercase;
  color: var(--hide-ink, #fff); text-shadow: 0 0 3px #000, 0 0 16px rgb(0 0 0 / .85);
}
#hideTitle.show { animation: hidehint 3.6s ease-out forwards; }
@keyframes hidehint { 0% { opacity: 0; } 11% { opacity: 1; } 72% { opacity: 1; } 100% { opacity: 0; } }
body.ui-hidden.cursor-idle, body.ui-hidden.cursor-idle * { cursor: none !important; }
@media (prefers-reduced-motion: reduce) {
  .screen, body.ui-hidden .screen, body.ui-hidden .overlay, #hideViz { transition-duration: 1ms; }
}
