:root {
  --bg: #0b0b0d;
  --fg: #f2f2f4;
  --dim: #9a9aa2;
  --line: #232329;
  --accent: #2e78ff;
  /* The three headings on the remote screen each have their own colour.
     Blue for what is playing, green for Featured and for Growing Fast. */
  --growing: #34c759;
  --featured: #34c759;
  --hot: #ff3b30;
  --panel: #141418;
  --safe: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* A rule like .chipRow { display: flex } beats the browser's own hidden rule,
   so hiding something by setting hidden quietly did nothing. This makes hidden
   mean hidden everywhere. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font: 15px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  overscroll-behavior: none;
}

#app {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

#stage {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  position: relative;
}
#player, #player iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

#attrib {
  padding: 6px 14px 0;
  color: var(--dim);
  font-size: 11px;
  letter-spacing: 0.02em;
}

#info {
  flex: 1;
  padding: 10px 14px 16px;
  touch-action: pan-y;
  user-select: none;
}

.chip {
  display: inline-block;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 10px;
}
.chip.tv { border-color: var(--accent); color: var(--accent); }

.title {
  display: block;
  color: var(--fg);
  text-decoration: none;
  font-size: 19px;
  font-weight: 650;
  line-height: 1.25;
}

.meta {
  margin-top: 8px;
  color: var(--dim);
  font-size: 13px;
}

.hint {
  margin-top: 18px;
  color: #56565e;
  font-size: 12px;
}

#dock {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 80;
  background: var(--bg);
  border-top: 1px solid var(--line);
  padding-bottom: var(--safe);
}

/* The control pad. Two rows of two, full width. Skip Ad and Tune are on top
   because they are looked at. Next and Hide are on the bottom row, twice the
   height, because they are pressed by feel. */
/* The playback bar. Three buttons, the ones touched constantly while
   watching, so they are the big reachable ones. Back was taken off. */
#strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--line);
}

/* The steering bar. Used when shaping the surf rather than driving it, so it
   is quieter, shorter and visually a different thing. Darker, with the
   buttons separated as pills rather than filling the width edge to edge, so
   there is no mistaking it for the playback bar above. */
#shapeBar {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  padding: 6px 8px;
  background: #0a0a0e;
  border-top: 1px solid var(--line);
}
.shapeb {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: none;
  border: 1px solid #2c2c38;
  border-radius: 999px;
  color: var(--dim);
  padding: 7px 4px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  min-width: 0;
}
.shapeb em { font-style: normal; white-space: nowrap; }
.shapeb .shapeIcon {
  display: inline-flex;
  align-items: center;
  font-size: 15px;
  line-height: 1;
}
.shapeb:active { color: var(--accent); border-color: var(--accent); }
.shapeb.on { color: var(--accent); border-color: var(--accent); }

/* If the screen is short, the steering bar gives way first. The playback bar
   is never the thing that shrinks. */
@media (max-height: 700px) {
  #shapeBar { padding: 4px 8px; gap: 5px; }
  .shapeb { padding: 5px 3px; font-size: 11px; }
  .shapeb .shapeIcon { font-size: 13px; }
}
@media (max-height: 620px) {
  .shapeb em { display: none; }
  .shapeb { padding: 6px 3px; }
}

#nav {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
}

.navb {
  background: var(--bg);
  border: 0;
  color: var(--dim);
  font: inherit;
  font-size: 12px;
  padding: 9px 4px 10px;
}
.navb:active { background: #1e1e24; color: var(--fg); }
.navb.on { color: var(--accent); }

/* Keep content clear of the fixed pad. The height is measured at startup
   and on every rotation, so a taller pad never covers anything. */
#app { padding-bottom: calc(var(--dock, 250px) + 16px + var(--safe)); }
.toast { bottom: calc(var(--dock, 250px) + 30px + var(--safe)); }

.btn {
  background: var(--panel);
  border: 0;
  color: var(--fg);
  /* Every button identical. One row, five equal shares of the width. */
  padding: 18px 1px 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font: inherit;
  min-width: 0;
}
.btn span { font-size: 24px; line-height: 1; }
.btn em {
  font-style: normal;
  font-size: 11px;
  color: var(--dim);
  white-space: nowrap;
}
/* The drawn icons match the emoji beside them. */
.btn .wheel svg { width: 24px; height: 24px; }

.btn.small, .btn.big { padding: 0; grid-column: auto; }
.btn:active { background: #1e1e24; }
.btn.on span, .btn.on em { color: var(--accent); }

.sheet {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.72);
  display: flex;
  align-items: flex-end;
  z-index: 50;
}
.sheet[hidden] { display: none; }

.sheetInner {
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--panel);
  border-top: 1px solid var(--line);
  border-radius: 18px 18px 0 0;
  padding-top: 18px;
  padding-left: 16px;
  padding-right: 16px;
  /* clears the fixed control strip, whose real height is measured on load */
  padding-bottom: calc(var(--dock, 100px) + 20px + var(--safe));
}

