careermate 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +33 -0
- package/LICENSE +21 -0
- package/README.md +3 -1
- package/apps/web/public/pages/documents.js +7 -2
- package/apps/web/public/pages/home.js +4 -7
- package/apps/web/public/pages/jobs.js +1 -5
- package/apps/web/public/pages/profile.js +3 -3
- package/apps/web/public/styles.css +7 -2
- package/dist/doctor.mjs +112 -90
- package/dist/install-page/analytics.js +97 -0
- package/dist/install-page/index.html +77 -56
- package/dist/install-page/og.png +0 -0
- package/dist/install-page/robots.txt +4 -0
- package/dist/install-page/sitemap.xml +21 -0
- package/dist/install-page/start.html +13 -10
- package/dist/install-page/style.css +75 -40
- package/dist/mcp.mjs +112 -90
- package/dist/migrate.mjs +95 -82
- package/dist/public/pages/documents.js +7 -2
- package/dist/public/pages/home.js +4 -7
- package/dist/public/pages/jobs.js +1 -5
- package/dist/public/pages/profile.js +3 -3
- package/dist/public/styles.css +7 -2
- package/dist/web.mjs +113 -86
- package/docs/FAQ.md +101 -0
- package/docs/career-os/README.md +76 -0
- package/docs/career-os/eop/cover-letter.md +46 -0
- package/docs/career-os/eop/fit-analysis.md +48 -0
- package/docs/career-os/eop/interview-prep.md +39 -0
- package/docs/career-os/eop/job-analysis.md +42 -0
- package/docs/career-os/eop/profile-extraction.md +37 -0
- package/docs/career-os/knowledge/ats.md +131 -0
- package/docs/career-os/knowledge/company-research.md +137 -0
- package/docs/career-os/knowledge/cover-letter.md +135 -0
- package/docs/career-os/knowledge/fit-matching.md +121 -0
- package/docs/career-os/knowledge/human-writing.md +118 -0
- package/docs/career-os/knowledge/interview-behavioral.md +132 -0
- package/docs/career-os/knowledge/interview-technical.md +126 -0
- package/docs/career-os/knowledge/linkedin-profile.md +152 -0
- package/docs/career-os/knowledge/networking-referrals.md +166 -0
- package/docs/career-os/knowledge/offer-evaluation-decision.md +121 -0
- package/docs/career-os/knowledge/onboarding-first-90-days.md +126 -0
- package/docs/career-os/knowledge/portfolio.md +121 -0
- package/docs/career-os/knowledge/recruiter-screen.md +105 -0
- package/docs/career-os/knowledge/rejection-triage-iteration.md +115 -0
- package/docs/career-os/knowledge/resume.md +123 -0
- package/docs/career-os/knowledge/salary-negotiation.md +123 -0
- package/docs/career-os/knowledge/verifiers/ats-compat.md +64 -0
- package/docs/career-os/knowledge/verifiers/consistency.md +61 -0
- package/docs/career-os/knowledge/verifiers/human-voice.md +82 -0
- package/docs/career-os/knowledge/verifiers/recency-staleness.md +72 -0
- package/docs/career-os/knowledge/verifiers/responsiveness-on-target.md +82 -0
- package/docs/career-os/knowledge/verifiers/truthfulness.md +67 -0
- package/package.json +11 -3
- package/packages/db/src/repositories.ts +18 -1
- package/packages/mcp-tools/src/tools.ts +5 -5
- package/packages/parsers/src/documents.ts +13 -1
- package/packages/shared/src/schemas.ts +115 -81
- package/scripts/build-dist.mjs +7 -1
- package/scripts/gen-og.mjs +1 -1
- package/scripts/test.ts +25 -0
- package/scripts/ui-smoke.ts +32 -4
- package/dist/install-page/.omc/state/agent-replay-55a58c0d-bb6e-43ea-8a05-4b6c93b80b34.jsonl +0 -12
- package/dist/install-page/.omc/state/idle-notif-cooldown.json +0 -3
- package/dist/install-page/.omc/state/sessions/55a58c0d-bb6e-43ea-8a05-4b6c93b80b34/mission-state.json +0 -147
- package/dist/install-page/.omc/state/sessions/55a58c0d-bb6e-43ea-8a05-4b6c93b80b34/pre-tool-advisory-throttle.json +0 -22
- package/dist/install-page/.omc/state/sessions/55a58c0d-bb6e-43ea-8a05-4b6c93b80b34/subagent-tracking-state.json +0 -44
- package/docs/ARCHITECTURE.md +0 -208
- package/docs/CHANGES_V1.md +0 -103
- package/docs/DATA_MODEL.md +0 -460
- package/docs/DECISIONS.md +0 -277
- package/docs/DEMO.md +0 -242
- package/docs/ROADMAP.md +0 -135
- package/docs/RUNTIME_DISTRIBUTION_RESEARCH.md +0 -135
- package/docs/TODO.md +0 -57
- package/docs/UX_NOTES.md +0 -247
- package/docs/superpowers/specs/2026-06-16-demo-dashboard-deploy-design.md +0 -64
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// CareerMate marketing-site analytics — careermate.life ONLY.
|
|
3
|
+
//
|
|
4
|
+
// SCOPE: this file loads on the PUBLIC marketing/demo site (install-page/) that
|
|
5
|
+
// Vercel serves. It must NEVER be loaded by the local dashboard (apps/web, bound
|
|
6
|
+
// to 127.0.0.1) — that would break the core promise in AGENTS.md:
|
|
7
|
+
// "절대 사용자 데이터를 외부로 업로드하지 마라."
|
|
8
|
+
// There is no user career data on this site; only anonymous page/traffic signals.
|
|
9
|
+
//
|
|
10
|
+
// What runs here:
|
|
11
|
+
// 1) Vercel Web Analytics — cookieless, no PII, no consent banner required.
|
|
12
|
+
// 2) Vercel Speed Insights — Core Web Vitals, also cookieless.
|
|
13
|
+
// 3) Google Analytics 4 — OPTIONAL. Off until GA_MEASUREMENT_ID is filled in.
|
|
14
|
+
// Runs under Google Consent Mode v2 with analytics_storage DENIED by default,
|
|
15
|
+
// i.e. cookieless pings, so it needs no consent banner and stays consistent
|
|
16
|
+
// with the local-first / privacy-first brand. (Flip consent to 'granted'
|
|
17
|
+
// later only if you add a real consent UI.)
|
|
18
|
+
//
|
|
19
|
+
// The marketing pages (index.html, start.html) are classic multi-page navigations,
|
|
20
|
+
// so a single pageview on load is enough. The demo (/demo/) is a hash-router SPA,
|
|
21
|
+
// so we emit a virtual pageview on every hashchange — otherwise every sub-route
|
|
22
|
+
// (#/jobs, #/applications, …) would collapse into one "/demo" view.
|
|
23
|
+
// =============================================================================
|
|
24
|
+
(function () {
|
|
25
|
+
'use strict';
|
|
26
|
+
|
|
27
|
+
// ── 1. Vercel Web Analytics (cookieless) ───────────────────────────────────
|
|
28
|
+
// Queue shim per Vercel's HTML snippet; the injected script drains window.vaq.
|
|
29
|
+
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
|
|
30
|
+
loadScript('/_vercel/insights/script.js');
|
|
31
|
+
|
|
32
|
+
// ── 2. Vercel Speed Insights (cookieless) — OFF by default ──────────────────
|
|
33
|
+
// Vercel's Hobby plan allows Speed Insights on only ONE project at a time, and it's
|
|
34
|
+
// more valuable on the real app than on this rarely-changing static site (use the free
|
|
35
|
+
// PageSpeed Insights for ad-hoc checks here). Flip to true to load it (needs Enable in
|
|
36
|
+
// the Vercel dashboard too); leaving it false avoids a dead 404 script request.
|
|
37
|
+
var ENABLE_SPEED_INSIGHTS = false;
|
|
38
|
+
if (ENABLE_SPEED_INSIGHTS) {
|
|
39
|
+
window.si = window.si || function () { (window.siq = window.siq || []).push(arguments); };
|
|
40
|
+
loadScript('/_vercel/speed-insights/script.js');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ── 3. Google Analytics 4 (optional, cookieless via Consent Mode v2) ────────
|
|
44
|
+
// Paste your GA4 measurement ID (looks like "G-XXXXXXXXXX") here to turn it on.
|
|
45
|
+
// Leaving it blank keeps GA off entirely — Vercel analytics above still runs.
|
|
46
|
+
var GA_MEASUREMENT_ID = 'G-HK9KWTYCBD';
|
|
47
|
+
if (/^G-[A-Z0-9]+$/.test(GA_MEASUREMENT_ID)) initGoogleAnalytics(GA_MEASUREMENT_ID);
|
|
48
|
+
|
|
49
|
+
// ── Demo SPA: report hash route changes to Vercel as a custom event ─────────
|
|
50
|
+
// Vercel's script auto-tracks History API navigations but not hashchange.
|
|
51
|
+
if (location.pathname.indexOf('/demo') === 0) {
|
|
52
|
+
window.addEventListener('hashchange', function () {
|
|
53
|
+
window.va('event', { name: 'demo_route', data: { route: currentRoute() } });
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ── helpers ─────────────────────────────────────────────────────────────────
|
|
58
|
+
function loadScript(src) {
|
|
59
|
+
var s = document.createElement('script');
|
|
60
|
+
s.src = src;
|
|
61
|
+
s.defer = true;
|
|
62
|
+
document.head.appendChild(s);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function currentRoute() {
|
|
66
|
+
return (location.hash || '').replace(/^#\/?/, '').split('/')[0] || 'home';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function initGoogleAnalytics(id) {
|
|
70
|
+
window.dataLayer = window.dataLayer || [];
|
|
71
|
+
function gtag() { window.dataLayer.push(arguments); }
|
|
72
|
+
window.gtag = gtag;
|
|
73
|
+
// Deny storage by default → GA runs cookieless. No banner required.
|
|
74
|
+
gtag('consent', 'default', {
|
|
75
|
+
ad_storage: 'denied',
|
|
76
|
+
ad_user_data: 'denied',
|
|
77
|
+
ad_personalization: 'denied',
|
|
78
|
+
analytics_storage: 'denied',
|
|
79
|
+
});
|
|
80
|
+
gtag('js', new Date());
|
|
81
|
+
// send_page_view:false so we control pageviews (incl. the demo's hash routes).
|
|
82
|
+
gtag('config', id, { send_page_view: false, anonymize_ip: true });
|
|
83
|
+
loadScript('https://www.googletagmanager.com/gtag/js?id=' + id);
|
|
84
|
+
|
|
85
|
+
sendGaPageview();
|
|
86
|
+
window.addEventListener('hashchange', sendGaPageview);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function sendGaPageview() {
|
|
90
|
+
if (!window.gtag) return;
|
|
91
|
+
window.gtag('event', 'page_view', {
|
|
92
|
+
page_path: location.pathname + location.search + location.hash,
|
|
93
|
+
page_location: location.href,
|
|
94
|
+
page_title: document.title,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
})();
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
<title>CareerMate — 내 AI를 커리어 비서로</title>
|
|
16
16
|
<meta name="description" content="Claude Desktop·Claude Code·Codex 같은 로컬 AI 앱에 연결하세요. CareerMate가 이력서·자기소개서·지원 현황을 이 컴퓨터에만 저장하고 MCP로 당신의 AI에 연결합니다." />
|
|
17
17
|
<link rel="canonical" href="https://careermate.life/" />
|
|
18
|
+
<meta name="google-site-verification" content="MfU5uwl1RNXKklsJhXz2hPCRytjLpCjCXSa2ls5JQH0" />
|
|
18
19
|
<meta name="theme-color" content="#faf8f4" media="(prefers-color-scheme: light)" />
|
|
19
20
|
<meta name="theme-color" content="#14130f" media="(prefers-color-scheme: dark)" />
|
|
20
21
|
|
|
@@ -42,6 +43,8 @@
|
|
|
42
43
|
|
|
43
44
|
<link rel="preload" href="fonts/PretendardVariable.woff2" as="font" type="font/woff2" crossorigin />
|
|
44
45
|
<link rel="stylesheet" href="style.css" />
|
|
46
|
+
<!-- Privacy-friendly analytics for the marketing site only (never the local 127.0.0.1 app). -->
|
|
47
|
+
<script src="/analytics.js" defer></script>
|
|
45
48
|
</head>
|
|
46
49
|
<body>
|
|
47
50
|
<a class="skip-link" href="#top">본문으로 건너뛰기</a>
|
|
@@ -72,68 +75,86 @@
|
|
|
72
75
|
|
|
73
76
|
<!-- ========================================================== hero -->
|
|
74
77
|
<header class="hero">
|
|
75
|
-
<
|
|
76
|
-
<span class="pill-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
78
|
+
<div class="hero__main">
|
|
79
|
+
<span class="pill-badge">
|
|
80
|
+
<span class="pill-badge__dot" aria-hidden="true"></span>
|
|
81
|
+
로컬 전용 · 무료
|
|
82
|
+
</span>
|
|
83
|
+
<h1 class="hero__title">
|
|
84
|
+
내가 쓰던 AI를<br />
|
|
85
|
+
나만의 커리어 비서로
|
|
86
|
+
</h1>
|
|
87
|
+
<p class="hero__lede">
|
|
88
|
+
<strong>공고 분석 · 맞춤 자기소개서 · 지원 현황 추적</strong>을 평소 쓰던 AI에게 말로 시키면, 결과가 이 컴퓨터 안에 쌓입니다. 한 번 정리한 경력은 대화마다 다시 붙여넣지 않아도 돼요.
|
|
89
|
+
</p>
|
|
90
|
+
|
|
91
|
+
<ul class="trust-strip" aria-label="안심 포인트">
|
|
92
|
+
<li>내 컴퓨터에만 저장</li>
|
|
93
|
+
<li>외부 업로드 없음</li>
|
|
94
|
+
<li>계정·API 키 불필요</li>
|
|
95
|
+
<li>언제든 삭제</li>
|
|
96
|
+
</ul>
|
|
97
|
+
|
|
98
|
+
<div class="hero__cta">
|
|
99
|
+
<a class="btn btn--primary" href="start.html">처음이세요? — 내게 맞는 설치법 찾기</a>
|
|
100
|
+
<a class="btn btn--ghost" href="#install">
|
|
101
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></svg>
|
|
102
|
+
바로 설치 방법 보기
|
|
103
|
+
</a>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<p class="hero__note">
|
|
107
|
+
CareerMate는 <strong>내 컴퓨터에서 도는 로컬 도구</strong>예요. 그래서 <span class="nowrap">Claude Desktop · Claude Code · Codex</span>처럼 내 컴퓨터의 프로그램을 띄울 수 있는 AI에서 동작합니다. 설치를 마쳤다면 대시보드 <code>http://127.0.0.1:4319</code>에서 내 데이터를 확인하세요.
|
|
108
|
+
</p>
|
|
101
109
|
</div>
|
|
102
110
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
<!-- signature element: CareerMate를 설치하는 방식 자체가 "내 AI에게 한 문장" — 그 순간을 보여준다.
|
|
112
|
+
장식적 예시라 aria-hidden; 실제 복사 가능한 안내는 #install에 맥락과 함께 있다. -->
|
|
113
|
+
<aside class="hero__demo" aria-hidden="true">
|
|
114
|
+
<div class="chat">
|
|
115
|
+
<div class="chat__head">
|
|
116
|
+
<span class="chat__dot"></span>
|
|
117
|
+
내 AI 앱
|
|
118
|
+
</div>
|
|
119
|
+
<div class="chat__msg chat__msg--me">
|
|
120
|
+
<span class="chat__who">나</span>
|
|
121
|
+
<p>careermate.life/llms-install.txt 읽고, 이 폴더에 CareerMate 설치하고 연결해줘.</p>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="chat__msg chat__msg--ai">
|
|
124
|
+
<span class="chat__who">AI</span>
|
|
125
|
+
<p>설치했어요. 이제 이력서를 주거나 공고를 붙여넣어 보세요.</p>
|
|
126
|
+
<ul class="chat__steps">
|
|
127
|
+
<li>Node 확인 후 이 폴더에 설치</li>
|
|
128
|
+
<li>데이터는 <code>.cm/data</code>에만 저장</li>
|
|
129
|
+
<li>대시보드 <code>127.0.0.1:4319</code> 열림</li>
|
|
130
|
+
</ul>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
<p class="hero__demo-note">내 AI 앱 대화창에 붙여넣으면 끝 — 터미널이 없어도 돼요.</p>
|
|
134
|
+
</aside>
|
|
107
135
|
</header>
|
|
108
136
|
|
|
109
137
|
<!-- ========================================================== how -->
|
|
110
138
|
<section id="how" class="section">
|
|
111
139
|
<div class="section__head">
|
|
112
|
-
<
|
|
113
|
-
<
|
|
114
|
-
<p>CareerMate 안에는 AI가 들어 있지 않습니다.<br />생각하는 일은 당신의 AI가, 데이터 보관은 CareerMate가 맡습니다.</p>
|
|
140
|
+
<h2>당신의 AI가 두뇌, CareerMate는 커리어 서랍장</h2>
|
|
141
|
+
<p>CareerMate 안에는 AI가 들어 있지 않습니다. 생각하는 일은 당신의 AI가, 데이터 보관은 CareerMate가 맡습니다.</p>
|
|
115
142
|
</div>
|
|
116
143
|
<div class="cards-3">
|
|
117
144
|
<article class="feature">
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
<h3>1. 당신의 AI와 대화</h3>
|
|
122
|
-
<p>평소 쓰던 Claude에게 말로 시키면 됩니다.<br />분석·글쓰기 같은 “생각”은 전부 당신의 AI가 합니다.</p>
|
|
145
|
+
<span class="feature__no">01</span>
|
|
146
|
+
<h3>당신의 AI와 대화</h3>
|
|
147
|
+
<p>평소 쓰던 Claude에게 말로 시키면 됩니다. 분석·글쓰기 같은 “생각”은 전부 당신의 AI가 합니다.</p>
|
|
123
148
|
</article>
|
|
124
149
|
<article class="feature">
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
<h3>2. 안전하게 연결</h3>
|
|
129
|
-
<p>표준 연결 방식(MCP)이 AI와 CareerMate를 잇는 다리가 됩니다.<br />AI가 당신의 커리어 기록을 직접 읽고 정리해 저장합니다.</p>
|
|
150
|
+
<span class="feature__no">02</span>
|
|
151
|
+
<h3>안전하게 연결</h3>
|
|
152
|
+
<p>표준 연결 방식(MCP)이 AI와 CareerMate를 잇는 다리가 됩니다. AI가 당신의 커리어 기록을 직접 읽고 정리해 저장합니다.</p>
|
|
130
153
|
</article>
|
|
131
154
|
<article class="feature">
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
</
|
|
135
|
-
<h3>3. 이 컴퓨터에 저장</h3>
|
|
136
|
-
<p>모든 데이터는 로컬 SQLite(<code>~/.careermate</code>)에만 저장됩니다.<br />외부 서버로 전송하지 않습니다. 대시보드로 눈으로 확인하세요.</p>
|
|
155
|
+
<span class="feature__no">03</span>
|
|
156
|
+
<h3>이 컴퓨터에 저장</h3>
|
|
157
|
+
<p>모든 데이터는 로컬 SQLite(<code>~/.careermate</code>)에만 저장됩니다. 외부 서버로 전송하지 않고, 대시보드에서 눈으로 볼 수 있습니다.</p>
|
|
137
158
|
</article>
|
|
138
159
|
</div>
|
|
139
160
|
</section>
|
|
@@ -141,8 +162,7 @@
|
|
|
141
162
|
<!-- ====================================================== features -->
|
|
142
163
|
<section id="features" class="section">
|
|
143
164
|
<div class="section__head">
|
|
144
|
-
<
|
|
145
|
-
<h2>지원 한 건을 <span class="accent">끝까지</span> 함께 처리</h2>
|
|
165
|
+
<h2>지원 한 건을 끝까지 함께 처리</h2>
|
|
146
166
|
<p>프로필 정리부터 면접 준비까지, AI와 대화만으로 이어집니다.</p>
|
|
147
167
|
</div>
|
|
148
168
|
<div class="checks">
|
|
@@ -157,9 +177,8 @@
|
|
|
157
177
|
|
|
158
178
|
<!-- ======================================================= preview -->
|
|
159
179
|
<section id="preview" class="section">
|
|
160
|
-
<div class="section__head">
|
|
161
|
-
<
|
|
162
|
-
<h2>내 데이터를 <span class="accent">눈으로</span> 확인</h2>
|
|
180
|
+
<div class="section__head section__head--center">
|
|
181
|
+
<h2>내 데이터를 눈으로 확인</h2>
|
|
163
182
|
<p>모든 기록은 이 컴퓨터의 대시보드(<code>127.0.0.1:4319</code>)에 모입니다.<br>아래는 실제 화면 — 설치 없이 바로 둘러볼 수 있어요.</p>
|
|
164
183
|
<div class="section__cta">
|
|
165
184
|
<a class="btn btn--primary" href="demo/">데모 둘러보기 →</a>
|
|
@@ -268,9 +287,8 @@
|
|
|
268
287
|
|
|
269
288
|
<!-- ======================================================= install -->
|
|
270
289
|
<section id="install" class="section">
|
|
271
|
-
<div class="section__head">
|
|
272
|
-
<
|
|
273
|
-
<h2>내 <span class="accent">AI 앱</span>에 연결하기</h2>
|
|
290
|
+
<div class="section__head section__head--center">
|
|
291
|
+
<h2>내 AI 앱에 연결하기</h2>
|
|
274
292
|
<p>빈 폴더 잡고 <strong>한 문장이면 끝.</strong><br />
|
|
275
293
|
터미널이 익숙하면 한 줄 설치, 싫으면 파일 하나로 — <strong>무료도 있습니다.</strong></p>
|
|
276
294
|
</div>
|
|
@@ -455,6 +473,9 @@
|
|
|
455
473
|
<li><strong>내보내기</strong> 자기소개서 등을 <code>~/.careermate/exports</code>로</li>
|
|
456
474
|
<li><strong>삭제·관리</strong> 대시보드 <strong>설정(Settings)</strong>에서 직접</li>
|
|
457
475
|
</ul>
|
|
476
|
+
<p class="privacy-card__note">
|
|
477
|
+
위 내용은 <strong>설치하는 앱</strong> 이야기예요. 지금 보고 계신 <strong>이 소개 웹사이트</strong>는 방문 통계를 보려고 쿠키 없는 익명 분석(Vercel Analytics)만 사용하며, 여기엔 어떤 커리어 데이터도 포함되지 않습니다.
|
|
478
|
+
</p>
|
|
458
479
|
</div>
|
|
459
480
|
</div>
|
|
460
481
|
</section>
|
package/dist/install-page/og.png
CHANGED
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
3
|
+
<url>
|
|
4
|
+
<loc>https://careermate.life/</loc>
|
|
5
|
+
<lastmod>2026-06-17</lastmod>
|
|
6
|
+
<changefreq>weekly</changefreq>
|
|
7
|
+
<priority>1.0</priority>
|
|
8
|
+
</url>
|
|
9
|
+
<url>
|
|
10
|
+
<loc>https://careermate.life/start</loc>
|
|
11
|
+
<lastmod>2026-06-17</lastmod>
|
|
12
|
+
<changefreq>monthly</changefreq>
|
|
13
|
+
<priority>0.8</priority>
|
|
14
|
+
</url>
|
|
15
|
+
<url>
|
|
16
|
+
<loc>https://careermate.life/demo</loc>
|
|
17
|
+
<lastmod>2026-06-17</lastmod>
|
|
18
|
+
<changefreq>monthly</changefreq>
|
|
19
|
+
<priority>0.6</priority>
|
|
20
|
+
</url>
|
|
21
|
+
</urlset>
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
<meta name="theme-color" content="#14130f" media="(prefers-color-scheme: dark)" />
|
|
20
20
|
<link rel="preload" href="fonts/PretendardVariable.woff2" as="font" type="font/woff2" crossorigin />
|
|
21
21
|
<link rel="stylesheet" href="style.css" />
|
|
22
|
+
<!-- Privacy-friendly analytics for the marketing site only (never the local 127.0.0.1 app). -->
|
|
23
|
+
<script src="/analytics.js" defer></script>
|
|
22
24
|
<style>
|
|
23
25
|
/* 선택형 위저드 — start.html 전용. style.css 토큰 재사용. */
|
|
24
26
|
.wizard { max-width: 760px; margin: 0 auto; }
|
|
@@ -70,13 +72,14 @@
|
|
|
70
72
|
</nav>
|
|
71
73
|
|
|
72
74
|
<main id="top">
|
|
73
|
-
<header class="hero">
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
<header class="hero hero--solo">
|
|
76
|
+
<div class="hero__main">
|
|
77
|
+
<span class="pill-badge"><span class="pill-badge__dot" aria-hidden="true"></span> 처음이세요?</span>
|
|
78
|
+
<h1 class="hero__title">터미널이 뭔지 몰라도 괜찮아요</h1>
|
|
79
|
+
<p class="hero__lede">
|
|
80
|
+
<strong>쓰는 AI</strong>와 <strong>컴퓨터</strong>만 고르면, 당신에게 맞는 설치 길 <strong>하나</strong>를 처음부터 알려드립니다.
|
|
81
|
+
</p>
|
|
82
|
+
</div>
|
|
80
83
|
</header>
|
|
81
84
|
|
|
82
85
|
<section class="section" style="padding-top:0">
|
|
@@ -112,7 +115,7 @@
|
|
|
112
115
|
<!-- ===== Claude 유료 → Code 탭 ===== -->
|
|
113
116
|
<div class="path" data-sub="claude">
|
|
114
117
|
<span class="path__tag">당신에겐 — Claude "Code" 탭</span>
|
|
115
|
-
<h2>Claude 데스크톱 앱의
|
|
118
|
+
<h2>Claude 데스크톱 앱의 Code 탭으로</h2>
|
|
116
119
|
<p>이미 Claude를 구독 중이라 추가 비용 없이 가장 매끄럽습니다.<br />앱 안에서 끝나 별도 터미널이 필요 없습니다.</p>
|
|
117
120
|
<ol class="steps">
|
|
118
121
|
<li class="step"><div class="step__no">1</div><div class="step__body">
|
|
@@ -147,7 +150,7 @@
|
|
|
147
150
|
<!-- ===== ChatGPT 유료 → Codex CLI ===== -->
|
|
148
151
|
<div class="path" data-sub="chatgpt">
|
|
149
152
|
<span class="path__tag">당신에겐 — Codex CLI</span>
|
|
150
|
-
<h2>ChatGPT 구독으로
|
|
153
|
+
<h2>ChatGPT 구독으로 Codex에서</h2>
|
|
151
154
|
<p>ChatGPT는 <strong>Codex를 터미널(CLI)에서</strong> 씁니다 — 명령을 몇 줄 입력합니다.<br />Codex <strong>데스크톱 앱은 등록이 사라질 수 있어</strong> 권장하지 않습니다. 터미널이 부담되면 <a href="#" data-goto-free>터미널 없이 가능한 무료 길</a>도 있습니다.</p>
|
|
152
155
|
<ol class="steps">
|
|
153
156
|
<li class="step"><div class="step__no">1</div><div class="step__body">
|
|
@@ -182,7 +185,7 @@
|
|
|
182
185
|
<!-- ===== 무료/없음 → .mcpb 1순위, Antigravity 2순위 ===== -->
|
|
183
186
|
<div class="path" data-sub="free">
|
|
184
187
|
<span class="path__tag">당신에겐 — 무료로 시작</span>
|
|
185
|
-
<h2>유료 구독 없이
|
|
188
|
+
<h2>유료 구독 없이 무료로</h2>
|
|
186
189
|
<p>유료 구독이 없어도 됩니다. 터미널이 필요 없는, 가장 쉬운 길부터 안내합니다.</p>
|
|
187
190
|
|
|
188
191
|
<div class="subcard">
|
|
@@ -183,34 +183,42 @@ code { font-family: var(--mono); }
|
|
|
183
183
|
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
|
184
184
|
|
|
185
185
|
/* ----------------------------------------------------------------- hero */
|
|
186
|
-
/*
|
|
186
|
+
/* Asymmetric two columns: headline + CTAs on the left, the "한 문장" install
|
|
187
|
+
demo (the signature element) on the right. Left-aligned, not centered.
|
|
188
|
+
Stacks to one column on narrow screens. */
|
|
187
189
|
.hero {
|
|
188
|
-
max-width:
|
|
190
|
+
max-width: var(--maxw); margin: 0 auto; padding: 72px 24px 8px;
|
|
191
|
+
display: grid; grid-template-columns: 1.02fr 0.98fr; gap: 52px; align-items: start;
|
|
189
192
|
}
|
|
193
|
+
.hero__main { min-width: 0; }
|
|
194
|
+
/* solo variant (start.html): no demo column — one left-aligned column */
|
|
195
|
+
.hero--solo { grid-template-columns: 1fr; max-width: 760px; }
|
|
190
196
|
/* gentle staggered entrance on load */
|
|
191
197
|
@keyframes riseIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
|
|
192
|
-
.
|
|
198
|
+
.hero__main > *, .hero__demo { animation: riseIn .55s cubic-bezier(.22,.61,.36,1) both; }
|
|
193
199
|
.hero__title { animation-delay: .04s; }
|
|
194
200
|
.hero__lede { animation-delay: .10s; }
|
|
195
201
|
.hero__cta { animation-delay: .18s; }
|
|
196
202
|
.hero__note { animation-delay: .24s; }
|
|
203
|
+
.hero__demo { animation-delay: .16s; }
|
|
197
204
|
.pill-badge {
|
|
198
205
|
display: inline-flex; align-items: center; gap: 8px;
|
|
199
206
|
padding: 5px 13px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
|
|
200
207
|
color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-border);
|
|
201
208
|
}
|
|
202
209
|
.pill-badge__dot { width: 6px; height: 6px; border-radius: 999px; background: var(--accent); }
|
|
203
|
-
|
|
210
|
+
/* heavy display weight + tight tracking — strong contrast against the 400 lede */
|
|
211
|
+
.hero__title { font-size: clamp(2.15rem, 4.6vw, 3.1rem); font-weight: 800; margin: 20px 0 0; letter-spacing: -0.035em; line-height: 1.1; }
|
|
204
212
|
.hero__lede {
|
|
205
|
-
font-size: clamp(
|
|
206
|
-
margin: 18px
|
|
213
|
+
font-size: clamp(1.02rem, 1.7vw, 1.18rem); color: var(--text-secondary);
|
|
214
|
+
margin: 18px 0 0; max-width: 34rem; line-height: 1.6;
|
|
207
215
|
}
|
|
208
216
|
.hero__lede strong { color: var(--text); font-weight: 650; }
|
|
209
217
|
|
|
210
218
|
/* trust strip — the four anxiety answers, scannable, restrained (accent only on the ✓) */
|
|
211
219
|
.trust-strip {
|
|
212
|
-
list-style: none; margin:
|
|
213
|
-
display: flex; flex-wrap: wrap;
|
|
220
|
+
list-style: none; margin: 20px 0 0; padding: 0; max-width: 38rem;
|
|
221
|
+
display: flex; flex-wrap: wrap; gap: 8px;
|
|
214
222
|
}
|
|
215
223
|
.trust-strip li {
|
|
216
224
|
display: inline-flex; align-items: center; gap: 6px;
|
|
@@ -221,50 +229,71 @@ code { font-family: var(--mono); }
|
|
|
221
229
|
.trust-strip li::before { content: "✓"; color: var(--accent); font-weight: 700; }
|
|
222
230
|
|
|
223
231
|
/* hero call-to-action — two install paths */
|
|
224
|
-
.hero__cta { margin:
|
|
232
|
+
.hero__cta { margin: 26px 0 0; display: flex; flex-wrap: wrap; gap: 10px; }
|
|
225
233
|
.hero__cta .btn { height: 42px; padding: 0 18px; font-size: 14.5px; }
|
|
226
234
|
|
|
227
235
|
.hero__note {
|
|
228
|
-
margin:
|
|
236
|
+
margin: 20px 0 0; max-width: 36rem; font-size: 12.5px; line-height: 1.65;
|
|
229
237
|
color: var(--text-tertiary);
|
|
230
238
|
}
|
|
231
239
|
.hero__note strong { color: var(--text-secondary); font-weight: 600; }
|
|
232
240
|
.hero__note code { font-family: var(--mono); font-size: .92em; background: var(--bg-sunken); padding: 1px 5px; border-radius: 4px; color: var(--text-secondary); }
|
|
233
241
|
|
|
234
|
-
/*
|
|
235
|
-
|
|
236
|
-
.
|
|
237
|
-
.
|
|
238
|
-
|
|
239
|
-
text-transform: uppercase; color: var(--accent); margin-bottom: 9px;
|
|
240
|
-
}
|
|
241
|
-
.section__head h2 { font-size: clamp(1.4rem, 3vw, 1.9rem); }
|
|
242
|
-
.section__head p { margin-top: 11px; color: var(--text-secondary); font-size: 1rem; }
|
|
243
|
-
.section__cta { margin-top: 20px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
|
|
244
|
-
.section__cta-note { font-size: 13px; color: var(--text-tertiary, var(--text-secondary)); }
|
|
245
|
-
|
|
246
|
-
/* how-it-works */
|
|
247
|
-
.cards-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
|
|
248
|
-
.feature {
|
|
242
|
+
/* signature — the "내 AI에게 한 문장" install demo (the one bold idea on the page).
|
|
243
|
+
nudged down so its top sits around the headline, not the small pill kicker. */
|
|
244
|
+
.hero__demo { min-width: 0; margin-top: 40px; }
|
|
245
|
+
.hero__demo-note { margin: 12px 2px 0; font-size: 12.5px; line-height: 1.55; color: var(--text-tertiary); }
|
|
246
|
+
.chat {
|
|
249
247
|
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
|
|
250
|
-
|
|
248
|
+
box-shadow: var(--shadow-md); overflow: hidden;
|
|
251
249
|
}
|
|
252
|
-
.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
250
|
+
.chat__head {
|
|
251
|
+
display: flex; align-items: center; gap: 8px; padding: 10px 15px;
|
|
252
|
+
font-family: var(--mono); font-size: 12px; color: var(--text-tertiary);
|
|
253
|
+
background: var(--bg-subtle); border-bottom: 1px solid var(--border);
|
|
256
254
|
}
|
|
257
|
-
.
|
|
258
|
-
.
|
|
259
|
-
.
|
|
255
|
+
.chat__dot { width: 8px; height: 8px; border-radius: 999px; background: var(--accent); flex: none; }
|
|
256
|
+
.chat__msg { padding: 15px 16px; }
|
|
257
|
+
.chat__msg + .chat__msg { border-top: 1px solid var(--border); }
|
|
258
|
+
.chat__who { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-tertiary); margin-bottom: 7px; }
|
|
259
|
+
.chat__msg--me p {
|
|
260
|
+
font-family: var(--mono); font-size: 12.5px; line-height: 1.6; color: var(--code-text);
|
|
261
|
+
background: var(--code-bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 11px 13px;
|
|
262
|
+
}
|
|
263
|
+
.chat__msg--ai p { color: var(--text-secondary); font-size: 14px; }
|
|
264
|
+
.chat__steps { list-style: none; margin: 11px 0 0; padding: 0; display: grid; gap: 6px; }
|
|
265
|
+
.chat__steps li { display: flex; gap: 8px; font-size: 12.5px; color: var(--text-secondary); }
|
|
266
|
+
.chat__steps li::before { content: "✓"; color: var(--accent); font-weight: 700; flex: none; }
|
|
267
|
+
.chat__steps code { font-family: var(--mono); font-size: .92em; background: var(--bg-sunken); padding: 1px 5px; border-radius: 4px; color: var(--text); }
|
|
268
|
+
|
|
269
|
+
/* ----------------------------------------------------------------- sections */
|
|
270
|
+
.section { max-width: var(--maxw); margin: 0 auto; padding: 112px 24px 0; scroll-margin-top: 80px; }
|
|
271
|
+
/* left-aligned section heads (centered heads + uppercase eyebrows read as a template) */
|
|
272
|
+
.section__head { max-width: 50rem; margin: 0 0 36px; }
|
|
273
|
+
.section__head h2 { font-size: clamp(1.55rem, 3vw, 2.1rem); font-weight: 750; letter-spacing: -0.02em; }
|
|
274
|
+
.section__head p { margin-top: 12px; color: var(--text-secondary); font-size: 1.02rem; max-width: 42rem; }
|
|
275
|
+
.section__cta { margin-top: 22px; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
|
|
276
|
+
.section__cta-note { font-size: 13px; color: var(--text-tertiary, var(--text-secondary)); }
|
|
277
|
+
/* Centered head for showcase/guide sections whose body is itself centered (the big
|
|
278
|
+
carousel screenshot, the reading-column install guide) — a left head would misalign
|
|
279
|
+
with the centered media below it. Left-aligned heads stay on the content sections above. */
|
|
280
|
+
.section__head--center { text-align: center; margin-left: auto; margin-right: auto; }
|
|
281
|
+
.section__head--center p { margin-left: auto; margin-right: auto; }
|
|
282
|
+
.section__head--center .section__cta { align-items: center; }
|
|
283
|
+
|
|
284
|
+
/* how-it-works — a quiet numbered sequence, not an icon-card grid */
|
|
285
|
+
.cards-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
|
|
286
|
+
.feature { padding-top: 16px; border-top: 1px solid var(--border-strong); }
|
|
287
|
+
.feature__no { display: block; font-family: var(--mono); font-size: 13px; font-weight: 700; letter-spacing: .06em; color: var(--accent); }
|
|
288
|
+
.feature h3 { font-size: 16px; margin: 12px 0 6px; }
|
|
289
|
+
.feature p { color: var(--text-secondary); font-size: 14px; line-height: 1.6; }
|
|
260
290
|
.feature code { font-family: var(--mono); font-size: .85em; background: var(--bg-sunken); padding: 1px 5px; border-radius: 4px; }
|
|
261
291
|
|
|
262
|
-
/*
|
|
263
|
-
.checks { display: grid; grid-template-columns: repeat(2, 1fr); gap:
|
|
292
|
+
/* capability list — hairline rows, not boxes ("use fewer borders") */
|
|
293
|
+
.checks { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 40px; max-width: 880px; margin: 0; }
|
|
264
294
|
.check {
|
|
265
295
|
display: flex; gap: 12px; align-items: flex-start;
|
|
266
|
-
|
|
267
|
-
padding: 15px 17px;
|
|
296
|
+
padding: 16px 0; border-bottom: 1px solid var(--border);
|
|
268
297
|
}
|
|
269
298
|
.check > svg { width: 18px; height: 18px; flex: none; color: var(--accent); margin-top: 1px; }
|
|
270
299
|
.check strong { display: block; font-size: 14.5px; font-weight: 650; }
|
|
@@ -309,9 +338,12 @@ code { font-family: var(--mono); }
|
|
|
309
338
|
:root[data-theme='dark'] .shot__img--dark { display: block; }
|
|
310
339
|
:root:not([data-theme='dark']) .shot__img--light { display: block; }
|
|
311
340
|
|
|
312
|
-
/* prev / next arrows — overlap the frame edges, vertically centred on the
|
|
341
|
+
/* prev / next arrows — overlap the frame edges, vertically centred on the FRAME
|
|
342
|
+
(not the frame+caption). top:0 / bottom:caption-height + margin-block:auto centers
|
|
343
|
+
the arrow within the image area regardless of the responsive frame height — no
|
|
344
|
+
eyeballed percentage. ~36px ≈ figcaption line (13.5px ×1.65) + its 14px margin-top. */
|
|
313
345
|
.carousel__arrow {
|
|
314
|
-
position: absolute; top:
|
|
346
|
+
position: absolute; top: 0; bottom: 36px; margin-block: auto;
|
|
315
347
|
width: 44px; height: 44px; border-radius: 999px; display: grid; place-items: center;
|
|
316
348
|
background: var(--surface); border: 1px solid var(--border-strong); color: var(--text);
|
|
317
349
|
box-shadow: var(--shadow-md); cursor: pointer; z-index: 2;
|
|
@@ -468,6 +500,7 @@ kbd {
|
|
|
468
500
|
.privacy-card__list li { font-size: 13.5px; color: var(--text-secondary); }
|
|
469
501
|
.privacy-card__list strong { color: var(--text); margin-right: 8px; }
|
|
470
502
|
.privacy-card__list code { font-family: var(--mono); font-size: .86em; background: var(--bg-sunken); padding: 1px 6px; border-radius: 4px; color: var(--text); }
|
|
503
|
+
.privacy-card__note { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--border); font-size: 12.5px; color: var(--text-tertiary); line-height: 1.6; }
|
|
471
504
|
|
|
472
505
|
/* footer */
|
|
473
506
|
.foot {
|
|
@@ -495,7 +528,9 @@ kbd {
|
|
|
495
528
|
|
|
496
529
|
/* responsive */
|
|
497
530
|
@media (max-width: 820px) {
|
|
498
|
-
.
|
|
531
|
+
.hero { grid-template-columns: 1fr; gap: 32px; padding-top: 56px; }
|
|
532
|
+
.hero__demo { max-width: 480px; margin-top: 0; }
|
|
533
|
+
.cards-3 { grid-template-columns: 1fr; gap: 24px; }
|
|
499
534
|
.checks { grid-template-columns: 1fr; }
|
|
500
535
|
.trouble { grid-template-columns: 1fr; }
|
|
501
536
|
/* Logo-only brand on mobile frees room to keep the guided wizard ('처음이세요?')
|