/* ==========================================================================
   FutureInfra — 공용 스타일
   토큰의 단일 출처는 저장소 루트 DESIGN.md 다. 여기에 새 색·간격을 즉흥적으로
   만들지 않는다. 필요하면 DESIGN.md 에 토큰을 먼저 추가하고 여기로 가져온다.
   ========================================================================== */

@import url("./pretendard.css");

:root{
  /* --- 표면. 따뜻한 중성색. 파랑 기가 도는 회색을 쓰지 않는다 --- */
  --surface:#fff;
  --surface-subtle:#f7f7f7;
  --surface-sunken:#f0f0f0;
  --surface-warm:#faf9f7;          /* 갤러리 배경 — 순백 위 흰 카드는 사라져 보인다 */
  --surface-inverse:#1a1a1a;

  /* --- 경계 --- */
  --border:#dddddd;
  --border-subtle:#ebebeb;
  --border-strong:#b0b0b0;

  /* --- 글자 (흰 배경 대비비 실측 · AA 4.5:1) --- */
  --text:#222222;                  /* 15.91:1 */
  --text-2:#5e5e5e;                /*  6.48:1 */
  --text-3:#717171;                /*  4.88:1 — 하한 */
  --text-disabled:#b0b0b0;         /*  2.17:1 — 비활성 표시 전용 */
  --on-brand:#fff;

  /* --- 브랜드 --- */
  --brand:#e11d48;                 /*  4.70:1 — 버튼 */
  --brand-hover:#c2264b;
  --brand-ink:#9f1239;             /*  8.02:1 — 본문 링크 */
  --brand-subtle:#fff1f2;
  --accent:#0e7c86;

  /* --- 의미 --- */
  --ok:#067647;      --ok-bg:#ecfdf3;
  --warn:#b54708;    --warn-bg:#fffaeb;
  --danger:#b42318;  --danger-bg:#fef3f2;

  /* --- 모서리 --- */
  --r-sm:8px; --r-md:12px; --r-lg:16px; --r-xl:24px; --r-full:999px;

  /* --- 그림자. 평소엔 없고 떠 있음을 알릴 때만 --- */
  --e-raised:0 2px 4px rgba(0,0,0,.06);
  --e-hover:0 6px 16px rgba(0,0,0,.12);
  --e-overlay:0 8px 28px rgba(0,0,0,.14);
  --e-modal:0 24px 48px rgba(0,0,0,.18);

  /* --- 간격. 4px 배수만 --- */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s6:24px;
  --s8:32px; --s10:40px; --s12:48px; --s16:64px; --s20:80px; --s24:96px;

  --wrap:1120px;
  --ease:cubic-bezier(.2,.8,.3,1);
}

/* --- 다크 --- */
:root[data-theme="dark"]{
  --surface:#0f1115;
  --surface-subtle:#171a21;
  --surface-sunken:#1e222b;
  --surface-warm:#141720;
  --surface-inverse:#000;
  --border:#2a2f3a;
  --border-subtle:#22262f;
  --border-strong:#3a4150;
  --text:#e6e8ec;
  --text-2:#a8aeb8;
  --text-3:#8b93a1;
  --text-disabled:#5a616c;
  --brand:#ff5c7a;
  --brand-hover:#ff7a92;
  --brand-ink:#ff8fa3;
  --brand-subtle:#2a1720;
  /* 어두운 배경에서 검은 그림자는 보이지 않는다. 깊이는 표면 밝기로 만든다. */
  --e-raised:none;
  --e-hover:0 6px 16px rgba(0,0,0,.5);
  --e-overlay:0 8px 28px rgba(0,0,0,.6);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--surface);
  color:var(--text);
  font-family:"Pretendard Variable",Pretendard,-apple-system,"Segoe UI",system-ui,sans-serif;
  font-size:16px;
  line-height:1.75;
  -webkit-font-smoothing:antialiased;
  /* ★ 한국어에서 가장 중요한 두 줄.
     keep-all 이 없으면 한글이 어절 중간에서 끊긴다.
     break-word 는 긴 URL 이 레이아웃을 밀지 않게 하는 안전판. */
  word-break:keep-all;
  overflow-wrap:break-word;
}

a{color:inherit;text-decoration:none}
p{margin:0 0 var(--s4)}
img{max-width:100%;height:auto;display:block}
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* ★ hidden 을 걸었는데 그대로 보이던 사고(2026-08-11).
 *
 *   로그인한 사람에게도 "로그인" 버튼이 계속 떴다. 스크립트는 제대로
 *   `hidden = true` 를 걸고 있었다 — 그런데 `.btn{display:flex}` 처럼
 *   display 를 **명시한** 규칙은 브라우저 기본값인 `[hidden]{display:none}`
 *   보다 우선순위가 높아서 조용히 이긴다.
 *
 *   JS 는 맞고 CSS 가 어긋난 종류라 콘솔에 오류 하나 안 남고, 코드를 읽어도
 *   틀린 데가 없어 보인다. 그래서 규칙 한 줄로 못 박는다. */
[hidden]{display:none !important}

/* 키보드로만 다니는 사람에게 현재 위치를 알려준다. 마우스 클릭에는 안 뜬다. */
:focus-visible{outline:2px solid var(--brand);outline-offset:3px;border-radius:4px}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--s6)}
.nowrap{white-space:nowrap}
.tnum{font-variant-numeric:tabular-nums}

/* ==================== 타이포 ==================== */
/* 제목은 크게가 아니라 굵게. 큰 글씨는 화려하지만 신뢰감을 주지 않는다. */
h1,h2,h3,h4{margin:0;font-weight:700;letter-spacing:-.02em;line-height:1.35}
h1{font-size:clamp(30px,4.5vw,48px);line-height:1.25;letter-spacing:-.025em}
h2{font-size:clamp(22px,2.6vw,32px)}
h3{font-size:18px;font-weight:600;letter-spacing:-.01em;line-height:1.45}

.lead{font-size:17px;color:var(--text-2);max-width:34em}
.sub{color:var(--text-2);font-size:15px;margin:var(--s2) 0 var(--s8)}
.caption{font-size:13px;color:var(--text-3);line-height:1.5}
.prose{max-width:34em}   /* 68자. 이보다 길면 눈이 줄을 놓친다 */

.eyebrow{
  display:inline-block;font-size:13px;font-weight:600;
  color:var(--brand-ink);background:var(--brand-subtle);
  padding:5px 12px;border-radius:var(--r-full);margin-bottom:var(--s4);
}

/* ==================== 헤더 ==================== */
header{
  position:sticky;top:0;z-index:30;
  background:color-mix(in srgb,var(--surface) 90%,transparent);
  backdrop-filter:blur(12px);
  border-bottom:1px solid transparent;
  transition:border-color .2s,box-shadow .2s;
}
/* 처음부터 떠 있으면 상단이 무겁다. 스크롤했을 때만 경계가 생긴다. */
header.scrolled{border-bottom-color:var(--border);box-shadow:var(--e-raised)}
header .wrap{display:flex;align-items:center;justify-content:space-between;height:68px;gap:var(--s6)}
.brand{font-weight:800;font-size:18px;letter-spacing:-.03em}
.nav{display:flex;gap:var(--s6);align-items:center;font-size:15px;color:var(--text-2)}
.nav a{transition:color .15s}
.nav a:hover{color:var(--text)}
.nav .on{color:var(--text);font-weight:600}

/* 로그인·콘솔은 "읽을 것"이 아니라 "누를 것"이다. 링크와 같은 간격으로
   늘어놓으면 메뉴가 다섯 개로 읽힌다. 둘을 한 덩어리로 묶어 서로는 붙이고,
   마지막 링크(문서)와는 확실히 떼어 놓는다. */
