// MSECM 가로 페이지 사이트 (2026-10 리디자인)
// 페이지 6장을 가로로 나란히 두고 scroll-snap으로 한 장씩 넘긴다.
// 이전 세로 원페이지 디자인은 _backup_2026-10-13_원페이지디자인/ 에 있다.
const { useState, useEffect, useRef } = React;
const D = window.MSECM_DATA;

// 외부 글 제목의 긴 줄표를 짧은 하이픈으로
const clean = (s) => (s || '').replace(/\s*[—–]\s*/g, ' - ');

const PAGES = [
  { id: 'home', label: '홈' },
  { id: 'business', label: '사업분야' },
  { id: 'services', label: '서비스' },
  { id: 'record', label: '운영 실적' },
  { id: 'history', label: '연혁' },
  { id: 'news', label: '소식' },
  { id: 'contact', label: '회사·문의' },
];

function App() {
  const trackRef = useRef(null);
  const [active, setActive] = useState(0);

  const go = (i, smooth = true) => {
    const track = trackRef.current;
    if (!track || i < 0 || i >= PAGES.length) return;
    track.scrollTo({ left: i * track.clientWidth, behavior: smooth ? 'smooth' : 'auto' });
  };

  // 지금 보이는 페이지 추적 → 메뉴 표시·주소(#id) 갱신
  useEffect(() => {
    const track = trackRef.current;
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (!e.isIntersecting) continue;
        const i = PAGES.findIndex((p) => p.id === e.target.id);
        setActive(i);
        history.replaceState(null, '', i === 0 ? location.pathname : `#${PAGES[i].id}`);
      }
    }, { root: track, threshold: 0.6 });
    track.querySelectorAll('.page').forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);

  // 주소의 #id 페이지로 이동: 첫 진입은 즉시, 이후 주소가 바뀌면 부드럽게
  useEffect(() => {
    const toHash = (smooth) => {
      const i = PAGES.findIndex((p) => `#${p.id}` === location.hash);
      if (i >= 0) go(i, smooth);
    };
    requestAnimationFrame(() => toHash(false));
    const onHash = () => toHash(true);
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  // 모바일 메뉴 줄에서 현재 페이지 탭이 보이도록
  useEffect(() => {
    document.querySelector('.tabs [aria-current="page"]')?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
  }, [active]);

  // 키보드 ← → 로 페이지 넘김 (입력 중일 때는 제외)
  useEffect(() => {
    const onKey = (e) => {
      if (e.target.closest('input, textarea, [contenteditable]')) return;
      const d = e.key === 'ArrowRight' ? 1 : e.key === 'ArrowLeft' ? -1 : 0;
      if (!d) return;
      e.preventDefault(); // 트랙 자체의 화살표 스크롤과 겹치지 않게
      go(active + d);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [active]);

  // 창 크기가 바뀌면 현재 페이지 위치 다시 맞춤
  useEffect(() => {
    const onResize = () => go(active, false);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, [active]);

  const goId = (id) => go(PAGES.findIndex((p) => p.id === id));
  const onNav = (e, i) => { e.preventDefault(); go(i); };
  const prev = PAGES[active - 1], next = PAGES[active + 1];
  const pageClass = (i) => `page${i === active ? ' is-active' : ''}`;

  return (
    <>
      <header className="nav">
        <a className="brand" href="#" onClick={(e) => onNav(e, 0)} aria-label="MSECM 홈">
          <img className="logo" src="/assets/msecm-logo.avif" alt="MSECM" width="284" height="104" />
        </a>
        <nav className="tabs" aria-label="페이지">
          {PAGES.map((p, i) => (
            <a key={p.id} href={`#${p.id}`} aria-current={i === active ? 'page' : undefined} onClick={(e) => onNav(e, i)}>{p.label}</a>
          ))}
        </nav>
      </header>

      <main className="track" ref={trackRef}>
        {PAGES.map((p, i) => {
          const View = VIEWS[p.id];
          return <section key={p.id} id={p.id} className={pageClass(i)}><View go={goId} /></section>;
        })}
      </main>

      <div className="pager">
        <button onClick={() => go(active - 1)} disabled={!prev} aria-label={prev ? `이전: ${prev.label}` : '이전'}>
          <i className="ph ph-arrow-left" aria-hidden="true"></i>
        </button>
        <span className="pos num" aria-live="polite">{active + 1} / {PAGES.length}</span>
        <button onClick={() => go(active + 1)} disabled={!next}>
          <span className="label">{next ? next.label : '마지막'}</span>
          <i className="ph ph-arrow-right" aria-hidden="true"></i>
        </button>
      </div>

    </>
  );
}

// ── 1. 홈 ────────────────────────────────────
function Home({ go }) {
  return (
    <div className="page-inner">
      <div className="home">
        <div className="home-copy">
          <p className="eyebrow rv">교육·위탁운영 NO.1 파트너</p>
          <h1 className="h1 rv" style={{ '--i': 1 }}>공공교육과 시설 운영을<br />18년째 맡고 있습니다</h1>
          <p className="lead rv" style={{ '--i': 2 }}>공무원·교원·시민 교육과 공공 교육시설 위탁 운영, 그리고 직접 만든 교육 서비스를 운영합니다.</p>
          <div className="home-ctas rv" style={{ '--i': 3 }}>
            <button className="btn btn-primary" onClick={() => go('contact')}>상담 문의 <i className="ph ph-arrow-right" aria-hidden="true"></i></button>
            <button className="btn btn-ghost" onClick={() => go('business')}>사업분야 보기</button>
          </div>
        </div>
        <figure className="home-media rv" style={{ '--i': 2, margin: 0 }}>
          <img className="photo" src="/assets/cap-education.jpg" alt="공무원 대상 탄소중립·녹색성장 인식교육 현장" fetchpriority="high" />
        </figure>
      </div>
      <div className="stats">
        {D.stats.map((s, i) => (
          <div key={s.l} className="stat rv" style={{ '--i': 4 + i }}>
            <b className="num">{s.v}</b><span>{s.l}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── 2. 사업분야 ──────────────────────────────
const BIZ = [
  {
    letter: 'E', name: '교육·연수', short: '공무원, 교원, 시민 대상 역량강화',
    img: '/assets/photo-workshop.jpg', alt: '공무원 역량강화 워크숍 현장', caption: '공무원 역량강화 워크숍',
    title: '현장에서 바로 쓰는 역량을 가르칩니다',
    facts: [
      '2018년 이후 공무원 5,514명 교육',
      '2009년부터 전국 지자체·공공기관 공무원 독서통신교육',
      '생성형 AI 활용 교원역량강화 연수',
      '부산·경남교육연수원 지정 교원 특수분야 연수기관 (2014)',
    ],
  },
  {
    letter: 'C', name: '교육 콘텐츠', short: '체험 프로그램, SW·AI, 독서 교육',
    img: '/assets/cap-contents.jpg', alt: '독서통신교육 휴러닝 소개 이미지', caption: '독서통신교육 휴러닝',
    title: '배우는 사람이 머무는 콘텐츠를 만듭니다',
    facts: [
      '미래교육원 체험 콘텐츠 기획·개발',
      '부산광역시교육청 SW·AI교육거점센터 체험프로그램 개발',
      '공무원 독서통신교육 「휴러닝」, 초등 명작 도서관 「부기」 직접 운영',
      '지역 관광·문화 융합형 교육프로그램 개발',
    ],
  },
  {
    letter: 'M', name: '시설·행사 운영', short: '공공 교육시설 위탁, 포럼·워크숍 운영',
    img: '/assets/photo-forum.jpg', alt: '시민 포럼 패널 토론 현장', caption: '탄소중립 시민 포럼',
    title: '큰 시설과 행사를 안정적으로 운영합니다',
    facts: [
      '이순신리더십국제센터 민간위탁 운영 (2020년~)',
      '경상남도교육청 미래교육원 체험프로그램 위탁 운영 (2023년~)',
      '탄소중립 시민 포럼 운영, 유튜브 실시간 송출',
      '도시재생 문화도시 사업 위탁 운영',
    ],
  },
];

function Business() {
  const [sel, setSel] = useState(0);
  const b = BIZ[sel];
  return (
    <div className="page-inner">
      <h2 className="h2 rv">교육, 콘텐츠, 운영을 한 회사가 맡습니다</h2>
      <div className="biz">
        <div className="biz-list rv" style={{ '--i': 1 }} role="tablist" aria-label="사업분야">
          {BIZ.map((x, i) => (
            <button key={x.letter} className="biz-item" role="tab" aria-selected={i === sel} aria-controls="biz-panel" onClick={() => setSel(i)}>
              <span className="letter" aria-hidden="true">{x.letter}</span>
              <span className="name">{x.name}</span>
              <span className="short">{x.short}</span>
            </button>
          ))}
        </div>
        <div id="biz-panel" className="biz-detail rv" style={{ '--i': 2 }} role="tabpanel">
          <figure style={{ margin: 0 }}>
            <div className="media"><img key={b.img} className="photo" src={b.img} alt={b.alt} loading="lazy" /></div>
            <figcaption className="caption">{b.caption}</figcaption>
          </figure>
          <div>
            <h3 className="h3">{b.title}</h3>
            <ul className="facts">
              {b.facts.map((f) => <li key={f}><i className="ph ph-check" aria-hidden="true"></i><span>{f}</span></li>)}
            </ul>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── 3. 서비스 (직접 만들어 운영하는 교육 서비스) ──
const SERVICES = [
  {
    name: '휴러닝', logo: '/assets/logo-hulearning.png', logoW: 134, logoH: 40, who: '지자체·공공기관 전문 독서학습', color: '#0076ab', url: 'http://huedu.co.kr/', host: 'huedu.co.kr',
    slides: [{ img: '/assets/shot-hulearning.jpg', alt: '휴러닝 사이트 첫 화면' }],
    lead: '대한민국 공공기관에서 가장 많이 채택한 독서 통신 교육 프로그램',
    facts: ['2009년 전국 지자체 및 공공기관 「독서통신교육」 사업 개시', '30,000권의 도서권수, 매월 100권 이상 신규 도서 업데이트', '교육 담당자·학습자 만족도 최고'],
  },
  {
    name: '부기', logo: '/assets/logo-bookie.png', logoW: 76, logoH: 50, who: '교실을 위한 어린이 명작 도서관', color: '#004020', url: 'https://bookie.io.kr/', host: 'bookie.io.kr',
    slides: [
      { label: '첫 화면', img: '/assets/shot-bookie-landing.jpg', alt: '부기 어린이 명작 도서관 첫 화면' },
      { label: '책 숲', img: '/assets/shot-bookie-forest.jpg', alt: '학년별 집을 걸어 다니며 책을 고르는 책 숲 화면' },
      { label: '교사 앱', img: '/assets/shot-bookie-teacher.jpg', alt: '교사 앱 오늘 우리 반 화면: 학급 읽기 진행과 열려 있는 활동' },
      { label: '학생 앱', img: '/assets/shot-bookie-student.jpg', alt: '학생 앱 나의 책상 화면: 지금 읽는 책과 독서 레벨' },
    ],
    lead: '책과 이야기하며 스스로 생각하는 아이로 자라도록 돕습니다.',
    facts: ['어린이 명작 300권, 1~6학년 학년별 추천 서가', '저학년 그림책 100권', '모든 책에 다양한 독후 활동과 수업 설계 제공'],
  },
  {
    // 문구는 앱 첫 화면 원문. 자세한 소개는 /jinro-passport 한 장짜리 페이지
    name: '학생 진로 여권', logo: '/assets/logo-jinro-passport.svg', logoW: 40, logoH: 40, logoText: '학생 진로 여권', who: 'CAREER PASSPORT · 누구나 무료', color: '#123e7a',
    url: 'https://jinro-passport.vercel.app/', host: 'jinro-passport.vercel.app', more: '/jinro-passport', wide: true,
    slides: [
      { label: '첫 화면', img: '/assets/jp-landing.jpg', alt: '학생 진로 여권 첫 화면' },
      { label: '내 여권', img: '/assets/jp-passport.jpg', alt: '학생 여권 첫 장: 나의 힘 육각형과 나의 흥미 육각형' },
      { label: '성장 지도', img: '/assets/jp-map.jpg', alt: '성장 지도: 기록이 길처럼 이어진 화면' },
      { label: '선생님 화면', img: '/assets/jp-stats.jpg', alt: '선생님 화면의 반 통계' },
    ],
    lead: '진로 흥미 검사, 체험 도장, 직업 영상, 성장 기록을 학생 한 명당 여권 한 권에 모아요. 학교, 진로체험처, 진로교육 기관 누구나 회원가입만 하면 바로 쓸 수 있어요.',
    facts: ['흥미 검사 39문항 · 직업 40개 · 영상 80편', '체험 도장, 성장 지도, 미션과 선생님 확인', '학생 이름 받지 않음'],
  },
];

// 교사 제작 콘텐츠 (문구는 에듀랩.kr 원문, 코딩 레이싱·드론촬영은 사이트에 «서비스 준비중»)
const TEACHER_MADE = [
  {
    name: '에듀랩', logo: '/assets/logo-edulab.png', logoW: 50, logoH: 50, logoText: '에듀랩', who: '미래교육 플랫폼', color: '#316dc7', url: 'https://www.xn--ox1b68crws.kr/', host: '에듀랩.kr',
    slides: [
      { label: '첫 화면', img: '/assets/shot-edulab-landing.jpg', alt: '에듀랩 첫 화면: 드론축구·드론레이싱·코딩 레이싱·드론촬영 카드' },
      { label: '드론축구', img: '/assets/shot-edulab-soccer.jpg', alt: '드론축구 경기 화면' },
      { label: '드론레이싱', img: '/assets/shot-edulab-racing.jpg', alt: '드론레이싱 경기 화면' },
    ],
    lead: '에듀랩 드론 프로그램은 드론축구, 레이싱, 코딩, 촬영 활동을 통해 학생들이 조종 기술을 넘어 협업하고, 창작하며, 미래를 설계하도록 돕는 체험형 미래교육입니다.',
    facts: ['드론축구 · 드론레이싱 운영, 코딩 레이싱 · 드론촬영 서비스 준비중', '설치 없이 브라우저에서 바로 · 컴퓨터 · 태블릿 · 휴대폰 모두 가능', '학생은 이름 없이 기록 코드로'],
  },
];

// 서비스 화면 캡처. 두 장 이상이면 5초마다 넘기고, 마우스·초점이 올라가 있으면 멈춤
function Shots({ v }) {
  const n = v.slides.length;
  const [i, setI] = useState(0);
  const [hold, setHold] = useState(false);
  useEffect(() => {
    if (n < 2 || hold || window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const t = setInterval(() => setI((k) => (k + 1) % n), 5000);
    return () => clearInterval(t);
  }, [n, hold]);
  return (
    <div className="shots" onMouseEnter={() => setHold(true)} onMouseLeave={() => setHold(false)}
      onFocus={() => setHold(true)} onBlur={() => setHold(false)}>
      <a className="shot" href={v.url} target="_blank" rel="noopener noreferrer" aria-label={`${v.name} 사이트 열기`}>
        {v.slides.map((s, k) => (
          <img key={s.img} className={`photo${k === i ? ' on' : ''}`} src={s.img} alt={k === i ? s.alt : ''} aria-hidden={k !== i} loading="lazy" />
        ))}
      </a>
      {n > 1 && (
        <div className="slide-tabs" role="tablist" aria-label={`${v.name} 화면`}>
          {v.slides.map((s, k) => (
            <button key={s.label} role="tab" aria-selected={k === i} onClick={() => setI(k)}>{s.label}</button>
          ))}
        </div>
      )}
    </div>
  );
}

function ServiceCard({ v, i, wide }) {
  return (
    <article className={`service rv${wide || v.wide ? ' wide' : ''}`} style={{ '--i': i }}>
      <div className="service-head">
        <h3 className="logo-head">
          <img src={v.logo} alt={v.logoText ? '' : v.name} width={v.logoW} height={v.logoH} />
          {v.logoText && <span>{v.logoText}</span>}
        </h3>
        <span className="who" style={{ color: v.color }}>{v.who}</span>
        <a className="visit" href={v.url} target="_blank" rel="noopener noreferrer">{v.host} <i className="ph ph-arrow-up-right" aria-hidden="true"></i></a>
      </div>
      <p className="body">{v.lead}</p>
      <ul className="facts">
        {v.facts.map((f) => <li key={f}><i className="ph ph-check" aria-hidden="true"></i><span>{f}</span></li>)}
      </ul>
      {v.more && <a className="btn btn-ghost more" href={v.more}>자세히 보기 <i className="ph ph-arrow-right" aria-hidden="true"></i></a>}
      <Shots v={v} />
    </article>
  );
}

function Services() {
  return (
    <div className="page-inner">
      <h2 className="h2 rv">직접 만들어 운영하는 교육 서비스</h2>
      <div className="services">
        {SERVICES.map((v, i) => <ServiceCard key={v.name} v={v} i={1 + i} />)}
        <h3 className="eyebrow services-group rv" style={{ '--i': 4 }}>교사 제작 콘텐츠</h3>
        {TEACHER_MADE.map((v, i) => <ServiceCard key={v.name} v={v} i={5 + i} wide />)}
      </div>
    </div>
  );
}

// ── 4. 운영 실적 ─────────────────────────────
const FACILITIES = [
  {
    name: '이순신리더십국제센터', since: '2020년부터 운영',
    img: '/assets/photo-yisunsin-center.jpg', alt: '이순신리더십국제센터 건물 전경',
    big: '6만 2천명', bigNote: '누적 1,400여 건',
    body: '국가지정 K-리더십 교육 수탁기관입니다. 대회의장, 회의실, 숙박시설, 이순신 체험관까지 시설 전반을 맡고 있습니다.',
  },
  {
    name: '경상남도교육청 미래교육원', since: '2023년부터 운영',
    img: '/assets/photo-future-center.jpg', alt: '경상남도교육청 미래교육원 전경',
    big: '28만여 명', bigNote: '누적 체험객',
    body: '2023년 9월 개원 후 1년 3개월 만에 25만 명을 넘었습니다. 평일 학교 단체, 주말 체험, 방학 심화 과정을 연중무휴로 운영합니다.',
  },
];

function Record() {
  return (
    <div className="page-inner">
      <h2 className="h2 rv">지금 운영 중인 공공시설</h2>
      <div className="record">
        {FACILITIES.map((f, i) => (
          <article key={f.name} className="facility rv" style={{ '--i': 1 + i }}>
            <div className="media"><img className="photo" src={f.img} alt={f.alt} loading="lazy" /></div>
            <div className="meta"><h3 className="h3">{f.name}</h3><span className="since">{f.since}</span></div>
            <p className="big num">{f.big}<small>{f.bigNote}</small></p>
            <p className="body">{f.body}</p>
          </article>
        ))}
        <aside className="clients rv" style={{ '--i': 3 }}>
          <h3>함께 일한 기관</h3>
          <div className="client-grid">
            {D.clients.map((c) => <span key={c}>{c}</span>)}
          </div>
          <p className="client-note">휴러닝으로 전국 지자체·공공기관과도 함께합니다.</p>
          <div className="also">
            <b>부산광역시교육청 SW·AI교육거점센터</b>
            <span>2026년 체험프로그램 위탁 운영</span>
          </div>
        </aside>
      </div>
    </div>
  );
}

// ── 5. 연혁 ──────────────────────────────────
const ERAS = [
  { name: 'AI·미래교육', range: '2024 - 2026', from: 2024, to: 2026 },
  { name: '공공시설 위탁 운영', range: '2020 - 2023', from: 2020, to: 2023 },
  { name: '교육 전문기업 기반', range: '2008 - 2019', from: 2008, to: 2019 },
];

function History() {
  return (
    <div className="page-inner">
      <h2 className="h2 rv">연도별 주요 사업</h2>
      <div className="eras">
        {ERAS.map((era, i) => (
          <div key={era.name} className="rv" style={{ '--i': 1 + i }}>
            <div className="era-head"><b>{era.name}</b><span className="num">{era.range}</span></div>
            {D.timeline.filter((t) => t.year >= era.from && t.year <= era.to).map((t) => (
              <div key={t.year} className="year">
                <b className="num">{t.year}</b>
                <div>
                  <p className="theme">{t.theme}</p>
                  <ul>{t.items.map((it) => <li key={it}>{it}</li>)}</ul>
                </div>
              </div>
            ))}
          </div>
        ))}
      </div>
    </div>
  );
}

// ── 6. 소식 (네이버 블로그 + 교육 뉴스, 라이브) ──
// 실패해도 무한 로딩이 되지 않게 8초 타임아웃
function useFeed(url, pick) {
  const [state, setState] = useState({ status: 'loading', items: [] });
  const [tick, setTick] = useState(0);
  useEffect(() => {
    let alive = true;
    setState({ status: 'loading', items: [] });
    fetch(url, { signal: AbortSignal.timeout(8000) })
      .then((r) => (r.ok ? r.json() : Promise.reject(r.status)))
      .then((d) => { const items = pick(d); if (alive) setState({ status: items.length ? 'ok' : 'empty', items }); })
      .catch(() => alive && setState({ status: 'error', items: [] }));
    return () => { alive = false; };
  }, [url, tick]);
  return [state, () => setTick((t) => t + 1)];
}

const pickPosts = (d) => (d.topics || [])
  .flatMap((t) => t.posts || [])
  .sort((a, b) => (b.publishedAt || '').localeCompare(a.publishedAt || ''))
  .slice(0, 3);
const pickNews = (d) => (d.items || []).slice(0, 6);

function FeedState({ status, retry, what }) {
  if (status === 'empty') return <div className="state">아직 올라온 {what}이 없습니다.</div>;
  return (
    <div className="state">
      {what}을 불러오지 못했습니다.
      <button className="btn btn-ghost" onClick={retry}>다시 시도</button>
    </div>
  );
}

function News() {
  const [blog, retryBlog] = useFeed('/api/insights', pickPosts);
  const [news, retryNews] = useFeed('/api/news', pickNews);
  return (
    <div className="page-inner">
      <h2 className="h2 rv">현장 소식과 교육 뉴스</h2>
      <div className="news">
        <div className="rv" style={{ '--i': 1 }}>
          <div className="col-head">
            <b>MSECM 블로그</b>
            <a href="https://blog.naver.com/ms_ecm" target="_blank" rel="noopener noreferrer">전체 보기 <i className="ph ph-arrow-up-right" aria-hidden="true"></i></a>
          </div>
          {blog.status === 'loading' && (
            <div className="posts">
              <div className="post"><div className="media skel"></div><div className="skel" style={{ height: 60 }}></div></div>
            </div>
          )}
          {blog.status === 'ok' && (
            <div className="posts">
              {blog.items.map((p) => (
                <a key={p.link} className="post" href={p.link} target="_blank" rel="noopener noreferrer">
                  <div className="media">{p.thumbnail && <img className="photo" src={p.thumbnail} alt="" loading="lazy" referrerPolicy="no-referrer" />}</div>
                  <div style={{ display: 'grid', gap: 8 }}>
                    <span className="date num">{p.date}</span>
                    <span className="title">{clean(p.title)}</span>
                    {p.summary && <span className="sum">{clean(p.summary)}</span>}
                  </div>
                </a>
              ))}
            </div>
          )}
          {(blog.status === 'error' || blog.status === 'empty') && <FeedState status={blog.status} retry={retryBlog} what="글" />}
        </div>

        <div className="rv" style={{ '--i': 2 }}>
          <div className="col-head"><b>교육 뉴스</b></div>
          {news.status === 'loading' && [0, 1, 2, 3].map((i) => <div key={i} className="skel" style={{ height: 54, margin: '16px 0' }}></div>)}
          {news.status === 'ok' && (
            <ul className="headlines">
              {news.items.map((n) => (
                <li key={n.link}>
                  <a href={n.link} target="_blank" rel="noopener noreferrer">
                    <span className="src">{n.source}, {n.time}</span>
                    <span className="t">{clean(n.title)}</span>
                  </a>
                </li>
              ))}
            </ul>
          )}
          {(news.status === 'error' || news.status === 'empty') && <FeedState status={news.status} retry={retryNews} what="뉴스" />}
        </div>
      </div>
    </div>
  );
}

// ── 7. 회사·문의 ─────────────────────────────
function Contact() {
  const c = D.company;
  return (
    <div className="page-inner">
      <div className="contact-band rv">
        <img className="photo" src="/assets/photo-corridor.jpg" alt="" loading="lazy" style={{ position: 'absolute', inset: 0 }} />
        <div className="copy">
          <h2 className="h2">사업 상담은 전화와 메일로 받습니다</h2>
          <p>교육 위탁, 연수 과정 설계, 시설 운영 제안을 검토해 회신드립니다.</p>
        </div>
      </div>
      <div className="ways rv" style={{ '--i': 1 }}>
        <a className="way" href={`tel:${c.tel}`}><i className="ph ph-phone" aria-hidden="true"></i><span>대표 전화</span><b className="num">{c.tel}</b></a>
        <a className="way" href={`mailto:${c.email}`}><i className="ph ph-envelope-simple" aria-hidden="true"></i><span>이메일</span><b>{c.email}</b></a>
        <a className="way" href={`https://map.naver.com/p/search/${encodeURIComponent(c.address.split(',')[0])}`} target="_blank" rel="noopener noreferrer">
          <i className="ph ph-map-pin" aria-hidden="true"></i><span>찾아오시는 길</span><b style={{ fontSize: 17, lineHeight: 1.45 }}>{c.address}</b>
        </a>
      </div>
      <dl className="company rv" style={{ '--i': 2 }}>
        <div><dt>상호</dt><dd>{c.name}</dd></div>
        <div><dt>대표</dt><dd>{c.ceo}</dd></div>
        <div><dt>설립</dt><dd>{c.founded}</dd></div>
        <div><dt>팩스</dt><dd className="num">{c.fax}</dd></div>
      </dl>
      <p className="copyright">© {new Date().getFullYear()} {c.name}. All rights reserved.</p>
    </div>
  );
}

const VIEWS = { home: Home, business: Business, services: Services, record: Record, history: History, news: News, contact: Contact };

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
