feat(site): rework 19 marketing showcases for composition diversity
Some checks are pending
ci / build (push) Waiting to run

Measured convergence before: split hero 13/19, top-bar nav 19/19,
one-line notice footer 14/19, body Pretendard 17/21, 10 similarity
pairs above 0.78. Each showcase got a pre-assigned hero family, nav
form, footer form, type pair, background, accent hue, radius, motion
grammar and material from outputs/rework-2026-10-06/plan.md; direction
cards and the chosen reason are recorded in every design.md.

After: 0 similarity warnings, 19 distinct display faces, 7 hero
families, 5 nav forms, 5 footer forms, no scroll reveals, 5 showcases
with SVG filter materials. Example contact values replace bracket
placeholders under the existing fictional-brand notices. Thumbnails,
OG images, card copy and three e2e assertions updated; dead CSS in
dure-enrollment and hannam-jari removed; similarity.mjs learns the new
font families.
This commit is contained in:
Yun Chan 2026-10-06 16:55:50 +09:00
parent 88c11682b1
commit 8e3cdb0d3b
296 changed files with 19131 additions and 17538 deletions

File diff suppressed because one or more lines are too long

View file

@ -1,13 +0,0 @@
# MaruBuri source record
Downloaded 2026-09-12 from the official NAVER Hangeul static host. The files are retained unchanged: no conversion or subsetting was performed.
| File | Official URL | HTTP content type | Size | SHA-256 |
| --- | --- | --- | --- | --- |
| `MaruBuri-Regular.woff2` | https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-Regular.woff2 | `font/woff2` | 433776 bytes | `4CF1341CF2F23FB3E263712DFDE1D8F25EEDCC328B696A2E5A2C8ADD55E5C17B` |
| `MaruBuri-SemiBold.woff2` | https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-SemiBold.woff2 | `font/woff2` | 466108 bytes | `7AEF4862FA3219B0A7DEB6746E27116A38C4069F4424EB51EDF103B29795F5C2` |
- Official stylesheet checked: https://hangeul.pstatic.net/hangeul_static/css/maru-buri.css
- Official NAVER license page saved verbatim as `LICENSE.html`: https://help.naver.com/service/11029/contents/18088?lang=ko&osType=PC
- `LICENSE.html` SHA-256: `8538F7921744D5E040F603BC301465EFBD038F1054D0754B7508DE3286452EC3`
- The saved official page includes the NAVER copyright notice and the SIL Open Font License 1.1 text for MaruBuri.

View file

@ -1,17 +1,78 @@
# 청온 케어 — 디자인 결정 기록
# design.md — 청온 케어
## 관찰과 방향
## 진행 상태
- 관찰: 기존 첫 화면은 카드 안의 사진과 떠 있는 수치 배지가 서비스 범위보다 먼저 읽혔다.
- 원리 적용 범위: 소개와 견적 행동은 왼쪽 읽기 폭에, 생활 공간 사진과 32개 검수 항목 예시는 오른쪽 한 장면에 둔다. 견적은 입력 작업표와 합계 명세를 분리한다.
- 결정: 이중 프레임·떠 있는 배지를 제거하고 사진 캡션으로 검수 항목의 맥락을 연결했다. 성능 수치·인증·의학적 표현은 근거가 없으므로 작업표에 기록할 확인 절차로 바꿨다.
- 기각 조건: 사진이 견적 행동을 밀거나 작은 폭에서 입력과 합계가 동시에 읽히지 않으면 1열 순서와 간격을 다시 조정한다.
- 2026-10-06 재작업(전체·리디자인 경로, 방향 선택은 사용자 위임). 0 현행 감사 → 1 레퍼런스 → 2 카드 3장 중 A → 3 토큰 → 4 구현(index + protocol 공통 셸) → 5 감사 통과 → 6 이 문서. 완료.
## 토큰과 검증
## 브리프
- 타입: `MaruBuri` 로컬 400·600은 제목 역할, Pretendard는 본문·입력 역할이다. 본문은 `--step-0`, 보조 기록은 `--step--1`을 유지한다.
- 색: 기존 청록 `--accent`, 밝은 표면과 선 토큰을 유지한다. 청록은 상태·행동과 검수 표시에만 쓴다.
- 구도: 넓은 화면은 5:7 소개/사진, 견적은 입력/합계 두 열이며 860px 이하에서는 한 열이다.
- `verify-final` 18개 묶음은 16개가 즉시 통과했다. 전체 묶음의 invariant·visual 검사는 Gaon·Dure를 대상으로 하며, 나머지 2개는 수정 뒤 release 독립 재실행에서 ALL PASS·ALL MATCH였다.
- root는 28개 모바일, 21개 데스크톱, 7개 하위 경로와 30개 앱 상태를 직접 검토해 수용했다. stress 112건은 hard failure 0이며, 가로 넘침 4건은 targeted fix 뒤 390px 재측정에서 0이다.
- 이 기록은 렌더·계약 범위의 현재 결과다. 모든 폭·키보드 경로·인쇄 등 개별 기능을 완전 재실행했다는 뜻이 아니며, 참여자 과업 효과도 미측정이다.
- 무엇을: 가상 입주·이사·사무실 청소 브랜드의 견적 페이지 한 장 + 작업 절차 2차 페이지. 정적 HTML/CSS + 인라인 JS, 쇼케이스 사이트(`apps/site/public/work/cheongon-care/`) 안.
- 누구에게: 입주·이사를 앞둔 사람이 평형과 옵션을 골라 예상 금액을 보고 견적을 요청한다. 보조로 운영 화면 예시(접수·배차)를 같은 페이지에서 전환해 본다.
- 제약: 기본 언어 ko-KR(기존 로컬라이제이션). 상호·단가·옵션 가격·32개 항목·6단계 문구는 기존 파일 값 유지. 새 이미지 금지. 서체는 OFL·공개 배포본. plan.md 배정값(아래 지문 블록)이 제약이다.
- 화면 목록: `index.html`(견적 계산기 → 절차 → 장비 → 요청 푸터, 운영 화면 예시 모드) · `protocol/index.html`(절차 상세, 같은 셸).
## 미확정
- 대표 전화번호 02-000-4172 — 푸터 연락처 줄, 전화 다이얼로그. 예시 값이다(사용자 결정 2026-10-06, 다이얼로그와 푸터 고지에 명시).
- 응답 시간·서비스 지역 — 기존 파일에 없어 사실 목록에 넣지 않았다. 값이 오면 `.facts`에 행 하나 추가.
- og:image — 전용 1200×630 이미지가 없어 기존 사진의 절대 URL을 가리킨다.
- 방향 카드 선택(A)은 위임으로 정했다.
## 레퍼런스
- R1 구조: Homeaglow https://www.homeaglow.com/ — 중간 크기 표제 아래 입력 한 칸, 옆에 가격 사실 3줄($19·$59/월·7일 예약). 가져온 원리: 표제 작게, 사실 목록, 입력이 첫 화면.
- R1′ 같은 시장: 청연 https://www.chyeon.com/, 미소 https://miso.kr/ — 앱 다운로드 히어로·상단 바·가격 없음. 가져온 원리: 가격을 첫 화면에 두는 것이 이 시장에서 차별점이다.
- R2 톤: 기존 design.md의 "입력 작업표와 합계 명세 분리" 결정 재사용.
- R3 디테일: designpaca `mobile-app-ux.md` safe area 절(`viewport-fit=cover` + `env()` + `max()`).
- 미검증: 숨고 검색 페이지(404), 당근 비즈프로필 하단 바(페처 불가).
## 방향
지문: 히어로 데이터·도구(견적 패널이 첫 화면, 표제 작게, 사실 목록 4줄, 행동은 패널 안 링크) · 표제/본문 Wanted Sans / Wanted Sans · 바탕 밝음·쿨 #eef3f6 · 강조 187° #156a75 · radius 8px · 흐름 견적 계산기 → 6단계 번호 목록 → 장비 누끼 + 기록 4항목 → 견적 요청(푸터) · 내비 없음 + 모바일 하단 고정 바(전화·견적) · 푸터 = 견적 요청 폼 + 상호·전화 placeholder·고지 한 줄 · 이미지 multiply + 방사형 마스크 누끼 · 모션 없음(폼 상태 색·테두리 전환 160ms만)
- 한 문장 컨셉: 입주를 앞둔 사람이 공간 유형·평형·옵션을 고르고 합계를 본 뒤 연락처를 남긴다.
- 프리셋: swiss-minimal 지배(흰 작업 패널, 선으로 나눈 사실 목록) + 보조 없음. 강조색은 행동·합계·활성 상태에만.
- 표현 리스크: 합계 숫자(44px)가 페이지에서 가장 큰 글자이고 표제(28px)보다 크다 — 도구가 주인이라는 구도를 글자 크기로 말한다. 검증: 회색조 캡처 첫 시선이 합계였다.
- 표면 다이얼: 고객 화면 표현성 1·밀도 2 / 운영 화면 예시 표현성 0·밀도 3·증거 노출(예시 고지) 3.
- 제시 카드: A 계산기가 첫 화면(채택) · B 영수증 한 장(기각 — 1440 폭 낭비, 390에서 합계가 멀다) · C 단가표가 먼저(기각 — 390 표 변환, 행동까지 읽을 것이 많다). A를 고른 이유: 배정 제약과 R1 구성이 같고, 기존 E2E가 슬라이더·유형·합계가 한 화면에서 바뀌는 것을 단언한다.
- 반사실: 고유 요소 — 단가 3종 버튼(11,000/9,500/14,500), 32개 항목 검수 사실, 옵션 4종 가격. 같은 업종 치환에서 값이 바뀌어야 하고, 세무사무소 치환에서 평형 슬라이더가 무의미 → 통과. 수렴: plan 분포에서 같은 내비 형태인 thursday-flowers와 흐름·푸터·이미지·모션이 다르다(B-2 2/6 같음).
- 보존 자산: 상호, 단가·옵션 가격, 32개 항목·6단계 문구, 운영 표 예시 행, `assets/*.webp` 3장, `#calculator`·`#pyeongSlider`·`#sumTotal`·`.type-btn[data-base]`·`#btnModeAdmin/#btnModeClient`·`#qcModal`·`.card a[href='../index.html#calculator']`(E2E 계약).
## 토큰과 예산
- 값은 `styles/tokens.css`. 역할: `--surface`(바탕) / `--surface-raised`(패널·입력) / `--surface-card`(합계 면·표 헤더) / `--accent`(행동·활성·절차 번호) / `--accent-hover`(합계 숫자·호버) / `--ink-faint`(가격·눈금, 흰 위 5.36:1) / 상태 알약 3종은 브랜드 강조와 분리.
- 타입: step--1 13 / 0 16 / 1 19 / 2 22~28(h1·섹션 제목) / 3 32~44(합계 한 곳). measure 36em. 서체 하나(Wanted Sans Variable, jsdelivr split 서브셋, swap). 모노 없음 — 숫자는 `tabular-nums`.
- 간격 토큰 1~8, 컨테이너 78rem, 컨트롤 44px, 하단 바 높이 4.25rem + safe area.
- 예산: tokens §5 기본선. 실측 — 인라인 JS 약 5KB, 첫 화면 이미지 0장, 아래 사진 2장 lazy(84KB·72KB). 폰트 전송량은 split 서브셋이라 쓰인 글자 범위만 — 미측정.
## 이펙트와 폴백
- 누끼 대체: `.gear-cutout img { mix-blend-mode: multiply; mask-image: radial-gradient(ellipse …) }`. 마스크 미지원이면 직사각 사진 그대로 보인다(완성된 상태).
- 폼 상태 전환 160ms 색·테두리. 감소 모션에서 1ms.
- 그 밖의 모션·재질 없음.
## 하지 않기로 한 것
- 상단 바 내비·sticky·backdrop-filter — 한 장짜리에 행동 하나라 차례가 필요 없다.
- 히어로 사진 — 도구가 주인인 구도가 포기한 것. `clean-hero.webp`는 남기되 쓰지 않는다.
- eyebrow·영문 라벨·가운뎃점 메타 문자열 — 라벨은 `dt` 한 낱말.
- JetBrains Mono·MaruBuri — 한글 라벨에 라틴 모노를 쓰지 않고, 쓰지 않는 표제 서체를 싣지 않는다(`assets/fonts/` 삭제).
- 지어낸 전화번호·응답 시간·지역 — placeholder 또는 생략.
- 스크롤 리빌·등장 모션 — 배정표에 없다.
## 검증
- 자동: html-validate 0 오류(2페이지) · stylelint 0 · no-hanja PASS · integrity cheongon-care 5/5 · design-gate 충족 28/미검증 0/실패 0(폭 320·390·768·1440·1920, axe AA 0건) · showcase-audit PASS 12/0 · archive E2E cheongon 블록 24/24.
- 수동: 키보드 순회 1440·390 전부 도달·포커스 링 보임 · 전화 다이얼로그 Esc 닫힘·포커스 복귀 · 감소 모션 1ms · 대비 실측(흰/강조 6.27, 합계/회색 면 7.14, 희미/흰 5.36, 알약 6.56~7.42; 어두운 면 위 텍스트 없음) · h1·h2 마지막 줄 어절 ≥2.
- 시각 루브릭(약한 축부터): R5 1 · R6 1 · R9 1 · R1 2 · R2 2 · R3 2 · R4 2 · R7 2 · R8 2 · R10 2 = 17/20. 대표 화면 index, 2차는 캡처만 열어 봄. 근거는 `outputs/rework-2026-10-06/cheongon-care.md`.
- 미검증: 하단 바 국내 실측 사례, 실기기 safe area, 200% 확대 캡처, WebKit, 폰트 전송량.
## 피드백 기록 · 보존 목록
- 2026-10-02 카피 교정에서 정한 업종 어휘(입주청소, 평당 단가, 줄눈, 추가 옵션, 팀장)와 합니다체는 유지했다.
## 변경 기록
- 2026-08 초기: ledger-console 프리셋, 5:7 소개/사진 히어로, 입력 작업표/합계 명세 분리, verify-final 18묶음 통과.
- 2026-10-02 카피 교정: "공간의 숨결"·"케어 솔루션"·영문 직함 제거, 합니다체 통일.
- 2026-10-06 재작업: 히어로를 견적 패널로, 내비 제거 + 하단 행동 바, 푸터를 요청 폼으로, 서체 Wanted Sans 하나, radius 8 한 값, eyebrow 0, 가운뎃점 메타 0, 2차 페이지 공통 셸·인라인 style 제거, 운영 표 행 추가를 DOM 생성으로 변경.

