/* =====================================================================
   ONDERBALK  --  2560 x 248, onder de gameplay (y = 1192)
   Raster: cam 340 | characters 900 | raid 330 | chat 520 | recent 342

   De vier vlakken zijn rcards uit css/ribbon.css: schuine hoek rechtsonder,
   1px omlijning uit twee geklipte lagen, en het bijschrift als tag op de
   bovenrand. Dat is dezelfde vormtaal als de balken in de bovenbalk, dus
   de kaarten dragen ook hetzelfde icoon in hun bijschrift.
   Boven zit een aparte strook (topbar.html) met de sessiestatus.
   ===================================================================== */

html,body{
  width:100vw;height:100vh;
  background:transparent;          /* grond komt uit .ground__hole */
  overflow:hidden;
}
#stage{position:absolute;top:0;left:0;transform-origin:0 0;overflow:hidden}

/* ---- grond met camera-gat ------------------------------------------
   De box-shadow vult de hele strook en laat het cameravlak leeg. Je OBS
   camera-source ligt daarachter en krijgt zo zijn vorm zonder mask.

   Het gat heeft dezelfde schuine hoek als de kaarten: een driehoekje
   grondkleur dekt de hoek af, en de omlijning is een polygon in de svg
   ernaast -- een border volgt een diagonaal niet mee. */
.ground{position:absolute;inset:0;z-index:0;pointer-events:none}
.ground__hole{
  position:absolute;left:24px;top:24px;width:340px;height:200px;
  box-shadow:0 0 0 3000px var(--ink-900);
}
.ground__hole::after{
  content:'';position:absolute;right:0;bottom:0;width:30px;height:30px;
  background:var(--ink-900);clip-path:polygon(100% 0,100% 100%,0 100%);
}
.ground__frame{
  position:absolute;left:24px;top:24px;width:340px;height:200px;
  fill:none;stroke:var(--jade);stroke-opacity:.38;stroke-width:2;
}

/* naad tussen gameplay en balk: twee kale lijnen, goedkoop voor de encoder */
#stage::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;
  background:var(--jade);opacity:.55;z-index:20}
#stage::after{content:'';position:absolute;top:2px;left:0;right:0;height:1px;
  background:var(--holy);opacity:.05;z-index:20}

/* De strook ligt boven de grond (die vult alles behalve het cameragat) en
   onder de kaarten. Links afgesneden tot voorbij het cameravlak, anders
   drijven de banen over je webcam -- dezelfde fout die Just Chatting had. */
.bg--slice{z-index:1;clip-path:inset(0 0 0 384px)}

.banner{
  position:relative;z-index:2;height:100%;
  display:grid;grid-template-columns:340px 900px 330px 1fr 342px;
  gap:20px;padding:24px;
}

/* Tint per kaart. Het bijschrift zelf blijft rustig grijs; de tint zit in
   het icoon, net zoals de kleur in een ribbon in het kopblok zit. */
.card--char  {--acc:var(--paper)}
.card--boss  {--acc:var(--jade)}
.card--chat  {--acc:var(--paper-dim)}
.card--events{--acc:var(--jade)}

.banner .rcard__cap{color:var(--ink-300)}
.banner .rcard__in{position:relative;padding:15px 22px 17px}

/* min-height:0 is hier geen detail. Een grid-item krimpt standaard niet
   onder zijn inhoud (min-height:auto), dus zodra er een lang chatbericht
   binnenkwam werd de kaart 225px hoog in een rij van 200 en liep hij onder
   de balk uit -- de onderste regel werd door #stage afgesneden. Met deze
   nul kan de keten wrap -> rcard -> rcard__in -> #chatList wel krimpen, en
   schuift de oudste regel bovenaan onder het masker weg zoals bedoeld. */
.banner .rcard-wrap{min-height:0}

/* =====================================================================
   1. CAMERA -- leeg vlak boven het gat
   ===================================================================== */
.cam{position:relative}

/* Naamplaatje: dezelfde ribbon als de gebeurtenisbalk die er overheen
   schuift, en even hoog, zodat het wisselen niet verspringt. */
.cam__plate{position:absolute;left:12px;bottom:12px;z-index:3;
  transition:opacity 240ms var(--ease)}
.cam__plate .rib{--rib-h:38px;--rib-cut:12px}
.cam__plate .rib__bar{margin-top:0}
.cam.busy .cam__plate{opacity:0}