/* Action buttons ride at the bottom of the sheet and stay reachable */
.sheetActions {
  position: sticky;
  bottom: 0;
  background: var(--panel);
  padding-top: 10px;
  padding-bottom: 4px;
  box-shadow: 0 -10px 14px -6px var(--panel);
}

.sheetInner h2 { margin: 0 0 14px; font-size: 17px; }

.lbl {
  display: block;
  margin: 18px 0 7px;
  font-size: 13px;
  color: var(--dim);
}

.inp {
  width: 100%;
  background: #0b0b0d;
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 10px;
  padding: 11px 12px;
  font: inherit;
}
input[type=range] { padding: 0; accent-color: var(--accent); }

.row { display: flex; gap: 8px; margin-top: 12px; }

.wide {
  width: 100%;
  margin-top: 10px;
  background: #222229;
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 11px;
  padding: 13px;
  font: inherit;
  font-weight: 600;
}
.wide:active { background: #2c2c35; }
.wide.danger { color: #ff6b60; }

.note { margin-top: 8px; font-size: 12px; color: var(--dim); min-height: 15px; }

.laneRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 2px;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
}
.laneRow button {
  background: none;
  border: 1px solid var(--line);
  color: var(--dim);
  border-radius: 999px;
  padding: 5px 13px;
  font: inherit;
  font-size: 12px;
}
.laneRow button.on { color: var(--accent); border-color: var(--accent); }

.pickRow {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--fg);
  padding: 15px 2px;
  font: inherit;
  font-size: 16px;
}
.pickRow.cur { color: var(--accent); font-weight: 650; }
.pickRow small { color: var(--dim); font-size: 12px; }

.toast {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(86px + var(--safe));
  background: #26262e;
  border: 1px solid var(--line);
  color: var(--fg);
  padding: 10px 16px;
  border-radius: 999px;
  font-size: 13px;
  z-index: 90;
  max-width: 84vw;
  text-align: center;
}
.toast[hidden] { display: none; }

/* Left over from the old TV only design, where picking a television turned the
   phone into a remote and the video was hidden completely.

   That is not how it works any more. The phone always plays. Choosing a
   television adds it on top, and the phone carries on showing the picture with
   its own sound muted. This rule was hiding the whole stage the moment a
   television was chosen, which is why the phone showed no video while
   insisting it was playing on both.

   Nothing styles the tvonly class now. The class itself is left in place in
   case anything else reads it. */

/* Remote mode. While a television is playing the video the phone does not
   play it, so the video area gives way to a small card saying what is on and
   the rest of the screen is left open.

   The player is moved off screen rather than removed, so it is ready the
   moment the video comes back to the phone. */
body.casting #stage {
  position: absolute;
  left: -9999px;
  top: 0;
  width: 320px;
  height: 180px;
  pointer-events: none;
}
body.casting #attrib,
body.casting #now { display: none; }

