/*
 * Base styles for the FACEIT overlay.
 *
 * Theme files in /themes/ override the CSS custom properties
 * (--bg, --accent, --win, etc.). This file owns the layout, the
 * card composition, and the skeleton/error states.
 *
 * Sizes follow the spec composition for the `vertical` layout
 * (380×~220px). Horizontal and compact layouts come in M5.
 */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: transparent;
  color: var(--text, #e8eaed);
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.mono {
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

.overlay-root {
  display: inline-block;
}

/* --------------------------------------------------------------------------
 * Card — outermost frame for all states (calibration, ranked, error, loading)
 * ------------------------------------------------------------------------ */

.card {
  position: relative; /* watermark anchors to bottom-right */
  width: 380px;
  padding: 18px 20px;
  border-radius: 12px;
  background: var(--bg, #0d1117);
  border: 1px solid var(--border, #1f2733);
  display: grid;
  gap: 14px;
  box-sizing: border-box;
  animation: card-fade-in 200ms ease-out;
}

[data-nobg="1"] .card {
  background: transparent;
  border-color: transparent;
}

/* Suppress fade-in on background refresh ticks — value swaps shouldn't
   re-animate the whole card every minute. M6 will add per-value pulse
   transitions on actual changes. */
.overlay-root--silent .card {
  animation: none;
}

@keyframes card-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --------------------------------------------------------------------------
 * Header — avatar + nickname + sub + badge
 * ------------------------------------------------------------------------ */

.card__header {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  align-items: center;
}

/*
 * .avatar is the 36×36 round box. Two flavors share it:
 *   - <img class="avatar"> for real player avatars (FACEIT CDN / DiceBear)
 *   - <div class="avatar avatar--initials"> for the colored-initials fallback
 * Splitting the rules avoids img inheriting `display: flex` (which makes
 * non-square FACEIT avatars escape the circle mask on some browsers).
 */
.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--bg-2, #161b22);
  overflow: hidden;
  flex-shrink: 0;
}

img.avatar {
  display: block;
  width: 36px;
  height: 36px;
  object-fit: cover;
}

.avatar--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 600;
  font-size: 13px;
  font-family: "Inter", sans-serif;
}

.card__title {
  min-width: 0;
}

.card__nick {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card__sub {
  font-size: 11px;
  font-weight: 400;
  color: var(--text-dim);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Right-aligned badge: CAL during calibration, LVL N when ranked. */
.badge {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 4px 7px;
  border-radius: 4px;
  background: var(--bg-2);
  color: var(--text-dim);
  white-space: nowrap;
}

.badge--cal {
  background: var(--accent);
  color: #fff;
}

.badge--lvl {
  background: var(--bg-2);
  color: var(--accent);
  border: 1px solid var(--accent);
}

/* --------------------------------------------------------------------------
 * Level badge — official FACEIT PNG icons from public/assets/levels/.
 * Each icon already includes ring, color, and level number, so we just
 * size and add a soft drop-shadow so it lifts off any background.
 * ------------------------------------------------------------------------ */

.lvl-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
}

.lvl-badge__img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
  /* Crisp scaling — FACEIT level icons are pixel-art-friendly at small sizes. */
  image-rendering: -webkit-optimize-contrast;
}

/* --------------------------------------------------------------------------
 * Unranked badge — grey question-mark circle shown during calibration in
 * place of the level icon. Same 32×32 footprint as .lvl-badge so the two
 * swap cleanly when calibrationDone flips. All colors come from CSS
 * variables so neon / light / liquid-glass themes adapt automatically.
 *
 * Pure CSS — circle shape is just border-radius:50%, the "?" is a child
 * span. No SVG, no external image.
 * ------------------------------------------------------------------------ */

.unranked-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--bg-2);
  border: 1px solid color-mix(in srgb, var(--text-dim) 40%, transparent);
  flex-shrink: 0;
  /* Subtle drop on dark themes; barely visible on light, by design. */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  user-select: none;
}

.unranked-badge__q {
  font-family: "Inter", system-ui, sans-serif;
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  color: var(--text-dim);
  /* Pull up a hair so the question mark visually centers — Inter's "?"
     glyph baseline sits low. */
  margin-top: -1px;
  letter-spacing: 0;
}

/* --------------------------------------------------------------------------
 * Progress block — used by both placement (calibration) and last-10 (ranked)
 * ------------------------------------------------------------------------ */

.progress {
  display: grid;
  gap: 6px;
}

.progress__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.progress__meta {
  font-size: 11px;
  color: var(--text-dim);
}

.progress__meta.is-up   { color: var(--win); }
.progress__meta.is-down { color: var(--loss); }
.progress__meta.is-zero { color: var(--text-dim); }

.progress__bar {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 4px;
}

