fix(redesign): 카드 4:3 비율·검색바 정렬·다크 고스트버튼 가시성 외 13건
직전 리디자인에서 미해결된 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) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0162BaZnrbiYgWc9JJMZ9Czb
This commit is contained in:
parent
cf1e7cea62
commit
9489365fa2
|
|
@ -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) 정확.
|
||||
|
|
@ -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. 회귀 아님.
|
||||
|
|
@ -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 @@
|
|||
<h1 class="section-title" style="font-size:1.875rem">직접 만든 인디 게임을 올리고, 함께 즐기세요</h1>
|
||||
<p class="section-desc">유니티 개발자들이 만든 웹게임을 플레이하고 리뷰를 남길 수 있어요.</p>
|
||||
<section class="search-section" aria-label="게임·제작자 검색">
|
||||
<%
|
||||
boolean advOpen = !searchKeyword.isBlank() || !searchCreator.isBlank() || !"latest".equals(searchSort) || !selectedTagSlugs.isEmpty();
|
||||
%>
|
||||
<div class="home-toolbar">
|
||||
<div class="search-stack">
|
||||
<form class="search-form" role="search" action="<%= ctx %>/" method="get">
|
||||
<div class="search-form__field">
|
||||
<label class="search-form__label" for="q">게임·제작자 검색</label>
|
||||
|
|
@ -776,21 +778,6 @@
|
|||
</div>
|
||||
<button class="search-form__submit" type="submit">검색</button>
|
||||
</form>
|
||||
<% if (loggedIn) { %>
|
||||
<a class="home-action-button" href="<%= ctx %>/game/new">
|
||||
<span class="home-action-button__icon" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 5v14"/>
|
||||
<path d="M5 12h14"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>신규 게임 개시</span>
|
||||
</a>
|
||||
<% } %>
|
||||
</div>
|
||||
<%
|
||||
boolean advOpen = !searchKeyword.isBlank() || !searchCreator.isBlank() || !"latest".equals(searchSort) || !selectedTagSlugs.isEmpty();
|
||||
%>
|
||||
<details class="advanced-search"<%= advOpen ? " open" : "" %>>
|
||||
<summary class="advanced-search__summary">상세 검색</summary>
|
||||
<form class="advanced-search-form" role="search" action="<%= ctx %>/games/search" method="get">
|
||||
|
|
@ -851,6 +838,19 @@
|
|||
</div>
|
||||
<div class="search-history__chips" id="search-history-chips" role="list"></div>
|
||||
</div>
|
||||
</div><!-- /.search-stack -->
|
||||
<% if (loggedIn) { %>
|
||||
<a class="home-action-button" href="<%= ctx %>/game/new">
|
||||
<span class="home-action-button__icon" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 5v14"/>
|
||||
<path d="M5 12h14"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>신규 게임 개시</span>
|
||||
</a>
|
||||
<% } %>
|
||||
</div><!-- /.home-toolbar -->
|
||||
</section>
|
||||
|
||||
<%-- 정렬 칩 --%>
|
||||
|
|
|
|||
|
|
@ -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 @@
|
|||
<jsp:include page="/WEB-INF/views/header.jsp"/>
|
||||
<main class="recruit-page">
|
||||
<section class="recruit-hero" aria-labelledby="recruit-title">
|
||||
<div>
|
||||
<div class="recruit-hero__titles">
|
||||
<p class="recruit-hero__eyebrow">INDIE GAME TEAM</p>
|
||||
<h1 id="recruit-title">함께 만들 팀원을 찾는 공간</h1>
|
||||
<p>기획, 아트, 프로그래머가 작은 프로젝트부터 출시 목표 팀까지 가볍게 만나는 게시판입니다.</p>
|
||||
</div>
|
||||
<a class="recruit-write" href="<%= ctx %>/recruit/new">모집글 작성</a>
|
||||
<a class="recruit-write<%= recruitPosts.isEmpty() ? " recruit-write--ghost" : "" %>" href="<%= ctx %>/recruit/new">모집글 작성</a>
|
||||
</section>
|
||||
|
||||
<section class="recruit-toolbar" aria-label="모집글 검색 및 필터">
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue