/* ═══════════════════════════════════════════════════════════════════════
   Blood & Nectar — the FRIENDS RAIL.
   ---------------------------------------------------------------------
   The right-hand social rail, on the same terms as shell-topbar.css:
   EVERYTHING here is self-contained. The tokens the rail needs are
   declared on #bn-friends itself, never on :root, and every selector is
   scoped under #bn-friends — so /game/ (a 10k-line page that deliberately
   does NOT load shell.css) can wear the identical rail without a single
   global rule leaking into its layout.

   The rail is `position:fixed` and overlays the page rather than sitting
   in flow. That is on purpose: /game/'s views are themselves fixed
   full-screen overlays, so a rail in normal flow would be painted over.
   Pages that WANT to reserve space can read --bn-friends-w, which
   friends.js keeps in sync on <html> (0px while collapsed).

   Consumers:
     • web/game/index.html         — links it directly
     • web/game/collection.html    — links it directly
   Bump the ?v= on BOTH when you edit this file: .css is not in
   battleApi's no-store list, so browsers keep a stale copy otherwise.
   ═══════════════════════════════════════════════════════════════════════ */

#bn-friends{
  --gold:#c8aa6e;--gold-lt:#f0e6d2;--gold-dk:#785a28;--gold-d2:#463714;
  --teal:#0ac8b9;--text:#f0e6d2;--text-m:#a09b8c;--text-d:#5b5a56;
  --border:rgba(200,170,110,.15);
  --on:#5fd478;--away:#e8c874;--off:#5b5a56;
  --fd:'Cinzel Decorative',serif;--fu:'Alegreya Sans',sans-serif;
  --w:264px;

  position:fixed;top:54px;right:0;bottom:0;width:var(--w);z-index:55;
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,#040e18,#020a11);
  border-left:1px solid var(--border);
  font-family:var(--fu);color:var(--text);box-sizing:border-box;
  transition:transform .22s ease;
}
#bn-friends *,#bn-friends *::before,#bn-friends *::after{box-sizing:border-box;}
#bn-friends.collapsed{transform:translateX(100%);}

/* The handle stays put when the rail slides away — it is the way back in. */
#bn-friends .fr-handle{
  position:absolute;top:14px;left:-30px;width:30px;height:64px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  background:linear-gradient(180deg,#040e18,#020a11);
  border:1px solid var(--border);border-right:none;border-radius:4px 0 0 4px;
  cursor:pointer;color:var(--gold);font-size:13px;line-height:1;
  transition:color .15s,border-color .15s;
}
#bn-friends .fr-handle:hover{border-color:rgba(200,170,110,.45);color:var(--gold-lt);}
#bn-friends .fr-handle .hc{
  font-family:var(--fu);font-size:9px;font-weight:800;color:var(--on);letter-spacing:0;
}
#bn-friends:not(.collapsed) .fr-handle .hc{display:none;}

/* ═══ HEADER ═══ */
#bn-friends .fr-head{
  display:flex;align-items:center;gap:8px;padding:0 12px;height:44px;flex-shrink:0;
  border-bottom:1px solid var(--border);
}
#bn-friends .fr-title{
  font-family:var(--fd);font-size:10px;font-weight:700;letter-spacing:3px;
  text-transform:uppercase;color:var(--gold);white-space:nowrap;
}
#bn-friends .fr-count{font-size:11px;color:var(--text-d);margin-left:auto;letter-spacing:.5px;}
#bn-friends .fr-ico{
  width:26px;height:26px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  background:none;border:1px solid transparent;border-radius:3px;
  color:var(--text-m);font-size:14px;line-height:1;cursor:pointer;transition:all .15s;
}
#bn-friends .fr-ico:hover{color:var(--gold);border-color:rgba(200,170,110,.35);}
#bn-friends .fr-ico.on{color:var(--gold);border-color:var(--gold);}