.seg {
  height: 6px;
  border-radius: 2px;
  background: var(--bg-2);
  transition: background-color 200ms ease;
  transform-origin: left center;
}

.seg--win   { background: var(--win); }
.seg--loss  { background: var(--loss); }
.seg--empty { background: var(--bg-2); }

/* Newly added placement segment fades in from collapsed when the player
   completes another match. paint() applies .is-new for ~500ms then strips
   it so subsequent unrelated paints don't replay the animation. */
.seg.is-new {
  animation: seg-fade-in 450ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

@keyframes seg-fade-in {
  0%   { opacity: 0; transform: scaleX(0.2); }
  100% { opacity: 1; transform: scaleX(1); }
}

/* --------------------------------------------------------------------------
 * Stats grid — 3 columns: W/L · KD · WIN RATE  (or KD · ADR · HS%)
 * ------------------------------------------------------------------------ */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.stat__label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 4px;
  white-space: nowrap;
}

.stat__value {
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  line-height: 1;
}

/* --------------------------------------------------------------------------
 * Error state — same card frame, centered iconography
 * ------------------------------------------------------------------------ */

.card--error {
  justify-items: center;
  text-align: center;
  padding: 22px 20px;
  gap: 6px;
}

.error__icon {
  font-size: 22px;
  color: var(--loss);
  line-height: 1;
}

.error__msg {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
}

.error__hint {
  font-size: 11px;
  color: var(--text-dim);
}

/* --------------------------------------------------------------------------
 * Skeleton / shimmer — shown during initial load and ?mock=loading
 * ------------------------------------------------------------------------ */

.skel {
  background: linear-gradient(
    90deg,
    var(--bg-2) 0%,
    color-mix(in srgb, var(--text-dim) 18%, var(--bg-2)) 50%,
    var(--bg-2) 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
  border-radius: 4px;
}

@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.skel--avatar { width: 36px; height: 36px; border-radius: 50%; }
.skel--nick   { width: 60%; height: 14px; margin-bottom: 6px; }
.skel--sub    { width: 80%; height: 11px; }
.skel--label  { width: 30%; height: 10px; margin-bottom: 8px; }
.skel--bar    { width: 100%; height: 6px; }
.skel--stat   { height: 30px; }

/* --------------------------------------------------------------------------
 * Cache-status dot — shown when stale=true (M4 will toggle the class)
 * ------------------------------------------------------------------------ */

.stale-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-dim);
  margin-left: 6px;
  vertical-align: middle;
  animation: stale-pulse 1.6s ease-in-out infinite;
}

@keyframes stale-pulse {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 0.85; }
}

/* --------------------------------------------------------------------------
 * Value-change pulse — soft accent-color flash on a stat that just changed.
 * paint() adds .is-changed for the keyframe duration, then strips it so the
 * same field can pulse again on a future refresh without an animation-name
 * reset hack.
 * ------------------------------------------------------------------------ */

.is-changed {
  animation: value-pulse 600ms ease-out;
  border-radius: 4px;
}

@keyframes value-pulse {
  0%   { background-color: color-mix(in srgb, var(--accent) 40%, transparent); }
  60%  { background-color: color-mix(in srgb, var(--accent) 20%, transparent); }
  100% { background-color: transparent; }
}

/* --------------------------------------------------------------------------
 * Inline W/L bars — small last-5 recap rendered next to the nickname in
 * the compact layout. Mini-segments (3×8) so they read as a tiny version
 * of the full placement bar, not a separate widget.
 * ------------------------------------------------------------------------ */

.bars {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.bar {
  display: inline-block;
  width: 3px;
  height: 8px;
  border-radius: 1px;
}

.bar--win   { background: var(--win); }
.bar--loss  { background: var(--loss); }
.bar--empty { background: var(--bg-2); }

/* Compact bars: 10 horizontal segments stretched between nickname and
   the level badge, with a small breathing-room on the right so the
   last segment doesn't run into the badge column. */
[data-layout="compact"] .bars,
.layout-compact .bars {
  flex: 1 1 0;
  min-width: 0;
  gap: 2px;
  margin-right: 16px;
}

[data-layout="compact"] .bar,
.layout-compact .bar {
  flex: 1 1 0;
  width: auto;
  height: 5px;
  border-radius: 2px;
}

/* --------------------------------------------------------------------------
 * Watermark — small "powered by relaxie" tag anchored to bottom-right of
 * the card. Hidden in compact (no room) and on error/loading states.
 * Pointer-events off so it never intercepts clicks (overlay is OBS only,
 * but defensive).
 * ------------------------------------------------------------------------ */

.card__watermark {
  position: absolute;
  top: 4px;
  right: 8px;
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  opacity: 0.4;
  pointer-events: none;
  user-select: none;
  font-family: "Inter", sans-serif;
  text-transform: lowercase;
}

[data-layout="compact"] .card__watermark,
.layout-compact .card__watermark,
.card--error .card__watermark,
.card--loading .card__watermark {
  display: none;
}

/* --------------------------------------------------------------------------
 * Card badges — wraps challenger badge + level icon together so they sit
 * side-by-side in the header's right slot. Either one can be absent.
 * ------------------------------------------------------------------------ */

.card__badges {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Challenger badge — colored ring around a black disc with #N inside.
   Surfaces the player's regional position when they're in the top-1000. */

.challenger-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
}

.challenger-badge svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}