.cam__hint{
  position:absolute;inset:0;display:none;place-items:center;
  background:var(--ink-850);color:var(--ink-500);font-size:11px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;
  clip-path:polygon(0 0,100% 0,100% calc(100% - 30px),calc(100% - 30px) 100%,0 100%);
}
body.demo .cam__hint{display:grid}

/* gebeurtenisbalk onder de camera: schuift omhoog over het naamplaatje */
.camev{
  position:absolute;left:12px;right:12px;bottom:12px;z-index:4;
  transform:translateY(150%);opacity:0;
  transition:transform 400ms var(--ease), opacity 260ms var(--ease);
}
.camev.on{transform:none;opacity:1}
.camev .rib{--rib-h:38px;--rib-cut:12px}
.camev .rib__val{font-size:17px}

/* =====================================================================
   2. CHARACTERS
   ===================================================================== */
/* Hier stond een verenwatermerk. In een kaart van 189px hoog viel er maar
   een lob van binnen beeld, en die lag precies achter de naam van het
   tweede character: geen watermerk meer, wel een vlek. */

/* Eén kaart, één kolom per character, met een scheidslijn ertussen. Twee
   kolommen is het maximum dat op 900px leesbaar blijft; staan er meer
   characters in de config, dan rouleert de kaart per paar (js/banner.js). */
.chars{
  position:relative;z-index:1;flex:1;min-height:0;
  display:flex;align-items:stretch;
  transition:opacity 220ms var(--ease), transform 220ms var(--ease);
}
.char{display:flex;gap:20px;align-items:center;flex:1 1 0;min-width:0}
.char + .char{margin-left:22px;padding-left:22px;border-left:1px solid var(--ink-700)}

.char__portrait{position:relative;width:104px;height:104px;flex:0 0 104px}
.char__portrait img{position:absolute;inset:8px;width:88px;height:88px;
  border-radius:50%;object-fit:cover;background:var(--ink-700)}
.char__halo{position:absolute;inset:0;width:104px;height:104px}
.char__halo circle{fill:none;stroke:var(--jade);stroke-width:2.5;
  stroke-dasharray:210 92;stroke-linecap:round;
  transform:rotate(-96deg);transform-origin:50% 50%}
.char__halo circle.inner{stroke:var(--holy);stroke-width:1;opacity:.22;stroke-dasharray:3 9}

.char__meta{flex:1;min-width:0;line-height:1.3}
.char__name{font-size:29px;font-weight:600;line-height:1.04;letter-spacing:-.015em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.char__sub{display:flex;align-items:center;gap:8px;font-size:14px;
  color:var(--paper-dim);margin-top:3px;white-space:nowrap;overflow:hidden}
.char__sub .swatch{width:8px;height:8px;border-radius:50%;background:var(--ink-400);flex:0 0 8px}
.char__sub .sep{color:var(--ink-500)}

.char__stats{display:flex;gap:28px;margin-top:12px}
.stat__v{font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:25px;font-weight:500;line-height:1}
.stat__l{font-size:9px;font-weight:600;color:var(--ink-400);margin-top:6px;
  letter-spacing:.14em;text-transform:uppercase}

/* Raidprogress van het character zelf. De kaart ernaast toont de guild;
   dit zijn de kills van deze speler, per moeilijkheid. */
.prog{display:flex;align-items:baseline;gap:16px;margin-top:12px;padding-top:10px;
  border-top:1px solid var(--ink-700);overflow:hidden}
.prog__nm{font-size:13px;color:var(--ink-300);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.prog__t{display:flex;align-items:baseline;gap:14px;flex:0 0 auto}
.tier{display:flex;align-items:baseline;gap:5px;white-space:nowrap}
.tier__v{font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:13px;font-weight:700;color:var(--paper-dim)}
.tier__l{font-size:9px;font-weight:700;color:var(--ink-400);
  letter-spacing:.14em;text-transform:uppercase}
.tier--top .tier__v{color:var(--jade)}
.tier--none .tier__v{color:var(--ink-500)}
.prog__empty{font-size:13px;color:var(--ink-500)}

/* twee kolommen: alles een maatje kleiner, en de raidnaam laat de kaart
   ernaast wel weten -- hier is de ruimte voor de cijfers */
.is-two .char{gap:16px}
.is-two .char__portrait{width:88px;height:88px;flex:0 0 88px}
.is-two .char__portrait img{inset:7px;width:74px;height:74px}
.is-two .char__halo{width:88px;height:88px}
.is-two .char__name{font-size:24px}
.is-two .char__sub{font-size:13px}
.is-two .char__stats{gap:20px;margin-top:10px}
.is-two .stat__v{font-size:21px}
.is-two .prog{margin-top:10px}
.is-two .prog__nm{display:none}

.rotdots{position:absolute;right:18px;top:14px;display:flex;gap:5px;z-index:2}
.rotdots i{width:15px;height:3px;background:var(--ink-600);
  transition:background var(--t-med) var(--ease)}
.rotdots i.on{background:var(--jade)}

/* =====================================================================
   3. BOSS PROGRESS  --  widget of eigen weergave
   ===================================================================== */
.card--boss .rcard__in{padding:0;background:var(--ink-850)}

/* ingesloten Raider.IO widget */
.rio{position:absolute;inset:0;overflow:hidden}
.rio iframe{position:absolute;left:50%;top:50%;width:500px;height:312px;
  border:0;transform-origin:50% 50%}

/* eigen weergave van dezelfde gegevens */
.boss{position:absolute;inset:0;padding:16px 20px;overflow:hidden}
.boss__art{
  position:absolute;right:-28px;top:-22px;width:190px;height:190px;
  background-size:cover;background-position:center 14%;
  opacity:.17;pointer-events:none;z-index:0;
  -webkit-mask-image:linear-gradient(to left,#000 8%,transparent 94%);
          mask-image:linear-gradient(to left,#000 8%,transparent 94%);
}
.boss__over,.boss__top,.boss__sub,.boss__stat{position:relative;z-index:1}
.boss__over{font-size:9px;font-weight:600;color:var(--ink-400);
  letter-spacing:.14em;text-transform:uppercase;line-height:1.3}
.boss__top{display:flex;align-items:flex-start;gap:10px;margin-top:4px}
.boss__nm{font-size:19px;font-weight:600;line-height:1.14;letter-spacing:-.012em;
  flex:1;min-width:0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.boss__tag{font-size:8px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  padding:3px 8px;flex:0 0 auto;margin-top:3px;
  clip-path:polygon(0 0,100% 0,calc(100% - 4px) 100%,0 100%)}
.boss__tag.down{background:var(--jade-ghost);color:var(--jade)}
.boss__tag.prog{background:rgba(216,178,99,.15);color:var(--gold)}
.boss__sub{font-size:11px;color:var(--ink-300);margin-top:5px;line-height:1.3}
.boss__sub b{color:var(--paper-dim);font-weight:500;font-family:var(--f-mono)}
/* Race to Dutch First-rang achter de voortgangsregel; goud voor de koploper,
   zoals op racetodutchfirst.bmiest.be. */
.boss__race{margin-left:8px;padding-left:8px;border-left:1px solid var(--ink-600);
  font-family:var(--f-mono);font-weight:500;color:var(--paper-dim);white-space:nowrap}
.boss__race.is-lead{color:var(--gold)}
.boss__stat{display:flex;align-items:flex-end;gap:18px;margin-top:12px}
.boss__v{font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:26px;font-weight:500;line-height:1}
.boss__v.jade{color:var(--jade)}
.boss__v.gold{color:var(--gold)}
.boss__l{font-size:8px;font-weight:600;color:var(--ink-400);margin-top:5px;
  letter-spacing:.14em;text-transform:uppercase}

/* pull-historie: hoger = meer boss-HP eraf */
.spark{display:flex;align-items:flex-end;gap:3px;height:30px;flex:0 0 auto;padding-bottom:2px}
.spark i{width:6px;min-height:2px;display:block;background:var(--ink-500)}
.spark i.best{background:var(--paper-dim)}
.spark i.kill{background:var(--jade)}

/* Alleen het nieuwe staafje groeit in, en het grote getal licht kort op.
   Beweging die antwoordt op iets dat gebeurd is, en verder staat de reeks
   stil -- de hele rij laten animeren bij elke poll is beweging zonder
   nieuws, en dat kost bitrate naast je gameplay. */
.spark i.fresh{transform-origin:bottom;animation:sparkIn 520ms var(--ease) both}
@keyframes sparkIn{from{transform:scaleY(.12);opacity:.35}to{transform:none;opacity:1}}
.boss__v.hit{animation:bossHit 620ms var(--ease)}
@keyframes bossHit{0%{filter:brightness(2.3)}100%{filter:none}}

/* Melding bij een poging erbij, een nieuwe beste of een kill: schuift over de
   kaart omhoog, blijft liveTracking.flashSeconds staan en zakt weer weg.
   Boven de kaart uitkomen kan niet, de bron is 248px hoog.

   Een gewone poging krijgt dezelfde vorm met een gedempte kop (js/banner.js
   zet --acc en de timer). Alleen een nieuwe beste en
   een kill komen ook over je gameplay; een wipe elke twee minuten hoort niet
   over het beeld. */
.boss__flash{
  position:absolute;left:14px;right:14px;bottom:14px;z-index:3;
  transform:translateY(170%);opacity:0;
  transition:transform 420ms var(--ease), opacity 260ms var(--ease);
}
.boss__flash.on{transform:none;opacity:1}
.boss__flash .rib{--rib-h:34px;--rib-cut:11px}
.boss__flash .rib__val{font-size:15px}

/* =====================================================================
   4. CHAT
   ===================================================================== */
.card--chat .rcard__in{padding:15px 0 15px}
#chatList{
  display:flex;flex-direction:column;justify-content:flex-end;gap:7px;
  flex:1;min-height:0;padding:0 22px;overflow:hidden;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 30px,#000 100%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 30px,#000 100%);
}
/* Een chatregel is tekst, geen rij vakjes. Als flexrij bleven badge en naam
   op de eerste regel staan terwijl de tekst in een eigen kolom viel: onder
   naam en badge een gat, en bij een bericht van drie regels zakte de badge
   naar het midden van de rij (align-self:center op een rij die meegroeit).
   Inline laten lopen wrapt zoals chat hoort te wrappen: de tweede regel
   begint gewoon links. */
.msg{font-size:17px;line-height:1.3;
  animation:msgIn var(--t-fast) var(--ease) both}
@keyframes msgIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.msg__badges{display:inline-flex;gap:4px;margin-right:7px;vertical-align:2px}
.bdg{font-size:9px;font-weight:700;letter-spacing:.08em;padding:2px 6px;
  background:var(--ink-600);color:var(--ink-200);
  clip-path:polygon(0 0,100% 0,calc(100% - 4px) 100%,0 100%);
  text-transform:uppercase;line-height:1.35}
.bdg--broadcaster{background:var(--jade);color:var(--ink-900)}
.bdg--moderator  {background:var(--jade-deep);color:var(--paper)}
.bdg--vip        {background:var(--rose);color:var(--ink-900)}
.bdg--subscriber {background:var(--ink-500);color:var(--paper)}
.msg__name{font-weight:600;margin-right:7px}
.msg__body{color:var(--paper-dim);overflow-wrap:break-word}
.msg__body img.emote{height:22px;vertical-align:-5px;margin:0 1px}
.msg--action .msg__body{font-style:italic;color:var(--jade)}

/* =====================================================================
   5. RECENTE EVENTS  --  lijst, geen doorlopende ticker: constante
      beweging over de volle breedte eet bitrate die je gameplay nodig heeft
   ===================================================================== */
.events{display:flex;flex-direction:column;gap:10px;flex:1;min-height:0;overflow:hidden}
.ev{display:flex;align-items:center;gap:10px;font-size:17px;
  animation:msgIn var(--t-fast) var(--ease) both}
.ev .tag{font-size:8px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  padding:4px 8px;flex:0 0 auto;
  clip-path:polygon(0 0,100% 0,calc(100% - 5px) 100%,0 100%);
  background:var(--ink-600);color:var(--ink-200)}
.ev .tag--follow{background:var(--jade-ghost);color:var(--jade)}
.ev .tag--sub   {background:rgba(255,255,255,.11);color:var(--holy)}
.ev .tag--cheer,
.ev .tag--tip   {background:rgba(216,178,99,.14);color:var(--gold)}
.ev .tag--raid  {background:var(--jade-ghost);color:var(--jade)}
.ev b{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.ev i{margin-left:auto;font-style:normal;font-family:var(--f-mono);
  font-size:13px;color:var(--ink-400);flex:0 0 auto}
.events__empty{font-size:16px;color:var(--ink-500)}

#health{position:absolute;right:8px;top:4px;z-index:30;
  font-family:var(--f-mono);font-size:10px;color:var(--rose);
  opacity:0;transition:opacity var(--t-med)}
#health.show{opacity:.75}
