/*
 * Livesuomi multiview.
 *
 * Sääntö joka näkyy koko tiedostossa: soittimen päälle ei tule mitään.
 * Otsikkorivit ovat soittimen yläpuolella eivätkä sen päällä, eikä yhtään
 * position:absolute -elementtiä ole .ls-mv__frame -laatikon sisällä.
 * Tämä ei ole tyylivalinta vaan alustojen upotusehto.
 */

/*
 * Komponentti asettaa oman laatikkomallinsa.
 *
 * Teema sattuu asettamaan border-boxin globaalisti, mutta plugin ei saa
 * olettaa sitä: ilman tätä .ls-mv:n oma padding lisättiin 100 %:n korkeuden
 * PÄÄLLE, jolloin näkymä oli aina 32 pikseliä liian korkea ja sivu rullasi.
 * Vika olisi ilmennyt vasta jossain toisessa teemassa.
 */
.ls-mv,
.ls-mv *,
.ls-mv *::before,
.ls-mv *::after {
  box-sizing: border-box;
}

.ls-mv {
  /*
   * Näkymä täyttää sille annetun korkeuden ja jakaa sen palkin ja lavan
   * kesken. Sovellusnäkymässä teema antaa koko ruudun korkeuden, jolloin
   * multiview mahtuu kerralla eikä sivu rullaa.
   */
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 520px;

  --ls-mv-gap: 10px;
  --ls-mv-bg: #101214;
  --ls-mv-fg: #e9edf1;
  --ls-mv-dim: #9aa4ae;
  --ls-mv-line: #2a3037;
  --ls-mv-accent: #0f4c5c;
  --ls-mv-live: #e0245e;

  color: var(--ls-mv-fg);
  background: var(--ls-mv-bg);
  padding: 16px;
  border-radius: 10px;
  font: 15px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* ------------------------------------------------------------------ palkki */

.ls-mv__bar {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.ls-mv__title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--ls-mv-fg);
}

.ls-mv__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.ls-mv__layouts {
  display: inline-flex;
  border: 1px solid var(--ls-mv-line);
  border-radius: 7px;
  overflow: hidden;
}

.ls-mv__layout,
.ls-mv__chattoggle {
  appearance: none;
  border: 1px solid var(--ls-mv-line);
  background: transparent;
  color: var(--ls-mv-dim);
  font: inherit;
  font-size: 0.85rem;
  padding: 6px 12px;
  border-radius: 7px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}

.ls-mv__layout {
  border: 0;
  border-radius: 0;
}

.ls-mv__layout + .ls-mv__layout {
  border-left: 1px solid var(--ls-mv-line);
}

.ls-mv__layout:hover,
.ls-mv__chattoggle:hover {
  color: var(--ls-mv-fg);
  background: #1a1f24;
}

.ls-mv__layout.is-on,
.ls-mv__chattoggle[aria-pressed="true"] {
  background: var(--ls-mv-accent);
  color: #fff;
}

/* ------------------------------------------------------------------- lava */

/*
 * Lava täyttää käytettävissä olevan korkeuden eikä rullaa.
 *
 * Mitat lasketaan JS:ssä ja tulevat tänne muuttujina. Syy on kehä jota CSS
 * ei ratkaise: pystypylväässä pikkuruudun leveys riippuu käytettävissä
 * olevasta korkeudesta, ja korkeus leveydestä. Siksi mittaus tehdään
 * kerran JS:ssä ja tulos kirjoitetaan --ls-mv-* -muuttujiin.
 */
.ls-mv__stage {
  display: flex;
  gap: var(--ls-mv-gap);
  flex: 1;
  min-height: 0;
  min-width: 0;
}

/*
 * Ruudukko ei saa levitä lavansa ulkopuolelle.
 *
 * Mitoitus laskee leveydet ja on toistaiseksi laskenut ne oikein, mutta
 * yksi virhe laskussa tarkoitti että pylväs piirtyi chatin päälle. Raja
 * kuuluu rakenteeseen eikä laskuun: JS päättää mitat, CSS vastaa siitä
 * ettei niillä pääse ulos. Näin pahin mahdollinen vika on väärän
 * kokoinen ruutu eikä rikkinäinen sivu.
 */
.ls-mv__slots {
  display: grid;
  gap: var(--ls-mv-gap);
  flex: 1;
  min-width: 0;
  min-height: 0;
  max-width: 100%;
  align-content: start;
}

/* Hero: iso ruutu vasemmalla, pikkuruudut omana pylväänään oikealla. */
.ls-mv__slots[data-mode="hero"] {
  display: flex;
  align-items: stretch;
}

/*
 * Iso ruutu on 16:9 eikä täytä korkeutta kokonaan — neljän 16:9-ruudun
 * pylväs on aina korkeampi kuin yksi 16:9-ruutu samalla leveydellä.
 * Soitin keskitetään pystysuunnassa, jolloin jäljelle jäävä tila jakautuu
 * tasan ylä- ja alareunaan eikä näytä siltä että jotain puuttuu alta.
 */
.ls-mv__slot--main .ls-mv__frame {
  margin-top: auto;
  margin-bottom: auto;
}

.ls-mv__slots[data-mode="hero"] .ls-mv__slot--main {
  flex: 0 0 var(--ls-mv-main-w, 60%);
  max-width: var(--ls-mv-main-w, 60%);
}

/*
 * Paikan korkeus on kiinteä ja sama täytettynä kuin tyhjänä, jotta
 * täyttäminen ei siirrä muita ruutuja.
 */
.ls-mv__col .ls-mv__slot,
.ls-mv__slots[data-mode="grid"] .ls-mv__slot {
  height: var(--ls-mv-tile-h, auto);
}

.ls-mv__col {
  display: grid;
  grid-template-columns: repeat(var(--ls-mv-cols, 1), var(--ls-mv-tile-w, 240px));
  gap: var(--ls-mv-gap);
  align-content: start;
  flex: 0 0 auto;
  /* Varaventtiili: jos mitoitus jostain syystä ei riitä, pylväs rullaa —
     sivu ei. Normaalitilanteessa tätä ei tarvita. */
  max-height: 100%;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* Tasaruudukko: kaikki paikat samankokoisia. */
.ls-mv__slots[data-mode="grid"] {
  grid-template-columns: repeat(var(--ls-mv-cols, 2), var(--ls-mv-tile-w, 240px));
  justify-content: center;
}

/* ------------------------------------------------------------------ palkki */

/*
 * Oikea palkki on joko chat tai mainos — ei koskaan molempia eikä tyhjä.
 * Se on ainoa kohta joka pysyy näkyvissä koko toiston ajan, joten siinä
 * oleva mainos täyttää näkyvyysehdon (50 % / 1 s) koko session ajan.
 */
.ls-mv__rail {
  flex: 0 0 340px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: #16191d;
  border: 1px solid var(--ls-mv-line);
  border-radius: 8px;
  overflow: hidden;
}

.ls-mv__chat {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.ls-mv__chat[hidden] { display: none; }

.ls-mv__chat iframe {
  flex: 1;
  width: 100%;
  border: 0;
  min-height: 0;
}

.ls-mv__adrail {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ls-mv__adrail[hidden] { display: none; }

/* Tyhjä mainospaikka ei piirrä mitään eikä varaa mitään näkyvää. */
.ls-mv__adrail:empty::after {
  content: "";
}

/* ------------------------------------------------------------- tyhjä paikka */

/*
 * Tyhjä paikka on nappi, ei aukko. Napauttaminen avaa kanavavalitsimen
 * modaalissa — juuri siksi ettei kanavan vaihtaminen vaadi rullaamista
 * pois lähetysten luota.
 */
.ls-mv__slot--empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: #14181c;
  border: 1px dashed var(--ls-mv-line);
  color: var(--ls-mv-dim);
  cursor: pointer;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}

.ls-mv__slot--empty:hover,
.ls-mv__slot--empty:focus-visible {
  border-color: var(--ls-mv-accent);
  color: var(--ls-mv-fg);
  background: #181d22;
}

.ls-mv__plus {
  font-size: 1.6rem;
  line-height: 1;
}

.ls-mv__emptylabel {
  font-size: 0.8rem;
}

/* --------------------------------------------------------------- modaali */

.ls-mv__modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.72);
}

.ls-mv__modal[hidden] { display: none; }

.ls-mv__modalbox {
  width: min(880px, 100%);
  max-height: min(80vh, 720px);
  display: flex;
  flex-direction: column;
  background: var(--ls-mv-bg);
  border: 1px solid var(--ls-mv-line);
  border-radius: 12px;
  overflow: hidden;
}