.nav-actions{display:flex;align-items:center;gap:var(--s2);margin-left:var(--s4)}

/* 헤더 버튼만 낮춘다. .btn 의 48px 은 본문 CTA 기준이라 그대로 두면 헤더가
   본문 버튼과 같은 무게로 서서 시선을 먼저 가져간다. 헤더는 안내지 행동이
   아니다. 40px 은 터치 최소치(≈40)를 지키는 하한선이라 더는 못 줄인다.

   ★ min-width 로 둘을 같은 폭에 맞춘다 — "콘솔"은 두 글자, "로그인"은 세
     글자라 좌우 여백만 같게 주면 콘솔이 눈에 띄게 작아 보인다. 나란히 붙여
     둔 두 버튼의 폭이 다르면 그 자체가 흠으로 읽힌다. */
.nav-actions .btn{min-height:40px;padding:0 var(--s4);min-width:92px}

/* 로그인한 사람의 이메일. 헤더는 안내라 버튼보다 조용해야 하므로 muted 로 둔다.
   긴 주소가 헤더를 밀지 않게 잘라낸다 — 누구인지 알아볼 정도면 충분하다. */
.nav-user{color:var(--muted);font-size:13px;max-width:200px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
@media(max-width:820px){.nav-user{max-width:120px}}
@media(max-width:820px){.nav .hide-sm{display:none}.nav-actions{margin-left:0}}

/* ==================== 버튼 ==================== */
/* Primary 는 페이지당 하나. 그 하나가 우리가 원하는 행동이다. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  min-height:48px;padding:0 var(--s6);
  background:var(--brand);color:var(--on-brand);
  border:0;border-radius:var(--r-sm);
  font-family:inherit;font-size:15px;font-weight:600;line-height:1;
  cursor:pointer;transition:background .15s,transform .15s var(--ease),box-shadow .15s;
}
.btn:hover{background:var(--brand-hover);transform:translateY(-1px);box-shadow:var(--e-raised)}
.btn:active{transform:translateY(0)}

/* 회색 테두리가 아니라 검정. Airbnb 계열의 특징적인 대비다. */
.btn.ghost{background:var(--surface);color:var(--text);border:1px solid var(--text)}
.btn.ghost:hover{background:var(--surface-subtle)}
.btn.quiet{background:transparent;color:var(--text-2);border:1px solid var(--border)}
.btn.quiet:hover{background:var(--surface-subtle);color:var(--text)}
.btn.sm{min-height:38px;padding:0 var(--s4);font-size:14px}

.link{color:var(--brand-ink);font-weight:600}
.link:hover{text-decoration:underline;text-underline-offset:3px}

/* ==================== 섹션 ==================== */
/* 흰색 → 따뜻한 회색 → 흰색으로 번갈아 깔아 선 없이 덩어리를 나눈다. */
section{padding:var(--s20) 0}
section.alt{background:var(--surface-subtle)}
section.warm{background:var(--surface-warm)}
@media(max-width:820px){section{padding:var(--s12) 0}}

.hero{padding:var(--s24) 0 var(--s16);text-align:center}
.hero .lead{margin:0 auto var(--s8)}
.hero .cta{display:flex;gap:var(--s3);justify-content:center;flex-wrap:wrap}
@media(max-width:820px){.hero{padding:var(--s16) 0 var(--s12)}}

/* AI 에이전트로 건네는 첫 동작. 명령어처럼 한 덩어리로 보여야
   "복사해서 채팅에 붙여넣는 것"임을 설명 없이도 알아볼 수 있다. */
.ai-handoff{max-width:820px;margin:0 auto var(--s6);text-align:left}
.ai-handoff-label{
  display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);
  margin:0 var(--s1) var(--s2);font-size:13px;color:var(--text-3);
}
.ai-handoff-label strong{color:var(--text);font-size:14px;font-weight:600}
.ai-handoff-bar{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--s3);
  padding:var(--s4);background:var(--surface-inverse);color:var(--on-brand);
  border:1px solid var(--border-strong);border-radius:var(--r-md);
}
.ai-handoff-mark{
  align-self:start;color:var(--brand);font:600 20px/1.6 "JetBrains Mono","SF Mono",Consolas,monospace;
  -webkit-user-select:none;user-select:none;
}
.ai-handoff-text{
  font-family:"JetBrains Mono","SF Mono",Consolas,monospace;
  font-size:13px;line-height:1.65;color:var(--on-brand);overflow-wrap:anywhere;
}
.ai-handoff-copy{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);align-self:center;
  min-height:48px;padding:0 var(--s4);
  border:1px solid var(--border-strong);border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--on-brand) 10%,transparent);color:var(--on-brand);
  font-family:inherit;font-size:13px;font-weight:600;line-height:1;
  cursor:pointer;transition:background .15s,border-color .15s;
}
.ai-handoff-copy:hover{
  background:color-mix(in srgb,var(--on-brand) 20%,transparent);
  border-color:var(--on-brand);
}
.ai-handoff-copy .ico{width:18px;height:18px}
.ai-handoff>p{margin:var(--s2) var(--s1) 0;color:var(--text-3);font-size:13px;line-height:1.5}

@media(max-width:640px){
  .ai-handoff{margin-bottom:var(--s6)}
  .ai-handoff-label{align-items:flex-start;flex-direction:column;gap:0}
  .ai-handoff-bar{grid-template-columns:auto minmax(0,1fr);padding:var(--s3)}
  .ai-handoff-mark{line-height:1.5}
  .ai-handoff-text{font-size:12.5px;line-height:1.6}
  .ai-handoff-copy{grid-column:1/-1;width:100%}
}

/* ==================== 그리드 · 카드 ==================== */
.grid{display:grid;gap:var(--s6)}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
@media(max-width:1000px){.g3,.g4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.g2,.g3,.g4{grid-template-columns:1fr}}

/* 평소 평면 + 테두리. 그림자는 "만질 수 있다"는 신호로만 쓴다. */
.card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-md);padding:var(--s6);
  transition:border-color .2s,transform .2s var(--ease),box-shadow .2s;
}
a.card:hover{border-color:var(--text);transform:translateY(-2px);box-shadow:var(--e-hover)}
.card h3{margin-bottom:var(--s2)}
.card p{margin:0;color:var(--text-2);font-size:14px;line-height:1.7}
.card .more{display:inline-block;margin-top:var(--s4);color:var(--brand-ink);font-size:14px;font-weight:600}

/* 아이콘 — 선 아이콘, 둥근 끝. 색은 상속해 테마 전환에서 깨지지 않는다. */
.ico{width:24px;height:24px;stroke:currentColor;fill:none;
     stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.card .ico{color:var(--brand);margin-bottom:var(--s3)}

/* ==================== 표 ==================== */
.tablewrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface)}
table{width:100%;border-collapse:collapse;font-size:15px;min-width:560px}
th,td{padding:14px var(--s4);text-align:left;border-bottom:1px solid var(--border-subtle);white-space:nowrap}
th{color:var(--text-3);font-weight:600;font-size:13px;background:var(--surface-subtle)}
tr:last-child td{border-bottom:0}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
td strong{font-weight:600}

/* ==================== 코드 ==================== */
pre{
  background:var(--surface-inverse);color:#e6e8ec;
  border-radius:var(--r-md);padding:var(--s6);
  overflow-x:auto;font-size:13.5px;line-height:1.65;margin:0;
}
code{font-family:"JetBrains Mono","SF Mono",Consolas,"D2Coding",monospace}
.inline{background:var(--surface-sunken);color:var(--text);padding:2px 6px;border-radius:5px;font-size:14px}

