/* Extraction Compass - shared card + tag components.
   Used by BOTH branches of index.php: the homepage results grid (tool.css) AND
   the "similar games" grid + fact-tag row on the game detail / 404 page (game.css).
   ec_render_card() in render-ssr.php and cardTemplate() in index.php both emit this
   markup, so the rules that dress it have to load on every route index.php serves.

   Load order: /tokens.css -> /base.css -> /components.css -> (/tool.css | /game.css)
   -> /header.css. Page CSS and @media blocks come after and win.

   NOT here: layout that is genuinely homepage-only (the .main grid, filter panel,
   hero, release/deal strips, detail modal, FAQ, A-Z index, top-hit view) stays in
   tool.css; the game-page-only blocks stay in game.css. */

/* ---------- results grid ---------- */
.grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 20px;
}
.grid-compact{ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }

/* ---------- card ---------- */
.card{
  position: relative; /* containing block for the .card-link::after click overlay */
  background: var(--bg-panel);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.card:hover{
  border-color: var(--text-dim);
  transform: translateY(-3px);
  box-shadow: 0 16px 32px -16px rgba(0,0,0,0.55);
}

.card-visual{
  position: relative;
  z-index: 2; /* keep stamp/match/stripe above the .card-link::after overlay */
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background:
    repeating-linear-gradient(135deg,
      rgba(255,255,255,0.03) 0px, rgba(255,255,255,0.03) 2px,
      transparent 2px, transparent 14px),
    var(--bg-panel-raised);
  display: flex;
  align-items: center;
  justify-content: center;
}
.card-visual img{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
}
.card-visual .glyph{
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-glyph);
  color: var(--line);
  letter-spacing: 0.02em;
}
.card-visual .stamp{
  position: absolute;
  top: 8px; left: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #fff;
  background: var(--accent-red);
  padding: 3px 6px;
  text-transform: uppercase;
  z-index: 2;
}
/* Genre-Einfaerbung: Stamp (solide Flaeche auf dem Kartenbild) und Tag (Outline,
   z.B. im Modal) teilen sich dieselben Klassennamen, aber unterschiedliche Optik. */
