stylelint 도 html-validate 도 "var(--x) 를 썼는데 --x 가 어디에도 없다"를 잡지 못한다. 미정의 변수는 선언 전체를 무효로 만드는데 콘솔 에러가 없어 조용히 남는다. 검사기를 심자마자 v0.9.1 의 실제 결함이 나왔다. 게이트 신설 - tools/integrity.mjs — L0 무결성. CSS 커스텀 프로퍼티 참조, 상대경로, 한글 조판 필수 규칙(keep-all·한글 폰트 지정), 슬롭 지문, 스크롤 리스너를 검사. verify.mjs 체인에 편입해 실패 시 배포를 막는다. 폴백이 있는 var(--x, 기본값) 은 선택적 주입이므로 미정의로 세지 않는다. - tools/showcase-audit.mjs — 320/390/768/1440 실렌더 감사. 가로 스크롤·오버플로· 컨트롤 줄바꿈·대비 AA·왼쪽 인셋·h1 개수·히어로 줄 수·깨진 이미지·콘솔 에러. 반투명 배경을 합성해 대비를 재고, WebGL 페이지를 위해 swiftshader 로 렌더한다. - html-validate 대상을 두 페이지에서 public/work 전체로 넓혔다. 수리한 결함 - 미정의 변수 64건: --dur-fast·--radius-xs 가 정의된 적이 없어 cask-archive, cheongon-care, materia-interior 의 transition 선언이 통째로 무효였다. 새 토큰을 만들지 않고 기존 --dur-quick·--radius 로 매핑했다 — 토큰을 늘리면 radius 어휘가 4종이 되어 하드 게이트 3에 걸린다. - 한글 조판: lumina-optics·pulsegate·synapse-bci 가 word-break: keep-all 없이 IBM Plex Sans 만 지정해 한글이 시스템 기본으로 떨어지고 있었다. 같은 계열의 IBM Plex Sans KR 을 스택에 넣고 keep-all 을 추가했다. - 슬롭 지문 19건: text-transform: uppercase 로 만든 영문 대문자 eyebrow 를 한글 문장으로 바꾸고, 대문자용으로 잡아둔 넓은 자간과 모노 서체도 되돌렸다. - 하드 게이트 9: materia-interior/hannam-duplex.html 의 100vh → 100dvh. 이 파일은 어디서도 참조되지 않으면서 인라인 hex 까지 갖고 있어 토큰 기반으로 다시 썼다. - 접근성 11건: label 하나가 output 과 input 둘에 걸리던 것 5건(font-foundry, lumina-optics), dl > div > div > dt 4건(muwol-coffee), div 에 붙은 aria-label 2건(overtone-sound, pulsegate). 측정기 자체의 오류 둘도 고쳤다 — 눈에 보이지 않는 .sr-only 를 대비 실패로 잡던 것과, overflow-x: auto 상자 안의 넓은 표를 오버플로로 잡던 것. 재는 도구가 틀리면 통과도 실패도 의미가 없다.
608 lines
30 KiB
HTML
608 lines
30 KiB
HTML
<!doctype html>
|
||
<html lang="ko">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||
<title>청온 케어 (淸溫) · 프리미엄 주거·오피스 전문 위생 케어 & 관제 콘솔</title>
|
||
<meta
|
||
name="description"
|
||
content="임상 수준의 6단계 위생 프로토콜과 100% 정찰제 견적. 독일 카처 4.0bar 고온스팀과 에코서트 인증 천연 세제. 실시간 견적 신청 및 관제 콘솔 지원."
|
||
/>
|
||
<meta property="og:title" content="청온 케어 (淸溫) · 프리미엄 위생 케어" />
|
||
<meta property="og:description" content="공간의 숨결을 되돌리는 6단계 프로토콜과 투명한 정찰제 견적." />
|
||
<meta property="og:type" content="website" />
|
||
<meta name="theme-color" content="#f8faf9" />
|
||
|
||
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
<link
|
||
rel="stylesheet"
|
||
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
|
||
/>
|
||
<link
|
||
rel="stylesheet"
|
||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap"
|
||
/>
|
||
<link rel="stylesheet" href="./styles/main.css?v=1" />
|
||
<link
|
||
rel="icon"
|
||
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%230D9488'/%3E%3Cpath d='M9 16.5l5 5 9-10' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E"
|
||
/>
|
||
</head>
|
||
|
||
<body data-view="client">
|
||
<a class="skip-link" href="#mainContent">본문으로 건너뛰기</a>
|
||
|
||
<!-- 최상단 헤더 (.site-head SSOT) -->
|
||
<header class="site-head">
|
||
<div class="wrap head-inner">
|
||
<a class="wordmark" href="#" id="brandLogo">
|
||
<span class="wordmark-badge">淸</span>
|
||
청온 케어 <span class="wordmark-han">淸溫</span>
|
||
</a>
|
||
|
||
<nav class="nav" aria-label="메인 메뉴">
|
||
<a href="#services">케어 솔루션</a>
|
||
<a href="#calculator">정찰제 견적</a>
|
||
<a href="./protocol/index.html" style="color: var(--accent); font-weight: 600;">6단계 프로토콜 (상세)</a>
|
||
<a href="#equipment">전문 장비</a>
|
||
</nav>
|
||
|
||
<div class="head-actions">
|
||
<div class="mode-toggle" role="group" aria-label="뷰 모드 전환">
|
||
<button type="button" class="mode-btn is-active" id="btnModeClient">
|
||
고객 소개 뷰
|
||
</button>
|
||
<button type="button" class="mode-btn" id="btnModeAdmin" title="단축키: Alt + A">
|
||
<span class="badge-dot" aria-hidden="true"></span>
|
||
관리자 콘솔
|
||
</button>
|
||
</div>
|
||
<a href="#calculator" class="btn client-only-btn">
|
||
간편 견적
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main id="mainContent">
|
||
<!-- ===================================================================
|
||
1. 고객 소개 및 간편 신청 뷰 (Client View)
|
||
=================================================================== -->
|
||
<div class="client-view">
|
||
<!-- 히어로 섹션 -->
|
||
<section class="hero-section" aria-labelledby="heroHeading">
|
||
<div class="wrap hero-grid">
|
||
<div class="hero-content">
|
||
<div class="eyebrow">
|
||
<span>임상 수준 위생 프로토콜</span>
|
||
</div>
|
||
<h1 id="heroHeading" class="hero-title">
|
||
보이지 않는 미세 오염까지,<br />
|
||
<em>공간의 숨결</em>을 되돌립니다
|
||
</h1>
|
||
<p class="hero-desc">
|
||
단순한 미화가 아닙니다. 독일 카처 4.0bar 고온 스팀과 에코서트(ECOCERT) 인증 친환경 세제로 새집증후군, 미세 분진, 알레르기 유발 물질을 근본적으로 제거합니다.
|
||
</p>
|
||
<div class="hero-ctas">
|
||
<a href="#calculator" class="btn-primary">
|
||
실시간 정찰제 견적 계산하기
|
||
<span class="btn-icon-circle" aria-hidden="true">↗</span>
|
||
</a>
|
||
<div class="hero-trust">
|
||
<span class="hero-trust-stars">★★★★★</span>
|
||
<span>누적 케어 4,820세대 · 만족도 99.4%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hero-visual">
|
||
<div class="bezel-outer">
|
||
<div class="hero-frame">
|
||
<img
|
||
src="./assets/clean-hero.webp"
|
||
alt="정밀 입주 케어가 완료된 미니멀한 프리미엄 주거 거실 전경"
|
||
width="1200"
|
||
height="900"
|
||
loading="eager"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div class="hero-stat-floating">
|
||
<span class="stat-val">32 Point</span>
|
||
<span class="stat-label">마스터 클리너<br />정밀 검수 체크리스트</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 실시간 정찰제 견적 계산기 -->
|
||
<section class="calc-section" id="calculator" aria-labelledby="calcHeading">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<h2 id="calcHeading" class="section-title">투명한 정찰제 실시간 견적 산정</h2>
|
||
<p class="section-sub">추가금 없는 명확한 기준. 공간 면적과 맞춤 옵션을 선택하시면 즉시 예상 금액이 산출됩니다.</p>
|
||
</div>
|
||
|
||
<div class="calc-grid">
|
||
<div class="calc-card">
|
||
<form id="quoteForm" onsubmit="return false;">
|
||
<!-- 공간 유형 -->
|
||
<div class="form-group">
|
||
<label class="form-label" id="spaceTypeLabel">공간 유형 선택</label>
|
||
<div class="type-selector" role="radiogroup" aria-labelledby="spaceTypeLabel">
|
||
<button type="button" class="type-btn is-active" data-type="apt" data-base="11000">
|
||
주거 입주/이사
|
||
</button>
|
||
<button type="button" class="type-btn" data-type="office" data-base="9500">
|
||
오피스 정기 케어
|
||
</button>
|
||
<button type="button" class="type-btn" data-type="premium" data-base="14500">
|
||
하이엔드 준공 청소
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 평수 슬라이더 -->
|
||
<div class="form-group">
|
||
<div class="slider-header">
|
||
<label class="form-label" for="pyeongSlider">공간 공급면적 (평형)</label>
|
||
<span class="slider-val" id="pyeongValue">32 평 (약 105㎡)</span>
|
||
</div>
|
||
<input
|
||
type="range"
|
||
id="pyeongSlider"
|
||
class="range-input"
|
||
min="12"
|
||
max="75"
|
||
value="32"
|
||
step="1"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 특수 케어 옵션 -->
|
||
<div class="form-group">
|
||
<span class="form-label">정밀 특수 옵션</span>
|
||
<div class="addon-grid">
|
||
<label class="addon-label">
|
||
<input type="checkbox" name="addon" value="steam" data-price="45000" checked />
|
||
<span>160℃ 고온 살균 스팀 (+45,000원)</span>
|
||
</label>
|
||
<label class="addon-label">
|
||
<input type="checkbox" name="addon" value="phytoncide" data-price="35000" checked />
|
||
<span>편백 피톤치드 훈증 (+35,000원)</span>
|
||
</label>
|
||
<label class="addon-label">
|
||
<input type="checkbox" name="addon" value="aircon" data-price="80000" />
|
||
<span>시스템 에어컨 분해 (+80,000원)</span>
|
||
</label>
|
||
<label class="addon-label">
|
||
<input type="checkbox" name="addon" value="glass" data-price="50000" />
|
||
<span>외부 유리창 특수 발수 (+50,000원)</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 예약 정보 입력 -->
|
||
<div class="form-group" style="margin-top: 1.5rem;">
|
||
<span class="form-label">신청자 정보</span>
|
||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 0.75rem;">
|
||
<input
|
||
type="text"
|
||
id="clientName"
|
||
placeholder="성함 / 고객명"
|
||
style="width: 100%; min-width: 0; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: var(--step--1);"
|
||
value="이서연"
|
||
required
|
||
/>
|
||
<input
|
||
type="tel"
|
||
id="clientPhone"
|
||
placeholder="연락처 (010-0000-0000)"
|
||
style="width: 100%; min-width: 0; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: var(--step--1);"
|
||
value="010-4821-9930"
|
||
required
|
||
/>
|
||
</div>
|
||
<input
|
||
type="text"
|
||
id="clientAddress"
|
||
placeholder="케어 현장 주소 (예: 서울시 마포구 공덕동 120)"
|
||
style="width: 100%; min-width: 0; margin-top: 0.5rem; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: var(--step--1);"
|
||
value="서울시 성동구 성수동2가 아크로포레스트 102동"
|
||
required
|
||
/>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- 요약 및 접수 CTA -->
|
||
<div class="calc-summary">
|
||
<h3 class="summary-title">실시간 견적 명세서</h3>
|
||
<div class="summary-row">
|
||
<span>선택 공간</span>
|
||
<span id="sumSpaceType" class="mono">주거 입주/이사</span>
|
||
</div>
|
||
<div class="summary-row">
|
||
<span>면적 기준</span>
|
||
<span id="sumPyeong" class="mono">32평 (평당 11,000원)</span>
|
||
</div>
|
||
<div class="summary-row">
|
||
<span>기본 케어비</span>
|
||
<span id="sumBasePrice" class="mono">352,000원</span>
|
||
</div>
|
||
<div class="summary-row">
|
||
<span>정밀 옵션 합계</span>
|
||
<span id="sumAddonPrice" class="mono">80,000원</span>
|
||
</div>
|
||
<div class="summary-total">
|
||
<span>총 예상 견적</span>
|
||
<span class="total-amount" id="sumTotal">432,000원</span>
|
||
</div>
|
||
|
||
<button type="button" class="calc-submit" id="btnSubmitQuote">
|
||
이 견적으로 신청 접수하기
|
||
</button>
|
||
<p style="font-size: 12px; color: var(--ink-inverse-muted); margin-top: 10px; text-align: center;">
|
||
✓ 접수 즉시 배차 팀장이 연락 후 사전 현장 조율을 진행합니다.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 6단계 위생 프로토콜 -->
|
||
<section class="protocol-section" id="protocol" aria-labelledby="protoHeading">
|
||
<div class="wrap">
|
||
<div class="section-head" style="display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: 12px;">
|
||
<div>
|
||
<h2 id="protoHeading" class="section-title">임상 수준의 6단계 청온 케어 프로토콜</h2>
|
||
<p class="section-sub">표면만 닦는 청소가 아닌, 미세 분진과 세균 번식의 원인을 제거하는 체계적인 과정입니다.</p>
|
||
</div>
|
||
<a href="./protocol/index.html" class="action-btn" style="text-decoration: none; padding: 10px 20px; font-size: 14px; background: var(--surface-card); color: var(--accent); border: 1px solid var(--accent);">
|
||
나인원한남 ATP 측정 리포트 보기 →
|
||
</a>
|
||
</div>
|
||
|
||
<div class="protocol-grid">
|
||
<div class="protocol-card">
|
||
<div class="protocol-num">STEP 01</div>
|
||
<h3>건식 초미세 집진</h3>
|
||
<p>H14 헤파 필터 흡진기로 벽면, 천장 몰딩, 바닥의 시공 미세분진 및 부유 입자를 99.97% 1차 포집합니다.</p>
|
||
</div>
|
||
|
||
<div class="protocol-card">
|
||
<div class="protocol-num">STEP 02</div>
|
||
<h3>160℃ 고온 스팀 살균</h3>
|
||
<p>배수구, 욕실 타일 틈새, 주방 후드 기름때를 화학 세제 없이 4.0bar 고온 증기로 녹여 살균합니다.</p>
|
||
</div>
|
||
|
||
<div class="protocol-card">
|
||
<div class="protocol-num">STEP 03</div>
|
||
<h3>약알칼리 친환경 분해</h3>
|
||
<p>에코서트(ECOCERT) 인증 천연 식물성 세정제를 도포하여 자재 손상 없이 찌든 때를 안전하게 중화합니다.</p>
|
||
</div>
|
||
|
||
<div class="protocol-card">
|
||
<div class="protocol-num">STEP 04</div>
|
||
<h3>서랍·후드 전면 탈거 세척</h3>
|
||
<p>보이지 않는 싱크대 걸레받이, 전등갓, 수납장 서랍 레일을 전면 탈거하여 내측 분진을 완벽 제거합니다.</p>
|
||
</div>
|
||
|
||
<div class="protocol-card">
|
||
<div class="protocol-num">STEP 05</div>
|
||
<h3>편백 피톤치드 연무 훈증</h3>
|
||
<p>순수 제주 편백 오일 연무로 벽지 속 새집증후군 원인 물질(포름알데히드, VOCs)을 중화하고 탈취합니다.</p>
|
||
</div>
|
||
|
||
<div class="protocol-card">
|
||
<div class="protocol-num">STEP 06</div>
|
||
<h3>32개 항목 마스터 검수</h3>
|
||
<p>현장 팀장과 고객이 함께 32개 체크리스트를 1:1 대조하고, 미흡 지점 발생 시 즉시 재케어 후 인도합니다.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 전문 장비 & Before/After -->
|
||
<section class="equipment-section" id="equipment" aria-labelledby="equipHeading">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<h2 id="equipHeading" class="section-title">전문 위생 장비 및 검수 스펙</h2>
|
||
<p class="section-sub">가정용 장비가 아닌 독일 카처 정품 산업용 위생 기기를 전 현장에 투입합니다.</p>
|
||
</div>
|
||
|
||
<div class="equip-grid">
|
||
<div class="equip-specs">
|
||
<div class="spec-item">
|
||
<span class="spec-key">고온 스팀 압력</span>
|
||
<span class="spec-val">Kärcher SG 4/4 (4.0 bar · 160℃)</span>
|
||
</div>
|
||
<div class="spec-item">
|
||
<span class="spec-key">미세먼지 집진 등급</span>
|
||
<span class="spec-val">HEPA H14 (0.3㎛ 99.995% 포집)</span>
|
||
</div>
|
||
<div class="spec-item">
|
||
<span class="spec-key">사용 세제 인증</span>
|
||
<span class="spec-val">ECOCERT 100% 생분해 식물성</span>
|
||
</div>
|
||
<div class="spec-item">
|
||
<span class="spec-key">포름알데히드 저감</span>
|
||
<span class="spec-val">한국화학융합시험연구원 인증 94.2%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ba-container">
|
||
<img
|
||
src="./assets/steam-qc.webp"
|
||
alt="청온 케어 마스터 위생 장비와 정밀 세척 노즐"
|
||
width="800"
|
||
height="600"
|
||
loading="lazy"
|
||
/>
|
||
<span class="ba-badge before">정밀 장비 규격</span>
|
||
<span class="ba-badge after">QC 완결 보증</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- ===================================================================
|
||
2. 관리자 관제 콘솔 모드 (Admin Dashboard Mockup)
|
||
=================================================================== -->
|
||
<section class="admin-view wrap" aria-label="청온 케어 관리자 콘솔">
|
||
<div class="admin-header">
|
||
<div>
|
||
<div class="eyebrow" style="margin-bottom: 4px;">배차 관제 콘솔</div>
|
||
<h2 style="font-size: var(--step-2); font-weight: 800;">실시간 배차 및 현장 관제 현황</h2>
|
||
</div>
|
||
<button type="button" class="btn-primary" id="btnOpenQcModal">
|
||
32개 현장 검수표 열기
|
||
</button>
|
||
</div>
|
||
|
||
<!-- KPI 통계 카드 -->
|
||
<div class="admin-kpis">
|
||
<div class="kpi-card">
|
||
<div class="kpi-label">오늘 신규 접수</div>
|
||
<div class="kpi-val accent" id="kpiNewCount">6건</div>
|
||
</div>
|
||
<div class="kpi-card">
|
||
<div class="kpi-label">현재 현장 진행 중</div>
|
||
<div class="kpi-val">4개 조</div>
|
||
</div>
|
||
<div class="kpi-card">
|
||
<div class="kpi-label">검수 대기 / 완료</div>
|
||
<div class="kpi-val">2건</div>
|
||
</div>
|
||
<div class="kpi-card">
|
||
<div class="kpi-label">오늘 견적 총액</div>
|
||
<div class="kpi-val mono" id="kpiTotalRevenue">2,480,000원</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 실시간 접수 및 배차 원장 테이블 -->
|
||
<div class="admin-table-card">
|
||
<div class="table-header">
|
||
<span class="table-title">실시간 예약 및 케어 원장 (Live Ledger)</span>
|
||
<div class="table-filter-tabs">
|
||
<button class="filter-tab is-active" data-filter="all">전체</button>
|
||
<button class="filter-tab" data-filter="new">신규접수</button>
|
||
<button class="filter-tab" data-filter="progress">진행중</button>
|
||
<button class="filter-tab" data-filter="done">완료</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table class="admin-table">
|
||
<thead>
|
||
<tr>
|
||
<th>접수번호</th>
|
||
<th>고객명 / 연락처</th>
|
||
<th>공간 / 면적</th>
|
||
<th>현장 주소</th>
|
||
<th>견적액</th>
|
||
<th>배정 팀장</th>
|
||
<th>상태</th>
|
||
<th>조치</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="adminTableBody">
|
||
<tr>
|
||
<td class="mono">#CO-2026-0819</td>
|
||
<td><strong>이서연</strong><br /><span style="color:var(--ink-muted);font-size:11px;">010-4821-9930</span></td>
|
||
<td>주거 입주 (32평)</td>
|
||
<td>성동구 성수동 아크로포레스트</td>
|
||
<td class="mono" style="font-weight:700;">432,000원</td>
|
||
<td>김정온 마스터</td>
|
||
<td><span class="status-pill new">신규 접수</span></td>
|
||
<td><button class="action-btn" onclick="alert('배차 확인 알림톡이 고객님께 전송되었습니다.');">배차 확정</button></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="mono">#CO-2026-0818</td>
|
||
<td><strong>박도현</strong><br /><span style="color:var(--ink-muted);font-size:11px;">010-9120-3341</span></td>
|
||
<td>오피스 정기 (45평)</td>
|
||
<td>강남구 테헤란로 142 위워크</td>
|
||
<td class="mono" style="font-weight:700;">520,000원</td>
|
||
<td>박준호 팀장 (2팀)</td>
|
||
<td><span class="status-pill progress">스팀 케어 중</span></td>
|
||
<td><button class="action-btn" onclick="document.getElementById('qcModal').showModal();">실시간 검수</button></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="mono">#CO-2026-0817</td>
|
||
<td><strong>한지민</strong><br /><span style="color:var(--ink-muted);font-size:11px;">010-7712-4091</span></td>
|
||
<td>하이엔드 준공 (58평)</td>
|
||
<td>용산구 한남동 나인원한남</td>
|
||
<td class="mono" style="font-weight:700;">841,000원</td>
|
||
<td>최수진 닥터 (1팀)</td>
|
||
<td><span class="status-pill done">검수 승인 완료</span></td>
|
||
<td><button class="action-btn" onclick="alert('완료 검수 리포트가 PDF로 발행되었습니다.');">리포트 다운</button></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 32개 항목 QC 검수 모달 다이얼로그 -->
|
||
<dialog id="qcModal" class="qc-dialog" aria-labelledby="qcTitle">
|
||
<div class="qc-head">
|
||
<h3 id="qcTitle" style="font-size: var(--step-1); font-weight: 700;">32개 정밀 위생 검수 체크리스트</h3>
|
||
<button type="button" onclick="document.getElementById('qcModal').close();" aria-label="닫기" style="font-size: 18px; font-weight: 700;">✕</button>
|
||
</div>
|
||
<ul class="qc-list">
|
||
<li class="qc-item"><input type="checkbox" checked /> <span>01. 천장 몰딩 및 전등갓 상단 분진 흡진</span></li>
|
||
<li class="qc-item"><input type="checkbox" checked /> <span>02. 창틀 상하좌우 틈새 시멘트 가루 및 찌든때 제거</span></li>
|
||
<li class="qc-item"><input type="checkbox" checked /> <span>03. 싱크대 하부 걸레받이 전면 탈거 및 분진 집진</span></li>
|
||
<li class="qc-item"><input type="checkbox" checked /> <span>04. 가스레인지/인덕션 상판 및 후드 필터 기름때 고온 스팀 분해</span></li>
|
||
<li class="qc-item"><input type="checkbox" checked /> <span>05. 욕실 벽타일 메지 및 배수구 트랩 고온 살균 세척</span></li>
|
||
<li class="qc-item"><input type="checkbox" checked /> <span>06. 수납장 모든 서랍 완전 탈거 후 레일 틈새 분진 청소</span></li>
|
||
<li class="qc-item"><input type="checkbox" checked /> <span>07. 베란다 및 다용도실 바닥 타일 약알칼리 세정</span></li>
|
||
<li class="qc-item"><input type="checkbox" /> <span>08. 전 실 편백 피톤치드 훈증 및 공기질 측정기 수치 확인</span></li>
|
||
</ul>
|
||
<div style="display: flex; justify-content: flex-end; gap: 8px;">
|
||
<button type="button" class="action-btn" onclick="document.getElementById('qcModal').close();">닫기</button>
|
||
<button type="button" class="btn-primary" style="padding: 6px 14px; font-size: 13px;" onclick="alert('검수 승인이 완료되었습니다.'); document.getElementById('qcModal').close();">최종 검수 서명 승인</button>
|
||
</div>
|
||
</dialog>
|
||
|
||
<!-- 푸터 (.site-foot SSOT) -->
|
||
<footer class="site-foot">
|
||
<div class="wrap foot-inner">
|
||
<p>청온 케어 · 서울 마포구 마포대로 109 청온랩 4층</p>
|
||
<p class="muted">연중무휴 08:00 – 20:00 (사전 예약제)</p>
|
||
<p class="muted">care@cheongon.kr</p>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- 인터랙티브 스크립트 -->
|
||
<script>
|
||
(function () {
|
||
// 1. 뷰 모드 전환 (고객 뷰 vs 관리자 뷰)
|
||
const btnClient = document.getElementById("btnModeClient");
|
||
const btnAdmin = document.getElementById("btnModeAdmin");
|
||
|
||
function setViewMode(mode) {
|
||
document.body.setAttribute("data-view", mode);
|
||
if (mode === "admin") {
|
||
btnAdmin.classList.add("is-active");
|
||
btnClient.classList.remove("is-active");
|
||
} else {
|
||
btnClient.classList.add("is-active");
|
||
btnAdmin.classList.remove("is-active");
|
||
}
|
||
}
|
||
|
||
btnClient.addEventListener("click", () => setViewMode("client"));
|
||
btnAdmin.addEventListener("click", () => setViewMode("admin"));
|
||
|
||
// 단축키 Alt + A 로 관리자 모드 토글
|
||
window.addEventListener("keydown", (e) => {
|
||
if (e.altKey && (e.key === "a" || e.key === "A" || e.key === "ㅁ")) {
|
||
const cur = document.body.getAttribute("data-view");
|
||
setViewMode(cur === "admin" ? "client" : "admin");
|
||
}
|
||
});
|
||
|
||
// 2. 견적 계산기 로직
|
||
const pyeongSlider = document.getElementById("pyeongSlider");
|
||
const pyeongValue = document.getElementById("pyeongValue");
|
||
const sumPyeong = document.getElementById("sumPyeong");
|
||
const sumBasePrice = document.getElementById("sumBasePrice");
|
||
const sumAddonPrice = document.getElementById("sumAddonPrice");
|
||
const sumTotal = document.getElementById("sumTotal");
|
||
const sumSpaceType = document.getElementById("sumSpaceType");
|
||
const typeBtns = document.querySelectorAll(".type-btn");
|
||
const addonCheckboxes = document.querySelectorAll("input[name='addon']");
|
||
|
||
let currentBaseRate = 11000;
|
||
let currentTypeLabel = "주거 입주/이사";
|
||
|
||
function updateQuote() {
|
||
const pyeong = parseInt(pyeongSlider.value, 10);
|
||
const sqm = Math.round(pyeong * 3.30578);
|
||
pyeongValue.textContent = `${pyeong} 평 (약 ${sqm}㎡)`;
|
||
sumPyeong.textContent = `${pyeong}평 (평당 ${currentBaseRate.toLocaleString()}원)`;
|
||
sumSpaceType.textContent = currentTypeLabel;
|
||
|
||
const baseCost = pyeong * currentBaseRate;
|
||
sumBasePrice.textContent = `${baseCost.toLocaleString()}원`;
|
||
|
||
let addonCost = 0;
|
||
addonCheckboxes.forEach((cb) => {
|
||
if (cb.checked) {
|
||
addonCost += parseInt(cb.getAttribute("data-price"), 10);
|
||
}
|
||
});
|
||
sumAddonPrice.textContent = `${addonCost.toLocaleString()}원`;
|
||
|
||
const total = baseCost + addonCost;
|
||
sumTotal.textContent = `${total.toLocaleString()}원`;
|
||
}
|
||
|
||
pyeongSlider.addEventListener("input", updateQuote);
|
||
|
||
typeBtns.forEach((btn) => {
|
||
btn.addEventListener("click", () => {
|
||
typeBtns.forEach((b) => b.classList.remove("is-active"));
|
||
btn.classList.add("is-active");
|
||
currentBaseRate = parseInt(btn.getAttribute("data-base"), 10);
|
||
currentTypeLabel = btn.textContent.trim();
|
||
updateQuote();
|
||
});
|
||
});
|
||
|
||
addonCheckboxes.forEach((cb) => {
|
||
cb.addEventListener("change", updateQuote);
|
||
});
|
||
|
||
// 초기 계산 1회 실행
|
||
updateQuote();
|
||
|
||
// 3. 견적 신청 버튼 클릭 -> 관리자 원장에 즉시 추가되는 풀-루프 인터랙션!
|
||
const btnSubmit = document.getElementById("btnSubmitQuote");
|
||
const tableBody = document.getElementById("adminTableBody");
|
||
const kpiNewCount = document.getElementById("kpiNewCount");
|
||
let submissionCount = 6;
|
||
|
||
btnSubmit.addEventListener("click", () => {
|
||
const name = document.getElementById("clientName").value || "고객님";
|
||
const phone = document.getElementById("clientPhone").value || "010-0000-0000";
|
||
const address = document.getElementById("clientAddress").value || "서울시 현장 주소";
|
||
const pyeong = pyeongSlider.value;
|
||
const totalStr = sumTotal.textContent;
|
||
|
||
submissionCount++;
|
||
kpiNewCount.textContent = `${submissionCount}건`;
|
||
|
||
// 새 행을 관리자 테이블 최상단에 삽입
|
||
const newRow = document.createElement("tr");
|
||
newRow.style.backgroundColor = "var(--accent-light)";
|
||
newRow.innerHTML = `
|
||
<td class="mono">#CO-2026-082${submissionCount}</td>
|
||
<td><strong>${name}</strong><br /><span style="color:var(--ink-muted);font-size:11px;">${phone}</span></td>
|
||
<td>${currentTypeLabel} (${pyeong}평)</td>
|
||
<td>${address}</td>
|
||
<td class="mono" style="font-weight:700;color:var(--accent);">${totalStr}</td>
|
||
<td>배차 지정 대기</td>
|
||
<td><span class="status-pill new">방금 접수됨</span></td>
|
||
<td><button class="action-btn" onclick="alert('배차 팀장을 매칭 중입니다.');">배차 지정</button></td>
|
||
`;
|
||
tableBody.insertBefore(newRow, tableBody.firstChild);
|
||
|
||
alert(`[청온 케어] ${name}님의 견적(${totalStr}) 신청이 성공적으로 접수되었습니다.\n관리자 콘솔에 실시간 등록되었습니다.`);
|
||
});
|
||
|
||
// 모달 열기
|
||
const btnOpenQc = document.getElementById("btnOpenQcModal");
|
||
const qcModal = document.getElementById("qcModal");
|
||
if (btnOpenQc && qcModal) {
|
||
btnOpenQc.addEventListener("click", () => qcModal.showModal());
|
||
}
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|