섹션마다 다른 배경 사진을 만들어 붙인다
모션에 적용한 규칙("섹션마다 다른 말을 해야 한다")이 배경에서만 면제될
이유가 없다. 같은 그림을 전부에 깔면 그건 벽지다.
gpt-image-2 로 넉 장. 프롬프트마다 그 섹션의 주장을 그림으로 옮겼다
bg-refraction 겹친 유리판을 통과한 빛 재료·설치 표면은 한 겹이 아니다
bg-split 한 빔이 둘로 갈라진다 사례 같은 절차, 다른 결과
bg-align 정렬선 하나가 끊겨 있다 프리플라이트 자기 결과물을 남의 것처럼 본다
bg-paper 무광 인쇄용지, 섬유와 데클 조판 한글이 종이 위에 있어야 한다
넣지 않은 곳도 결정이다
파이프라인·수치 격자가 그 섹션의 주장이다
히어로 three.js 가 있다
규칙 목록은 담백해야 한다
프롬프트에는 매번 토큰 값을 그대로 넣었다. 광원은 #4FD6C4 와 #3D7BD6 둘뿐,
보라·마젠타·무지개·프리즘 분광 금지. "흰 본문 뒤에 깔리니 활자와 경쟁할
만큼 밝은 곳이 있으면 안 된다" 를 매번 반복했다.
BgPhoto 를 variant 로 확장. 소스 WebP 37/14/11/112KB,
빌드 12개 합계 276KB. 뷰포트에 맞는 하나씩만 lazy 로 받는다.
This commit is contained in:
parent
54b9628879
commit
2bb1da9ce9
8 changed files with 54 additions and 28 deletions
|
|
@ -222,11 +222,24 @@ WebGL 게이트: `prefers-reduced-motion` 이면 **아예 시작하지 않는다
|
|||
**실측 3층** (스크롤 1000 → 1600): 격자 **+14.9px** · 산출물 **-14px** · 단계명 **0**.
|
||||
한 층은 반드시 고정이다. 전부 움직이면 기준이 없어 그냥 흔들리는 페이지가 된다.
|
||||
|
||||
### 배경 사진 (gpt-image-2 로 생성)
|
||||
### 배경 사진 넉 장 (gpt-image-2 로 생성)
|
||||
|
||||
CSS 그라디언트 광원만으로는 기준면이 약해서, 굴절과 그레인이 실제로 들어 있는 이미지를 넣었다.
|
||||
Codex CLI 의 내장 `image_gen`(gpt-image-2)을 ChatGPT 구독 인증으로 호출해 만들었다 — 스톡 이미지가 아니다.
|
||||
|
||||
**섹션마다 다른 그림을 쓴다.** 같은 배경을 전부에 깔면 그건 벽지고,
|
||||
모션에 적용한 규칙("섹션마다 다른 말을 해야 한다")이 배경에서만 면제될 이유가 없다.
|
||||
|
||||
| 이미지 | 무엇 | 어디 | 그 섹션의 주장 |
|
||||
|---|---|---|---|
|
||||
| `bg-refraction` | 겹친 유리판을 통과한 빛 | 재료 · 설치(flip) | 표면은 한 겹이 아니다 |
|
||||
| `bg-split` | 한 빔이 둘로 갈라진다 | 사례 | 같은 파이프라인, 다른 결과 |
|
||||
| `bg-align` | 정렬선 여럿 중 **하나가 어긋나 끊겨 있다** | 프리플라이트 | 자기 결과물을 남의 것처럼 본다 |
|
||||
| `bg-paper` | 무광 인쇄용지, 섬유와 데클 엣지 | 조판(밝은 밴드) | 한글이 종이 위에 있어야 한다 |
|
||||
|
||||
**격자를 쓰는 파이프라인·수치에는 사진을 넣지 않았다.** 거기서는 격자가 그 섹션의 주장이다.
|
||||
규칙·히어로도 그대로 뒀다 — 히어로에는 three.js 가 있고, 규칙 목록은 담백해야 한다.
|
||||
|
||||
프롬프트는 **이 페이지의 토큰 값을 그대로** 넣었다:
|
||||
|
||||
- 바탕 `#0B0E12` — 순흑도 네이비도 아니게
|
||||
|
|
@ -242,13 +255,17 @@ Codex CLI 의 내장 `image_gen`(gpt-image-2)을 ChatGPT 구독 인증으로 호
|
|||
절대배치한다 — background-image 로 깔면 **항상 받고 최적화도 안 된다.**
|
||||
같은 이미지를 설치 섹션에서는 `flip` 으로 좌우 반전해 같은 그림으로 읽히지 않게 했다.
|
||||
|
||||
| 크기 | 빌드 결과 (WebP) |
|
||||
|---|---|
|
||||
| 1920px | **26KB** |
|
||||
| 1400px | 14KB |
|
||||
| 860px | 7KB |
|
||||
소스 WebP: `refraction` 37KB · `split` 14KB · `align` 11KB · `paper` 112KB
|
||||
(종이만 큰 이유는 섬유 질감이 고주파라 압축이 안 붙기 때문이다)
|
||||
|
||||
추상 그라디언트라 압축이 잘 붙는다. 소스도 PNG 2MB 대신 **WebP 37KB** 로 두었다.
|
||||
빌드 결과 12개 파일 합계 **276KB**. 실제로는 뷰포트에 맞는 크기 하나씩만,
|
||||
그것도 `loading="lazy"` 로 받는다.
|
||||
|
||||
**codex 0.147.0 메모** — `codex-image` 스킬의 `extract_imagegen.py` 는 rollout JSONL 의
|
||||
`image_generation_call` base64 를 찾는데, 0.147.0 은 다시 **파일**로 저장한다
|
||||
(`~/.codex/generated_images/<sid>/exec-*.png`, 이벤트는 `custom_tool_call` + `image_generation_end`).
|
||||
그래서 추출이 fail-loud 로 죽는다 — 이미지는 실제로 생성돼 있다.
|
||||
그리고 `$imagegen` 은 **프롬프트 맨 앞**에 있어야 내장 도구가 발동한다.
|
||||
|
||||
## 그리드의 `wide` 트랙을 좁은 화면에서 닫는다
|
||||
|
||||
|
|
|
|||
BIN
apps/site/src/assets/bg/bg-align.webp
Normal file
BIN
apps/site/src/assets/bg/bg-align.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
apps/site/src/assets/bg/bg-paper.webp
Normal file
BIN
apps/site/src/assets/bg/bg-paper.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
BIN
apps/site/src/assets/bg/bg-split.webp
Normal file
BIN
apps/site/src/assets/bg/bg-split.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,36 +1,40 @@
|
|||
---
|
||||
import { Image } from "astro:assets";
|
||||
import bgRefraction from "../assets/bg/bg-refraction.webp";
|
||||
import refraction from "../assets/bg/bg-refraction.webp";
|
||||
import paper from "../assets/bg/bg-paper.webp";
|
||||
import split from "../assets/bg/bg-split.webp";
|
||||
import align from "../assets/bg/bg-align.webp";
|
||||
|
||||
/**
|
||||
* 배경은 섹션마다 다른 말을 해야 한다. 같은 그림을 전부에 깔면 그건 벽지다.
|
||||
* 넷 다 gpt-image-2 로 만들었고, 프롬프트에 이 페이지의 토큰 값을 그대로 넣었다.
|
||||
*
|
||||
* refraction 겹친 유리판을 통과한 빛 재질이 주제인 자리
|
||||
* split 한 빔이 둘로 갈라진다 같은 절차, 다른 결과
|
||||
* align 정렬선 하나가 어긋나 있다 자기 검사
|
||||
* paper 무광 인쇄용지 밝은 밴드. 한글이 종이 위에 있어야 한다
|
||||
*/
|
||||
const SOURCES = { refraction, paper, split, align } as const;
|
||||
|
||||
interface Props {
|
||||
/** 0~1. 이 레이어는 본문 뒤에 깔리므로 기본값을 낮게 둔다 */
|
||||
variant?: keyof typeof SOURCES;
|
||||
/** 0~1. 본문 뒤에 깔리므로 기본값을 낮게 둔다 */
|
||||
opacity?: number;
|
||||
/** 좌우 반전. 같은 이미지를 두 섹션에 쓸 때 같은 그림으로 안 읽히게 한다 */
|
||||
/** 좌우 반전. 같은 그림을 두 섹션에 쓸 때 되풀이로 안 읽히게 한다 */
|
||||
flip?: boolean;
|
||||
}
|
||||
const { opacity = 0.45, flip = false } = Astro.props;
|
||||
const { variant = "refraction", opacity = 0.45, flip = false } = Astro.props;
|
||||
const src = SOURCES[variant];
|
||||
---
|
||||
|
||||
{/*
|
||||
배경 사진 레이어.
|
||||
|
||||
CSS 그라디언트로 만든 광원과 달리 굴절·그레인·빛의 감쇠가 실제로 들어 있어
|
||||
패럴랙스의 기준면으로 훨씬 잘 읽힌다. 대신 무게가 있으므로 규칙이 붙는다.
|
||||
|
||||
- `loading="lazy"` — 초기 번들에 들어가지 않는다. CSS background-image 로 깔면
|
||||
이 통제권을 잃는다(항상 받고, 최적화도 안 된다). 그래서 <img> 를 절대배치한다
|
||||
- `aria-hidden` + 빈 alt — 장식이다. 보조기술이 읽을 것이 없다
|
||||
- opacity 기본 0.45 — 본문 대비를 지키는 선. 올리려면 그 위 글자를 다시 재라
|
||||
*/}
|
||||
<div class="bg-photo" class:list={{ flip }} aria-hidden="true" style={`--bg-opacity:${opacity}`}>
|
||||
<Image
|
||||
src={bgRefraction}
|
||||
alt=""
|
||||
widths={[860, 1400, 1920]}
|
||||
sizes="100vw"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<Image src={src} alt="" widths={[860, 1400, 1920]} sizes="100vw" loading="lazy" decoding="async" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
@ -67,7 +71,6 @@ const { opacity = 0.45, flip = false } = Astro.props;
|
|||
}
|
||||
}
|
||||
|
||||
/* 투명도를 줄여달라는 설정에서는 더 낮춘다 */
|
||||
@media (prefers-reduced-transparency: reduce) {
|
||||
.bg-photo :global(img) { opacity: calc(var(--bg-opacity) * 0.5); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
import BgPhoto from "./BgPhoto.astro";
|
||||
import type { Content } from "../i18n/content";
|
||||
|
||||
interface Props { c: Content["preflight"]; }
|
||||
|
|
@ -10,7 +11,8 @@ const { c } = Astro.props;
|
|||
걸린 것과 고친 것이 한 줄에서 이어진다. 상자에 담지 않는다.
|
||||
왼쪽 세로선이 로그라는 형식을 만든다.
|
||||
*/}
|
||||
<section class="section preflight" aria-labelledby="pf-h">
|
||||
<section class="section preflight has-bg" aria-labelledby="pf-h">
|
||||
<BgPhoto variant="align" opacity={0.55} />
|
||||
<h2 id="pf-h" class="reveal">{c.h2}</h2>
|
||||
<p class="lead pf-lead reveal">{c.lead}</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { Image } from "astro:assets";
|
||||
import shotCoffee from "../assets/shots/shot-coffee.png";
|
||||
import shotSaas from "../assets/shots/shot-saas.png";
|
||||
import BgPhoto from "./BgPhoto.astro";
|
||||
import type { Content } from "../i18n/content";
|
||||
|
||||
interface Props { c: Content["showcase"]; }
|
||||
|
|
@ -10,7 +11,8 @@ const shots = [shotCoffee, shotSaas];
|
|||
---
|
||||
|
||||
{/* 레이아웃 패밀리: Z축 캐스케이드. 두 판이 서로 겹치고 각도가 다르다 */}
|
||||
<section id="showcase" class="section showcase" aria-labelledby="showcase-h">
|
||||
<section id="showcase" class="section showcase has-bg" aria-labelledby="showcase-h">
|
||||
<BgPhoto variant="split" opacity={0.3} />
|
||||
<h2 id="showcase-h" class="reveal">{c.h2}</h2>
|
||||
<p class="lead showcase-lead reveal">{c.lead}</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
import BgPhoto from "./BgPhoto.astro";
|
||||
import type { Content } from "../i18n/content";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -7,7 +8,8 @@ interface Props {
|
|||
const { c } = Astro.props;
|
||||
---
|
||||
|
||||
<section class="section band-inverse" aria-labelledby="type-h">
|
||||
<section class="section band-inverse has-bg" aria-labelledby="type-h">
|
||||
<BgPhoto variant="paper" opacity={0.85} />
|
||||
<p class="eyebrow reveal">{c.eyebrow}</p>
|
||||
<h2 id="type-h" class="reveal">{c.h2}</h2>
|
||||
<p class="lead type-lead reveal">{c.lead}</p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue