feat: strengthen design skill and refresh all showcases
Some checks failed
ci / build (push) Has been cancelled

This commit is contained in:
Yun Chan 2026-09-12 18:16:33 +09:00
parent 69e5cc1efd
commit e09d4efb1c
257 changed files with 8196 additions and 2374 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,13 @@
# MaruBuri source record
Downloaded 2026-09-12 from the official NAVER Hangeul static host. The files are retained unchanged: no conversion or subsetting was performed.
| File | Official URL | HTTP content type | Size | SHA-256 |
| --- | --- | --- | --- | --- |
| `MaruBuri-Regular.woff2` | https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-Regular.woff2 | `font/woff2` | 433776 bytes | `4CF1341CF2F23FB3E263712DFDE1D8F25EEDCC328B696A2E5A2C8ADD55E5C17B` |
| `MaruBuri-SemiBold.woff2` | https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-SemiBold.woff2 | `font/woff2` | 466108 bytes | `7AEF4862FA3219B0A7DEB6746E27116A38C4069F4424EB51EDF103B29795F5C2` |
- Official stylesheet checked: https://hangeul.pstatic.net/hangeul_static/css/maru-buri.css
- Official NAVER license page saved verbatim as `LICENSE.html`: https://help.naver.com/service/11029/contents/18088?lang=ko&osType=PC
- `LICENSE.html` SHA-256: `8538F7921744D5E040F603BC301465EFBD038F1054D0754B7508DE3286452EC3`
- The saved official page includes the NAVER copyright notice and the SIL Open Font License 1.1 text for MaruBuri.

View file

@ -0,0 +1,17 @@
# 목요일의 화원
크림색 종이와 차분한 세리프, 세 장의 꽃 사진을 유지한다. 히어로는 제목·설명·상담 CTA와 사진을 분리한 0.9:1.1 두 칼럼으로 두고, 사진은 중심 꽃다발 하나와 보조 두 장을 공통 캡션선으로 묶는다. 아래 작업 기록도 대표 한 장과 보조 두 장의 크기 차이를 유지한다.
| 판단 축 | 적용 | 한계 |
| --- | --- | --- |
| 구도 | Hofmann의 정렬과 대비를 참고해 사진 겹침을 기준선·캡션으로 바꿨다. | 원전의 방법을 보편적 시선 법칙으로 간주하지 않는다. |
| 타입 | Ruder의 위계 구분을 참고해 큰 제목, 본문, 작은 캡션의 역할을 분리했다. | 실제 읽기 성과는 브라우저 검증에서 확인한다. |
| 색 | Albers의 관계 관점을 참고해 크림 바탕과 적갈색 강조를 유지했다. | 색의 효과를 사용자 반응으로 단정하지 않는다. |
토큰은 `--paper`, `--ink`, `--accent`, `--space-*`, `--step-*`에 유지한다. 로컬 MaruBuri 400/600은 `styles/fonts.css`에서, 본문 Pretendard는 기존 CDN에서 로드한다. 가상 문의·구독·가격성 안내와 기존 앵커 계약은 보존했다.
## 2026-09-12 현재 검증 기록
- `verify-final` 18개 묶음은 16개가 즉시 통과했다. 전체 묶음의 invariant·visual 검사는 Gaon·Dure를 대상으로 하며, 나머지 2개는 수정 뒤 release 독립 재실행에서 ALL PASS·ALL MATCH였다.
- root는 28개 모바일, 21개 데스크톱, 7개 하위 경로와 30개 앱 상태를 직접 검토해 수용했다. stress 112건은 hard failure 0이며, 가로 넘침 4건은 targeted fix 뒤 390px 재측정에서 0이다.
- 이 기록은 렌더·계약 범위의 현재 결과다. 모든 폭·키보드 경로·인쇄 등 개별 기능을 완전 재실행했다는 뜻이 아니며, 참여자 과업 효과도 미측정이다.

View file

@ -21,13 +21,13 @@
<!-- 한글 세리프. 라틴 세리프만 지정하면 한글이 시스템 기본으로 떨어져 전부 무너진다 -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/webfontworld/naver/MaruBuri.css"
href="./styles/fonts.css?v=20260912all"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
/>
<link rel="stylesheet" href="./styles/main.css?v=2" />
<link rel="stylesheet" href="./styles/main.css?v=20260912all" />
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Ctext y='26' font-size='26'%3E🌿%3C/text%3E%3C/svg%3E" />
</head>
@ -83,6 +83,7 @@
loading="eager"
fetchpriority="high"
/>
<figcaption>이번 주의 중심 꽃다발</figcaption>
</figure>
<figure class="ph ph-b reveal" style="--delay: 260ms">
<img
@ -92,6 +93,7 @@
height="1448"
loading="lazy"
/>
<figcaption>꽃잎의 결</figcaption>
</figure>
<figure class="ph ph-c reveal" style="--delay: 340ms">
<img
@ -101,6 +103,7 @@
height="1086"
loading="lazy"
/>
<figcaption>목요일의 작업대</figcaption>
</figure>
<p class="hero-tags reveal" style="--delay: 420ms">
주문 제작 / 정기 구독 / 공간 장식

View file

@ -0,0 +1,15 @@
@font-face {
font-family: "MaruBuri";
src: url("../assets/fonts/MaruBuri-Regular.woff2") format("woff2");
font-style: normal;
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: "MaruBuri";
src: url("../assets/fonts/MaruBuri-SemiBold.woff2") format("woff2");
font-style: normal;
font-weight: 600;
font-display: swap;
}

View file

@ -1,4 +1,4 @@
@import url("./tokens.css");
@import url("./tokens.css?v=20260912all");
/* ────────────────────────────────────────────────────────
리셋 — 필요한 것만
@ -141,6 +141,9 @@ h3 + * {
.section {
padding-block: var(--space-8);
}
.section[id] {
scroll-margin-top: 5rem;
}
/* 가로 정보 라벨. 여백은 글자를 세우지 않고도 충분히 구분된다. */
.hero-role,
@ -252,6 +255,7 @@ h3 + * {
}
.nav {
display: flex;
flex-wrap: wrap;
gap: var(--space-4);
font-size: var(--step-label);
font-weight: var(--weight-bold);
@ -267,31 +271,26 @@ h3 + * {
color: var(--ink);
}
/* ── 히어로 ───────────────────────────────────────────
리스크를 감수한 자리다. 큰 사진 한 장 대신 셋을 흩뿌린다.
그리드를 12칸으로 두되 각 사진이 **서로 다른 칸에서 시작해 다른 칸에서 끝난다.**
R1 을 실측했더니 이미지 6개의 좌측 정렬선이 6개 전부 달랐다(117·173·188·433·588·948).
정렬선이 하나로 모이는 순간 이 레이아웃은 그냥 어긋난 그리드가 된다. */
/* ── 히어로 ─────────────────────────────────────────── */
.hero {
padding-block: var(--space-6) var(--space-8);
}
/* 12칸 그리드에 grid-row 를 손으로 배치했더니 행 높이가 콘텐츠에 따라
285/195/88/266px 로 제각각 잡히고 사이에 빈 칸이 생겼다.
글과 사진을 두 덩어리로 나누고, **사진 안에서만** 흩뿌린다.
그래야 정렬선을 흩는 것과 빈 공간이 생기는 것이 분리된다. */
.hero-inner {
display: grid;
/* 텍스트 칼럼이 좁으면 h1 이 3줄로 접힌다(카운트 규칙: 헤드라인 2줄 이하).
정보 라벨이 왼쪽에서 자리를 먹으므로 그만큼 더 준다. */
grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
gap: var(--space-5);
grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
gap: var(--space-7);
align-items: center;
}
.hero-inner > *,
.two > *,
.gallery > *,
.visit-inner > * {
min-width: 0;
}
.hero-text {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
grid-template-columns: minmax(0, 1fr);
gap: var(--space-5);
align-items: start;
}
@ -300,52 +299,49 @@ h3 + * {
}
.hero-role {
align-self: start;
white-space: normal;
}
.hero-cta {
justify-self: start;
}
/* 사진 셋. 위치·크기·비율이 전부 다르고 서로 겹친다.
R1 실측에서 이미지 6개의 좌측 정렬선이 6개 전부 달랐다 —
정렬선이 하나로 모이면 이 레이아웃은 그냥 어긋난 그리드가 된다. */
.hero-photos {
position: relative;
/* 가장 아래 사진(.ph-c)이 63% 에서 시작해 폭 47%·4:3 이므로 약 0.99 에서 끝난다.
컨테이너를 그보다 길게 잡으면 히어로 아래에 빈 띠가 남는다. */
aspect-ratio: 1 / 0.995;
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: var(--space-3) var(--space-4);
align-items: start;
}
.ph {
position: absolute;
margin: 0;
overflow: hidden;
}
.ph img {
display: block;
width: 100%;
height: 100%;
height: auto;
object-fit: cover;
}
.ph figcaption {
margin-top: var(--space-2);
color: var(--ink-muted);
font-size: var(--step-label);
font-weight: var(--weight-bold);
letter-spacing: var(--track-label);
}
.ph-a {
left: 16%;
top: 0;
width: 60%;
aspect-ratio: 3 / 4;
grid-column: 1 / 9;
grid-row: 1 / span 2;
}
.ph-b {
left: 0;
top: 52%;
width: 27%;
aspect-ratio: 3 / 4;
grid-column: 9 / -1;
grid-row: 1;
}
.ph-c {
right: 0;
top: 63%;
width: 47%;
aspect-ratio: 4 / 3;
grid-column: 9 / -1;
grid-row: 2;
}
.hero-tags {
position: absolute;
right: -1.4rem;
top: 4%;
grid-column: 1 / -1;
margin-top: var(--space-2);
}
/* ── 섹션 공통 ────────────────────────────────────── */
@ -406,8 +402,7 @@ h3 + * {
margin: 0;
}
/* ── 작업 갤러리 ──────────────────────────────────────
균일한 3열 그리드를 쓰지 않는다. 셋의 크기와 세로 위치가 전부 다르다. */
/* ── 작업 갤러리 ────────────────────────────────────── */
.gallery {
margin-top: var(--space-7);
display: grid;
@ -430,21 +425,21 @@ h3 + * {
color: var(--ink-muted);
}
.g-1 {
grid-column: 1 / 9;
grid-column: 1 / 8;
}
.g-1 img {
aspect-ratio: 16 / 9;
}
.g-2 {
grid-column: 9 / 13;
margin-top: var(--space-7);
grid-column: 8 / 13;
margin-top: 0;
}
.g-2 img {
aspect-ratio: 3 / 4;
}
.g-3 {
grid-column: 3 / 10;
margin-top: var(--space-5);
grid-column: 8 / 13;
margin-top: var(--space-2);
}
.g-3 img {
aspect-ratio: 4 / 3;
@ -494,7 +489,8 @@ h3 + * {
max-width: 24ch;
}
.visit-mark {
color: var(--line);
/* 장식이라도 실제 문장이므로 배경선 색을 그대로 쓰지 않는다. */
color: var(--ink-muted);
font-family: var(--font-display);
font-size: 1rem;
letter-spacing: 0.2em;
@ -526,7 +522,17 @@ h3 + * {
display: none;
}
.hero-photos {
aspect-ratio: 1 / 0.9;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.ph-a,
.ph-b,
.ph-c,
.hero-tags {
grid-column: auto;
grid-row: auto;
}
.ph-a {
grid-column: 1 / -1;
}
.visit-mark {
max-width: 100%;
@ -574,7 +580,7 @@ h3 + * {
display: inline;
}
.nav {
flex-wrap: nowrap;
flex-wrap: wrap;
justify-content: space-between;
gap: var(--space-2);
letter-spacing: 0.04em;
@ -586,20 +592,12 @@ h3 + * {
padding-inline: var(--space-4);
white-space: nowrap;
}
/* 히어로 사진 셋을 세로로 세우면 화면이 너무 길어진다.
가장 작은 것 하나만 남기고 나머지는 갤러리에서 다시 보여준다. */
.hero-photos {
aspect-ratio: 3 / 4;
}
.ph-b {
display: none;
}
.ph-a {
left: 0;
width: 78%;
}
.ph-c {
top: 58%;
width: 62%;
grid-template-columns: 1fr;
gap: var(--space-4);
}
.ph-a,
.ph-b,
.ph-c,
.hero-tags { grid-column: 1; }
}

View file

@ -15,7 +15,7 @@
--paper-deep: #f1ede4; /* 섹션 하나만 살짝 눕힌다. 리듬용 */
--ink: #2a2723;
--ink-muted: #6b655c;
--ink-faint: #a09889;
--ink-faint: #746c60;
--accent: #7c4a3f; /* 마른 장미. 꽃의 초록과 충돌하지 않는다 */
--line: #ddd7ca;
@ -33,7 +33,7 @@
정보 라벨이 왼쪽에서 60px 을 먹으므로 텍스트 칼럼은 화면 폭의 절반보다 좁다.
1024px 에서 55.7px 로 잡히자 딱 넘쳐 3줄이 됐다(카운트 규칙 위반).
기울기를 낮춰 전 구간에서 2줄을 유지한다. */
--step-display: clamp(2.2rem, 1.3rem + 2.9vw, 4.2rem);
--step-display: clamp(2.2rem, 1.5rem + 2.4vw, 3.5rem);
--step-lead: clamp(1.05rem, 0.98rem + 0.3vw, 1.25rem);
--step-body: 1rem;
--step-label: 0.75rem;