/* GAME HUB — shared styles. Dark theme, responsive grid. No external requests. */

/* Display fonts for thumbnail title lockups — bundled LOCALLY (dist/fonts/),
   vendored from @fontsource (OFL). Zero external font/CDN requests. */
@font-face {
  font-family: "Lilita One";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/lilita-one-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Luckiest Guy";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/luckiest-guy-latin-400-normal.woff2") format("woff2");
}

:root {
  --bg: #10141f;
  --surface: #1c2333;
  --surface-2: #232c42;
  --primary: #4f8cff;
  --accent: #ffc94d;
  --text: #f2f5fb;
  --muted: #9aa7c2;
  --radius: 14px;
  --shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    "Malgun Gothic", "Apple SD Gothic Neo", sans-serif;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

a {
  color: inherit;
  text-decoration: none;
}

.wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 16px;
}

/* ---------- Top bar ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: rgba(16, 20, 31, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.topbar-inner {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 60px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 800;
  font-size: 20px;
  letter-spacing: 0.3px;
}
.brand .logo {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--primary), var(--accent));
  color: #0b0f18;
  font-size: 18px;
  font-weight: 900;
}
.brand .accent {
  color: var(--accent);
}
.topbar .spacer {
  flex: 1;
}
.topbar .count {
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid rgba(255, 255, 255, 0.07);
  font-weight: 600;
  font-size: 14px;
  transition: background 0.15s;
}
.back-link:hover {
  background: var(--surface-2);
}

/* ---------- Hero ---------- */
.hero {
  padding: 40px 0 24px;
  text-align: center;
}
.hero h1 {
  margin: 0 0 10px;
  font-size: clamp(28px, 5vw, 44px);
  font-weight: 900;
  letter-spacing: -0.5px;
}
.hero h1 .accent {
  color: var(--accent);
}
.hero p {
  margin: 0;
  color: var(--muted);
  font-size: clamp(14px, 2.5vw, 17px);
}

/* ---------- Filter chips ---------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  justify-content: center;
  padding: 8px 0 28px;
}
.chip {
  padding: 8px 16px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--muted);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
  user-select: none;
}
.chip:hover {
  color: var(--text);
  border-color: rgba(255, 255, 255, 0.2);
}
.chip.active {
  background: var(--primary);
  border-color: var(--primary);
  color: #0b0f18;
}

/* ---------- Game grid ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  padding-bottom: 56px;
}
@media (min-width: 620px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (min-width: 900px) {
  .grid {
    grid-template-columns: repeat(4, 1fr);
  }
}
@media (min-width: 1140px) {
  .grid {
    grid-template-columns: repeat(5, 1fr);
  }
}

.card {
  display: block;
  background: var(--surface);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.16s ease, box-shadow 0.16s ease,
    border-color 0.16s ease;
}
.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
  border-color: rgba(79, 140, 255, 0.5);
}
.card .thumb {
  position: relative;
  aspect-ratio: 3 / 4;
  background: var(--surface-2);
  overflow: hidden;
  /* cqw units let the title lockup scale with the card, any grid width */
  container-type: inline-size;
}
.card .thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* CSS gradient fallback thumbnail (no cover art — big lockup carries the card) */
.card .thumb.fallback {
  padding: 14px;
}
.card .thumb .badge {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(11, 15, 24, 0.72);
  backdrop-filter: blur(4px);
  font-size: 11px;
  font-weight: 700;
  color: var(--accent);
}
/* ============ Title lockup — mobile-game-logo treatment ============
   Layers (bottom→top):
   1. scrim        — soft dark gradient anchoring the lower third
   2. element text — thick dark stroke + hard/soft shadows = outline plate
   3. ::after      — identical text, gradient fill (per-category scheme)
                     with a near-white top highlight, cycled per line (1lh)
   Sizing: --ts is computed per title at build time (cqw units) so the
   longest line always fills ~82% of the card width. */
