들어가며

먼저 고백하자면, 이 블로그 글도 AI가 썼다.

“블로그 만든 과정 글로 써줘”라고 했더니 진짜 써줌. 심지어 “제목 좀 짜치게”라고 했더니 빙수 얘기까지 넣어줌.

근데 내용은 진짜다. 실제 git 커밋 내역을 기반으로 2025년 12월 6일부터 7일까지 이틀간 Claude Code와 Speckit으로 이 블로그를 만든 과정을 기록한다.


타임라인: 실제 커밋 내역 기반

Day 1 (2025-12-06)

14:xx - Speckit 초기 설정

4376539 스팩킷 초기 설정

Next.js로 시작했다가 Astro로 갈아탔다가 Rust 백엔드까지 시도하다가, 결국 Speckit을 도입하기로 결정. 이전 커밋들을 보면 “테일윈드 너무 어려움”, “블로그 환경이 마음에 안들어 다시 설정” 같은 방황의 흔적이 있다.

15:xx - 헌법(Constitution) 정의

cdba956 스팩킷 헌법 정의 + 우선 프론트엔드만 있는 구조로 변경

Speckit의 핵심인 헌법을 작성했다. AI에게 “이 규칙 따라”라고 가르치는 문서다.

실제 작성한 헌법 일부:

# SCLOG Constitution

## VI. Design System

- **브랜드 표기**: "SCLOG"는 반드시 대문자로 표기한다
- **테마**: 라이트 모드 기본, 다크 모드 스위칭 지원
- **컬러**: 브랜드 컬러 `rgb(233, 172, 159)` (코랄/피치 톤)
- **타이포그래피**: Roboto (영문), Noto Sans KR (한글)

이후 AI가 생성하는 모든 코드에 이 규칙이 자동 적용됐다.

16:xx - MDX 블로그 시스템 구현 (Feature 001)

be0244e MDX 기반 블로그 포스트 시스템 구현

/speckit.specify로 스펙 작성 → /speckit.plan으로 계획 → /speckit.tasks로 태스크 분해 → /speckit.implement로 구현.

실제 작성한 스펙 (specs/001-mdx-blog-post/spec.md):

### User Story 1 - 블로그 글 작성 및 발행 (Priority: P1)

**Acceptance Scenarios**:

1. **Given** 작성자가 MDX 파일을 콘텐츠 디렉토리에 생성했을 때,
   **When** 사이트를 빌드하면,
   **Then** 해당 글이 고유 URL로 접근 가능한 페이지가 된다

17:xx - 디자인 시스템 적용 (Feature 002)

d993b87 Update design system and improve blog layout
179abc9 디자인 시스템 적용: CSS 토큰 기반 라이트/다크 테마 구현

실제 작성한 스펙 (specs/002-design-system/spec.md):

### User Story 2 - 다크 모드 스위칭 (Priority: P1)

**Acceptance Scenarios**:

1. **Given** 라이트 모드 상태,
   **When** 테마 토글 버튼을 클릭하면,
   **Then** 다크 모드로 전환된다

CSS 변수 기반 테마 시스템, FOUC 방지 스크립트, localStorage 테마 저장까지 AI가 알아서 구현했다.

9df0734 SCLog => SCLOG

로고가 소문자로 생성돼서 “SCLOG로 해”라고 했더니 수정해줌.


Day 2 (2025-12-07)

09:xx - 포트폴리오 홈페이지 (Feature 003)

9db0108 포트폴리오 홈페이지 기능 추가 및 데이터 모델 정의

실제 작성한 스펙 (specs/003-portfolio-home/spec.md):

### User Story 1 - 첫인상 확인 (Priority: P1)

**Why this priority**: 첫인상이 가장 중요하며,
방문자가 3초 내에 "이 사람이 누구인지"를 이해해야 이탈하지 않음

**Acceptance Scenarios**:

1. **Given** 방문자가 SCLOG 홈페이지에 접속했을 때,
   **When** 페이지가 로드되면,
   **Then** 프로필 사진/아바타, 이름, 한 줄 소개가 화면 상단에 표시된다

14:xx - 읽기 경험 개선 (Feature 004)

661c1d5 feat: 블로그 읽기 경험 개선 기능 추가
38d05b6 헤더 sticky 기능 추가

목차(TOC), 코드 복사 버튼, 읽기 진행률 바, 맨 위로 버튼을 한 번에 추가했다.

실제 작성한 스펙 (specs/004-reading-experience/spec.md):

### User Story 2 - 목차로 빠른 탐색 (Priority: P2)

**Acceptance Scenarios**:

1. **Given** h2, h3 헤딩이 포함된 블로그 글,
   **When** 독자가 페이지를 열면,
   **Then** 화면 우측에 헤딩 목록이 표시된다

2. **Given** 독자가 글을 스크롤하며 읽는 중,
   **When** 새로운 섹션에 진입하면,
   **Then** 목차에서 해당 섹션이 시각적으로 강조된다

AI가 Intersection Observer API를 사용해서 현재 섹션 감지 기능을 구현했다:

