diff --git a/src/main/webapp/WEB-INF/views/game-detail.jsp b/src/main/webapp/WEB-INF/views/game-detail.jsp index 90220ed..1d2cc63 100644 --- a/src/main/webapp/WEB-INF/views/game-detail.jsp +++ b/src/main/webapp/WEB-INF/views/game-detail.jsp @@ -998,6 +998,7 @@ margin: 0 0 1.25rem; display: flex; align-items: center; + justify-content: center; gap: 1.25rem; padding: 1rem 1.25rem; background: @@ -1081,75 +1082,38 @@ font-size: 0.75rem; color: var(--text-muted); } - .game-reviews__axis-legend { - margin: 0; - flex: 1; - min-width: 11.5rem; - display: grid; - gap: 0.4rem 0; - font-size: 0.75rem; - color: var(--text-muted); + .game-reviews__title-meter { + display: inline-flex; + align-items: flex-end; + gap: 0.15rem; + height: 0.95rem; } - .game-reviews__axis-legend-row { - display: grid; - grid-template-columns: 3.4rem 1fr 1.15rem; - align-items: center; - gap: 0.55rem; - } - .game-reviews__axis-legend dt { - font-weight: 600; - color: var(--text); - } - .game-reviews__axis-legend dd { - margin: 0; - font-variant-numeric: tabular-nums; - font-weight: 700; - text-align: right; - color: var(--accent); - } - .game-reviews__axis-meter { + .game-reviews__title-meter .stick { position: relative; - height: 0.4rem; - border-radius: 999px; + width: 0.2rem; + height: 100%; + border-radius: 2px; background: var(--border); overflow: hidden; } - .game-reviews__axis-meter::before { - content: ''; + .game-reviews__title-meter .stick span { position: absolute; - inset: 0; - z-index: 2; - pointer-events: none; - background-image: repeating-linear-gradient(90deg, - transparent 0, transparent calc(20% - 1px), - rgba(255, 255, 255, 0.45) calc(20% - 1px), rgba(255, 255, 255, 0.45) 20%); - mix-blend-mode: overlay; + bottom: 0; + left: 0; + right: 0; + border-radius: 2px; + background: linear-gradient(180deg, #f0c978, var(--accent)); + animation: game-title-meter-grow 0.5s cubic-bezier(0.22, 1, 0.36, 1) both; + transform-origin: bottom; } - .game-reviews__axis-meter span { - position: relative; - z-index: 1; - display: block; - height: 100%; - border-radius: 999px; - background: linear-gradient(90deg, #f0c978, var(--accent)); - animation: game-meter-grow 0.7s cubic-bezier(0.22, 1, 0.36, 1) both; - transform-origin: left; - } - @keyframes game-meter-grow { - from { transform: scaleX(0); } - to { transform: scaleX(1); } + @keyframes game-title-meter-grow { + from { transform: scaleY(0); } + to { transform: scaleY(1); } } @media (prefers-reduced-motion: reduce) { .game-reviews__radar .game-axis-poly, .game-reviews__radar .game-axis-dot, - .game-reviews__axis-meter span { animation: none; } - } - .game-reviews__card-radar { - margin-top: 0.6rem; - display: inline-flex; - } - .game-reviews__card-radar svg { - display: block; + .game-reviews__title-meter .stick span { animation: none; } } /* ── sort 토글 / 더보기 ──────────────────────────────── */ @@ -1756,28 +1720,29 @@ return { svg: svg, nums: nums, hasData: hasData }; } - // 시각 보조
(축명/미터바/점수) — 폴리곤만으로 종료 금지(§6.6) - function buildRadarLegend(nums, hasData) { - var dl = document.createElement('dl'); - dl.className = 'game-reviews__axis-legend'; - AXIS_KEYS.forEach(function (k, i) { - var row = document.createElement('div'); - row.className = 'game-reviews__axis-legend-row'; - var dt = document.createElement('dt'); - dt.textContent = AXIS_LABELS_KO[k]; - var meter = document.createElement('div'); - meter.className = 'game-reviews__axis-meter'; - var bar = document.createElement('span'); - bar.style.width = (hasData ? (nums[i] / 5 * 100) : 0) + '%'; - meter.appendChild(bar); - var dd = document.createElement('dd'); - dd.textContent = hasData ? String(nums[i]) : '–'; - row.appendChild(dt); - row.appendChild(meter); - row.appendChild(dd); - dl.appendChild(row); + // 리뷰 카드 제목행 삽입용 6축 미니 미터바 — axes 없으면 null(§6.6: 그래프는 요약에만, 카드는 이 미터바로 대체) + function buildTitleMeter(axes) { + var nums = AXIS_KEYS.map(function (k) { + var v = axes ? Number(axes[k]) : 0; + return (isFinite(v) && v > 0) ? v : 0; }); - return dl; + var hasData = nums.some(function (v) { return v > 0; }); + if (!hasData) return null; + var wrap = document.createElement('div'); + wrap.className = 'game-reviews__title-meter'; + wrap.setAttribute('role', 'img'); + wrap.setAttribute('aria-label', '6축 평가: ' + AXIS_KEYS.map(function (k, i) { + return AXIS_LABELS_KO[k] + ' ' + nums[i]; + }).join(', ')); + nums.forEach(function (v) { + var stick = document.createElement('span'); + stick.className = 'stick'; + var fill = document.createElement('span'); + fill.style.height = (v / 5 * 100) + '%'; + stick.appendChild(fill); + wrap.appendChild(stick); + }); + return wrap; } // ===== 별점 radiogroup 완전 패턴 (C6) ===== @@ -2234,6 +2199,9 @@ mb.textContent = '내 리뷰'; head.appendChild(mb); } + // 6축 미니 미터바 — 제목행 노출(§6.6: 요약 그래프와 별개로 카드 단위 시각화) + var titleMeter = buildTitleMeter(r.axes); + if (titleMeter) head.appendChild(titleMeter); var t = document.createElement('time'); t.className = 'game-reviews__time'; t.dateTime = (r.updatedAt || r.createdAt) || ''; @@ -2255,25 +2223,6 @@ li.appendChild(p); } - // 카드 컴팩트 육각형 (6축). axes null/누락 시 "데이터 없음" - var cardScores = AXIS_KEYS.map(function (k) { return r.axes ? Number(r.axes[k]) || 0 : 0; }); - var cardRadar = buildHexRadar(cardScores, 60, 60, 44); - var radarWrap = document.createElement('div'); - radarWrap.className = 'game-reviews__radar game-reviews__card-radar'; - if (cardRadar.hasData) { - radarWrap.appendChild(cardRadar.svg); - // §6.6: 폴리곤만으로 종료 금지 — 시각/스크린리더 보조 표 동반(시각적으로 숨김) - var legend = buildRadarLegend(cardRadar.nums, true); - legend.className += ' sr-only'; - radarWrap.appendChild(legend); - } else { - var none = document.createElement('span'); - none.className = 'game-reviews__radar-empty'; - none.textContent = '6축 평가 데이터 없음'; - radarWrap.appendChild(none); - } - li.appendChild(radarWrap); - if (canActOn(r.userId)) { var foot = document.createElement('div'); foot.className = 'game-reviews__footer'; @@ -2322,7 +2271,6 @@ rSummaryPanel.hidden = false; if (radar.hasData) { rSummaryRadar.appendChild(radar.svg); - rSummaryRadar.appendChild(buildRadarLegend(radar.nums, true)); } else { var none = document.createElement('span'); none.className = 'game-reviews__radar-empty';