/* ============================================================ */
/* In-game Win Card                                             */
/*                                                              */
/* Port of chat-relay's /streamer "Win Card" widget — the        */
/* `.wc-frame > .win-card` block in                              */
/* /opt/chat-relay/public/streamer/goals-overlay.html — so the   */
/* card players see in-game is the card viewers see on stream.   */
/* Rendered by client/src/ui/WinOverlay.js (normal AND grid      */
/* mode; both entry points share the class).                     */
/*                                                              */
/* Everything is namespaced under .searchle-win-overlay-root.    */
/* The root/.swo-backdrop/.swo-hidden rules it relies on already */
/* live in main.css and are unchanged; the old `.holo` rules      */
/* next to them are now dead (nothing renders that DOM).         */
/*                                                              */
/* The card's config is baked into WIN_CARD_CONFIG in            */
/* WinOverlay.js, mirroring the live searchle-grid win card in   */
/* the relay's data/streamer-setups.json: glass / gold /         */
/* pad-regular, radius 0, no border, bg opacity 70, top 10.      */
/* ============================================================ */

.searchle-win-overlay-root {
  --text-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
}
.searchle-win-overlay-root .c-gold { --accent: #f6c453; --glow: rgba(246, 196, 83, 0.55); }

/* Outer frame — wraps .win-card so the winner's profile_border +
   profile_glow can decorate the entire popup. Stays inert (no border, no
   padding) until applyWinCardCosmetics writes --wc-frame-border /
   --wc-frame-glow. */
.searchle-win-overlay-root .wc-frame {
  display: inline-block;
  border-radius: var(--radius, 18px);
  padding: 0;
  border: var(--wc-frame-border, 0 solid transparent);
  box-shadow: var(--wc-frame-glow, none);
  transition: box-shadow 220ms ease, border-color 220ms ease;
  /* The root is pointer-events:none so the board stays clickable around
     the card; the card itself takes events back. */
  pointer-events: auto;
  opacity: 0;
  animation: wc-frame-fit-in 0.45s cubic-bezier(0.24, 1, 0.32, 1) 0.05s forwards;
}
/* Entrance. Its own keyframes rather than the .holo card's swo-glass-fade-in
   so the two can never drift into each other. .wc-frame starts at opacity:0
   and depends on this animation to become visible — if the name here and the
   animation-name above ever disagree, the card renders invisible. */
@keyframes wc-frame-fit-in {
  0%   { opacity: 0; transform: translateY(12px) scale(0.96); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
/* When the frame is decorated by a cosmetic, suppress the card's own border
   so we don't get a double-stroke offset from the cosmetic stroke. */
.searchle-win-overlay-root .wc-frame.wc-frame-decorated > .win-card {
  border-color: transparent !important;
  /* NESTED RADIUS. The card sits directly inside the frame's stroke
     (.wc-frame has padding:0), so its corner radius must be the frame's
     radius MINUS that stroke's width — otherwise the fill bulges out
     through the ring at every corner. --wc-frame-bw is written from the
     frame's COMPUTED border width (cosmetics supply arbitrary shorthands,
     so the width can't be parsed out of the string reliably). */
  border-radius: max(0px, calc(var(--radius, 18px) - var(--wc-frame-bw, 0px)));
}

/* Hero badge background layer — absolute-positioned behind the card content.
   Opacity is controlled by --wc-hero-opacity so text stays legible over even
   a busy badge. */
.searchle-win-overlay-root .wc-hero-bg {
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: var(--wc-hero-opacity, 0);
  background: var(--wc-hero-bg, transparent);
  background-size: cover;
  background-position: center;
  transition: opacity 220ms ease;
  z-index: 0;
}
/* The hero-bg lives inside .win-card; the flex children must render above
   it, so force them into a higher stacking context. */
.searchle-win-overlay-root .win-card > .wc-row,
.searchle-win-overlay-root .win-card > .wc-lb { position: relative; z-index: 1; }

.searchle-win-overlay-root .win-card {
  position: relative;
  min-width: 420px; max-width: 720px;
  border-radius: var(--radius, 18px);
  color: var(--text-c, inherit);
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.55), 0 0 60px var(--glow);
  display: flex; flex-direction: column; gap: 10px;
  /* NO overflow:hidden. .wc-hero-bg is inset:0 with border-radius:inherit so
     it already clips ITSELF — and the clip would also swallow the winner's
     avatar, which is deliberately allowed to spill past the card edges (see
     .wc-avatar). Re-adding overflow:hidden here squares the pfp off at the
     border and undoes the whole corner-badge look. */
  /* Avatar geometry, consumed by .wc-avatar's negative margins. --wc-av-padx
     / --wc-av-pady must mirror this preset's padding so the overhang is
     measured from the card BORDER rather than from the padding box. */
  --wc-av-size: 180px; --wc-av-padx: 22px; --wc-av-pady: 18px;
}
.searchle-win-overlay-root .win-card.pad-compact  { padding: 10px 14px; gap: 6px; --wc-av-size: 130px; --wc-av-padx: 14px; --wc-av-pady: 10px; }
.searchle-win-overlay-root .win-card.pad-regular  { padding: 18px 22px; gap: 10px; --wc-av-size: 180px; --wc-av-padx: 22px; --wc-av-pady: 18px; }
.searchle-win-overlay-root .win-card.pad-spacious { padding: 26px 32px; gap: 14px; --wc-av-size: 180px; --wc-av-padx: 32px; --wc-av-pady: 26px; }

.searchle-win-overlay-root .win-card.style-glass {
  background:
    linear-gradient(var(--glass-fill, rgba(0, 0, 0, 0.7)), var(--glass-fill, rgba(0, 0, 0, 0.7))) padding-box,
    var(--glass-edge, linear-gradient(135deg, rgba(255,255,255,0.55) 0%, rgba(255,255,255,0.06) 40%, rgba(255,255,255,0.22) 75%, rgba(255,255,255,0.05) 100%)) border-box;
  border: var(--bw, 1px) var(--bs, solid) transparent;
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  box-shadow:
    0 12px 48px rgba(0, 0, 0, 0.55),
    0 0 60px var(--glow),
    inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.searchle-win-overlay-root .win-card.style-solid    { background: #0d1320; border: var(--bw, 1px) var(--bs, solid) var(--bc, var(--accent)); }
.searchle-win-overlay-root .win-card.style-outlined { background: transparent; border: var(--bw, 2px) var(--bs, solid) var(--bc, var(--accent)); }
.searchle-win-overlay-root .win-card.style-banner   { background: linear-gradient(90deg, rgba(0,0,0,0.85), rgba(0,0,0,0.55)); border: 0; border-left: var(--bw, 4px) var(--bs, solid) var(--bc, var(--accent)); border-radius: 4px; min-width: 520px; max-width: 920px; }

.searchle-win-overlay-root .wc-row { display: flex; align-items: center; gap: 16px; }

/* Winner pfp — 180px, pinned to the card's top-left corner and deliberately
   spilling past the card's left and top borders so all that extra size costs
   the layout as little as possible. 40% of the disc hangs off the left edge,
   30% off the top.

   NEGATIVE MARGINS, not position:absolute. A flex item pulled left by a
   negative margin still reserves only the portion that stays INSIDE the row,
   so the text gutter and the row's height both come out right for free — and
   they collapse to nothing the moment the avatar is hidden (no profilePic, or
   the image failed to load), which an absolutely-positioned disc plus a
   hard-coded padding-left would not.

   The "- var(--wc-av-padx/pady)" terms cancel the card's own padding so the
   overhang is measured from the card BORDER; without them the padding eats
   most of the spill and the disc barely breaks the edge. */
.searchle-win-overlay-root .wc-avatar {
  width: var(--wc-av-size, 180px); height: var(--wc-av-size, 180px);
  border-radius: 50%;
  object-fit: cover;
  align-self: flex-start; /* upper-left corner, not vertically centered */
  margin-left: calc(var(--wc-av-size, 180px) * -0.4 - var(--wc-av-padx, 22px));
  margin-top:  calc(var(--wc-av-size, 180px) * -0.3 - var(--wc-av-pady, 18px));
  /* When the winner has profile_border, their cosmetic stroke overrides the
     accent ring. 5px so the ring still reads at 180px. */
  border: var(--wc-pfp-border, 5px solid var(--accent));
  outline: var(--wc-pfp-outline, none);
  /* profile_glow stacks on top of the accent halo so cosmetic owners get an
     additive halo (their tint + the card's accent). */
  box-shadow: var(--wc-pfp-glow, 0 0 20px var(--glow));
  flex-shrink: 0;
}
.searchle-win-overlay-root .win-card.pad-compact .wc-avatar { border-width: 4px; }
/* The WT logo (and profile-logo cosmetics) aren't perfect circles — a cover
   crop cuts the tile off the top. Matches the .is-logo treatment the rest of
   Searchle's avatars get; markAvatarLogo moves the art to background-image
   at 115% so it fills the ring without the source PNG's transparent padding. */
.searchle-win-overlay-root .wc-avatar.is-logo {
  object-fit: contain;
  background-color: transparent;
}

.searchle-win-overlay-root .wc-text { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.searchle-win-overlay-root .wc-headline {
  font-weight: 900; font-size: calc(1.05rem * var(--tm, 1) / var(--ws, 1)); color: var(--accent);
  letter-spacing: 0.05em; text-transform: uppercase;
  text-shadow: var(--text-shadow);
}
.searchle-win-overlay-root .wc-name-line { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; min-width: 0; }

/* Name + winning-word chip share one line. It is a FLEX row, not plain inline
   text, so the chip can never be the thing that gets clipped: the name
   shrinks to an ellipsis (.wc-name-text) and the word always reads. */
.searchle-win-overlay-root .wc-name {
  font-weight: 800; font-size: calc(1.6rem * var(--tm, 1) / var(--ws, 1));
  text-shadow: var(--text-shadow);
  display: flex; align-items: center; min-width: 0; overflow: hidden;
}
/* The shrinkable half of a name line (win card + leaderboard rows). */
.searchle-win-overlay-root .wc-name-text {
  flex: 0 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.searchle-win-overlay-root .win-card.pad-compact .wc-name { font-size: calc(1.25rem * var(--tm, 1) / var(--ws, 1)); }
.searchle-win-overlay-root .wc-game-pill {
  font-size: calc(0.78rem * var(--tm, 1) / var(--ws, 1)); font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent);
}
.searchle-win-overlay-root .wc-meta { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; font-size: calc(0.92rem * var(--tm, 1) / var(--ws, 1)); opacity: 0.92; }
.searchle-win-overlay-root .wc-chip { padding: 2px 8px; border-radius: 8px; background: rgba(255, 255, 255, 0.08); font-variant-numeric: tabular-nums; }

.searchle-win-overlay-root .wc-lb {
  display: flex; flex-direction: column; gap: 4px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-top: 8px;
  /* Nine rows fit comfortably on a desktop viewport, but a short window (or
     a phone in landscape) would push the card past the screen. Scroll the
     LIST rather than the card — .win-card must never get an overflow rule
     or it clips the avatar's overhang. */
  max-height: 46vh; overflow-y: auto;
}
.searchle-win-overlay-root .wc-lb-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; font-size: calc(0.92rem * var(--tm, 1) / var(--ws, 1)); }
.searchle-win-overlay-root .wc-lb-rank { width: 22px; text-align: center; font-weight: 800; color: rgba(255, 255, 255, 0.7); font-variant-numeric: tabular-nums; }
.searchle-win-overlay-root .wc-lb-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: calc(0.85rem * var(--tm, 1) / var(--ws, 1)); overflow: hidden; flex-shrink: 0;
}
.searchle-win-overlay-root .wc-lb-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }
.searchle-win-overlay-root .wc-lb-avatar.has-logo { overflow: visible; background: transparent; }
.searchle-win-overlay-root .wc-lb-avatar img.is-logo { object-fit: contain; }
.searchle-win-overlay-root .wc-lb-name { flex: 1; min-width: 0; display: flex; align-items: center; overflow: hidden; }
.searchle-win-overlay-root .wc-lb-points { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--accent); }

/* Word chip — the word the winner solved, next to their name. */
.searchle-win-overlay-root .wc-found-word {
  display: inline-block;
  padding: 1px 10px;
  margin-left: 8px;
  border: 1px solid rgba(0, 0, 0, 0.55);
  border-radius: 8px;
  font-size: 0.78em;
  font-weight: 700;
  letter-spacing: 0.02em;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  vertical-align: middle;
  white-space: nowrap;
  /* Never shrink or wrap inside a .wc-name flex row — the name yields space
     to the word, not the other way round. */
  flex: 0 0 auto; max-width: 100%;
}

/* ── Narrow screens ──
   The card's natural footprint is ~620px: a 420px minimum body plus the
   avatar's ~94px of left overhang. On a phone there is not room, and letting
   it reflow is worse than useless — the word chip holds its full width by
   design, so the winner's NAME is what collapses, right down to a single
   ellipsised character.

   Scale it down through the card's OWN size vars rather than a transform:
   every font-size in this file is calc(<base>rem * var(--tm)), and the avatar
   reads --wc-av-size, so setting those two (plus the padding they're keyed
   to) shrinks the card as a unit with no unit math. A transform can't do it
   — .wc-frame is mid-animation on that property, and `scale()` needs a
   unitless ratio, which calc() cannot derive from a vw length.

   --wc-av-padx / --wc-av-pady MUST keep mirroring the padding here or the
   avatar's overhang stops lining up with the card border. */
@media (max-width: 620px) {
  .searchle-win-overlay-root .win-card.pad-regular {
    --tm: 0.8;
    --wc-av-size: 132px; --wc-av-padx: 16px; --wc-av-pady: 14px;
    padding: 14px 16px;
    min-width: 0; max-width: calc(100vw - 77px);
  }
  /* Shove the card right by the avatar's overhang so the disc doesn't run off
     the left edge — but ONLY when there is an avatar, or a card without one
     (a solo win, or a player with no pfp) sits visibly off-centre.
     .wc-has-avatar is set by WinOverlay.show(). */
  .searchle-win-overlay-root .wc-frame.wc-has-avatar { margin-left: 69px; }
  .searchle-win-overlay-root .wc-frame:not(.wc-has-avatar) .win-card { max-width: calc(100vw - 16px); }
}
@media (max-width: 420px) {
  .searchle-win-overlay-root .win-card.pad-regular {
    --tm: 0.66;
    --wc-av-size: 104px; --wc-av-padx: 14px; --wc-av-pady: 12px;
    padding: 12px 14px;
    max-width: calc(100vw - 64px);
  }
  .searchle-win-overlay-root .wc-frame.wc-has-avatar { margin-left: 56px; }
}