/* ═══ ADD-FRIEND SEARCH ═══ */
#bn-friends .fr-add{display:none;padding:10px 12px;border-bottom:1px solid var(--border);}
#bn-friends .fr-add.open{display:block;}
#bn-friends .fr-add input{
  width:100%;background:rgba(1,10,19,.85);border:1px solid rgba(200,170,110,.22);border-radius:3px;
  color:var(--text);font-family:var(--fu);font-size:12.5px;padding:7px 10px;outline:none;
}
#bn-friends .fr-add input:focus{border-color:rgba(200,170,110,.55);}
#bn-friends .fr-add input::placeholder{color:var(--text-d);}
#bn-friends .fr-hint{font-size:10.5px;color:var(--text-d);line-height:1.5;margin-top:7px;}

/* ═══ LIST ═══ */
#bn-friends .fr-list{flex:1;overflow-y:auto;overflow-x:hidden;padding-bottom:12px;}
#bn-friends .fr-list::-webkit-scrollbar{width:6px;}
#bn-friends .fr-list::-webkit-scrollbar-thumb{background:rgba(200,170,110,.2);border-radius:3px;}
#bn-friends .fr-sec{
  display:flex;align-items:center;gap:6px;padding:14px 12px 6px;
  font-family:var(--fd);font-size:9px;letter-spacing:2.5px;text-transform:uppercase;
  color:rgba(200,170,110,.4);cursor:pointer;user-select:none;
}
#bn-friends .fr-sec:hover{color:rgba(200,170,110,.7);}
#bn-friends .fr-sec .sec-lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* The online/total tally sits hard right, like the client's own group headers,
   so the numbers line up down the rail instead of drifting with label length. */
#bn-friends .fr-sec .sec-n{margin-left:auto;flex-shrink:0;letter-spacing:1px;color:rgba(200,170,110,.55);}
#bn-friends .fr-sec .caret{font-size:8px;flex-shrink:0;transition:transform .15s;}
#bn-friends .fr-sec.shut .caret{transform:rotate(-90deg);}

#bn-friends .fr-row{
  display:flex;align-items:center;gap:9px;padding:6px 12px;cursor:pointer;
  border-left:2px solid transparent;transition:background .12s,border-color .12s;
}
#bn-friends .fr-row:hover{background:rgba(200,170,110,.06);border-left-color:rgba(200,170,110,.45);}
#bn-friends .fr-row.sel{background:rgba(200,170,110,.09);border-left-color:var(--gold);}

#bn-friends .fr-av{
  position:relative;width:30px;height:30px;flex-shrink:0;border-radius:50%;
  background:linear-gradient(140deg,#1b2a3b,#0c1622);border:1px solid rgba(200,170,110,.25);
  display:flex;align-items:center;justify-content:center;overflow:hidden;
  font-family:var(--fd);font-size:12px;color:var(--gold);
}
#bn-friends .fr-av img{width:100%;height:100%;object-fit:cover;display:block;}
#bn-friends .fr-dot{
  position:absolute;right:-1px;bottom:-1px;width:9px;height:9px;border-radius:50%;
  border:2px solid #030c15;background:var(--off);
}
#bn-friends .fr-row.st-online  .fr-dot{background:var(--on);}
#bn-friends .fr-row.st-away    .fr-dot{background:var(--away);}
#bn-friends .fr-row.st-offline .fr-av{opacity:.5;}

#bn-friends .fr-who{display:block;min-width:0;flex:1;overflow:hidden;}
/* display:block is load-bearing, not tidiness: these are <span>s, and
   text-overflow:ellipsis does nothing to an inline box — a long display name
   would push the row wider than the rail and make the whole list scroll
   sideways instead of truncating. */
#bn-friends .fr-name{
  display:block;font-size:12.5px;font-weight:600;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
#bn-friends .fr-row.st-offline .fr-name{color:var(--text-m);}
#bn-friends .fr-sub{
  display:block;font-size:10.5px;color:var(--text-d);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px;
}
#bn-friends .fr-row.st-online .fr-sub{color:rgba(95,212,120,.75);}

#bn-friends .fr-badge{
  flex-shrink:0;min-width:16px;height:16px;padding:0 5px;border-radius:9px;
  display:flex;align-items:center;justify-content:center;
  background:var(--gold-dk);color:var(--gold-lt);font-size:10px;font-weight:800;
}