.ls-mv__modalhead {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--ls-mv-line);
}

.ls-mv__modaltitle {
  margin: 0;
  font-size: 1rem;
  flex: 0 0 auto;
}

.ls-mv__search {
  flex: 1;
  min-width: 0;
  padding: 8px 12px;
  border: 1px solid var(--ls-mv-line);
  border-radius: 7px;
  background: #16191d;
  color: var(--ls-mv-fg);
  font: inherit;
  font-size: 0.9rem;
}

.ls-mv__modalclose {
  appearance: none;
  border: 0;
  background: none;
  color: var(--ls-mv-dim);
  font-size: 1.5rem;
  line-height: 1;
  padding: 2px 6px;
  cursor: pointer;
}

.ls-mv__modalclose:hover { color: var(--ls-mv-fg); }

/* Rullaus tapahtuu VAIN täällä. Se on modaalin koko olemassaolon syy. */
.ls-mv__modalbody {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px;
}

/* ------------------------------------------------------------------ ruutu */

.ls-mv__slot {
  min-width: 0;
  background: #000;
  border: 1px solid var(--ls-mv-line);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.ls-mv__slot.is-audio {
  border-color: var(--ls-mv-accent);
  box-shadow: 0 0 0 1px var(--ls-mv-accent);
}

/*
 * Otsikkorivi on AINA saman korkuinen.
 *
 * Mitoitus vähentää rivin korkeuden ruudun korkeudesta, ja se lukee
 * korkeuden yhdestä rivistä olettaen että kaikki ovat samanlaisia. Kun
 * kapean pikkuruudun rivi kietoutui kahdelle riville, oletus petti:
 * sama ikkuna antoi isolle ruudulle milloin 821, milloin 733 pikseliä
 * riippuen siitä minkä rivin mittaus sattui osumaan. Kiinteä korkeus
 * tekee luvusta vakion, ja vakio on mitoituksen ainoa vaatimus.
 */
.ls-mv__tilebar {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 8px;
  height: 32px;
  flex: 0 0 32px;
  padding: 0 8px;
  overflow: hidden;
  background: #16191d;
  border-bottom: 1px solid var(--ls-mv-line);
  font-size: 0.8rem;
}

.ls-mv__tilename {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

.ls-mv__audio,
.ls-mv__close {
  appearance: none;
  border: 1px solid var(--ls-mv-line);
  background: transparent;
  color: var(--ls-mv-dim);
  font: inherit;
  font-size: 0.75rem;
  line-height: 1;
  padding: 5px 9px;
  border-radius: 5px;
  cursor: pointer;
  flex: 0 0 auto;
}

.ls-mv__audio.is-on {
  background: var(--ls-mv-accent);
  border-color: var(--ls-mv-accent);
  color: #fff;
}

.ls-mv__close {
  font-size: 1rem;
  padding: 3px 9px;
}

.ls-mv__audio:hover,
.ls-mv__close:hover { color: var(--ls-mv-fg); }

/* Soitinlaatikko. Tänne ei sijoiteta mitään muuta. */
/*
 * Soitinlaatikko. Tänne ei sijoiteta mitään muuta.
 *
 * Aiemmin tässä oli min-height: 300px, joka piti Twitchin upotusehdon
 * (400 × 300) voimassa kapeimmillakin ruuduilla. Se poistettiin tietoisena
 * päätöksenä: paikkapohjaisessa asettelussa ruudun koko lasketaan
 * käytettävissä olevasta tilasta, ja 300 pikselin pakotus teki pylväästä
 * aina korkeamman kuin ruudulle mahtuu. Koko on nyt se mitä mitoitus
 * antaa, ja se voi alittaa Twitchin vähimmäiskoon.
 */
/*
 * Soitin ei voi olla paikkaansa suurempi.
 *
 * Alustojen upotukset kirjoittavat iframeensa omat mitat, ja jos ne
 * pääsevät voimaan, video piirtyy ruudun reunojen yli. Paikassa on
 * overflow:hidden, mutta selvempi on ettei ylitystä synny lainkaan.
 */
.ls-mv__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  max-width: 100%;
  max-height: 100%;
}

.ls-mv__frame > iframe,
.ls-mv__frame > div,
.ls-mv__frame iframe {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  border: 0;
  display: block;
}

.ls-mv__error {
  margin: 0;
  padding: 16px;
  color: var(--ls-mv-dim);
  font-size: 0.85rem;
}

/* ------------------------------------------------------------------- chat */

.ls-mv__chat {
  min-width: 0;
  background: #16191d;
  border: 1px solid var(--ls-mv-line);
  border-radius: 8px;
  overflow: hidden;
  min-height: 320px;
  display: flex;
  flex-direction: column;
}

.ls-mv__chat iframe {
  width: 100%;
  flex: 1 1 auto;
  min-height: 420px;
  border: 0;
  display: block;
}

.ls-mv__chatnone {
  margin: 0;
  padding: 16px;
  color: var(--ls-mv-dim);
  font-size: 0.85rem;
}

/*
 * Ulos vievä linkki on aina näkyvissä. Kickin popout-chat ei ole
 * dokumentoitu rajapinta, joten se voi lakata toimimasta ilman varoitusta —
 * silloin käyttäjällä on jo reitti eteenpäin eikä tyhjä laatikko.
 */
/* Linkki alustalle näkyy vain siellä missä chattia ei ole. */
.ls-mv__chatlink {
  display: inline-block;
  margin: 0 12px 12px;
  color: #6fb3c4;
}

/* --------------------------------------------------------------- valitsin */

.ls-mv__pickheading {
  margin: 0 0 10px;
  font-size: 0.8rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ls-mv-dim);
}

