Built by developers, no designer involved (yet).
디자이너의 빈자리를 말이 아닌 인터랙션으로 보여준 네트워킹 데이 피칭 프로젝트입니다.
Caution
웹 키패드의 테마 입력은 Firebase를 통해 현재 사이트에 접속한 다른 브라우저에도 전달될 수 있습니다.
MoveBuild는 소프트웨어융합대학 1학년 개발자 두 명의 작업을 소개하기 위해 만든 포트폴리오입니다. 네트워킹 데이에서 디자인 팀을 만나야 했지만, 정작 우리 팀에는 디자이너가 없었습니다.
그래서 그 빈자리를 숨기는 대신 콘셉트로 삼았습니다. 처음 접속하면 색도, 둥근 모서리도, 세련된 장식도 거의 없는 평범한 포트폴리오가 나타납니다. 대신 디자이너에게 ESP32-S3, TFT 디스플레이, 4×4 키패드로 만든 장치를 건네 직접 버튼을 누르게 했습니다. 버튼을 누르는 즉시 배포된 사이트의 색·폰트·배경·효과가 바뀌고, 기기나 브라우저 종류와 관계없이 접속 중인 화면들이 함께 반응합니다.
네트워킹 데이에서는 디자이너들에게 이 장치를 직접 눌러보게 하며 사이트를 시연했습니다.
사이트의 초기 화면은 의도적으로 비어 보이게 설계했습니다. 디자인이 없는 상태와 인터랙션 이후의 대비가 프로젝트의 핵심입니다.
키패드 입력 하나가 Firebase Realtime Database에 기록되고, 그 값을 구독하는 모든 브라우저가 즉시 같은 변화를 적용합니다.
flowchart LR
K["4×4 키패드"] -->|"버튼 1–16"| E["ESP32-S3<br/>스캔 · 디바운스"]
E --> S["TFT · 부저<br/>상태 피드백"]
E -->|"HTTPS PUT<br/>{ button, nonce }"| F[("Firebase RTDB<br/>demo/lastButton")]
V["웹 키패드<br/>?themeControls"] --> F
F -->|"onValue"| B1["노트북 브라우저<br/>ThemeController"]
F -->|"onValue"| B2["태블릿 브라우저<br/>ThemeController"]
F -->|"onValue"| B3["모바일 브라우저<br/>ThemeController"]
B1 --> T1["색 · 폰트 · WebGL · 효과"]
B2 --> T2["색 · 폰트 · WebGL · 효과"]
B3 --> T3["색 · 폰트 · WebGL · 효과"]
Firebase는 순간 신호만 전달하는 대신 마지막 버튼 상태를 보관합니다. 따라서 늦게 접속한 브라우저도 현재 상태를 바로 받아 같은 화면으로 시작합니다.
| 1 | 2 | 3 | 4 |
|---|---|---|---|
| 기본 | 먹빛 | 크림 | 네온 |
| 5 | 6 | 7 | 8 |
| ASCII | 그라데이션 | 도면 | 터미널 |
| 9 | 10 | 11 | 12 |
| 궁서체 | 도스체 | 임팩트 | 코믹 |
| 13 | 14 | 15 | 16 |
| 이모지 | 화면 흔들기 | 비밀 화면 | 전체 리셋 |
| 영역 | 기술 | 역할 |
|---|---|---|
| Frontend | Astro 5, React 18, TypeScript, Tailwind CSS, MDX | 정적 포트폴리오와 React 아일랜드 구성 |
| Interaction | Motion, Lenis, Three.js, React Three Fiber | 모달·스크롤·WebGL 배경과 시각 효과 |
| Realtime | Firebase Realtime Database, Firebase Web SDK | 버튼 상태 저장과 모든 브라우저 실시간 동기화 |
| Firmware | C++, Arduino, PlatformIO | 키패드 스캔, 상태 표시, Firebase REST 요청 |
| Hardware | Adafruit Feather ESP32-S3 TFT, 4×4 matrix keypad | 휴대 가능한 물리 인터페이스 |
| Deployment | Vercel | Astro 정적 사이트 배포 |
- Astro Content Collection과 MDX로 프로젝트 콘텐츠를 관리합니다.
- React 카드와 모달이 이미지·영상 타임라인을 렌더링합니다.
ThemeController가 Firebase의 버튼 상태를 구독해 CSS data attribute, 폰트, WebGL 배경과 이스터에그를 적용합니다.?themeControls쿼리로 실물 장치 없이도 16버튼 패널을 열 수 있습니다.
demo/lastButton한 경로만 데모 입력에 사용합니다.- 현재 페이로드는
{ "button": 1..16, "nonce": "..." }형태입니다. - Database Rules는 버튼 범위와 payload 형태를 검증하고, 나머지 경로의 읽기·쓰기는 차단합니다.
- 4×4 매트릭스 키패드를 직접 스캔하고 25ms 디바운스를 적용합니다.
- 입력 성공 시 LED와 부저로 피드백하고 Firebase REST endpoint에 HTTPS PUT을 보냅니다.
- TFT에 Wi-Fi 연결, IP, 마지막 버튼, HTTP 응답, 전송 횟수와 배터리 상태를 표시합니다.
- Adafruit Feather ESP32-S3 TFT
- 4×4 matrix keypad
- Li-Po battery와 온보드 배터리 모니터
- Piezo buzzer
- 투명 휴대용 케이스와 점퍼 배선
Node.js 18.20.8 이상이 필요합니다.
npm install
cp .env.example .env
npm run dev.env에 Firebase Web App 설정을 입력합니다. 프로덕션 빌드는 다음 명령으로 확인할 수 있습니다.
npm run buildcp firmware/include/secrets.example.h firmware/include/secrets.hfirmware/include/secrets.h에 Wi-Fi와 Firebase REST endpoint를 설정합니다. 이 파일은 Git에서 추적하지 않습니다.
pio run --project-dir firmware
pio run --project-dir firmware --target upload
pio device monitor --project-dir firmwareMoveBuild는 네트워킹 데이에서 무채색 포트폴리오와 직접 만든 하드웨어를 함께 시연했습니다. 현장에서 디자이너들이 키패드를 눌러 실시간으로 바뀌는 사이트를 확인했고, 이후 디자인 팀과 매칭됐습니다.