.castNow { padding: 16px 14px 10px; touch-action: pan-y; user-select: none; }
.castWhere {
  text-align: center;
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: 10px;
}
.castCard { display: flex; gap: 14px; align-items: center; }
.castThumb {
  position: relative;
  flex: 0 0 50%;
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  overflow: hidden;
  background: #000;
}
.castThumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.castThumb .tapMark { width: 46px; height: 46px; margin: -23px 0 0 -23px; font-size: 19px; }
.castWords { flex: 1; min-width: 0; }
.castTitle {
  font-size: 18px;
  font-weight: 650;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.castChannel { color: var(--dim); font-size: 14px; margin-top: 6px; }
.promoWhere { color: var(--dim); margin-top: 22px; text-align: center; font-size: 15px; }
.discoverWhere { margin: 12px 14px 10px; color: var(--growing); }
/* On the phone face the scroll is a compact strip under the playing video,
   so its heading is smaller and tighter to match. */
body:not(.casting) .discoverWhere { margin: 10px 14px 6px; font-size: 12px; }
.promoCard { color: var(--fg); text-decoration: none; cursor: pointer; transition: opacity 350ms ease; }
.promoCard.fading { opacity: 0; }

/* The Featured label and the featured title flash together, a steady pulse
   between white and green, so the eye goes to them. Held still for anyone
   whose phone asks for less motion. */
.promoCard .castTitle,
.promoWhere { animation: promoFlash 1.2s ease-in-out infinite; }
@keyframes promoFlash {
  0%, 100% { color: var(--fg); }
  50% { color: var(--featured); }
}
@media (prefers-reduced-motion: reduce) {
  .promoCard .castTitle,
  .promoWhere { animation: none; }
}

/* Remote screen */
.rTop {
  display: flex;
  gap: 10px;
  margin-bottom: 10px;
}

.rk {
  flex: 1;
  background: #22222a;
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 14px;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  padding: 18px 6px;
  min-height: 58px;
}
.rk:active { background: var(--accent); border-color: var(--accent); color: #fff; }

.rPad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 10px;
  margin: 6px 0 14px;
}
.rUp { grid-area: 1 / 2; }
.rLeft { grid-area: 2 / 1; }
.rOk { grid-area: 2 / 2; border-radius: 999px; font-size: 17px; }
.rRight { grid-area: 2 / 3; }
.rDown { grid-area: 3 / 2; }
.rPad .rk { min-height: 66px; }

#nav.noTv { grid-template-columns: repeat(2, 1fr); }

.prompt {
  margin: 14px 14px 0;
  padding: 12px 14px;
  background: #1b2338;
  border: 1px solid #2e78ff;
  border-radius: 12px;
  color: #cddcff;
  font-size: 13px;
  line-height: 1.45;
}
.prompt[hidden] { display: none; }

.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
textarea.inp { resize: vertical; line-height: 1.4; }
.laneRow .rowBtns { display: flex; gap: 8px; }
.laneRow em { font-style: normal; color: var(--dim); font-size: 11px; display: block; }

.seg { display: flex; gap: 8px; }
.seg button {
  flex: 1;
  background: #22222a;
  border: 1px solid var(--line);
  color: var(--dim);
  border-radius: 11px;
  padding: 12px 4px;
  font: inherit;
  font-size: 13px;
}
.seg button.on { color: var(--accent); border-color: var(--accent); font-weight: 600; }

#topbar {
  display: flex;
  justify-content: flex-end;
  padding: 8px 14px 0;
}
.tvpick {
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--dim);
  border-radius: 999px;
  padding: 7px 14px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}
.tvpick.set { color: var(--accent); border-color: var(--accent); }



.linkBtn {
  background: none;
  border: 0;
  color: var(--accent);
  font: inherit;
  font-size: 13px;
  padding: 12px 0 4px;
  text-decoration: underline;
}



.resName { font-size: 22px; font-weight: 650; margin-top: 4px; }
.resDesc { color: var(--fg); font-size: 14px; margin-top: 6px; line-height: 1.45; }
.resStats { color: var(--dim); font-size: 12px; margin-top: 10px; }
.resItem {
  border-top: 1px solid var(--line);
  padding: 11px 0;
  font-size: 14px;
  line-height: 1.35;
}
.resItem small { display: block; color: var(--dim); font-size: 12px; margin-top: 3px; }

/* Round five: the lane name is a label now, not a control */


/* Browse rows indent by depth so the tree reads as a tree */
.treeRow { padding-left: 0; }
.treeRow.d1 { padding-left: 18px; }
.treeRow.d2 { padding-left: 36px; }
.treeRow.d3 { padding-left: 54px; }
.treeRow.d4 { padding-left: 72px; }
.treeRow small { color: var(--dim); font-size: 12px; }

/* Topic picker. Rows indent by depth and carry a checkbox on the right. */
.topRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 2px;
  border-bottom: 1px solid var(--line);
}
.topRow .nm { font-size: 15px; }
.nmBtn {
  flex: 1;
  text-align: left;
  background: none;
  border: 0;
  color: var(--fg);
  font: inherit;
  padding: 2px 0;
}
.nmBtn small { display: block; color: var(--dim); font-size: 12px; margin-top: 2px; }
.nmBtn.into .nm::after { content: "  \203A"; color: var(--dim); }
.topRow.group .nm { font-weight: 650; }
.topRow.league .nm { font-weight: 600; color: var(--fg); }
.topRow.team .nm { font-size: 14px; color: var(--dim); }

.ctrls { display: flex; gap: 8px; flex: 0 0 auto; }

.box {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: #0b0b0d;
  color: var(--dim);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
}
.box.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.box.x { font-weight: 400; font-size: 13px; }
.box.dim { opacity: 0.35; }

/* Two plainly labelled buttons. No cycling, no hidden meanings. */
.pill {
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #0b0b0d;
  color: var(--dim);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 9px 12px;
  min-width: 68px;
}
.pill.follow.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.pill.block.on {
  background: #3a1d1d;
  border-color: #ff6b60;
  color: #ff6b60;
}

.secLbl {
  margin: 18px 0 8px;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
}



