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
+6
View File
@@ -0,0 +1,6 @@
.nuxt
.output
node_modules
.git
.env
npm-debug.log
+5
View File
@@ -0,0 +1,5 @@
node_modules
.nuxt
.output
.env
.env.*
+25
View File
@@ -0,0 +1,25 @@
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Production runner stage
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=80
ENV HOST=0.0.0.0
COPY --from=builder /app/.output ./.output
EXPOSE 80
CMD ["node", ".output/server/index.mjs"]
+63
View File
@@ -0,0 +1,63 @@
<template>
<div class="site-wrapper">
<!-- Header는 사용자 요청에 의해 제외 -->
<main class="site-main">
<NuxtPage />
</main>
<AppFooter />
</div>
</template>
<script setup>
// Header 없는 클린 랜딩 구조
</script>
<style>
/* Reset & Base Layout */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-family: "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", sans-serif;
font-size: 16px;
line-height: 1.5;
color: var(--text-color, #1e293b);
background-color: var(--bg-body, #ffffff);
-webkit-text-size-adjust: 100%;
word-break: keep-all;
overflow-x: hidden;
}
body {
width: 100%;
min-width: 280px;
overflow-x: hidden;
background-color: var(--bg-body, #ffffff);
}
.site-wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
overflow-x: hidden;
}
.site-main {
flex: 1;
width: 100%;
}
a {
color: inherit;
text-decoration: none;
}
button, input, select, textarea {
font-family: inherit;
font-size: inherit;
}
</style>
+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: #fafbff;
border: 1px solid #c7d2fe;
border-radius: 8px;
box-shadow: 0 8px 24px rgba(79, 70, 229, 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: #3730a3;
letter-spacing: -0.5px;
margin-bottom: 8px;
line-height: 1.3;
}
.consult-desc {
font-size: clamp(0.88rem, 2.2vw, 0.98rem);
color: #4f46e5;
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: #312e81;
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: #f5f7ff;
border: 1px solid #c7d2fe;
border-radius: 6px;
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: #4f46e5;
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.25);
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: #6366f1;
line-height: 1.45;
cursor: pointer;
}
.privacy-checkbox {
margin-top: 3px;
cursor: pointer;
width: 16px;
height: 16px;
accent-color: #4f46e5;
}
.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: #4f46e5;
border: none;
border-radius: 8px;
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: #4338ca;
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: #4338ca;
background: #eef2ff;
border: 2px solid #4f46e5;
border-radius: 8px;
cursor: pointer;
text-decoration: none;
transition: all 0.2s ease;
letter-spacing: -0.3px;
box-sizing: border-box;
}
.btn-call:hover {
background: #e0e7ff;
}
.success-box {
text-align: center;
padding: 40px 20px;
}
.success-title {
font-size: 1.25rem;
font-weight: 800;
color: #3730a3;
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: #4f46e5;
background: transparent;
border: 1px solid #4f46e5;
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>
+207
View File
@@ -0,0 +1,207 @@
{
"korean": {
"name": "국어",
"badge": "문해력·서술형·수능비문학",
"slogan": "어휘력과 구조 독해로 내신 1등급과 수능 1등급을 동시에",
"grades": [
{
"grade": "중학생 국어",
"focus": "갈래별 개념어 확립 및 서술형 감점 0점화",
"points": [
"교과서 수록 문학(시·소설·수필) 핵심 개념어와 표현상의 특징 완벽 암기",
"문법(품사, 문장 성분, 음운 변동) 체계도 직접 작성 훈련",
"서술형 채점 기준표(조건 단어 누락 방지) 기반 1:1 첨삭 지도"
],
"examPattern": "학교별 교과서 학습활동 응용 및 외부 연계 현대시 출제 비중 35% 이상"
},
{
"grade": "고등학생 국어",
"focus": "수능 연계 EBS 독서·문학 및 내신 킬러 외부지문 정복",
"points": [
"낯선 고전문학 해석을 위한 필수 고어 150선 및 시가 갈래별 공식 체화",
"독서(비문학) 철학·경제·과학기술 제재 문단 간 유기적 독해 및 도표 분석 훈련",
"시험 범위 외 학교 프린트 및 학평/모평 기출 변형 킬러 문항 대비"
],
"examPattern": "객관식 보기 변형 및 5지선다 오답 매력도 극대화, 서술형 1문항 당 부분점수 3~4개 조건 제시"
}
],
"skills": [
{
"title": "문학 개념어 사전화",
"desc": "반어, 역설, 감정이입 등 헷갈리기 쉬운 개념어를 기출 예문과 매칭"
},
{
"title": "비문학 3색 펜 구조화",
"desc": "주제문, 근거, 대립 쌍을 시각적으로 도식화하는 독해 훈련"
},
{
"title": "서술형 키워드 적중",
"desc": "출제자가 요구하는 필수 조건 키워드를 1초 만에 캐치하여 답안 작성"
}
]
},
"english": {
"name": "영어",
"badge": "구문독해·조건영작·내신1등급",
"slogan": "단어 암기 그 이상, 문장 구조 분석과 서술형 통암기 탈피 훈련",
"grades": [
{
"grade": "중학생 영어",
"focus": "핵심 문법 뼈대 완성과 교과서 본문 어법 변형 대비",
"points": [
"to부정사, 동명사, 관계대명사, 수동태 등 핵심 10대 문법 완벽 정복",
"교과서 대화문 및 본문 단순 암기가 아닌 어법 변형 문항 실전 풀이",
"중간·기말고사 대비 서술형 조건 영작(단어 수 제한, 형태 변형) 집중 훈련"
],
"examPattern": "어법상 어색한 문장 개수 고르기(모두 고르시오) 및 본문 빈칸 영작 출제"
},
{
"grade": "고등학생 영어",
"focus": "모의고사 변형 부교재 완벽 분석 및 1등급 가르는 킬러 영작",
"points": [
"학교별 부교재(수능특강, 올림포스, 자이스토리) 외부 지문 패러프레이징 분석",
"어휘 유의어/반의어 정리 및 지문 내용 빈칸 추론 변형 완벽 대비",
"서술형 주제문 영작(도치, 가정법, 분사구문 등 복합 구문 적용)"
],
"examPattern": "지문 어휘 변형 40% 이상, 서술형 조건 영작 배점 30점 이상으로 최상위권 변별"
}
],
"skills": [
{
"title": "구문 끊어읽기 맵핑",
"desc": "주어·동사·수식어구를 직관적으로 묶어 긴 복문도 3초 내 파악"
},
{
"title": "학교별 기출 족보 변형",
"desc": "최근 3개년 학교 기출 문항 유형을 분석하여 유사 변형 문제 반복 풀이"
},
{
"title": "서술형 감점 방지 훈련",
"desc": "단복수, 수일치, 시제, 전치사 오류를 사전에 차단하는 셀프 검토법"
}
]
},
"math": {
"name": "수학",
"badge": "개념정립·오답클리닉·킬러문항",
"slogan": "공식 암기가 아닌 개념 원리 추론, 오답의 원인을 뿌리 뽑는 1:1 솔루션",
"grades": [
{
"grade": "중학생 수학",
"focus": "연산 실수 제로화 및 중등 도형·대수 연계 심화 개념 체화",
"points": [
"소인수분해부터 이차방정식, 이차함수까지 고등 연계 대수 영역 기초 확립",
"삼각형·원의 성질 등 중등 기하(도형) 성질을 증명하고 적용하는 논리력 훈련",
"계산 실수 노트를 통한 자주 틀리는 계산 유형 집중 교정"
],
"examPattern": "교과서 외 심화 유형서(에이급, 블랙라벨) 스텝 2~3 수준 3~4문항 출제"
},
{
"grade": "고등학생 수학",
"focus": "공통수학 및 수1, 수2, 미적분/확통 킬러 4점 문항 정복",
"points": [
"개념의 유도 과정부터 실전 적용까지 백지 복습법으로 완전 체화",
"모의고사/수능 기출 준킬러 문항의 조건 해석 및 발상 노트 작성",
"학교별 부교재(EBS, 수능완성 등) 반복 회독 및 서술형 단계별 감점 요소 제거"
],
"examPattern": "제한 시간 50분 대비 문항 수가 많아 시간 안배 및 준킬러 신속 풀이가 1등급 결정"
}
],
"skills": [
{
"title": "1:1 오답 역추적 클리닉",
"desc": "틀린 문제의 개념 오류인지 연산 실수인지 정확히 분리해 맞춤 처방"
},
{
"title": "조건 해석 공식화",
"desc": "문제 속 숨은 수학적 조건(정수 조건, 범위, 극값 등)을 찾아내는 훈련"
},
{
"title": "실전 타임어택 모의평가",
"desc": "실제 시험과 동일한 OMR 카드와 시간 제한으로 실전 긴장감 극복"
}
]
},
"science": {
"name": "과학",
"badge": "통합과학·물화생지·탐구보고서",
"slogan": "원리 이해와 실험 탐구, 킬러 계산 문항까지 완벽 대비",
"grades": [
{
"grade": "중학생 과학",
"focus": "물상/생물 영역의 기본 법칙 이해와 암기 체계화",
"points": [
"빛과 파동, 화학반응식, 유전 등 복잡한 과학 원리의 시각적 도식화 이해",
"단원별 핵심 과학 용어와 정의 완벽 암기",
"실험 과정-결과-해석으로 이어지는 탐구형 문항 정복"
],
"examPattern": "실험 보고서 기반 객관식 문항 및 오차 원인 분석 서술형 출제"
},
{
"grade": "고등학생 통합과학/과탐",
"focus": "통합과학 내신 1등급 및 과탐 I/II 수능 연계 킬러 정복",
"points": [
"역학적 시스템(물리), 중화반응·산화환원(화학) 고난도 계산 집중 공략",
"지구시스템, 생명시스템의 방대한 암기 내용을 마인드맵으로 일목요연 정리",
"과학탐구실험 수행평가 만점 보고서 작성 1:1 컨설팅"
],
"examPattern": "수능형 자료(그래프, 실험 도표) 해석 문항이 50% 이상 차지하여 자료 해석력 필수"
}
],
"skills": [
{
"title": "원리 도해 노트",
"desc": "복잡한 과학 현상을 그림과 도표로 직접 그려보며 원리 직관화"
},
{
"title": "자료 해석 3단계 스캔",
"desc": "가로축/세로축 변인 통제 -> 변곡점 확인 -> 결론 도출의 정형화"
},
{
"title": "서술형 과학 용어 완성",
"desc": "교과서 공인 학술 용어를 사용하여 채점관 감점 빌미 제거"
}
]
},
"social": {
"name": "사회",
"badge": "통합사회·한국사·수행평가",
"slogan": "단순 암기가 아닌 역사적 흐름과 시사 자료 분석의 융합",
"grades": [
{
"grade": "중학생 사회/역사",
"focus": "시대순 연표 흐름과 지리·일반사회 기본 개념 정립",
"points": [
"한국사 및 세계사 핵심 사건의 원인-전개-결과 인과관계 구조화",
"지형도, 기후 그래프, 지도 자료를 보고 특징을 유추하는 시각 자료 분석",
"정치와 법, 경제 단원의 헷갈리는 사회 제도 용어 정리"
],
"examPattern": "지도 및 사료 제시형 문항, 시대 순서 배열 문항 다수 출제"
},
{
"grade": "고등학생 통합사회/한국사",
"focus": "통합사회 융합 서술형 및 수능 필수 한국사 만점 전략",
"points": [
"사회적 딜레마(윤리, 환경, 인권) 관련 학교별 수행평가 논술 1:1 지도",
"사탐 선택과목(생윤, 사문, 한지, 정법 등) 킬러 도표·양적 계산 완벽 훈련",
"한국사 근현대사 촘촘한 연도별 조약 및 단체 활동 암기 카드 제공"
],
"examPattern": "지문 사료의 미세한 단서를 통한 인물/사건 특정 및 시사 융합 서술형 출제"
}
],
"skills": [
{
"title": "인과관계 스토리텔링",
"desc": "역사적 사건의 전후 맥락을 인과관계로 엮어 잊히지 않는 장기기억화"
},
{
"title": "통계/도표 역산 기법",
"desc": "사회문화, 한국지리 등 킬러 통계 문항의 빠른 수식 계산법 전수"
},
{
"title": "세특 연계 보고서 가이드",
"desc": "사회적 쟁점을 학생의 희망 진로와 연결하는 탐구 보고서 피드백"
}
]
}
}
File diff suppressed because it is too large Load Diff
+746
View File
@@ -0,0 +1,746 @@
{
"영어": {
"name": "영어",
"slug": "english",
"badge": "수능·내신 1등급",
"summary": "중·고등 1:1 밀착 내신 서술형 및 수능 1등급 집중 완성",
"coreKeywords": [
"영어 과외",
"영어 내신 과외",
"영어 내신 대비",
"영어 학원",
"영어 1:1 과외",
"공통영어 과외",
"영어 서술형 대비",
"수능 영어 과외",
"영어 전문 과외",
"내신 영어 학원"
],
"studentKeywords": {
"시험 정보": [
"영어 기출",
"영어 기출문제",
"영어 족보",
"영어 시험범위",
"영어 시험 난이도",
"영어 중간고사",
"영어 기말고사",
"영어 서술형",
"영어 시험 유형",
"영어 출제 경향",
"영어 평균",
"영어 등급컷",
"영어 시험 후기",
"영어 시험 시간 부족",
"수능특강 영어"
],
"교재·지문": [
"영어 부교재",
"영어 교과서",
"영어 교과서 출판사",
"영어 프린트",
"영어 필기",
"영어 외부지문",
"영어 연계 지문",
"모의고사 변형문제",
"영어 지문 분석",
"공통영어 기출",
"영어1 기출",
"영어2 기출",
"영어 단어장",
"영어 구문독해",
"어법 끝"
],
"공부·성적": [
"영어 1등급",
"영어 2등급",
"영어 공부법",
"영어 내신 공부법",
"영어 등급 올리는 법",
"영어 문법 정리",
"영어 벼락치기",
"영어 서술형 감점",
"영어 단어 암기법",
"영어 모의고사 1등급",
"영포자 탈출",
"영어 빈칸추론",
"영어 순서배열",
"영어 세특 주제",
"영어 성취도 분포"
]
},
"parentKeywords": {
"과외·학원 찾기": [
"영어 과외 선생님 추천",
"영어 과외 구하기",
"영어 방문 과외",
"영어 화상 과외",
"영어 개인과외",
"영어 과외 비용",
"영어 과외비",
"영어 과외 후기",
"영어 과외 상담",
"영어 학원 추천",
"영어 근처 학원",
"영어 과외 vs 학원",
"영어 대학생 과외",
"영어 전문 강사 과외",
"영어 단기 과외"
],
"과목·학년": [
"공통영어 과외",
"공통영어1 과외",
"공통영어2 과외",
"영어1 과외",
"영어2 과외",
"1학년 영어 과외",
"2학년 영어 과외",
"3학년 영어 과외",
"예비고1 영어 과외",
"영어 선행",
"영어 문법 과외",
"영어 독해 과외",
"영어 구문 과외",
"영어 어휘 과외",
"영어 서술형 과외"
],
"성적·시기": [
"영어 내신 올리기",
"영어 등급 올리기",
"영어 기초 과외",
"영어 심화 과외",
"영포자 과외",
"영어 노베이스 과외",
"영어 하위권 과외",
"영어 상위권 과외",
"영어 서술형 대비",
"영어 중간고사 대비 과외",
"영어 기말고사 대비 과외",
"영어 시험기간 단기 과외",
"영어 겨울방학 과외",
"영어 내신 수능 병행",
"수능 영어 과외"
]
}
},
"국어": {
"name": "국어",
"slug": "korean",
"badge": "독서·문학·문법 완벽대비",
"summary": "교과서 및 외부지문 완벽 분석, 서술형 감점 제로 및 수능 국어 연계 훈련",
"coreKeywords": [
"국어 과외",
"국어 내신 과외",
"국어 내신 대비",
"국어 내신",
"국어 학원",
"국어 1:1 과외",
"국어 전문 과외",
"국어 과외 추천",
"국어 과외 선생님",
"국어 내신 학원"
],
"studentKeywords": {
"시험 정보": [
"국어 기출",
"국어 기출문제",
"국어 족보",
"국어 시험범위",
"국어 시험 난이도",
"국어 중간고사",
"국어 기말고사",
"국어 서술형",
"국어 시험 유형",
"국어 출제 경향",
"국어 평균",
"국어 등급컷",
"국어 시험 후기",
"국어 시험 시간 부족",
"문학 시험범위"
],
"교재·지문": [
"국어 부교재",
"국어 교과서",
"국어 교과서 출판사",
"국어 프린트",
"국어 필기",
"국어 수업 필기 정리",
"국어 외부지문",
"국어 연계 작품",
"국어 모의고사 변형",
"국어 변형문제",
"국어 작품 정리",
"공통국어 기출",
"공통국어 시험범위",
"문학 기출",
"독서와 작문 기출"
],
"공부·성적": [
"국어 1등급",
"국어 2등급",
"국어 공부법",
"국어 내신 공부법",
"국어 올리는 법",
"국어 문법",
"국어 문법 정리",
"국어 벼락치기",
"국어 서술형 감점",
"국어 수행평가",
"국어 독서 수행평가",
"국어 글쓰기 수행평가",
"국어 발표 수행평가",
"국어 세특 주제",
"국어 성취도 분포"
]
},
"parentKeywords": {
"과외·학원 찾기": [
"국어 과외 선생님 추천",
"국어 과외 구하기",
"국어 방문 과외",
"국어 화상 과외",
"국어 개인과외",
"국어 과외 비용",
"국어 과외비",
"국어 과외 후기",
"국어 과외 상담",
"국어 학원 추천",
"국어 근처 학원",
"국어 과외 vs 학원",
"국어 대학생 과외",
"국어 전문 강사 과외",
"국어 단기 과외"
],
"과목·학년": [
"공통국어 과외",
"공통국어1 과외",
"공통국어2 과외",
"문학 과외",
"독서 과외",
"독서와 작문 과외",
"화법과 언어 과외",
"국어 문법 과외",
"비문학 과외",
"고전문학 과외",
"1학년 국어 과외",
"2학년 국어 과외",
"3학년 국어 과외",
"예비고1 국어 과외",
"국어 선행"
],
"성적·시기": [
"국어 내신 올리기",
"국어 등급 올리기",
"국어 기초 과외",
"국어 심화 과외",
"국어 노베이스 과외",
"국어 하위권 과외",
"국어 상위권 과외",
"국어 서술형 대비",
"국어 중간고사 대비 과외",
"국어 기말고사 대비 과외",
"국어 시험기간 단기 과외",
"국어 겨울방학 과외",
"국어 내신 수능 병행",
"수능 국어 과외",
"국어 독해력 과외"
]
}
},
"수학": {
"name": "수학",
"slug": "math",
"badge": "개념 완성·킬러 문항 정복",
"summary": "공통수학·대수·미적분·기하 개념부터 심화 킬러문항까지 1:1 맞춤 피드백",
"coreKeywords": [
"수학 과외",
"수학 내신 과외",
"수학 내신 대비",
"수학 학원",
"수학 1:1 과외",
"공통수학 과외",
"수학 서술형 대비",
"수능 수학 과외",
"수학 전문 과외",
"수포자 탈출 과외"
],
"studentKeywords": {
"시험 정보": [
"수학 기출",
"수학 기출문제",
"수학 족보",
"수학 시험범위",
"수학 시험 난이도",
"수학 중간고사",
"수학 기말고사",
"수학 서술형",
"수학 출제 경향",
"수학 평균",
"수학 등급컷",
"수학 시험 후기",
"수학 시간 부족",
"공통수학 기출",
"대수 기출"
],
"교재·지문": [
"수학 부교재",
"수학 교과서",
"수학 교과서 출판사",
"수학 프린트",
"수학 오답노트",
"수학 부교재 변형문제",
"쎈 수학",
"블랙라벨",
"일품",
"마더텅 수학",
"자이스토리",
"수학 서술형 풀이집",
"수학 개념원리",
"수학의 정석",
"수학 수행평가"
],
"공부·성적": [
"수학 1등급",
"수학 2등급",
"수학 공부법",
"수학 내신 공부법",
"수학 올리는 법",
"수학 공식 암기법",
"수학 벼락치기",
"수학 서술형 감점 방지",
"수포자 공부법",
"수학 킬러문제 풀이법",
"수학 오답 정리법",
"수학 세특 주제",
"수학 성취도 분포",
"수학 모의고사 1등급",
"수학 계산실수 줄이기"
]
},
"parentKeywords": {
"과외·학원 찾기": [
"수학 과외 선생님 추천",
"수학 과외 구하기",
"수학 방문 과외",
"수학 화상 과외",
"수학 개인과외",
"수학 과외 비용",
"수학 과외비",
"수학 과외 후기",
"수학 과외 상담",
"수학 학원 추천",
"수학 근처 학원",
"수학 과외 vs 학원",
"수학 대학생 과외",
"수학 전문 강사 과외",
"수학 단기 과외"
],
"과목·학년": [
"공통수학1 과외",
"공통수학2 과외",
"대수 과외",
"미적분1 과외",
"미적분2 과외",
"확률과 통계 과외",
"기하 과외",
"1학년 수학 과외",
"2학년 수학 과외",
"3학년 수학 과외",
"예비고1 수학 선행",
"중학 수학 총정리",
"고등 수학 선행",
"수학 심화 과외",
"수학 기초 과외"
],
"성적·시기": [
"수학 내신 올리기",
"수학 등급 올리기",
"수학 기초 과외",
"수학 심화 과외",
"수포자 과외",
"수학 노베이스 과외",
"수학 하위권 과외",
"수학 상위권 과외",
"수학 서술형 대비",
"수학 중간고사 대비 과외",
"수학 기말고사 대비 과외",
"수학 시험기간 단기 과외",
"수학 방학 특강 과외",
"내신 수능 병행 수학",
"수능 수학 과외"
]
}
},
"과학": {
"name": "과학",
"slug": "science",
"badge": "통합과학·물화생지 마스터",
"summary": "원리 이해와 계산 추론 완벽 정리, 탐구실험 수행평가 및 서술형 평가 집중 대비",
"coreKeywords": [
"과학 과외",
"과학 내신 과외",
"과학 내신 대비",
"통합과학 과외",
"과학 학원",
"과학 내신",
"통합과학 내신",
"과학 1:1 과외",
"과학 전문 과외",
"과학 과외 선생님"
],
"studentKeywords": {
"시험 정보": [
"과학 기출",
"과학 기출문제",
"과학 족보",
"과학 시험범위",
"과학 시험 난이도",
"과학 중간고사",
"과학 기말고사",
"과학 서술형",
"과학 시험 유형",
"과학 출제 경향",
"과학 평균",
"과학 등급컷",
"과학 시험 후기",
"과학 부교재",
"과학 교과서"
],
"과목별": [
"통합과학 기출",
"통합과학 시험범위",
"통합과학 시험 난이도",
"통합과학 서술형",
"통합과학 교과서",
"물리 기출",
"물리 시험범위",
"화학 기출",
"화학 시험범위",
"생명과학 기출",
"생명과학 시험범위",
"지구과학 기출",
"지구과학 시험범위",
"과학 선택과목",
"과학 선택과목 추천"
],
"공부·수행": [
"과학 1등급",
"과학 공부법",
"과학 내신 공부법",
"과학 암기법",
"과학 계산 문제",
"과학 벼락치기",
"과학 문제집 추천",
"과학 프린트",
"과학 수행평가",
"과학탐구실험 수행평가",
"과학탐구실험 보고서",
"과학 실험 보고서",
"과학 탐구 보고서",
"과학 세특 주제",
"과학 성취도 분포"
]
},
"parentKeywords": {
"과외·학원 찾기": [
"과학 과외 추천",
"과학 과외 선생님 추천",
"과학 과외 구하기",
"과학 방문 과외",
"과학 화상 과외",
"과학 개인과외",
"과학 과외 비용",
"과학 과외비",
"과학 과외 후기",
"과학 과외 상담",
"과학 학원 추천",
"과학 내신 학원",
"과학 근처 학원",
"과학 과외 vs 학원",
"과학 단기 과외"
],
"과목·학년": [
"통합과학1 과외",
"통합과학2 과외",
"통합과학 내신 대비",
"통합과학 선행",
"물리 과외",
"물리학 과외",
"화학 과외",
"생명과학 과외",
"지구과학 과외",
"물리 내신",
"화학 내신",
"생명과학 내신",
"지구과학 내신",
"1학년 과학 과외",
"2학년 과학 과외"
],
"성적·시기": [
"과학 내신 올리기",
"과학 등급 올리기",
"과학 기초 과외",
"과학 노베이스 과외",
"과학 하위권 과외",
"과학 상위권 과외",
"과학 서술형 대비",
"과학 선행",
"과학 중간고사 대비 과외",
"과학 기말고사 대비 과외",
"과학 시험기간 단기 과외",
"과학 겨울방학 과외",
"과탐 과외",
"수능 과탐 과외",
"통합과학 수능 대비"
]
}
},
"사회": {
"name": "사회",
"slug": "social",
"badge": "통합사회·한국사·사탐 고득점",
"summary": "방대한 암기량의 흐름 구조화 및 도표·사료 분석, 만점 서술형 가이드",
"coreKeywords": [
"사회 과외",
"사회 내신 과외",
"사회 내신 대비",
"통합사회 과외",
"한국사 과외",
"사회 내신",
"통합사회 내신",
"한국사 내신",
"사회 1:1 과외",
"사회 과외 선생님"
],
"studentKeywords": {
"시험 정보": [
"사회 기출",
"사회 기출문제",
"사회 족보",
"사회 시험범위",
"사회 시험 난이도",
"사회 중간고사",
"사회 기말고사",
"사회 서술형",
"사회 시험 유형",
"사회 출제 경향",
"사회 평균",
"사회 등급컷",
"사회 시험 후기",
"사회 부교재",
"사회 교과서"
],
"과목별": [
"통합사회 기출",
"통합사회 시험범위",
"통합사회 시험 난이도",
"통합사회 서술형",
"통합사회 교과서",
"한국사 기출",
"한국사 시험범위",
"한국사 시험 난이도",
"한국사 서술형",
"사회문화 기출",
"생활과 윤리 기출",
"세계사 기출",
"한국지리 기출",
"사회 선택과목",
"사회 선택과목 추천"
],
"공부·수행": [
"사회 1등급",
"사회 공부법",
"사회 내신 공부법",
"사회 암기법",
"한국사 암기법",
"통합사회 암기",
"사회 벼락치기",
"사회 문제집 추천",
"사회 프린트",
"사회 필기",
"사회 수행평가",
"사회 발표 수행평가",
"사회 보고서 수행평가",
"사회 세특 주제",
"사회 성취도 분포"
]
},
"parentKeywords": {
"과외·학원 찾기": [
"사회 과외 추천",
"사회 과외 선생님 추천",
"사회 과외 구하기",
"사회 전문 과외",
"사회 방문 과외",
"사회 화상 과외",
"사회 개인과외",
"사회 과외 비용",
"사회 과외비",
"사회 과외 후기",
"사회 과외 상담",
"사회 학원",
"사회 내신 학원",
"사회 과외 vs 학원",
"사회 단기 과외"
],
"과목·학년": [
"통합사회1 과외",
"통합사회2 과외",
"통합사회 내신 대비",
"한국사 내신 대비",
"사회문화 과외",
"사회와 문화 과외",
"생활과 윤리 과외",
"현대사회와 윤리 과외",
"윤리와 사상 과외",
"세계사 과외",
"한국지리 과외",
"정치와 법 과외",
"경제 과외",
"1학년 사회 과외",
"2학년 사회 과외"
],
"성적·시기": [
"사회 내신 올리기",
"사회 등급 올리기",
"사회 기초 과외",
"사회 노베이스 과외",
"사회 하위권 과외",
"사회 상위권 과외",
"사회 서술형 대비",
"사회 중간고사 대비 과외",
"사회 기말고사 대비 과외",
"사회 시험기간 단기 과외",
"사회 겨울방학 과외",
"사탐 과외",
"사탐 학원",
"수능 사탐 과외",
"통합사회 수능 대비"
]
}
},
"수행평가": {
"name": "수행평가",
"slug": "performance-eval",
"badge": "세특·생기부·보고서 1:1 코칭",
"summary": "과목별 탐구보고서, 발표 PPT, 서술형 논술 및 학생부 세특 차별화 컨설팅",
"coreKeywords": [
"수행평가",
"수행평가 대비",
"수행평가 과외",
"세특 관리",
"생기부 관리",
"수행평가 대비 과외",
"수행평가 일정",
"수행평가 비율",
"세특",
"생기부"
],
"studentKeywords": {
"기본 정보": [
"수행평가 기간",
"수행평가 공지",
"수행평가 계획",
"수행평가 종류",
"수행평가 배점",
"수행평가 기준",
"수행평가 채점 기준",
"수행평가 난이도",
"수행평가 감점",
"수행평가 만점",
"수행평가 미제출",
"수행평가 재시험",
"수행평가 몰리는 기간",
"시험기간 수행평가",
"수행평가 꿀팁"
],
"과목별": [
"수학 수행평가",
"영어 수행평가",
"국어 수행평가",
"과학 수행평가",
"사회 수행평가",
"한국사 수행평가",
"통합과학 수행평가",
"통합사회 수행평가",
"과학탐구실험 수행평가",
"체육 수행평가",
"음악 수행평가",
"미술 수행평가",
"정보 수행평가",
"기술가정 수행평가",
"제2외국어 수행평가"
],
"유형·주제": [
"발표 수행평가",
"보고서 수행평가",
"서술형 수행평가",
"논술형 수행평가",
"글쓰기 수행평가",
"독서 수행평가",
"토론 수행평가",
"조별 수행평가",
"PPT 수행평가",
"탐구 보고서",
"실험 보고서",
"수행평가 주제 추천",
"수행평가 발표 주제",
"수행평가 보고서 양식",
"세특 주제"
]
},
"parentKeywords": {
"대비·도움": [
"수행평가 코칭",
"수행평가 도움",
"수행평가 준비 방법",
"수행평가 일정 관리",
"수행평가 중간고사 병행",
"수행평가 관리",
"수행평가 컨설팅",
"수학 수행평가 대비",
"영어 수행평가 대비",
"국어 수행평가 대비",
"과학 수행평가 대비",
"사회 수행평가 대비",
"탐구 보고서 지도",
"수행평가 글쓰기 지도",
"수행평가 발표 지도"
],
"반영·성적": [
"수행평가 반영 비율",
"수행평가 내신 반영",
"수행평가 지필 비율",
"수행평가 성적 확인",
"수행평가 이의신청",
"수행평가 등급 영향",
"수행평가 감점 기준",
"수행평가 평가 계획서",
"수행평가 인정점",
"수행평가 결석",
"1학년 수행평가",
"2학년 수행평가",
"3학년 수행평가",
"1학기 수행평가",
"2학기 수행평가"
],
"세특·입시": [
"세특 관리 과외",
"세특 주제 추천",
"세특 컨설팅",
"과목별 세특",
"수학 세특",
"영어 세특",
"국어 세특",
"과학 세특",
"사회 세특",
"생기부 관리 과외",
"생기부 컨설팅",
"생기부 관리 방법",
"학생부종합 수행평가",
"수행평가 세특 연계",
"학생부종합 준비"
]
}
}
}
+992
View File
@@ -0,0 +1,992 @@
{
"total": 71,
"regionName": "인천",
"defaultSido": "인천광역시",
"keywordPrefix": "인천 ",
"sampleKeyword": "인천 연수구 송도동 수학과외",
"uniqueDongCount": 64,
"list": [
{
"fullName": "인천광역시 강화군 강화읍",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "강화읍"
},
{
"fullName": "인천광역시 강화군 교동면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "교동면"
},
{
"fullName": "인천광역시 강화군 길상면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "길상면"
},
{
"fullName": "인천광역시 강화군 내가면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "내가면"
},
{
"fullName": "인천광역시 강화군 서도면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "서도면"
},
{
"fullName": "인천광역시 강화군 양도면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "양도면"
},
{
"fullName": "인천광역시 검단구 당하동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "당하동"
},
{
"fullName": "인천광역시 검단구 마전동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "마전동"
},
{
"fullName": "인천광역시 검단구 백석동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "백석동"
},
{
"fullName": "인천광역시 검단구 불로동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "불로동"
},
{
"fullName": "인천광역시 검단구 원당동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "원당동"
},
{
"fullName": "인천광역시 계양구 계산동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "계산동"
},
{
"fullName": "인천광역시 계양구 방축동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "방축동"
},
{
"fullName": "인천광역시 계양구 병방동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "병방동"
},
{
"fullName": "인천광역시 계양구 서운동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "서운동"
},
{
"fullName": "인천광역시 계양구 용종동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "용종동"
},
{
"fullName": "인천광역시 계양구 작전동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "작전동"
},
{
"fullName": "인천광역시 계양구 효성동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "효성동"
},
{
"fullName": "인천광역시 남동구 간석동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "간석동"
},
{
"fullName": "인천광역시 남동구 논현동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "논현동"
},
{
"fullName": "인천광역시 남동구 만수동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "만수동"
},
{
"fullName": "인천광역시 남동구 서창동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "서창동"
},
{
"fullName": "인천광역시 동구 만석동",
"sido": "인천광역시",
"sigungu": "동구",
"dong": "만석동"
},
{
"fullName": "인천광역시 미추홀구 관교동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "관교동"
},
{
"fullName": "인천광역시 미추홀구 도화동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "도화동"
},
{
"fullName": "인천광역시 미추홀구 문학동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "문학동"
},
{
"fullName": "인천광역시 미추홀구 용현동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "용현동"
},
{
"fullName": "인천광역시 미추홀구 주안동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "주안동"
},
{
"fullName": "인천광역시 미추홀구 학익동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "학익동"
},
{
"fullName": "인천광역시 부평구 갈산동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "갈산동"
},
{
"fullName": "인천광역시 부평구 부개동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "부개동"
},
{
"fullName": "인천광역시 부평구 부평동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "부평동"
},
{
"fullName": "인천광역시 부평구 산곡동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "산곡동"
},
{
"fullName": "인천광역시 부평구 삼산동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "삼산동"
},
{
"fullName": "인천광역시 부평구 십정동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "십정동"
},
{
"fullName": "인천광역시 부평구 일신동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "일신동"
},
{
"fullName": "인천광역시 서구 당하동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "당하동"
},
{
"fullName": "인천광역시 서구 마전동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "마전동"
},
{
"fullName": "인천광역시 서구 연희동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "연희동"
},
{
"fullName": "인천광역시 서구 원당동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "원당동"
},
{
"fullName": "인천광역시 서해구 가좌동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "가좌동"
},
{
"fullName": "인천광역시 서해구 검암동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "검암동"
},
{
"fullName": "인천광역시 서해구 공촌동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "공촌동"
},
{
"fullName": "인천광역시 서해구 석남동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "석남동"
},
{
"fullName": "인천광역시 서해구 신현동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "신현동"
},
{
"fullName": "인천광역시 서해구 연희동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "연희동"
},
{
"fullName": "인천광역시 서해구 청라동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "청라동"
},
{
"fullName": "인천광역시 연수구 동춘동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "동춘동"
},
{
"fullName": "인천광역시 연수구 선학동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "선학동"
},
{
"fullName": "인천광역시 연수구 송도동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "송도동"
},
{
"fullName": "인천광역시 연수구 연수동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "연수동"
},
{
"fullName": "인천광역시 연수구 옥련동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "옥련동"
},
{
"fullName": "인천광역시 연수구 청학동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "청학동"
},
{
"fullName": "인천광역시 영종구 운남동",
"sido": "인천광역시",
"sigungu": "영종구",
"dong": "운남동"
},
{
"fullName": "인천광역시 영종구 운서동",
"sido": "인천광역시",
"sigungu": "영종구",
"dong": "운서동"
},
{
"fullName": "인천광역시 영종구 중산동",
"sido": "인천광역시",
"sigungu": "영종구",
"dong": "중산동"
},
{
"fullName": "인천광역시 옹진군 대청면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "대청면"
},
{
"fullName": "인천광역시 옹진군 덕적면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "덕적면"
},
{
"fullName": "인천광역시 옹진군 백령면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "백령면"
},
{
"fullName": "인천광역시 옹진군 연평면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "연평면"
},
{
"fullName": "인천광역시 옹진군 영흥면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "영흥면"
},
{
"fullName": "인천광역시 제물포구 도원동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "도원동"
},
{
"fullName": "인천광역시 제물포구 북성동1가",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "북성동1가"
},
{
"fullName": "인천광역시 제물포구 송림동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "송림동"
},
{
"fullName": "인천광역시 제물포구 율목동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "율목동"
},
{
"fullName": "인천광역시 제물포구 전동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "전동"
},
{
"fullName": "인천광역시 제물포구 창영동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "창영동"
},
{
"fullName": "인천광역시 중구 도원동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "도원동"
},
{
"fullName": "인천광역시 중구 신포동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "신포동"
},
{
"fullName": "인천광역시 중구 운서동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "운서동"
},
{
"fullName": "인천광역시 중구 율목동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "율목동"
}
],
"dongMap": {
"강화읍": [
{
"fullName": "인천광역시 강화군 강화읍",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "강화읍"
}
],
"교동면": [
{
"fullName": "인천광역시 강화군 교동면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "교동면"
}
],
"길상면": [
{
"fullName": "인천광역시 강화군 길상면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "길상면"
}
],
"내가면": [
{
"fullName": "인천광역시 강화군 내가면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "내가면"
}
],
"서도면": [
{
"fullName": "인천광역시 강화군 서도면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "서도면"
}
],
"양도면": [
{
"fullName": "인천광역시 강화군 양도면",
"sido": "인천광역시",
"sigungu": "강화군",
"dong": "양도면"
}
],
"당하동": [
{
"fullName": "인천광역시 검단구 당하동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "당하동"
},
{
"fullName": "인천광역시 서구 당하동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "당하동"
}
],
"마전동": [
{
"fullName": "인천광역시 검단구 마전동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "마전동"
},
{
"fullName": "인천광역시 서구 마전동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "마전동"
}
],
"백석동": [
{
"fullName": "인천광역시 검단구 백석동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "백석동"
}
],
"불로동": [
{
"fullName": "인천광역시 검단구 불로동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "불로동"
}
],
"원당동": [
{
"fullName": "인천광역시 검단구 원당동",
"sido": "인천광역시",
"sigungu": "검단구",
"dong": "원당동"
},
{
"fullName": "인천광역시 서구 원당동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "원당동"
}
],
"계산동": [
{
"fullName": "인천광역시 계양구 계산동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "계산동"
}
],
"방축동": [
{
"fullName": "인천광역시 계양구 방축동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "방축동"
}
],
"병방동": [
{
"fullName": "인천광역시 계양구 병방동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "병방동"
}
],
"서운동": [
{
"fullName": "인천광역시 계양구 서운동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "서운동"
}
],
"용종동": [
{
"fullName": "인천광역시 계양구 용종동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "용종동"
}
],
"작전동": [
{
"fullName": "인천광역시 계양구 작전동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "작전동"
}
],
"효성동": [
{
"fullName": "인천광역시 계양구 효성동",
"sido": "인천광역시",
"sigungu": "계양구",
"dong": "효성동"
}
],
"간석동": [
{
"fullName": "인천광역시 남동구 간석동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "간석동"
}
],
"논현동": [
{
"fullName": "인천광역시 남동구 논현동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "논현동"
}
],
"만수동": [
{
"fullName": "인천광역시 남동구 만수동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "만수동"
}
],
"서창동": [
{
"fullName": "인천광역시 남동구 서창동",
"sido": "인천광역시",
"sigungu": "남동구",
"dong": "서창동"
}
],
"만석동": [
{
"fullName": "인천광역시 동구 만석동",
"sido": "인천광역시",
"sigungu": "동구",
"dong": "만석동"
}
],
"관교동": [
{
"fullName": "인천광역시 미추홀구 관교동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "관교동"
}
],
"도화동": [
{
"fullName": "인천광역시 미추홀구 도화동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "도화동"
}
],
"문학동": [
{
"fullName": "인천광역시 미추홀구 문학동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "문학동"
}
],
"용현동": [
{
"fullName": "인천광역시 미추홀구 용현동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "용현동"
}
],
"주안동": [
{
"fullName": "인천광역시 미추홀구 주안동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "주안동"
}
],
"학익동": [
{
"fullName": "인천광역시 미추홀구 학익동",
"sido": "인천광역시",
"sigungu": "미추홀구",
"dong": "학익동"
}
],
"갈산동": [
{
"fullName": "인천광역시 부평구 갈산동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "갈산동"
}
],
"부개동": [
{
"fullName": "인천광역시 부평구 부개동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "부개동"
}
],
"부평동": [
{
"fullName": "인천광역시 부평구 부평동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "부평동"
}
],
"산곡동": [
{
"fullName": "인천광역시 부평구 산곡동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "산곡동"
}
],
"삼산동": [
{
"fullName": "인천광역시 부평구 삼산동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "삼산동"
}
],
"십정동": [
{
"fullName": "인천광역시 부평구 십정동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "십정동"
}
],
"일신동": [
{
"fullName": "인천광역시 부평구 일신동",
"sido": "인천광역시",
"sigungu": "부평구",
"dong": "일신동"
}
],
"연희동": [
{
"fullName": "인천광역시 서구 연희동",
"sido": "인천광역시",
"sigungu": "서구",
"dong": "연희동"
},
{
"fullName": "인천광역시 서해구 연희동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "연희동"
}
],
"가좌동": [
{
"fullName": "인천광역시 서해구 가좌동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "가좌동"
}
],
"검암동": [
{
"fullName": "인천광역시 서해구 검암동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "검암동"
}
],
"공촌동": [
{
"fullName": "인천광역시 서해구 공촌동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "공촌동"
}
],
"석남동": [
{
"fullName": "인천광역시 서해구 석남동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "석남동"
}
],
"신현동": [
{
"fullName": "인천광역시 서해구 신현동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "신현동"
}
],
"청라동": [
{
"fullName": "인천광역시 서해구 청라동",
"sido": "인천광역시",
"sigungu": "서해구",
"dong": "청라동"
}
],
"동춘동": [
{
"fullName": "인천광역시 연수구 동춘동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "동춘동"
}
],
"선학동": [
{
"fullName": "인천광역시 연수구 선학동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "선학동"
}
],
"송도동": [
{
"fullName": "인천광역시 연수구 송도동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "송도동"
}
],
"연수동": [
{
"fullName": "인천광역시 연수구 연수동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "연수동"
}
],
"옥련동": [
{
"fullName": "인천광역시 연수구 옥련동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "옥련동"
}
],
"청학동": [
{
"fullName": "인천광역시 연수구 청학동",
"sido": "인천광역시",
"sigungu": "연수구",
"dong": "청학동"
}
],
"운남동": [
{
"fullName": "인천광역시 영종구 운남동",
"sido": "인천광역시",
"sigungu": "영종구",
"dong": "운남동"
}
],
"운서동": [
{
"fullName": "인천광역시 영종구 운서동",
"sido": "인천광역시",
"sigungu": "영종구",
"dong": "운서동"
},
{
"fullName": "인천광역시 중구 운서동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "운서동"
}
],
"중산동": [
{
"fullName": "인천광역시 영종구 중산동",
"sido": "인천광역시",
"sigungu": "영종구",
"dong": "중산동"
}
],
"대청면": [
{
"fullName": "인천광역시 옹진군 대청면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "대청면"
}
],
"덕적면": [
{
"fullName": "인천광역시 옹진군 덕적면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "덕적면"
}
],
"백령면": [
{
"fullName": "인천광역시 옹진군 백령면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "백령면"
}
],
"연평면": [
{
"fullName": "인천광역시 옹진군 연평면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "연평면"
}
],
"영흥면": [
{
"fullName": "인천광역시 옹진군 영흥면",
"sido": "인천광역시",
"sigungu": "옹진군",
"dong": "영흥면"
}
],
"도원동": [
{
"fullName": "인천광역시 제물포구 도원동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "도원동"
},
{
"fullName": "인천광역시 중구 도원동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "도원동"
}
],
"북성동1가": [
{
"fullName": "인천광역시 제물포구 북성동1가",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "북성동1가"
}
],
"송림동": [
{
"fullName": "인천광역시 제물포구 송림동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "송림동"
}
],
"율목동": [
{
"fullName": "인천광역시 제물포구 율목동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "율목동"
},
{
"fullName": "인천광역시 중구 율목동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "율목동"
}
],
"전동": [
{
"fullName": "인천광역시 제물포구 전동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "전동"
}
],
"창영동": [
{
"fullName": "인천광역시 제물포구 창영동",
"sido": "인천광역시",
"sigungu": "제물포구",
"dong": "창영동"
}
],
"신포동": [
{
"fullName": "인천광역시 중구 신포동",
"sido": "인천광역시",
"sigungu": "중구",
"dong": "신포동"
}
]
}
}
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-11-01',
devtools: { enabled: false },
future: {
compatibilityVersion: 3
},
// SSR (Server-Side Rendering) 모드 강제 - 네이버 Yeti 봇 100% 대응
ssr: true,
// Windows 경로 구분자 대응 및 Nitro 번들링 안정화
nitro: {
externals: {
inline: [/[\\/]node_modules[\\/]nuxt[\\/]dist[\\/]/]
}
},
runtimeConfig: {
discordWebhookUrl: process.env.DISCORD_WEBHOOK_URL || 'https://discordapp.com/api/webhooks/1557204310369116210/9J4y96kmSbYNGtw5OxRgIz7InWcM8o3f8UX0Ad71-IyofwdS7tWmXkF7dj457-I8Ypiu',
public: {
siteName: '튜터온',
siteDomain: process.env.SITE_DOMAIN || 'https://aeseo.site',
naverVerificationKey: process.env.NAVER_VERIFICATION_KEY || '797ab1ac988eb27c80ae544bb6aba05c2231a9c9'
}
},
app: {
head: {
htmlAttrs: {
lang: 'ko'
},
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'shortcut icon', href: '/favicon.ico' },
{ rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' },
{ rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' },
{ rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' },
{ rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css' },
{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css' },
{ rel: 'stylesheet', href: '/css/theme.css' }
],
script: [
{ src: 'https://cdn.tailwindcss.com' }
],
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0' },
{ name: 'format-detection', content: 'telephone=no' },
// 네이버 서치어드바이저 사이트 소유확인 키 메타태그
{ name: 'naver-site-verification', content: process.env.NAVER_VERIFICATION_KEY || '797ab1ac988eb27c80ae544bb6aba05c2231a9c9' }
]
}
}
})
+17
View File
@@ -0,0 +1,17 @@
{
"name": "technova-site3",
"type": "module",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev --port 3013",
"generate": "nuxt generate",
"preview": "nuxt preview --port 3013",
"postinstall": "nuxt prepare"
},
"dependencies": {
"nuxt": "^4.5.2",
"vue": "^3.5.43",
"vue-router": "^5.3.1"
}
}
+141
View File
@@ -0,0 +1,141 @@
<template>
<div class="landing-page-wrap">
<!-- 1. 광고 랜딩 전용 지역 식별 바 (외부 이탈 링크 없음) -->
<div class="ad-location-bar">
<span class="loc-badge-tag">[지역센터]</span>
<span class="loc-text">{{ parsed.shortRegionName }} ({{ parsed.sigungu }}) 관내 초·중·고 전담</span>
<span class="loc-tag">1:1 맞춤 배정 센터</span>
</div>
<!-- 2. 상단 히어로 배너 (Header 제거, H1 태그 포함) -->
<HeroBanner
:region="parsed.region"
:shortRegionName="parsed.shortRegionName"
:grade="parsed.grade"
:subjectName="parsed.subjectName"
/>
<!-- 3. 실시간 성과 지표 4선 -->
<QuickMetrics :regionDong="parsed.dong" />
<!-- 4. 인근 학교별 내신 기출 정밀 분석 -->
<NearbySchools
:regionDong="parsed.dong"
:grade="parsed.grade"
:subjectName="parsed.subjectName"
/>
<!-- 5. 과목별 상세 커리큘럼 & 1등급 도약 솔루션 -->
<SubjectMastery
:regionDong="parsed.dong"
:grade="parsed.grade"
:curriculum="curriculum"
/>
<!-- 6. 1:1 강사진 4단계 검증 프로세스 -->
<TeacherVerification />
<!-- 7. 메타인지 스터디 플래너 & 밀착 코칭 시스템 -->
<CoachingSystem />
<!-- 8. 실제 성적 향상 수기 (해당 학년/과목 100% 매칭) -->
<SuccessStories
:regionDong="parsed.dong"
:grade="parsed.grade"
:subjectName="parsed.subjectName"
/>
<!-- 9. 수업 진행 4단계 절차 안내 -->
<ProcessGuide />
<!-- 10. 자주 묻는 질문 (FAQ) -->
<FaqAccordion
:regionDong="parsed.dong"
:grade="parsed.grade"
:subjectName="parsed.subjectName"
/>
<!-- 11. 네이버 5개 멀티 이미지 매칭용 핵심 과외 프로그램 빠른 보기 -->
<FastConsultFocus
:regionDong="parsed.dong"
:grade="parsed.grade"
:subjectName="parsed.subjectName"
/>
<!-- 웹 광고 단일 목적: 해당 학년과 과목이 기본 선택된 무료 상담 신청 폼 -->
<ConsultForm
:regionName="parsed.shortRegionName"
:defaultGrade="parsed.grade"
:defaultSubject="parsed.subjectName"
/>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
import { parseRouteSlug, getCurriculumBySubject, getAllSubjectsList, getPopularRegions } from '~/utils/dataHelper'
import { generateSeoMeta } from '~/utils/seoHelper'
const route = useRoute()
const config = useRuntimeConfig()
// URL 파라미터 파싱
const slug = route.params.slug
const parsed = parseRouteSlug(slug)
// 커리큘럼 데이터 로드
const curriculum = getCurriculumBySubject(parsed.subjectKey)
const allSubjects = getAllSubjectsList()
const popularRegions = getPopularRegions(12)
// 네이버 Yeti 봇 100% 대응 SEO 메타태그 설정
const seo = generateSeoMeta(
parsed,
config.public.siteName,
config.public.siteDomain
)
useHead({
title: seo.title,
meta: seo.meta,
link: seo.link,
script: seo.script
})
</script>
<style scoped>
.landing-page-wrap {
width: 100%;
overflow-x: hidden;
}
.ad-location-bar {
max-width: 1080px;
margin: 10px auto;
padding: 8px 16px;
font-size: clamp(0.78rem, 2vw, 0.88rem);
color: #334155;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.loc-pin {
font-size: 1rem;
}
.loc-text {
font-weight: 700;
color: var(--primary-color, #1e3a8a);
}
.loc-tag {
font-size: 0.75rem;
font-weight: 800;
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
color: var(--primary-color, #1e3a8a);
padding: 2px 8px;
border-radius: 4px;
}
</style>
+572
View File
@@ -0,0 +1,572 @@
<template>
<div class="landing-container bg-[#F0F9FF] text-slate-800 antialiased relative pb-24 md:pb-12 min-h-screen w-full">
<!-- Header -->
<header class="bg-white border-b border-slate-200 sticky top-0 z-40 shadow-sm w-full">
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
<div class="flex items-center space-x-2">
<div class="w-9 h-9 rounded-xl bg-sky-600 flex items-center justify-center text-white font-extrabold text-lg shadow-sm">
T
</div>
<div>
<span class="font-extrabold text-xl sm:text-2xl tracking-tight text-sky-950">{{ siteName }}</span>
<span class="text-[10px] font-bold text-cyan-700 bg-cyan-50 px-2 py-0.5 rounded-full ml-1.5 border border-cyan-200">SMART 정밀 진단</span>
</div>
</div>
<div class="flex items-center space-x-4">
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-sky-600 transition">
<i class="fa-solid fa-phone text-sky-600"></i>
<span>010-5961-5807</span>
</a>
<a href="#leadFormSection" class="bg-sky-600 hover:bg-sky-700 text-white text-xs sm:text-sm font-bold px-5 py-2.5 rounded-full transition shadow-md flex items-center gap-1.5">
<span>정밀 진단 신청</span>
<i class="fa-solid fa-arrow-right text-[11px]"></i>
</a>
</div>
</div>
</header>
<!-- 메인 컨텐츠 (좌우 꽉 찬 와이드) -->
<main class="w-full bg-[#F0F9FF] min-h-screen pb-20">
<!-- 히어로 섹션 (테크 블루 & 사이언 풀와이드) -->
<section class="w-full bg-gradient-to-b from-[#0369A1] via-[#0275B2] to-[#0284C7] text-white px-4 sm:px-6 pt-12 pb-20 rounded-b-[2.5rem] relative overflow-hidden text-center shadow-lg">
<div class="absolute -right-24 -top-24 w-96 h-96 bg-cyan-400/20 rounded-full blur-3xl pointer-events-none"></div>
<div class="absolute -left-24 bottom-0 w-96 h-96 bg-sky-300/20 rounded-full blur-3xl pointer-events-none"></div>
<div class="max-w-4xl mx-auto relative z-10">
<div class="inline-flex items-center gap-2 bg-white/10 backdrop-blur-md border border-white/20 px-4 py-1.5 rounded-full text-xs sm:text-sm font-medium text-sky-100 mb-5 shadow-sm">
<span class="w-2.5 h-2.5 rounded-full bg-cyan-300 animate-ping"></span>
<span>관내 초·중·고 학교별 내신 기출 완벽 분석</span>
</div>
<h1 class="text-2xl sm:text-4xl md:text-5xl font-extrabold leading-snug sm:leading-tight tracking-tight text-white mb-4">
우리 동네 학교별 맞춤 내신·수능 대비<br class="hidden sm:inline">
<span class="text-cyan-200 underline decoration-wavy decoration-cyan-300">취약 단원 핀포인트 1:1 클리닉</span> 무료 리포트 신청
</h1>
<p class="text-xs sm:text-base text-sky-100/90 font-normal max-w-2xl mx-auto leading-relaxed mb-8">
어디서 틀리는지 모르는 막연한 공부는 끝! 취약 개념을 역추적하여 가장 빠른 성적 향상 지름길을 찾아드립니다.
</p>
<!-- 지표 카운터 -->
<div class="grid grid-cols-3 gap-3 bg-white/10 backdrop-blur-md border border-white/20 rounded-2xl p-4 sm:p-5 text-center max-w-xl mx-auto mb-6 shadow-inner">
<div>
<div class="text-[11px] sm:text-xs text-sky-200">지역 전담 강사진</div>
<div class="font-extrabold text-base sm:text-2xl text-white mt-0.5">3,500<span class="text-xs sm:text-sm font-normal">+명</span></div>
</div>
<div class="border-x border-white/20">
<div class="text-[11px] sm:text-xs text-sky-200">학교별 기출 분석</div>
<div class="font-extrabold text-base sm:text-2xl text-cyan-200 mt-0.5">100<span class="text-xs sm:text-sm font-normal">%</span></div>
</div>
<div>
<div class="text-[11px] sm:text-xs text-sky-200">성적 향상 만족도</div>
<div class="font-extrabold text-base sm:text-2xl text-white mt-0.5">98.9<span class="text-xs sm:text-sm font-normal">%</span></div>
</div>
</div>
<!-- 실시간 롤링 알림 -->
<div class="bg-black/30 backdrop-blur-md rounded-full px-4 py-2 flex items-center justify-center gap-2.5 text-xs text-slate-200 border border-white/15 mx-auto max-w-md shadow-md">
<span class="bg-sky-500 text-white text-[10px] font-bold px-2 py-0.5 rounded-full">실시간</span>
<span class="truncate font-medium transition-opacity duration-300">{{ currentNotice }}</span>
</div>
</div>
</section>
<!-- 리드 수집 폼 섹션 (상단 카드 오버랩) -->
<section id="leadFormSection" class="px-4 sm:px-6 -mt-10 relative z-20 max-w-3xl mx-auto">
<div class="bg-white rounded-3xl shadow-2xl border border-slate-200/80 p-6 sm:p-8 transition-all">
<header class="text-center mb-6 pb-4 border-b border-slate-100">
<span class="inline-block px-3 py-1 rounded-full text-xs font-bold bg-sky-100 text-sky-800 mb-2">
선착순 30명 정밀 분석 무료
</span>
<h2 class="text-xl sm:text-2xl font-bold text-slate-900">
분석받고 싶은 과목과 학년을 선택하세요!
</h2>
<p class="text-xs sm:text-sm text-slate-500 mt-1">
오답 패턴을 정밀 진단하여 최적의 단원 보완 플랜과 전문 선생님을 매칭합니다.
</p>
</header>
<form @submit.prevent="handleSubmit" class="space-y-5">
<!-- 학년 & 취약 과목 -->
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label for="studentGrade" class="block text-xs sm:text-sm font-bold text-slate-700 mb-1.5">
학년 선택 <span class="text-sky-600">*</span>
</label>
<select id="studentGrade" v-model="formData.grade" required class="w-full bg-slate-50 border border-slate-300 text-slate-800 text-xs sm:text-sm rounded-xl focus:ring-2 focus:ring-sky-600 focus:border-sky-600 p-3 outline-none font-medium transition">
<option value="" disabled>학년 선택</option>
<optgroup label="중등부 (내신·기출 분석)">
<option value="중학교 1학년">중학교 1학년 (기초개념 데이터)</option>
<option value="중학교 2학년">중학교 2학년 (내신 킬러문항)</option>
<option value="중학교 3학년">중학교 3학년 (고등선행 심화)</option>
</optgroup>
<optgroup label="고등부 (내신·수능 클리닉)">
<option value="고등학교 1학년">고등학교 1학년 (공통수학/영어)</option>
<option value="고등학교 2학년">고등학교 2학년 (선택과목 심화)</option>
<option value="고등학교 3학년/N수">고등학교 3학년 / N수 (수능 실전)</option>
</optgroup>
<optgroup label="초등부">
<option value="초등 5~6학년">초등 5~6학년 (중등 브릿지)</option>
</optgroup>
</select>
</div>
<div>
<label for="weakSubject" class="block text-xs sm:text-sm font-bold text-slate-700 mb-1.5">
취약 과목 <span class="text-sky-600">*</span>
</label>
<select id="weakSubject" v-model="formData.subject" required class="w-full bg-slate-50 border border-slate-300 text-slate-800 text-xs sm:text-sm rounded-xl focus:ring-2 focus:ring-sky-600 focus:border-sky-600 p-3 outline-none font-medium transition">
<option value="" disabled>과목 선택</option>
<option value="수학">수학 (개념 역추적 & 킬러 문항)</option>
<option value="영어">영어 (구문 독해 & 빈칸 추론)</option>
<option value="과학">과학 (물리·화학·생명·지구과학)</option>
<option value="국어">국어 (비문학 제재별 독해 분석)</option>
<option value="사회/역사">사회/역사 (도표·사료 분석)</option>
</select>
</div>
</div>
<!-- 빠른 과목 픽 -->
<div>
<div class="text-xs font-semibold text-slate-500 mb-2 flex justify-between items-center">
<span>빠른 과목 픽 (PICK)</span>
<span class="text-xs text-sky-600 font-semibold">터치 시 자동 선택</span>
</div>
<div class="grid grid-cols-5 gap-2 text-center">
<button
v-for="subj in subjects"
:key="subj.name"
type="button"
@click="formData.subject = subj.name"
:class="[
'py-2 px-1 rounded-xl text-xs sm:text-sm font-bold transition shadow-sm',
formData.subject === subj.name
? 'border-2 border-sky-600 bg-sky-50 text-sky-800 ring-2 ring-sky-300/50'
: 'border border-slate-200 text-slate-700 hover:border-sky-400 bg-white'
]"
>
<span>{{ subj.label }}</span>
<span class="block text-[10px] font-normal" :class="formData.subject === subj.name ? 'text-sky-700 font-semibold' : 'text-slate-400'">
{{ subj.badge }}
</span>
</button>
</div>
</div>
<!-- 공부 고민 체크박스 -->
<div>
<label class="block text-xs sm:text-sm font-bold text-slate-700 mb-2">
현재 가장 큰 고민은 무엇인가요? (복수 선택 가능)
</label>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2.5 text-xs sm:text-sm">
<label v-for="c in concernOptions" :key="c" class="flex items-center gap-2.5 p-3 bg-slate-50 border border-slate-200 rounded-xl cursor-pointer hover:bg-sky-50/50 transition">
<input type="checkbox" :value="c" v-model="formData.concerns" class="w-4 h-4 text-sky-600 rounded border-slate-300 focus:ring-sky-500">
<span class="text-slate-700 text-xs sm:text-sm font-medium">{{ c }}</span>
</label>
</div>
</div>
<!-- 거주 지역 / 학교 -->
<div>
<label for="regionInput" class="block text-xs sm:text-sm font-bold text-slate-700 mb-1.5">
거주 지역 및 학교명 <span class="text-slate-400 font-normal text-xs">(지역 내신 기출 DB 매칭)</span>
</label>
<input type="text" id="regionInput" v-model="formData.region" placeholder="예: 경기 성남시 분당구 수내동 / 수내고" class="w-full bg-slate-50 border border-slate-300 text-slate-800 text-xs sm:text-sm rounded-xl focus:ring-2 focus:ring-sky-600 focus:border-sky-600 p-3 outline-none placeholder:text-slate-400 transition">
</div>
<!-- 학부모 연락처 -->
<div>
<label for="parentPhone" class="block text-xs sm:text-sm font-bold text-slate-700 mb-1.5">
학부모 연락처 <span class="text-sky-600">*</span>
<span class="text-slate-400 font-normal text-xs">(정밀 진단표 발송용)</span>
</label>
<div class="relative">
<input
type="tel"
id="parentPhone"
v-model="formData.phone"
@input="formatPhone"
required
placeholder="010-0000-0000"
maxlength="13"
class="w-full bg-slate-50 border border-slate-300 text-slate-900 text-base font-semibold rounded-xl focus:ring-2 focus:ring-sky-600 focus:border-sky-600 p-3.5 pl-11 outline-none tracking-wider"
>
<i class="fa-solid fa-mobile-screen-button absolute left-4 top-4 text-slate-400 text-base"></i>
</div>
</div>
<!-- 개인정보 동의 -->
<div class="flex items-center gap-2 text-xs text-slate-500 pt-1">
<input type="checkbox" id="privacyAgree" v-model="formData.privacy" required class="w-4 h-4 text-sky-600 rounded border-slate-300 focus:ring-sky-500">
<label for="privacyAgree" class="cursor-pointer">
[필수] 개인정보 수집 및 상담 안내 제공에 동의합니다.
</label>
</div>
<!-- 제출 버튼 -->
<button
type="submit"
:disabled="isSubmitting"
class="w-full bg-gradient-to-r from-sky-600 via-cyan-600 to-sky-600 hover:opacity-95 text-white font-extrabold text-base sm:text-lg py-4 px-6 rounded-2xl shadow-xl transition flex items-center justify-center gap-2 disabled:opacity-50"
>
<i class="fa-solid fa-chart-column text-lg"></i>
<span>{{ isSubmitting ? '분석 중...' : '정밀 진단 리포트 & 1:1 클리닉 신청하기' }}</span>
</button>
<div class="text-center text-xs text-slate-400 flex items-center justify-center gap-1.5">
<i class="fa-solid fa-lock text-xs"></i>
<span>입력하신 정보는 상담 및 리포트 제공 목적으로만 안전하게 보관됩니다.</span>
</div>
<!-- 안내 문구 (상담 결과 전달 시 원활 진행 안내) -->
<div class="mt-3 p-3.5 bg-sky-50/90 border border-sky-200/90 rounded-xl flex items-start gap-2.5 text-xs text-sky-950 leading-relaxed shadow-sm">
<i class="fa-solid fa-circle-info text-sky-600 mt-0.5 text-sm shrink-0"></i>
<div>
<strong class="font-bold text-sky-950 block mb-0.5">📢 원활한 상담 진행 안내</strong>
<span>상담 신청 후 안내받으신 <strong>상담결과를 매니저에게 전달해 주시면</strong> 더욱 원활하고 신속한 맞춤 강사 배정과 심층 상담이 진행됩니다. (직통 문의: <a href="tel:010-5961-5807" class="font-extrabold text-sky-900 underline hover:text-sky-700">010-5961-5807</a>)</span>
</div>
</div>
</form>
<!-- 완료 메시지 -->
<div v-if="submitSuccess" id="submitResultBox" class="mt-5 p-5 bg-emerald-50 border border-emerald-300 rounded-2xl text-emerald-900 text-xs sm:text-sm">
<div class="flex items-center gap-2 font-bold text-sm sm:text-base mb-1.5 text-emerald-800">
<i class="fa-solid fa-circle-check text-emerald-600 text-lg"></i>
<span>학습 정밀 진단 신청이 성공적으로 접수되었습니다!</span>
</div>
<p class="leading-relaxed">
기재해주신 연락처로 <strong>‘취약 단원 정밀 분석 리포트’</strong>가 발송되며, 전문 입시 분석관이 유선으로 심층 솔루션을 안내해 드립니다.
</p>
<div class="mt-3 p-2.5 bg-white/80 rounded-xl border border-emerald-200 text-xs text-emerald-900 flex items-start gap-2">
<i class="fa-solid fa-lightbulb text-emerald-600 mt-0.5 shrink-0"></i>
<span><strong>💡 안내:</strong> 매니저 유선 상담 시 <strong>상담결과를 공유해 주시면</strong> 수준별 맞춤 커리큘럼 설계가 훨씬 원활하게 진행됩니다. (문의: 010-5961-5807)</span>
</div>
</div>
</div>
</section>
<!-- 4대 혜택 섹션 (데스크톱 4열 그리드) -->
<section class="mt-16 px-4 sm:px-6 max-w-6xl mx-auto">
<header class="text-center mb-8">
<span class="text-xs sm:text-sm font-bold text-sky-700 tracking-wider uppercase bg-sky-100 px-3 py-1 rounded-full">TUTOR ON BENEFITS</span>
<h2 class="text-2xl sm:text-3xl font-extrabold text-slate-900 mt-2">튜터온 4대 특화 혜택</h2>
<p class="text-xs sm:text-sm text-slate-500 mt-1">데이터 분석으로 취약점만 콕 집어 최단기 성적 향상을 이끕니다.</p>
</header>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="bg-white p-5 rounded-2xl border border-slate-200/80 shadow-sm hover:border-sky-300 hover:shadow-md transition group">
<div class="w-12 h-12 rounded-2xl bg-sky-100 text-sky-700 flex items-center justify-center text-xl font-bold mb-4 group-hover:scale-110 transition-transform">
<i class="fa-solid fa-brain"></i>
</div>
<span class="inline-block text-[11px] font-bold text-sky-700 bg-sky-50 px-2 py-0.5 rounded mb-1.5">혜택 01</span>
<h3 class="font-bold text-slate-900 text-sm sm:text-base">취약 단원 역추적 시트</h3>
<p class="text-xs text-slate-500 mt-1.5 leading-relaxed">어느 단원에서 구멍이 생겼는지 5단계 오답 원인 분석</p>
</div>
<div class="bg-white p-5 rounded-2xl border border-slate-200/80 shadow-sm hover:border-cyan-300 hover:shadow-md transition group">
<div class="w-12 h-12 rounded-2xl bg-cyan-100 text-cyan-700 flex items-center justify-center text-xl font-bold mb-4 group-hover:scale-110 transition-transform">
<i class="fa-solid fa-database"></i>
</div>
<span class="inline-block text-[11px] font-bold text-cyan-700 bg-cyan-50 px-2 py-0.5 rounded mb-1.5">혜택 02</span>
<h3 class="font-bold text-slate-900 text-sm sm:text-base">학군별 3개년 킬러족보</h3>
<p class="text-xs text-slate-500 mt-1.5 leading-relaxed">분당·판교·강남 주요 학교별 고난도 변별력 문항 모음</p>
</div>
<div class="bg-white p-5 rounded-2xl border border-slate-200/80 shadow-sm hover:border-blue-300 hover:shadow-md transition group">
<div class="w-12 h-12 rounded-2xl bg-blue-100 text-blue-700 flex items-center justify-center text-xl font-bold mb-4 group-hover:scale-110 transition-transform">
<i class="fa-solid fa-chart-line"></i>
</div>
<span class="inline-block text-[11px] font-bold text-blue-700 bg-blue-50 px-2 py-0.5 rounded mb-1.5">혜택 03</span>
<h3 class="font-bold text-slate-900 text-sm sm:text-base">1:1 약점 클리닉 워크북</h3>
<p class="text-xs text-slate-500 mt-1.5 leading-relaxed">틀린 유형과 유사한 변형 문제만 선별 제공</p>
</div>
<div class="bg-white p-5 rounded-2xl border border-slate-200/80 shadow-sm hover:border-indigo-300 hover:shadow-md transition group">
<div class="w-12 h-12 rounded-2xl bg-indigo-100 text-indigo-700 flex items-center justify-center text-xl font-bold mb-4 group-hover:scale-110 transition-transform">
<i class="fa-solid fa-user-gear"></i>
</div>
<span class="inline-block text-[11px] font-bold text-indigo-700 bg-indigo-50 px-2 py-0.5 rounded mb-1.5">혜택 04</span>
<h3 class="font-bold text-slate-900 text-sm sm:text-base">데이터 분석 전문 강사진</h3>
<p class="text-xs text-slate-500 mt-1.5 leading-relaxed">학생의 오답 성향에 최적화된 1:1 전담 매칭</p>
</div>
</div>
</section>
<!-- 성적 향상 사례 (데스크톱 와이드 2열) -->
<section class="mt-16 px-4 sm:px-6 max-w-6xl mx-auto">
<header class="text-center mb-8">
<span class="text-xs sm:text-sm font-bold text-sky-700 tracking-wider bg-sky-100 px-3 py-1 rounded-full">DATA-DRIVEN SUCCESS</span>
<h2 class="text-2xl sm:text-3xl font-extrabold text-slate-900 mt-2">실제 성적 반등 결과</h2>
<p class="text-xs sm:text-sm text-slate-500 mt-1">데이터 분석으로 원인을 찾아 성적을 역전시킨 학생들의 사례입니다.</p>
</header>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5 mb-6">
<!-- Case 1 -->
<div class="bg-white p-6 rounded-3xl border border-slate-200 shadow-sm hover:shadow-md transition">
<div class="flex items-center justify-between mb-3">
<div class="flex items-center gap-2">
<span class="bg-sky-100 text-sky-800 font-bold text-xs px-2.5 py-1 rounded-full">공통수학 1등급</span>
<span class="font-bold text-sm sm:text-base text-slate-800">분당 수내동 고1 정OO 학생</span>
</div>
<span class="text-xs text-slate-400">3개월 만에 달성</span>
</div>
<div>
<div class="flex justify-between text-xs sm:text-sm mb-1.5 font-semibold">
<span class="text-slate-400">진단 전: 4등급 (52점)</span>
<span class="text-sky-700 font-bold">진단 후: 1등급 (96점) 🔥</span>
</div>
<div class="w-full bg-slate-100 rounded-full h-3 overflow-hidden">
<div class="bg-gradient-to-r from-slate-300 to-sky-600 h-3 rounded-full" style="width: 92%"></div>
</div>
</div>
<p class="text-xs sm:text-sm text-slate-600 mt-3.5 bg-slate-50 p-3.5 rounded-xl leading-relaxed">
"어디서 틀리는지 모른 채 무작정 문제집만 풀었는데, 정밀 분석 리포트로 이차함수 판별식 연계 개념이 비어있다는 걸 알고 단기간에 메꿨습니다."
</p>
</div>
<!-- Case 2 -->
<div class="bg-white p-6 rounded-3xl border border-slate-200 shadow-sm hover:shadow-md transition">
<div class="flex items-center justify-between mb-3">
<div class="flex items-center gap-2">
<span class="bg-cyan-100 text-cyan-800 font-bold text-xs px-2.5 py-1 rounded-full">과학 탐구 만점</span>
<span class="font-bold text-sm sm:text-base text-slate-800">판교 중3 윤OO 학생</span>
</div>
<span class="text-xs text-slate-400">2개월 만에 달성</span>
</div>
<div>
<div class="flex justify-between text-xs sm:text-sm mb-1.5 font-semibold">
<span class="text-slate-400">진단 전: 62점 (C등급)</span>
<span class="text-cyan-700 font-bold">진단 후: 98점 (전교 2등) 🚀</span>
</div>
<div class="w-full bg-slate-100 rounded-full h-3 overflow-hidden">
<div class="bg-gradient-to-r from-slate-300 to-cyan-600 h-3 rounded-full" style="width: 96%"></div>
</div>
</div>
<p class="text-xs sm:text-sm text-slate-600 mt-3.5 bg-slate-50 p-3.5 rounded-xl leading-relaxed">
"물리 파트 공식 유도와 계산 실수 패턴을 정확히 잡아주셔서 내신 시험에서 만점에 가까운 점수를 받았습니다."
</p>
</div>
</div>
<!-- 학부모 리뷰 (2열) -->
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm text-left">
<div class="text-amber-400 text-sm mb-2">
<i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i>
</div>
<h4 class="font-bold text-sm sm:text-base text-slate-800">분당 파크뷰 학부모 이OO님</h4>
<p class="text-xs sm:text-sm text-slate-600 mt-1.5 leading-relaxed">"정밀 진단표가 학원 상담보다 훨씬 객관적이고 정확했습니다. 어디에 집중해야 할지 명확해졌어요."</p>
</div>
<div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm text-left">
<div class="text-amber-400 text-sm mb-2">
<i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i>
</div>
<h4 class="font-bold text-sm sm:text-base text-slate-800">판교 백현마을 학부모 강OO님</h4>
<p class="text-xs sm:text-sm text-slate-600 mt-1.5 leading-relaxed">"시간 낭비 없이 부족한 단원만 집중 공략하니 단 2개월 만에 성적이 수직 상승했습니다."</p>
</div>
</div>
</section>
<!-- FAQ 섹션 -->
<section class="mt-16 px-4 sm:px-6 max-w-4xl mx-auto">
<header class="text-center mb-8">
<span class="text-xs sm:text-sm font-bold text-slate-400 tracking-wider">FAQ</span>
<h2 class="text-2xl sm:text-3xl font-extrabold text-slate-900 mt-1">자주 묻는 질문</h2>
<p class="text-xs sm:text-sm text-slate-500 mt-1">궁금하신 내용을 미리 확인해 보세요.</p>
</header>
<div class="space-y-3">
<div v-for="(faq, idx) in faqs" :key="idx" class="border border-slate-200 rounded-2xl overflow-hidden bg-white shadow-sm">
<button @click="faq.open = !faq.open" class="w-full p-4 sm:p-5 text-left text-sm sm:text-base font-bold text-slate-800 flex justify-between items-center hover:bg-slate-50 transition">
<span>{{ faq.q }}</span>
<i class="fa-solid fa-chevron-down text-xs sm:text-sm text-slate-400 transition-transform" :class="{ 'rotate-180': faq.open }"></i>
</button>
<div v-show="faq.open" class="p-4 sm:p-5 pt-0 text-xs sm:text-sm text-slate-600 leading-relaxed border-t border-slate-100 bg-slate-50/50">
{{ faq.a }}
</div>
</div>
</div>
</section>
</main>
<!-- 하단 모바일 고정 CTA 바 -->
<aside class="fixed bottom-0 left-0 right-0 bg-white/95 backdrop-blur-md border-t border-slate-200 p-3 sm:p-4 z-40 shadow-2xl">
<div class="max-w-4xl mx-auto flex items-center gap-3">
<a href="tel:010-5961-5807" class="flex flex-col items-center justify-center px-4 py-2.5 bg-slate-100 hover:bg-slate-200 text-slate-800 rounded-xl text-xs font-bold shrink-0 transition" title="전화상담">
<i class="fa-solid fa-phone text-sky-600 text-sm mb-0.5"></i>
<span>010-5961-5807</span>
</a>
<a href="#leadFormSection" class="flex-1 bg-gradient-to-r from-sky-600 via-cyan-600 to-sky-600 hover:opacity-95 text-white font-extrabold text-sm sm:text-base py-3 sm:py-3.5 px-4 rounded-xl shadow-lg transition flex items-center justify-center gap-2">
<i class="fa-solid fa-microchip text-xs sm:text-sm"></i>
<span>지금 무료 정밀 진단 신청하기</span>
</a>
</div>
</aside>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
const config = useRuntimeConfig()
const siteName = config.public.siteName || '튜터온'
const siteDomain = config.public.siteDomain || 'https://aeseo.site'
const isSubmitting = ref(false)
const submitSuccess = ref(false)
const rollingMessages = [
"경기 성남시 분당구 수내동 고1 수학 킬러문항 정밀 분석 접수 (방금 전)",
"경기 성남시 판교동 중3 과학 탐구 오답 클리닉 신청 완료 (1분 전)",
"경기 수원시 영통구 고2 영어 빈칸추론 정밀 진단 신청 (3분 전)",
"경기 용인시 수지구 중2 수학 개념 단원 역추적 접수 (5분 전)",
"서울 강남구 역삼동 중1 국어 비문학 정밀 분석 신청 (7분 전)"
]
const currentNotice = ref(rollingMessages[0])
let rollingIdx = 0
onMounted(() => {
setInterval(() => {
rollingIdx = (rollingIdx + 1) % rollingMessages.length
currentNotice.value = rollingMessages[rollingIdx]
}, 3500)
})
const subjects = [
{ name: '수학', label: '수학', badge: '인기' },
{ name: '영어', label: '영어', badge: 'PICK' },
{ name: '과학', label: '과학', badge: '추천' },
{ name: '국어', label: '국어', badge: 'PICK' },
{ name: '사회/역사', label: '사회', badge: 'PICK' }
]
const concernOptions = [
'개념은 아는데 심화·킬러 문제에서 실패',
'어느 단원이 부족한지 모르는 막연한 공부',
'학원 숙제만 많고 실제 성적은 정체',
'시험 시간 관리 및 잦은 계산 실수'
]
const formData = reactive({
grade: '고등학교 1학년',
subject: '수학',
concerns: ['개념은 아는데 심화·킬러 문제에서 실패'],
region: '',
phone: '',
privacy: true
})
const faqs = reactive([
{
q: '1. 학습 정밀 진단은 어떻게 진행되나요?',
a: '신청서를 남겨주시면 최근 학교 시험지 및 모의고사 성적을 바탕으로 학생의 취약 단원과 오답 패턴을 5단계로 역추적하여 정밀 리포트를 제공합니다.',
open: false
},
{
q: '2. 진단 후 과외 매칭은 어떻게 이루어지나요?',
a: '분석된 취약 단원을 가장 빠르고 정확하게 메꿔줄 수 있는 전문 베테랑 선생님을 데이터 기반으로 우선 매칭해 드립니다.',
open: false
},
{
q: '3. 정밀 진단 비용이 정말 무료인가요?',
a: '네, 현재 프로모션 기간 동안 신청하시는 모든 분께 정밀 진단 리포트와 전문 학습 매니저의 전화 분석이 전액 무료로 제공됩니다.',
open: false
},
{
q: '4. 온라인 화상 과외도 가능한가요?',
a: '네, 실시간 전자칠판 시스템을 통한 비대면 화상 과외와 방문 과외 중 원하시는 형태를 자유롭게 선택하실 수 있습니다.',
open: false
}
])
function formatPhone() {
let val = formData.phone.replace(/[^0-9]/g, '')
if (val.length > 3 && val.length <= 7) {
formData.phone = val.substring(0, 3) + '-' + val.substring(3)
} else if (val.length > 7) {
formData.phone = val.substring(0, 3) + '-' + val.substring(3, 7) + '-' + val.substring(7, 11)
} else {
formData.phone = val
}
}
async function handleSubmit() {
if (!formData.phone || formData.phone.length < 12) {
alert('올바른 학부모 연락처(휴대폰 번호)를 입력해 주세요.')
return
}
isSubmitting.value = true
try {
const res = await $fetch('/api/consult', {
method: 'POST',
body: {
name: '학부모 (정밀진단신청)',
phone: formData.phone,
grade: formData.grade,
schoolName: formData.region || '지역 미기재',
location: formData.region || '온라인 랜딩',
memo: `[과목]: ${formData.subject} / [고민]: ${formData.concerns.join(', ')}`,
url: window.location.href
}
})
if (res && res.success) {
submitSuccess.value = true
setTimeout(() => {
document.getElementById('submitResultBox')?.scrollIntoView({ behavior: 'smooth' })
}, 100)
} else {
alert('신청 접수 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.')
}
} catch (err) {
console.error(err)
alert('접수 처리 중 문제가 발생했습니다.')
} finally {
isSubmitting.value = false
}
}
useHead({
title: `${siteName} | 우리 동네 1:1 전담 맞춤과외`,
meta: [
{ name: 'naver-site-verification', content: '797ab1ac988eb27c80ae544bb6aba05c2231a9c9' },
{ name: 'description', content: `${siteName} - 관내 초·중·고 학교별 내신 기출 완벽 분석 및 취약 단원 1:1 맞춤과외 매칭.` },
{ property: 'og:title', content: `${siteName} | 우리 동네 1:1 맞춤과외 센터` },
{ property: 'og:description', content: '데이터로 찾는 성적 향상의 지름길! 취약 단원 핀포인트 클리닉.' },
{ property: 'og:url', content: siteDomain }
],
script: [
{
type: 'application/ld+json',
children: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'EducationalOrganization',
name: siteName,
url: siteDomain,
telephone: '+82-10-5961-5807',
areaServed: '경기·서울 전지역'
})
}
]
})
</script>
<style scoped>
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css');
.landing-container {
font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, system-ui, Roboto, sans-serif;
word-break: keep-all;
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+21
View File
@@ -0,0 +1,21 @@
/* site3: 튜터온 - 하이테크 인디고 & 네온 일렉트릭 바이올렛 */
:root {
--primary-color: #3730a3;
--primary-dark: #1e1b4b;
--primary-light: #6366f1;
--accent-color: #8b5cf6;
--accent-light: #c084fc;
--hero-gradient: linear-gradient(135deg, #0f172a 0%, #1e1b4b 50%, #312e81 100%);
--hero-region-color: #c7d2fe;
--hero-btn-bg: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%);
--badge-bg: rgba(99, 102, 241, 0.12);
--card-radius: 8px;
--border-color: #e0e7ff;
--bg-card: #ffffff;
--bg-body: #f8fafc;
--text-color: #1e1b4b;
--skills-bg: #eef2ff;
--coaching-bg: #e0e7ff;
--consult-bg: #f5f3ff;
--footer-bg: #0f172a;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,38 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#0284c7"/>
<stop offset="100%" stop-color="#0369a1"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">초등 집중 1단계</text>
<!-- 중앙 아이콘 -->
<g>
<path d="M170 200 C210 185 240 185 250 195 C260 185 290 185 330 200 L330 290 C290 275 260 275 250 285 C240 275 210 275 170 290 Z" fill="none" stroke="#ffffff" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="250" y1="195" x2="250" y2="285" stroke="#ffffff" stroke-width="10" stroke-linecap="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">기초학습</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">개념 이해와 튼튼한 연산 기본기</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -0,0 +1,43 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#059669"/>
<stop offset="100%" stop-color="#047857"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">초등 집중 2단계</text>
<!-- 중앙 아이콘 -->
<g>
<circle cx="250" cy="240" r="60" fill="none" stroke="#ffffff" stroke-width="10"/>
<circle cx="250" cy="240" r="38" fill="none" stroke="#ffffff" stroke-width="8"/>
<circle cx="250" cy="240" r="16" fill="#ffffff"/>
<line x1="250" y1="165" x2="250" y2="185" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<line x1="250" y1="295" x2="250" y2="315" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<line x1="175" y1="240" x2="195" y2="240" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<line x1="305" y1="240" x2="325" y2="240" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">공부방법</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">스스로 이해하는 올바른 학습 원리</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,38 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#d97706"/>
<stop offset="100%" stop-color="#b45309"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">초등 집중 3단계</text>
<!-- 중앙 아이콘 -->
<g>
<rect x="185" y="180" width="130" height="130" rx="16" fill="none" stroke="#ffffff" stroke-width="10"/>
<path d="M215 245 L238 268 L285 215" fill="none" stroke="#ffffff" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">숙제검사</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">매일 1:1 오답 점검과 꼼꼼한 피드백</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,42 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#7c3aed"/>
<stop offset="100%" stop-color="#6d28d9"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">초등 집중 4단계</text>
<!-- 중앙 아이콘 -->
<g>
<line x1="170" y1="310" x2="330" y2="310" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<rect x="190" y="245" width="26" height="65" rx="4" fill="#ffffff" opacity="0.6"/>
<rect x="237" y="215" width="26" height="95" rx="4" fill="#ffffff" opacity="0.8"/>
<rect x="284" y="175" width="26" height="135" rx="4" fill="#ffffff"/>
<path d="M195 230 L245 190 L295 155" fill="none" stroke="#fcd34d" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
<polygon points="295,145 310,158 290,165" fill="#fcd34d"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">공부습관</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">매일 정해진 시간 몰입하는 자기주도력</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,41 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#e11d48"/>
<stop offset="100%" stop-color="#be123c"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">초등 집중 5단계</text>
<!-- 중앙 아이콘 -->
<g>
<path d="M190 190 L310 190 L300 250 C290 280 270 290 250 290 C230 290 210 280 200 250 Z" fill="none" stroke="#ffffff" stroke-width="10" stroke-linejoin="round"/>
<line x1="250" y1="290" x2="250" y2="320" stroke="#ffffff" stroke-width="12" stroke-linecap="round"/>
<line x1="215" y1="320" x2="285" y2="320" stroke="#ffffff" stroke-width="12" stroke-linecap="round"/>
<path d="M190 205 C170 205 160 220 160 235 C160 250 175 255 195 255" fill="none" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<path d="M310 205 C330 205 340 220 340 235 C340 250 325 255 305 255" fill="none" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">중등대비</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">중학교 내신 서술형과 심화 선행</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,43 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#2563eb"/>
<stop offset="100%" stop-color="#1d4ed8"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">실전 시험 대비</text>
<!-- 중앙 아이콘 -->
<g>
<circle cx="250" cy="240" r="60" fill="none" stroke="#ffffff" stroke-width="10"/>
<circle cx="250" cy="240" r="38" fill="none" stroke="#ffffff" stroke-width="8"/>
<circle cx="250" cy="240" r="16" fill="#ffffff"/>
<line x1="250" y1="165" x2="250" y2="185" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<line x1="250" y1="295" x2="250" y2="315" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<line x1="175" y1="240" x2="195" y2="240" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<line x1="305" y1="240" x2="325" y2="240" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">중간고사 수학과외</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">학교별 기출 족보 및 서술형 킬러 대비</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,38 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#0d9488"/>
<stop offset="100%" stop-color="#0f766e"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">학기말 총정리</text>
<!-- 중앙 아이콘 -->
<g>
<rect x="185" y="180" width="130" height="130" rx="16" fill="none" stroke="#ffffff" stroke-width="10"/>
<path d="M215 245 L238 268 L285 215" fill="none" stroke="#ffffff" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">기말고사 수학과외</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">전 범위 오답 분석 및 약점 완벽 클리닉</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,42 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#4f46e5"/>
<stop offset="100%" stop-color="#4338ca"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">수능·전국연합</text>
<!-- 중앙 아이콘 -->
<g>
<line x1="170" y1="310" x2="330" y2="310" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<rect x="190" y="245" width="26" height="65" rx="4" fill="#ffffff" opacity="0.6"/>
<rect x="237" y="215" width="26" height="95" rx="4" fill="#ffffff" opacity="0.8"/>
<rect x="284" y="175" width="26" height="135" rx="4" fill="#ffffff"/>
<path d="M195 230 L245 190 L295 155" fill="none" stroke="#fcd34d" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
<polygon points="295,145 310,158 290,165" fill="#fcd34d"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">모의고사 수학과외</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">수능형 사고력 확장 및 시간관리 특훈</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,38 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ea580c"/>
<stop offset="100%" stop-color="#c2410c"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">서술형·과제</text>
<!-- 중앙 아이콘 -->
<g>
<path d="M170 200 C210 185 240 185 250 195 C260 185 290 185 330 200 L330 290 C290 275 260 275 250 285 C240 275 210 275 170 290 Z" fill="none" stroke="#ffffff" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="250" y1="195" x2="250" y2="285" stroke="#ffffff" stroke-width="10" stroke-linecap="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">수행평가 수학과외</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">조건 감점 0점화 및 탐구보고서 세특</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -0,0 +1,41 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#be123c"/>
<stop offset="100%" stop-color="#9f1239"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="30%" r="50%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.25"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- 배경 -->
<rect width="500" height="500" rx="32" fill="url(#grad)"/>
<rect width="500" height="500" rx="32" fill="url(#glow)"/>
<!-- 장식 원형 패턴 -->
<circle cx="430" cy="80" r="100" fill="#ffffff" opacity="0.05"/>
<circle cx="70" cy="420" r="80" fill="#ffffff" opacity="0.04"/>
<!-- 상단 뱃지 -->
<rect x="50" y="45" width="140" height="38" rx="19" fill="#ffffff" opacity="0.2"/>
<text x="120" y="70" font-family="'Pretendard', sans-serif" font-size="16" font-weight="700" fill="#ffffff" text-anchor="middle" letter-spacing="-0.3">1등급 집중공략</text>
<!-- 중앙 아이콘 -->
<g>
<path d="M190 190 L310 190 L300 250 C290 280 270 290 250 290 C230 290 210 280 200 250 Z" fill="none" stroke="#ffffff" stroke-width="10" stroke-linejoin="round"/>
<line x1="250" y1="290" x2="250" y2="320" stroke="#ffffff" stroke-width="12" stroke-linecap="round"/>
<line x1="215" y1="320" x2="285" y2="320" stroke="#ffffff" stroke-width="12" stroke-linecap="round"/>
<path d="M190 205 C170 205 160 220 160 235 C160 250 175 255 195 255" fill="none" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
<path d="M310 205 C330 205 340 220 340 235 C340 250 325 255 305 255" fill="none" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
</g>
<!-- 하단 텍스트 영역 -->
<text x="250" y="380" font-family="'Pretendard', sans-serif" font-size="34" font-weight="900" fill="#ffffff" text-anchor="middle" letter-spacing="-0.8">내신대비 수학과외</text>
<text x="250" y="420" font-family="'Pretendard', sans-serif" font-size="18" font-weight="600" fill="#ffffff" opacity="0.85" text-anchor="middle" letter-spacing="-0.5">관내 교과서·부교재 적중 1:1 맞춤 지도</text>
<!-- 하단 액션 텍스트 -->
<rect x="175" y="445" width="150" height="28" rx="14" fill="#ffffff" opacity="0.25"/>
<text x="250" y="464" font-family="'Pretendard', sans-serif" font-size="13" font-weight="700" fill="#ffffff" text-anchor="middle">1:1 맞춤 클리닉</text>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

+17
View File
@@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630">
<defs>
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#1e3a8a"/>
<stop offset="100%" stop-color="#2563eb"/>
</linearGradient>
</defs>
<rect width="1200" height="630" fill="url(#bg)"/>
<rect x="80" y="80" width="160" height="48" rx="8" fill="#fbbf24"/>
<text x="160" y="112" font-family="'Pretendard', sans-serif" font-size="22" font-weight="900" fill="#1e293b" text-anchor="middle">AESEO</text>
<text x="80" y="240" font-family="'Pretendard', sans-serif" font-size="56" font-weight="900" fill="#ffffff">우리 동네 초·중·고 1:1 맞춤 과외</text>
<text x="80" y="320" font-family="'Pretendard', sans-serif" font-size="68" font-weight="900" fill="#fbbf24">내신 1등급 전문 과외애서</text>
<text x="80" y="420" font-family="'Pretendard', sans-serif" font-size="30" font-weight="500" fill="#e0e7ff">국어 · 영어 · 수학 · 과학 · 사회 · 수행평가 세특</text>
<text x="80" y="480" font-family="'Pretendard', sans-serif" font-size="28" font-weight="700" fill="#ffffff">전국 568개 동 학교별 기출 족보 완벽 분석</text>
<rect x="80" y="530" width="340" height="50" rx="25" fill="#10b981"/>
<text x="250" y="563" font-family="'Pretendard', sans-serif" font-size="24" font-weight="700" fill="#ffffff" text-anchor="middle">1회 무료 상담: 010-5961-5807</text>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,124 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 480" width="100%" height="100%">
<defs>
<!-- 배경 그라디언트 -->
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#0f172a" />
<stop offset="50%" stop-color="#1e3a8a" />
<stop offset="100%" stop-color="#3b82f6" />
</linearGradient>
<!-- 골드 액센트 그라디언트 -->
<linearGradient id="goldGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#f59e0b" />
<stop offset="100%" stop-color="#fbbf24" />
</linearGradient>
<!-- 카드 반투명 배경 -->
<linearGradient id="cardGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.12" />
<stop offset="100%" stop-color="#ffffff" stop-opacity="0.04" />
</linearGradient>
</defs>
<!-- 메인 배경 -->
<rect width="1200" height="480" rx="16" fill="url(#bgGrad)" />
<!-- 배경 기하학적 그리드 및 원형 장식 -->
<circle cx="1100" cy="80" r="320" fill="#3b82f6" opacity="0.15" />
<circle cx="950" cy="400" r="260" fill="#60a5fa" opacity="0.1" />
<circle cx="150" cy="420" r="180" fill="#1d4ed8" opacity="0.2" />
<!-- 격자 선 데코레이션 -->
<path d="M 0,120 L 1200,120 M 0,240 L 1200,240 M 0,360 L 1200,360" stroke="#ffffff" stroke-opacity="0.05" stroke-width="1" />
<path d="M 300,0 L 300,480 M 600,0 L 600,480 M 900,0 L 900,480" stroke="#ffffff" stroke-opacity="0.05" stroke-width="1" />
<!-- 좌측 컨텐츠 영역 -->
<!-- 1. 상단 배지 태그 -->
<rect x="70" y="55" width="220" height="38" rx="19" fill="url(#goldGrad)" />
<text x="180" y="80" fill="#0f172a" font-size="15" font-weight="900" font-family="'Pretendard', sans-serif" text-anchor="middle">
2026 1:1 밀착 내신 케어
</text>
<!-- 2. 메인 헤드라인 텍스트 -->
<text x="70" y="150" fill="#ffffff" font-size="42" font-weight="900" font-family="'Pretendard', sans-serif" letter-spacing="-1">
우리 학교 기출 족보 완벽 분석
</text>
<text x="70" y="210" fill="#60a5fa" font-size="42" font-weight="900" font-family="'Pretendard', sans-serif" letter-spacing="-1">
내신 1등급 역전 솔루션
</text>
<!-- 3. 서브 카피 텍스트 -->
<text x="70" y="265" fill="#cbd5e1" font-size="18" font-family="'Pretendard', sans-serif" font-weight="500">
서술형 감점 0점 방지부터 수능 1등급 킬러 문항까지,
</text>
<text x="70" y="295" fill="#94a3b8" font-size="18" font-family="'Pretendard', sans-serif" font-weight="500">
관내 학교 전문 검증 튜터가 1:1 맞춤형 커리큘럼을 직접 설계합니다.
</text>
<!-- 4. 하단 특징 뱃지들 -->
<g transform="translate(70, 345)">
<!-- 뱃지 1 -->
<rect x="0" y="0" width="170" height="48" rx="8" fill="url(#cardGrad)" stroke="#ffffff" stroke-opacity="0.2" />
<circle cx="28" cy="24" r="10" fill="#10b981" />
<text x="28" y="28" fill="#ffffff" font-size="11" font-weight="900" text-anchor="middle">✓</text>
<text x="48" y="29" fill="#ffffff" font-size="14" font-weight="700" font-family="'Pretendard', sans-serif">1회 무료 레벨진단</text>
<!-- 뱃지 2 -->
<rect x="185" y="0" width="180" height="48" rx="8" fill="url(#cardGrad)" stroke="#ffffff" stroke-opacity="0.2" />
<circle cx="213" cy="24" r="10" fill="#3b82f6" />
<text x="213" y="28" fill="#ffffff" font-size="11" font-weight="900" text-anchor="middle">✓</text>
<text x="233" y="29" fill="#ffffff" font-size="14" font-weight="700" font-family="'Pretendard', sans-serif">관내 학교 3개년 기출</text>
<!-- 뱃지 3 -->
<rect x="380" y="0" width="175" height="48" rx="8" fill="url(#cardGrad)" stroke="#ffffff" stroke-opacity="0.2" />
<circle cx="408" cy="24" r="10" fill="#f59e0b" />
<text x="408" y="28" fill="#ffffff" font-size="11" font-weight="900" text-anchor="middle">✓</text>
<text x="428" y="29" fill="#ffffff" font-size="14" font-weight="700" font-family="'Pretendard', sans-serif">수행평가 · 세특 코칭</text>
</g>
<!-- 우측 비주얼 인포그래픽 카드 영역 -->
<g transform="translate(740, 60)">
<!-- 우측 메인 카드 배경 -->
<rect x="0" y="0" width="390" height="350" rx="16" fill="url(#cardGrad)" stroke="#ffffff" stroke-opacity="0.2" />
<!-- 성적 상승 그래프 비주얼 -->
<text x="35" y="55" fill="#f8fafc" font-size="18" font-weight="800" font-family="'Pretendard', sans-serif">
AESEO 성적 향상 지표
</text>
<text x="35" y="80" fill="#94a3b8" font-size="13" font-family="'Pretendard', sans-serif">
수강생 평균 2.3등급 수직 상승
</text>
<!-- 등급 비교 바 차트 -->
<g transform="translate(35, 120)">
<!-- 이전 성적 바 -->
<rect x="0" y="70" width="65" height="90" rx="6" fill="#475569" opacity="0.6" />
<text x="32" y="55" fill="#94a3b8" font-size="13" font-weight="700" text-anchor="middle">4등급</text>
<text x="32" y="185" fill="#94a3b8" font-size="12" text-anchor="middle">수강 전</text>
<!-- 과외애서 수강 후 바 -->
<rect x="95" y="10" width="75" height="150" rx="6" fill="url(#goldGrad)" />
<text x="132" y="-5" fill="#f59e0b" font-size="16" font-weight="900" text-anchor="middle">1등급!</text>
<text x="132" y="185" fill="#ffffff" font-size="13" font-weight="800" text-anchor="middle">수강 3개월</text>
<!-- 화살표 곡선 -->
<path d="M 40,75 Q 85,25 105,25" fill="none" stroke="#fbbf24" stroke-width="3" stroke-dasharray="4,4" />
<!-- 오른쪽 미니 스탯 -->
<g transform="translate(195, 20)">
<rect x="0" y="0" width="125" height="55" rx="8" fill="#1e293b" stroke="#334155" />
<text x="12" y="24" fill="#94a3b8" font-size="11">내신 적중률</text>
<text x="12" y="45" fill="#38bdf8" font-size="18" font-weight="900">96.8%</text>
<rect x="0" y="70" width="125" height="55" rx="8" fill="#1e293b" stroke="#334155" />
<text x="12" y="94" fill="#94a3b8" font-size="11">학부모 만족도</text>
<text x="12" y="115" fill="#10b981" font-size="18" font-weight="900">99.2%</text>
</g>
</g>
<!-- 우측 하단 워터마크 -->
<text x="355" y="325" fill="#ffffff" opacity="0.3" font-size="13" font-weight="800" text-anchor="end" font-family="'Pretendard', sans-serif">
AESEO TUTORING POSTER
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

+7
View File
@@ -0,0 +1,7 @@
User-agent: *
Allow: /
User-agent: Yeti
Allow: /
Sitemap: https://aeseo.site/sitemap.xml
File diff suppressed because it is too large Load Diff
+141
View File
@@ -0,0 +1,141 @@
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
const body = await readBody(event)
const {
studentName,
parentPhone,
name,
phone,
schoolName,
grade,
location,
regionName,
memo,
url
} = body || {}
const finalStudentName = studentName || name || '미기재'
const finalParentPhone = parentPhone || phone || ''
const finalLocation = location || regionName || '미기재'
const finalGrade = grade || '미지정'
const finalSchool = schoolName || '미기재'
if (!finalParentPhone) {
throw createError({
statusCode: 400,
statusMessage: '부모님 연락처를 올바르게 입력해주세요.'
})
}
const webhookUrl = config.discordWebhookUrl || 'https://discordapp.com/api/webhooks/1557204310369116210/9J4y96kmSbYNGtw5OxRgIz7InWcM8o3f8UX0Ad71-IyofwdS7tWmXkF7dj457-I8Ypiu'
const siteName = config.public.siteName || '1:1 맞춤과외'
const siteDomain = config.public.siteDomain || 'https://aeseo.cloud'
// 한국 시간 (KST)
const now = new Date()
const kstTime = new Intl.DateTimeFormat('ko-KR', {
timeZone: 'Asia/Seoul',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).format(now)
// 디스코드 Embed 페이로드 (이모지 완전 배제, 깔끔한 직사각형 뱃지 규격)
const discordPayload = {
username: `${siteName} 상담 알림 봇`,
avatar_url: 'https://cdn-icons-png.flaticon.com/512/2997/2997295.png',
embeds: [
{
title: `[신규 무료 상담 신청 접수] ${finalLocation} - ${finalGrade} (${finalStudentName} 학생)`,
description: `**${siteName}** 사이트에서 새로운 1:1 학습 상담 신청이 접수되었습니다.`,
color: 0x991b1b, // 신뢰감 있는 딥 레드/네이비
fields: [
{
name: "[접수 사이트]",
value: `**${siteName}**\n${siteDomain}`,
inline: true
},
{
name: "[사는 곳]",
value: finalLocation,
inline: true
},
{
name: "[학생 이름]",
value: `**${finalStudentName}**`,
inline: true
},
{
name: "[부모님 연락처]",
value: `**${finalParentPhone}**`,
inline: true
},
{
name: "[다니는 학교]",
value: finalSchool,
inline: true
},
{
name: "[학년]",
value: finalGrade,
inline: true
},
{
name: "[접수 일시 (KST)]",
value: kstTime,
inline: true
},
{
name: "[유입 페이지 URL]",
value: url ? `${url}` : `${siteDomain}`,
inline: false
},
{
name: "[상담문의 내용 (선택)]",
value: memo && memo.trim() ? memo.trim() : '입력된 상세 문의 내용 없음',
inline: false
}
],
footer: {
text: `${siteName} 실시간 상담 알림 시스템`
},
timestamp: now.toISOString()
}
]
}
try {
const res = await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(discordPayload)
})
if (!res.ok) {
const errText = await res.text()
console.error('[Discord Webhook Error]:', res.status, errText)
return {
success: false,
message: '디스코드 전송 중 오류가 발생했습니다.'
}
}
return {
success: true,
message: '상담 신청이 정상적으로 완료되었습니다.'
}
} catch (err: any) {
console.error('[Consult Submission Error]:', err.message)
return {
success: false,
message: '서버 오류로 인해 전송에 실패했습니다.'
}
}
})
+32
View File
@@ -0,0 +1,32 @@
import regionsData from '../../data/regions.json'
export default defineEventHandler((event) => {
const config = useRuntimeConfig()
const baseUrl = config.public.siteDomain || 'https://aeseo.site'
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
const subjects = ['영어', '수학', '국어', '통합과학', '통합사회']
const grades = ['중학생', '고등학생']
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n`
// 메인
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n </url>\n`
// 568개 동별 주요 과목 및 학년 URL 생성
list.forEach(r => {
// 1. 동 대표
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}</loc>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n </url>\n`
// 2. 동-과목-학년 대표 조합
subjects.slice(0, 3).forEach(sub => {
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}-${encodeURIComponent(grades[0])}-${encodeURIComponent(sub)}</loc>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n </url>\n`
})
})
xml += `</urlset>`
setHeader(event, 'content-type', 'application/xml; charset=utf-8')
return xml
})
+4
View File
@@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}
+214
View File
@@ -0,0 +1,214 @@
import regionsData from '../data/regions.json'
import keywordsData from '../data/keywords.json'
import curriculumsData from '../data/curriculums.json'
export interface RegionInfo {
fullName: string
sido: string
sigungu: string
dong: string
}
export interface ParsedRouteParams {
region: RegionInfo
sido: string
shortSido: string
sigungu: string
dong: string
shortRegionName: string
grade: string
subjectKey: string
subjectName: string
targetTerm: string
fullKeyword: string
}
// 5대 핵심 과목 정의
export const SUBJECTS_MAP: Record<string, { key: string, name: string, badge: string, aliases: string[] }> = {
korean: { key: 'korean', name: '국어', badge: '문해력·서술형', aliases: ['국어', '문학', '독서', '비문학', '화법'] },
english: { key: 'english', name: '영어', badge: '구문독해·내신', aliases: ['영어', '영문법', '영어독해', '공통영어'] },
math: { key: 'math', name: '수학', badge: '개념정립·킬러문항', aliases: ['수학', '수1', '수2', '미적분', '확통', '기하'] },
science: { key: 'science', name: '과학', badge: '통합과학·물화생지', aliases: ['과학', '통합과학', '물리', '화학', '생명과학', '지구과학', '과탐'] },
social: { key: 'social', name: '사회', badge: '통합사회·한국사', aliases: ['사회', '통합사회', '한국사', '사탐', '역사', '사회문화', '생활과윤리'] }
}
// 학년 정의
export const GRADES_LIST = [
{ key: 'middle', name: '중학생', aliases: ['중학생', '중1', '중2', '중3', '중등'] },
{ key: 'high', name: '고등학생', aliases: ['고등학생', '고1', '고2', '고3', '고등', '예비고1'] },
{ key: 'elem', name: '초등학생', aliases: ['초등학생', '초등', '초5', '초6'] }
]
// 동 이름으로 지역 검색
export function getRegionByDong(dongQuery: string): RegionInfo | null {
if (!dongQuery) return null
const clean = dongQuery.trim().replace(/동$/, '') // '황금' 또는 '황금동' 모두 매칭
const map = regionsData.dongMap as Record<string, RegionInfo[]>
// 1. 정확 매칭 (황금동)
if (map[dongQuery] && map[dongQuery].length > 0) {
return map[dongQuery][0]
}
// 2. '동' 붙여서 매칭
if (map[dongQuery + '동'] && map[dongQuery + '동'].length > 0) {
return map[dongQuery + '동'][0]
}
// 3. 리스트 전체 순회 매칭
const found = (regionsData.list as RegionInfo[]).find(r =>
r.dong === dongQuery ||
r.dong === (dongQuery + '동') ||
r.dong.startsWith(clean)
)
return found || null
}
// 17개 시도 축약 매핑 및 헬퍼 함수 (예: 대구광역시 -> 대구, 서울특별시 -> 서울)
export function getShortSido(sido: string): string {
if (!sido) return ''
const trimmed = sido.trim()
if (trimmed.includes('서울')) return '서울'
if (trimmed.includes('대구')) return '대구'
if (trimmed.includes('부산')) return '부산'
if (trimmed.includes('인천')) return '인천'
if (trimmed.includes('광주')) return '광주'
if (trimmed.includes('대전')) return '대전'
if (trimmed.includes('울산')) return '울산'
if (trimmed.includes('세종')) return '세종'
if (trimmed.includes('경기')) return '경기'
if (trimmed.includes('강원')) return '강원'
if (trimmed.includes('충북') || trimmed.includes('충청북')) return '충북'
if (trimmed.includes('충남') || trimmed.includes('충청남')) return '충남'
if (trimmed.includes('전북') || trimmed.includes('전라북')) return '전북'
if (trimmed.includes('전남') || trimmed.includes('전라남')) return '전남'
if (trimmed.includes('경북') || trimmed.includes('경상북')) return '경북'
if (trimmed.includes('경남') || trimmed.includes('경상남')) return '경남'
if (trimmed.includes('제주')) return '제주'
return trimmed.slice(0, 2)
}
// 축약 지역명 생성 (예: '대구 황금동', '서울 대치동', '경기 정발산동')
export function getShortRegionName(sido: string, dong: string, sigungu?: string): string {
const meta = regionsData as any
const prefix = meta.keywordPrefix !== undefined ? meta.keywordPrefix : `${getShortSido(sido)} `
if (prefix === '') {
// 서울 (예: 강남구 개포동)
return `${sigungu ? sigungu + ' ' : ''}${dong || ''}`.trim()
}
// 경기, 인천, 광주, 부산, 대구, 대전 (예: 경기 수원 영통동, 대구 수성구 범어동)
return `${prefix}${sigungu ? sigungu + ' ' : ''}${dong || ''}`.trim()
} ${dong || ''}`.trim()
}
// 지능형 URL 슬러그 파서
// 지원 예시:
// - ['대구광역시', '수성구', '황금동']
// - ['대구광역시', '황금동', '중학생', '영어']
// - ['황금동', '중학생', '영어']
// - ['황금동-중학생-영어']
// - '대구광역시-황금동-중학생-영어'
export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams {
let tokens: string[] = []
if (Array.isArray(slugInput)) {
tokens = slugInput.flatMap(s => decodeURIComponent(s).split(/[-_\s/]+/))
} else if (typeof slugInput === 'string' && slugInput.trim()) {
tokens = decodeURIComponent(slugInput).split(/[-_\s/]+/)
}
tokens = tokens.map(t => t.trim()).filter(Boolean)
let matchedRegion: RegionInfo | null = null
let detectedGrade = '중학생'
let detectedSubjectKey = 'english'
let detectedSubjectName = '영어'
let detectedTerm = '과외'
// 1. 토큰들 중 동 이름 매칭
for (const token of tokens) {
const reg = getRegionByDong(token)
if (reg) {
matchedRegion = reg
break
}
}
// 2. 동 이름이 토큰에 없으면 전체 리스트에서 부분 일치 검색
if (!matchedRegion && tokens.length > 0) {
for (const token of tokens) {
const found = (regionsData.list as RegionInfo[]).find(r => token.includes(r.dong) || (token.length >= 2 && r.dong.includes(token)))
if (found) {
matchedRegion = found
break
}
}
}
// 기본값 (568개 타겟 지역 중 첫 번째 기준)
if (!matchedRegion) {
matchedRegion = (regionsData.list as RegionInfo[])[0] || {
fullName: '경기도 고양시 덕양구 고양동',
sido: '경기도',
sigungu: '고양시 덕양구',
dong: '고양동'
}
}
// 3. 학년 추출
const fullText = tokens.join(' ')
for (const g of GRADES_LIST) {
if (g.aliases.some(a => fullText.includes(a))) {
detectedGrade = g.name
break
}
}
// 4. 과목 추출
for (const [key, sub] of Object.entries(SUBJECTS_MAP)) {
if (sub.aliases.some(a => fullText.includes(a))) {
detectedSubjectKey = key
detectedSubjectName = sub.name
break
}
}
// 5. 목적/행동 추출
if (fullText.includes('내신')) detectedTerm = '내신대비'
else if (fullText.includes('학원')) detectedTerm = '학원추천'
else if (fullText.includes('수능')) detectedTerm = '수능대비'
else if (fullText.includes('기출')) detectedTerm = '기출문제분석'
else detectedTerm = '1:1 맞춤과외'
const shortSido = getShortSido(matchedRegion.sido)
const shortRegionName = getShortRegionName(matchedRegion.sido, matchedRegion.dong, matchedRegion.sigungu)
const fullKeyword = `${shortRegionName} ${detectedGrade} ${detectedSubjectName} ${detectedTerm}`
return {
region: matchedRegion,
sido: matchedRegion.sido,
shortSido,
sigungu: matchedRegion.sigungu,
dong: matchedRegion.dong,
shortRegionName,
grade: detectedGrade,
subjectKey: detectedSubjectKey,
subjectName: detectedSubjectName,
targetTerm: detectedTerm,
fullKeyword
}
}
export function getAllSubjectsList() {
return Object.values(SUBJECTS_MAP)
}
export function getCurriculumBySubject(subjectKey: string) {
const data = curriculumsData as any
return data[subjectKey] || data['english']
}
export function getPopularRegions(count = 20) {
return (regionsData.list as RegionInfo[]).slice(0, count)
}
export function getTotalRegionsCount() {
return regionsData.total
}
+94
View File
@@ -0,0 +1,94 @@
import type { ParsedRouteParams } from './dataHelper'
import { getShortRegionName } from './dataHelper'
export function generateSeoMeta(parsed: ParsedRouteParams, siteName = '튜터온', siteDomain = 'https://aeseo.site') {
const { sido, sigungu, dong, shortRegionName, grade, subjectName, targetTerm, fullKeyword } = parsed
const regionTitle = shortRegionName || getShortRegionName(sido, dong)
const pageTitle = `${regionTitle} ${grade} ${subjectName} 과외 | ${dong} 내신·수능 1:1 맞춤수업 - ${siteName}`
const pageDescription = `${sido} ${sigungu} ${dong} 지역 초·중·고 ${grade} ${subjectName} 1:1 전문 과외. 인근 학교별 기출 족보 완벽 분석, 서술형 감점 방지, 취약 개념 클리닉 및 맞춤 학습 플래너 제공. 지금 ${dong} 무료 학습 진단 및 모의수업을 신청하세요.`
// 표준 Canonical URL
const canonicalUrl = `${siteDomain}/${encodeURIComponent(dong)}-${encodeURIComponent(grade)}-${encodeURIComponent(subjectName)}`
const jsonLd = {
'@context': 'https://schema.org',
'@graph': [
{
'@type': 'EducationalOrganization',
'name': siteName,
'url': siteDomain,
'description': pageDescription,
'areaServed': {
'@type': 'AdministrativeArea',
'name': `${sido} ${sigungu} ${dong}`
}
},
{
'@type': 'Course',
'name': `${dong} ${grade} ${subjectName} 1:1 맞춤 과외`,
'description': `${dong} 인근 학교 내신 출제 경향 분석 및 ${subjectName} 1등급 도약 커리큘럼`,
'provider': {
'@type': 'Organization',
'name': siteName
}
},
{
'@type': 'BreadcrumbList',
'itemListElement': [
{
'@type': 'ListItem',
'position': 1,
'name': '홈',
'item': siteDomain
},
{
'@type': 'ListItem',
'position': 2,
'name': sido,
'item': `${siteDomain}/${encodeURIComponent(sido)}`
},
{
'@type': 'ListItem',
'position': 3,
'name': sigungu,
'item': `${siteDomain}/${encodeURIComponent(sigungu)}`
},
{
'@type': 'ListItem',
'position': 4,
'name': `${dong} ${subjectName}`,
'item': canonicalUrl
}
]
}
]
}
return {
title: pageTitle,
meta: [
{ name: 'naver-site-verification', content: '797ab1ac988eb27c80ae544bb6aba05c2231a9c9' },
{ name: 'description', content: pageDescription },
{ name: 'keywords', content: `${dong}과외, ${dong}${subjectName}과외, ${dong}${grade}과외, ${sigungu}과외, ${dong}학원, ${dong}내신대비, ${subjectName}1:1과외` },
{ property: 'og:type', content: 'website' },
{ property: 'og:title', content: pageTitle },
{ property: 'og:description', content: pageDescription },
{ property: 'og:url', content: canonicalUrl },
{ property: 'og:site_name', content: siteName },
{ property: 'og:image', content: `${siteDomain}/img/og-preview.png` },
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'twitter:title', content: pageTitle },
{ name: 'twitter:description', content: pageDescription }
],
link: [
{ rel: 'canonical', href: canonicalUrl }
],
script: [
{
type: 'application/ld+json',
children: JSON.stringify(jsonLd)
}
]
}
}