View file

@ -3,372 +3,248 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>청온 케어 · 프리미엄 주거·오피스 위생 케어 안내</title>
<title>청온 케어 입주청소 견적</title>
<meta
name="description"
content="위생 케어 절차, 예상 견적, 운영 정보의 표시 방식을 소개합니다. 가격과 접수 정보는 예시이며 실제 신청은 진행되지 않습니다."
content="공간 유형과 평형, 추가 옵션을 고르면 항목별 단가와 합계가 바로 나옵니다. 청소가 끝나면 32개 검수 항목을 현장 팀장과 함께 확인하고 서명하는 가상 입주청소 서비스입니다."
/>
<meta property="og:title" content="청온 케어 · 프리미엄 위생 케어" />
<meta property="og:description" content="공간의 숨결을 되돌리는 6단계 프로토콜과 투명한 정찰제 견적." />
<meta property="og:title" content="청온 케어 입주청소 견적" />
<meta property="og:description" content="평당 단가로 바로 계산하는 견적, 6단계 작업 절차, 32개 항목 마감 검수." />
<meta property="og:type" content="website" />
<meta name="theme-color" content="#f8faf9" />
<meta property="og:image" content="https://designpaca.chanpaca.net/work/cheongon-care/assets/steam-qc.webp" />
<meta property="og:image:alt" content="청온 케어 현장에서 쓰는 스팀 청소기와 세척 노즐, 극세사 천, 세제 샘플" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="theme-color" content="#eef3f6" />
<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"
href="https://cdn.jsdelivr.net/gh/wanteddev/wanted-sans@v1.0.3/packages/wanted-sans/fonts/webfonts/variable/split/WantedSansVariable.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/fonts.css?v=20260912all" />
<link rel="stylesheet" href="./styles/main.css?v=20260912all" />
<link rel="stylesheet" href="./styles/tokens.css?v=20261006" />
<link rel="stylesheet" href="./styles/main.css?v=20261006" />
<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"
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='%23156a75'/%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>
청온 케어
</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>
<a class="wordmark" href="./index.html" id="brandLogo">청온 케어</a>
<a class="head-action" href="#request">견적 요청</a>
</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">
공간 유형과 선택 항목을 바탕으로 케어 범위와 예상 금액을 살펴볼 수 있습니다.
</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>선택 항목별 예상 금액을 확인하세요</span>
<!-- 첫 화면: 견적 계산기가 주인. 표제는 작게, 리드는 사실 목록 -->
<section class="quote" id="calculator" aria-labelledby="heroHeading">
<div class="wrap quote-grid">
<div class="quote-intro">
<h1 id="heroHeading" class="quote-title">입주·이사 청소 견적, 평형과 옵션을 고르면 바로 나옵니다</h1>
<dl class="facts">
<div class="fact">
<dt>기본 단가</dt>
<dd>평당 9,500원부터</dd>
</div>
</div>
<p class="demo-notice" role="note">안내: 이 페이지의 서비스·가격·운영 현황은 예시입니다. 입력 정보는 저장·전송되지 않으며 실제 견적이나 신청으로 이어지지 않습니다.</p>
<div class="fact">
<dt>범위</dt>
<dd>주거 입주와 이사, 사무실 정기, 준공 청소</dd>
</div>
<div class="fact">
<dt>검수</dt>
<dd>32개 항목을 현장 팀장과 함께 확인하고 서명</dd>
</div>
<div class="fact">
<dt>추가 옵션</dt>
<dd>스팀, 피톤치드, 에어컨 분해, 유리창 발수 4종</dd>
</div>
</dl>
</div>
<div class="hero-visual">
<figure class="hero-frame">
<img
src="./assets/clean-hero.webp"
alt="정돈된 주거 공간의 거실 전경"
width="1200"
height="900"
loading="eager"
/>
<figcaption>주거 공간 케어 예시 · 현장에서는 32개 검수 항목을 확인하는 흐름을 표시합니다.</figcaption>
</figure>
</div>
</div>
</section>
<!-- 실시간 정찰제 견적 계산기 -->
<section class="calc-section" id="calculator" aria-labelledby="calcHeading">
<div class="wrap">
<div class="section-head">
<p class="eyebrow">견적 작업표</p>
<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 class="quote-tool">
<form id="quoteForm" class="quote-form" onsubmit="return false;">
<fieldset class="form-group">
<legend class="form-label">공간 유형</legend>
<div class="type-selector" role="radiogroup" aria-label="공간 유형">
<button type="button" class="type-btn is-active" data-type="apt" data-base="11000" aria-pressed="true">
주거 입주/이사
</button>
<button type="button" class="type-btn" data-type="office" data-base="9500" aria-pressed="false">
사무실 정기 청소
</button>
<button type="button" class="type-btn" data-type="premium" data-base="14500" aria-pressed="false">
준공 청소
</button>
</div>
</fieldset>
<!-- 평수 슬라이더 -->
<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"
name="spaceSize"
class="range-input"
min="12"
max="75"
value="32"
step="1"
/>
<div class="form-group">
<div class="slider-header">
<label class="form-label" for="pyeongSlider">공급면적</label>
<output class="slider-val" id="pyeongValue" for="pyeongSlider">32평 (약 105㎡)</output>
</div>
<input
type="range"
id="pyeongSlider"
name="spaceSize"
class="range-input"
min="12"
max="75"
value="32"
step="1"
/>
<div class="slider-scale" aria-hidden="true"><span>12평</span><span>75평</span></div>
</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>고온 스팀 작업 기록 (+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>
<fieldset class="form-group">
<legend class="form-label">추가 옵션</legend>
<div class="addon-grid">
<label class="addon-label">
<input type="checkbox" name="addon" value="steam" data-price="45000" checked />
<span class="addon-name">고온 스팀 청소</span>
<span class="addon-price">+45,000원</span>
</label>
<label class="addon-label">
<input type="checkbox" name="addon" value="phytoncide" data-price="35000" checked />
<span class="addon-name">피톤치드 마감</span>
<span class="addon-price">+35,000원</span>
</label>
<label class="addon-label">
<input type="checkbox" name="addon" value="aircon" data-price="80000" />
<span class="addon-name">시스템 에어컨 분해</span>
<span class="addon-price">+80,000원</span>
</label>
<label class="addon-label">
<input type="checkbox" name="addon" value="glass" data-price="50000" />
<span class="addon-name">외부 유리창 발수 코팅</span>
<span class="addon-price">+50,000원</span>
</label>
</div>
</fieldset>
</form>
<!-- 예약 정보 입력 -->
<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;">
<label class="sr-only" for="clientName">신청자 성함</label>
<input
type="text"
id="clientName"
name="clientName"
autocomplete="name"
placeholder="성함 / 고객명"
style="width: 100%; min-width: 0; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: var(--step--1);"
required
/>
<label class="sr-only" for="clientPhone">신청자 연락처</label>
<input
type="tel"
id="clientPhone"
name="clientPhone"
autocomplete="tel"
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);"
required
/>
</div>
<label class="sr-only" for="clientAddress">케어 현장 주소</label>
<input
type="text"
id="clientAddress"
name="clientAddress"
autocomplete="off"
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);"
required
/>
<div class="quote-summary" aria-live="polite" aria-atomic="true">
<h2 class="summary-title">예상 견적</h2>
<dl class="summary-list">
<div class="summary-row">
<dt>공간</dt>
<dd id="sumSpaceType">주거 입주/이사</dd>
</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-row">
<dt>면적</dt>
<dd id="sumPyeong">32평 (평당 11,000원)</dd>
</div>
<div class="summary-row">
<dt>기본 청소비</dt>
<dd id="sumBasePrice">352,000원</dd>
</div>
<div class="summary-row">
<dt>추가 옵션</dt>
<dd id="sumAddonPrice">80,000원</dd>
</div>
</dl>
<div class="summary-total">
<span>총 예상 견적</span>
<span class="total-amount" id="sumTotal">432,000원</span>
<span class="summary-total-label">합계</span>
<strong class="total-amount" id="sumTotal">432,000원</strong>
</div>
<button type="button" class="calc-submit" id="btnSubmitQuote">
예상 견적 보기
</button>
<p style="font-size: 12px; color: var(--ink-muted); margin-top: 10px; text-align: center;">
선택 항목에 따른 예상 금액을 확인할 수 있습니다. 실제 견적·신청은 진행되지 않습니다.
</p>
<a href="#request" class="btn-primary summary-cta">이 금액으로 견적 요청</a>
<p class="summary-note">예시 금액입니다. 실제 견적과 신청은 진행되지 않습니다.</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);">
검수 절차 예시 보기 →
</a>
</div>
<div class="protocol-grid">
<div class="protocol-card">
<div class="protocol-num">STEP 01</div>
<h3>건식 초미세 집진</h3>
<p>벽면, 천장 몰딩, 바닥의 시공 잔여물을 확인하고 흡진 작업 여부를 기록합니다.</p>
</div>
<div class="protocol-card">
<div class="protocol-num">STEP 02</div>
<h3>스팀 장비 설정 확인</h3>
<p>배수구, 욕실 타일 틈새, 주방 후드처럼 확인이 필요한 면과 장비 설정을 작업표에 기록합니다.</p>
</div>
<div class="protocol-card">
<div class="protocol-num">STEP 03</div>
<h3>표면별 세정 확인</h3>
<p>표면 재질과 사용 제품 정보를 작업표에 기록하고, 적용 전후 상태를 함께 확인합니다.</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>환기와 마감 상태를 확인하고, 사용한 향·마감 제품이 있다면 작업표에 표시합니다.</p>
</div>
<div class="protocol-card">
<div class="protocol-num">STEP 06</div>
<h3>32개 항목 마스터 검수</h3>
<p>현장 담당자와 의뢰자가 검수 항목을 함께 확인하는 흐름을 예시로 표시합니다.</p>
</div>
</div>
</div>
</section>
<!-- 전문 장비 & Before/After -->
<section class="equipment-section" id="equipment" aria-labelledby="equipHeading">
<!-- 6단계 절차 -->
<section class="steps" id="protocol" aria-labelledby="stepsHeading">
<div class="wrap">
<div class="section-head">
<h2 id="equipHeading" class="section-title">작업 장비와 검수 기록</h2>
<p class="section-sub">현장에서 확인할 장비·필터·제품·마감 항목을 작업표에 표시하는 예시입니다.</p>
<h2 id="stepsHeading" class="section-title">6단계로 작업하고, 단계마다 쓴 장비와 제품을 작업표에 적습니다</h2>
<a href="./protocol/index.html" class="text-link">절차 상세 보기</a>
</div>
<div class="equip-grid">
<div class="equip-specs">
<div class="spec-item">
<span class="spec-key">장비 기록</span>
<span class="spec-val">사용 장비와 설정값을 작업표에 표시</span>
</div>
<div class="spec-item">
<span class="spec-key">필터 확인</span>
<span class="spec-val">필터 종류와 교체 상태를 현장에서 확인</span>
</div>
<div class="spec-item">
<span class="spec-key">사용 제품</span>
<span class="spec-val">제품명과 적용 표면을 작업표에 기록</span>
</div>
<div class="spec-item">
<span class="spec-key">마감 확인</span>
<span class="spec-val">환기·표면 상태를 검수 항목으로 확인</span>
</div>
</div>
<ol class="step-list">
<li class="step">
<h3>공사 먼지 흡진</h3>
<p>벽면, 천장 몰딩, 바닥의 시공 잔여물을 확인하고 흡진 작업 여부를 기록합니다.</p>
</li>
<li class="step">
<h3>스팀 장비 설정 확인</h3>
<p>배수구, 욕실 타일 줄눈, 주방 후드를 스팀으로 청소하고 장비 온도 설정을 작업표에 적습니다.</p>
</li>
<li class="step">
<h3>재질에 맞는 세제 사용</h3>
<p>대리석, 원목, 스테인리스 등 재질에 맞는 세제를 쓰고 사용한 제품을 작업표에 적습니다.</p>
</li>
<li class="step">
<h3>서랍과 후드 분리 세척</h3>
<p>서랍과 후드 필터를 떼어 내 안쪽까지 닦고, 분리한 부위를 작업표에 표시합니다.</p>
</li>
<li class="step">
<h3>환기와 마감 확인</h3>
<p>환기와 마감 상태를 확인하고, 사용한 향이나 마감 제품이 있으면 작업표에 표시합니다.</p>
</li>
<li class="step">
<h3>32개 항목 최종 검수</h3>
<p>현장 팀장과 고객님이 32개 검수 항목을 작업표로 함께 확인하고 서명합니다.</p>
</li>
</ol>
</div>
</section>
<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">검수 항목 확인</span>
</div>
<!-- 장비와 기록 -->
<section class="gear" id="equipment" aria-labelledby="gearHeading">
<div class="wrap gear-grid">
<figure class="gear-cutout">
<img
src="./assets/steam-qc.webp"
alt="청온 케어 현장에서 쓰는 스팀 청소기와 세척 노즐, 극세사 천, 세제 샘플"
width="800"
height="600"
loading="lazy"
/>
<figcaption>스팀 청소기, 극세사 천, 세제 샘플. 현장에서 쓰는 장비와 제품입니다.</figcaption>
</figure>
<div class="gear-text">
<h2 id="gearHeading" class="section-title">장비 설정값과 사용 제품은 현장에서 작업표에 적습니다</h2>
<dl class="record-list">
<div class="record">
<dt>장비</dt>
<dd>사용 장비와 설정값을 작업표에 표시합니다.</dd>
</div>
<div class="record">
<dt>필터</dt>
<dd>필터 종류와 교체 상태를 현장에서 확인합니다.</dd>
</div>
<div class="record">
<dt>제품</dt>
<dd>제품명과 적용 표면을 작업표에 기록합니다.</dd>
</div>
<div class="record">
<dt>마감</dt>
<dd>환기와 표면 상태를 검수 항목으로 확인합니다.</dd>
</div>
</dl>
</div>
</div>
</section>
</div>
<!-- ===================================================================
2. 운영 현황 보기
=================================================================== -->
<!-- 운영 현황 보기 (예시 화면) -->
<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>
<p class="demo-notice" role="note">아래 접수·배차 정보는 운영 화면 예시입니다. 실제 고객 정보나 접수 내역이 아닙니다.</p>
<h2 class="section-title">오늘 작업 현황</h2>
<p class="demo-notice" role="note">아래 접수와 배차 정보는 운영 화면 예시입니다. 실제 고객 정보나 접수 내역이 아닙니다.</p>
</div>
<button type="button" class="btn-primary" id="btnOpenQcModal">
32개 검수 항목 보기
</button>
<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>
@ -379,34 +255,33 @@
<div class="kpi-val">4개 조</div>
</div>
<div class="kpi-card">
<div class="kpi-label">검수 대기 / 완료</div>
<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 class="kpi-val" id="kpiTotalRevenue">2,480,000원</div>
</div>
</div>
<!-- 실시간 접수 및 배차 원장 테이블 -->
<div class="admin-table-card">
<div class="table-header">
<span class="table-title">접수·배차 현황</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>
<span class="table-title">접수와 배차 현황</span>
<div class="table-filter-tabs" role="group" aria-label="상태 필터">
<button type="button" class="filter-tab is-active" data-filter="all">전체</button>
<button type="button" class="filter-tab" data-filter="new">신규접수</button>
<button type="button" class="filter-tab" data-filter="progress">진행중</button>
<button type="button" class="filter-tab" data-filter="done">완료</button>
</div>
</div>
<div style="overflow-x: auto;">
<div class="table-scroll">
<table class="admin-table">
<thead>
<tr>
<th scope="col">접수번호</th>
<th scope="col">고객명 / 연락처</th>
<th scope="col">공간 / 면적</th>
<th scope="col">고객명</th>
<th scope="col">공간</th>
<th scope="col">현장 주소</th>
<th scope="col">견적액</th>
<th scope="col">배정 팀장</th>
@ -416,108 +291,157 @@
</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 class="num">#CO-2026-0819</td>
<td><strong>이서연</strong><br /><span class="cell-sub">010-4821-9930</span></td>
<td>주거 입주 (32평)</td>
<td>성동구 성수동 아크로포레스트</td>
<td class="mono" style="font-weight:700;">432,000원</td>
<td>김정온 마스터</td>
<td class="num cell-strong">432,000원</td>
<td>김정온 팀장 (3팀)</td>
<td><span class="status-pill new">신규 접수</span></td>
<td><button class="action-btn" onclick="alert('배차 상태를 확인했습니다. 이 화면의 접수 정보는 예시이며 실제 알림은 전송되지 않습니다.');">배차 상태 보기</button></td>
<td><button type="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 class="num">#CO-2026-0818</td>
<td><strong>박도현</strong><br /><span class="cell-sub">010-9120-3341</span></td>
<td>사무실 정기 (45평)</td>
<td>강남구 테헤란로 142 위워크</td>
<td class="mono" style="font-weight:700;">520,000원</td>
<td class="num cell-strong">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>
<td><span class="status-pill progress">작업 중</span></td>
<td><button type="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 class="num">#CO-2026-0817</td>
<td><strong>한지민</strong><br /><span class="cell-sub">010-7712-4091</span></td>
<td>준공 청소 (58평)</td>
<td>용산구 한남동 나인원한남</td>
<td class="mono" style="font-weight:700;">841,000원</td>
<td>최수진 닥터 (1팀)</td>
<td class="num cell-strong">841,000원</td>
<td>최수진 팀장 (1팀)</td>
<td><span class="status-pill done">검수 승인 완료</span></td>
<td><button class="action-btn" onclick="alert('검수 리포트 내용을 확인했습니다. 실제 발행은 진행되지 않습니다.');">리포트 보기</button></td>
<td><button type="button" class="action-btn" onclick="alert('검수 리포트 내용을 확인했습니다. 실제 발행은 진행되지 않습니다.');">리포트 보기</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<!-- 화면 전환: 고객 화면과 운영 화면 예시 -->
<div class="wrap view-switch">
<span class="view-switch-label" id="viewSwitchLabel">화면</span>
<div class="mode-toggle" role="group" aria-labelledby="viewSwitchLabel">
<button type="button" class="mode-btn is-active" id="btnModeClient" aria-pressed="true">고객 화면</button>
<button type="button" class="mode-btn" id="btnModeAdmin" aria-pressed="false" title="단축키: Alt + A">운영 화면 예시</button>
</div>
</div>
</main>
<!-- 32개 항목 QC 검수 모달 다이얼로그 -->
<!-- 32개 항목 검수표 -->
<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>
<h3 id="qcTitle" class="qc-title">32개 항목 검수표</h3>
<button type="button" class="icon-btn" onclick="document.getElementById('qcModal').close();" aria-label="닫기">✕</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>
<li class="qc-item"><label><input type="checkbox" checked /> <span>01. 천장 몰딩 및 전등갓 상단 분진 흡진</span></label></li>
<li class="qc-item"><label><input type="checkbox" checked /> <span>02. 창틀 상하좌우 틈새 시멘트 가루 및 찌든때 제거</span></label></li>
<li class="qc-item"><label><input type="checkbox" checked /> <span>03. 싱크대 하부 걸레받이 전면 탈거 및 분진 집진</span></label></li>
<li class="qc-item"><label><input type="checkbox" checked /> <span>04. 가스레인지/인덕션 상판 및 후드 필터 기름때 고온 스팀 분해</span></label></li>
<li class="qc-item"><label><input type="checkbox" checked /> <span>05. 욕실 벽타일 줄눈과 배수구 트랩 스팀 청소</span></label></li>
<li class="qc-item"><label><input type="checkbox" checked /> <span>06. 수납장 모든 서랍 완전 탈거 후 레일 틈새 분진 청소</span></label></li>
<li class="qc-item"><label><input type="checkbox" checked /> <span>07. 베란다와 다용도실 바닥 타일 청소</span></label></li>
<li class="qc-item"><label><input type="checkbox" /> <span>08. 전 실 환기와 마감 상태 확인</span></label></li>
</ul>
<div style="display: flex; justify-content: flex-end; gap: 8px;">
<p class="qc-note">32개 항목 가운데 8개를 예시로 보입니다.</p>
<div class="qc-actions">
<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>
<button type="button" class="btn-primary btn-small" onclick="alert('검수 항목을 확인했습니다. 이 화면에서 실제 승인 처리는 진행되지 않습니다.'); document.getElementById('qcModal').close();">검수 항목 확인</button>
</div>
</dialog>
<!-- 푸터 (.site-foot SSOT) -->
<!-- 전화 (모바일 하단 바) — 가상 브랜드라 번호는 예시다. 실제로 연결되지 않는다 -->
<dialog id="callDialog" class="call-dialog" aria-labelledby="callTitle">
<h3 id="callTitle" class="qc-title">전화 문의</h3>
<p class="call-number">02-000-4172</p>
<p class="call-note">예시 번호라 실제로 연결되지 않습니다. 견적 요청 폼으로 흐름을 확인할 수 있습니다.</p>
<div class="qc-actions">
<button type="button" class="action-btn" onclick="document.getElementById('callDialog').close();">닫기</button>
</div>
</dialog>
<!-- 푸터: 다음 행동 하나(견적 요청)가 푸터의 대부분이다 -->
<footer class="site-foot">
<div class="wrap foot-inner">
<p>청온 케어 · 위생 케어 안내</p>
<p class="muted">이 페이지의 가격·접수 정보는 예시이며 입력 정보는 저장·전송되지 않습니다.</p>
<section class="wrap request" id="request" aria-labelledby="requestHeading">
<div class="request-head">
<h2 id="requestHeading" class="request-title">견적을 요청합니다</h2>
<p class="request-lead">위에서 고른 조건으로 <output class="request-total" id="requestTotal" for="quoteForm">432,000원</output>이 계산됐습니다. 연락처를 남기면 현장 팀장이 일정을 잡습니다.</p>
</div>
<form id="requestForm" class="request-form" onsubmit="return false;">
<div class="field">
<label class="form-label" for="clientName">성함</label>
<input type="text" id="clientName" name="clientName" autocomplete="name" class="text-input" required />
</div>
<div class="field">
<label class="form-label" for="clientPhone">연락처</label>
<input type="tel" id="clientPhone" name="clientPhone" autocomplete="tel" class="text-input" placeholder="010-0000-0000" required />
</div>
<div class="field field-wide">
<label class="form-label" for="clientAddress">청소할 곳 주소</label>
<input type="text" id="clientAddress" name="clientAddress" autocomplete="off" class="text-input" placeholder="예: 서울시 마포구 공덕동 120" required />
</div>
<button type="button" class="calc-submit" id="btnSubmitQuote">견적 요청</button>
<p class="request-note">예시 화면입니다. 입력한 정보는 저장하거나 전송하지 않습니다.</p>
</form>
</section>
<div class="wrap foot-meta">
<p class="foot-brand">청온 케어</p>
<p class="foot-contact">전화 02-000-4172</p>
<p class="foot-notice">청온 케어는 가상 브랜드 쇼케이스입니다. 서비스, 가격, 접수, 운영 현황, 연락처는 예시입니다.</p>
</div>
</footer>
<!-- 인터랙티브 스크립트 -->
<!-- 모바일 하단 고정 행동 바 -->
<div class="action-bar" role="group" aria-label="빠른 행동">
<button type="button" class="action-bar-call" id="btnCall">전화</button>
<a class="action-bar-quote" href="#request">견적 요청</a>
</div>
<script>
(function () {
// 1. 뷰 모드 전환 (고객 뷰 vs 관리자 뷰)
// 1. 화면 전환 (고객 화면 / 운영 화면 예시)
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");
}
const adminOn = mode === "admin";
btnAdmin.classList.toggle("is-active", adminOn);
btnClient.classList.toggle("is-active", !adminOn);
btnAdmin.setAttribute("aria-pressed", String(adminOn));
btnClient.setAttribute("aria-pressed", String(!adminOn));
}
btnClient.addEventListener("click", () => setViewMode("client"));
btnAdmin.addEventListener("click", () => setViewMode("admin"));
// 단축키 Alt + A 로 관리자 모드 토글
// 단축키 Alt + A — 입력 중에는 무시한다
window.addEventListener("keydown", (e) => {
const tag = (e.target && e.target.tagName) || "";
if (/^(INPUT|TEXTAREA|SELECT)$/.test(tag)) return;
if (e.altKey && (e.key === "a" || e.key === "A" || e.key === "ㅁ")) {
const cur = document.body.getAttribute("data-view");
setViewMode(cur === "admin" ? "client" : "admin");
}
});
// 2. 견적 계산기 로직
// 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 requestTotal = document.getElementById("requestTotal");
const sumSpaceType = document.getElementById("sumSpaceType");
const typeBtns = document.querySelectorAll(".type-btn");
const addonCheckboxes = document.querySelectorAll("input[name='addon']");
@ -528,45 +452,45 @@
function updateQuote() {
const pyeong = parseInt(pyeongSlider.value, 10);
const sqm = Math.round(pyeong * 3.30578);
pyeongValue.textContent = `${pyeong} 평 (약 ${sqm}㎡)`;
sumPyeong.textContent = `${pyeong}평 (평당 ${currentBaseRate.toLocaleString()}원)`;
pyeongValue.textContent = `${pyeong}평 (약 ${sqm}㎡)`;
sumPyeong.textContent = `${pyeong}평 (평당 ${currentBaseRate.toLocaleString("ko-KR")}원)`;
sumSpaceType.textContent = currentTypeLabel;
const baseCost = pyeong * currentBaseRate;
sumBasePrice.textContent = `${baseCost.toLocaleString()}원`;
sumBasePrice.textContent = `${baseCost.toLocaleString("ko-KR")}원`;
let addonCost = 0;
addonCheckboxes.forEach((cb) => {
if (cb.checked) {
addonCost += parseInt(cb.getAttribute("data-price"), 10);
}
if (cb.checked) addonCost += parseInt(cb.getAttribute("data-price"), 10);
});
sumAddonPrice.textContent = `${addonCost.toLocaleString()}원`;
sumAddonPrice.textContent = `${addonCost.toLocaleString("ko-KR")}원`;
const total = baseCost + addonCost;
sumTotal.textContent = `${total.toLocaleString()}원`;
const totalStr = `${total.toLocaleString("ko-KR")}원`;
sumTotal.textContent = totalStr;
requestTotal.textContent = totalStr;
}
pyeongSlider.addEventListener("input", updateQuote);
typeBtns.forEach((btn) => {
btn.addEventListener("click", () => {
typeBtns.forEach((b) => b.classList.remove("is-active"));
typeBtns.forEach((b) => {
b.classList.remove("is-active");
b.setAttribute("aria-pressed", "false");
});
btn.classList.add("is-active");
btn.setAttribute("aria-pressed", "true");
currentBaseRate = parseInt(btn.getAttribute("data-base"), 10);
currentTypeLabel = btn.textContent.trim();
updateQuote();
});
});
addonCheckboxes.forEach((cb) => {
cb.addEventListener("change", updateQuote);
});
// 초기 계산 1회 실행
addonCheckboxes.forEach((cb) => cb.addEventListener("change", updateQuote));
updateQuote();
// 3. 견적 신청 버튼 클릭 -> 관리자 원장에 즉시 추가되는 풀-루프 인터랙션!
// 3. 견적 요청 → 운영 화면 예시 표에 한 줄 추가
const btnSubmit = document.getElementById("btnSubmitQuote");
const tableBody = document.getElementById("adminTableBody");
const kpiNewCount = document.getElementById("kpiNewCount");
@ -582,30 +506,58 @@
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>
`;
newRow.className = "row-fresh";
const cells = [
["num", `#CO-2026-082${submissionCount}`],
["", ""],
["", `${currentTypeLabel} (${pyeong}평)`],
["", address],
["num cell-strong cell-accent", totalStr],
["", "배차 지정 대기"],
["", ""],
["", ""],
];
cells.forEach(([cls, text], i) => {
const td = document.createElement("td");
if (cls) td.className = cls;
if (i === 1) {
const strong = document.createElement("strong");
strong.textContent = name;
const sub = document.createElement("span");
sub.className = "cell-sub";
sub.textContent = phone;
td.append(strong, document.createElement("br"), sub);
} else if (i === 6) {
const pill = document.createElement("span");
pill.className = "status-pill new";
pill.textContent = "방금 접수됨";
td.append(pill);
} else if (i === 7) {
const b = document.createElement("button");
b.type = "button";
b.className = "action-btn";
b.textContent = "배차 지정";
b.addEventListener("click", () => alert("배차 팀장을 매칭 중입니다. 예시 화면이라 실제 배차는 진행되지 않습니다."));
td.append(b);
} else {
td.textContent = text;
}
newRow.append(td);
});
tableBody.insertBefore(newRow, tableBody.firstChild);
alert(`${name}님의 예상 견적은 ${totalStr}입니다.\n실제 견적·신청은 진행되지 않았으며 입력 정보는 저장하거나 전송하지 않습니다.`);
alert(`${name}님의 예상 견적은 ${totalStr}입니다.\n실제 견적과 신청은 진행되지 않았으며 입력 정보는 저장하거나 전송하지 않습니다.`);
});
// 모달 열기
// 4. 다이얼로그
const btnOpenQc = document.getElementById("btnOpenQcModal");
const qcModal = document.getElementById("qcModal");
if (btnOpenQc && qcModal) {
btnOpenQc.addEventListener("click", () => qcModal.showModal());
}
if (btnOpenQc && qcModal) btnOpenQc.addEventListener("click", () => qcModal.showModal());
const btnCall = document.getElementById("btnCall");
const callDialog = document.getElementById("callDialog");
if (btnCall && callDialog) btnCall.addEventListener("click", () => callDialog.showModal());
})();
</script>
</body>