.topRow.off .nm { color: #5c5c64; text-decoration: line-through; }

.foldBtn {
  background: none;
  border: 0;
  color: var(--dim);
  font: inherit;
  font-size: 12px;
  padding: 4px 8px;
}

.chipRow { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.chip.refresh { font-weight: 500; color: var(--dim); }
.chip.refresh:active { color: var(--accent); border-color: var(--accent); }
.chip.refresh.busy { color: var(--accent); border-color: var(--accent); }

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-bottom: 6px;
}
.crumb {
  background: none;
  border: 0;
  color: var(--accent);
  font: inherit;
  font-size: 13px;
  padding: 6px 2px;
}
.crumb.cur { color: var(--fg); font-weight: 650; }
.crumbSep { color: var(--dim); font-size: 13px; }

.topRow.group .nm, .topRow.league .nm { font-weight: 600; }
.topRow { min-height: 54px; }

/* Add Me card */
.addThumb {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 12px;
  background: #000;
  margin-bottom: 12px;
}
.addName { font-size: 22px; font-weight: 650; line-height: 1.2; }
.addSub { color: var(--dim); font-size: 13px; margin-top: 6px; line-height: 1.45; }
.addItem {
  border-top: 1px solid var(--line);
  padding: 11px 0;
  font-size: 14px;
  line-height: 1.35;
}
.addItem small { display: block; color: var(--dim); font-size: 12px; margin-top: 3px; }

/* A lane that has not gathered enough channels to be worth opening yet */
.topRow.building .nm { color: #6a6a74; }
.topRow.building .buildNote { color: var(--accent); }
.topRow.building .pill.follow { opacity: 0.75; }

/* ---------- the surf screen ---------- */

.chipRow {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 4px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.chipRow::-webkit-scrollbar { display: none; }

.chipList { display: flex; gap: 8px; }

.chipRow .chip {
  flex: 0 0 auto;
  margin-bottom: 0;
  white-space: nowrap;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--dim);
  border-radius: 999px;
  padding: 9px 15px;
  font-size: 14px;
  font-weight: 600;
}
.chipRow .chip.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.chipRow .chip.shuffle {
  border-style: dashed;
  border-color: #4a4a56;
  color: var(--fg);
}
.chipRow .chip.shuffle.on {
  border-style: solid;
  background: #2a2a34;
  border-color: var(--accent);
  color: var(--accent);
}
.chipRow .chip.add {
  font-size: 18px;
  font-weight: 400;
  padding: 7px 16px;
  color: var(--dim);
}
.chipRow .chip.removing {
  background: #3a1d1d;
  border-color: #ff6b60;
  color: #ff6b60;
}

.freshRow {
  display: flex;
  gap: 6px;
  padding: 8px 12px 10px;
  overflow-x: auto;
  scrollbar-width: none;
}
.freshRow::-webkit-scrollbar { display: none; }
.freshRow .fresh {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--line);
  color: var(--dim);
  border-radius: 999px;
  padding: 6px 13px;
  font: inherit;
  font-size: 12px;
  white-space: nowrap;
}
.freshRow .fresh.on { color: var(--accent); border-color: var(--accent); font-weight: 600; }
.freshRow .fresh.custom::after { content: " \2022"; color: var(--accent); }

#now { padding: 12px 14px 16px; touch-action: pan-y; user-select: none; }

#now .tags {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.tag {
  font-size: 12px;
  border-radius: 999px;
  padding: 5px 11px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--dim);
  font-weight: 600;
  white-space: nowrap;
}
.tag.source { color: var(--accent); border-color: var(--accent); }
.tag.tv { font: inherit; font-size: 12px; font-weight: 600; }
.tag.tv.set { color: var(--fg); }


.subjRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 2px;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
}
.subjRow small { display: block; color: var(--dim); font-size: 12px; margin-top: 2px; }
.subjRow button {
  flex: 0 0 auto;
  background: #22222a;
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 999px;
  padding: 8px 14px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}
.subjRow button.have { color: var(--dim); border-color: var(--line); background: none; }

#strip .btn em { font-size: 10px; }
.undoToast { display: flex; align-items: center; gap: 12px; }
.undoToast button {
  background: none; border: 0; color: var(--accent);
  font: inherit; font-size: 13px; font-weight: 700; padding: 0;
}

/* Developer review mode. Never visible to a customer. */
.devPanel {
  margin-top: 14px;
  padding: 12px;
  background: #12121a;
  border: 1px solid #2a2a3a;
  border-radius: 12px;
}
.devStreams { display: flex; gap: 6px; margin-bottom: 10px; }
.devTab {
  flex: 1;
  background: none;
  border: 1px solid var(--line);
  color: var(--dim);
  border-radius: 999px;
  padding: 8px 6px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}