.ls-mv__picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}

.ls-mv__pick {
  appearance: none;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  background: #16191d;
  border: 1px solid var(--ls-mv-line);
  border-radius: 8px;
  color: var(--ls-mv-fg);
  font: inherit;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}

.ls-mv__pick:hover { background: #1c2126; }

.ls-mv__pick.is-on {
  border-color: var(--ls-mv-accent);
  background: #14262c;
}

.ls-mv__avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  flex: 0 0 auto;
  object-fit: cover;
}

.ls-mv__pickmeta {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ls-mv__pickname {
  font-weight: 600;
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * Jakson nimi. Kaksi riviä, sitten katkaisu.
 *
 * Yksi rivi katkaisisi YouTube-otsikon lähes aina keskeltä — ne ovat
 * pitkiä — ja kaksi jaksoa samasta sarjasta näyttäisi taas samalta.
 * Rajattomana taas pisin otsikko määräisi koko listan rivikorkeuden.
 */
.ls-mv__picktitle {
  font-size: 0.8rem;
  line-height: 1.3;
  color: var(--ls-mv-fg);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ls-mv__picksub {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  align-items: center;
  font-size: 0.75rem;
  color: var(--ls-mv-dim);
}

/*
 * Kategoria voi olla pitkä ("Just Chatting" mahtuu, sarjan nimi ei).
 * Se on vähiten tärkeä tieto rivillä, joten se kutistuu ensimmäisenä.
 */
.ls-mv__cat {
  min-width: 0;
  max-width: 12em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ls-mv__src { font-weight: 600; }
.ls-mv__src--twitch { color: #a970ff; }
.ls-mv__src--kick { color: #53fc18; }
.ls-mv__src--youtube { color: #ff5a5a; }

.ls-mv__viewers::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--ls-mv-live);
  vertical-align: middle;
}

/* ------------------------------------------------------------------- muut */

.ls-mv__empty,
.ls-mv__none {
  margin: 0 0 18px;
  color: var(--ls-mv-dim);
  font-size: 0.88rem;
}

.ls-mv__notice {
  margin: 0 0 12px;
  padding: 9px 12px;
  background: #1c2126;
  border-left: 3px solid var(--ls-mv-accent);
  border-radius: 4px;
  color: var(--ls-mv-fg);
  font-size: 0.85rem;
  min-height: 0;
}

.ls-mv__notice:empty { display: none; }

.ls-mv [hidden] { display: none !important; }

/* ---------------------------------------------------------------- mobiili */

/*
 * Ruudukko on työpöytäominaisuus. Mobiilissa yksi lähetys kerrallaan:
 * äänessä oleva näkyy, muut kutistuvat vaihtajariviksi. Tämä on konseptin
 * luvun 5.2 kohta 7, ja se on tietoinen päätös eikä puute.
 */
/*
 * Kapea näyttö: päänäkymä ylhäällä, pikkuruudut SEN ALLE, palkki alimmaksi.
 *
 * Kytkimenä on data-ls-narrow jonka JS asettaa mitoituksen yhteydessä, ei
 * @media. Syy on aiempi vika: media query siirsi rakenteen sarakkeeksi,
 * mutta JS laski silti leveän näytön pikselimitat ja kirjoitti ne
 * muuttujiin — pystysuorassa flexissä --ls-mv-main-w olisi lisäksi
 * tarkoittanut korkeutta eikä leveyttä. Kun sama koodi päättää molemmat,
 * ne eivät voi olla eri mieltä.
 *
 * Tämä on ainoa näkymä joka rullaa pystysuunnassa. Puhelimessa viiden
 * ruudun ahtaminen yhdelle näytölle tekisi jokaisesta lukukelvottoman,
 * joten "ei rullausta" on työpöydän lupaus.
 */
/* Korkeus vapautuu: näkymä saa olla ruutua korkeampi ja sivu rullaa. */
.ls-mv[data-ls-narrow="1"] {
  height: auto;
  min-height: 0;
}

.ls-mv[data-ls-narrow="1"] .ls-mv__stage {
  flex-direction: column;
  align-items: stretch;
  flex: 0 0 auto;
}

.ls-mv[data-ls-narrow="1"] .ls-mv__slots[data-mode="hero"] {
  flex-direction: column;
}

/*
 * Kapealla näytöllä TYHJÄ paikka tarvitsee oman kuvasuhteensa.
 *
 * Työpöydällä paikan korkeus tulee mitoituksesta, mutta kapealla näytöllä
 * korkeus tulee sisällöstä — ja tyhjän paikan sisältö on yksi rivi
 * tekstiä. Ilman tätä sääntöä tyhjät ruudut litistyivät 52 pikselin
 * viivoiksi, eli puhelimella ei nähnyt mihin kanavan voi laittaa.
 */
.ls-mv[data-ls-narrow="1"] .ls-mv__slot--empty {
  aspect-ratio: 16 / 9;
  height: auto;
}

/* Iso ruutu koko leveydeltä. Pikselileveys nollataan: pystysuorassa
   flexissä flex-basis on korkeus. */
.ls-mv[data-ls-narrow="1"] .ls-mv__slots[data-mode="hero"] .ls-mv__slot--main {
  flex: 0 0 auto;
  width: 100%;
  max-width: none;
  height: auto;
}

/* Pikkuruudut riviin ison alle. Sarakeleveys on osuus eikä pikseliarvo,
   jotta se ei voi olla eri mieltä mitatun leveyden kanssa. */
.ls-mv[data-ls-narrow="1"] .ls-mv__col,
.ls-mv[data-ls-narrow="1"] .ls-mv__slots[data-mode="grid"] {
  width: 100%;
  grid-template-columns: repeat(var(--ls-mv-cols, 2), minmax(0, 1fr));
  max-height: none;
  overflow: visible;
  justify-content: stretch;
}

/* Chat tai mainos tulee ruutujen alle, ei viereen. */
.ls-mv[data-ls-narrow="1"] .ls-mv__rail {
  flex: 0 0 auto;
  width: 100%;
  height: 60vh;
  min-height: 320px;
}

@media (max-width: 720px) {
  .ls-mv { padding: 12px; }

  /* Kapealla näytöllä 300 px pakottaisi mustat palkit kuvan ylle ja alle. */
  .ls-mv__frame {
    min-height: 0;
  }

  .ls-mv__layoutwrap { font-size: 0.8rem; }

  .ls-mv__picker { grid-template-columns: 1fr; }
}


/* Tallennemerkintä ja alustalinkki ruudun otsikkorivillä. */
.ls-mv__badge {
  flex: 0 0 auto;
  padding: 2px 6px;
  border: 1px solid var(--ls-mv-line);
  border-radius: 4px;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ls-mv-dim);
}

/*
 * Nimi on linkki alustalle, mutta se ei näytä linkiltä ennen kuin siihen
 * osuu hiirellä. Kyse on varauloskäynnistä estetyn upotuksen varalta,
 * ei kehotuksesta poistua.
 */
a.ls-mv__tilename {
  color: inherit;
  text-decoration: none;
}

a.ls-mv__tilename:hover,
a.ls-mv__tilename:focus-visible {
  text-decoration: underline;
}

.ls-mv__pickheading--video {
  margin-top: 22px;
}

.ls-mv__pick--video .ls-mv__pickname {
  font-weight: 550;
}
