/* Watched streamer cards, and the spinner a recording shows while it is being combined.
   Loaded last so it can settle the card layout that style.css, responsive.css and
   connections.css each contributed a piece of. */

/* ---- A recording with no picture yet --------------------------------------------- */

/* While a join runs there is no video to take a frame from, so the row used to point an
   <img> at a thumbnail that does not exist and the browser drew a broken image. */
.video-icon.working{background:#22301f;border:1px solid #3c5131}
.spinner{display:block;width:15px;height:15px;border:2px solid #3f5a36;border-top-color:var(--green);border-radius:50%;animation:spin .9s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){
  .spinner{animation:none;border-top-color:var(--green);opacity:.8}
}

/* ---- Watched streamers ------------------------------------------------------------ */

/* One padding value for the whole card, so the identity, the facts, an error and the
   buttons all line up on the same left edge instead of each choosing its own. */
.channel{--pad:20px}

/* Wider columns: the old 295px minimum made every card a narrow strip on a desktop and
   forced the name to truncate at 170px even when there was room to spare. */
.channels{grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:18px}

/* What a card is doing has to be readable across a grid of them without stopping to
   read any text, so each state changes the whole card rather than a hairline down one
   edge: the colour of the bar, the border, the background wash, and whether it glows. */
.channel{position:relative;overflow:hidden;display:flex;flex-direction:column;transition:border-color .18s ease,background .18s ease,box-shadow .18s ease}
.channel::before{content:"";position:absolute;inset:0 auto 0 0;width:5px;background:#3a4a3e}

/* Capturing: the loudest state, because it is the one worth noticing from across a room. */
.channel.is-live::before{background:var(--red)}
.channel.is-live{border-color:#7a4b45;background:linear-gradient(140deg,#241a19,#181e1a 60%);box-shadow:0 0 0 1px #3a2422,0 6px 22px -12px #ff786f80}
.channel.is-live .channel-name{color:#ffe2dd}

/* Watching: on duty and healthy. Calm, but unmistakably lit rather than grey. */
.channel.is-watching::before{background:var(--green)}
.channel.is-watching{border-color:#3f5a3a;background:linear-gradient(140deg,#1a231b,#181e1a 60%)}

/* Wants a decision from you. */
.channel.is-attention::before{background:#e3c77e}
.channel.is-attention{border-color:#5d5232;background:linear-gradient(140deg,#231f17,#181e1a 60%)}

/* Paused is deliberate, so it reads as switched off: no wash, a hollow bar rather than a
   solid one, and the identity dimmed. The buttons stay legible because pressing Resume is
   exactly what you came to the card to do. */
.channel.is-paused{background:#131714;border-color:#232a25}
.channel.is-paused::before{background:repeating-linear-gradient(180deg,#3a4238 0 6px,transparent 6px 12px)}
.channel.is-paused .avatar,.channel.is-paused .channel-name,.channel.is-paused .channel-link,.channel.is-paused .platform-mark{opacity:.5}
.channel.is-paused .channel-facts dt,.channel.is-paused .channel-facts dd{color:#788478}

.channel:hover{border-color:#4a5a4c}
.channel.is-live:hover{border-color:#8f5750}

/* Identity row: avatar and name on the left, state badge pinned to the right edge and
   aligned to the name rather than floating against the top of the card. */
.channel-top{display:flex;align-items:flex-start;gap:13px;padding:var(--pad) var(--pad) 0}
.channel-identity{min-width:0;flex:1;padding-top:1px}
.channel-name{max-width:none;font-size:14px;line-height:1.3}
.channel-link{display:block;margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.channel-link:hover{color:var(--green)}
.channel-top .badge{flex-shrink:0;margin-top:1px}

/* The site's own mark sits on the streamer's initials, the way an account badge does. */
.avatar-stack{position:relative;flex-shrink:0;line-height:0}
/* A site's own favicon is drawn for whatever background that site uses: Bigo's is pale
   line art that would all but vanish on this panel. Every mark therefore sits on the same
   light chip, which also keeps badges a consistent shape whatever a new adapter ships. */
.platform-mark{position:absolute;right:-4px;bottom:-4px;width:20px;height:20px;padding:2px;border-radius:7px;background:#f4f7f3;object-fit:contain;box-shadow:0 0 0 2px var(--panel),0 1px 3px #0006}
.channel.is-paused .platform-mark{box-shadow:0 0 0 2px #151a16,0 1px 3px #0006}

/* Facts replace a row that held a status badge and a lone em dash. Two columns keeps
   pairs readable; the row gap is larger than the column gap so rows do not blur together. */
.channel-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:15px 18px;margin:18px 0;padding:0 var(--pad)}
.channel-facts dt{font-size:9px;letter-spacing:.9px;text-transform:uppercase;color:#7c8d80;line-height:1}
.channel-facts dd{margin:6px 0 0;font-size:12px;line-height:1.35;color:#d6e3d7;overflow-wrap:anywhere}
/* How long ago, under the timestamp: the timestamp says when, this says whether
   checking is still happening. */
.channel-facts dd small{display:block;margin-top:3px;font-size:10px;line-height:1.3;color:#7f8f83}
.channel-facts .duration{font-size:14px;line-height:1.2}
.channel.is-live .channel-facts .duration{color:#ffd0c8}

/* The facts above already supply the gap, so an error does not add a second one. */
.channel-error{margin:0 0 18px;padding:0 var(--pad);font-size:11px;line-height:1.5;color:#d8b77c}

/* Pushed to the bottom so cards of unequal height still line their buttons up, with the
   divider spanning the full width rather than stopping at the text. */
.channel-bottom{margin-top:auto;padding:var(--pad);padding-top:16px;border-top:1px solid #232c26;justify-content:stretch}
.channel-buttons{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:9px;width:100%}
.channel-buttons .small-button{width:100%}

/* The old free-standing "Connection: x" line had no padding of its own and sat flush
   against the card edge; it is a fact among the others now. */
.channel-connection{display:none}

@media(max-width:760px){
  .channels{grid-template-columns:1fr;gap:14px}
  .channel{--pad:16px}
  .channel-facts{margin:16px 0;gap:13px 16px}
  .channel-error{margin-bottom:16px}
}

/* ---- Favourite marker -------------------------------------------------------------- */

/* Sits with the name rather than among the action buttons: it marks the recording, it is
   not something done to it, and the action row is already full on a narrow screen. */
.row-title{display:inline-flex;align-items:center;gap:7px}
.row-buttons{display:contents}
/* On a phone the name takes the full width and the buttons follow it, wrapping with it,
   rather than squeezing a long name into a column beside them. The table keeps its cells
   on one line, which here ran the name and the comment count under the select box. */
@media(max-width:760px){
  .row-title{display:block;white-space:normal;overflow-wrap:anywhere}
  /* The cell's own room for the box is undone by the card padding, so the title line,
     the one beside it, keeps that room itself. */
  .recordings-table tr:has(.pick-cell input) .row-title{padding-right:28px}
  /* The buttons go to the next line together, never one left behind on its own. */
  .row-buttons{display:inline-flex;align-items:center;gap:7px;vertical-align:middle;margin-left:7px;white-space:nowrap}
}
.star{padding:2px 4px;background:none;border:0;line-height:1;font-size:15px;color:#5f6f63;border-radius:5px;transition:color .15s ease}
.star:hover{color:#e8c86a}
.star.on{color:#f0cc5e}
/* Big enough to hit on a phone without pushing the name around on a desktop. */
@media(max-width:760px){.star{padding:6px;font-size:17px}}

/* A recording card gets a pulsing dot on its accent bar, so a grid of cards shows which
   one is capturing even out of the corner of your eye. */
.channel.is-live::after{content:"";position:absolute;left:11px;top:22px;width:7px;height:7px;border-radius:50%;background:var(--red);box-shadow:0 0 0 4px #ff786f26;animation:beat 1.6s ease-in-out infinite}
.channel.is-live .channel-top{padding-left:30px}
.channel.is-live .channel-facts,.channel.is-live .channel-error,.channel.is-live .channel-bottom{padding-left:30px}
@keyframes beat{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}
@media(prefers-reduced-motion:reduce){.channel.is-live::after{animation:none}}

/* ---- Keeping Remove out of the way ------------------------------------------------ */

/* It used to be one of three equal columns, which on a phone put a destructive action
   under the thumb next to the one you actually meant. The actions you use routinely take
   the width; Remove shrinks to its label and is pushed away from them by a wider gap. */
.channel-buttons{display:flex;flex-wrap:nowrap;gap:9px;width:100%}
/* width:auto matters: an earlier rule sets width:100% on these for the grid layout this
   replaces, and a flex item with flex:0 0 auto would then take that width literally. */
.channel-buttons .small-button{flex:1 1 0;width:auto;min-width:0}
.channel-buttons .small-button.remove{flex:0 0 auto;width:auto;margin-left:9px;padding-inline:12px;opacity:.75}
.channel-buttons .small-button.remove:hover,.channel-buttons .small-button.remove:focus-visible{opacity:1}
/* A thin rule marks it off as belonging to a different class of action. */
.channel-buttons .small-button.remove::before{content:"";position:absolute;left:-9px;top:6px;bottom:6px;width:1px;background:#2f3a31}
.channel-buttons .small-button.remove{position:relative}

/* ---- Watched ----------------------------------------------------------------------- */

/* A tick over the corner of the picture for something seen right through, a bar across
   its foot for something part way. Nothing at all for a recording not yet opened, so the
   library only gains marks as you actually work through it. */
.seen{position:absolute;pointer-events:none}
.seen.done{right:-4px;top:-4px;width:15px;height:15px;border-radius:50%;background:var(--green);color:#16240f;font-size:10px;line-height:15px;text-align:center;font-weight:700;box-shadow:0 0 0 2px var(--panel)}
.seen.part{left:0;right:0;bottom:0;height:3px;background:#0009;border-radius:0 0 6px 6px;overflow:hidden}
.seen.part i{display:block;height:100%;background:var(--green)}

/* The tick sits on the thumbnail, which has to allow it out of its own box. */
.video-icon{overflow:visible}
.video-icon img{border-radius:6px}

/* Correcting it by hand, beside the favourite star. */
.seen-toggle{padding:2px 4px;background:none;border:0;line-height:1;font-size:13px;color:#5f6f63;border-radius:5px;transition:color .15s ease}
.seen-toggle:hover{color:#bcd9b4}
.seen-toggle.on{color:var(--green)}
@media(max-width:760px){.seen-toggle{padding:6px;font-size:15px}}

/* Bigger pictures in the library: the frame is stored at 180px tall, so there was plenty
   of detail behind a 33px box. A 16:9 shape also matches what was actually recorded. */
.video-icon{width:76px;height:44px;font-size:17px}
.recordings-table .table-name{gap:14px}
.seen.done{width:17px;height:17px;font-size:11px;line-height:17px}
@media(max-width:760px){
  .video-icon{width:96px;height:56px;font-size:19px}
  .recordings-table .table-name{gap:13px}
}

/* The same watched shape as the player shows, sized for a row in the library. */
.row-timeline{position:relative;display:block;height:4px;margin-top:8px;max-width:320px;border-radius:2px;background:#28342b;overflow:hidden}
.row-timeline i{position:absolute;top:0;bottom:0;border-radius:2px;background:var(--green);min-width:2px}
@media(max-width:760px){.row-timeline{max-width:none}}

/* Portrait recordings, which is most of them: these sites are filmed on phones. A taller
   box shows the actual frame instead of a letterboxed sliver of it. */
.video-icon.portrait{width:52px;height:92px}
@media(max-width:760px){
  .video-icon.portrait{width:72px;height:128px}
}

/* One length for every row, so the amount watched can be compared down the column at a
   glance. It was sized by the name cell before, so it varied with the streamer's name. */
.row-timeline{width:260px;max-width:100%}
@media(max-width:760px){.row-timeline{width:100%}}

/* Marked moments on a row in the library, in the same colours and the same places as the
   player's own timeline draws them. A recording nobody has played yet still gets a
   timeline if there is anything marked on it. */
.row-mark{position:absolute;top:-3px;bottom:-3px;width:2px;margin-left:-1px;border-radius:1px;
  background:var(--green);box-shadow:0 0 0 1px #10151299}
.row-mark.is-green{background:#b5f99a}.row-mark.is-blue{background:#8fc4f0}
.row-mark.is-purple{background:#c2a4ee}.row-mark.is-amber{background:#eec27f}
.row-mark.is-red{background:#f19b90}.row-mark.is-grey{background:#c0cbc2}
.row-timeline{overflow:visible}

/* Tagged sections on a row: a line just under the watched bar, in the tag's colour. */
.row-span{position:absolute;top:calc(100% + 2px);height:2px;min-width:2px;border-radius:1px}
.row-span.is-green{background:#b5f99a}.row-span.is-blue{background:#8fc4f0}
.row-span.is-purple{background:#c2a4ee}.row-span.is-amber{background:#eec27f}
.row-span.is-red{background:#f19b90}.row-span.is-grey{background:#c0cbc2}
/* Sections that overlap, as two tags on one stretch do, a row each below the first. */
.row-span[data-row="1"]{top:calc(100% + 5px)}
.row-span[data-row="2"]{top:calc(100% + 8px)}
.row-span[data-row="3"]{top:calc(100% + 11px)}
.row-timeline[data-stack="1"]{margin-bottom:3px}
.row-timeline[data-stack="2"]{margin-bottom:6px}
.row-timeline[data-stack="3"]{margin-bottom:9px}

/* Where a recording was left, on its row: a notch standing proud of the bar, like the
   player's own position. */
.row-resume{position:absolute;top:-4px;bottom:-4px;width:3px;margin-left:-1.5px;border-radius:2px;
  background:#f4f8f2;box-shadow:0 0 0 1px #101512}

/* The library in days: a heading per day that opens and closes the recordings under it. */
.recordings-table tr.day-row td{padding:0;background:#151d17;border-bottom:1px solid var(--line)}
.recordings-table tr.day-row:not(:first-child) td{border-top:1px solid var(--line)}
.day-toggle{display:flex;align-items:center;gap:12px;width:100%;padding:12px 18px;background:none;text-align:left;font-size:13px;color:var(--text)}
.day-toggle:hover{background:#1b251d}
.day-toggle b{font-weight:550}
.day-toggle small{margin:0 0 0 auto!important;color:var(--muted);font-size:11px;white-space:nowrap}
.day-caret{width:16px;color:var(--green);font-size:16px;line-height:1}
.day-live{color:#ff9c91}

/* ---- Two actions and More ---------------------------------------------------------- */

/* At most two labelled buttons, sharing the width, and More at the end. Their labels stay
   on one line: five buttons in a row used to leave each about fifty pixels on a phone,
   and the words broke across two lines or ran off the button. */
.channel-buttons{display:flex;flex-wrap:nowrap;align-items:stretch;gap:9px;width:100%}
.channel-buttons>.small-button{flex:1 1 0;min-width:0;width:auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.channel-more{position:relative;flex:0 0 auto;display:flex}
.channel-more .more-button{flex:0 0 auto;width:44px;min-width:44px;padding-inline:0;font-size:16px;line-height:1;letter-spacing:1px}
.more-button[aria-expanded="true"]{border-color:var(--green);color:var(--green)}
/* Opens upward, over the card's own facts: the card clips anything that leaves it. */
.channel-menu{position:absolute;right:0;bottom:calc(100% + 8px);z-index:3;display:flex;flex-direction:column;gap:4px;
  min-width:168px;padding:6px;background:#141a15f5;border:1px solid #3c4b38;border-radius:11px;box-shadow:0 12px 30px #000b}
.menu-item{display:block;width:100%;padding:9px 11px;border-radius:7px;background:none;border:0;color:#d6e3d7;
  font-size:12px;text-align:left;white-space:nowrap}
.menu-item:hover,.menu-item:focus-visible{background:#233022;color:var(--text)}
.menu-item.danger{margin-top:3px;border-top:1px solid #2a332c;border-radius:0 0 7px 7px;color:#f0a99c}
.menu-item.danger:hover,.menu-item.danger:focus-visible{background:#3a2724;color:#ffc4b8}
@media(max-width:760px){
  .menu-item{padding:12px 13px;font-size:13px}
  .channel-more .more-button{width:48px;min-width:48px}
}

/* ---- Overview: groups, search and the compact list ---------------------------------- */

/* The heading used to be a slogan only; it now also says what is happening. */
.overview-heading{padding:30px 0 24px}
#overview-summary{color:#b7c8ba}

.channels-heading{flex-wrap:wrap;row-gap:12px}
.channel-tools{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-left:auto}
.channel-tools>span{font-size:11px;color:var(--muted)}
#channel-search{width:220px;padding:8px 11px;font-size:12px}
.layout-toggle{display:inline-flex;padding:3px;background:#141b16;border:1px solid var(--line);border-radius:8px}
.layout-toggle button{padding:5px 11px;background:none;border-radius:6px;font-size:11px;color:#a7b9a9}
.layout-toggle button[aria-pressed="true"]{background:#263223;color:var(--green)}

/* One group per state, each with a heading you can press to fold it away. Folded, the
   heading still names who is in it, so nobody disappears without a trace. */
.channel-groups{display:flex;flex-direction:column;gap:14px;margin-bottom:8px}
.channel-group{border:1px solid var(--line);border-radius:12px;background:#131915}
.group-toggle{display:flex;align-items:center;gap:10px;width:100%;padding:13px 16px;background:none;text-align:left;border-radius:12px;color:var(--text)}
.group-toggle:hover{background:#18201a}
.group-toggle b{font-weight:600;font-size:13px}
.group-toggle .count{margin-left:0}
.group-toggle small{margin-left:6px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted);font-size:11px}
.group-caret{width:14px;color:var(--green);font-size:14px;line-height:1}
.channel-group.is-live{border-color:#5a3b37}
.channel-group.is-live .group-toggle b{color:#ff9c91}
.channel-group.is-attention{border-color:#4d4530}
.channel-group.is-attention .group-toggle b{color:#e3c77e}
.channel-group.is-paused .group-toggle b,.channel-group.is-off .group-toggle b{color:#a2ada4}
.channel.is-off{background:#151a16;border-color:#2a322b}
.channel.is-off::before{background:#59645a}
.channel-group>.channels{padding:4px 14px 14px}
.channel-none{padding:22px;text-align:center;font-size:12px;border:1px dashed #344338;border-radius:10px}

/* The compact list: one line per streamer, the accent bar kept as a coloured left edge.
   Rows do not clip, so the More menu can open below them. */
.channels.as-list{display:flex;flex-direction:column;gap:6px}
.channel.channel-row{display:grid;grid-template-columns:auto minmax(150px,1.3fr) minmax(120px,1fr) auto minmax(250px,auto);align-items:center;gap:14px;
  padding:9px 12px 9px 14px;overflow:visible;border-left:4px solid #3a4a3e;border-radius:9px}
.channel.channel-row::before,.channel.channel-row::after{display:none}
.channel-row.is-live{border-left-color:var(--red)}
.channel-row.is-watching{border-left-color:var(--green)}
.channel-row.is-attention{border-left-color:#e3c77e}
.channel-row.is-paused{border-left-color:#3a4238}
.channel-row.is-off{border-left-color:#59645a}
.channel-row .avatar{width:32px;height:32px;font-size:12px}
.channel-row .platform-mark{width:16px;height:16px;right:-5px;bottom:-5px;border-radius:5px}
.channel-row .channel-identity{padding:0;min-width:0}
.channel-row .channel-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.channel-row .channel-link{margin-top:1px}
.row-error{display:block;margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;color:#d8b77c}
.row-detail{min-width:0;font-size:12px;color:#c4d3c6}
.row-detail small{display:block;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;color:var(--muted)}
.channel-row.is-live .row-detail{color:#ffd0c8}
.channel-row .channel-bottom{margin:0;padding:0;border:0}
.channel-row .channel-buttons>.small-button{min-height:30px;padding:5px 10px}
.channel-row .channel-more .more-button{width:36px;min-width:36px;min-height:30px}
.channel-row .channel-menu{bottom:auto;top:calc(100% + 6px)}
.channel-row.is-paused .channel-name,.channel-row.is-paused .avatar{opacity:.55}

@media(max-width:1100px){
  .channel.channel-row{grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:"pic who badge" "pic detail detail" "act act act";row-gap:8px}
  .channel-row .avatar-stack{grid-area:pic;align-self:start}
  .channel-row .channel-identity{grid-area:who}
  .channel-row .badge{grid-area:badge}
  .channel-row .row-detail{grid-area:detail}
  .channel-row .channel-bottom{grid-area:act}
}
@media(max-width:760px){
  .channel-tools{width:100%;margin-left:0}
  #channel-search{flex:1;width:auto;min-width:0}
  .channel-tools>span{width:100%}
  .group-toggle{padding:12px 13px}
  .group-toggle small{display:none}
  .channel-group>.channels{padding:2px 10px 10px}
  .channel-row .channel-buttons>.small-button{min-height:38px}
  .channel-row .channel-more .more-button{min-height:38px;width:44px;min-width:44px}
}