const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        document.querySelectorAll('.toc-link').forEach((link) => {
          link.classList.remove('active');
        });
        const activeLink = document.querySelector(
          `.toc-link[href="#${entry.target.id}"]`
        );
        activeLink?.classList.add('active');
      }
    });
  },
  { rootMargin: '-80px 0px -80% 0px' }
);

17:xx - 프로필 호버 애니메이션 (Feature 005)

5a1ca3a feat: 프로필 사진 3D 동전 뒤집기 hover 애니메이션 추가

“프로필 사진 scwon_pt에 마우스 올리면 좀 멋있는 애니메이션 막 돌아가면서 scwon_dot로 바뀌면 좋겠어”라고 했더니 스펙부터 작성해줌.

실제 작성한 스펙 (specs/005-profile-hover/spec.md):

### User Story 1 - 프로필 사진 Hover 시 이미지 전환 (Priority: P1)

**Acceptance Scenarios**:

1. **Given** 홈페이지가 로드된 상태,
   **When** 프로필 사진 위에 마우스를 올리면,
   **Then** 회전 애니메이션이 실행되며 scwon_dot.png 이미지로 전환된다

### Edge Cases

- 애니메이션 진행 중 마우스를 빠르게 올렸다 뗄 경우: 애니메이션이 부드럽게 전환되어야 함
- JavaScript 비활성화 시: 정적 프로필 사진만 표시 (graceful degradation)
- 접근성 고려: 애니메이션으로 인해 콘텐츠 인식에 방해가 되지 않아야 함

처음에는 단순 회전(rotate)으로 구현됐는데 “3D로 동전처럼 회전했으면 좋겠어!”라고 했더니:

.profile-avatar {
  perspective: 1000px;
}

.avatar-default,
.avatar-alternate {
  backface-visibility: hidden;
  transition: transform 0.6s ease;
}

.avatar-alternate {
  transform: rotateY(180deg);
}

.profile-avatar:hover .avatar-default {
  transform: rotateY(180deg);
}

.profile-avatar:hover .avatar-alternate {
  transform: rotateY(360deg);
}

perspective, backface-visibility 같은 3D CSS 속성을 내가 시킨 적 없다. AI가 3D 효과에 필요한 속성을 알아서 적용했다.

접근성도 자동 적용됐다:

@media (prefers-reduced-motion: reduce) {
  .avatar-default,
  .avatar-alternate {
    transition: opacity 0.1s ease;
    backface-visibility: visible;
  }
  /* 회전 대신 페이드 처리 */
}

이거 내가 요청 안 했다. 헌법에 “접근성 중요”라고 써놨더니 자동 적용됨.


Speckit 워크플로우

5개 기능을 모두 같은 패턴으로 개발했다:

단계명령어결과물
1/speckit.specifyspec.md (요구사항 정의)
2/speckit.planplan.md, research.md (기술 설계)
3/speckit.taskstasks.md (태스크 체크리스트)
4/speckit.implement실제 코드

스펙의 핵심: Given-When-Then

**Given** 사용자가 처음 블로그에 접속,
**When** 페이지가 로드되면,
**Then** 흰색 배경에 어두운 텍스트의 라이트 모드로 표시된다

이 형식이 중요한 이유:

  • 테스트 가능한 요구사항
  • AI가 “무엇을 구현해야 하는지” 명확히 이해
  • Edge case까지 사전 정의

실제로 느낀 점

좋았던 점

속도: 5개 기능을 이틀만에 구현. 스펙 작성 → 구현까지 기능당 평균 1-2시간.

일관성: 헌법에 정의한 디자인 토큰, 컬러, 폰트가 모든 컴포넌트에 일관되게 적용됨.

학습: AI가 짠 코드 보면서 Intersection Observer, CSS 3D transforms 같은 기술 배움.

한계

컨텍스트 유실: 대화가 길어지면 앞에서 한 얘기를 까먹음. 그래서 스펙 문서가 중요함.

반복 수정: “SCLOG로 해”, “3D로 해” 같이 추가 요청이 필요할 때가 있음.


결론

커밋 내역이 증명하듯이, 이틀 만에:

  • MDX 블로그 시스템
  • 라이트/다크 테마
  • 포트폴리오 홈페이지
  • 읽기 경험 개선 (목차, 코드 복사, 진행률 바)
  • 3D 호버 애니메이션

전부 구현했다. 타이핑은 AI가 했고, 나는 뭘 만들지 결정하고 스펙 검토하는 역할을 했다.


참고 자료

이 블로그의 실제 스펙 문서들 (GitHub에서 확인 가능):

  • specs/001-mdx-blog-post/ - MDX 블로그 시스템
  • specs/002-design-system/ - 디자인 시스템
  • specs/003-portfolio-home/ - 포트폴리오 홈페이지
  • specs/004-reading-experience/ - 읽기 경험 개선
  • specs/005-profile-hover/ - 프로필 호버 애니메이션
  • .specify/memory/constitution.md - 프로젝트 헌법