.devTab.on { color: var(--accent); border-color: var(--accent); }
.devTab.alt { flex: 0 0 auto; padding: 8px 14px; }

.devVerdict { font-size: 13px; font-weight: 700; margin-bottom: 6px; }
.devVerdict.accepted { color: #4ade80; }
.devVerdict.rejected { color: #ff6b60; }

.devWhy {
  font-size: 12px;
  line-height: 1.5;
  color: var(--dim);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre-wrap;
}
.devActions { margin-top: 10px; }
.devRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.devRow small { display: block; color: var(--dim); font-size: 11px; }
.devRow button {
  background: none; border: 1px solid var(--line); color: var(--dim);
  border-radius: 999px; padding: 6px 12px; font: inherit; font-size: 12px;
}

/* The steering menu. Broad choices first, specific ones last. */
.tuneRow {
  display: block;
  width: 100%;
  text-align: left;
  background: #1a1a22;
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 12px;
  padding: 14px 15px;
  margin-top: 9px;
  font: inherit;
  font-size: 15px;
  line-height: 1.3;
}
.tuneRow:active { border-color: var(--accent); }
.tuneRow small {
  display: block;
  margin-top: 4px;
  color: var(--dim);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.tuneRow.off { border-color: #5a2a2a; }
.tuneRow.off small { color: #ff6b60; }
.tuneLadder { margin-top: 4px; }

/* The Dev button. Plainly labelled, easy to find, easy to remove. */
.tag.dev {
  text-decoration: none;
  color: #8a8a96;
  border-style: dashed;
  border-color: #3a3a46;
  margin-left: auto;
}
.tag.dev:active { color: var(--accent); border-color: var(--accent); }

/* Evaluation mode. A separate page, so nothing here can leak into the
   customer screen by accident. */
.evalBar {
  display: flex;
  gap: 6px;
  padding: 10px 12px 4px;
}
.evalBar .devTab { flex: 1; }
.evalBar .devTab.return {
  flex: 0 0 auto;
  text-decoration: none;
  padding: 8px 14px;
  color: var(--fg);
  border-color: #3a3a46;
}
.evalpage #devPanel { display: block; }
.evalpage #strip { grid-template-columns: repeat(2, 1fr); }
.evalpage .btn { grid-column: auto; }

/* The first choice on every Tune menu. It does what the Keep button did. */
.tuneRow.keep {
  border-color: var(--accent);
}
.tuneRow.keep span { color: var(--accent); font-weight: 700; }

/* Steering. Not a search box, and it must not read like one. */
.steerBox {
  min-height: 84px;
  resize: none;
  line-height: 1.45;
}
.wide.go { background: var(--accent); color: #fff; border-color: var(--accent); }

.reqRow {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px;
  margin-bottom: 8px;
  background: #12121a;
}
.reqHead {
  font-size: 13px;
  font-weight: 700;
  color: var(--fg);
  margin-bottom: 6px;
}

/* The ship's wheel takes the colour of the label around it. */
.wheel { display: inline-flex; color: var(--dim); }
.btn:active .wheel { color: var(--fg); }

/* The account, the subscription and the help page. */
.tag.help {
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  width: 26px;
  padding: 5px 0;
  text-align: center;
  color: var(--dim);
}
.tag.help:active { color: var(--accent); border-color: var(--accent); }

/* Obvious enough to find, quiet enough not to nag. */
.tag.sub {
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(46,120,255,0.10);
}
.tag.sub:active { background: var(--accent); color: #fff; }
.tag.sub.trial {
  color: var(--dim);
  border-color: var(--line);
  background: none;
  font-weight: 600;
}

.planBox {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  margin: 12px 0 16px;
  background: #12121a;
}
.planLine { font-size: 13px; margin-bottom: 4px; }
.planLine.top { margin-top: 14px; }

.wide.prov {
  font-weight: 600;
  margin-bottom: 8px;
}
.wide.prov.google { border-color: #4a4a58; }
.wide.prov.apple { border-color: #4a4a58; }

.orLine {
  text-align: center;
  color: var(--dim);
  font-size: 12px;
  margin: 16px 0 10px;
}

#helpSheet .note a { color: var(--accent); }
#helpSheet .secLbl { margin-top: 16px; }

/* The two prices. */
.wide.price {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 14px 16px;
  margin-bottom: 8px;
}
.wide.price b { font-size: 16px; }
.wide.price small { color: var(--dim); font-size: 12px; font-weight: 400; }
.wide.price:active { border-color: var(--accent); }

/* The dev phase switcher. Sits above the title on the customer screen so a
   layout can be approved without leaving the page. Dev only, and it goes
   with the rest of the dev tools under the one flag. */
.devPhases {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
  padding: 6px 8px;
  border: 1px dashed #3a3a46;
  border-radius: 10px;
}
.devPhasesLbl {
  font-size: 11px;
  color: #6e6e7a;
  margin-right: 2px;
}
.devPhases .phase {
  flex: 1;
  background: none;
  border: 1px solid var(--line);
  color: var(--dim);
  border-radius: 999px;
  padding: 6px 4px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}
.devPhases .phase.on {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(46,120,255,0.10);
}

/* Up next. A light look down the queue, not a wall of thumbnails. The words
   lead and the picture is small enough to be a reminder rather than a hook. */
.tag.peek {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--dim);
}
.tag.peek:active { color: var(--accent); border-color: var(--accent); }

.peekRow {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  padding: 12px 2px;
  font: inherit;
  color: var(--fg);
}
.peekRow:last-child { border-bottom: 0; }
.peekRow:active { background: #16161d; }

.peekBody { flex: 1; min-width: 0; }

.peekSignal {
  font-size: 11px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.02em;
  margin-bottom: 3px;
}
.peekSignal.soft { color: var(--dim); font-weight: 600; }

.peekTitle {
  font-size: 14px;
  line-height: 1.35;
  margin-bottom: 3px;
}
.peekMeta { font-size: 12px; color: var(--dim); }

.peekPos {
  font-size: 11px;
  color: #5e5e6a;
  min-width: 16px;
  padding-top: 2px;
}

/* Deliberately small. This is a reminder of the video, not a shop window. */
.peekThumb {
  width: 52px;
  height: 30px;
  border-radius: 4px;
  object-fit: cover;
  background: #1a1a22;
  flex: 0 0 auto;
  margin-top: 2px;
}

/* The locked screen. It replaces the app entirely once the trial is over,
   because there is no half working version to fall back to. */
.locked {
  position: fixed;
  inset: 0;
  background: var(--bg, #0b0b0d);
  z-index: 80;
  overflow-y: auto;
  display: flex;
  align-items: center;
}
.locked[hidden] { display: none; }
.lockedInner {
  width: 100%;
  max-width: 30em;
  margin: 0 auto;
  padding: 32px 22px calc(32px + var(--safe));
}
.lockedInner h1 { font-size: 24px; margin: 0 0 10px; }
.lockedNote { color: var(--dim); font-size: 15px; line-height: 1.55; margin: 0 0 18px; }
.lockedBox {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  margin-bottom: 18px;
  background: #12121a;
}

/* The way out of the locked screen, for the owner only. */
.lockedDev { margin-top: 26px; }

/* The bottom row takes a fourth entry now that Up next has moved down. */
#nav.four { grid-template-columns: repeat(4, 1fr); }
#nav.four .navb { font-size: 12px; }

/* The top bar is gone, so the title sits straight under the video. */
#now .tags { display: none; }

/* The developer way in lives at the foot of Settings now, so there is
   nothing floating over the main screen. */
.devLink {
  display: block;
  text-align: center;
  text-decoration: none;
  color: var(--fg);
  border-style: dashed;
  border-color: #3a3a46;
  margin-bottom: 8px;
}
.devLink:active { color: var(--accent); border-color: var(--accent); }

/* On a narrow phone the longest label is Skip Ad, so the text shrinks a
   little rather than the row wrapping or a word being cut off. */
@media (max-width: 360px) {
  .btn em { font-size: 10px; }
  .btn span { font-size: 22px; }
  .btn .wheel svg { width: 22px; height: 22px; }
}

/* Nothing sits over the video any more. The badge that used to show which
   television was playing and offer a way back to the phone was clutter over
   the picture, and everything it did already lives in the Where to play
   sheet behind the TV button. */

/* ---------- the reel ---------- */
/*
   A slow horizontal drift of what is coming next. It exists to be glanced at,
   so it moves calmly rather than ticking along, and every card carries its
   title and channel. The whole point of this app is not judging a video by
   its thumbnail, so a thumbnail is never shown on its own.
*/
.reel {
  position: relative;
  overflow: hidden;
  background: #0d0d12;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
}
.reel[hidden] { display: none; }

.reelTrack {
  display: flex;
  gap: 8px;
  padding: 8px;
  will-change: transform;
}

.reelCard {
  position: relative;
  flex: 0 0 auto;
  border: 0;
  padding: 0;
  border-radius: 10px;
  overflow: hidden;
  background: #16161d;
  font: inherit;
  color: var(--fg);
  text-align: left;
}
.reelCard img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #1a1a22;
}
.reelCard:active { outline: 2px solid var(--accent); }

/* The words sit over the picture, always, never optional. */
.reelWords {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 16px 8px 7px;
  background: linear-gradient(to top, rgba(6,6,10,0.94) 42%, rgba(6,6,10,0));
}
.reelTitle {
  font-size: 12px;
  line-height: 1.25;
  font-weight: 600;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.reelChan {
  font-size: 10px;
  color: #9a9aa6;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Big, when a television is carrying the video and the phone is mostly a
   remote. The reel becomes the thing worth looking at. */
.reel.big .reelCard { width: 260px; height: 146px; }
.reel.big .reelTitle { font-size: 15px; }
.reel.big .reelChan { font-size: 12px; }

/* Small, when the phone is playing the video. A strip under it, not a rival
   to it. */
.reel.small .reelCard { width: 132px; height: 74px; }
.reel.small .reelTitle { font-size: 10px; -webkit-line-clamp: 2; }
.reel.small .reelChan { font-size: 9px; }
.reel.small .reelWords { padding: 12px 6px 5px; }

/* Held still while a finger is on it. */
.reel.held { box-shadow: inset 0 0 0 1px var(--growing); }

/* ---------- the comparison bench, dev only ---------- */
.benchpage { padding: 0 0 40px; }
.benchTop { padding: 20px 16px 8px; max-width: 1100px; margin: 0 auto; }
.benchTop h1 { font-size: 20px; margin: 0 0 8px; }
.benchIntro { color: var(--dim); font-size: 13px; line-height: 1.55; margin: 0 0 14px; max-width: 46em; }
.benchBar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.benchBar .wide { width: auto; padding: 9px 14px; font-size: 13px; }
.benchBar a.linkish { text-decoration: none; text-align: center; color: var(--fg); }

.benchVerdict {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  background: #12121a;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--dim);
}

.benchActs { padding: 12px 16px; max-width: 1100px; margin: 0 auto; }
.benchActs .row { display: flex; gap: 8px; align-items: center; }
.benchActs .row .inp { flex: 1; margin: 0; }
.benchActs .row .wide { width: auto; padding: 10px 16px; }

.benchCols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  padding: 8px 16px;
  max-width: 1100px;
  margin: 0 auto;
}
@media (max-width: 760px) { .benchCols { grid-template-columns: 1fr; } }

.benchCol h2 { font-size: 16px; margin: 0 0 8px; }
.benchCol h2 small { color: var(--dim); font-weight: 400; font-size: 12px; margin-left: 6px; }

.benchFile {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px;
  background: #12121a;
  font-size: 12px;
  line-height: 1.6;
  margin-bottom: 10px;
  white-space: pre-wrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.benchFile.clean { color: #6e6e7a; }

.benchFeed { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.benchRow {
  display: flex;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  align-items: flex-start;
}
.benchRow:last-child { border-bottom: 0; }
.benchRow.only { background: rgba(46,120,255,0.09); }
.benchNum { color: #5e5e6a; min-width: 18px; }
.benchBody { flex: 1; min-width: 0; }
.benchChan {
  background: none; border: 0; padding: 0;
  color: var(--accent); font: inherit; font-size: 12px; font-weight: 600;
  text-align: left; cursor: pointer;
}
.benchTitle { color: var(--dim); margin-top: 2px; }
.benchWhy { color: #4ade80; font-size: 11px; margin-top: 2px; }

/* The mood choices. */
.moodRow {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  background: none;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 11px 13px;
  margin-bottom: 8px;
  font: inherit;
  color: var(--fg);
}
.moodRow .em { font-size: 19px; line-height: 1; }
.moodRow b { font-size: 14px; font-weight: 600; display: block; }
.moodRow small { color: var(--dim); font-size: 12px; }
.moodRow.on { border-color: var(--accent); background: rgba(46,120,255,0.10); }
.moodRow.on b { color: var(--accent); }

/* The tap target over the video.
   Invisible and drawn over nothing. It exists because the video is a frame
   from YouTube, which the app cannot reach into, so a tap on it went to
   YouTube's own controls and never to us. */
.tapLayer {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: transparent;
  -webkit-tap-highlight-color: transparent;
}

/* A brief mark so it is obvious the tap registered, since the picture itself
   may be on a television in another room. */
.tapMark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 66px;
  height: 66px;
  margin: -33px 0 0 -33px;
  border-radius: 50%;
  background: rgba(8,8,12,0.66);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  color: #fff;
  animation: tapPop 700ms ease-out forwards;
  pointer-events: none;
}
.tapMark[hidden] { display: none; }
@keyframes tapPop {
  0% { opacity: 0; transform: scale(0.7); }
  18% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.1); }
}

/* Lining the phone's sound up with a television. */
.syncBar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 4px 0 10px;
}
.syncBar button {
  background: none;
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 999px;
  padding: 8px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
}
.syncBar button:active { border-color: var(--accent); color: var(--accent); }
.syncBar span {
  flex: 1;
  text-align: center;
  font-size: 13px;
  color: var(--dim);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.rVol button {
  flex: 1;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 14px;
  padding: 17px 8px;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
}
.rVol button:active { border-color: var(--accent); color: var(--accent); }
.rVol button.on { border-color: var(--accent); color: var(--accent); }

/* The volume slider. One control, dragged rather than tapped, because the
   television has no volume of its own to step through. This sets the level
   directly, which is the only thing that actually changes what comes out. */
.volSlide {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 6px 0 8px;
}
.volSlide button {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 999px;
  width: 44px;
  height: 44px;
  font-size: 18px;
  line-height: 1;
  padding: 0;
}
.volSlide button.muted { border-color: var(--accent); color: var(--accent); }
.volSlide span {
  flex: 0 0 auto;
  min-width: 34px;
  text-align: right;
  font-size: 13px;
  color: var(--dim);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.volRange {
  flex: 1;
  min-width: 0;
  height: 34px;
  -webkit-appearance: none;
  appearance: none;
  background: none;
}
.volRange::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 3px;
  background: #2c2c38;
}
.volRange::-moz-range-track {
  height: 6px;
  border-radius: 3px;
  background: #2c2c38;
}
/* A thumb big enough to find without looking. */
.volRange::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 26px;
  height: 26px;
  margin-top: -10px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid #0b0b0d;
}
.volRange::-moz-range-thumb {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid #0b0b0d;
}

/* Introductory pricing. The regular price is shown struck through beside the
   launch price, and the disclosure sits under the buttons. */
.price b s { opacity: .55; font-weight: 400; margin-right: 4px; }
.priceDisclose { margin-top: 8px; font-size: 12px; }

/* The tags under the video: which stream it came from, that it passed the
   quality check, and how old it is. They sit above the title on the phone and
   under the card on the TV screen. */
.vidTags { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.castTags { margin: 10px 0 0; }
.vidTags .tag { font-size: 11px; padding: 4px 10px; }
.tag.stream { color: var(--accent); border-color: var(--accent); }
.tag.stream.growing { color: var(--growing); border-color: var(--growing); }
.tag.quality { color: #3ecf8e; border-color: #1f6b4a; }
.tag.age { color: var(--dim); }

/* Where a free trial stands, under the video. Tapping it opens the plans. */
.trialLine {
  display: block;
  margin-top: 10px;
  padding: 0;
  background: none;
  border: 0;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  text-align: left;
  cursor: pointer;
}
.trialLine.last { color: #f5b44a; }

/* Two colours, two sources. Blue is the Quality stream: the Next button and
   the Quality stream label under the video. Green is Growing Fast: the scroll,
   its heading and the Growing Fast label. */
#strip .btn.nextQuality { gap: 3px; }
#strip .btn.nextQuality span,
#strip .btn.nextQuality em { color: var(--accent); }
#strip .btn.nextQuality em { font-weight: 700; }
#strip .btn.nextQuality small {
  color: var(--accent);
  font-size: 9px;
  font-weight: 600;
  white-space: nowrap;
  line-height: 1;
}
.reel { border-top-color: rgba(52, 199, 89, 0.5); border-bottom-color: rgba(52, 199, 89, 0.5); }

/* The playback bar. Rewind, pause, forward and stop, above the big buttons,
   quieter than them because they are used less than Next. */
#playbar {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 8px;
}
.pb {
  background: #22222a;
  border: 1px solid var(--line);
  border-radius: 14px;
  color: var(--fg);
  padding: 14px 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  font: inherit;
  min-width: 0;
}
.pb span { font-size: 20px; line-height: 1; }
.pb em { font-style: normal; font-size: 10px; color: var(--dim); white-space: nowrap; }
.pb:active { background: var(--accent); border-color: var(--accent); }
.pb.on span, .pb.on em { color: var(--accent); }

/* On the phone the video is YouTube's own player, so a tap belongs to it and
   brings up its controls. The invisible layer that used to swallow every tap
   is only over the card that stands in for the video while a television is
   playing. */
body:not(.casting) .tapLayer { display: none; }

/* Test mode, and the Getting Hot flash over the scroll. */
.testBanner {
  background: #6b4b00;
  color: #ffe9b0;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  text-align: center;
}
@keyframes hotFlash {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0.25; }
}
