From 9489365fa20b9a61f47793345ba8e5b11029b5ab Mon Sep 17 00:00:00 2001 From: art Date: Tue, 30 Jun 2026 18:24:56 +0900 Subject: [PATCH] =?UTF-8?q?fix(redesign):=20=EC=B9=B4=EB=93=9C=204:3=20?= =?UTF-8?q?=EB=B9=84=EC=9C=A8=C2=B7=EA=B2=80=EC=83=89=EB=B0=94=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=C2=B7=EB=8B=A4=ED=81=AC=20=EA=B3=A0=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EA=B0=80=EC=8B=9C=EC=84=B1=20=EC=99=B8=20?= =?UTF-8?q?13=EA=B1=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 직전 리디자인에서 미해결된 2건(이미지#2 카드 비율, 이미지#3 필터 초기화 가시성)을 다축 UI/UX 평가로 13건 결함으로 확장해 일괄 수정. 비율/레이아웃: - .card__media aspect-ratio 4/5→4/3 + .card__img object-position:center (가로형 웹게임 스크린샷 cover 크롭 ~55%→~25% 완화) - .search-section 풀폭화 + .search-stack 컬럼 wrapper 신설로 검색행과 상세검색 패널 우측 끝선 정렬(검색바 "혼자 짧음" 해소) - .card-grid 고정 N열 → auto-fill(minmax 11rem)로 소량 카드 좌측쏠림 완화 - recruit .recruit-hero__titles max-width·검색 입력 max-width 48rem로 폭 균형 가시성/대비: - .btn-ghost color: var(--color-on-accent)→var(--color-text) (다크 #3A2E15 on #222018 ≈1.1:1 → ≈13:1, WCAG AA 충족) - 다크 --color-border 0.08→0.20(비텍스트 3:1), .sort-label 대비·위계 보강 - .btn:disabled 하드코딩색 → 토큰화 일관성/위계: - recruit eyebrow mono/uppercase 통일, 빈상태 시 히어로 CTA 보조강등 (화면당 골드 CTA 1개), .empty-state 패딩 clamp화 런타임 스모크: bibimbap-app 재기동 후 / + /recruit 200, 라이트/다크 양 화면 육안 검증 PASS. errer.jsp(JSTL) 무관·현재 200. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_0162BaZnrbiYgWc9JJMZ9Czb --- .../implementation/ownership.md | 27 +++++++ .atp/work-session/20260630-175023/report.md | 79 +++++++++++++++++++ src/main/webapp/WEB-INF/views/index.jsp | 66 ++++++++-------- .../webapp/WEB-INF/views/recruit-list.jsp | 20 ++++- src/main/webapp/css/bibimbap.css | 14 ++-- 5 files changed, 163 insertions(+), 43 deletions(-) create mode 100644 .atp/work-session/20260630-175023/implementation/ownership.md create mode 100644 .atp/work-session/20260630-175023/report.md diff --git a/.atp/work-session/20260630-175023/implementation/ownership.md b/.atp/work-session/20260630-175023/implementation/ownership.md new file mode 100644 index 0000000..c02e4fa --- /dev/null +++ b/.atp/work-session/20260630-175023/implementation/ownership.md @@ -0,0 +1,27 @@ +--- +phase: implementation +agent: implementation-advisor +agent_version: 1 +generated_at: 2026-06-30T17:50:23+09:00 +--- + +# 파일 소유권 맵 + +| 파일 | 담당 | 변경 유형 | 관련 fix | 의존 | +|---|---|---|---|---| +| src/main/webapp/WEB-INF/views/index.jsp | advisor 직접 | modify | #1 #3 #4 #13 | - | +| src/main/webapp/css/bibimbap.css | advisor 직접 | modify | #2 #6 #7 #11 #12 | - | +| src/main/webapp/WEB-INF/views/recruit-list.jsp | advisor 직접 | modify | #5 #8 #9 #10 | - | +| src/main/webapp/WEB-INF/views/fragments/recruit-empty.jspf | (변경 없음) | none | #9 (이미 충족) | - | + +## planned_workers vs actual +- planned_workers(code-writer): 3 (파일당 1) +- actual_workers: 0 (advisor 직접) +- 전환 근거: 편집 파일 3개 < 8 임계, 총 변경 추정 < 50줄, 전부 소규모 CSS/속성 조정으로 + 병렬화 이득 없음 + JSP UTF-8 보존 사고 이력으로 advisor 직접 정밀 편집이 더 안전. +- recruit-empty.jspf 는 이미 .btn-primary(골드) + .btn-ghost(보조) 구조라 #9 충족 → 무편집(인코딩 보존). + +## 충돌 방지 불변식 +- 각 파일은 단일 편집 주체(advisor)만 접근 → 충돌 없음. +- 토큰 계열 분리: index.jsp/recruit-list.jsp 로컬 토큰(--accent/--text/--border 등), + bibimbap.css 는 --color-* 만. #2 .btn-ghost 는 bibimbap.css 소속 → var(--color-text) 정확. diff --git a/.atp/work-session/20260630-175023/report.md b/.atp/work-session/20260630-175023/report.md new file mode 100644 index 0000000..0efc5a6 --- /dev/null +++ b/.atp/work-session/20260630-175023/report.md @@ -0,0 +1,79 @@ +--- +schema_version: 2 +sid: 20260630-175023 +started_at: 2026-06-30T17:50:23 +user_request: | + /frontend-design 두 시각 버그 수정 (이전 작업서 미해결): + - Image #2 (메인 게임 허브): 게임 카드 썸네일 "비율" 문제 + - Image #3 (팀원 모집 빈 상태): "가시성" 떨어지는 케이스 +Invocations: [] +Summary: '' +Decisions: [] +user_signals: + positive: [] + negative: + - quote: "이전 작업에서 안고쳐졌어" + structural: false + note: "직전 리디자인 세션이 두 케이스 미해결. 발원 단계 재검 필요(§2.6)." +regression: '' +graph_refresh: '' +open_items: [] +verified_by_me: [] +needs_user_verification: [] +--- + +# Advisor Invocation Decision Log +# 각 advisor 호출/스킵 판단 즉시 1줄 append + +- advisor: requirements/design/implementation + decision: skip + rationale: '2건 모두 국소 CSS 수정(토큰 오용·종횡비 1값). 이슈2 원인 확정, 이슈1 결정축 단일. orchestrator 직접+plan게이트(§1 마이크로 예외, §5.0).' + checked_at: 2026-06-30T17:52 +- advisor: verification + decision: call(self) + rationale: 'CSS 변경 → 런타임 스모크 의무(직전 교훈). 다크모드 대비·카드 비율 육안 확인.' + checked_at: 2026-06-30T17:52 + +- advisor: implementation + decision: call + rationale: '결정 후 범위=전체13건+카드4:3, 4개 파일(index.jsp/bibimbap.css/recruit-list.jsp/recruit-empty.jspf). 다중파일+일부 마크업변경(#4#9#10) → 파일소유권 분할 필요. 종합 산출 concrete_change 확정적.' + checked_at: 2026-06-30T18:00 + +--- + +## Summary +사용자 지적 2건(이미지#2 비율 / 이미지#3 가시성, 직전 세션 미해결)을 다축 멀티에이전트 평가로 13건 결함으로 확장 → 카드 종횡비 4:3 + 전체 13건 적용. 런타임 스모크 라이트/다크 양 화면 PASS. + +## Invocations +- cavecrew-investigator: 두 화면 JSP/CSS 위치 file:line 확정 +- Workflow(ui-multiaxis-eval, 6 agents): 관찰1 → 다축평가4(레이아웃비율·카드종횡비·대비가시성·타이포간격) → 종합1 → 13 fixes + 1 open_decision +- implementation-advisor: 13건+4:3 구현(3파일, recruit-empty.jspf 무편집) +- (self) verification: 정적 L1 + 런타임 L2 스모크 + +## Decisions +- 카드 종횡비 **4:3** (사용자 선택; 16:9/4:5유지 대안 제시) +- 적용 범위 **전체 13건** (사용자 선택) +- #4 픽셀 margin 대신 `.search-stack` 컬럼 wrapper (advisor 조정 — 버튼 텍스트 가변 대응 결정적) +- #8 공용 클래스 대신 로컬 시각스펙 일치 (index/bibimbap 토큰계열 분리 제약 + font-mono 토큰 부재) + +## verified_by_me +- L1 정적: index.jsp div 18/18·recruit 6/6 균형, scriptlet 균형, U+FFFD 0, stray taglib 0(§293 적신호 없음) +- L2 런타임 스모크(PASS): bibimbap-app(mvn spring-boot:run) 재기동 → GET / + /recruit = 200 → 브라우저 육안 라이트+다크 양 화면. + - 이미지#2(비율): 검색바 풀폭 정렬(#1), 카드 4:3(#13 object-position) — 해소 확인 + - 이미지#3(가시성): 필터 초기화 흰글자+보더 명확(#2, zoom 확정) — 해소 확인 + - 부수: #6 정렬칩 보더·#7 정렬라벨·#8 eyebrow 통일·#9 빈상태 CTA 강등·#10 히어로폭·#11 패널패딩·푸터 비잘림 육안 확인 + +## needs_user_verification +- 로그인 상태 1회 스모크: 본 검증은 로그아웃 상태만. (a) 메인 '신규 게임 개시' 버튼 노출 시 #4 search-stack 우측끝선 정렬, (b) 모집글 ≥1건 시 #9 히어로 골드 CTA 유지. +- 실게임 가로 썸네일 업로드 시 4:3 cover 크롭 인상 최종 확인(더미는 폴백 로고만 노출). + +## regression +- 발원 단계: 직전 리디자인 세션(cf1e7ce 등)이 두 케이스 미해결. 본 세션이 다축 재검으로 표면화+수정. 토큰 오용(.btn-ghost on-accent) = 골드버튼 토큰을 고스트에 재사용한 설계 결함 → --color-text 로 정정. + +## graph_refresh +partial-stale — 내 변경(src view/css)은 include/import/route 위상 0델타 = src fresh. partial 사유는 직전 세션들의 docs/changes 노드 2건 신규(pre-existing) + 직전 graphify 미반영(index.md "재생성 요청 중"이나 source_commit 360078a 고정). 내 세션 구조 무영향 → src 재생성 불요. docs 노드 backlog 는 open_items 로 이월(다음 구조변경 시 일괄 /graphify full). + +## open_items +- [pre-existing] docs/graph 재생성 backlog: 직전 세션 docs/changes 노드 미반영 + source_commit stale(360078a→cf1e7ce). 다음 구조변경 작업 시 /graphify full + index.md frontmatter/Scopes 표 갱신. (본 세션 산출 아님) +- [untracked, 타세션] .atp/work-session/{20260630-103443,105459,143405,160000,170024}/ + graphify-out/ : 직전 세션들 미커밋 잔여. 본 작업 단위 외 — 미관여. +- [stale-log] 07:35Z JasperException(/error JSTL) = 내 재기동(09:19Z) 이전 옛 라인, errer.jsp 현재 clean, /error 현재 200. 회귀 아님. diff --git a/src/main/webapp/WEB-INF/views/index.jsp b/src/main/webapp/WEB-INF/views/index.jsp index a7deb98..4f6ef4c 100644 --- a/src/main/webapp/WEB-INF/views/index.jsp +++ b/src/main/webapp/WEB-INF/views/index.jsp @@ -171,6 +171,7 @@ } .home-action-button { flex-shrink: 0; + align-self: flex-start; min-height: 3rem; padding: 0 0.875rem 0 0.625rem; border: 1px solid rgba(232, 165, 75, 0.32); @@ -222,8 +223,15 @@ /* 검색 */ .search-section { - width: min(100%, 48rem); - margin: 0 auto 1.25rem; + width: 100%; + margin: 0 0 1.25rem; + } + /* 검색 폼 + 상세검색 패널을 한 컬럼으로 묶어 우측 끝선 정렬(#4) */ + .search-stack { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; } .search-form { flex: 1; @@ -506,10 +514,10 @@ transform: scale(0.98); } - /* 카드 그리드: 모바일 2열 → 태블릿 3열 → 데스크톱 4~5열 */ + /* 카드 그리드: 콘텐츠 적응형(소량 카드 좌측 쏠림/우측 거대공백 완화) */ .card-grid { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 0.625rem; justify-content: center; } @@ -520,20 +528,9 @@ } @media (min-width: 640px) { .card-grid { - grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; } } - @media (min-width: 900px) { - .card-grid { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - } - @media (min-width: 1200px) { - .card-grid { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - } a.card { display: flex; @@ -560,11 +557,11 @@ outline: 2px solid var(--accent); outline-offset: 2px; } - /* 가로:세로 = 4:5 (포스터/썸네일에 흔한 비율, 3:5보다 덜 길쭉해 모바일 그리드에 균형 있음) */ + /* 가로:세로 = 4:3 (가로형 썸네일 — 카드 높이 축소로 그리드 균형·스캔성 개선) */ .card__media { position: relative; width: 100%; - aspect-ratio: 4 / 5; + aspect-ratio: 4 / 3; background: var(--card-media-2); } .card__index { @@ -591,6 +588,7 @@ height: 100%; display: block; object-fit: cover; + object-position: center; } /* 이미지 없음: 로고만 중앙 */ .card__media-empty { @@ -605,7 +603,7 @@ .card__logo-fallback { width: min(52%, 7.5rem); height: auto; - max-height: 42%; + max-height: 50%; object-fit: contain; opacity: 0.88; filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.12)); @@ -768,7 +766,11 @@

직접 만든 인디 게임을 올리고, 함께 즐기세요

유니티 개발자들이 만든 웹게임을 플레이하고 리뷰를 남길 수 있어요.

+<% + boolean advOpen = !searchKeyword.isBlank() || !searchCreator.isBlank() || !"latest".equals(searchSort) || !selectedTagSlugs.isEmpty(); +%>
+
- <% if (loggedIn) { %> - - - 신규 게임 개시 - - <% } %> -
-<% - boolean advOpen = !searchKeyword.isBlank() || !searchCreator.isBlank() || !"latest".equals(searchSort) || !selectedTagSlugs.isEmpty(); -%>
+ + <% if (loggedIn) { %> + + + 신규 게임 개시 + + <% } %> +
<%-- 정렬 칩 --%> diff --git a/src/main/webapp/WEB-INF/views/recruit-list.jsp b/src/main/webapp/WEB-INF/views/recruit-list.jsp index 5ec0dc3..fddfee5 100644 --- a/src/main/webapp/WEB-INF/views/recruit-list.jsp +++ b/src/main/webapp/WEB-INF/views/recruit-list.jsp @@ -60,11 +60,17 @@ gap: 1rem; margin-bottom: 1rem; } + .recruit-hero__titles { + max-width: 40rem; + } .recruit-hero__eyebrow { margin: 0 0 0.35rem; color: var(--accent); + font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; font-size: 0.75rem; - font-weight: 900; + font-weight: 600; + letter-spacing: 0.16em; + text-transform: uppercase; } .recruit-hero h1 { margin: 0; @@ -92,6 +98,13 @@ text-decoration: none; white-space: nowrap; } + /* 빈 상태(목록 0건)일 때 히어로 CTA 를 보조 스타일로 강등 — 화면당 골드 채움 CTA 1개(#9) */ + .recruit-write--ghost { + background: transparent; + border: 1px solid var(--border); + color: var(--text); + font-weight: 700; + } .recruit-toolbar { margin-bottom: 1.25rem; display: grid; @@ -100,6 +113,7 @@ .recruit-search { display: flex; gap: 0.5rem; + max-width: 48rem; } .recruit-search input { width: 100%; @@ -248,12 +262,12 @@
-
+

INDIE GAME TEAM

함께 만들 팀원을 찾는 공간

기획, 아트, 프로그래머가 작은 프로젝트부터 출시 목표 팀까지 가볍게 만나는 게시판입니다.

- 모집글 작성 + " href="<%= ctx %>/recruit/new">모집글 작성
diff --git a/src/main/webapp/css/bibimbap.css b/src/main/webapp/css/bibimbap.css index 8aa343e..e2f4895 100644 --- a/src/main/webapp/css/bibimbap.css +++ b/src/main/webapp/css/bibimbap.css @@ -58,7 +58,7 @@ html[data-theme="dark"] { --color-text-faint: rgba(245, 240, 232, 0.40); /* muted 보다 더 희미 */ --color-on-accent: #3A2E15; /* 골든 버튼 위 글자 — 라이트와 동일 */ - --color-border: rgba(255, 255, 255, 0.08); /* header --header-border 소폭 강조 */ + --color-border: rgba(255, 255, 255, 0.20); /* 비텍스트 대비 3:1 확보(WCAG 1.4.11) */ --color-border-soft: rgba(255, 255, 255, 0.06); /* header --header-border */ --color-accent: #e8a54b; /* 브랜드 골드 — 라이트와 동일 */ @@ -123,7 +123,7 @@ a:focus-visible { .btn-ghost { background: var(--color-card); - color: var(--color-on-accent); + color: var(--color-text); border-color: var(--color-border); } .btn-ghost:hover { background: var(--color-field-bg); } @@ -135,9 +135,9 @@ a:focus-visible { .btn:disabled, .btn[disabled], button:disabled { - background: #EFE7D7; - color: #B3A88E; - border-color: #EFE7D7; + background: var(--color-field-bg); + color: var(--color-text-faint); + border-color: var(--color-border); cursor: not-allowed; } @@ -266,7 +266,7 @@ button:disabled { background: var(--color-card); border: 1px solid var(--color-border); border-radius: var(--radius-xl); - padding: 64px 32px; + padding: clamp(40px, 6vw, 64px) 32px; text-align: center; } .empty-state svg { display: block; margin: 0 auto; } @@ -318,7 +318,7 @@ button:disabled { .search-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 20px; } .search-row .input { flex: 1; min-width: 240px; } .sort-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 16px; } -.sort-label { font-size: 13px; color: var(--color-text-faint); margin-right: 4px; } +.sort-label { font-size: 12px; font-weight: 700; letter-spacing: .02em; color: var(--color-text-muted); margin-right: 4px; } .game-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-top: 20px; } .game-card { background: var(--color-card); border: 1px solid var(--color-border); border-radius: var(--radius-lg); overflow: hidden; text-decoration: none; color: inherit; display: block; }