diff --git a/src/pages/saju/views/match.mobile.jsx b/src/pages/saju/views/match.mobile.jsx
new file mode 100644
index 0000000..2188a54
--- /dev/null
+++ b/src/pages/saju/views/match.mobile.jsx
@@ -0,0 +1,108 @@
+import React from 'react';
+import TopRibbon from '../_shell/TopRibbon';
+import TitleBlock from '../_shell/TitleBlock';
+import Mascot from '../_shell/Mascot';
+import MascotBubble from '../_shell/MascotBubble';
+import OrnateFrame from '../_shell/OrnateFrame';
+import PrimaryButton from '../_shell/PrimaryButton';
+import InputRow from '../_shell/InputRow';
+import { IconHeart, IconSparkle } from '../_shell/Icons';
+
+const inputStyle = {
+ flex: 1, padding: '8px 10px', border: '1px solid rgba(31,42,68,0.12)',
+ borderRadius: 8, background: '#FBF7EF', fontSize: 13, color: '#1F2A44',
+ fontFamily: 'inherit',
+};
+
+function pad(n) { return String(n).padStart(2, '0'); }
+function dateValue(p) {
+ if (!p.year || !p.month || !p.day) return '';
+ return `${p.year}-${pad(p.month)}-${pad(p.day)}`;
+}
+function timeValue(p) {
+ if (p.hour === '' || p.hour == null) return '';
+ return `${pad(p.hour)}:00`;
+}
+function onDate(p, set, e) {
+ const v = e.target.value;
+ if (!v) return set({ ...p, year: '', month: '', day: '' });
+ const [y, m, d] = v.split('-');
+ set({ ...p, year: parseInt(y, 10), month: parseInt(m, 10), day: parseInt(d, 10) });
+}
+function onTime(p, set, e) {
+ const v = e.target.value;
+ if (!v) return set({ ...p, hour: null });
+ const [h] = v.split(':');
+ set({ ...p, hour: parseInt(h, 10) });
+}
+
+function PersonForm({ label, person, onChange }) {
+ return (
+
+ {label}
+
+ onChange({ ...person, name: e.target.value })}
+ placeholder="홍길동" style={inputStyle} />
+
+
+ onDate(person, onChange, e)} style={inputStyle} />
+
+
+ onTime(person, onChange, e)} style={inputStyle} />
+
+
+
+
+
+
+
+
+ );
+}
+
+export default function MatchMobile({ personA, personB, onChangeA, onChangeB, onSubmit, loading, error }) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}