.card .thumb-scrim {
  position: absolute;
  inset: auto 0 0 0;
  height: 52%;
  background: linear-gradient(
    180deg,
    transparent,
    rgba(5, 8, 16, 0.38) 55%,
    rgba(5, 8, 16, 0.82)
  );
  pointer-events: none;
}
.card .thumb-title {
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: 5%;
  z-index: 2;
  font-family: "Lilita One", "Arial Black", system-ui, sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  text-align: center;
  font-size: var(--ts, 15cqw);
  line-height: 0.94;
  letter-spacing: 0.015em;
  white-space: pre-line;
  transform: rotate(-2.5deg);
  transition: transform 0.2s ease;
  /* The element itself is the OUTLINE PLATE: fat dark stroke + shadows.
     The gradient fill sits on ::after ABOVE it (a gradient via
     background-clip:text is a *background* — anything pseudo-layered
     with z-index:-1 would still paint over it, so fill must be on top). */
  color: var(--ink);
  -webkit-text-stroke: 0.14em var(--ink);
  paint-order: stroke fill;
  text-shadow:
    0 0.07em 0 rgba(8, 5, 2, 0.5),
    0 0.14em 0.12em rgba(0, 0, 0, 0.42),
    0 0.3em 0.6em rgba(0, 0, 0, 0.55);
  pointer-events: none;
}
/* gradient fill layer: identical text on top, per-line gradient cycle
   (stops calibrated to Lilita One cap area inside each 1lh line box) */
.card .thumb-title::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  text-align: inherit;
  color: transparent;
  -webkit-text-stroke: 0;
  text-shadow: none;
  background-image: linear-gradient(
    180deg,
    #fffdf4 16%,
    var(--g1) 40%,
    var(--g2) 66%,
    var(--g3) 92%
  );
  background-size: 100% 1lh;
  background-repeat: repeat;
  -webkit-background-clip: text;
  background-clip: text;
}
.card:hover .thumb-title {
  transform: rotate(-2.5deg) scale(1.045);
}
/* per-category gradient schemes (all keep a light top for pop on any art) */
.tt-puzzle {
  /* classic premium gold */
  --g1: #ffe45c;
  --g2: #ffb028;
  --g3: #ff8a1e;
  --ink: #3a1a05;
}
.tt-arcade {
  /* hotter amber→red for action energy */
  --g1: #ffd94d;
  --g2: #ff8f1f;
  --g3: #f5471f;
  --ink: #40120a;
}
.tt-idle {
  /* fresh healing green */
  --g1: #d8f791;
  --g2: #7bdc46;
  --g3: #2fa344;
  --ink: #123a10;
}
.tt-3d {
  /* neon violet */
  --g1: #ecccff;
  --g2: #bb6dff;
  --g3: #8b32e8;
  --ink: #2a0a4e;
}
.card .thumb img {
  transition: transform 0.25s ease;
}
.card:hover .thumb img {
  transform: scale(1.06);
}
.card .meta {
  padding: 8px 12px 10px;
}
.card .meta .genre {
  font-size: 12px;
  color: var(--muted);
}

.empty {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--muted);
  padding: 48px 0;
}

/* ---------- Footer ---------- */
.foot {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding: 26px 0 40px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}

/* ---------- Play page ---------- */
.play-main {
  padding: 18px 0 40px;
}
.stage {
  position: relative;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  aspect-ratio: 3 / 4;
  background: #000;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
@media (min-width: 760px) {
  .stage {
    max-width: 900px;
    aspect-ratio: 16 / 10;
  }
}
.stage iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.stage-tools {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 14px auto 0;
}
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: var(--surface);
  color: var(--text);
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.15s;
}
.btn:hover {
  background: var(--surface-2);
}
.btn.primary {
  background: var(--primary);
  border-color: var(--primary);
  color: #0b0f18;
}
.btn.primary:hover {
  filter: brightness(1.07);
}