.stamp.setting-scifi{ background: var(--accent-blue-deep); }
.stamp.setting-military{ background: var(--accent-red); }
.stamp.setting-fantasy{ background: var(--accent-purple-deep); }
.stamp.setting-postapo{ background: var(--accent-gold); color: var(--on-gold); }
.stamp.setting-horror{ background: var(--danger-deep); }
.stamp.setting-other{ background: #55575c; }
.tag.setting-scifi{ border-color: var(--accent-blue); color: var(--accent-blue); }
.tag.setting-military{ border-color: var(--accent-red-bright); color: var(--accent-red-bright); }
.tag.setting-fantasy{ border-color: var(--accent-purple); color: var(--accent-purple); }
.tag.setting-postapo{ border-color: var(--accent-gold); color: var(--accent-gold); }
.tag.setting-horror{ border-color: var(--accent-horror); color: var(--accent-horror); }
.tag.setting-other{ border-color: var(--line); color: var(--text-muted); }
.card-visual .match{
  position: absolute;
  top: 8px; right: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  padding: 3px 7px;
  letter-spacing: 0.03em;
  border: 1px solid var(--accent-red-bright);
  color: var(--accent-red-bright);
  background: rgba(26,26,26,0.8);
  z-index: 2;
}
.card-visual .match.partial{
  border-color: var(--text-dim);
  color: var(--text-muted);
}
.card-visual .match.match-good{
  border-color: var(--accent-gold);
  color: var(--accent-gold);
}
.card-visual .status-badge{
  position: absolute;
  bottom: 8px; left: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 6px;
  border: 1px solid var(--text-dim);
  color: var(--text-muted);
  background: rgba(26,26,26,0.85);
  z-index: 2;
}
.status-stripe{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 3;
  text-align: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #fff;
  padding: 5px 0;
}
.stripe-upcoming{ background: var(--banner-soon); }
.stripe-discontinued{ background: var(--banner-discontinued); }
.card.discontinued .card-visual img{ filter: grayscale(0.7) brightness(0.75); }
.card.discontinued .card-title{ color: var(--text-muted); }

.card-body{
  padding: 14px 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}
.card-title{
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  margin: 0;
  letter-spacing: 0;
  line-height: 1.2;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.5em;
}
.card-dev{
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-dim);
  margin: -6px 0 0;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.card-blurb{
  font-size: var(--fs-md);
  color: var(--text-muted);
  margin: 0;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 3em;
}
.card-rating{
  display: flex;
  align-items: baseline;
  gap: 5px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--text-primary);
  min-height: 14px;
}
.card-rating-empty{ visibility: hidden; }
.steam-icon{ color: var(--accent-green); font-size: var(--fs-2xs); }
.card-rating-desc{
  font-weight: 400;
  font-size: var(--fs-2xs);
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.card-tags{
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 4px;
}
.tag{
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--line);
  padding: 4px 8px;
}
.tag-mode-pve{ border-color: var(--accent-green); color: var(--accent-green); }
.tag-mode-pvpve{ border-color: var(--accent-gold); color: var(--accent-gold); }
.tag-mode-pvp{ border-color: var(--accent-red-bright); color: var(--accent-red-bright); }
.tag-pm-single{ border-color: var(--accent-blue); color: var(--accent-blue); }
.tag-pm-multi{ border-color: var(--accent-gold); color: var(--accent-gold); }
.tag-pm-both{ border-color: var(--text-dim); color: var(--text-dim); }
.tag-price-f2p{ border-color: var(--accent-green); color: var(--accent-green); }
.tag-price-b2p{ border-color: var(--accent-blue); color: var(--accent-blue); }
/* Status-/Metadaten-Modifier - MUSS nach `.tag` stehen, sonst gewinnt dessen
   `border:`-Kurzform und die Tags rendern grau (frueherer Bug in tool.css, wo
   dieser Block versehentlich vor `.tag` lag). Farbcodierung laut DESIGN.md:
   early-access = gold, full-release = blau, VR = Alert Ember, Demo/Playtest =
   gruen, "~ ungefaehres Datum" = grau gestrichelt. */
.tag-early-access{ border-color: var(--accent-gold); color: var(--accent-gold); }
.tag-full-release{ border-color: var(--accent-blue); color: var(--accent-blue); }
.tag-vr{ border-color: var(--accent-red-bright); color: var(--accent-red-bright); }
.tag-demo, .tag-playtest{ border-color: var(--accent-green); color: var(--accent-green); }
.tag-approx{ border-style: dashed; color: var(--text-dim); }
.card-meta-line{
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
  border-top: 1px solid var(--line-soft);
  padding-top: 8px;
  margin-top: 2px;
  cursor: pointer;
}
.card-meta-line .meta-platform{
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-meta-line:hover .meta-platform{ color: var(--text-primary); }
.card-meta-line .meta-price{
  color: var(--text-primary);
  font-weight: 700;
  white-space: nowrap;
  flex-shrink: 0;
}
.card-meta-line .meta-price.is-deal{ color: var(--accent-gold); }

/* ---------- clickable card affordances ----------
   Only the title is a real link; a.card-link::after stretches the hit area to
   the whole .card (which is position:relative). .card-visual keeps z-index:2 so
   the genre stamp / match badge stay above that overlay - card clicks there are
   caught by the delegated handler in index.php instead. */
.card-visual{ cursor: pointer; }
.card:hover .card-title{ color: var(--accent-red-bright); }
a.card-link{
  text-decoration: none;
  color: inherit;
  transition: color .15s ease;
}
a.card-link::after{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.card-title{ transition: color .15s ease; }