/* ==================== 안내 박스 ==================== */
.note{background:var(--brand-subtle);border:1px solid color-mix(in srgb,var(--brand) 25%,transparent);
      border-radius:var(--r-sm);padding:14px var(--s4);font-size:14.5px;color:var(--brand-ink)}
.note.warn{background:var(--warn-bg);border-color:color-mix(in srgb,var(--warn) 28%,transparent);color:var(--warn)}
.note.ok{background:var(--ok-bg);border-color:color-mix(in srgb,var(--ok) 28%,transparent);color:var(--ok)}

/* ==================== 목록 ==================== */
ul.check{list-style:none;padding:0;margin:0}
ul.check li{position:relative;padding-left:28px;margin-bottom:var(--s3);color:var(--text-2);font-size:15px}
ul.check li::before{
  content:"";position:absolute;left:0;top:.6em;width:14px;height:8px;
  border-left:2px solid var(--ok);border-bottom:2px solid var(--ok);
  transform:rotate(-45deg);border-radius:1px;
}
ul.check li b,ul.check li strong{color:var(--text)}

/* ==================== 뱃지 ==================== */
.badge{display:inline-flex;align-items:center;gap:6px;
       background:var(--surface-subtle);color:var(--text-2);
       padding:4px 10px;border-radius:var(--r-full);font-size:13px;font-weight:500}
.badge.brand{background:var(--brand-subtle);color:var(--brand-ink)}
.badge.ok{background:var(--ok-bg);color:var(--ok)}
/* 상태는 색만으로 전달하지 않는다 — 점 + 글자를 함께 쓴다 */
.badge .dot{width:6px;height:6px;border-radius:50%;background:currentColor}

/* ==================== 신뢰 밴드 ==================== */
.trust{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s6);margin:0;
       padding:var(--s10) 0;border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.trust div{text-align:center}
.trust dt{font-size:13px;color:var(--text-3);margin-bottom:6px}
.trust dd{margin:0;font-size:20px;font-weight:700;letter-spacing:-.02em}
@media(max-width:820px){.trust{grid-template-columns:repeat(2,1fr);gap:var(--s8)}}

/* ==================== 약관 등 긴 글 ==================== */
.legal{max-width:760px}
.legal h2{font-size:19px;margin:var(--s10) 0 var(--s3);padding-top:var(--s6);border-top:1px solid var(--border)}
.legal h2:first-of-type{border-top:0;padding-top:0;margin-top:var(--s2)}
.legal ol,.legal ul{padding-left:22px;margin:0 0 var(--s4)}
.legal ol>li{margin-bottom:10px}
.legal ul li{margin-bottom:6px;color:var(--text-2)}
.legal ol>li>ul{margin-top:var(--s2)}
.legal .tablewrap{margin:var(--s4) 0}
.legal th{white-space:nowrap;vertical-align:top}
.legal td{white-space:normal}

/* ==================== 푸터 ==================== */
footer{border-top:1px solid var(--border);padding:var(--s16) 0 var(--s12);
       background:var(--surface-subtle);color:var(--text-3);font-size:14px}
footer .cols{display:flex;gap:var(--s16);flex-wrap:wrap;margin-bottom:var(--s10)}
footer h4{color:var(--text);font-size:14px;margin:0 0 var(--s3)}
footer a{display:block;margin-bottom:8px;color:var(--text-2)}
footer a:hover{color:var(--text)}
.bizinfo{line-height:1.9;font-size:13px;color:var(--text-3)}
.bizinfo a{display:inline;text-decoration:underline}

/* ==================== 모션 ==================== */
/* 전정기관 장애가 있는 분에게 모션은 실제 어지럼증을 유발한다. 선택이 아니라 필수. */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;
                       scroll-behavior:auto!important}
}

/* ==================== 앱 카드 (갤러리) ==================== */
/* 테두리도 그림자도 없다. 썸네일이 이미 경계 역할을 하고,
   테두리를 두르면 갤러리가 표처럼 보인다. */