.play-title {
  text-align: center;
  margin: 22px 0 4px;
}
.play-title h1 {
  margin: 0;
  font-size: clamp(22px, 4vw, 32px);
  font-weight: 900;
}
.play-title .sub {
  color: var(--muted);
  font-size: 14px;
  margin-top: 4px;
}

/* Ad slot placeholders (kept commented in HTML; this styles them if enabled) */
.ad-slot {
  max-width: 900px;
  margin: 20px auto;
  min-height: 90px;
  display: grid;
  place-items: center;
  border: 1px dashed rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  color: var(--muted);
  font-size: 12px;
}

/* ---------- 개발 중 구역 (MJ 2026-10-16 — 메인 그리드 아래) ---------- */
.devzone {
  margin-top: 8px;
  padding-top: 24px;
  border-top: 1px dashed rgba(255, 255, 255, 0.14);
}
.devzone h2 {
  font-size: 18px;
  font-weight: 800;
  margin: 0 0 16px;
}
.devzone .devnote {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  margin-left: 8px;
}
.devzone .card {
  opacity: 0.82;
}

/* ---------- Recommendations ---------- */
.recs {
  margin-top: 44px;
}
.recs h2 {
  font-size: 18px;
  font-weight: 800;
  margin: 0 0 16px;
  text-align: center;
}
.recs .grid {
  padding-bottom: 0;
}


/* ── 모바일 스크롤·가로모드 (MJ 2026-08-14) ────────────────────────────────
   두 불만이 같은 뿌리다:
   ① *"게임 화면에서는 스크롤이 안 돼서 좌·우 여백으로 힘겹게 가야 한다"*
   ② *"전체화면을 하거나 가로로 전환하면 가로모드로 될 줄 알았는데 세로 유지"*

   ①의 원인: 게임 캔버스는 조작을 위해 `touch-action:none`이라 그 위 스와이프가
   페이지를 못 움직인다. 26px 레일을 남겼지만 엄지로 잡기엔 너무 좁았다.
   해법을 "좁은 레일"에서 **"스크롤이 필요 없는 화면"**으로 바꾼다 — 스테이지를
   뷰포트 안에 들어오는 높이로 캡하면 조작 안내와 버튼줄까지 한 화면에 들어와
   스크롤할 이유 자체가 없다. 남는 스크롤은 아래 추천 목록뿐이고, 그 구간은
   캔버스 밖이라 정상 동작한다.

   ②의 원인: `aspect-ratio: 3/4`가 전체화면에서도 살아 있어 화면이 가로여도
   게임이 세로 상자에 갇혔다. `:fullscreen`에서 종횡비를 풀고 화면을 꽉 채운다.
   ------------------------------------------------------------------------ */
@media (pointer: coarse) and (max-width: 759px) {
  .stage {
    /* 위(헤더·제목) + 아래(조작 안내·버튼줄)를 남긴 높이. 스크롤 없이 전부 보인다. */
    max-height: 62dvh;
    max-width: min(480px, calc(62dvh * 3 / 4));
  }
  /* 인라인 스테이지가 작아진 만큼 "전체화면으로 플레이"가 주된 경로가 된다. */
  .stage-tools .btn.primary { font-size: 15px; padding: 12px 18px; }
}

/* 전체화면 = 화면 전체. 종횡비 상자를 풀어야 가로가 진짜 가로가 된다. */
.stage:fullscreen,
.stage:-webkit-full-screen {
  max-width: none;
  max-height: none;
  width: 100vw;
  height: 100dvh;
  aspect-ratio: auto;
  border-radius: 0;
  border: 0;
}
.stage:fullscreen iframe,
.stage:-webkit-full-screen iframe { width: 100%; height: 100%; }

/* 가로로 든 폰: 인라인이어도 세로 상자를 강요하지 않는다. */
@media (pointer: coarse) and (orientation: landscape) {
  .stage { aspect-ratio: 16 / 9; max-width: min(96vw, calc(78dvh * 16 / 9)); max-height: 78dvh; }
}