View file

@ -1,343 +1,185 @@
<!DOCTYPE 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>6단계 위생 케어 절차 · 예시 리포트 — 청온 케어</title>
<meta name="description" content="청온 케어의 현장 검수 절차와 기록 표시 방식을 소개합니다. 아래 사례와 값은 예시입니다." />
<title>청온 케어 6단계 작업 절차</title>
<meta name="description" content="청온 케어가 현장에서 장비, 필터, 세제, 마감 상태를 작업표에 적는 6단계 절차와 기록 방식입니다. 아래 사례와 값은 예시입니다." />
<meta property="og:title" content="청온 케어 6단계 작업 절차" />
<meta property="og:description" content="단계마다 쓴 장비와 제품을 작업표에 적고, 끝나면 32개 항목을 함께 확인합니다." />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://designpaca.chanpaca.net/work/cheongon-care/assets/atp-tester.webp" />
<meta property="og:image:alt" content="장갑을 낀 손이 잡은 휴대용 측정기와 면봉 검체 키트" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="theme-color" content="#eef3f6" />
<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="../styles/fonts.css?v=20260912all" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
href="https://cdn.jsdelivr.net/gh/wanteddev/wanted-sans@v1.0.3/packages/wanted-sans/fonts/webfonts/variable/split/WantedSansVariable.min.css"
/>
<link rel="stylesheet" href="../styles/tokens.css?v=20261006" />
<link rel="stylesheet" href="../styles/main.css?v=20261006" />
<link rel="stylesheet" href="../styles/protocol.css?v=20261006" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap"
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='%23156a75'/%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"
/>
<link rel="stylesheet" href="../styles/tokens.css?v=20260912all" />
<link rel="stylesheet" href="../styles/main.css?v=20260912all" />
<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" />
<style>
.breadcrumb-bar {
padding-top: var(--space-4);
padding-bottom: var(--space-3);
display: flex;
align-items: center;
gap: var(--space-2);
font-family: var(--font-mono);
font-size: var(--step--1);
color: var(--ink-muted);
border-bottom: 1px solid var(--line);
}
.breadcrumb-bar a {
color: var(--ink-muted);
text-decoration: none;
transition: color 0.15s ease;
}
.breadcrumb-bar a:hover {
color: var(--accent);
}
.breadcrumb-bar .sep {
opacity: 0.4;
}
.breadcrumb-bar .current {
color: var(--ink);
font-weight: 600;
}
.protocol-hero {
padding: var(--space-7) 0 var(--space-5);
}
.protocol-meta-strip {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: var(--space-3);
margin-top: var(--space-5);
background: var(--surface-card);
border: 1px solid var(--line);
border-radius: var(--radius-sm);
padding: var(--space-4);
}
.protocol-meta-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.protocol-meta-item .label {
font-family: var(--font-mono);
font-size: var(--step--1);
color: var(--ink-muted);
}
.protocol-meta-item .value {
font-size: var(--step-0);
font-weight: 700;
color: var(--accent);
}
.atp-compare-box {
background: var(--surface-card);
border: 1px solid var(--line);
border-radius: var(--radius-sm);
padding: var(--space-5);
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-4);
text-align: center;
}
.atp-val {
font-family: var(--font-mono);
font-size: var(--step-3);
font-weight: 800;
}
.atp-val.before {
color: #b91c1c;
}
.atp-val.after {
color: var(--accent);
}
.step-deep-list {
display: flex;
flex-direction: column;
gap: var(--space-4);
margin-top: var(--space-5);
}
.step-deep-item {
background: var(--surface-card);
border: 1px solid var(--line);
border-radius: var(--radius-sm);
padding: var(--space-5);
display: grid;
grid-template-columns: 120px 1fr;
gap: var(--space-5);
align-items: start;
}
@media (max-width: 680px) {
.step-deep-item {
grid-template-columns: 1fr;
gap: var(--space-3);
}
}
</style>
</head>
<body>
<a class="skip-link" href="#main-content">본문으로 건너뛰기</a>
<!-- Top Nav (GNB SSOT) -->
<a class="skip-link" href="#mainContent">본문으로 건너뛰기</a>
<header class="site-head">
<div class="wrap head-inner">
<a href="../index.html" class="wordmark" aria-label="청온 케어 홈">
<span class="wordmark-badge">청</span>
청온 케어
</a>
<nav class="nav" aria-label="메인 내비게이션">
<a href="./index.html" class="active" style="color: var(--accent); font-weight: 600;">6단계 프로토콜</a>
<a href="../index.html#services">케어 솔루션</a>
<a href="../index.html#calculator">정찰제 견적</a>
<a href="../index.html#equipment">전문 장비</a>
</nav>
<div class="head-actions">
<a href="../index.html#calculator" class="btn">간편 견적</a>
</div>
<a class="wordmark" href="../index.html">청온 케어</a>
<a class="head-action" href="../index.html#request">견적 요청</a>
</div>
</header>
<main id="main-content">
<!-- Hero Header -->
<section class="section protocol-hero" style="border-top: none; padding-top: var(--space-5);">
<main id="mainContent">
<!-- 표제는 작게, 사실 목록이 먼저 -->
<section class="proto-intro" aria-labelledby="protoHeading">
<div class="wrap">
<div class="breadcrumb-bar" style="margin-bottom: var(--space-4); display: flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); font-size: 12px; color: var(--ink-muted); letter-spacing: 0.04em;">
<a href="../index.html">CHEONG-ON CARE</a>
<span class="sep">/</span>
<span class="current" style="color: var(--ink); font-weight: 600;">CARE CHECKLIST &amp; CASE EXAMPLE</span>
</div>
<nav class="crumb" aria-label="현재 위치">
<a href="../index.html">청온 케어</a>
<span class="crumb-sep" aria-hidden="true">/</span>
<span aria-current="page">작업 절차</span>
</nav>
<h1 id="protoHeading" class="quote-title">6단계로 청소하고, 단계마다 작업표에 적습니다</h1>
<dl class="facts proto-facts">
<div class="fact">
<dt>단계</dt>
<dd>흡진, 스팀, 세제, 분리 세척, 환기와 마감, 최종 검수 6단계</dd>
</div>
<div class="fact">
<dt>기록</dt>
<dd>장비 설정값, 필터 상태, 사용 제품, 마감 상태 4가지</dd>
</div>
<div class="fact">
<dt>검수</dt>
<dd>32개 항목을 현장 팀장과 고객이 함께 확인하고 서명</dd>
</div>
</dl>
<p class="demo-notice" role="note">아래 절차와 기록값은 예시입니다. 실제 시공 결과를 보장하거나 예약을 접수하지 않습니다.</p>
</div>
</section>
<div class="protocol-hero-head">
<p class="hero-label">CARE CHECKLIST EXAMPLE</p>
<h1 class="hero-title" style="margin-bottom: var(--space-2);"><span style="color: var(--accent);">6단계 위생 케어 절차</span></h1>
<p class="hero-lead" style="font-size: var(--step-0); color: var(--ink-muted); max-width: var(--measure); margin-bottom: var(--space-5);">
현장 장비, 필터, 표면, 마감 상태를 작업표에 기록하는 절차와 확인 항목을 소개합니다.
</p>
<p class="demo-notice" role="note">안내: 아래 절차와 측정 수치는 예시입니다. 실제 시공 결과를 보장하거나 예약을 접수하지 않습니다.</p>
<dl class="protocol-specs" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-4); background: var(--surface-card); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--space-4) var(--space-5); margin-bottom: var(--space-6);">
<div>
<dt class="spec-label" style="font-family: var(--font-mono); font-size: 11px; color: var(--accent); letter-spacing: 0.02em; margin-bottom: 2px;">Steam Temp</dt>
<dd class="spec-val" style="font-size: var(--step-0); font-weight: 800; color: var(--ink);">현장 장비 설정 기록</dd>
<!-- 기록 방식 예시 -->
<section class="proto-record" aria-labelledby="recordHeading">
<div class="wrap proto-record-grid">
<figure class="gear-cutout">
<img
src="../assets/atp-tester.webp"
alt="장갑을 낀 손이 잡은 휴대용 측정기와 면봉 검체 키트"
width="1376"
height="768"
loading="lazy"
/>
<figcaption>표면 점검에 쓰는 휴대용 측정기. 읽은 값은 작업표에 적습니다.</figcaption>
</figure>
<div class="gear-text">
<h2 id="recordHeading" class="section-title">점검값은 전과 후를 나란히 적습니다</h2>
<p class="proto-lead">아래는 점검 기록이 작업표에 표시되는 방식의 예시입니다. 실제 현장 측정값이나 시공 결과가 아닙니다.</p>
<dl class="compare">
<div class="compare-cell">
<dt>점검 전</dt>
<dd class="compare-val before">기록값 A</dd>
<dd class="compare-sub">확인할 항목 표시</dd>
</div>
<div>
<dt class="spec-label" style="font-family: var(--font-mono); font-size: 11px; color: var(--accent); letter-spacing: 0.02em; margin-bottom: 2px;">Filtration</dt>
<dd class="spec-val" style="font-size: var(--step-0); font-weight: 800; color: var(--ink);">필터 종류·상태 확인</dd>
</div>
<div>
<dt class="spec-label" style="font-family: var(--font-mono); font-size: 11px; color: var(--accent); letter-spacing: 0.02em; margin-bottom: 2px;">Detergent</dt>
<dd class="spec-val" style="font-size: var(--step-0); font-weight: 800; color: var(--ink);">사용 제품·표면 기록</dd>
</div>
<div>
<dt class="spec-label" style="font-family: var(--font-mono); font-size: 11px; color: var(--accent); letter-spacing: 0.02em; margin-bottom: 2px;">QC Points</dt>
<dd class="spec-val" style="font-size: var(--step-0); font-weight: 800; color: var(--ink);">32개 정밀 항목</dd>
<div class="compare-cell">
<dt>점검 후</dt>
<dd class="compare-val after">기록값 B</dd>
<dd class="compare-sub">확인 완료 표시</dd>
</div>
</dl>
</div>
<figure class="hero-photo" style="border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface-card);">
<img
src="../assets/clean-hero.webp"
alt="정돈된 주거 공간의 실내 전경"
width="1600"
height="900"
style="width: 100%; aspect-ratio: 16/9; object-fit: cover;"
/>
<figcaption style="padding: 10px 16px; font-family: var(--font-mono); font-size: 12px; color: var(--ink-muted); border-top: 1px solid var(--line); background: var(--surface-raised);">
주거 공간 · 6단계 절차 예시
</figcaption>
</figure>
</div>
</section>
<!-- Inspection Record Layout -->
<section class="wrap" style="padding-bottom: var(--space-8);">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); gap: var(--space-8); align-items: center;">
<div class="frame">
<img
src="../assets/atp-tester.webp"
alt="검수 기록에 사용하는 계측 장비 화면 예시"
style="width: 100%; display: block;"
/>
</div>
<div style="display: flex; flex-direction: column; gap: var(--space-4);">
<div class="eyebrow">검수 기록 표시 예시</div>
<h2 style="font-size: var(--step-2); font-weight: 800; line-height: 1.25;">
주거 공간 예시<br />
<span style="color: var(--accent);">점검값 기록 방식</span>
</h2>
<p style="font-size: var(--step--1); color: var(--ink-muted); line-height: 1.7;">
아래 값은 점검 기록이 표시되는 방식을 설명하기 위한 예시입니다. 실제 현장 측정값이나 시공 결과를 뜻하지 않습니다.
</p>
<div class="atp-compare-box">
<div>
<div style="font-family: var(--font-mono); font-size: var(--step--1); color: var(--ink-muted); margin-bottom: 4px;">점검 전 기록</div>
<div class="atp-val before">기록값 A</div>
<div style="font-size: 12px; color: #b91c1c; margin-top: 4px;">확인할 항목 표시 예시</div>
</div>
<div style="border-left: 1px solid var(--line);">
<div style="font-family: var(--font-mono); font-size: var(--step--1); color: var(--ink-muted); margin-bottom: 4px;">점검 후 기록</div>
<div class="atp-val after">기록값 B</div>
<div style="font-size: 12px; color: var(--accent); margin-top: 4px;">확인 완료 표시 예시</div>
</div>
</div>
<!-- 6단계 -->
<section class="steps" aria-labelledby="stepsHeading">
<div class="wrap">
<div class="section-head">
<h2 id="stepsHeading" class="section-title">단계마다 무엇을 하고 무엇을 적는지</h2>
</div>
<ol class="step-list">
<li class="step">
<h3>공사 먼지 흡진</h3>
<p>벽면, 천장 몰딩, 조명 레일의 작업 범위를 확인하고 흡진 작업 여부를 작업표에 기록합니다.</p>
</li>
<li class="step">
<h3>스팀 장비 설정 확인</h3>
<p>배수구, 욕실 타일 줄눈, 주방 후드를 스팀으로 청소하고 장비 온도 설정을 적습니다.</p>
</li>
<li class="step">
<h3>재질에 맞는 세제 사용</h3>
<p>바닥과 석재의 재질을 확인한 뒤 사용 제품과 적용 범위를 작업표에 표시합니다.</p>
</li>
<li class="step">
<h3>서랍장과 걸레받이 분리 세척</h3>
<p>싱크대 하부 걸레받이와 수납장 서랍을 떼어 내 레일 안쪽까지 닦고, 분리한 부위를 기록합니다.</p>
</li>
<li class="step">
<h3>환기와 마감 확인</h3>
<p>환기와 마감 상태를 확인하고, 향이나 마감 제품을 사용했다면 제품명과 적용 범위를 기록합니다.</p>
</li>
<li class="step">
<h3>32개 항목 최종 검수</h3>
<p>현장 팀장과 고객님이 32개 항목 검수표를 함께 확인하고 서명합니다.</p>
</li>
</ol>
</div>
</section>
<!-- 6-Stage Deep Steps -->
<section class="wrap" style="padding-bottom: var(--space-8);">
<div class="eyebrow" style="text-align: center;">단계별 시공 절차</div>
<h2 style="font-size: var(--step-3); font-weight: 800; text-align: center; margin-top: 6px;">
청온 케어 6단계 검수 절차 예시
</h2>
<div class="step-deep-list">
<div class="step-deep-item">
<div style="font-family: var(--font-mono); font-size: var(--step-2); font-weight: 800; color: var(--accent);">STEP 01</div>
<div>
<h3 style="font-size: var(--step-1); font-weight: 700;">필터 흡진 작업 확인</h3>
<p style="font-size: var(--step--1); color: var(--ink-muted); margin-top: 6px; line-height: 1.6;">
벽면, 천장 몰딩, 조명 레일의 작업 범위를 확인하고 흡진 작업 여부를 작업표에 기록합니다.
</p>
</div>
</div>
<div class="step-deep-item">
<div style="font-family: var(--font-mono); font-size: var(--step-2); font-weight: 800; color: var(--accent);">STEP 02</div>
<div>
<h3 style="font-size: var(--step-1); font-weight: 700;">스팀 장비 설정 확인</h3>
<p style="font-size: var(--step--1); color: var(--ink-muted); margin-top: 6px; line-height: 1.6;">
배수구, 욕실 틈새, 주방 후드처럼 확인이 필요한 면을 구분하고 사용 장비 설정을 남깁니다.
</p>
</div>
</div>
<div class="step-deep-item">
<div style="font-family: var(--font-mono); font-size: var(--step-2); font-weight: 800; color: var(--accent);">STEP 03</div>
<div>
<h3 style="font-size: var(--step-1); font-weight: 700;">표면별 세정 확인</h3>
<p style="font-size: var(--step--1); color: var(--ink-muted); margin-top: 6px; line-height: 1.6;">
바닥과 석재의 재질을 확인한 뒤 사용 제품과 적용 범위를 작업표에 표시합니다.
</p>
</div>
</div>
<div class="step-deep-item">
<div style="font-family: var(--font-mono); font-size: var(--step-2); font-weight: 800; color: var(--accent);">STEP 04</div>
<div>
<h3 style="font-size: var(--step-1); font-weight: 700;">서랍장·걸레받이 전면 탈거 정밀 세척</h3>
<p style="font-size: var(--step--1); color: var(--ink-muted); margin-top: 6px; line-height: 1.6;">
싱크대 하부와 수납장 레일의 접근 가능 여부를 확인하고, 분리 작업 범위를 기록합니다.
</p>
</div>
</div>
<div class="step-deep-item">
<div style="font-family: var(--font-mono); font-size: var(--step-2); font-weight: 800; color: var(--accent);">STEP 05</div>
<div>
<h3 style="font-size: var(--step-1); font-weight: 700;">환기와 마감 확인</h3>
<p style="font-size: var(--step--1); color: var(--ink-muted); margin-top: 6px; line-height: 1.6;">
환기와 마감 상태를 확인하고, 향·마감 제품을 사용했다면 제품명과 적용 범위를 기록합니다.
</p>
</div>
</div>
<div class="step-deep-item">
<div style="font-family: var(--font-mono); font-size: var(--step-2); font-weight: 800; color: var(--accent);">STEP 06</div>
<div>
<h3 style="font-size: var(--step-1); font-weight: 700;">32개 항목 현장 검수 확인</h3>
<p style="font-size: var(--step--1); color: var(--ink-muted); margin-top: 6px; line-height: 1.6;">
현장 담당자와 의뢰자가 32개 체크리스트를 함께 확인하는 흐름을 예시로 표시합니다.
</p>
</div>
</div>
</div>
</section>
<!-- Steam QC Equipment Spec Strip -->
<div class="wrap" style="margin-bottom: var(--space-8);">
<div class="frame">
<img
src="../assets/steam-qc.webp"
alt="작업 장비와 검수 키트를 보여 주는 예시 이미지"
style="width: 100%; display: block; aspect-ratio: 16/9; object-fit: cover;"
/>
</div>
</div>
<!-- Quick CTA -->
<section class="wrap" style="padding-bottom: var(--space-8); text-align: center;">
<div class="card" style="max-width: 640px; margin: 0 auto; background: var(--surface-card);">
<div class="eyebrow" style="color: var(--accent);">정찰제 가격표</div>
<h2 style="font-size: var(--step-2); font-weight: 800; margin-top: 4px;">
우리 집 공간의 정찰제 견적을 확인하세요
</h2>
<p style="font-size: var(--step--1); color: var(--ink-muted); margin: 12px 0 24px;">
선택 항목을 기준으로 예상 금액을 확인할 수 있습니다. 실제 견적이나 신청은 진행되지 않습니다.
</p>
<a href="../index.html#calculator" class="btn-primary" style="display: inline-block; padding: 14px 28px; text-decoration: none; font-size: var(--step-0);">
항목별 예상 견적 보기 →
</a>
<!-- 계산기로 돌아가기 -->
<section class="wrap proto-cta" aria-labelledby="ctaHeading">
<div class="card">
<h2 id="ctaHeading" class="section-title">평형과 옵션을 고르면 예상 금액이 바로 나옵니다</h2>
<p class="proto-lead">평당 9,500원부터, 추가 옵션 4종. 예시 금액이며 실제 견적이나 신청은 진행되지 않습니다.</p>
<a href="../index.html#calculator" class="btn-primary">견적 계산하기</a>
</div>
</section>
</main>
<!-- 푸터 (.site-foot SSOT) -->
<dialog id="callDialog" class="call-dialog" aria-labelledby="callTitle">
<h3 id="callTitle" class="qc-title">전화 문의</h3>
<p class="call-number"><span class="placeholder">[대표 전화번호]</span></p>
<p class="call-note">청온 케어는 가상 브랜드라 실제 전화번호가 없습니다. 견적 요청 폼으로 흐름을 확인할 수 있습니다.</p>
<div class="qc-actions">
<button type="button" class="action-btn" onclick="document.getElementById('callDialog').close();">닫기</button>
</div>
</dialog>
<footer class="site-foot">
<div class="wrap foot-inner">
<p>청온 케어 · 위생 케어 안내</p>
<p class="muted">이 페이지의 절차와 수치는 예시이며 실제 예약은 접수되지 않습니다.</p>
<section class="wrap request" aria-labelledby="requestHeading">
<div class="request-head">
<h2 id="requestHeading" class="request-title">견적을 요청합니다</h2>
<p class="request-lead">첫 페이지에서 평형과 옵션을 고른 뒤 연락처를 남기면 현장 팀장이 일정을 잡습니다.</p>
</div>
<div class="request-form">
<a href="../index.html#request" class="calc-submit calc-submit-link">견적 요청으로 가기</a>
<p class="request-note">예시 화면입니다. 입력한 정보는 저장하거나 전송하지 않습니다.</p>
</div>
</section>
<div class="wrap foot-meta">
<p class="foot-brand">청온 케어</p>
<p class="foot-contact">전화 <span class="placeholder">[대표 전화번호]</span></p>
<p class="foot-notice">이 페이지의 절차와 수치는 예시이며 실제 예약은 접수되지 않습니다.</p>
</div>
</footer>
<div class="action-bar" role="group" aria-label="빠른 행동">
<button type="button" class="action-bar-call" id="btnCall">전화</button>
<a class="action-bar-quote" href="../index.html#request">견적 요청</a>
</div>
<script>
(function () {
const btnCall = document.getElementById("btnCall");
const callDialog = document.getElementById("callDialog");
if (btnCall && callDialog) btnCall.addEventListener("click", () => callDialog.showModal());
})();
</script>
</body>
</html>