.appcard{display:block}
.appcard .thumb{
  aspect-ratio:16/10;border-radius:var(--r-md);overflow:hidden;
  /* brand-subtle 위 text-3 은 4.44:1 로 AA 미달이라 배경을 웜블러시로 낮추고
     글자를 한 단계 진하게(text-2) 올렸다. */
  background:linear-gradient(135deg,var(--grad-warm),var(--surface-warm));
  display:grid;place-items:center;
  transition:transform .3s var(--ease);
}
/* hover 는 이미지만 확대. 카드 전체를 띄우면 그리드가 출렁인다. */
.appcard:hover .thumb{transform:scale(1.03)}
.appcard .thumb span{font-weight:700;color:var(--text-2);font-size:15px}
.apphead{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);margin-top:var(--s3)}
.apphead h3{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.appdesc{margin:4px 0 0;color:var(--text-2);font-size:14px;
         overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.appby{margin:6px 0 0;font-size:13px;color:var(--text-3)}

/* ==================== 디자인 스펙 페이지 전용 ==================== */
.swatches{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:var(--s3)}
.sw{display:flex;gap:var(--s3);align-items:center;background:var(--surface);
    border:1px solid var(--border);border-radius:var(--r-sm);padding:10px}
.sw-chip{width:44px;height:44px;border-radius:var(--r-sm);border:1px solid var(--border);flex:none}
.sw-meta{display:flex;flex-direction:column;gap:1px;font-size:12.5px;min-width:0}
.sw-meta b{font-size:13.5px}
.sw-meta code{color:var(--text-3);font-size:11.5px}
.sw-meta em{color:var(--text-3);font-style:normal;font-size:11.5px}
.sw-meta .pass{color:var(--ok);font-weight:600;font-size:11.5px}
.sw-meta .fail{color:var(--danger);font-weight:600;font-size:11.5px}

.specrow{display:flex;gap:var(--s6);align-items:baseline;padding:var(--s4) 0;
         border-bottom:1px solid var(--border-subtle)}
.speclabel{flex:none;width:96px;font-size:12px;color:var(--text-3);line-height:1.5}
.speclabel code{font-size:11px}

.scalerow{display:flex;align-items:center;gap:var(--s3);margin-bottom:10px;font-size:13px}
.scalerow code{width:52px;color:var(--text-3);font-size:12px;flex:none}
.scalerow i{height:20px;background:var(--brand);border-radius:3px;display:block}
.scalerow .rbox{width:44px;height:44px;background:var(--surface);
                border:1px solid var(--border-strong)}
.scalerow span{color:var(--text-3)}

/* --- 좌측 정렬 히어로 --- */
/* 기본 히어로는 가운데 정렬이라 .lead 에 margin auto 가 걸려 있다.
   좌측 정렬로 쓸 때는 그 auto 를 풀어야 제목과 왼쪽 선이 맞는다. */
.hero.left{text-align:left}
.hero.left .lead{margin-left:0;margin-right:0}
.hero.left .cta{justify-content:flex-start}

/* --- 코드 복사 버튼 --- */
.has-copy{position:relative}
.copybtn{
  position:absolute;top:10px;right:10px;z-index:1;
  background:rgba(255,255,255,.1);color:#e6e8ec;
  border:1px solid rgba(255,255,255,.2);border-radius:6px;
  padding:5px 10px;font-family:inherit;font-size:12px;font-weight:500;
  cursor:pointer;transition:background .15s;
}
.copybtn:hover{background:rgba(255,255,255,.2)}

/* ==================== 콘솔 미리보기 ==================== */
/* 실제 콘솔의 토큰을 그대로 써서 그린 축소판. 스크린샷 대신 HTML 이라
   확대해도 흐리지 않고, 콘솔 색이 바뀌면 여기도 같이 바뀐다. */
.console-mock{
  border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;
  box-shadow:var(--e-overlay);margin-bottom:var(--s16);background:#0f1115;
}
.cm-bar{display:flex;align-items:center;gap:6px;padding:10px 14px;
        background:#171a21;border-bottom:1px solid #2a2f3a}
.cm-bar i{width:10px;height:10px;border-radius:50%;background:#2a2f3a}
.cm-bar span{margin-left:12px;font-size:12px;color:#8b93a1}
.cm-body{display:flex;min-height:236px}
.cm-side{width:150px;flex:none;padding:16px 12px;border-right:1px solid #2a2f3a;
         display:flex;flex-direction:column;gap:2px}
.cm-side b{color:#e6e8ec;font-size:13px;margin-bottom:10px}
.cm-side span{color:#8b93a1;font-size:12.5px;padding:7px 10px;border-radius:8px}
.cm-side .on{color:#e6e8ec;background:#1e222b;font-weight:600}
.cm-main{flex:1;padding:16px;min-width:0}
.cm-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}
.cm-head b{color:#e6e8ec;font-size:14px}
.cm-head em{background:#ff5c7a;color:#fff;font-style:normal;font-size:11.5px;
            font-weight:600;padding:6px 12px;border-radius:8px}
.cm-row{display:flex;justify-content:space-between;align-items:center;gap:12px;
        border:1px solid #2a2f3a;border-radius:12px;padding:10px 12px;margin-bottom:8px}
.cm-row b{color:#e6e8ec;font-size:13px;margin-right:8px}
.cm-row p{margin:4px 0 0;color:#8b93a1;font-size:11.5px;
          overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cm-row em{font-style:normal;font-size:11.5px;color:#e6e8ec;flex:none;
           border:1px solid #2a2f3a;border-radius:8px;padding:6px 12px}
.cm-pill{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:600;
         padding:2px 8px;border-radius:999px}
.cm-pill i{width:5px;height:5px;border-radius:50%;background:currentColor}
.cm-pill.ok{color:#35c48a;background:rgba(53,196,138,.14)}
.cm-pill.off{color:#8b93a1;background:rgba(139,147,161,.14)}
@media(max-width:640px){.cm-side{display:none}}

/* ==================== 요금 계산기 ==================== */
/* 이 사이트의 시그니처. 분당 과금의 가치는 숫자로 보여주지 않으면 전달되지 않는다. */
.calc{
  display:grid;grid-template-columns:1fr 280px;gap:var(--s8);
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg);box-shadow:var(--e-overlay);padding:var(--s8);
}
@media(max-width:820px){.calc{grid-template-columns:1fr;gap:var(--s6);padding:var(--s6)}}
.calc-controls{display:flex;flex-direction:column;gap:var(--s6);min-width:0}
.calc-field{display:flex;flex-direction:column;gap:var(--s2)}
.calc-field>span{font-size:14px;font-weight:600}
.calc-field>span b{color:var(--brand-ink)}
.calc select{
  height:48px;padding:0 var(--s3);font-family:inherit;font-size:15px;
  background:var(--surface);color:var(--text);
  border:1px solid var(--border-strong);border-radius:var(--r-sm);
}
.calc input[type=range]{width:100%;accent-color:var(--brand);height:24px}
.calc-check{display:flex;align-items:center;gap:var(--s2);font-size:14px;cursor:pointer}
.calc-check input{width:18px;height:18px;accent-color:var(--brand)}
.calc-check em{font-style:normal;color:var(--text-3);font-size:13px}
.calc-out{
  background:var(--surface-subtle);border-radius:var(--r-md);
  padding:var(--s6);display:flex;flex-direction:column;justify-content:center;text-align:center;
}
.calc-out>span{font-size:13px;color:var(--text-3)}
.calc-out strong{display:block;font-size:34px;font-weight:800;letter-spacing:-.03em;margin:6px 0}
.calc-out em{font-style:normal;font-size:13px;color:var(--text-2);line-height:1.6}

/* ==================== 시작 3단계 ==================== */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s8)}
@media(max-width:820px){.steps{grid-template-columns:1fr;gap:var(--s6)}}
.steps>div>b{
  display:inline-grid;place-items:center;width:36px;height:36px;
  background:var(--brand);color:#fff;border-radius:50%;
  font-size:15px;font-weight:700;margin-bottom:var(--s3);
}
.steps h3{margin-bottom:6px}
.steps p{margin:0;color:var(--text-2);font-size:14.5px}

/* ==================== FAQ ==================== */
.faq details{border-bottom:1px solid var(--border);padding:var(--s4) 0}
.faq summary{
  cursor:pointer;font-size:16px;font-weight:600;list-style:none;
  display:flex;justify-content:space-between;align-items:center;gap:var(--s4);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--text-3);font-size:22px;font-weight:400;flex:none}
.faq details[open] summary::after{content:"−"}
.faq details p{margin:var(--s3) 0 0;color:var(--text-2);font-size:15px}

/* ==================== 터미널 ==================== */
/* 코드 블록은 "붙여넣을 것", 터미널은 "일어난 일". 그래서 복사 버튼을 붙이지
   않는다(data-nocopy) — 출력까지 복사되면 붙여넣을 수 없는 텍스트가 된다. */
.term{
  background:var(--surface-inverse);border-radius:var(--r-md);
  padding:var(--s6);font-family:"JetBrains Mono","SF Mono",Consolas,monospace;
  font-size:13.5px;line-height:1.9;color:#c9cdd4;overflow-x:auto;
}
.term b{color:var(--brand);font-weight:400;-webkit-user-select:none;user-select:none}
.term .ok{color:#7ee2b8}
.term .dim{color:#6b7280}
.term .out{color:#e6e8ec}
.term a{color:#7ee2b8;text-decoration:underline;text-underline-offset:3px}

/* ==================== 플레이그라운드 ==================== */
.pg{display:grid;grid-template-columns:1fr 300px;gap:var(--s6);align-items:start}
@media(max-width:1000px){.pg{grid-template-columns:1fr}}

.pg-main{border:1px solid var(--border);border-radius:var(--r-lg);
         background:var(--surface);overflow:hidden}
.pg-modelbar{display:flex;gap:var(--s2);padding:var(--s3);border-bottom:1px solid var(--border)}
.pg-modelbar input,.pg-modelbar select{
  height:44px;padding:0 var(--s3);font-family:inherit;font-size:14px;
  background:var(--surface);color:var(--text);
  border:1px solid var(--border-strong);border-radius:var(--r-sm);min-width:0;
}
.pg-modelbar input{flex:0 0 240px}
.pg-modelbar select{flex:1}
@media(max-width:640px){.pg-modelbar{flex-direction:column}.pg-modelbar input{flex:none}}

.pg-chat{min-height:340px;max-height:520px;overflow-y:auto;padding:var(--s6);
         background:var(--surface-subtle)}
.pg-empty{text-align:center;padding:var(--s12) 0;color:var(--text-3)}
.pg-empty p{margin:0 0 var(--s4);font-size:14.5px}
.pg-samples{display:flex;gap:var(--s2);justify-content:center;flex-wrap:wrap}
.pg-samples button{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-full);
  padding:8px 14px;font-family:inherit;font-size:13px;color:var(--text-2);cursor:pointer;
}
.pg-samples button:hover{border-color:var(--text);color:var(--text)}

.pg-msg{margin-bottom:var(--s4)}
.pg-msg b{display:block;font-size:12px;color:var(--text-3);margin-bottom:5px;font-weight:600}
.pg-msg div{background:var(--surface);border:1px solid var(--border);
            border-radius:var(--r-md);padding:var(--s3) var(--s4);
            font-size:15px;line-height:1.75;white-space:pre-wrap}
.pg-msg.user div{background:var(--brand-subtle);border-color:transparent}
.pg-msg.err div{border-color:color-mix(in srgb,var(--danger) 40%,transparent);color:var(--danger)}
.pg-msg.system div{background:var(--warn-bg);border-color:transparent;color:var(--warn)}

.pg-input{display:flex;gap:var(--s2);padding:var(--s3);border-top:1px solid var(--border)}
.pg-input textarea{
  flex:1;min-height:48px;max-height:200px;resize:none;padding:12px var(--s3);
  font-family:inherit;font-size:15px;line-height:1.6;
  background:var(--surface);color:var(--text);
  border:1px solid var(--border-strong);border-radius:var(--r-sm);
}
#pgHint{padding:0 var(--s3) var(--s3);margin:0}

.pg-side{display:flex;flex-direction:column;gap:var(--s4)}
.pg-cost{background:var(--surface);border:1px solid var(--border);
         border-radius:var(--r-md);padding:var(--s4);text-align:center}
.pg-cost>span{font-size:12.5px;color:var(--text-3)}
.pg-cost strong{display:block;font-size:26px;font-weight:800;letter-spacing:-.02em;margin:4px 0}
.pg-cost em{font-style:normal;font-size:12px;color:var(--text-3)}
.pg-field{display:flex;flex-direction:column;gap:6px}
.pg-field label{font-size:13px;font-weight:600}
.pg-field label b{color:var(--brand-ink)}
.pg-field textarea{
  resize:vertical;padding:10px 12px;font-family:inherit;font-size:13.5px;line-height:1.6;
  background:var(--surface);color:var(--text);
  border:1px solid var(--border-strong);border-radius:var(--r-sm);
}
.pg-field input[type=range]{accent-color:var(--brand);width:100%}

.pg-code{margin-top:var(--s6)}
.pg-tabs{display:flex;gap:var(--s1);margin-bottom:var(--s2)}
.pg-tabs button{
  background:transparent;border:0;border-bottom:2px solid transparent;
  padding:8px 12px;font-family:inherit;font-size:13.5px;font-weight:600;
  color:var(--text-3);cursor:pointer;
}
.pg-tabs button.on{color:var(--text);border-bottom-color:var(--brand)}

/* --- 채팅 말풍선 --- */
/* 내 말은 오른쪽, AI 말은 왼쪽. 카카오톡과 같은 규칙이라 라벨 없이도 읽힌다. */
.pg-row{display:flex;flex-direction:column;margin-bottom:var(--s4);max-width:78%}
.pg-row.user{margin-left:auto;align-items:flex-end}
.pg-row.assistant,.pg-row.system{margin-right:auto;align-items:flex-start}
.pg-who{font-size:11.5px;color:var(--text-3);margin-bottom:4px;padding:0 4px}

.pg-bubble{
  padding:11px var(--s4);border-radius:var(--r-lg);
  font-size:15px;line-height:1.75;white-space:pre-wrap;word-break:keep-all;
}
.pg-row.user .pg-bubble{
  background:var(--brand);color:#fff;
  border-bottom-right-radius:var(--r-sm);   /* 꼬리 쪽만 각지게 — 방향이 생긴다 */
}
.pg-row.assistant .pg-bubble{
  background:var(--surface);border:1px solid var(--border);
  border-bottom-left-radius:var(--r-sm);
}
.pg-row.system .pg-bubble{background:var(--warn-bg);color:var(--warn)}
.pg-bubble.err{background:var(--danger-bg);border-color:transparent;color:var(--danger)}
@media(max-width:640px){.pg-row{max-width:90%}}

/* 생성 중 표시. 정적인 "…" 은 멈춘 것처럼 보인다. */
.pg-typing{display:inline-flex;gap:5px;align-items:center;height:22px}
.pg-typing i{width:7px;height:7px;border-radius:50%;background:var(--text-3);
             animation:pgblink 1.2s infinite ease-in-out}
.pg-typing i:nth-child(2){animation-delay:.15s}
.pg-typing i:nth-child(3){animation-delay:.3s}
@keyframes pgblink{0%,60%,100%{opacity:.25;transform:translateY(0)}
                   30%{opacity:1;transform:translateY(-3px)}}

/* ==================== 배경 그라데이션 ==================== */
/* 사진이 준비될 때까지 빈 공간을 메우는 임시 수단이다.
   글로우(요소에서 새어 나오는 빛)와 다르다 — 이건 바탕을 데울 뿐 요소를 띄우지 않는다.

   ★ 가장 진한 지점을 #FFF7F5 로 잡았다. 여기에 캡션(#717171)을 올려도 4.62:1 로
   AA 를 넘긴다. brand-subtle(#FFF1F2)은 4.44 로 미달이라 배경으로 쓰지 않는다. */
:root{
  --grad-warm:#fff7f5;
  --grad-cool:#f7f9fa;
}
:root[data-theme="dark"]{
  /* 어두운 배경에서 같은 세기면 얼룩으로 보인다. 훨씬 약하게. */
  --grad-warm:#1a1620;
  --grad-cool:#141920;
}

/* 히어로 상단의 은은한 번짐. 위에서 아래로 사라진다.
   텍스트가 놓이는 구간에서는 이미 색이 다 빠져 있어 대비가 흔들리지 않는다. */
.hero-bg{position:relative;isolation:isolate}
.hero-bg::before{
  content:"";position:absolute;inset:0 0 auto;height:520px;z-index:-1;
  background:
    radial-gradient(60% 70% at 50% -10%, var(--grad-warm) 0%, transparent 70%),
    radial-gradient(45% 55% at 85% 0%, var(--grad-cool) 0%, transparent 65%);
  pointer-events:none;
}

/* 섹션 바탕. .alt(단색 회색) 대신 쓰는 변형 — 한 페이지에 하나만. */
section.grad{
  background:linear-gradient(180deg, var(--grad-warm) 0%, var(--surface) 100%);
}
section.grad-soft{
  background:linear-gradient(180deg, var(--surface) 0%, var(--surface-warm) 100%);
}

/* 이미지가 없는 자리. 사진이 들어오면 이 규칙째로 사라진다. */
.ph{
  background:linear-gradient(135deg, var(--grad-warm) 0%, var(--surface-warm) 55%, var(--grad-cool) 100%);
  border-radius:var(--r-md);
}

/* ==========================================================================
   로그인 팝업
   페이지를 갈아엎지 않고 그 자리에서 연다. 소개를 읽다 들어가려는 사람에게
   전체 화면 전환은 맥락을 끊는다.
   ========================================================================== */
.modal-open{overflow:hidden}

.modal{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:var(--s4)}
.modal[hidden]{display:none}

.modal-scrim{position:absolute;inset:0;background:rgba(0,0,0,.45);backdrop-filter:blur(2px)}

.modal-card{
  position:relative;width:100%;max-width:400px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg);box-shadow:var(--e-modal);
  padding:var(--s8) var(--s6) var(--s6);
  max-height:calc(100dvh - var(--s8));overflow-y:auto;
  animation:modal-in .18s var(--ease)
}
@keyframes modal-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.modal-card{animation:none}}

.modal-x{
  position:absolute;top:var(--s3);right:var(--s3);
  width:36px;height:36px;display:grid;place-items:center;
  border:0;background:transparent;color:var(--text-3);
  border-radius:var(--r-full);cursor:pointer
}
.modal-x:hover{background:var(--surface-subtle);color:var(--text)}

.modal-card h2{font-size:22px;letter-spacing:-.4px;margin:0}
.modal-sub{color:var(--text-3);font-size:13.5px;margin:var(--s1) 0 var(--s6)}

/* --- 소셜 --- */
.social:not(:empty){margin-bottom:var(--s2)}
.social-btn{
  display:flex;align-items:center;justify-content:center;
  height:48px;margin-bottom:var(--s2);
  border:1px solid;border-radius:var(--r-sm);
  font-size:14px;font-weight:600;text-decoration:none
}
.social-btn:hover{filter:brightness(.97)}
.or{display:flex;align-items:center;gap:var(--s3);margin:var(--s4) 0;
  color:var(--text-3);font-size:12.5px}
.or::before,.or::after{content:"";flex:1;height:1px;background:var(--border-subtle)}

/* --- 폼 --- */
#login-form label{display:block;font-size:12.5px;font-weight:600;
  color:var(--text-2);margin-bottom:var(--s1)}
#login-form input{
  width:100%;height:48px;padding:0 var(--s4);margin-bottom:var(--s4);
  border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--surface);color:var(--text);font-size:15px
}
#login-form input:focus{outline:none;border-color:var(--brand);
  box-shadow:0 0 0 3px var(--brand-subtle)}
#login-form input::placeholder{color:var(--text-disabled)}

.field-2fa{padding:var(--s4);margin-bottom:var(--s4);
  background:var(--surface-subtle);border-radius:var(--r-sm)}
.field-2fa input{margin-bottom:var(--s2);letter-spacing:.18em;font-size:17px}
.field-2fa .hint{color:var(--text-3);font-size:12px;margin:0}

/* 오류는 빨간 글씨만으로 알리지 않는다 — 색을 못 보는 사람에게는 안 보인다.
   옅은 배경 상자로 "여기 문제가 있다"를 형태로도 만든다. */
.form-error{
  background:var(--danger-bg);color:var(--danger);
  border:1px solid color-mix(in srgb,var(--danger) 25%,transparent);
  border-radius:var(--r-sm);padding:var(--s3) var(--s4);
  font-size:13px;margin:0 0 var(--s4)
}
.form-error[hidden]{display:none}

.btn.full{width:100%;justify-content:center;height:48px}
.modal-foot{text-align:center;color:var(--text-3);font-size:13px;margin:var(--s4) 0 0}
.modal-foot a{color:var(--brand-ink);font-weight:600}

@media (max-width:480px){
  .modal{padding:0;place-items:end stretch}
  .modal-card{max-width:none;border-radius:var(--r-lg) var(--r-lg) 0 0;
    max-height:92dvh;animation:sheet-in .2s var(--ease)}
  @keyframes sheet-in{from{transform:translateY(100%)}to{transform:none}}
}

/* ==========================================================================
   모바일 안전장치
   좁은 화면에서 페이지가 통째로 가로로 밀리는 것을 막는다.

   원인은 거의 항상 같다: 그리드/플렉스 아이템의 기본 min-width 는 auto 라서,
   안에 든 코드블록·긴 URL·표가 "이만큼은 있어야 한다"고 우기면 트랙이 컨테이너보다
   커진다. 375px 화면에서 1fr 컬럼이 464px 로 부푸는 식이다. 넘치는 요소만 스크롤
   시키려면 먼저 아이템이 줄어들 수 있어야 한다.
   ========================================================================== */
.grid>*,.pg>*,.calc>*,.steps>*,.trust>*,.has-copy{min-width:0}
pre,table,.has-copy{max-width:100%}

/* 표는 스스로 스크롤한다. 글자를 줄여 우겨넣으면 요금표에서 숫자를 잘못 읽는다. */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.table-scroll>table{min-width:520px}

/* 긴 URL·이메일이 칸을 밀어내지 않게. 한국어 줄바꿈(keep-all)은 그대로 둔다. */
.break-any{overflow-wrap:anywhere}

@media(max-width:640px){
  /* 헤더: 로고 + 로그인 + 콘솔만 남는다. 세 개가 겹치지 않게 여백을 줄인다. */
  header .wrap{gap:var(--s2)}
  .nav{gap:var(--s2)}
  .nav .btn{padding:0 12px;height:40px;font-size:13px}
  .brand{font-size:17px}

  /* 히어로: 데스크톱 크기를 그대로 두면 첫 화면이 제목만으로 꽉 찬다. */
  h1{font-size:30px;line-height:1.25}
  .lead{font-size:15.5px}
  .cta{flex-direction:column;align-items:stretch}
  .cta .btn{width:100%;justify-content:center}

  /* 코드블록: 좌우 여백이 크면 정작 코드가 안 보인다. */
  pre{padding:var(--s4);font-size:12.5px}
  .copybtn{top:6px;right:6px;padding:4px 8px;font-size:11px}
}

/* --- 모바일 입력 --- */
/* iOS Safari 는 글자 16px 미만인 입력칸을 누르면 페이지를 확대한다. 확대되면
   레이아웃이 튀고, 사용자가 손으로 다시 줄여야 한다. 로그인 첫 화면에서
   그런 일이 벌어지면 그 자체로 이탈 사유다. 그래서 모바일에선 16px 이상. */
@media(max-width:640px){
  #login-form input,.pg-modelbar input,input,textarea,select{font-size:16px}

  /* 손가락은 마우스보다 굵다. 최소 44px 을 확보한다. */
  .modal-x{width:44px;height:44px;top:var(--s2);right:var(--s2)}
  .modal-foot{padding:var(--s2) 0}
  .modal-foot a{display:inline-block;padding:var(--s2) 0}
}

/* ==================== 문서 2단 레이아웃 ==================== */
/* 좌측 = 문서 지도 + 이 문서의 목차(sticky), 우측 = 본문.
   문서는 "읽다가 다른 절로 건너뛰는" 매체라 목차가 화면에 붙어 있어야 한다. */
.docs-grid{display:grid;grid-template-columns:230px minmax(0,1fr);gap:var(--s10);align-items:start;padding-bottom:var(--s20)}
.docs-nav{position:sticky;top:84px;display:flex;flex-direction:column;gap:var(--s6)}
.docs-nav h4{font-size:12px;font-weight:600;color:var(--muted);letter-spacing:.04em;margin:0 0 var(--s2)}
.docs-nav nav{display:flex;flex-direction:column}
.docs-nav a{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:8px;
  color:var(--muted);font-size:14px;text-decoration:none}
.docs-nav a:hover{background:var(--surface-subtle);color:var(--text)}
.docs-nav .docs-pages a.on{background:var(--brand-subtle);color:var(--brand);font-weight:600}
.ico-sm{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.75;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.docs-toc a{padding:5px 10px;font-size:13.5px}
/* 본문 섹션 — 페이지 전체용 s20 패딩은 칼럼 안에서 과하다. 구분선으로 절을 나눈다. */
.docs-body section{padding:var(--s10) 0}
.docs-body section+section{border-top:1px solid var(--border)}
.docs-body section:first-child{padding-top:0}
.docs-body section.alt{background:transparent}
.docs-body h2{scroll-margin-top:96px}
@media(max-width:1000px){
  .docs-grid{grid-template-columns:1fr}
  .docs-nav{position:static;flex-direction:column;gap:var(--s4);
    border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s4)}
  .docs-toc{display:none}   /* 좁은 화면에서 목차까지 쌓으면 본문이 한 화면 아래로 밀린다 */
  .docs-nav .docs-pages{flex-direction:row;flex-wrap:wrap;gap:2px}
}

/* ==================== 도메인 검색 ==================== */
.dsearch{max-width:640px;margin:var(--s8) auto 0;text-align:left}
.dsearch-bar{display:flex;align-items:center;gap:10px;background:var(--surface);
  border:1.5px solid var(--border);border-radius:14px;padding:8px 8px 8px 16px;
  transition:border-color .15s,box-shadow .15s}
.dsearch-bar:focus-within{border-color:var(--brand);box-shadow:0 0 0 4px var(--brand-subtle)}
.dsearch-bar .ico{color:var(--muted);flex:none}
.dsearch-bar input{flex:1;min-width:0;border:0;outline:0;background:transparent;
  font-size:17px;font-family:inherit;color:var(--text)}
.dsearch-bar .btn{flex:none}
.dsearch-out{margin-top:var(--s4);border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--surface);overflow:hidden}
.ds-row{display:flex;align-items:center;gap:var(--s4);padding:12px 16px;font-size:15px}
.ds-row+.ds-row{border-top:1px solid var(--border)}
.ds-row b{font-weight:600}
.ds-row .ds-state{font-size:13px;font-weight:600}
.ds-row.ok .ds-state{color:var(--ok)}
.ds-row.no .ds-state{color:var(--muted)}
.ds-row .ds-price{margin-left:auto;text-align:right;font-variant-numeric:tabular-nums}
.ds-row .ds-price em{display:block;font-style:normal;font-size:12px;color:var(--muted)}
.ds-row .btn{flex:none;padding:6px 12px;font-size:13px}
.ds-msg{padding:14px 16px;font-size:14px;color:var(--muted)}
.ds-msg.err{color:var(--warn)}
.ds-head{display:flex;align-items:center;justify-content:flex-end;
  padding:10px 16px;border-bottom:1px solid var(--border);background:var(--surface-2, transparent)}
.ds-toggle{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:600;
  color:var(--muted);cursor:pointer;user-select:none}
.ds-toggle input{accent-color:var(--brand);width:15px;height:15px;cursor:pointer}
.ds-chip{flex:none;font-size:11px;font-weight:600;letter-spacing:.02em;color:var(--muted);
  border:1px solid var(--border);border-radius:999px;padding:2px 9px;text-decoration:none}
.ds-chip:hover{color:var(--ink);border-color:var(--ink)}
.ds-sub{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.ds-badge{flex:none;font-size:11px;font-weight:700;color:#fff;background:var(--ink);
  border-radius:4px;padding:2px 7px}
.ds-more{padding:12px 16px;text-align:center;border-top:1px solid var(--border)}
.ds-more .btn{font-size:13px;padding:8px 16px}
.ds-chip{cursor:pointer;background:transparent}
.ds-modal{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,.45);padding:var(--s4)}
.ds-modal[hidden]{display:none}
.ds-modal-box{width:100%;max-width:520px;max-height:80vh;overflow:auto;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 20px 60px rgba(0,0,0,.25)}
.ds-modal-head{display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  padding:14px 18px;border-bottom:1px solid var(--border);font-size:15px}
.ds-x{border:0;background:transparent;font-size:22px;line-height:1;color:var(--muted);cursor:pointer;padding:2px 6px}
.ds-x:hover{color:var(--ink)}
.ds-modal-body{padding:6px 0}
.ds-whois-table{width:100%;border-collapse:collapse;font-size:14px}
.ds-whois-table th{width:88px;text-align:left;color:var(--muted);font-weight:600;
  padding:9px 18px;vertical-align:top;white-space:nowrap}
.ds-whois-table td{padding:9px 18px 9px 0;word-break:break-all}
.ds-whois-table tr+tr th,.ds-whois-table tr+tr td{border-top:1px solid var(--border)}
.ds-whois-raw{margin:0;padding:14px 18px;font-size:12px;line-height:1.55;white-space:pre-wrap;
  word-break:break-all;color:var(--ink);max-height:56vh;overflow:auto}
.ssl-price{font-size:20px;font-weight:700;margin:var(--s3) 0;font-variant-numeric:tabular-nums}
.ds-old{font-size:.82em;font-weight:500;color:var(--muted);margin-right:6px}
.ds-inq{display:flex;flex-direction:column;gap:12px;padding:4px 18px 16px}
.ds-inq label{display:flex;flex-direction:column;gap:6px;font-size:13px;font-weight:600;color:var(--muted)}
.ds-inq input,.ds-inq textarea{border:1px solid var(--border);border-radius:8px;padding:9px 12px;
  font:inherit;font-size:14px;color:var(--ink);background:var(--surface)}
.ds-inq input:focus,.ds-inq textarea:focus{outline:0;border-color:var(--brand);
  box-shadow:0 0 0 3px var(--brand-subtle)}
.ds-inq .btn{align-self:flex-start}
.tld-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s4);margin-top:var(--s6)}
.tld-card{border:1px solid var(--border);border-radius:var(--r-md);padding:18px 20px;background:var(--surface)}
.tld-card:hover{box-shadow:0 6px 24px rgba(0,0,0,.07)}
.tld-name{font-size:24px;font-weight:800;letter-spacing:-.01em}
.tld-first{margin:10px 0 12px;font-variant-numeric:tabular-nums}
.tld-first b{font-size:22px;font-weight:800}
.tld-first b.sale{color:var(--brand)}
.tld-first .tld-unit{font-size:12px;color:var(--muted);margin-left:5px}
.tld-sub{display:flex;flex-direction:column;gap:3px;font-size:12.5px;color:var(--muted);
  border-top:1px solid var(--border);padding-top:10px;font-variant-numeric:tabular-nums}
@media (max-width:900px){.tld-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:480px){.tld-grid{grid-template-columns:1fr}}
.tpl-tabs{display:flex;flex-wrap:wrap;gap:6px;margin:var(--s6) 0 var(--s4)}
.tpl-tab{border:1px solid var(--border);background:var(--surface);color:var(--muted);
  border-radius:999px;padding:7px 16px;font-size:13px;font-weight:600;cursor:pointer}
.tpl-tab:hover{color:var(--ink)}
.tpl-tab.on{background:var(--ink);color:#fff;border-color:var(--ink)}
.tpl-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4)}
.tpl-card{display:flex;flex-direction:column;border:1px solid var(--border);
  border-radius:var(--r-md);padding:20px;background:var(--surface)}
.tpl-card:hover{box-shadow:0 6px 24px rgba(0,0,0,.07)}
.tpl-head{display:flex;align-items:center;gap:8px}
.tpl-head b{font-size:16px;font-weight:800}
.tpl-badge{font-size:10.5px;font-weight:700;color:var(--muted);border:1px solid var(--border);
  border-radius:5px;padding:1px 6px}
.tpl-tag{font-size:12.5px;font-weight:600;color:var(--brand-ink);margin-top:5px}
.tpl-desc{font-size:12.5px;color:var(--muted);line-height:1.55;margin:8px 0 14px;flex:1}
.tpl-foot{display:flex;align-items:center;gap:12px}
.tpl-foot .btn{font-size:13px;padding:7px 16px}
.tpl-doc{font-size:12px;color:var(--muted);text-decoration:none}
.tpl-doc:hover{color:var(--ink)}
/* 블로그 — 서버가 렌더한 페이지(control-plane/capabilities/blog.js)가 쓴다 */
.post-list{display:flex;flex-direction:column;gap:var(--s4);margin-top:var(--s6)}
.post-card{display:block;border:1px solid var(--border);border-radius:var(--r-md);
  padding:22px 24px;background:var(--surface);text-decoration:none;color:inherit}
.post-card:hover{box-shadow:0 6px 24px rgba(0,0,0,.07)}
.post-card h2{font-size:20px;font-weight:800;margin:0}
.post-card p{font-size:14px;color:var(--muted);margin:8px 0 0;line-height:1.6}
.post-meta{font-size:12.5px;color:var(--muted);margin-top:10px;font-variant-numeric:tabular-nums}
.post{max-width:720px}
.post h1{margin-bottom:6px}
.post h2{font-size:22px;margin:var(--s8) 0 var(--s3)}
.post h3{font-size:18px;margin:var(--s6) 0 var(--s2)}
.post p{font-size:16px;line-height:1.8;margin:var(--s3) 0}
.post ul{margin:var(--s3) 0;padding-left:22px}
.post li{font-size:16px;line-height:1.8}
.post pre{background:var(--surface-2,#f7f7f7);border:1px solid var(--border);
  border-radius:var(--r-sm);padding:14px 16px;overflow-x:auto;font-size:13px}
.post code{font-size:.92em}
.post a{color:var(--brand-ink)}
@media (max-width:900px){.tpl-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.tpl-grid{grid-template-columns:1fr}}
@media(max-width:640px){
  .dsearch-bar{flex-wrap:wrap}
  .ds-row{flex-wrap:wrap}
  .ds-row .ds-price{margin-left:0;width:100%;text-align:left}
}

/* --- 계정 연결 폼(/connect) ---------------------------------------------
   label 과 input 을 그냥 나열해 두면 인라인으로 붙어 "이름[   ]회사[   ]"
   처럼 한 줄에 뭉친다(실측 2026-08-10). 필드마다 세로 스택으로 감싸고 폭을
   맞춘다. */
.authform{display:flex;flex-direction:column;gap:14px}
.authform > [data-register-only]{display:flex;flex-direction:column;gap:14px}
.authform > [data-register-only][hidden]{display:none}
.authfield{display:flex;flex-direction:column;gap:6px}
.authfield label{font-size:13px;font-weight:600;color:var(--text-2)}
.authform input[type=text],
.authform input[type=email],
.authform input[type=password],
.authform input:not([type]){
  width:100%;padding:11px 12px;font-family:inherit;font-size:14.5px;
  background:var(--surface);color:var(--text);
  border:1px solid var(--border-strong);border-radius:var(--r-sm);
}
.authform input:focus-visible{outline:2px solid var(--brand);outline-offset:1px}

/* 동의 — 체크박스를 글과 같은 줄에 두되 줄바꿈 시 들여쓰기가 유지되게 */
.authconsent{display:flex;flex-direction:column;gap:9px;margin-top:2px}
.authcheck{display:flex;align-items:flex-start;gap:9px;font-size:13.5px;line-height:1.5;cursor:pointer}
.authcheck input[type=checkbox]{margin:2px 0 0;width:16px;height:16px;accent-color:var(--brand);flex:none}
.authcheck b{color:var(--brand-ink);font-weight:600}
.authcheck a{text-decoration:underline}

/* 이메일·인증번호처럼 입력 옆에 버튼이 붙는 줄.
   ★ display 를 주는 규칙은 반드시 [hidden] 을 함께 눌러 줘야 한다. hidden 은
     브라우저 기본 스타일의 display:none 으로 동작하는데, 우리 규칙이 그걸
     덮으면 **숨겼다고 생각한 것이 계속 보인다.** 인증번호 칸이 발송 전에
     노출되고 로그인 모드에서도 발송 버튼이 보이는 형태로 실제로 당했다
     (2026-08-10). authfield/authform 쪽도 같은 이유로 함께 막는다. */
.authrow{display:flex;gap:8px;align-items:stretch}
.authrow > input{flex:1;min-width:0}
.authform .authside{flex:none;white-space:nowrap;padding:0 14px;font-size:13.5px}
.authhint{margin:2px 0 0;font-size:12.5px;color:var(--text-3)}
.authhint.ok{color:var(--brand-ink);font-weight:600}
.authhint.bad{color:#c0243c}

/* hidden 우선 — 위 주석의 이유. 개별 규칙마다 반복하지 않고 한 곳에서 못 박는다. */
.authform [hidden],
.authrow [hidden],
.authfield[hidden],
.authconsent[hidden]{display:none !important}

/* --- 계정 연결 탭 -------------------------------------------------------
   활성 표시는 aria-pressed 하나로만 한다. 클래스로도 표시하면 상태가 두 군데에
   있게 되고, 언젠가 한쪽만 바뀌어 "눌렀는데 안 눌린 것처럼 보이는" 화면이 된다. */
.authtabs{display:inline-flex;gap:4px;padding:4px;margin:0 0 20px;
  background:var(--surface-2,#f4f4f5);border-radius:var(--r-sm)}
.authtabs button{
  appearance:none;border:0;background-color:transparent;cursor:pointer;
  padding:9px 18px;border-radius:calc(var(--r-sm) - 2px);
  font-family:inherit;font-size:14px;font-weight:600;color:var(--text-3);
  /* transition 대상을 background-color 로 좁힌다. shorthand 에 거는 것보다
     정확하고, 배경 이미지·위치까지 애니메이션 대상에 넣을 이유가 없다.

     ※ 한동안 "shorthand 가 var 를 막는다"고 적어 뒀는데 그건 오진이었다.
       검증하던 브라우저 창이 숨겨져 있어 페이지가 프레임을 합성하지 않았고,
       transition 은 프레임 단위로 진행되므로 getComputedStyle 이 전환 전 값에
       머물렀던 것이다. CSS 는 처음부터 정상이었다 — 화면이 안 보이는 환경에서
       잰 값으로 코드를 의심하지 말 것. */
  transition:background-color .12s ease,color .12s ease;
}
.authtabs button:hover{color:var(--text)}
.authtabs button[aria-pressed="true"]{background-color:var(--brand);color:#fff}
.authtabs button:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* 발송 버튼은 글자가 바뀌어도 폭이 흔들리지 않아야 한다.
   "인증번호 발송" → "발송 중…" → "인증번호 재발송" 으로 문구가 세 번 바뀌는데,
   폭이 따라 움직이면 옆의 입력칸까지 같이 출렁인다. 가장 긴 문구에 맞춰 고정한다. */
#connect-send-code{min-width:118px}
#connect-verify{min-width:56px}

/* --- 짧은 페이지에서 푸터가 화면 중간에 뜨는 문제 -----------------------
   /connect 처럼 내용이 한 화면보다 짧은 페이지는 푸터가 본문 바로 아래 붙어
   버려서, 그 아래로 빈 배경이 남는다. 본문을 늘려 푸터를 바닥으로 민다.
   내용이 긴 페이지는 flex 가 개입할 여지가 없어 지금과 똑같이 그려진다. */
body{min-height:100dvh;display:flex;flex-direction:column}
body > footer{margin-top:auto}

/* --- 로그인 ↔ 회원가입 전환 폭 줄이기 -----------------------------------
   로그인은 2칸(이메일·비밀번호), 회원가입은 이름·회사·인증번호·동의 3개까지
   붙어 카드 높이가 두 배 넘게 뛴다. 그 순간 화면 전체가 출렁여서 어디를 보던
   중인지 놓치게 된다. 바닥 높이를 잡아 두면 늘어나는 폭이 그만큼 줄고,
   전환도 눈으로 따라갈 수 있는 속도로 움직인다. */
.authcard{min-height:404px;transition:min-height .18s ease}
.authform{transition:opacity .12s ease}
@media (prefers-reduced-motion:reduce){
  .authcard,.authform{transition:none}
}
