feat: 대전(daejeon)을 울산(ulsan)으로 개편 및 전체 7개 광역 지역(seoul, gyeonggi, incheon, gwangju, busan, daegu, ulsan) 세팅 완료

This commit is contained in:
2026-10-15 12:41:19 +09:00
parent 2dcb2ae8e8
commit 655a0f8177
318 changed files with 107890 additions and 4 deletions
+93
View File
@@ -0,0 +1,93 @@
<template>
<footer class="site-footer">
<div class="footer-container">
<div class="footer-info">
<h4 class="footer-brand">{{ siteName }}</h4>
<p class="footer-meta">
전국 초·중·고 1:1 맞춤 방문과외 및 실시간 화상코칭 서비스 | 대표번호: 010-5961-5807<br />
사업자등록번호: 123-45-67890 | 통신판매업신고: 제2026-서울강남-0123호 | 개인정보관리책임자: 교육연구소<br />
주소: 서울특별시 강남구 테헤란로 123 비전타워 4층
</p>
<p class="footer-copy">
Copyright © 2026 {{ siteName }}. All rights reserved.
</p>
</div>
<div class="footer-links">
<a href="#consult-section" class="f-link">무료상담신청</a>
<span class="f-divider">|</span>
<span class="f-link">이용약관</span>
<span class="f-divider">|</span>
<span class="f-link"><strong>개인정보처리방침</strong></span>
</div>
</div>
</footer>
</template>
<script setup>
const config = useRuntimeConfig()
const siteName = config.public.siteName || '클래스픽'
</script>
<style scoped>
.site-footer {
background: var(--footer-bg, #0f172a);
color: #94a3b8;
padding: clamp(30px, 5vw, 50px) 16px;
font-size: clamp(0.72rem, 1.8vw, 0.82rem);
border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.footer-container {
max-width: 1080px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 24px;
flex-wrap: wrap;
}
.footer-info {
flex: 1 1 500px;
}
.footer-brand {
font-size: clamp(1rem, 2.4vw, 1.15rem);
font-weight: 800;
color: #ffffff;
margin-bottom: 8px;
}
.footer-meta {
line-height: 1.6;
margin-bottom: 12px;
word-break: keep-all;
}
.footer-copy {
color: #64748b;
}
.footer-links {
display: flex;
align-items: center;
gap: 10px;
flex-shrink: 0;
}
.f-link {
color: #cbd5e1;
}
.f-divider {
color: #475569;
}
@media (max-width: 640px) {
.footer-container {
flex-direction: column;
gap: 16px;
}
}
</style>
+223
View File
@@ -0,0 +1,223 @@
<template>
<section class="coaching-section">
<div class="coaching-inner">
<div class="coaching-text">
<span class="coaching-badge">📈 과외 시간 외에도 이어지는 케어</span>
<h2 class="coaching-title">주 2회 과외로 끝나지 않는<br /><strong>'1:1 메타인지 플래너 코칭'</strong></h2>
<p class="coaching-desc">
성적은 수업 시간이 아니라 <strong>스스로 복습하는 시간</strong>에 결정됩니다. 전담 선생님이 매일 카카오톡으로 일일 플래너를 점검하고 피드백을 전달합니다.
</p>
<div class="coaching-points">
<div class="cp-item">
<span class="cp-icon">🗓️</span>
<div>
<h4 class="cp-title">주간·일일 스터디 플래너 설계</h4>
<p class="cp-desc">학교 수업 복습, 과제량, 취약 단원 보충 분량을 학생 능력에 맞춰 쪼개어 배분합니다.</p>
</div>
</div>
<div class="cp-item">
<span class="cp-icon">📱</span>
<div>
<h4 class="cp-title">매일 학습 인증 & 밀착 피드백</h4>
<p class="cp-desc">학생이 푼 오답 노트와 플래너 사진을 확인하고 격려와 질문 해결을 진행합니다.</p>
</div>
</div>
<div class="cp-item">
<span class="cp-icon">📊</span>
<div>
<h4 class="cp-title">월간 학부모 정기 리포트 발송</h4>
<p class="cp-desc">출결, 단원별 이해도, 성취도 변화 그래프를 투명하게 정리하여 학부모님께 보고합니다.</p>
</div>
</div>
</div>
</div>
<div class="coaching-visual">
<div class="visual-card">
<div class="vc-header">
<span class="vc-tag">REAL SCORE UP</span>
<span class="vc-title">실제 성적 상승 로드맵</span>
</div>
<div class="vc-body">
<div class="timeline-step">
<span class="step-circle">1</span>
<div>
<strong>1개월 차 (습관 형성)</strong>
<p>무작정 외우기 탈피, 오답 노트 4분류 태깅 습관 정착</p>
</div>
</div>
<div class="timeline-step">
<span class="step-circle">2</span>
<div>
<strong>2개월 차 (취약점 집중)</strong>
<p>자주 틀리는 서술형 조건 누락 및 킬러 개념 1:1 완파</p>
</div>
</div>
<div class="timeline-step active">
<span class="step-circle">3</span>
<div>
<strong>3개월 차 (1등급 달성)</strong>
<p>실전 시험 타임어택 훈련으로 시간 부족 극복 및 내신 만점</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<style scoped>
.coaching-section {
max-width: 1080px;
margin: 0 auto 50px;
padding: 0 16px;
}
.coaching-inner {
background: var(--coaching-bg, #f1f5f9);
border-radius: var(--card-radius, 16px);
padding: clamp(24px, 5vw, 44px) clamp(18px, 4vw, 36px);
display: grid;
grid-template-columns: 1.15fr 0.85fr;
gap: 30px;
align-items: center;
}
.coaching-badge {
display: inline-block;
font-size: clamp(0.78rem, 2vw, 0.88rem);
font-weight: 700;
color: var(--primary-color, #1e3a8a);
background: rgba(255, 255, 255, 0.8);
padding: 5px 12px;
border-radius: 9999px;
margin-bottom: 12px;
}
.coaching-title {
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
font-weight: 800;
color: var(--text-color, #0f172a);
line-height: 1.35;
letter-spacing: -0.6px;
margin-bottom: 14px;
}
.coaching-title strong {
color: var(--primary-color, #1e3a8a);
}
.coaching-desc {
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
line-height: 1.6;
color: #475569;
margin-bottom: 22px;
word-break: keep-all;
}
.coaching-points {
display: flex;
flex-direction: column;
gap: 14px;
}
.cp-item {
display: flex;
gap: 12px;
align-items: flex-start;
}
.cp-icon {
font-size: 1.4rem;
flex-shrink: 0;
}
.cp-title {
font-size: clamp(0.88rem, 2.2vw, 0.98rem);
font-weight: 800;
color: var(--text-color, #0f172a);
margin-bottom: 2px;
}
.cp-desc {
font-size: clamp(0.76rem, 1.8vw, 0.85rem);
color: #64748b;
line-height: 1.45;
word-break: keep-all;
}
.visual-card {
background: #ffffff;
border-radius: 12px;
padding: 20px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}
.vc-header {
border-bottom: 1px solid #e2e8f0;
padding-bottom: 10px;
margin-bottom: 16px;
}
.vc-tag {
display: block;
font-size: 0.72rem;
font-weight: 800;
color: var(--accent-color, #d97706);
letter-spacing: 0.5px;
}
.vc-title {
font-size: 1.05rem;
font-weight: 800;
color: #0f172a;
}
.timeline-step {
display: flex;
gap: 12px;
margin-bottom: 14px;
position: relative;
}
.step-circle {
width: 24px;
height: 24px;
border-radius: 50%;
background: #e2e8f0;
color: #475569;
font-size: 0.75rem;
font-weight: 800;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.timeline-step.active .step-circle {
background: var(--accent-color, #d97706);
color: #ffffff;
}
.timeline-step strong {
display: block;
font-size: 0.85rem;
color: #1e293b;
margin-bottom: 2px;
}
.timeline-step p {
font-size: 0.76rem;
color: #64748b;
line-height: 1.4;
word-break: keep-all;
}
@media (max-width: 820px) {
.coaching-inner {
grid-template-columns: 1fr;
}
}
</style>
+443
View File
@@ -0,0 +1,443 @@
<template>
<section id="consult-section" class="consult-section">
<div class="consult-card">
<div class="consult-header">
<h2 class="consult-title">상담은 무료입니다</h2>
<p class="consult-desc">연락처만 남기시면 확인하는 대로 연락드리겠습니다.</p>
</div>
<div v-if="submitted" class="success-box">
<h3 class="success-title">상담 신청이 정상적으로 완료되었습니다!</h3>
<p class="success-desc">
남겨주신 부모님 연락처(<strong>{{ form.parentPhone }}</strong>)로 전문 상담 팀장이 확인하는 대로 빠른 시일 내에 연락드리겠습니다.
</p>
<button type="button" class="btn-reset" @click="resetForm">추가 문의하기</button>
</div>
<form v-else class="consult-form" @submit.prevent="handleSubmit">
<div class="form-grid">
<!-- 1행 좌: 학생 이름 -->
<div class="form-group">
<label for="c-student-name" class="form-label">학생 이름</label>
<input
id="c-student-name"
v-model="form.studentName"
type="text"
placeholder="홍길동"
required
class="form-input"
/>
</div>
<!-- 1행 우: 부모님 연락처 -->
<div class="form-group">
<label for="c-parent-phone" class="form-label">부모님 연락처</label>
<input
id="c-parent-phone"
v-model="form.parentPhone"
type="tel"
placeholder="010-0000-0000"
required
class="form-input"
/>
</div>
<!-- 2행 좌: 다니는 학교 -->
<div class="form-group">
<label for="c-school" class="form-label">다니는 학교</label>
<input
id="c-school"
v-model="form.schoolName"
type="text"
placeholder="OO고등학교"
class="form-input"
/>
</div>
<!-- 2행 우: 학년 -->
<div class="form-group">
<label for="c-grade" class="form-label">학년</label>
<div class="select-wrap">
<select id="c-grade" v-model="form.grade" class="form-select" required>
<option value="초등">초등</option>
<option value="중1">중1</option>
<option value="중2">중2</option>
<option value="중3">중3</option>
<option value="고1">고1</option>
<option value="고2">고2</option>
<option value="고3">고3</option>
<option value="N수">N수</option>
</select>
</div>
</div>
<!-- 3행 전체: 사는 곳 -->
<div class="form-group full-width">
<label for="c-location" class="form-label">사는 곳</label>
<input
id="c-location"
v-model="form.location"
type="text"
:placeholder="regionName || '행복시 행복동'"
class="form-input"
/>
</div>
<!-- 4행 전체: 상담문의 내용 (선택) -->
<div class="form-group full-width">
<label for="c-memo" class="form-label">상담문의 내용 (선택)</label>
<textarea
id="c-memo"
v-model="form.memo"
rows="4"
placeholder="지금 등급, 어려운 과목, 원하는 시간대 같은 것을 적어 주시면 상담이 빨라집니다."
class="form-textarea"
></textarea>
</div>
</div>
<!-- 개인정보 수집 동의 -->
<div class="privacy-wrap">
<label class="privacy-label">
<input type="checkbox" v-model="form.agree" required class="privacy-checkbox" />
<span>상담을 위해 학생 이름과 부모님 연락처를 받는 데 동의합니다. 받은 정보는 상담 외에 쓰지 않습니다.</span>
</label>
</div>
<!-- 버튼 그룹 -->
<div class="button-group">
<button type="submit" class="btn-submit" :disabled="loading">
<span v-if="loading">문의 전송 중...</span>
<span v-else>문의 보내기</span>
</button>
<a href="tel:010-5961-5807" class="btn-call">
전화로 바로 상담
</a>
</div>
</form>
</div>
</section>
</template>
<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
regionName: {
type: String,
default: ''
},
defaultGrade: {
type: String,
default: '고1'
},
defaultSubject: {
type: String,
default: ''
}
})
function resolveGrade(g) {
if (!g) return '고1'
if (g.includes('고1') || g.includes('고등학교 1')) return '고1'
if (g.includes('고2') || g.includes('고등학교 2')) return '고2'
if (g.includes('고3') || g.includes('고등학교 3')) return '고3'
if (g.includes('중1') || g.includes('중학교 1')) return '중1'
if (g.includes('중2') || g.includes('중학교 2')) return '중2'
if (g.includes('중3') || g.includes('중학교 3')) return '중3'
if (g.includes('초등')) return '초등'
if (g.includes('고등')) return '고1'
if (g.includes('중등') || g.includes('중학')) return '중2'
return '고1'
}
const form = ref({
studentName: '',
parentPhone: '',
schoolName: '',
grade: resolveGrade(props.defaultGrade),
location: props.regionName || '',
memo: '',
agree: false
})
watch(() => props.defaultGrade, (newVal) => {
if (newVal) form.value.grade = resolveGrade(newVal)
})
watch(() => props.regionName, (newVal) => {
if (newVal && !form.value.location) form.value.location = newVal
})
const loading = ref(false)
const submitted = ref(false)
const handleSubmit = async () => {
if (!form.value.parentPhone) return
loading.value = true
try {
const currentUrl = typeof window !== 'undefined' ? window.location.href : ''
await $fetch('/api/consult', {
method: 'POST',
body: {
studentName: form.value.studentName,
parentPhone: form.value.parentPhone,
schoolName: form.value.schoolName,
grade: form.value.grade,
location: form.value.location || props.regionName,
memo: form.value.memo,
url: currentUrl
}
})
submitted.value = true
} catch (err) {
console.error('상담 신청 전송:', err)
submitted.value = true
} finally {
loading.value = false
}
}
const resetForm = () => {
form.value = {
studentName: '',
parentPhone: '',
schoolName: '',
grade: resolveGrade(props.defaultGrade),
location: props.regionName || '',
memo: '',
agree: false
}
submitted.value = false
}
</script>
<style scoped>
.consult-section {
width: 100%;
padding: clamp(35px, 6vw, 65px) 16px;
display: flex;
justify-content: center;
align-items: center;
background: transparent;
}
.consult-card {
width: 100%;
max-width: 580px;
background: #fffbf8;
border: 1px solid #fed7aa;
border-radius: 16px;
box-shadow: 0 10px 25px rgba(234, 88, 12, 0.1);
padding: clamp(24px, 5vw, 40px) clamp(20px, 4vw, 36px);
box-sizing: border-box;
}
.consult-header {
margin-bottom: 24px;
}
.consult-title {
font-size: clamp(1.45rem, 3.5vw, 1.85rem);
font-weight: 800;
color: #c2410c;
letter-spacing: -0.5px;
margin-bottom: 8px;
line-height: 1.3;
}
.consult-desc {
font-size: clamp(0.88rem, 2.2vw, 0.98rem);
color: #9a3412;
line-height: 1.5;
letter-spacing: -0.3px;
}
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 18px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 6px;
}
.form-group.full-width {
grid-column: 1 / -1;
}
.form-label {
font-size: 0.88rem;
font-weight: 700;
color: #7c2d12;
letter-spacing: -0.3px;
}
.form-input,
.form-select,
.form-textarea {
width: 100%;
padding: 12px 14px;
font-size: 0.95rem;
font-family: inherit;
color: #1e293b;
background: #fff7ed;
border: 1px solid #fed7aa;
border-radius: 12px;
outline: none;
transition: all 0.2s ease;
box-sizing: border-box;
}
.form-input::placeholder,
.form-textarea::placeholder {
color: #94a3b8;
font-size: 0.9rem;
}
.form-input:focus,
.form-select:focus,
.form-textarea:focus {
border-color: #ea580c;
box-shadow: 0 0 0 3px rgba(234, 88, 12, 0.2);
background: #ffffff;
}
.select-wrap {
position: relative;
width: 100%;
}
.form-select {
appearance: none;
cursor: pointer;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 14px center;
padding-right: 36px;
}
.form-textarea {
resize: vertical;
min-height: 90px;
line-height: 1.5;
}
.privacy-wrap {
margin-bottom: 22px;
}
.privacy-label {
display: flex;
align-items: flex-start;
gap: 10px;
font-size: 0.82rem;
color: #9a3412;
line-height: 1.45;
cursor: pointer;
}
.privacy-checkbox {
margin-top: 3px;
cursor: pointer;
width: 16px;
height: 16px;
accent-color: #ea580c;
}
.button-group {
display: flex;
flex-direction: column;
gap: 12px;
}
.btn-submit {
width: 100%;
padding: 16px 20px;
font-size: 1.08rem;
font-weight: 800;
color: #ffffff;
background: #ea580c;
border: none;
border-radius: 12px;
cursor: pointer;
transition: all 0.2s ease;
letter-spacing: -0.3px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.btn-submit:hover:not(:disabled) {
background: #c2410c;
transform: translateY(-1px);
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16);
}
.btn-submit:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.btn-call {
display: block;
width: 100%;
padding: 15px 20px;
font-size: 1.02rem;
font-weight: 800;
text-align: center;
color: #9a3412;
background: #fff1e6;
border: 2px solid #ea580c;
border-radius: 12px;
cursor: pointer;
text-decoration: none;
transition: all 0.2s ease;
letter-spacing: -0.3px;
box-sizing: border-box;
}
.btn-call:hover {
background: #ffe4d6;
}
.success-box {
text-align: center;
padding: 40px 20px;
}
.success-title {
font-size: 1.25rem;
font-weight: 800;
color: #c2410c;
margin-bottom: 12px;
}
.success-desc {
font-size: 0.95rem;
color: #475569;
line-height: 1.6;
margin-bottom: 24px;
}
.btn-reset {
padding: 10px 24px;
font-size: 0.9rem;
font-weight: 700;
color: #ea580c;
background: transparent;
border: 1px solid #ea580c;
border-radius: 8px;
cursor: pointer;
}
@media (max-width: 520px) {
.form-grid {
grid-template-columns: 1fr;
gap: 14px;
}
}
</style>
+207
View File
@@ -0,0 +1,207 @@
<template>
<section class="faq-section">
<div class="section-header">
<span class="section-badge">궁금한 점을 풀어드립니다</span>
<h2 class="section-title">{{ regionDong }} 1:1 과외 자주 묻는 질문</h2>
<p class="section-desc">학부모님들께서 가장 많이 문의하시는 내용을 모았습니다.</p>
</div>
<div class="faq-list">
<div
v-for="(faq, idx) in faqs"
:key="idx"
class="faq-item"
:class="{ active: openIndex === idx }"
>
<button
type="button"
class="faq-question"
@click="toggle(idx)"
:aria-expanded="openIndex === idx"
>
<span class="q-icon">Q</span>
<span class="q-text">{{ faq.q }}</span>
<span class="toggle-icon">{{ openIndex === idx ? '▲' : '▼' }}</span>
</button>
<div v-show="openIndex === idx" class="faq-answer">
<span class="a-icon">A</span>
<p class="a-text">{{ faq.a }}</p>
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref, computed } from 'vue'
const props = defineProps({
regionDong: {
type: String,
required: true
},
grade: {
type: String,
default: '중학생'
},
subjectName: {
type: String,
default: '영어'
}
})
const openIndex = ref(0)
const toggle = (idx) => {
openIndex.value = openIndex.value === idx ? -1 : idx
}
const faqs = computed(() => [
{
q: `${props.regionDong} ${props.grade} ${props.subjectName} 방문 과외와 온라인 화상 과외 중 어떤 것이 가능한가요?`,
a: `학생과 학부모님의 선호에 따라 100% 자택 방문 대면 과외 또는 실시간 쌍방향 비대면 화상 과외 중 자유롭게 선택하실 수 있습니다. ${props.regionDong} 전 지역 방문 수업이 가능합니다.`
},
{
q: `${props.grade} ${props.subjectName} 전문 선생님이 학생과 잘 맞지 않으면 교체 가능한가요?`,
a: '네, 1회 무료 모의수업을 통해 사전에 호흡을 맞추며, 정규 수업 시작 후에도 학생의 성향이나 요청에 따라 추가 비용 없이 100% 무료 교체 및 환불 규정을 보장합니다.'
},
{
q: `${props.grade} ${props.subjectName} 과외 수업 비용은 어떻게 되나요?`,
a: `${props.grade} 내신 단계, 주당 수업 횟수, 수업 시간(1회 60분/90분/120분)에 따라 표준 교육청 가이드라인에 맞춘 투명한 정찰제로 운영됩니다. 무료 상담 시 상세 견적표를 안내해 드립니다.`
},
{
q: `${props.regionDong} 학교 중간·기말고사 직전 단기 ${props.subjectName} 족보 클리닉도 가능한가요?`,
a: `네, 시험 3~4주 전 학교별 기출 족보 풀이 및 서술형 배점 방어를 위한 ${props.grade} ${props.subjectName} 단기 속성 킬러 클리닉 프로그램도 상시 운영 중입니다.`
},
{
q: `${props.subjectName} 외에 다른 과목도 함께 상담받을 수 있나요?`,
a: `${props.subjectName} 집중 신청은 물론, 국영수 또는 수탐 복합 패키지로 맞춤 구성하여 전 과목 플래너 관리와 함께 시간표를 편성하실 수 있습니다.`
}
])
</script>
<style scoped>
.faq-section {
max-width: 860px;
margin: 0 auto 50px;
padding: 0 16px;
}
.section-header {
text-align: center;
margin-bottom: 28px;
}
.section-badge {
display: inline-block;
font-size: clamp(0.78rem, 2vw, 0.88rem);
font-weight: 700;
color: var(--primary-color, #1e3a8a);
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
padding: 5px 12px;
border-radius: 9999px;
margin-bottom: 8px;
}
.section-title {
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
font-weight: 800;
color: var(--text-color, #1e293b);
letter-spacing: -0.6px;
word-break: keep-all;
line-height: 1.35;
}
.section-desc {
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
color: #64748b;
margin-top: 6px;
word-break: keep-all;
}
.faq-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.faq-item {
background: var(--bg-card, #ffffff);
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 12px);
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}
.faq-question {
width: 100%;
display: flex;
align-items: center;
gap: 12px;
padding: clamp(14px, 3vw, 18px);
background: none;
border: none;
text-align: left;
cursor: pointer;
font-size: clamp(0.9rem, 2.2vw, 1.02rem);
font-weight: 800;
color: var(--text-color, #0f172a);
}
.q-icon {
width: 26px;
height: 26px;
border-radius: 6px;
background: var(--primary-color, #1e3a8a);
color: #ffffff;
font-size: 0.85rem;
font-weight: 900;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.q-text {
flex-grow: 1;
word-break: keep-all;
line-height: 1.45;
}
.toggle-icon {
font-size: 0.8rem;
color: #94a3b8;
flex-shrink: 0;
}
.faq-answer {
display: flex;
gap: 12px;
padding: 0 clamp(14px, 3vw, 18px) clamp(16px, 3vw, 20px);
background: #f8fafc;
border-top: 1px solid var(--border-color, #f1f5f9);
}
.a-icon {
width: 26px;
height: 26px;
border-radius: 6px;
background: var(--accent-color, #d97706);
color: #ffffff;
font-size: 0.85rem;
font-weight: 900;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 12px;
}
.a-text {
font-size: clamp(0.82rem, 2vw, 0.92rem);
line-height: 1.65;
color: #334155;
word-break: keep-all;
margin-top: 12px;
}
</style>
+364
View File
@@ -0,0 +1,364 @@
<template>
<section class="focus-programs-section" aria-label="맞춤 과외 핵심 프로그램">
<div class="focus-container">
<div class="focus-header">
<span class="focus-badge">{{ isElementary ? '초등 맞춤 집중 케어' : `${displayGrade} 실전 시험 케어` }}</span>
<h2 class="focus-main-title">
{{ regionDong }} {{ displayGrade }} {{ displaySubject }}과외
<span class="text-accent">5대 핵심 솔루션</span>
</h2>
<p class="focus-sub-desc">
네이버 검색 및 학부모님 선호도 1위! 취약 단원부터 시험 직전 족보 풀이까지 1:1로 책임 지도합니다.
</p>
</div>
<!-- 네이버 5개 멀티 썸네일 스니펫 및 상담 링크 매칭용 5개 리스트 -->
<div class="focus-grid">
<a
v-for="(item, idx) in programList"
:key="idx"
href="#consult-section"
class="focus-card"
:title="`${regionDong} ${item.title} 상담 신청`"
>
<div class="focus-thumb-wrap">
<img
:src="item.image"
:alt="`${regionDong} ${item.title} 1:1 맞춤 지도`"
width="500"
height="500"
loading="lazy"
class="focus-img"
/>
<span class="step-tag">STEP 0{{ idx + 1 }}</span>
</div>
<div class="focus-info">
<div class="focus-item-tag">{{ item.tag }}</div>
<strong class="focus-item-title">{{ item.title }}</strong>
<p class="focus-item-desc">{{ item.desc }}</p>
<div class="focus-cta-link">
<span>1:1 상담 예약</span>
<span class="arrow-sym">&rarr;</span>
</div>
</div>
</a>
</div>
</div>
</section>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
grade: {
type: String,
default: '중학생'
},
subjectName: {
type: String,
default: '수학'
},
regionDong: {
type: String,
default: ''
}
})
const isElementary = computed(() => {
return (props.grade || '').includes('초등')
})
const displayGrade = computed(() => {
return props.grade || '중학생'
})
const displaySubject = computed(() => {
return props.subjectName || '수학'
})
// 초등 vs 중등/고등 5개 항목 분기
const programList = computed(() => {
const dong = props.regionDong ? `${props.regionDong} ` : ''
const sub = displaySubject.value
const grd = displayGrade.value
if (isElementary.value) {
return [
{
tag: '개념 완성',
title: `${dong}초등 ${sub}과외 - 기초학습`,
desc: '개념 쏙쏙 이해와 튼튼한 연산 기본기 완성',
image: '/images/focus/elem-1-basic.svg'
},
{
tag: '학습 코칭',
title: `${dong}초등 ${sub}과외 - 공부방법`,
desc: '스스로 원리를 깨우치는 올바른 문제 해결력',
image: '/images/focus/elem-2-method.svg'
},
{
tag: '밀착 피드백',
title: `${dong}초등 ${sub}과외 - 숙제검사`,
desc: '매일 1:1 오답 점검과 꼼꼼한 피드백 피드백',
image: '/images/focus/elem-3-homework.svg'
},
{
tag: '자기주도',
title: `${dong}초등 ${sub}과외 - 공부습관`,
desc: '매일 스스로 책상에 앉는 주도적 학습 루틴',
image: '/images/focus/elem-4-habit.svg'
},
{
tag: '상위권 도약',
title: `${dong}초등 ${sub}과외 - 중등대비`,
desc: '중학교 내신 서술형과 심화 개념 선행 마스터',
image: '/images/focus/elem-5-middleprep.svg'
}
]
}
// 중등 & 고등 동일
return [
{
tag: '기출 정복',
title: `${dong}${grd} 중간고사 ${sub}과외`,
desc: '학교별 기출 족보 완벽 분석 및 서술형 킬러 대비',
image: '/images/focus/sec-1-midterm.svg'
},
{
tag: '학기말 총력',
title: `${dong}${grd} 기말고사 ${sub}과외`,
desc: '전 범위 오답 분석 및 취약 유형 완벽 클리닉',
image: '/images/focus/sec-2-final.svg'
},
{
tag: '수능·전국연합',
title: `${dong}${grd} 모의고사 ${sub}과외`,
desc: '수능형 사고력 확장 및 실전 시간 배분 특훈',
image: '/images/focus/sec-3-mock.svg'
},
{
tag: '내신 만점',
title: `${dong}${grd} 수행평가 ${sub}과외`,
desc: '조건 감점 0점화 및 과제·보고서 완벽 케어',
image: '/images/focus/sec-4-assessment.svg'
},
{
tag: '1등급 집중',
title: `${dong}${grd} 내신대비 ${sub}과외`,
desc: '관내 교과서·부교재 적중 1:1 맞춤 지도',
image: '/images/focus/sec-5-schoolprep.svg'
}
]
})
</script>
<style scoped>
.focus-programs-section {
padding: clamp(35px, 6vw, 65px) 16px;
background: var(--bg-body, #f8fafc);
border-top: 1px solid var(--border-color, #e2e8f0);
border-bottom: 1px solid var(--border-color, #e2e8f0);
}
.focus-container {
max-width: 1100px;
margin: 0 auto;
}
.focus-header {
text-align: center;
margin-bottom: clamp(24px, 4vw, 36px);
}
.focus-badge {
display: inline-block;
padding: 4px 12px;
font-size: 0.8rem;
font-weight: 700;
color: var(--primary-color, #1e3a8a);
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
border-radius: 9999px;
margin-bottom: 8px;
}
.focus-main-title {
font-size: clamp(1.35rem, 3.2vw, 1.85rem);
font-weight: 800;
color: var(--text-color, #0f172a);
letter-spacing: -0.5px;
margin-bottom: 8px;
}
.text-accent {
color: var(--primary-color, #1e3a8a);
}
.focus-sub-desc {
font-size: clamp(0.85rem, 2vw, 0.95rem);
color: #64748b;
margin: 0;
}
/* 5열 카드 그리드 */
.focus-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 14px;
}
.focus-card {
display: flex;
flex-direction: column;
background: #ffffff;
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 12px);
overflow: hidden;
text-decoration: none;
color: inherit;
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03);
}
.focus-card:hover {
transform: translateY(-4px);
border-color: var(--primary-color, #1e3a8a);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08);
}
.focus-thumb-wrap {
position: relative;
width: 100%;
aspect-ratio: 1 / 1;
background: #f1f5f9;
overflow: hidden;
}
.focus-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: transform 0.3s ease;
}
.focus-card:hover .focus-img {
transform: scale(1.04);
}
.step-tag {
position: absolute;
top: 8px;
left: 8px;
padding: 2px 8px;
background: rgba(0, 0, 0, 0.55);
backdrop-filter: blur(4px);
color: #ffffff;
font-size: 0.68rem;
font-weight: 800;
border-radius: 4px;
letter-spacing: 0.5px;
}
.focus-info {
padding: 14px 12px;
display: flex;
flex-direction: column;
flex: 1;
}
.focus-item-tag {
font-size: 0.72rem;
font-weight: 700;
color: var(--primary-color, #1e3a8a);
margin-bottom: 4px;
}
.focus-item-title {
font-size: 0.95rem;
font-weight: 800;
color: #0f172a;
line-height: 1.35;
margin-bottom: 6px;
word-break: keep-all;
}
.focus-item-desc {
font-size: 0.78rem;
color: #64748b;
line-height: 1.4;
margin-bottom: 12px;
flex: 1;
word-break: keep-all;
}
.focus-cta-link {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.76rem;
font-weight: 700;
color: var(--primary-color, #1e3a8a);
border-top: 1px dashed var(--border-color, #e2e8f0);
padding-top: 8px;
}
.arrow-sym {
transition: transform 0.2s ease;
}
.focus-card:hover .arrow-sym {
transform: translateX(3px);
}
/* 태블릿 및 모바일 반응형 */
@media (max-width: 960px) {
.focus-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 640px) {
.focus-grid {
grid-template-columns: 1fr;
gap: 12px;
}
.focus-card {
flex-direction: row;
align-items: center;
}
.focus-thumb-wrap {
width: 105px;
height: 105px;
aspect-ratio: 1 / 1;
flex-shrink: 0;
}
.focus-info {
padding: 10px 12px;
}
.focus-item-title {
font-size: 0.88rem;
margin-bottom: 2px;
}
.focus-item-desc {
font-size: 0.74rem;
margin-bottom: 6px;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.focus-cta-link {
padding-top: 4px;
font-size: 0.72rem;
}
}
</style>
+238
View File
@@ -0,0 +1,238 @@
<template>
<header class="hero-banner">
<div class="hero-container">
<div class="hero-badge-wrap">
<span class="hero-badge royal-badge">{{ region.dong }} 학군 맞춤 1:1 전문 지도</span>
<span class="hero-subbadge">2026 개정 교육과정 완벽 반영</span>
</div>
<h1 class="hero-title">
<span class="region-highlight">{{ displayRegionName }}</span><br />
<span class="subject-highlight">{{ grade }} {{ subjectName }}</span> 1:1 맞춤 과외
</h1>
<p class="hero-desc">
{{ region.dong }} 인근 학교별 기출 분석부터 서술형 조건 감점 0점화까지!<br />
우리 아이의 취약점을 1:1로 진단하고 <strong>성적 1등급 역전</strong>을 이끌어냅니다.
</p>
<div class="hero-cta-group">
<a href="#consult-section" class="btn-hero-primary">
<span>{{ region.dong }} 1:1 무료 방문·진단 모의수업 신청</span>
</a>
<div class="hero-call-info">
<span class="call-icon"></span>
<span class="call-text">실시간 학습상담 <strong>010-5961-5807</strong></span>
</div>
</div>
<div class="hero-tags">
<span class="tag-item">#{{ region.dong }}과외</span>
<span class="tag-item">#{{ region.dong }}{{ subjectName }}</span>
<span class="tag-item">#{{ grade }}내신대비</span>
<span class="tag-item">#서술형감점방지</span>
<span class="tag-item">#1대1밀착코칭</span>
</div>
</div>
</header>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
region: {
type: Object,
required: true
},
shortRegionName: {
type: String,
default: ''
},
grade: {
type: String,
default: '중학생'
},
subjectName: {
type: String,
default: '영어'
}
})
// '대구광역시 수성구 황금동' -> '대구 황금동' 등 축약 지역명 산출
const displayRegionName = computed(() => {
if (props.shortRegionName) return props.shortRegionName
if (props.region) {
const sido = props.region.sido || ''
const dong = props.region.dong || ''
if (sido && dong) {
let shortSido = sido.slice(0, 2)
if (sido.includes('서울')) shortSido = '서울'
else if (sido.includes('대구')) shortSido = '대구'
else if (sido.includes('부산')) shortSido = '부산'
else if (sido.includes('인천')) shortSido = '인천'
else if (sido.includes('광주')) shortSido = '광주'
else if (sido.includes('대전')) shortSido = '대전'
else if (sido.includes('울산')) shortSido = '울산'
else if (sido.includes('세종')) shortSido = '세종'
else if (sido.includes('경기')) shortSido = '경기'
else if (sido.includes('강원')) shortSido = '강원'
else if (sido.includes('충북') || sido.includes('충청북')) shortSido = '충북'
else if (sido.includes('충남') || sido.includes('충청남')) shortSido = '충남'
else if (sido.includes('전북') || sido.includes('전라북')) shortSido = '전북'
else if (sido.includes('전남') || sido.includes('전라남')) shortSido = '전남'
else if (sido.includes('경북') || sido.includes('경상북')) shortSido = '경북'
else if (sido.includes('경남') || sido.includes('경상남')) shortSido = '경남'
else if (sido.includes('제주')) shortSido = '제주'
return `${shortSido} ${dong}`.trim()
}
return props.region.fullName || ''
}
return ''
})
</script>
<style scoped>
.hero-banner {
background: var(--hero-gradient, linear-gradient(135deg, #0f172a 0%, #1e3a8a 100%));
color: #ffffff;
padding: clamp(40px, 8vw, 80px) 16px clamp(35px, 6vw, 60px);
text-align: center;
position: relative;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.hero-banner::before {
content: "";
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: radial-gradient(circle at 50% 20%, rgba(217, 119, 6, 0.15) 0%, transparent 60%);
pointer-events: none;
}
.hero-container {
max-width: 900px;
margin: 0 auto;
position: relative;
z-index: 1;
}
.hero-badge-wrap {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
flex-wrap: wrap;
margin-bottom: 20px;
}
.hero-badge {
display: inline-block;
padding: 6px 14px;
font-size: clamp(0.78rem, 2.2vw, 0.9rem);
font-weight: 700;
border-radius: 9999px;
background: var(--accent-color, #d97706);
color: #ffffff;
letter-spacing: -0.3px;
}
.hero-subbadge {
display: inline-block;
padding: 6px 12px;
font-size: clamp(0.75rem, 2vw, 0.85rem);
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(4px);
border-radius: 9999px;
color: #e2e8f0;
}
.hero-title {
font-size: clamp(1.65rem, 5vw, 2.85rem);
font-weight: 900;
line-height: 1.3;
margin-bottom: 18px;
word-break: keep-all;
letter-spacing: -0.8px;
}
.region-highlight {
color: var(--hero-region-color, #cbd5e1);
font-size: 0.85em;
font-weight: 700;
}
.subject-highlight {
color: var(--accent-light, #fbbf24);
text-decoration: underline;
text-underline-offset: 6px;
}
.hero-desc {
font-size: clamp(0.92rem, 2.6vw, 1.15rem);
line-height: 1.65;
color: #e2e8f0;
margin-bottom: 30px;
word-break: keep-all;
}
.hero-cta-group {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
margin-bottom: 26px;
}
.btn-hero-primary {
display: inline-flex;
align-items: center;
justify-content: center;
padding: clamp(14px, 3.5vw, 18px) clamp(20px, 5vw, 36px);
font-size: clamp(0.95rem, 2.8vw, 1.2rem);
font-weight: 800;
color: #ffffff;
background: var(--hero-btn-bg, linear-gradient(135deg, #d97706 0%, #b45309 100%));
border-radius: var(--card-radius, 12px);
box-shadow: 0 8px 24px rgba(217, 119, 6, 0.35);
transition: transform 0.2s ease, box-shadow 0.2s ease;
width: 100%;
max-width: 480px;
min-height: 48px;
}
.btn-hero-primary:hover {
transform: translateY(-2px);
box-shadow: 0 12px 28px rgba(217, 119, 6, 0.45);
}
.hero-call-info {
display: flex;
align-items: center;
gap: 6px;
font-size: clamp(0.85rem, 2.2vw, 0.95rem);
color: #cbd5e1;
}
.hero-call-info strong {
color: #ffffff;
font-size: 1.1em;
}
.hero-tags {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 6px;
}
.tag-item {
font-size: clamp(0.72rem, 1.8vw, 0.82rem);
padding: 4px 10px;
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 6px;
color: #cbd5e1;
}
</style>
+360
View File
@@ -0,0 +1,360 @@
<template>
<section class="schools-section">
<div class="section-header">
<span class="section-badge">{{ regionDong }} {{ grade }} 맞춤 출제경향</span>
<h2 class="section-title">{{ regionDong }} 관내 {{ targetSchoolType }} {{ subjectName }} 내신 기출 분석</h2>
<p class="section-desc">
{{ regionDong }} {{ targetSchoolType }}마다 교과서 출판사와 부교재, 서술형 배점이 완전히 다릅니다. {{ subjectName }} 전문 강사진이 학교별 족보를 1:1로 밀착 대비합니다.
</p>
</div>
<!-- 나이스(NEIS) 연동 관내 실제 고등학교 칩 영역 -->
<div v-if="nearbyHighSchools.length > 0" class="neis-schools-box">
<div class="neis-header">
<span class="neis-title">
<i class="fa-solid fa-school-flag text-blue-600 mr-1.5"></i>
<strong>{{ regionDong }} 인근 주요 고등학교 내신 대비 현황</strong>
</span>
<span class="neis-source">NEIS 학교정보 연동</span>
</div>
<div class="school-tags-wrap">
<div
v-for="school in nearbyHighSchools"
:key="school.code"
class="school-tag-pill"
>
<span class="school-tag-name">{{ school.name }}</span>
<span class="school-tag-type">{{ school.type }}</span>
</div>
</div>
</div>
<!-- 고등학생 타겟인 경우 -->
<div v-if="isHigh" class="schools-grid">
<div class="school-card">
<div class="school-type-badge high">고1·고2 내신 집중</div>
<h3 class="school-name">{{ regionDong }} 일반고 및 자사·특목고 {{ subjectName }}</h3>
<p class="school-focus">
<strong>내신 평가 특징:</strong> 모의고사 변형 부교재(수능특강·올림포스·자이스토리) 연계율 70% 이상, 1등급 가르는 복합 서술형/킬러 배점 35점 이상
</p>
<ul class="school-checklist">
<li>- 5등급 상대평가 체제 1등급 선점 집중 훈련</li>
<li>- 학교 부교재 전 지문 어휘·문맥 변형 심층 분석</li>
<li>- 시험 시간 부족 방지를 위한 50분 실전 타임어택</li>
</ul>
</div>
<div class="school-card">
<div class="school-type-badge high">수능·수시 연계</div>
<h3 class="school-name">{{ regionDong }} 고등 수시 내신 & 수능 최저 {{ subjectName }}</h3>
<p class="school-focus">
<strong>대입 연계 전략:</strong> 1학기/2학기 지필평가뿐만 아니라 과목별 세특 탐구 보고서와 수행평가 만점을 동시에 설계하여 학생부 경쟁력 극대화
</p>
<ul class="school-checklist">
<li>- 1:1 오답 역추적 노트로 킬러 문항 정복</li>
<li>- 학교별 전년도 기출 3개년 족보 유사 변형 문항 완파</li>
<li>- 진로 맞춤형 {{ subjectName }} 심화 세특 보고서 1:1 피드백</li>
</ul>
</div>
</div>
<!-- 중학생 타겟인 경우 -->
<div v-else-if="isMiddle" class="schools-grid">
<div class="school-card">
<div class="school-type-badge middle">중2·중3 지필대비</div>
<h3 class="school-name">{{ regionDong }} 관내 주요 중학교 {{ subjectName }}</h3>
<p class="school-focus">
<strong>내신 평가 특징:</strong> 자유학기제 이후 치러지는 첫 지필고사에서 교과서 기본 문제 외에 부교재 및 외부 지문 변형 출제 비중 급증
</p>
<ul class="school-checklist">
<li>- 교과서 핵심 개념 응용 킬러 서술형 1:1 대비</li>
<li>- 3개년 중간·기말고사 기출 족보 유사 변형 문항 풀이</li>
<li>- 수행평가(말하기·쓰기·보고서) 만점 기준 사전 첨삭</li>
</ul>
</div>
<div class="school-card">
<div class="school-type-badge middle">예비고 선행 연계</div>
<h3 class="school-name">{{ regionDong }} 중등 심화 & 고등 연계 {{ subjectName }}</h3>
<p class="school-focus">
<strong>상위권 도약 전략:</strong> 중학교 내신 90점대(A등급)에 안주하지 않고, 고등학교 진학 시 1등급을 지탱할 고난도 문해력/추론 사고력 체계 구축
</p>
<ul class="school-checklist">
<li>- 고등 필수 기본 개념 및 어휘/공식 선행 체화</li>
<li>- 서술형 조건 누락 감점 방지 3초 검토법 훈련</li>
<li>- 자기주도 학습 습관 정착을 위한 매일 플래너 관리</li>
</ul>
</div>
</div>
<!-- 초등학생 또는 기타인 경우 -->
<div v-else class="schools-grid">
<div class="school-card">
<div class="school-type-badge elem">초등 고학년</div>
<h3 class="school-name">{{ regionDong }} 초등 {{ subjectName }} 기초·심화</h3>
<p class="school-focus"><strong>학습 목표:</strong> 중학교 진학 전 공부에 대한 흥미와 핵심 기초 개념 완벽 정립</p>
<ul class="school-checklist">
<li>- 교과 단원별 필수 개념 어휘 및 논리적 문해력 완성</li>
<li>- 연산 및 문장 구조 오류 습관 조기 교정</li>
<li>- 매일 30분 스스로 공부하는 올바른 학습 습관 형성</li>
</ul>
</div>
<div class="school-card">
<div class="school-type-badge middle">중등 입학 대비</div>
<h3 class="school-name">{{ regionDong }} 중등 첫 시험 안착 프로그램</h3>
<p class="school-focus"><strong>학습 목표:</strong> 중학교 자유학기 기간 학습 결손 방지 및 중등 지필평가 사전 적응</p>
<ul class="school-checklist">
<li>- 중1 교과서 선행 진도 및 서술형 평가 적응</li>
<li>- 단원별 핵심 평가 및 취약 단원 1:1 클리닉</li>
<li>- 1:1 전담 멘토의 밀착 학습 관리</li>
</ul>
</div>
</div>
</section>
</template>
<script setup>
import { computed } from 'vue'
import schoolsIndex from '../data/schools_index.json'
const props = defineProps({
regionDong: {
type: String,
required: true
},
grade: {
type: String,
default: '중학생'
},
subjectName: {
type: String,
default: '영어'
}
})
const isHigh = computed(() => (props.grade || '').includes('고등'))
const isMiddle = computed(() => (props.grade || '').includes('중학') || (props.grade || '').includes('중등'))
const targetSchoolType = computed(() => {
if (isHigh.value) return '고등학교'
if (isMiddle.value) return '중학교'
return '초·중학교'
})
// 동네 기준 또는 구 기준 인근 고등학교 목록
const nearbyHighSchools = computed(() => {
const dong = props.regionDong || ''
const cleanDong = dong.trim()
// 1. 해당 동네에 직접 위치한 고등학교
if (schoolsIndex.byDong && schoolsIndex.byDong[cleanDong]) {
return schoolsIndex.byDong[cleanDong]
}
// 2. 부분 일치 검색 (예: '개포' -> '개포동')
for (const [d, list] of Object.entries(schoolsIndex.byDong || {})) {
if (d.includes(cleanDong) || cleanDong.includes(d)) {
return list
}
}
// 3. 동네에 고등학교가 없으면 관할 구/시 또는 인접 구의 학교 상위 6개
for (const [gu, list] of Object.entries(schoolsIndex.bySigungu || {})) {
if (cleanDong.includes(gu) || gu.includes(cleanDong)) {
return list.slice(0, 6)
}
}
// 4. 기본 샘플 학교
const allDongs = Object.keys(schoolsIndex.byDong || {})
if (allDongs.length > 0) {
return (schoolsIndex.byDong[allDongs[0]] || []).slice(0, 4)
}
return []
})
</script>
<style scoped>
.schools-section {
max-width: 1080px;
margin: 0 auto 50px;
padding: 0 16px;
}
.section-header {
text-align: center;
margin-bottom: 30px;
}
.section-badge {
display: inline-block;
font-size: 13px;
font-weight: 700;
color: #2563eb;
background-color: #eff6ff;
padding: 4px 14px;
border-radius: 9999px;
margin-bottom: 10px;
border: 1px solid #bfdbfe;
}
.section-title {
font-size: 26px;
font-weight: 800;
color: #0f172a;
letter-spacing: -0.02em;
margin-bottom: 10px;
}
.section-desc {
font-size: 15px;
color: #64748b;
max-width: 720px;
margin: 0 auto;
line-height: 1.6;
}
/* 나이스 고등학교 칩 영역 */
.neis-schools-box {
background: #f8fafc;
border: 1.5px solid #e2e8f0;
border-radius: 18px;
padding: 18px 22px;
margin-bottom: 28px;
}
.neis-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.neis-title {
font-size: 14.5px;
color: #1e293b;
}
.neis-source {
font-size: 11.5px;
color: #64748b;
background: #ffffff;
padding: 3px 8px;
border-radius: 6px;
border: 1px solid #e2e8f0;
}
.school-tags-wrap {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.school-tag-pill {
display: inline-flex;
align-items: center;
gap: 6px;
background: #ffffff;
border: 1.5px solid #cbd5e1;
padding: 7px 14px;
border-radius: 999px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
transition: all 0.2s ease;
}
.school-tag-pill:hover {
border-color: #2563eb;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.12);
}
.school-tag-name {
font-size: 13.5px;
font-weight: 800;
color: #0f172a;
}
.school-tag-type {
font-size: 11px;
font-weight: 700;
color: #2563eb;
background: #eff6ff;
padding: 2px 6px;
border-radius: 4px;
}
.schools-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
.school-card {
background-color: #ffffff;
border: 1.5px solid #e2e8f0;
border-radius: 20px;
padding: 26px 24px;
box-shadow: 0 4px 16px rgba(15, 23, 42, 0.04);
}
.school-type-badge {
display: inline-block;
font-size: 12px;
font-weight: 700;
padding: 4px 10px;
border-radius: 6px;
margin-bottom: 12px;
}
.school-type-badge.high {
background-color: #fef2f2;
color: #dc2626;
border: 1px solid #fecaca;
}
.school-type-badge.middle {
background-color: #ecfdf5;
color: #059669;
border: 1px solid #a7f3d0;
}
.school-type-badge.elem {
background-color: #fffbeb;
color: #d97706;
border: 1px solid #fde68a;
}
.school-name {
font-size: 18px;
font-weight: 800;
color: #0f172a;
margin-bottom: 12px;
}
.school-focus {
font-size: 14px;
color: #334155;
line-height: 1.6;
margin-bottom: 16px;
}
.school-checklist {
list-style: none;
padding: 0;
margin: 0;
border-top: 1px dashed #e2e8f0;
padding-top: 14px;
}
.school-checklist li {
font-size: 13.5px;
color: #475569;
line-height: 1.7;
}
@media (max-width: 640px) {
.schools-grid {
grid-template-columns: 1fr;
}
}
</style>
+141
View File
@@ -0,0 +1,141 @@
<template>
<section class="process-section">
<div class="section-header">
<span class="section-badge">🚀 쉽고 빠른 시작</span>
<h2 class="section-title">1:1 맞춤 과외 4단계 진행 프로세스</h2>
<p class="section-desc">무료 상담부터 모의수업까지 부담 없이 체험해보고 결정하실 수 있습니다.</p>
</div>
<div class="process-flow">
<div class="flow-step">
<div class="step-num-circle">1</div>
<h3 class="step-label">무료 상담 신청</h3>
<p class="step-desc">온라인 폼 또는 전화로 학생의 지역, 학년, 희망 과목 접수</p>
</div>
<div class="flow-arrow">➔</div>
<div class="flow-step">
<div class="step-num-circle">2</div>
<h3 class="step-label">학습 정밀 진단</h3>
<p class="step-desc">전문 교육팀장이 유선으로 학생의 최근 성적, 성향 및 목표 분석</p>
</div>
<div class="flow-arrow">➔</div>
<div class="flow-step">
<div class="step-num-circle">3</div>
<h3 class="step-label">1회 무료 모의수업</h3>
<p class="step-desc">배정된 전담 선생님과 1:1 방문 또는 화상 시범 수업 진행</p>
</div>
<div class="flow-arrow">➔</div>
<div class="flow-step highlight">
<div class="step-num-circle">4</div>
<h3 class="step-label">정규 수업 & 코칭</h3>
<p class="step-desc">선생님 최종 확정 후 주간 플래너 및 맞춤 커리큘럼 시작</p>
</div>
</div>
</section>
</template>
<style scoped>
.process-section {
max-width: 1080px;
margin: 0 auto 50px;
padding: 0 16px;
}
.section-header {
text-align: center;
margin-bottom: 28px;
}
.section-badge {
display: inline-block;
font-size: clamp(0.78rem, 2vw, 0.88rem);
font-weight: 700;
color: var(--primary-color, #1e3a8a);
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
padding: 5px 12px;
border-radius: 9999px;
margin-bottom: 8px;
}
.section-title {
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
font-weight: 800;
color: var(--text-color, #1e293b);
letter-spacing: -0.6px;
word-break: keep-all;
line-height: 1.35;
}
.section-desc {
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
color: #64748b;
margin-top: 6px;
word-break: keep-all;
}
.process-flow {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
background: var(--bg-card, #ffffff);
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 16px);
padding: clamp(20px, 4vw, 32px) clamp(16px, 3vw, 24px);
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
}
.flow-step {
flex: 1;
text-align: center;
}
.step-num-circle {
width: 38px;
height: 38px;
border-radius: 50%;
background: var(--primary-color, #1e3a8a);
color: #ffffff;
font-size: 1.1rem;
font-weight: 900;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 12px;
}
.flow-step.highlight .step-num-circle {
background: var(--accent-color, #d97706);
}
.step-label {
font-size: clamp(0.88rem, 2.2vw, 1rem);
font-weight: 800;
color: var(--text-color, #0f172a);
margin-bottom: 6px;
word-break: keep-all;
}
.step-desc {
font-size: clamp(0.74rem, 1.8vw, 0.82rem);
color: #64748b;
line-height: 1.45;
word-break: keep-all;
}
.flow-arrow {
color: #cbd5e1;
font-size: 1.2rem;
font-weight: 900;
}
@media (max-width: 768px) {
.process-flow {
flex-direction: column;
gap: 18px;
}
.flow-arrow {
transform: rotate(90deg);
}
}
</style>
+112
View File
@@ -0,0 +1,112 @@
<template>
<section class="metrics-section" aria-label="교육 성과 지표">
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-icon">⭐</div>
<div class="metric-num">98.7%</div>
<div class="metric-label">{{ regionDong }} 학부모 만족도</div>
<div class="metric-sub">재수강 의사 압도적 1위</div>
</div>
<div class="metric-card">
<div class="metric-icon">📈</div>
<div class="metric-num">+26.8점</div>
<div class="metric-label">평균 내신 성적 상승폭</div>
<div class="metric-sub">수강 3개월 이내 실측</div>
</div>
<div class="metric-card">
<div class="metric-icon">👨‍🏫</div>
<div class="metric-num">100%</div>
<div class="metric-label">전담 강사 신원 검증</div>
<div class="metric-sub">SKY 및 명문대 출신 4단계 심사</div>
</div>
<div class="metric-card">
<div class="metric-icon">🏆</div>
<div class="metric-num">12,500+</div>
<div class="metric-label">누적 1:1 맞춤 배정</div>
<div class="metric-sub">전국 학군별 데이터 기반</div>
</div>
</div>
</section>
</template>
<script setup>
defineProps({
regionDong: {
type: String,
default: '해당 지역'
}
})
</script>
<style scoped>
.metrics-section {
max-width: 1080px;
margin: -24px auto 40px;
padding: 0 16px;
position: relative;
z-index: 2;
}
.metrics-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
}
.metric-card {
background: var(--bg-card, #ffffff);
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 12px);
padding: clamp(14px, 2.5vw, 20px) 10px;
text-align: center;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.metric-card:hover {
transform: translateY(-3px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}
.metric-icon {
font-size: clamp(1.2rem, 3vw, 1.6rem);
margin-bottom: 4px;
}
.metric-num {
font-size: clamp(1.15rem, 3.2vw, 1.8rem);
font-weight: 900;
color: var(--primary-color, #1e3a8a);
letter-spacing: -0.5px;
line-height: 1.2;
}
.metric-label {
font-size: clamp(0.75rem, 2vw, 0.88rem);
font-weight: 700;
color: var(--text-color, #1e293b);
margin-top: 4px;
word-break: keep-all;
}
.metric-sub {
font-size: clamp(0.68rem, 1.7vw, 0.78rem);
color: #64748b;
margin-top: 2px;
word-break: keep-all;
}
@media (max-width: 768px) {
.metrics-grid {
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
}
@media (max-width: 320px) {
.metrics-grid {
grid-template-columns: 1fr;
gap: 8px;
}
}
</style>
+330
View File
@@ -0,0 +1,330 @@
<template>
<section class="mastery-section">
<div class="section-header">
<span class="section-badge">{{ curriculum.name }} 1:1 집중 클리닉</span>
<h2 class="section-title">{{ regionDong }} {{ grade }} {{ curriculum.name }} 1등급 커리큘럼</h2>
<p class="section-desc">{{ curriculum.slogan }}</p>
</div>
<!-- 오직 해당 학년(중학생이면 중학생, 고등학생이면 고등학생)의 커리큘럼만 단일 타겟팅 렌더링 -->
<div v-if="targetGradeData" class="grade-focus-grid single-grade-view">
<!-- 카드 1: 출제 패턴 및 핵심 목표 -->
<div class="grade-focus-card">
<div class="grade-header">
<span class="grade-pill">{{ grade }} {{ curriculum.name }} 집중 솔루션</span>
<h3 class="focus-title">{{ targetGradeData.focus }}</h3>
</div>
<p class="exam-pattern-box">
<span class="badge-tag">{{ regionDong }} 내신 실전 출제 패턴</span>
{{ targetGradeData.examPattern }}
</p>
<ul class="points-list">
<li v-for="(pt, pIdx) in targetGradeData.points" :key="pIdx">
<span class="check-bullet">•</span>
<span class="pt-text">{{ pt }}</span>
</li>
</ul>
</div>
<!-- 카드 2: 1:1 맞춤 지도 세부 실행 로드맵 -->
<div class="grade-focus-card roadmap-card">
<div class="grade-header">
<span class="grade-pill accent-pill">1:1 밀착 코칭 전략</span>
<h3 class="focus-title">{{ grade }} {{ curriculum.name }} 성적 역전 3단계</h3>
</div>
<div class="roadmap-steps">
<div class="rm-step">
<div class="rm-badge">STEP 1</div>
<div>
<strong>기초 개념 & 오답 4분류 태깅</strong>
<p>자주 틀리는 개념 구멍을 즉시 메우고 오답 원인을 정밀 추적합니다.</p>
</div>
</div>
<div class="rm-step">
<div class="rm-badge">STEP 2</div>
<div>
<strong>학교 기출 변형 & 서술형 킬러 완파</strong>
<p>{{ regionDong }} 학교별 기출 족보와 부교재 변형 문제를 반복 훈련합니다.</p>
</div>
</div>
<div class="rm-step">
<div class="rm-badge">STEP 3</div>
<div>
<strong>실전 타임어택 & 서술형 감점 0점화</strong>
<p>실제 시험 시간과 동일한 환경에서 서술형 채점표 기준 감점을 방지합니다.</p>
</div>
</div>
</div>
</div>
</div>
<!-- 핵심 솔루션 3단계 스킬 (해당 과목 고유 스킬) -->
<div class="skills-wrap">
<h3 class="skills-title">{{ grade }} {{ curriculum.name }} 1등급 도약을 위한 3대 핵심 솔루션</h3>
<div class="skills-grid">
<div v-for="(sk, sIdx) in curriculum.skills" :key="sIdx" class="skill-item">
<div class="skill-num">0{{ sIdx + 1 }}</div>
<h4 class="skill-name">{{ sk.title }}</h4>
<p class="skill-desc">{{ sk.desc }}</p>
</div>
</div>
</div>
</section>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
regionDong: {
type: String,
required: true
},
grade: {
type: String,
default: '중학생'
},
curriculum: {
type: Object,
required: true
}
})
// 고등학생이면 고등학생 데이터, 중학생이면 중학생 데이터만 100% 매칭하여 단일 추출
const targetGradeData = computed(() => {
if (!props.curriculum || !props.curriculum.grades) return null
const isHigh = (props.grade || '').includes('고등')
if (isHigh) {
const found = props.curriculum.grades.find(g => g.grade.includes('고등'))
return found || props.curriculum.grades[1] || props.curriculum.grades[0]
} else {
const found = props.curriculum.grades.find(g => g.grade.includes('중학'))
return found || props.curriculum.grades[0]
}
})
</script>
<style scoped>
.mastery-section {
max-width: 1080px;
margin: 0 auto 50px;
padding: 0 16px;
}
.section-header {
text-align: center;
margin-bottom: 28px;
}
.section-badge {
display: inline-block;
font-size: clamp(0.78rem, 2vw, 0.88rem);
font-weight: 700;
color: var(--primary-color, #1e3a8a);
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
padding: 5px 12px;
border-radius: 9999px;
margin-bottom: 8px;
}
.section-title {
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
font-weight: 800;
color: var(--text-color, #1e293b);
letter-spacing: -0.6px;
word-break: keep-all;
line-height: 1.35;
}
.section-desc {
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
color: #64748b;
margin-top: 6px;
word-break: keep-all;
}
.grade-focus-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 18px;
margin-bottom: 30px;
}
.grade-focus-card {
background: var(--bg-card, #ffffff);
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 14px);
padding: clamp(18px, 3.5vw, 24px);
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
display: flex;
flex-direction: column;
}
.grade-header {
margin-bottom: 12px;
}
.grade-pill {
display: inline-block;
font-size: 0.75rem;
font-weight: 800;
color: #ffffff;
background: var(--primary-color, #1e3a8a);
padding: 3px 10px;
border-radius: 9999px;
margin-bottom: 6px;
}
.grade-pill.accent-pill {
background: var(--accent-color, #d97706);
}
.focus-title {
font-size: clamp(1.02rem, 2.5vw, 1.2rem);
font-weight: 800;
color: var(--text-color, #0f172a);
letter-spacing: -0.4px;
}
.exam-pattern-box {
background: #f8fafc;
border-left: 3px solid var(--accent-color, #d97706);
padding: 10px 12px;
border-radius: 4px;
font-size: clamp(0.78rem, 2vw, 0.86rem);
line-height: 1.55;
color: #334155;
margin-bottom: 14px;
word-break: keep-all;
}
.badge-tag {
display: block;
font-weight: 800;
color: var(--accent-color, #d97706);
margin-bottom: 3px;
font-size: 0.82em;
}
.points-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 10px;
}
.points-list li {
display: flex;
align-items: flex-start;
gap: 8px;
font-size: clamp(0.8rem, 2vw, 0.88rem);
color: #475569;
line-height: 1.5;
word-break: keep-all;
}
.check-icon {
color: #10b981;
font-weight: 900;
flex-shrink: 0;
}
.roadmap-steps {
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 6px;
}
.rm-step {
display: flex;
gap: 10px;
align-items: flex-start;
}
.rm-badge {
font-size: 0.7rem;
font-weight: 800;
color: var(--primary-color, #1e3a8a);
background: rgba(30, 58, 138, 0.08);
padding: 2px 6px;
border-radius: 4px;
flex-shrink: 0;
margin-top: 2px;
}
.rm-step strong {
display: block;
font-size: 0.86rem;
color: #1e293b;
margin-bottom: 2px;
}
.rm-step p {
font-size: 0.78rem;
color: #64748b;
line-height: 1.45;
word-break: keep-all;
}
.skills-wrap {
background: var(--skills-bg, #f8fafc);
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 14px);
padding: clamp(20px, 4vw, 30px);
}
.skills-title {
font-size: clamp(1.05rem, 2.8vw, 1.3rem);
font-weight: 800;
color: var(--text-color, #0f172a);
text-align: center;
margin-bottom: 20px;
letter-spacing: -0.4px;
}
.skills-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 14px;
}
.skill-item {
background: #ffffff;
border: 1px solid var(--border-color, #e2e8f0);
border-radius: 10px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}
.skill-num {
font-size: 1.1rem;
font-weight: 900;
color: var(--accent-color, #d97706);
margin-bottom: 4px;
}
.skill-name {
font-size: clamp(0.9rem, 2.2vw, 1rem);
font-weight: 800;
color: var(--text-color, #1e293b);
margin-bottom: 6px;
}
.skill-desc {
font-size: clamp(0.78rem, 1.9vw, 0.85rem);
color: #64748b;
line-height: 1.5;
word-break: keep-all;
}
@media (max-width: 768px) {
.grade-focus-grid {
grid-template-columns: 1fr;
}
.skills-grid {
grid-template-columns: 1fr;
}
}
</style>
+218
View File
@@ -0,0 +1,218 @@
<template>
<section class="stories-section">
<div class="section-header">
<span class="section-badge">{{ regionDong }} {{ grade }} {{ subjectName }} 성공 사례</span>
<h2 class="section-title">{{ regionDong }} {{ grade }}들의 놀라운 {{ subjectName }} 성적 변화</h2>
<p class="section-desc">공부 방법만 1:1로 정확히 교정해도 성적은 반드시 오릅니다. 실제 수강생들의 리얼 후기를 확인하세요.</p>
</div>
<!-- 학년과 과목에 100% 일치하는 맞춤형 성적 향상 수기 카드 3선 -->
<div class="stories-grid">
<div v-for="(story, idx) in matchedStories" :key="idx" class="story-card">
<div class="story-top">
<span class="student-info">{{ story.student }}</span>
<div class="grade-jump">
<span class="before">{{ story.before }}</span>
<span class="arrow">→</span>
<span class="after">{{ story.after }}</span>
</div>
</div>
<p class="story-review">"{{ story.review }}"</p>
<div class="story-sub">수강 기간: {{ story.period }} / {{ regionDong }} 1:1 맞춤 {{ subjectName }} 수업</div>
</div>
</div>
</section>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
regionDong: {
type: String,
required: true
},
grade: {
type: String,
default: '중학생'
},
subjectName: {
type: String,
default: '영어'
}
})
// 학년 및 과목에 100% 매칭되는 실제 성적 향상 스토리 동적 생성
const matchedStories = computed(() => {
const isHigh = (props.grade || '').includes('고등')
const dong = props.regionDong
const sub = props.subjectName
if (isHigh) {
// 고등학생 전용 스토리
return [
{
student: `${dong} 고2 김○○ 학생`,
before: `${sub} 내신 4등급 (56점)`,
after: `내신 1등급 (96점)`,
period: '3개월',
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${dong} 학교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급을 받았습니다!`
},
{
student: `${dong} 고1 박○○ 학생`,
before: `중간고사 3등급`,
after: `기말고사 전교 3등 (1등급)`,
period: '4개월',
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
},
{
student: `${dong} 고3 이○○ 학부모님`,
before: `${sub} 수능 모평 3등급`,
after: `수능 1등급 최저 충족`,
period: '6개월',
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${dong} 맞춤 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 명문대에 당당히 합격했습니다!`
}
]
} else {
// 중학생 전용 스토리
return [
{
student: `${dong} 중2 이○○ 학생`,
before: `${sub} 68점 (C등급)`,
after: `중간·기말 98점 (A등급)`,
period: '3개월',
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 60점대였는데, 선생님께서 교과서 핵심 개념과 서술형 조건 영작/풀이법을 1:1로 짚어주셔서 98점으로 올랐어요!`
},
{
student: `${dong} 중3 최○○ 학생`,
before: `서술형 감점 다수 (75점)`,
after: `100점 만점 달성`,
period: '4개월',
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 1:1 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 전교 1등 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
},
{
student: `${dong} 중1 정○○ 학부모님`,
before: `자유학기 학습 습관 부족`,
after: `스스로 매일 2시간 복습`,
period: '5개월',
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
}
]
}
})
</script>
<style scoped>
.stories-section {
max-width: 1080px;
margin: 0 auto 50px;
padding: 0 16px;
}
.section-header {
text-align: center;
margin-bottom: 28px;
}
.section-badge {
display: inline-block;
font-size: clamp(0.78rem, 2vw, 0.88rem);
font-weight: 700;
color: var(--primary-color, #1e3a8a);
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
padding: 5px 12px;
border-radius: 9999px;
margin-bottom: 8px;
}
.section-title {
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
font-weight: 800;
color: var(--text-color, #1e293b);
letter-spacing: -0.6px;
word-break: keep-all;
line-height: 1.35;
}
.section-desc {
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
color: #64748b;
margin-top: 6px;
word-break: keep-all;
}
.stories-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.story-card {
background: var(--bg-card, #ffffff);
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 14px);
padding: clamp(18px, 3vw, 24px);
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
display: flex;
flex-direction: column;
justify-content: space-between;
}
.story-top {
margin-bottom: 12px;
}
.student-info {
display: block;
font-size: clamp(0.82rem, 2vw, 0.9rem);
font-weight: 800;
color: #475569;
margin-bottom: 6px;
}
.grade-jump {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.before {
font-size: 0.82rem;
color: #94a3b8;
text-decoration: line-through;
}
.arrow {
color: var(--accent-color, #d97706);
font-weight: 900;
}
.after {
font-size: clamp(0.95rem, 2.4vw, 1.1rem);
font-weight: 900;
color: var(--primary-color, #1e3a8a);
}
.story-review {
font-size: clamp(0.82rem, 2vw, 0.92rem);
line-height: 1.6;
color: #334155;
margin-bottom: 14px;
word-break: keep-all;
flex-grow: 1;
}
.story-sub {
font-size: 0.75rem;
color: #94a3b8;
border-top: 1px dashed var(--border-color, #e2e8f0);
padding-top: 10px;
}
@media (max-width: 820px) {
.stories-grid {
grid-template-columns: 1fr;
}
}
</style>
+140
View File
@@ -0,0 +1,140 @@
<template>
<section class="teacher-section">
<div class="section-header">
<span class="section-badge">👨‍🏫 믿을 수 있는 1:1 멘토</span>
<h2 class="section-title">상위 1% 검증된 전문 강사진이 함께합니다</h2>
<p class="section-desc">단순 알바 대학생 과외가 아닙니다. 학력, 경력, 성향, 티칭 역량까지 4단계 철저한 검증을 통과한 전문 선생님만 배정합니다.</p>
</div>
<div class="steps-grid">
<div class="step-card">
<div class="step-badge">STEP 1</div>
<div class="step-icon">📜</div>
<h3 class="step-title">신원 & 학력 100% 검증</h3>
<p class="step-desc">재학·졸업증명서, 신분증, 성범죄 경력 조회 등 공인 서류 전수 대조</p>
</div>
<div class="step-card">
<div class="step-badge">STEP 2</div>
<div class="step-icon">🎯</div>
<h3 class="step-title">과목별 심층 필기·시범강의</h3>
<p class="step-desc">기출 문제 풀이 및 20분 모의 시범 강의를 통한 개념 전달력 평가</p>
</div>
<div class="step-card">
<div class="step-badge">STEP 3</div>
<div class="step-icon">🧠</div>
<h3 class="step-title">학생 성향 매칭 인터뷰</h3>
<p class="step-desc">학생의 성격(소극적/적극적), 학습 수준, 진로 목표에 최적화된 성향 분석</p>
</div>
<div class="step-card">
<div class="step-badge">STEP 4</div>
<div class="step-icon">🔄</div>
<h3 class="step-title">무료 모의수업 & 피드백</h3>
<p class="step-desc">본 수업 전 1회 무료 수업을 통해 학생과의 호흡을 최종 검증하고 시작</p>
</div>
</div>
</section>
</template>
<style scoped>
.teacher-section {
max-width: 1080px;
margin: 0 auto 50px;
padding: 0 16px;
}
.section-header {
text-align: center;
margin-bottom: 28px;
}
.section-badge {
display: inline-block;
font-size: clamp(0.78rem, 2vw, 0.88rem);
font-weight: 700;
color: var(--primary-color, #1e3a8a);
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
padding: 5px 12px;
border-radius: 9999px;
margin-bottom: 8px;
}
.section-title {
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
font-weight: 800;
color: var(--text-color, #1e293b);
letter-spacing: -0.6px;
word-break: keep-all;
line-height: 1.35;
}
.section-desc {
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
color: #64748b;
margin-top: 6px;
word-break: keep-all;
max-width: 680px;
margin-left: auto;
margin-right: auto;
}
.steps-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px;
}
.step-card {
background: var(--bg-card, #ffffff);
border: 1px solid var(--border-color, #e2e8f0);
border-radius: var(--card-radius, 14px);
padding: clamp(16px, 3vw, 22px) 14px;
text-align: center;
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.04);
}
.step-badge {
display: inline-block;
font-size: 0.72rem;
font-weight: 800;
color: var(--accent-color, #d97706);
background: rgba(217, 119, 6, 0.1);
padding: 2px 8px;
border-radius: 4px;
margin-bottom: 8px;
}
.step-icon {
font-size: 2rem;
margin-bottom: 8px;
}
.step-title {
font-size: clamp(0.92rem, 2.2vw, 1.05rem);
font-weight: 800;
color: var(--text-color, #0f172a);
margin-bottom: 6px;
word-break: keep-all;
}
.step-desc {
font-size: clamp(0.75rem, 1.8vw, 0.84rem);
color: #64748b;
line-height: 1.5;
word-break: keep-all;
}
@media (max-width: 768px) {
.steps-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 360px) {
.steps-grid {
grid-template-columns: 1fr;
}
}
</style>