맘편한(CareCode) 서비스 소개 사이트입니다. 앱(CareCode_FE)과 API(CareCode_Interface)와는 별개로 배포합니다.
앱은 로그인한 사용자가 쓰는 모바일 화면이고, 이 사이트는 아직 가입하지 않은 사람이 보는 데스크톱 중심 문서입니다. 레이아웃도 배포 주기도 다릅니다.
앱 안에 두면 소개 문구 한 줄 고치는 데 앱 전체를 다시 배포해야 하고, 앱의 모바일 셸과 세션·푸시 초기화를 경로마다 우회해야 합니다.
npm install
npm run dev # http://localhost:3000
npm run build # out/ 에 정적 파일 생성서버가 할 일이 없어 output: 'export' 로 정적 출력만 만듭니다. out/ 를 그대로 어디든
올리면 됩니다.
| 경로 | 내용 |
|---|---|
/ |
여섯 해. 스크롤이 아이의 개월 수(0 → 72)이고, 뒤의 3D 동네가 그에 맞춰 자랍니다 |
/benefits |
자격 판정, 수령액 계산, 금액 신뢰도 |
/facilities |
정원 관측, 빈자리 알림, 대기 기간 통계 |
/data |
출처 네 곳과 아는 것 / 모르는 것 대조 |
/trust |
수집 항목, 민감정보 처리, 정보주체 권리 |
방향은 앱과 같은 제품입니다. 소개 사이트에서 본 것과 앱을 열었을 때의 인상이 같아야 합니다.
색·서체·모서리는 CareCode_FE 의
src/styles/globals.css(@theme) 를 그대로 옮겼고, 로고와 파비콘도 앱 아이콘(public/icon.svg)을 씁니다.
값을 바꿀 때는 앱 쪽이 원본입니다.
| 토큰 | 값 | 쓰임 |
|---|---|---|
--bg |
#FFFFFF |
바탕 |
--surface |
#FAFAFA (gray-50) |
카드 · 표 머리 · 막대 바탕 |
--fg / --fg-soft |
#212121 / #616161 |
글자 |
--brand |
#4FBE27 (green-600) |
유효 · 현재. 앱 버튼과 같은 색 |
--brand-deep |
#007300 (green-900) |
초록 글자. 흰 바탕 본문 크기에서 4.5:1 을 넘기려면 900 까지 내려야 합니다 |
--alert / --alert-deep |
#E55656 / #B83A3A |
마감 · 경고. 앱의 red 는 면용이라 글자는 한 단계 짙게 씁니다 |
--muted |
#9E9E9E |
이미 지나간 것 · 모르는 것 |
--line |
#EEEEEE |
구분선 |
표제는 Pretendard 700, 버튼은 앱의 Button 과 같은 둥근 12px · 600 굵기 · green 600→700 입니다.
숫자는 서체를 바꾸지 않고 tabular-nums 로 자릿수만 맞춥니다.
처음에는 "육아수첩 · 관공서 기록부" 방향(모눈 종이, 도장, 얇은 표제)이었습니다. 3D 동네와 두 시각 언어가 부딪히고, 앱과 인상이 달라 바꿨습니다. 토큰 이름도
--paper·--ink·--seal에서 의미 이름으로 옮겼습니다.
홈 전체가 아이의 첫 여섯 해입니다. 스크롤 진행이 곧 개월 수이고, 그 값 하나가 뒤에 깔린 3D 동네의 세 가지를 동시에 정합니다.
- 계절 — 4월생으로 가정합니다. 벚꽃, 초록, 은행잎, 눈이 차례로 지나갑니다
- 성장 — 유모차에서 걸음마로, 마지막에는 책가방을 멥니다. 태어난 봄에 심은 벚나무도 함께 자랍니다
- 시선 — 그 시기에 부모가 드나드는 건물(어린이집 · 소아과 · 행정복지센터)로 카메라가 갑니다. 건물 위의 알림 표식은 그 시기에 살아 있는 알림만큼 떠오르고, 부모급여가 끝나기 직전(20–24개월)에는 경고 빨강으로 바뀝니다
4월생으로 고른 이유는 동네가 보이는 구간(출생 · 6 · 18 · 72개월)이 봄과 가을에 앉기 때문입니다. 3월생이면 전부 초봄이라 계절이 흐르는 게 안 보입니다.
구간 사이에는 월령 타임라인(12개월 구간)이 있습니다. 스크롤이 개월 수를 정하는 페이지에서
여기서만은 부모가 직접 축을 옮깁니다. 밴드 구성은 실제 정책 데이터 모델(대상 연령 상·하한, 지급액,
소급 개월)을 따랐고, 금액을 모르는 정책은 미상 으로 둡니다.
구조 문법은 JellySafe 소개 사이트(스크롤 = 하루)에서 가져왔고, 색은 3D 동네까지 앱 팔레트(흰 벽 · green · yellow · blue)로 칠했습니다.
구간은 실제로 그 개월 수에 일어나는 일이 있을 때만 둡니다 — 출생 · 1개월(출생신고) · 6개월(어린이집 대기) · 12개월(첫만남이용권 종료) · 18개월(접종) · 24개월(부모급여 종료) · 72개월(취학 전). 개월 수와 관계없는 이야기(모르는 것 · 부모의 기록 · 개인정보)에 "48개월" 같은 배지를 붙이면 약속이 억지가 되어, 마지막 구간의 원칙 카드로 모았습니다.
src/features/
├── grow/ 스크롤 엔진(GrowScene) · 구간 목록(stages.ts)
├── stations/ 구간 하나 = 파일 하나. 전부 서버 컴포넌트
└── town/ 3D 동네(three.js). GrowScene 이 동적 import 한다
구간 목록은 두 곳에 있고 순서가 같아야 합니다 — src/app/page.tsx 와
src/features/grow/stages.ts. 레일 눈금이 stages.ts 에서 나오고, 개월 수의 닻은 페이지의
[data-month] 에서 읽습니다. 개발 모드에서는 둘이 어긋나면 콘솔에 경고가 뜹니다.
개월 수는 문서 진행도가 아니라 구간 위치로 정합니다. 각 구간 머리가 화면 가운데에 온 순간을 닻으로 삼아 사이를 잇습니다. 구간 길이가 제각각이라 진행도를 선형으로 나누면 "18개월" 배지를 읽는 순간 장면은 15개월이 됩니다.
스크롤 경로에 React 상태를 두지 않습니다. GrowScene 은 초당 60회 도는 경로라 값은 ref 로 직접 씁니다.
3D 는 쓰지 않을 사용자에게 받게 하지 않습니다. 동작 줄이기(prefers-reduced-motion),
WebGL2 미지원, GPU 가속 없는 소프트웨어 렌더러(SwiftShader · llvmpipe)면 three.js 청크를
import 하기 전에 판정하고 정적 배경을 띄웁니다. 소프트웨어 렌더러에서는 이 장면이 초당 몇
프레임이라 메인 스레드를 잡아먹고 스크롤까지 끊깁니다 — CI 의 헤드리스 Chrome 에서 페이지 로드가
60초를 넘긴 것도 이 때문이었습니다. 카피는 전부 DOM 이라 3D 가 없어도 페이지는 온전합니다.
GPU 없는 환경에서 장면을 확인만 하려면 주소에 ?town=force 를 붙입니다.
Windows 에서 "애니메이션 효과"를 꺼 두면 브라우저가 동작 줄이기를 보고해 3D 대신 정적 배경이 뜹니다. 고장이 아닙니다.
프레이밍은 재서 맞춥니다. 콘솔에서:
carecodeTown.probe() // { home: [67, 32], daycare: [80, 42], … } ← 화면 좌표 %
carecodeTown.stats() // { fps, jsMs, drawCalls, triangles, … }가족이 설 곳 · 카메라가 볼 곳 · 거리는 town-scene.ts 의 BEATS 한 표에, 계절은 SEASONS
한 표에 있습니다. 건물 벽은 면마다 재질을 나누지 않고 벽/옥상 두 번에 그립니다(wallBox) —
BoxGeometry 에 재질 배열을 주면 상자 하나에 드로우콜이 여섯 번 듭니다.
main 에 들어가면 GitHub Actions 가 빌드해 GitHub Pages 로 올립니다. PR 에서는 배포하지 않고
빌드·타입·린트와 화면 검증만 돕니다.
배포가 끝나면 페이지 5개와 sitemap.xml·robots.txt 가 실제로 200 인지, 그리고 CSS 가 붙는지
확인합니다. 파일은 올라갔는데 basePath 가 어긋나 스타일만 404 인 경우가 흔해서입니다.
npm run verify # 로컬에서 같은 검사 (out/ 을 먼저 서빙해야 합니다)사이트에 적힌 수집량은 src/content/figures.ts 한 곳에 있고 MEASURED_ON 과 함께 둡니다.
백엔드가 매주 공공데이터를 새로 받아 오므로 값이 낡습니다.
자동으로 매주 화요일 새벽에 백엔드 공개 통계에서 받아 와 PR 을 엽니다.
| 값 | 출처 |
|---|---|
| 어린이집 · 유치원 | GET /facilities/statistics 의 typeDistribution |
| 소아청소년과 | GET /health/hospitals/statistics |
| 정부지원 서비스 | GET /policies/statistics |
넷 중 하나라도 못 받으면 아무것도 바꾸지 않습니다. 일부만 갱신하고 날짜를 새로 찍으면 낡은 값에 새 날짜가 붙어 거짓말이 됩니다.
동작하려면 저장소 변수 STATS_API_BASE 에 백엔드 공개 주소가 있어야 합니다. 없으면 워크플로가
조용히 건너뜁니다 — 백엔드가 공개되기 전에 실패로 울리면 알림이 무의미해지기 때문입니다.
STATS_API_BASE=https://api.example.com npm run refresh # 로컬에서 직접PR 에서 사람이 볼 것은 하나입니다 — 숫자가 갑자기 크게 줄지 않았는지. 공공데이터 수집이 부분 실패하면 값이 뚝 떨어질 수 있습니다.
근거 없는 숫자는 쓰지 않습니다. /data 에 무엇을 모르는지 적어 둔 것도 같은 이유입니다.
어린이집 자리와 지원금은 부모가 실제 결정을 내리는 정보라, 그럴듯한 추정치를 믿고 다른
선택지를 포기한 사람이 손해를 봅니다.
수치를 고칠 때는 CareCode_Interface 문서의 실측값을 근거로 삼으세요.
Next.js 15 (App Router, 정적 출력) · React 19 · Tailwind CSS v4 · TypeScript · three.js (홈의 3D 동네, 지연 로드)
이 프로젝트의 소스 코드는 MIT 라이선스를 따릅니다. Copyright (c) 2026 CareCode. 전문은 LICENSE 파일에 있습니다.