# AI 꾸러미 — CSS 무늬 (그러데이션 · 데이터 SVG) — CSS gradient patterns (repeating-linear / radial / conic-gradient)
> 그림 파일 없이 CSS 그러데이션(줄 · 원 · 원뿔 반복)과 주소에 넣은 SVG 만으로 나뭇결 · 공책 · 줄무늬 · 집중선 · 모눈 · 물방울 무늬를 만든다.  
> 견본: https://ai-techstudio.web.app/#t/u62

이 문서를 코드 도우미(Claude Code · Cursor · ChatGPT 등)에 그대로 주면 돼요. 「## 주문서」 가 할 일, 나머지는 참고 자료예요.

## 주문서

### 만들어 줘: CSS 무늬 (그러데이션 · 데이터 SVG) — CSS gradient patterns (repeating-linear / radial / conic-gradient)

#### 1. 목표
게임 판 · 패널 바탕에 그림 파일 없이 CSS 만으로 나뭇결 · 공책 종이 · 모눈 무늬를 깔아 줘 — 그러데이션 반복과 데이터 SVG 로, 크기가 바뀌어도 또렷하게.

#### 2. 핵심 기술 용어
- **CSS gradient patterns (repeating-linear / radial / conic-gradient)** — CSS 그러데이션 반복 무늬
- **Data URI SVG background** — 주소 안에 넣은 SVG 그림 (data:image/svg+xml)
- **Multiple backgrounds + background-size / position** — 배경 여러 겹 · 무늬 크기 · 위치 옮기기
- **Hard color stops** — 같은 자리에 두 색을 둬 경계를 칼같이

#### 3. 환경
- 플랫폼: TypeScript (브라우저), 라이브러리 없이 — 화면과 떨어진 순수 함수로
- 화면: 브라우저 — PC · 폰 모두

#### 4. 조건
- 경계가 또렷해야 하는 줄무늬는 같은 자리 두 색(하드 스톱)으로
- 무늬 크기는 cqmin · em 처럼 상자에 따라 바뀌는 단위로 (폰에서 줄이 너무 촘촘하지 않게)
- SVG 를 주소에 넣을 땐 encodeURIComponent 로 감싼다 (# · < 가 깨지지 않게)
- 움직임은 background-position · background-size 로 (무늬 식을 매번 다시 만들지 않는다)

#### 5. 완성 기준 (이게 보이면 성공)
- 나뭇결 · 공책 · 줄무늬 · 집중선 · 모눈 · 물방울 여섯 칸이 그림 파일 없이 보인다
- 줄무늬가 흐르고 집중선이 돌고 물방울이 숨 쉰다
- 창 크기를 바꿔도 선이 흐려지지 않는다
- 네트워크 탭에 그림 요청이 없다

#### 6. 진행 방식
- 핵심 코드 위주로, 설명은 짧게. 내 프로젝트에 끼워 넣기 쉬운 함수 · 클래스로 나눠 줘.
- 처음 화면에 바로 결과가 보이게, 그리고 켬/끔(또는 전/후) 비교를 할 수 있게 만들어 줘.
- 그림 · 소리 · 모델 파일이 필요하면 코드로 만든 임시 대체물로 먼저 돌아가게 하고, 진짜 파일로 바꿀 자리를 표시해 줘.
- 마지막에 「확인 방법」(무엇을 보면 성공인지)과 「조절할 값」 목록을 짧게 정리해 줘.
- 답변과 코드 주석은 한국어로 해 줘.

## 원리
- 같은 위치에 두 색을 두면(#ffd34d 0 4cqmin, #262626 4cqmin 8cqmin) 흐림 없이 칼같은 띠가 된다 — 반복(repeating-)하면 줄무늬.
- 공책 = 가로 줄 반복 위에 빨간 세로 여백 줄 한 겹. 물방울 = 원 그러데이션 두 겹을 반 칸 비켜 깔기.
- 집중선 = repeating-conic-gradient(가운데에서 도는 쐐기) 위에 가운데 흰 원 그러데이션.
- 모눈처럼 선 모양이 중요하면 작은 SVG 를 encodeURIComponent 로 주소에 넣어 url("data:image/svg+xml,…") 로 깐다.
- background-position · background-size 만 바꾸면 줄무늬가 흐르고, 물방울이 숨 쉬고, 집중선이 돈다.

## 핵심 코드 — 줄무늬 · 공책 · 물방울 · 모눈(SVG) · 집중선
(발췌: demos/demosDraw2d.ts u62 의 CSS 와 update() 를 정리)
```ts
const grid = encodeURIComponent("<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><path d='M20 0H0V20' fill='none' stroke='#7fb2e6' stroke-width='1'/></svg>");

const css =
  // 공사 줄무늬: 같은 자리 두 색 = 칼같은 경계
  '.stripe{background:repeating-linear-gradient(45deg,#ffd34d 0 4cqmin,#262626 4cqmin 8cqmin)}' +
  // 공책: 가로 줄 반복 + 빨간 여백 줄 한 겹
  '.paper{background:linear-gradient(90deg,#0000 16%,#ef7a7a 16% 17%,#0000 17%),repeating-linear-gradient(#fffdf4 0 4.6cqmin,#a9cdeb 4.6cqmin 5cqmin)}' +
  // 물방울: 원 두 겹을 반 칸 비켜서
  '.dots{background:radial-gradient(circle,#ff7fb0 28%,#0000 31%) 0 0/7cqmin 7cqmin,radial-gradient(circle,#ffd1e3 28%,#0000 31%) 3.5cqmin 3.5cqmin/7cqmin 7cqmin,#fff0f6}' +
  // 모눈: 작은 SVG 를 주소에 넣어 반복
  '.grid{background:#f6fbff url("data:image/svg+xml,' + grid + '")}';

function animate(t: number, stripe: HTMLElement, burst: HTMLElement, dots: HTMLElement) {
  stripe.style.backgroundPosition = ((t * 30) % 1000) + 'px 0';          // 흐르는 줄무늬
  const a = (t * 25) % 360;                                              // 도는 집중선
  burst.style.background = 'radial-gradient(circle at 50% 45%,#fff 0 12%,#fff0 34%),' +
    'repeating-conic-gradient(from ' + a + 'deg at 50% 45%,#ff9a3c 0 4deg,#ffe27a 4deg 10deg)';
  const s = 1 + 0.08 * Math.sin(t * 2);                                  // 숨 쉬는 물방울
  dots.style.backgroundSize = 7 * s + 'cqmin ' + 7 * s + 'cqmin';
}
```

## 흔한 실수 · 확인 목록
- [ ] **두 색 사이에 간격을 두면 줄무늬 경계가 흐릿하다** — 앞 색 끝과 뒤 색 시작을 같은 값으로 둔다 (하드 스톱).
- [ ] **SVG 를 그대로 주소에 넣으면 # 색 코드에서 깨진다** — encodeURIComponent 로 감싸 넣는다.
- [ ] **물방울 두 겹의 크기를 따로 바꾸면 무늬가 어긋난다** — 두 겹에 같은 background-size 를 한 번에 준다.
- [ ] **45° 줄무늬를 px 단위로 두면 폰에서 너무 굵거나 가늘다** — 상자 기준 단위(cqmin)로 두어 칸 크기에 따라 같이 바뀌게.

## 완성 기준 체크리스트
- [ ] 나뭇결 · 공책 · 줄무늬 · 집중선 · 모눈 · 물방울 여섯 칸이 그림 파일 없이 보인다
- [ ] 줄무늬가 흐르고 집중선이 돌고 물방울이 숨 쉰다
- [ ] 창 크기를 바꿔도 선이 흐려지지 않는다
- [ ] 네트워크 탭에 그림 요청이 없다

## 이 기술 정보
- id: `u62` · 분류: 2D · 화면 › CSS · 화면 틀 · 공통 · 난이도 쉬움 · 폰 부담 가벼움 (폰 OK) — 그림 파일 0개. 움직이는 무늬는 background-position 만 바꾸면 가볍다 — 무늬 식 자체를 매 프레임 새로 쓰는 집중선은 칸 몇 개까지만.
- 라이브 견본 (브라우저에서 직접 조작): https://ai-techstudio.web.app/#t/u62
- 쓰면 좋을 때: 단순한 반복 무늬 — 그림 파일을 받을 필요가 없다 / 크기가 바뀌어도 또렷해야 하는 틀 · 단추 바탕
- 쓰지 말 때: 사진 같은 질감(종이 섬유 · 얼룩) — 캔버스로 구운 그림이 낫다 / 그러데이션 수십 겹 — 큰 화면에서 매 프레임 바꾸면 그리기가 무거워진다

## 견본 실제 코드 (라이브 견본이 돌리는 코드 — three.js · TypeScript)
### u62 견본 항목 — `src/demos/demosDraw2d.ts:1308`
```ts
  u62: {
    kind: 'dom',
    caption: '그림 파일 없이 CSS 그러데이션 · 데이터 SVG 만으로 — 나뭇결 · 종이 · 줄무늬 · 집중선 · 모눈 · 물방울',
    make(box) {
      const grid = encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><path d='M20 0H0V20' fill='none' stroke='#7fb2e6' stroke-width='1'/></svg>`);
      const root = domRoot(
        box,
        'd2-pat',
        `.d2-pat{background:#151a3a;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr);gap:2cqmin;padding:2.5cqmin;box-sizing:border-box}
         .d2-pat .t{position:relative;border-radius:3cqmin;overflow:hidden;box-shadow:0 1cqmin 2cqmin #0006}
         .d2-pat .t span{position:absolute;left:50%;bottom:4%;transform:translateX(-50%);white-space:nowrap;font-size:5cqmin;font-weight:800;padding:.2em .7em;border-radius:99px;background:#000a;color:#fff}
         .d2-pat .wood{background:radial-gradient(ellipse 22% 7% at 32% 38%,#0000 45%,#5a301455 50%,#0000 58%),radial-gradient(ellipse 14% 5% at 72% 70%,#0000 40%,#5a301455 48%,#0000 56%),repeating-linear-gradient(1.5deg,#c8894f 0 1.6cqmin,#b6763e 1.6cqmin 2.2cqmin,#d69a62 2.2cqmin 3.6cqmin)}
         .d2-pat .paper{background:linear-gradient(90deg,#0000 16%,#ef7a7a 16% 17%,#0000 17%),repeating-linear-gradient(#fffdf4 0 4.6cqmin,#a9cdeb 4.6cqmin 5cqmin)}
         .d2-pat .stripe{background:repeating-linear-gradient(45deg,#ffd34d 0 4cqmin,#262626 4cqmin 8cqmin)}
         .d2-pat .burst{background:#ffe27a}
         .d2-pat .grid{background:#f6fbff url("data:image/svg+xml,${grid}")}
         .d2-pat .dots{background:radial-gradient(circle,#ff7fb0 28%,#0000 31%) 0 0/7cqmin 7cqmin,radial-gradient(circle,#ffd1e3 28%,#0000 31%) 3.5cqmin 3.5cqmin/7cqmin 7cqmin,#fff0f6}`,
        `<div class="t wood"><span>나뭇결</span></div><div class="t paper"><span>공책 종이</span></div><div class="t stripe"><span>줄무늬</span></div>
         <div class="t burst"><span>집중선</span></div><div class="t grid"><span>모눈 (데이터 SVG)</span></div><div class="t dots"><span>물방울</span></div>`,
      );
      const wood = q(root, '.wood');
      const stripe = q(root, '.stripe');
      const burst = q(root, '.burst');
      const grd = q(root, '.grid');
      const dots = q(root, '.dots');
      return {
        update(t) {
          stripe.style.backgroundPosition = `${(t * 30) % 1000}px 0`;
          const a = (t * 25) % 360;
          burst.style.background = `radial-gradient(circle at 50% 45%,#fff 0 12%,#fff0 34%),repeating-conic-gradient(from ${a}deg at 50% 45%,#ff9a3c 0 4deg,#ffe27a 4deg 10deg)`;
          wood.style.backgroundPosition = `0 0, 0 0, ${Math.sin(t * 0.5) * 20}px 0`;
          grd.style.backgroundPosition = `${(t * 8) % 20}px ${(t * 8) % 20}px`;
          const s = 1 + 0.08 * Math.sin(t * 2);
          dots.style.backgroundSize = `${7 * s}cqmin ${7 * s}cqmin`;
        },
      };
    },
  }
```

## 관련 기술
- 먼저 알면 좋은 기술: [테마 갈아입히기 (공통 틀 + CSS 변수 옷)](https://ai-techstudio.web.app/ai/t/u61.md) `u61`
- 다음에 해 볼 기술: [마스크 · 섞기 · 잘라내기](https://ai-techstudio.web.app/ai/t/u63.md) `u63` · [글자 테 · 그러데이션 글자](https://ai-techstudio.web.app/ai/t/u64.md) `u64`
- 참고 문서: [MDN — repeating-linear-gradient()](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/repeating-linear-gradient) · [MDN — repeating-conic-gradient()](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/repeating-conic-gradient)
