패럴랙스에 기준면을 준다 — 배경 격자와 광원 레이어

배경이 단색이면 패럴랙스는 성립하지 않는다. 앞의 것이 몇 px 어긋나도
비교할 대상이 없다. 히어로 말고는 기준면이 없어 시차가 안 보였다.

배경 이미지를 사 오는 대신 이 페이지가 이미 주장하는 것을 그렸다
  .bg-grid  간격 눈금 격자. 셀이 --grid-cell = --space-6
            파이프라인 · 수치. "모든 값이 토큰에서 나온다"가 배경에서도 성립
  .bg-glow  광원 블롭. 섹션마다 --glow-x 로 자리를 옮긴다
            재료 · 설치. 히어로의 빛이 마지막 CTA 에서 돌아온다

실측 3층 (스크롤 1000 -> 1600)
  격자 +14.9px  ·  산출물 -14px  ·  단계명 0
  한 층은 반드시 고정이다. 전부 움직이면 그냥 흔들리는 페이지다

그리드 wide 트랙을 좁은 화면에서 닫는다
  고정 10rem 이라 모바일에서도 좌우 80px 이 살아남아, 390px 에서 본문이
  x=112 부터 시작하고 폭이 278px 로 줄어 제목이 네 줄로 접혔다.
  --wide-pad 를 clamp 로 바꿔 닫았다. 이제 전부 x=32 에서 시작하고 두 줄이다

파이프라인 정렬선을 하나로
  제목 x=371 / 리드 x=435 / 스파인 x=143 이던 것을 전부 x=183 으로.
  제목·리드·브리프를 스파인과 같은 컨테이너에 넣었다

히어로 높이를 콘텐츠에 맞춘다
  모바일에서 콘텐츠 390px 에 736px 을 씌워 여백이 화면의 41% 였고
  다음 섹션이 화면 밖으로 밀려 스크롤 단서까지 사라졌다.
  모바일 min-height 제거(736 -> 554), 데스크톱 88dvh -> 78dvh
  배경 마스크 62% -> 82% 로 늘려 하단의 죽은 띠를 없앴다

스킬 motion.md 에 "패럴랙스에는 기준면이 필요하다" 를 추가.
페이지가 주장하는 것을 배경으로 그리는 표와, 한 층은 고정이라는 규칙.

390px / 1440px 실렌더: 가로 스크롤 0, 대비 실패 0. 테스트 22개 통과
This commit is contained in:
Yun Chan 2026-08-20 14:25:02 +09:00
parent 9c9ab2de7e
commit 0e03bbafac
9 changed files with 158 additions and 19 deletions

View file

@ -139,9 +139,9 @@ section[id] { scroll-margin-top: calc(var(--header-h) + var(--space-4)); }
display: grid;
grid-template-columns:
[full-start] minmax(var(--gutter), 1fr)
[wide-start] minmax(0, var(--space-8))
[wide-start] minmax(0, var(--wide-pad))
[main-start] minmax(0, var(--measure)) [main-end]
minmax(0, var(--space-8)) [wide-end]
minmax(0, var(--wide-pad)) [wide-end]
minmax(var(--gutter), 1fr) [full-end];
}
.page > * { grid-column: main; }
@ -415,6 +415,61 @@ a:hover { color: var(--accent); }
}
}
/* ---- 배경 레이어 --------------------------------------------
패럴랙스는 깊이 차가 보여야 성립한다. 배경이 단색이면 앞의 것이
px 어긋나 봐야 아무도 느낀다 기준면이 없기 때문이다.
그래서 배경을 깐다. 다만 이미지가 아니라 페이지가 주장하는 ,
간격 눈금 자체를 격자로 그린다. --grid-cell --space-5 . */
.bg-grid,
.bg-glow {
position: relative;
isolation: isolate;
}
.bg-grid::before,
.bg-glow::before {
content: "";
position: absolute;
inset: -12% 0;
z-index: -1;
pointer-events: none;
}
.bg-grid::before {
background-image:
repeating-linear-gradient(to right,
var(--line-strong) 0 1px, transparent 1px var(--grid-cell)),
repeating-linear-gradient(to bottom,
var(--line-strong) 0 1px, transparent 1px var(--grid-cell));
/* 가장자리에서 지운다. 화면 끝까지 격자가 가면 표가 되어버린다 */
-webkit-mask-image: radial-gradient(135% 95% at 50% 45%, black 22%, transparent 92%);
mask-image: radial-gradient(135% 95% at 50% 45%, black 22%, transparent 92%);
opacity: 0.7;
}
/* 히어로의 두 광원이 페이지를 관통한다. 섹션마다 자리가 다르다 */
.bg-glow::before {
background:
radial-gradient(42% 46% at var(--glow-x, 78%) var(--glow-y, 32%),
color-mix(in oklab, var(--accent) 15%, transparent), transparent 70%),
radial-gradient(38% 42% at calc(100% - var(--glow-x, 78%)) 78%,
color-mix(in oklab, var(--glow-2) 13%, transparent), transparent 68%);
}
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: view()) {
/* 배경이 가장 느리다. 콘텐츠보다 적게 움직여야 뒤에 있는 것으로 읽힌다 */
.bg-grid::before { --par-from: -34px; --par-to: 34px; }
.bg-glow::before { --par-from: -58px; --par-to: 58px; }
.bg-grid::before,
.bg-glow::before {
animation: par linear both;
animation-timeline: view();
animation-range: cover 0% cover 100%;
}
}
}
/* ---- 유틸 -------------------------------------------------- */
.visually-hidden {
position: absolute;

View file

@ -128,6 +128,18 @@
모바일 구간 32px 깔고 넓은 화면에서만 40px 까지 연다. */
--gutter: clamp(2rem, 1.4rem + 1.8vw, 2.5rem);
/* 배경 격자의 . 간격 스케일에서 가져온다
장식용 격자가 아니라 페이지가 실제로 쓰는 눈금이어야
"모든 값이 토큰에서 나온다" 주장이 배경에서도 성립한다. */
--grid-cell: var(--space-6);
/* main 칼럼 바깥의 여유 (wide 트랙). 넓은 화면에서 제목과 넓은 블록이
본문보다 밖으로 나갈 자리를 만든다.
값을 고정으로 두면 모바일에서도 좌우 80px 살아남아, 390px 화면에서
본문이 x=112 부터 시작하고 폭이 278px 줄어든다 제목이 줄로 접힌다.
좁은 화면에서는 0 으로 닫는다. */
--wide-pad: clamp(0rem, -3.7rem + 15.2vw, 10rem);
/* 헤더가 차지하는 높이. 있는 헤더라 문서 흐름에서 빠져 있고,
그래서 히어로 상단 여백과 앵커 목적지가 값을 알아야 한다.
간격 토큰을 clamp 바꾸는 순간 관계가 끊겨 h1 헤더 뒤로