/* Request rows carry their answer inline — a friend request that needs a
   second click to find its buttons is a friend request that rots. */
#bn-friends .fr-acts{display:flex;gap:4px;flex-shrink:0;}
#bn-friends .fr-btn{
  background:rgba(1,10,19,.6);border:1px solid rgba(200,170,110,.28);border-radius:3px;
  color:var(--text-m);font-family:var(--fu);font-size:10px;font-weight:700;
  letter-spacing:.5px;padding:4px 7px;cursor:pointer;transition:all .15s;white-space:nowrap;
}
#bn-friends .fr-btn:hover{border-color:var(--gold);color:var(--gold);}
#bn-friends .fr-btn.yes:hover{border-color:var(--on);color:var(--on);}
#bn-friends .fr-btn.no:hover{border-color:#e5544b;color:#e5544b;}

#bn-friends .fr-empty{
  padding:16px 14px;font-size:11.5px;color:var(--text-d);line-height:1.6;
}
#bn-friends .fr-empty b{color:var(--gold);font-weight:700;}

/* ═══ SIGNED-OUT / FOOTER ═══ */
#bn-friends .fr-foot{
  flex-shrink:0;padding:9px 12px;border-top:1px solid var(--border);
  font-size:10px;color:var(--text-d);line-height:1.5;
}
#bn-friends .fr-foot a{color:var(--gold-dk);text-decoration:none;}
#bn-friends .fr-foot a:hover{color:var(--gold);text-decoration:underline;}

/* ═══ THE PANEL (quick chat + actions), League's voice-popup slot ═══ */
#bn-friends .fr-panel{
  position:absolute;right:calc(100% + 8px);bottom:14px;width:290px;
  background:linear-gradient(165deg,#0b1826,#050b12);
  border:1px solid rgba(200,170,110,.3);border-radius:6px;
  box-shadow:0 16px 44px rgba(0,0,0,.72);
  display:none;flex-direction:column;overflow:hidden;
}
#bn-friends .fr-panel.open{display:flex;}
#bn-friends .fr-panel .pn-head{
  display:flex;align-items:center;gap:9px;padding:11px 12px;
  border-bottom:1px solid rgba(200,170,110,.14);
}
#bn-friends .fr-panel .pn-name{font-size:13px;font-weight:700;color:var(--gold-lt);flex:1;min-width:0;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
/* Same reason as .fr-name above — an inline span cannot ellipsise. */
#bn-friends .fr-panel .pn-sub{display:block;font-size:10.5px;color:var(--text-d);margin-top:1px;font-weight:400;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
#bn-friends .fr-panel .pn-x{
  background:none;border:none;color:var(--text-d);font-size:17px;line-height:1;cursor:pointer;padding:0 2px;
}
#bn-friends .fr-panel .pn-x:hover{color:var(--gold);}

#bn-friends .pn-cta{display:flex;gap:6px;padding:10px 12px;border-bottom:1px solid rgba(200,170,110,.1);}
#bn-friends .pn-cta button{
  flex:1;padding:8px 6px;border-radius:3px;cursor:pointer;transition:all .18s;
  font-family:var(--fd);font-size:9px;letter-spacing:1.5px;text-transform:uppercase;
  background:linear-gradient(135deg,var(--gold-dk),var(--gold-d2));
  border:1px solid var(--gold-dk);color:var(--gold-lt);
}
#bn-friends .pn-cta button:hover{background:linear-gradient(135deg,var(--gold),var(--gold-dk));}
#bn-friends .pn-cta button.ghost{
  background:transparent;border-color:rgba(200,170,110,.25);color:rgba(200,170,110,.65);
}
#bn-friends .pn-cta button.ghost:hover{border-color:var(--gold);color:var(--gold);background:transparent;}

/* The ··· menu. Favourite / remove / block, inline rather than a browser
   prompt — this rail sits inside a game client, not a form. */