View file

@ -1,15 +0,0 @@
@font-face {
font-family: "MaruBuri";
src: url("../assets/fonts/MaruBuri-Regular.woff2") format("woff2");
font-style: normal;
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: "MaruBuri";
src: url("../assets/fonts/MaruBuri-SemiBold.woff2") format("woff2");
font-style: normal;
font-weight: 600;
font-display: swap;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,162 @@
/* ==========================================================================
청온 케어 — 2차 페이지(작업 절차) 전용 스타일. 공통 셸과 토큰은 main.css·tokens.css 가 맡는다.
========================================================================== */
.proto-intro {
padding-block: var(--space-5) var(--space-7);
}
.crumb {
display: flex;
align-items: center;
gap: var(--space-2);
font-size: var(--step--1);
color: var(--ink-muted);
margin-bottom: var(--space-4);
}
.crumb a {
display: inline-flex;
align-items: center;
min-height: var(--control-block);
text-decoration: underline;
text-underline-offset: 0.25em;
}
.crumb a:hover {
color: var(--accent);
}
.crumb-sep {
color: var(--ink-faint);
}
.crumb [aria-current="page"] {
color: var(--ink);
font-weight: var(--weight-strong);
}
.proto-facts {
max-width: 40em;
}
.proto-intro .demo-notice {
margin-top: var(--space-5);
}
.proto-record {
padding-block: var(--space-7);
border-top: 1px solid var(--line);
}
.proto-record-grid {
display: grid;
grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
gap: var(--space-6);
align-items: center;
}
.proto-record-grid .gear-cutout img {
aspect-ratio: 16 / 10;
object-position: 55% 45%;
mask-image: radial-gradient(ellipse 58% 62% at 55% 50%, var(--ink) 55%, transparent 100%);
-webkit-mask-image: radial-gradient(ellipse 58% 62% at 55% 50%, var(--ink) 55%, transparent 100%);
}
.proto-lead {
margin-top: var(--space-3);
color: var(--ink-muted);
max-width: var(--measure);
}
.compare {
margin-top: var(--space-4);
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
border: 1px solid var(--line);
border-radius: var(--radius);
background: var(--surface-raised);
overflow: hidden;
}
.compare-cell {
padding: var(--space-4);
}
.compare-cell + .compare-cell {
border-left: 1px solid var(--line);
}
.compare dt {
font-size: var(--step--1);
font-weight: var(--weight-medium);
color: var(--ink-muted);
}
.compare-val {
margin-top: var(--space-1);
font-size: var(--step-2);
font-weight: var(--weight-strong);
letter-spacing: -0.01em;
}
.compare-val.before {
color: var(--ink-muted);
text-decoration: line-through;
text-decoration-thickness: 2px;
}
.compare-val.after {
color: var(--accent-hover);
}
.compare-sub {
font-size: var(--step--1);
color: var(--ink-muted);
}
.proto-cta {
padding-block: 0 var(--space-7);
}
.card {
padding: var(--space-5);
background: var(--surface-raised);
border: 1px solid var(--line);
border-radius: var(--radius);
display: grid;
gap: var(--space-2);
justify-items: start;
}
.card .btn-primary {
margin-top: var(--space-3);
}
.calc-submit-link {
display: inline-flex;
align-items: center;
justify-content: center;
}
@media (max-width: 60em) {
.proto-record-grid {
grid-template-columns: minmax(0, 1fr);
gap: var(--space-5);
}
.proto-record-grid .gear-cutout {
order: 2;
}
}
@media (max-width: 37.5em) {
.compare {
grid-template-columns: minmax(0, 1fr);
}
.compare-cell + .compare-cell {
border-left: 0;
border-top: 1px solid var(--line);
}
}

View file

@ -1,58 +1,69 @@
/* ==========================================================================
청온 케어 (CHEONG-ON CARE) — 디자인 토큰 SSOT
프리셋: ledger-console + swiss-minimal
컨셉: 현장 검수 절차와 정직한 정찰제 — 공간의 상태를 기록하는 케어
단일 강조색: 에메랄드 틸 (#0D9488)
청온 케어 — 디자인 토큰 (유일한 정의 지점)
방향: 도구가 주인인 견적 페이지. 밝은 쿨 바탕 위에 흰 작업 패널, 청록(187°) 하나만 상태·행동에 쓴다.
서체는 Wanted Sans 하나로 표제·본문·숫자를 다 맡긴다(모노 없음, 숫자는 tabular-nums).
radius 8px 한 값. 모션은 폼 상태 전환(색·테두리)뿐이다.
========================================================================== */
:root {
/* 타이포그래피 스케일 */
--step--1: 0.8125rem; /* 13px — 캡션·태그 */
--step-0: 1rem; /* 16px — 본문 */
--step-1: 1.1875rem; /* 19px — 소제목 */
--step-2: clamp(1.375rem, 1.2rem + 0.9vw, 1.875rem); /* 30px — 섹션 헤딩 */
--step-3: clamp(2.25rem, 1.5rem + 3vw, 3.8rem); /* 60px — 메인 디스플레이 */
/* ── 타입 스케일 (16px 기준, 비율 1.2) ── */
--step--1: 0.8125rem; /* 13px — 보조 기록·캡션 */
--step-0: 1rem; /* 16px — 본문·입력 */
--step-1: 1.1875rem; /* 19px — 소제목·요약 행 */
--step-2: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem); /* 22~28px — h1(작게)·섹션 제목 */
--step-3: clamp(2rem, 1.3rem + 1.8vw, 2.75rem); /* 32~44px — 합계 금액 한 곳(1,297,500원 10자가 합계 열에 한 줄로 들어가는 상한) */
--leading-tight: 1.2;
--leading-tight: 1.3;
--leading-normal: 1.7;
--measure: 58ch;
--measure: 36em;
--font-serif: "MaruBuri", "Noto Serif KR", serif;
--font-display: "Pretendard Variable", Pretendard, -apple-system, sans-serif;
--font-body: "Pretendard Variable", Pretendard, -apple-system, sans-serif;
--font-mono: "JetBrains Mono", monospace;
--weight-regular: 400;
--weight-medium: 500;
--weight-strong: 700;
/* 색상 — 클린 퓨어 화이트 & 딥 슬레이트 + 에메랄드 틸 1강조색 */
--surface: #f8faf9;
--font-body: "Wanted Sans Variable", "Wanted Sans", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
--font-display: var(--font-body);
/* ── 색 — 밝은 쿨 바탕(#eef3f6) + 흰 패널 + 청록 187° ── */
--surface: #eef3f6;
--surface-raised: #ffffff;
--surface-card: #f0f4f2;
--surface-subtle: #e6ede9;
--surface-sunken: #e2e9e5;
--surface-inverse: #0f172a;
--surface-card: #e1eaef;
--surface-sunken: #d8e3e9;
--surface-inverse: #15252e;
--ink: #0f172a;
--ink-muted: #475569;
--ink-faint: #94a3b8;
--ink-inverse: #f8faf9;
--ink-inverse-muted: #cbd5e1;
--ink: #112027;
--ink-muted: #4b616c;
--ink-faint: #586e79; /* 흰 바탕 5.4:1, 쿨 바탕 4.8:1 — 보조 글자도 AA */
--ink-inverse: #eef3f6;
--ink-inverse-muted: #b2c0c7;
--line: #e2e8e5;
--line-strong: #cbd5e1;
--line-subtle: #edf2ef;
--line-inverse: #334155;
--line: #ced9de;
--line-strong: #b2c0c7;
/* 단일 강조색 (에메랄드 틸) */
--accent: #0f766e;
--accent-hover: #115e59;
--accent-light: #f0fdfa;
--accent-surface: #ccfbf1;
--accent: #156a75; /* 바탕 위 5.6:1, 흰 글자 6.3:1 */
--accent-hover: #0f535c;
--accent-light: #e5f3f5;
--accent-surface: #cde6ea;
--accent-ink: #ffffff;
--radius: 2px;
--radius-sm: 4px;
--radius-md: 8px;
--placeholder-ink: #4b616c;
/* 간격 — SSOT 표준 */
/* 상태색 — 운영 화면 접수 상태 알약에만 쓴다(브랜드 강조와 분리) */
--status-new-bg: #fdf0d5;
--status-new-ink: #7a4b08;
--status-progress-bg: #cde6ea;
--status-progress-ink: #0f535c;
--status-done-bg: #dde7f6;
--status-done-ink: #27467f;
--scrim: rgba(21, 37, 46, 0.55);
--shadow-panel: 0 1px 2px rgba(21, 37, 46, 0.06), 0 12px 32px -16px rgba(21, 37, 46, 0.18);
--shadow-bar: 0 -8px 24px -12px rgba(21, 37, 46, 0.28);
--head-bg: rgba(238, 243, 246, 0.96);
--radius: 8px;
/* ── 간격 ── */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 1rem;
@ -62,14 +73,17 @@
--space-7: 6rem;
--space-8: clamp(4.5rem, 3rem + 6vw, 9rem);
/* 컨테이너 및 패딩 — 전체 쇼케이스 절대 통일 SSOT */
--container: clamp(70rem, 62vw, 85rem);
--pad-inline: clamp(1.25rem, 1rem + 2.5vw, 4rem);
--container: 78rem;
--pad-inline: clamp(1rem, 0.5rem + 2.5vw, 3rem);
--control-block: 2.75rem;
--control-pad-inline: 0.875rem;
--action-bar-height: 4.25rem;
/* 모션 */
--dur-quick: 180ms;
--dur-normal: 420ms;
--safe-bottom: env(safe-area-inset-bottom, 0px);
--safe-left: env(safe-area-inset-left, 0px);
--safe-right: env(safe-area-inset-right, 0px);
/* ── 모션 — 폼 상태 전환만 ── */
--dur-quick: 160ms;
--ease-soft: cubic-bezier(0.25, 1, 0.35, 1);
}