diff --git a/src/main/resources/static/css/web/makeReservation.css b/src/main/resources/static/css/web/makeReservation.css
new file mode 100644
index 0000000..b2ceb7b
--- /dev/null
+++ b/src/main/resources/static/css/web/makeReservation.css
@@ -0,0 +1,470 @@
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Noto Sans KR', sans-serif;
+ margin: 0;
+ background: #fafafa;
+ color: #222;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+/* Main container */
+.reservation-container {
+ display: flex;
+ max-width: 1280px !important;
+ margin: 0 auto;
+ gap: 20px;
+ height: 100%;
+ flex: 1;
+ padding: 20px 0;
+ margin-top: 65px;
+}
+
+.box {
+ background: #fff;
+ border-radius: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+ padding: 24px 16px;
+ flex: 1 1 0;
+ min-width: 260px;
+ display: flex;
+ flex-direction: column;
+ height: fit-content;
+ min-height: 600px;
+}
+
+.step-title {
+ color: #b23c3c;
+ font-weight: 700;
+ font-size: 1.1em;
+ margin-bottom: 12px;
+ letter-spacing: 0.02em;
+ transition: color 0.3s ease;
+}
+
+.step-title.completed {
+ color: #008000 !important;
+}
+
+/* Service section */
+.service-list {
+ flex: 1;
+ margin-bottom: 24px;
+}
+
+.service-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 1.1em;
+ margin-bottom: 10px;
+}
+
+.service-item .del {
+ cursor: pointer;
+ color: #b23c3c;
+ margin-left: 8px;
+ font-size: 1.2em;
+ transition: color 0.3s ease, opacity 0.3s ease;
+}
+
+.service-item .del:hover {
+ color: #ff0000;
+}
+
+.service-item .del.disabled {
+ color: #ccc;
+ cursor: not-allowed;
+ opacity: 0.5;
+}
+
+.service-item .del.disabled:hover {
+ color: #ccc;
+}
+
+.service-item .price {
+ font-weight: bold;
+ color: #b23c3c;
+}
+
+/* Service count indicator */
+.service-count-info {
+ font-size: 0.85em;
+ color: #888;
+ margin-bottom: 8px;
+ text-align: center;
+ padding: 4px 8px;
+ background: #f8f9fa;
+ border-radius: 4px;
+}
+
+.service-count-info.single {
+ color: #ff8c00;
+ background: #fff3e0;
+ border: 1px solid #ffcc80;
+}
+
+.total {
+ border-top: 1px solid #eee;
+ margin-top: auto;
+ padding-top: 16px;
+ display: flex;
+ justify-content: space-between;
+ font-size: 1.1em;
+ font-weight: bold;
+}
+
+.total .price {
+ color: #b23c3c;
+}
+
+.total small {
+ font-weight: normal;
+ color: #888;
+ font-size: 0.9em;
+ margin-right: 8px;
+}
+
+/* Calendar section */
+.calendar-box {
+ margin-bottom: 20px;
+}
+
+.calendar-header {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 8px;
+}
+
+.calendar-header button {
+ background: none;
+ border: none;
+ font-size: 1.2em;
+ cursor: pointer;
+ color: #b23c3c;
+ padding: 0 6px;
+}
+
+.calendar-table {
+ width: 100%;
+ border-collapse: collapse;
+ text-align: center;
+ margin-bottom: 8px;
+}
+
+.calendar-table th,
+.calendar-table td {
+ width: 2em;
+ height: 2em;
+ padding: 2px;
+ font-size: 1em;
+ border-radius: 50%;
+ cursor: pointer;
+ transition: background 0.15s;
+}
+
+.calendar-table th {
+ color: #b23c3c;
+ font-weight: 500;
+ background: none;
+}
+
+.calendar-table td.selected {
+ background: #b23c3c;
+ color: #fff;
+}
+
+.calendar-table td.today {
+ border: 1.5px solid #b23c3c;
+}
+
+.calendar-table td:not(.selected):hover {
+ background: #f5eaea;
+}
+
+.calendar-table td.disabled {
+ color: #ccc;
+ pointer-events: none;
+ background: none;
+}
+
+/* Time slots */
+.time-slots {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 12px;
+}
+
+.time-btn {
+ flex: 1 0 30%;
+ min-width: 80px;
+ padding: 8px 0;
+ border: 1px solid #b23c3c;
+ border-radius: 20px;
+ background: #fff;
+ color: #b23c3c;
+ font-size: 1em;
+ cursor: pointer;
+ transition: background 0.15s, color 0.15s;
+}
+
+.time-btn.selected,
+.time-btn:active {
+ background: #b23c3c;
+ color: #fff;
+}
+
+.time-btn:disabled {
+ color: #ccc;
+ border-color: #eee;
+ background: #f5f5f5;
+ cursor: not-allowed;
+}
+
+.person-count {
+ margin-top: 12px;
+ font-size: 0.98em;
+ color: #888;
+}
+
+/* Form section */
+.form-group {
+ margin-bottom: 16px;
+}
+
+.form-group label {
+ display: block;
+ margin-bottom: 4px;
+ font-weight: 500;
+}
+
+.form-group input,
+.form-group textarea {
+ width: 100%;
+ padding: 8px 10px;
+ border: 1px solid #ddd;
+ border-radius: 6px;
+ font-size: 1em;
+ resize: none;
+ transition: border-color 0.3s ease;
+}
+
+.form-group textarea {
+ min-height: 60px;
+}
+
+.checkbox-group {
+ display: flex;
+ align-items: center;
+ margin-bottom: 18px;
+ font-size: 0.98em;
+}
+
+.checkbox-group input[type="checkbox"] {
+ margin-right: 8px;
+ accent-color: #b23c3c;
+}
+
+.submit-btn {
+ width: 100%;
+ padding: 14px 0;
+ background: #ddd;
+ color: #888;
+ border: none;
+ border-radius: 8px;
+ font-size: 1.1em;
+ font-weight: bold;
+ cursor: not-allowed;
+ transition: all 0.3s ease;
+}
+
+.submit-btn.step-progress {
+ background: linear-gradient(45deg, #ddd, #bbb);
+ color: #666;
+ font-size: 0.95em;
+}
+
+.submit-btn.ready {
+ background: #b23c3c;
+ color: #fff;
+ cursor: pointer;
+ animation: pulse 2s infinite;
+}
+
+@keyframes pulse {
+ 0% { transform: scale(1); }
+ 50% { transform: scale(1.02); }
+ 100% { transform: scale(1); }
+}
+
+/* Phone message styles (common.js PhoneValidator용) */
+.phone-message {
+ font-size: 12px;
+ margin-top: 5px;
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-weight: 500;
+ transition: all 0.3s ease;
+}
+
+.phone-message.error {
+ color: #ff0000;
+ background-color: #ffebee;
+ border: 1px solid #ffcdd2;
+}
+
+.phone-message.warning {
+ color: #ff8c00;
+ background-color: #fff3e0;
+ border: 1px solid #ffcc80;
+}
+
+.phone-message.success {
+ color: #008000;
+ background-color: #f1f8e9;
+ border: 1px solid #c8e6c9;
+}
+
+.phone-message.info {
+ color: #2196f3;
+ background-color: #e3f2fd;
+ border: 1px solid #90caf9;
+}
+
+/* Birth date message styles */
+.birth-date-message {
+ font-size: 12px;
+ margin-top: 5px;
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-weight: 500;
+ transition: all 0.3s ease;
+}
+
+.birth-date-message.error {
+ color: #ff0000;
+ background-color: #ffebee;
+ border: 1px solid #ffcdd2;
+}
+
+.birth-date-message.warning {
+ color: #ff8c00;
+ background-color: #fff3e0;
+ border: 1px solid #ffcc80;
+}
+
+.birth-date-message.success {
+ color: #008000;
+ background-color: #f1f8e9;
+ border: 1px solid #c8e6c9;
+}
+
+.birth-date-message.info {
+ color: #2196f3;
+ background-color: #e3f2fd;
+ border: 1px solid #90caf9;
+}
+
+/* Disabled calendar cell - 강화된 스타일 */
+.calendar-table td.disabled {
+ color: #ccc;
+ cursor: not-allowed;
+ pointer-events: none;
+ background: none !important;
+}
+
+.calendar-table td.disabled:hover {
+ background: none !important;
+ cursor: not-allowed !important;
+}
+
+/* Responsive Design */
+@media (max-width: 1199.98px) {
+ .reservation-container {
+ max-width: 960px !important;
+ gap: 16px;
+ padding: 20px 15px;
+ }
+
+ .box {
+ padding: 20px 14px;
+ }
+}
+
+@media (max-width: 991.98px) {
+ .reservation-container {
+ max-width: 720px !important;
+ flex-direction: column;
+ gap: 24px;
+ height: auto;
+ padding: 20px 15px;
+ }
+
+ .box {
+ min-height: unset;
+ min-width: unset;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .reservation-container {
+ max-width: 540px !important;
+ padding: 15px;
+ gap: 20px;
+ }
+
+ .box {
+ padding: 16px 12px;
+ }
+
+ .calendar-table th,
+ .calendar-table td {
+ width: 1.8em;
+ height: 1.8em;
+ }
+
+ .time-btn {
+ min-width: 70px;
+ font-size: 0.95em;
+ }
+}
+
+@media (max-width: 575.98px) {
+ .reservation-container {
+ max-width: 100% !important;
+ padding: 10px;
+ gap: 16px;
+ }
+
+ .box {
+ padding: 16px 8px;
+ }
+
+ .calendar-table th,
+ .calendar-table td {
+ width: 1.5em;
+ height: 1.5em;
+ font-size: 0.9em;
+ }
+
+ .time-btn {
+ min-width: 60px;
+ font-size: 0.9em;
+ padding: 6px 0;
+ }
+
+ .step-title {
+ font-size: 1em;
+ }
+
+ .service-item {
+ font-size: 1em;
+ }
+}
diff --git a/src/main/resources/static/js/makeReservation.js b/src/main/resources/static/js/makeReservation.js
new file mode 100644
index 0000000..19ae860
--- /dev/null
+++ b/src/main/resources/static/js/makeReservation.js
@@ -0,0 +1,598 @@
+// 휴일(완전 휴무) 설정
+const disabledSpecificDates = [
+ '2025-12-25', // 크리스마스
+ '2026-01-01' // 신정
+];
+
+// 단축 진료일 (15:30까지, 점심시간 없음)
+const shortWorkingDates = [
+ '2025-12-24', // 크리스마스 이브
+ '2025-12-31' // 연말
+];
+
+// 점심시간 (14:00 ~ 15:00)
+const lunchTimeStart = 1400; // 14:00
+const lunchTimeEnd = 1500; // 15:00
+
+// 날짜가 휴무일인지 확인
+function isDateDisabled(date) {
+ const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
+ return disabledSpecificDates.includes(dateStr);
+}
+
+// 단축 근무일인지 확인
+function isShortWorkingDate(date) {
+ const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
+ return shortWorkingDates.includes(dateStr);
+}
+
+// 점심시간인지 확인 (월화수목금만 해당)
+function isLunchTime(timeStr) {
+ const timeNum = parseInt(timeStr.replace(':', '')); // "14:30" -> 1430
+ return timeNum >= lunchTimeStart && timeNum < lunchTimeEnd;
+}
+
+// 생년월일 검증 클래스
+class BirthDateValidator {
+ constructor(inputId, options = {}) {
+ this.inputElement = document.getElementById(inputId);
+ this.messageElement = null;
+ this.options = {
+ showMessage: true,
+ realTimeValidation: true,
+ minAge: 0,
+ maxAge: 150,
+ format: 'YYYYMMDD',
+ allowFuture: false,
+ onValidationChange: null,
+ ...options
+ };
+
+ if (this.inputElement && this.options.showMessage) {
+ this.createMessageElement();
+ }
+
+ if (this.inputElement && this.options.realTimeValidation) {
+ this.bindEvents();
+ }
+ }
+
+ createMessageElement() {
+ this.messageElement = document.createElement('div');
+ this.messageElement.className = 'birth-date-message';
+ this.messageElement.style.display = 'none';
+ this.inputElement.parentNode.insertBefore(this.messageElement, this.inputElement.nextSibling);
+ }
+
+ bindEvents() {
+ this.inputElement.addEventListener('input', () => {
+ this.inputElement.value = this.inputElement.value.replace(/[^0-9]/g, '');
+ this.validateAndShowMessage();
+ });
+
+ this.inputElement.addEventListener('blur', () => {
+ this.validateAndShowMessage();
+ });
+
+ this.inputElement.addEventListener('keydown', (e) => {
+ if ([8, 9, 46, 37, 38, 39, 40].includes(e.keyCode)) return;
+ if ((e.keyCode < 48 || e.keyCode > 57) && (e.keyCode < 96 || e.keyCode > 105)) {
+ e.preventDefault();
+ }
+ });
+ }
+
+ validateBirthDate(dateStr) {
+ if (!dateStr) return { valid: false, message: '생년월일을 입력해주세요.' };
+
+ let cleanDate = dateStr.replace(/[^0-9]/g, '');
+ if (cleanDate.length !== 8) {
+ return { valid: false, message: '생년월일은 8자리 숫자로 입력해주세요. (예: 19900115)' };
+ }
+
+ const year = parseInt(cleanDate.slice(0, 4));
+ const month = parseInt(cleanDate.slice(4, 6));
+ const day = parseInt(cleanDate.slice(6, 8));
+
+ const currentYear = new Date().getFullYear();
+ const minYear = currentYear - this.options.maxAge;
+ const maxYear = currentYear - this.options.minAge;
+
+ if (year < minYear || year > maxYear) {
+ return { valid: false, message: `출생연도는 ${minYear}년부터 ${maxYear}년 사이여야 합니다.` };
+ }
+
+ if (month < 1 || month > 12) return { valid: false, message: '월은 01부터 12까지 입력 가능합니다.' };
+ if (day < 1 || day > 31) return { valid: false, message: '일은 01부터 31까지 입력 가능합니다.' };
+
+ const date = new Date(year, month - 1, day);
+ const isValidDate = date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
+
+ if (!isValidDate) return { valid: false, message: '존재하지 않는 날짜입니다.' };
+ if (!this.options.allowFuture && date > new Date()) return { valid: false, message: '미래 날짜는 입력할 수 없습니다.' };
+
+ return { valid: true, message: '올바른 생년월일입니다.' };
+ }
+
+ validateAndShowMessage() {
+ const result = this.validateBirthDate(this.inputElement.value);
+ if (this.messageElement) {
+ this.messageElement.textContent = result.message;
+ this.messageElement.className = `birth-date-message ${result.valid ? 'success' : 'error'}`;
+ this.messageElement.style.display = 'block';
+ }
+ if (typeof this.options.onValidationChange === 'function') {
+ this.options.onValidationChange(result, this.inputElement.value);
+ }
+ return result.valid;
+ }
+
+ isValid() {
+ return this.validateBirthDate(this.inputElement.value).valid;
+ }
+}
+
+// 전역 변수
+let birthDateValidator;
+let selectedTreatments = [];
+let selectedDate = null;
+let selectedTime = null;
+let selectedYear, selectedMonth;
+
+// DOM 요소
+const calendarTitle = document.getElementById('calendar-title');
+const calendarTable = document.getElementById('calendar-table');
+const timeSlots = document.getElementById('time-slots');
+const personCount = document.getElementById('person-count');
+const form = document.getElementById('reserve-form');
+const agree = document.getElementById('agree');
+const submitBtn = document.getElementById('submit-btn');
+const step02Title = document.getElementById('step02-title');
+const step03Title = document.getElementById('step03-title');
+
+// 진료시간 설정 (점심시간 제외)
+const times_mon_wed_fri = [
+ "10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30",
+ "15:00","15:30","16:00","16:30","17:00","17:30","18:00","18:30"
+];
+
+const times_tue_thu = [
+ "10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30",
+ "15:00","15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00","19:30"
+];
+
+const times_sat_short = [
+ "10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30",
+ "14:00","14:30","15:00","15:30"
+];
+
+// 시술 관리 함수들
+function removeService(el) {
+ const serviceItems = document.querySelectorAll('.service-item');
+ if (serviceItems.length <= 1) {
+ alert('최소 1개의 시술은 선택되어 있어야 합니다.');
+ return false;
+ }
+
+ const serviceName = el.closest('.service-item').querySelector('span:first-child').textContent;
+ if (!confirm(`'${serviceName}' 시술을 삭제하시겠습니까?`)) return false;
+
+ el.closest('.service-item').remove();
+ updateTotalPrice();
+ updateServiceCount();
+ return true;
+}
+
+function updateTotalPrice() {
+ const serviceItems = document.querySelectorAll('.service-item');
+ let totalPrice = 0;
+ serviceItems.forEach(item => {
+ const priceText = item.querySelector('.price').textContent;
+ totalPrice += parseInt(priceText.replace(/[^0-9]/g, '')) || 0;
+ });
+ document.getElementById('total-price').textContent = totalPrice.toLocaleString() + '원';
+}
+
+function updateServiceCount() {
+ const serviceItems = document.querySelectorAll('.service-item');
+ const count = serviceItems.length;
+ const info = document.getElementById('service-count-info');
+ info.textContent = `선택된 시술: ${count}개${count === 1 ? ' (최소 필수)' : ''}`;
+ info.className = count === 1 ? 'service-count-info single' : 'service-count-info';
+
+ serviceItems.forEach(item => {
+ const delBtn = item.querySelector('.del');
+ if (count <= 1) {
+ delBtn.className = 'del disabled';
+ delBtn.title = '최소 1개의 시술은 필요합니다';
+ } else {
+ delBtn.className = 'del';
+ delBtn.title = '삭제';
+ }
+ });
+}
+
+// 캘린더 렌더링 (일요일 + 공휴일만 휴무)
+function renderCalendar(year, month) {
+ selectedYear = year;
+ selectedMonth = month;
+ calendarTitle.textContent = `${year}.${String(month + 1).padStart(2, '0')}`;
+
+ const firstDay = new Date(year, month, 1);
+ const lastDay = new Date(year, month + 1, 0);
+ const todayDate = new Date();
+ todayDate.setHours(0, 0, 0, 0);
+
+ let html = '';
+ ['일','월','화','수','목','금','토'].forEach(d => html += ` ${d} `);
+ html += '