#bn-friends .pn-more{
  display:flex;flex-direction:column;border-bottom:1px solid rgba(200,170,110,.12);
  background:rgba(1,10,19,.5);
}
#bn-friends .pn-more button{
  text-align:left;background:none;border:none;cursor:pointer;
  font-family:var(--fu);font-size:11.5px;color:var(--text-m);padding:8px 14px;transition:all .13s;
}
#bn-friends .pn-more button:hover{background:rgba(200,170,110,.08);color:var(--gold-lt);}
#bn-friends .pn-more button.danger:hover{background:rgba(229,84,75,.1);color:#e5544b;}
#bn-friends .pn-cta button.ghost.on{border-color:var(--gold);color:var(--gold);}

#bn-friends .pn-log{
  max-height:190px;overflow-y:auto;padding:10px 12px;display:flex;flex-direction:column;gap:6px;
}
#bn-friends .pn-log::-webkit-scrollbar{width:5px;}
#bn-friends .pn-log::-webkit-scrollbar-thumb{background:rgba(200,170,110,.2);border-radius:3px;}
#bn-friends .pn-msg{
  max-width:82%;padding:5px 9px;border-radius:9px;font-size:12px;line-height:1.4;
  background:rgba(255,255,255,.05);color:var(--text);align-self:flex-start;
}
#bn-friends .pn-msg.mine{align-self:flex-end;background:rgba(200,170,110,.14);color:var(--gold-lt);}
#bn-friends .pn-none{font-size:11px;color:var(--text-d);line-height:1.6;text-align:center;padding:6px 0;}

/* Quick chat is the WHOLE vocabulary — there is no text input here, and that
   is a product decision, not a stub. See logic/social.js. */
#bn-friends .pn-say{
  display:flex;flex-wrap:wrap;gap:5px;padding:10px 12px;border-top:1px solid rgba(200,170,110,.12);
}
#bn-friends .pn-say button{
  background:rgba(1,10,19,.7);border:1px solid rgba(200,170,110,.2);border-radius:12px;
  color:var(--text-m);font-family:var(--fu);font-size:11px;padding:4px 9px;cursor:pointer;transition:all .15s;
}
#bn-friends .pn-say button:hover{border-color:var(--gold);color:var(--gold-lt);}
#bn-friends .pn-say button:disabled{opacity:.4;cursor:default;}
#bn-friends .pn-note{
  padding:0 12px 10px;font-size:10px;color:var(--text-d);line-height:1.5;
}

/* ═══ NARROW SCREENS ═══
   The rail is the first thing to go: it is company, not the game. */
@media (max-width:1100px){
  #bn-friends{--w:238px;}
}
@media (max-width:820px){
  #bn-friends{display:none;}
}

/* ── A friend who is fighting right now ──────────────────────────────────
   `inMatch` is not a presence label: it comes from the live duel registry
   (see logic/social.js setLiveMatchLookup), so it is true the instant the
   match starts and false the instant it ends, regardless of what their
   heartbeat last said. It is the one row on the rail with something to
   press, so it reads red rather than sitting in the green online band. */
#bn-friends .fr-row.in-match{
  background:rgba(255,90,90,.06);border-left-color:rgba(255,110,110,.5);
}
#bn-friends .fr-row.in-match:hover{background:rgba(255,90,90,.1);}
#bn-friends .fr-row.in-match .fr-sub{color:rgba(255,145,145,.85);}
#bn-friends .fr-row.in-match .fr-dot{
  background:#ff6b6b;animation:bn-fr-live 2s ease-out infinite;
}
@keyframes bn-fr-live{
  0%{box-shadow:0 0 0 0 rgba(255,107,107,.55);}
  70%{box-shadow:0 0 0 5px rgba(255,107,107,0);}
  100%{box-shadow:0 0 0 0 rgba(255,107,107,0);}
}
@media (prefers-reduced-motion:reduce){
  #bn-friends .fr-row.in-match .fr-dot{animation:none;}
}

/* Observe takes Challenge's slot while they are mid-fight — a challenge sent
   now would only sit unanswered until the match ended. */
#bn-friends .pn-cta button.watch{
  background:linear-gradient(135deg,#8f2b2b,#571818);
  border-color:#8f2b2b;color:#ffe4e4;
}
#bn-friends .pn-cta button.watch:hover{
  background:linear-gradient(135deg,#b83c3c,#7a2020);border-color:#b83c3c;
}
