From 559ca8d934d2f20fa01be63c1ef61022e8263b26 Mon Sep 17 00:00:00 2001 From: gahusb Date: Mon, 4 May 2026 04:18:32 +0900 Subject: [PATCH] fix: tighten codex hint visibility and constants (A-5 polish) - Hoist MAX_UNDISCOVERED_PER_TIER to module scope (was a local const that expressed game-design intent, not runtime state). - Filter undiscovered slots to those with at least one known ingredient so a fresh player never sees useless `? + ?` cards on high tiers. - Move card-level opacity off the wrapper so the recipe-hint span can stay full-color (especially the craftable-now blue) while sprite + name remain dimmed. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/screens/ElementsScreen.tsx | 40 +++++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/components/screens/ElementsScreen.tsx b/src/components/screens/ElementsScreen.tsx index 10856a6..9553c90 100644 --- a/src/components/screens/ElementsScreen.tsx +++ b/src/components/screens/ElementsScreen.tsx @@ -769,12 +769,19 @@ const undiscoveredCardStyle = css` ${elementCardBaseStyle} background: ${adaptive.greyBackground}; border: 1.5px dashed ${adaptive.grey300}; - opacity: 0.4; cursor: default; justify-content: center; min-height: 80px; `; +const undiscoveredDimStyle = css` + opacity: 0.45; + display: flex; + flex-direction: column; + align-items: center; + gap: 5px; +`; + const spriteWrapStyle = css` width: 52px; height: 52px; @@ -1106,9 +1113,11 @@ const genealogyTextStyle = css` `; // ──────────────────────────────────────────────────────────── -// Tier labels +// Tier labels & game design constants // ──────────────────────────────────────────────────────────── +const MAX_UNDISCOVERED_PER_TIER = 6; + const TIER_LABELS: Record = { 1: 'Tier 1 — 기본 원소', 2: 'Tier 2 — 2차 원소', @@ -1128,6 +1137,7 @@ const elementMap = Object.fromEntries(elementsData.map((el) => [el.id, el])); interface RecipeHint { display: string; craftableNow: boolean; + partiallyKnown: boolean; } function getRecipeHintForElement( @@ -1148,6 +1158,7 @@ function getRecipeHintForElement( return { display: `${aSym} + ${bSym}`, craftableNow: aDiscovered && bDiscovered && hasA && hasB, + partiallyKnown: aDiscovered || bDiscovered, }; } @@ -1323,18 +1334,20 @@ const ElementCard = memo(function ElementCard({ if (state === 'undiscovered') { return (
-
-
- +
+
+
+ +
+ ???
- ??? {hint && ( {hint.display} )} @@ -1539,8 +1552,6 @@ export function ElementsScreen() { .filter((summary): summary is ActiveBoostSummary => summary !== null && summary.remainingMs > 0) .sort((a, b) => a.remainingMs - b.remainingMs); - const MAX_UNDISCOVERED_PER_TIER = 6; - const tierGroups = [1, 2, 3, 4, 5].map((tier) => { const tierElements = elementsData.filter((el) => el.tier === tier); const owned = tierElements.filter((el) => discoveredElementIds.includes(el.id)); @@ -1548,6 +1559,7 @@ export function ElementsScreen() { const undiscoveredWithHints = undiscovered .map((el) => ({ el, hint: getRecipeHintForElement(el.id, discoveredElementIds, elements) })) + .filter(({ hint }) => hint?.partiallyKnown ?? false) .sort((a, b) => { const aCraftable = a.hint?.craftableNow ? 1 : 0; const bCraftable = b.hint?.craftableNow ? 1 : 0;