.challenger-badge__num {
  position: relative;
  z-index: 1;
  font-size: 9px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
  line-height: 1;
}

/* --------------------------------------------------------------------------
 * Layout: horizontal — 720×~120, three columns side by side.
 * Selector is duplicated for [data-layout] (live mode) and .layout-N
 * (demo grid where each cell scopes its own layout).
 * ------------------------------------------------------------------------ */

[data-layout="horizontal"] .card,
.layout-horizontal .card {
  width: 720px;
  grid-template-columns: 200px 1fr 220px;
  grid-template-rows: auto;
  gap: 24px;
  align-items: center;
}

[data-layout="horizontal"] .card__header,
.layout-horizontal .card__header {
  /* Avatar + title + lvl-badge. Text CAL badge is dropped (no room for
     a wide badge here), but the level icon stays since it's just 32px. */
  grid-template-columns: 36px 1fr auto;
}

[data-layout="horizontal"] .card__header .badge,
.layout-horizontal .card__header .badge {
  display: none;
}

[data-layout="compact"] .card__badges,
.layout-compact .card__badges {
  gap: 4px;
}

[data-layout="compact"] .challenger-badge,
.layout-compact .challenger-badge {
  display: none;
}

/* --------------------------------------------------------------------------
 * Layout: compact — 380×~80, single line. Avatar + nick + summary.
 * Hides the placement bar and stats grid; the subtitle slot becomes the
 * one-line numeric summary (computed in overlay.js: compactSummary*).
 * ------------------------------------------------------------------------ */

[data-layout="compact"] .card,
.layout-compact .card {
  width: 380px;
  padding: 12px 16px;
  grid-template-columns: 36px 1fr auto;
  grid-template-rows: auto;
  gap: 12px;
  align-items: center;
}

/* display: contents lets header's children participate directly in the
   card grid, so we get [avatar] [title] [badge] in one row. */
[data-layout="compact"] .card__header,
.layout-compact .card__header {
  display: contents;
}

[data-layout="compact"] .card__sub,
.layout-compact .card__sub {
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--text);
  margin-top: 2px;
}

/* Compact nick row becomes a flex row so the bars sit next to the
   nickname text. Nick text gets its own span with ellipsis so a long
   nickname truncates instead of pushing the bars off the card. */
[data-layout="compact"] .card__nick,
.layout-compact .card__nick {
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

[data-layout="compact"] .card__nick-text,
.layout-compact .card__nick-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex-shrink: 1;
}

[data-layout="compact"] .progress,
[data-layout="compact"] .stats,
.layout-compact .progress,
.layout-compact .stats {
  display: none;
}

[data-layout="compact"] .lvl-badge,
.layout-compact .lvl-badge,
[data-layout="compact"] .unranked-badge,
.layout-compact .unranked-badge {
  width: 26px;
  height: 26px;
}

[data-layout="compact"] .unranked-badge__q,
.layout-compact .unranked-badge__q {
  font-size: 14px;
}

[data-layout="compact"] .badge--cal,
.layout-compact .badge--cal {
  font-size: 9px;
  padding: 3px 6px;
}

/* --------------------------------------------------------------------------
 * ?demo=1 page — 4 themes × 3 layouts grid, each cell self-contained.
 * Renders against a colorful gradient so liquid-glass blur is visible.
 * ------------------------------------------------------------------------ */

[data-demo="1"] body,
.demo-page {
  background: radial-gradient(ellipse at top left, #1e1b4b 0%, transparent 50%),
              radial-gradient(ellipse at bottom right, #831843 0%, transparent 50%),
              linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
  background-attachment: fixed;
  min-height: 100vh;
}

.demo-grid {
  padding: 32px;
  display: grid;
  grid-template-columns: 380px 720px 380px;
  gap: 28px 32px;
  justify-content: start;
  align-items: start;
}

.demo-cell {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.demo-label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  font-family: "JetBrains Mono", ui-monospace, monospace;
}

.demo-title {
  margin: 24px 32px 0;
  color: rgba(255, 255, 255, 0.9);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.05em;
}

.demo-title .mono {
  color: var(--accent, #ff5500);
}
