/* 로그인 · 내 계정 화면.
 *
 * app.css의 종이/잉크 토큰(--paper, --ink, --orange)을 그대로 쓰되, 공급자
 * 버튼만은 각 브랜드 가이드가 지정한 값을 그대로 박는다. 사이트 테마에 맞춰
 * 색을 손대면 두 가이드 모두 위반이다.
 *
 * 공급자 버튼 규격 근거:
 *   구글 Branding guidelines(Light theme)
 *     - Fill #FFFFFF / Stroke #747775 1px inside / Font #1F1F1F
 *     - 4색 "G" 로고는 크기·색 변경 금지, 흰 배경 위에만
 *     - 제3자 로그인과 "최소한 동등하게 부각" → 네이버 버튼과 크기·형태 동일
 *   네이버 로그인 버튼 사용 가이드
 *     - 지정 컬러 #03C75A 변경 불가, 녹색 배경 완성형 권장
 *     - N 로고 완성형 16px 이상, 레이블과 간격 8px
 *
 * hover에서 배경색 자체를 바꾸지 않고 반투명 오버레이를 덮는 이유: 두 가이드가
 * 지정 컬러 변경을 금지하므로, 상태 피드백은 덮어서 표현한다.
 */

/* ------------------------------------------------------------------ */
/* 로그인                                                              */
/* ------------------------------------------------------------------ */

.auth-main {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    width: var(--container);
    margin: 0 auto;
    padding: clamp(2rem, 6vw, 4.5rem) 0 clamp(3rem, 8vw, 6rem);
}

.auth-card {
    width: 100%;
    max-width: 26rem;
    padding: clamp(1.5rem, 4vw, 2.25rem);
    border: 1px solid var(--line);
    border-radius: 0.25rem;
    background: var(--paper-strong);
    box-shadow: var(--shadow);
}

.auth-card__head {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.75rem;
}

.auth-card__title {
    margin: 0;
    font-size: clamp(1.35rem, 3.5vw, 1.6rem);
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--ink);
}

.auth-card__lede {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--ink-soft);
}

/* flex를 쓰지 않는다. 본문에 <strong>이 섞이면 그 하나하나가 별개 flex 항목이
   되어 문장이 여러 칸으로 쪼개진다(초대 화면에서 실제로 깨졌다). 아이콘만
   띄우고 본문은 평범한 인라인 흐름으로 둔다 — 어떤 마크업이 와도 안 깨진다. */
.auth-alert {
    display: block;
    margin: 1.25rem 0 0;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--danger);
    border-radius: 0.25rem;
    background: rgba(168, 59, 48, 0.07);
    color: var(--danger);
    font-size: 0.82rem;
    line-height: 1.5;
}

.auth-alert > i:first-child {
    float: left;
    margin: 0.15rem 0.5rem 0 0;
}

/* 두 버튼을 같은 폭·같은 간격으로 세로 배치. 구글 가이드의 "동등한 부각"
   요구를 레이아웃에서 보장한다. */
.auth-providers {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 1.5rem;
}

/* 공통 규격 — 두 공급자 버튼이 완전히 같은 기하를 갖게 한다. */
.oauth-btn {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px; /* 네이버 가이드: 로고-레이블 간격 8px */
    box-sizing: border-box;
    width: 100%;
    min-height: 3rem;
    padding: 0 1rem;
    border-radius: 0.25rem;
    font-family: var(--sans);
    font-size: 0.94rem;
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: -0.01em;
    text-decoration: none;
    overflow: hidden;
    transition: box-shadow 160ms ease, transform 160ms ease;
}

/* hover/active 피드백은 지정 컬러를 건드리지 않는 오버레이로만 표현한다. */
.oauth-btn::after {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity 160ms ease;
    pointer-events: none;
}

.oauth-btn:hover::after { opacity: 0.06; }
.oauth-btn:active::after { opacity: 0.12; }

.oauth-btn:active { transform: translateY(1px); }

.oauth-btn:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

.oauth-btn__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

.oauth-btn__label {
    position: relative;
    z-index: 1;
}

/* 구글 — Light theme. Fill #FFFFFF, Stroke #747775 1px inside, Font #1F1F1F.
   stroke는 "inside"라 box-sizing:border-box + border로 구현한다. */
.oauth-btn--google {
    border: 1px solid #747775;
    background: #ffffff;
    color: #1f1f1f;
}

/* 네이버 — 지정 컬러 #03C75A. 변경 금지. */
.oauth-btn--naver {
    border: 1px solid #03c75a;
    background: #03c75a;
    color: #ffffff;
}

.auth-note {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 1.5rem 0 0;
    padding: 0.7rem 0.85rem;
    border: 1px dashed var(--line);
    border-radius: 0.25rem;
    background: var(--paper-muted);
    color: var(--ink-soft);
    font-size: 0.8rem;
    line-height: 1.55;
}

.auth-note i { margin-top: 0.15rem; color: var(--success); }

.auth-consent {
    margin: 1rem 0 0;
    font-size: 0.76rem;
    line-height: 1.6;
    color: var(--ink-soft);
}

.auth-consent a { color: var(--ink); text-decoration: underline; }

/* ------------------------------------------------------------------ */
/* 내 계정                                                             */
/* ------------------------------------------------------------------ */

.account-main {
    width: min(100% - 2rem, 56rem);
    margin: 0 auto;
    padding: clamp(1.75rem, 5vw, 3rem) 0 clamp(3rem, 8vw, 6rem);
}

/* API 관리만 넓게 쓴다.
   프로필·택배사 키 화면은 읽는 화면이라 56rem(읽기 폭)이 맞지만, 여기 API 키
   표는 8열이라 실제로 920px 안팎을 요구한다. 56rem(896px) 안에 가두면 1440px
   짜리 데스크톱에서도 '폐기' 버튼이 잘려 가로로 밀어야 보인다. */
.account-main--wide { width: min(100% - 2rem, 72rem); }

.account-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
}

.account-head__title {
    margin: 0;
    font-size: clamp(1.5rem, 4vw, 1.9rem);
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--ink);
}

.account-head__logout { margin: 0; }

/* 카드에 들어가지 않는 화면 설명문. 카드로 감싸면 "설정할 것이 하나 더
   있다"처럼 보이는데, 실제로는 아래 카드들을 읽는 방법을 알려 줄 뿐이다. */
.account-lede {
    max-width: 62ch;
    margin: -0.4rem 0 1.5rem;
    font-size: 0.86rem;
    line-height: 1.65;
    color: var(--ink-soft);
}

/* 한글은 ch 기준으로 폭을 재면 영문보다 훨씬 일찍 줄이 바뀐다.
   택배사 키 안내는 짧은 두 문단이므로 화면의 읽기 폭을 고르게 쓴다. */
.account-lede--full { max-width: none; }

/* 본문 한가운데에 굵은 오렌지 링크가 끼면 문장이 거기서 끊긴다. 다른 화면으로
   보내는 안내는 문단 아래 한 줄로 떼어 놓는다. */
.account-lede__aside {
    display: block;
    margin-top: 0.5rem;
    font-size: 0.8rem;
}

.account-lede a,
.account-card__lede a,
.account-card__hint a {
    color: var(--orange-deep);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

/* 프로필에서 나머지 계정 화면으로 가는 길.
   내비게이션의 계정 메뉴와 같은 목적지지만, 메뉴는 닫아 두면 보이지 않는다.
   여기서는 각 화면이 무엇을 하는 곳인지까지 한 줄로 밝힌다. */
.account-links {
    display: grid;
    gap: 0.6rem;
    margin: 0 0 1.25rem;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.account-link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--line);
    border-radius: 0.25rem;
    background: var(--paper-strong);
    color: var(--ink);
    text-decoration: none;
    transition: border-color 150ms ease, background 150ms ease;
}

.account-link:hover {
    border-color: var(--orange);
    background: var(--orange-wash);
}

.account-link:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 2px;
}

.account-link__icon {
    display: inline-grid;
    flex: 0 0 auto;
    width: 2.15rem;
    aspect-ratio: 1;
    place-items: center;
    border-radius: 0.25rem;
    background: var(--paper-muted);
    color: var(--ink-soft);
    font-size: 0.86rem;
}

.account-link:hover .account-link__icon {
    background: var(--orange);
    color: #fffdf8;
}

.account-link__text {
    display: flex;
    min-width: 0;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.15rem;
}

.account-link__text strong {
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.account-link__text > span {
    color: var(--ink-soft);
    font-size: 0.76rem;
    line-height: 1.4;
}

.account-link__go {
    flex: 0 0 auto;
    color: var(--ink-soft);
    font-size: 0.75rem;
    opacity: 0.6;
}

@media (prefers-reduced-motion: reduce) {
    .account-link,
    .account-link__icon { transition: none; }
}

.account-card {
    margin-bottom: 1.25rem;
    padding: clamp(1.15rem, 3vw, 1.75rem);
    border: 1px solid var(--line);
    border-radius: 0.25rem;
    background: var(--paper-strong);
}

.account-card__title {
    margin: 0 0 0.35rem;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--ink);
}

/* 사용량처럼 현재 프로젝트에 따라 뜻이 바뀌는 카드 제목은 이름까지 함께
   보여준다. 긴 사용자 입력이 제목의 위계를 덮지 않도록 한 단계 작게 둔다. */
.account-card__title-context {
    color: var(--ink-soft);
    font-size: 0.82em;
    font-weight: 600;
    letter-spacing: -0.01em;
    overflow-wrap: anywhere;
}

/* 본문에 프로젝트 이름이 그대로 들어간다(최대 60자). 공백 없는 이름은 줄바꿈
   지점이 없어 문단 밖으로 삐져나가고, 그만큼 문서가 가로로 스크롤된다. */
.account-card__lede {
    margin: 0 0 1.15rem;
    font-size: 0.83rem;
    line-height: 1.6;
    color: var(--ink-soft);
    overflow-wrap: anywhere;
}

/* 리드문보다 한 단계 낮은 부연. 숫자 옆에 붙는 "이 값이 왜 이런가" 설명이라
   기본 문단 크기로 렌더되면 본문과 같은 무게로 읽힌다. */
.account-card__hint {
    display: block;
    margin: 0.4rem 0 0;
    font-size: 0.78rem;
    line-height: 1.6;
    color: var(--ink-soft);
    overflow-wrap: anywhere;
}

/* 계정 정보 — 검수용 '제공 정보 활용처' 화면 */
.account-profile { margin: 0.5rem 0 0; }

.account-profile__row {
    display: grid;
    grid-template-columns: 7rem 1fr;
    gap: 0.75rem;
    padding: 0.6rem 0;
    border-top: 1px solid var(--line-soft);
}

.account-profile__row:first-child { border-top: 0; }

.account-profile dt {
    margin: 0;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--ink-soft);
}

.account-profile dd {
    margin: 0;
    font-size: 0.88rem;
    color: var(--ink);
    overflow-wrap: anywhere;
}

/* 로그인 방식 배지 — 텍스트 대신 공급자 로고를 담는다.
 *
 * 구글 G는 "흰 배경 위, 표준 4색, 무변형"이 요구사항이라 배지 자체를 흰색으로
 * 두고 얇은 테두리(#747775, 버튼과 동일)로 형태를 잡는다. 네이버는 지정 컬러
 * #03C75A 위에 흰 N을 올린다. 두 배지의 크기는 같게 유지한다. */
.provider-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 2rem;
    height: 2rem;
    border-radius: 0.25rem;
}

.provider-badge svg { display: block; }

.provider-badge--google {
    border: 1px solid #747775;
    background: #ffffff;
}

.provider-badge--naver {
    border: 1px solid #03c75a;
    background: #03c75a;
}

/* API 키 발급 */
/* 점선은 "여기 비었다"는 뜻으로 쓴다(.key-empty). 입력 폼까지 점선이면
   빈 상태와 나란히 놓였을 때 둘 다 자리표시자처럼 보인다. */
.key-create {
    margin: 0 0 1.25rem;
    padding: 1rem;
    border: 1px solid var(--line-soft);
    border-radius: 0.35rem;
    background: var(--paper-muted);
}

.key-create__label {
    display: block;
    margin-bottom: 0.4rem;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--ink);
}

.key-create__row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.key-create__input {
    flex: 1 1 14rem;
    min-width: 0;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: 0.2rem;
    background: var(--paper-strong);
    color: var(--ink);
    font-family: var(--sans);
    font-size: 0.86rem;
}

.key-create__input:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 1px;
}

.key-create__hint {
    margin: 0.5rem 0 0;
    font-size: 0.76rem;
    color: var(--ink-soft);
}

/* 조회 결과 저장 스위치.
   .checkbox-container / .account-hint 는 템플릿에만 있고 CSS가 없어 기본
   inline으로 흘렀다. 체크박스와 라벨이 설명문 바로 아래 같은 줄 흐름에
   붙어 "이게 눌리는 것인지" 구분되지 않았다. */
.checkbox-container {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.85rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--line-soft);
    border-radius: 0.25rem;
    background: var(--paper-strong);
    color: var(--ink);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}

.checkbox-container input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    flex: 0 0 auto;
    accent-color: var(--orange);
    cursor: pointer;
}

.checkbox-container:has(input:focus-visible) {
    outline: 2px solid var(--orange);
    outline-offset: 1px;
}

.account-hint {
    margin: 0;
    font-size: 0.78rem;
    line-height: 1.55;
    color: var(--ink-soft);
}

/* 박스 맨 위에 오는 설명문일 때 - key-create__hint는 원래 폼 아래 붙는
   작은 보조문구용이라 위쪽 여백이 없다. 여기선 체크박스보다 먼저 오는
   본문이라 아래쪽에 숨 쉴 공간을 주고, 글자 크기도 label과 body 사이로
   올려 "작은 각주"가 아니라 "설명 문단"으로 읽히게 한다. */
.key-create__hint--lede {
    margin: 0 0 0.85rem;
    font-size: 0.82rem;
    line-height: 1.55;
}

/* 발급 직후 1회 노출 패널 */
.key-reveal {
    margin-bottom: 1.25rem;
    padding: 1rem;
    border: 2px solid var(--success);
    border-radius: 0.25rem;
    background: rgba(63, 108, 64, 0.06);
}

.key-reveal__title {
    margin: 0 0 0.3rem;
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--success);
}

.key-reveal__warn,
.key-reveal__note {
    margin: 0 0 0.75rem;
    font-size: 0.8rem;
    line-height: 1.55;
    color: var(--ink-soft);
}

.key-reveal__row {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.key-reveal__value {
    flex: 1 1 18rem;
    min-width: 0;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: 0.2rem;
    background: var(--paper-strong);
    color: var(--ink);
    font-family: var(--mono);
    font-size: 0.82rem;
    overflow-wrap: anywhere;
}

/* 키 목록 */
.key-empty {
    margin: 0;
    padding: 1.25rem;
    border: 1px dashed var(--line);
    border-radius: 0.25rem;
    color: var(--ink-soft);
    font-size: 0.84rem;
    text-align: center;
}

/* 계정 API 키 카드 (/account/courier-keys).
 *
 * 계정 단위로 등록하는 택배사는 지금 DHL 하나뿐이다(courier_config.rs
 * ACCOUNT_API_KEY_COURIERS). 표+별도 입력폼 2단 구성은 행이 하나뿐인 표를
 * 위해 8열 가로스크롤 상자를 띄우는 과잉이었다 — 택배사 하나당 카드 하나로
 * 합쳐서 "지금 등록돼 있나 / 없나"가 카드를 보는 즉시 드러나게 한다.
 * 택배사가 늘어도 카드가 쌓일 뿐 표처럼 좁은 화면에서 잘리지 않는다. */
.courier-key-list {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

/* 이 화면에서는 택배사 카드가 곧 최상위 섹션이라 .account-card와 같은 무게로
   그린다. 카드 안에 카드를 겹쳐 넣으면 테두리만 두 겹 생기고 정보는 늘지 않는다. */
.courier-key-card {
    padding: clamp(1.15rem, 3vw, 1.6rem);
    border: 1px solid var(--line);
    border-left: 3px solid var(--line);
    border-radius: 0.25rem;
    background: var(--paper-strong);
}

/* 등록 여부는 배지(글자)로 이미 말한다. 왼쪽 선은 목록을 훑을 때 "여기는
   끝났고 여기는 남았다"를 배지를 읽기 전에 잡아 주는 두 번째 신호다. */
.courier-key-card--registered {
    border-left-color: var(--success);
}

.courier-key-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}

.courier-key-card__identity {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.courier-key-card__name {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--ink);
}

.courier-key-card__badge {
    padding: 0.15rem 0.5rem;
    border-radius: 1rem;
    background: var(--paper-muted);
    border: 1px solid var(--line-soft);
    color: var(--ink-soft);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.courier-key-card--registered .courier-key-card__badge {
    color: var(--success);
    border-color: var(--success);
    background: rgba(63, 108, 64, 0.08);
}

.courier-key-card__help {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.78rem;
    color: var(--ink-soft);
    white-space: nowrap;
}

.courier-key-card__help:hover { color: var(--orange); }
.courier-key-card__help i { font-size: 0.68rem; }

.courier-key-card__current {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 0.85rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px dashed var(--line-soft);
}

.courier-key-card__current-info {
    display: flex;
    align-items: baseline;
    gap: 0.65rem;
    flex-wrap: wrap;
    min-width: 0;
}

.courier-key-card__date {
    font-size: 0.76rem;
    color: var(--ink-soft);
}

.courier-key-card__usage {
    font-size: 0.76rem;
    color: var(--ink-soft);
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: var(--paper-muted);
}

.courier-key-card__usage--full {
    color: var(--danger);
    background: color-mix(in srgb, var(--danger) 12%, var(--paper-strong));
    font-weight: 600;
}

.courier-key-card__form {
    margin: 0;
}

/* 표는 좁은 화면에서 자기 영역만 가로 스크롤한다(본문은 스크롤되지 않게).
 *
 * position: relative가 필요하다. 표 헤더의 .sr-only(관리 열 레이블)는
 * position:absolute인데, 위치 기준이 되는 조상이 없으면 스크롤 컨테이너를
 * 빠져나가 문서 오른쪽 끝(x≈575px)에 놓인다. 그러면 375px 화면에서 본문
 * 전체가 가로로 밀린다. 기준을 여기로 고정해 스크롤 영역 안에 가둔다. */
/* 8열짜리 표라 좁은 화면에서는 반드시 가로 스크롤이다. 테두리와 오른쪽
   그라데이션이 없으면 "여기서 잘렸다"는 신호가 전혀 없어, 상태·관리 열이
   존재하는지조차 모른다. */
.key-table-wrap {
    position: relative;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--line-soft);
    border-radius: 0.35rem;

    /* 잘린 쪽에만 그림자를 띄운다. 앞의 두 겹은 배경과 같은 색 덮개인데
       `local`이라 내용과 함께 스크롤하고, 뒤의 두 겹은 `scroll`이라 상자에
       붙어 있는다. 스크롤이 끝에 닿으면 덮개가 그림자를 정확히 가리고,
       스크롤할 게 없으면 처음부터 가려져 아무것도 안 보인다.
       (항상 켜 두면 잘리지도 않은 표에 "더 있다"고 거짓말을 하게 된다.) */
    background:
        linear-gradient(to right, var(--paper-strong) 30%, rgba(255, 253, 248, 0)) left / 2rem 100% no-repeat local,
        linear-gradient(to left, var(--paper-strong) 30%, rgba(255, 253, 248, 0)) right / 2rem 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, rgba(31, 41, 36, 0.16), rgba(31, 41, 36, 0)) left / 0.7rem 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, rgba(31, 41, 36, 0.16), rgba(31, 41, 36, 0)) right / 0.7rem 100% no-repeat scroll;
    background-color: var(--paper-strong);
}



.key-table {
    width: 100%;
    /* 8열이라 좁은 화면에서 100%에 맞추려 들면 모든 열이 눌린다. 최소 폭을
       두고 상자(.key-table-wrap)가 스크롤하게 한다. */
    min-width: 46rem;
    border-collapse: collapse;
    font-size: 0.83rem;
}

.key-table th,
.key-table td {
    padding: 0.6rem 0.7rem;
    border-bottom: 1px solid var(--line-soft);
    text-align: left;
    white-space: nowrap;
}

.key-table th {
    padding: 0.6rem 0.7rem;
    background: var(--paper-muted);
    border-bottom: 1px solid var(--line);
    text-align: left;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--ink-soft);
    white-space: nowrap;
}

/* 키 이름은 60자까지 들어온다. 이 열만 줄바꿈을 허용하되 최소 폭을 준다.
   폭 제한만 걸었더니 375px에서 열이 한 글자까지 눌려 "문/서/검/증/용"으로
   세로로 쏟아졌다. 좁으면 열을 짜부라뜨리지 말고 상자를 가로로 스크롤한다. */
.key-table td:first-child {
    white-space: normal;
    min-width: 7rem;
    max-width: 12rem;
    overflow-wrap: anywhere;
}

.key-table td { color: var(--ink); }

.key-row--revoked td { color: var(--ink-soft); }

.key-prefix {
    font-family: var(--mono);
    font-size: 0.8rem;
}

.key-muted { color: var(--ink-soft); }

.key-status {
    display: inline-block;
    padding: 0.12rem 0.45rem;
    border-radius: 0.2rem;
    font-size: 0.74rem;
    font-weight: 700;
}

.key-status--active {
    background: rgba(63, 108, 64, 0.14);
    color: var(--success);
}

.key-status--revoked {
    background: var(--paper-muted);
    color: var(--ink-soft);
}

.key-table__actions { text-align: right; }
.key-table__actions form { margin: 0; }

.key-revoke-btn {
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: 0.18rem;
    background: transparent;
    color: var(--danger);
    font-family: var(--sans);
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}

.key-revoke-btn:hover {
    border-color: var(--danger);
    background: var(--danger);
    color: #fff;
}

.key-revoke-btn:focus-visible {
    outline: 2px solid var(--danger);
    outline-offset: 2px;
}

/* 연동 해제 */
.account-card--danger { border-color: var(--danger); }

.account-card--danger .account-card__title { color: var(--danger); }

.account-danger-btn {
    padding: 0.65rem 1rem;
    border: 1px solid var(--danger);
    border-radius: 0.2rem;
    background: transparent;
    color: var(--danger);
    font-family: var(--sans);
    font-size: 0.84rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    cursor: pointer;
    transition: background 160ms ease, color 160ms ease;
}

.account-danger-btn:hover {
    background: var(--danger);
    color: #fff;
}

.account-danger-btn:focus-visible {
    outline: 2px solid var(--danger);
    outline-offset: 2px;
}

@media (max-width: 640px) {
    .account-profile__row { grid-template-columns: 1fr; gap: 0.2rem; }
}

@media (prefers-reduced-motion: reduce) {
    .oauth-btn,
    .oauth-btn::after,
    .key-revoke-btn,
    .account-danger-btn,
    .site-navigation__account {
        transition: none;
    }
    .oauth-btn:active { transform: none; }
}

/* 사용량 — 한도를 노출하지 않으므로 게이지(비율) 대신 수치만 보여준다. */
/* 값이 "오늘 12건" 두 개뿐이라, 카드 폭(최대 72rem)을 그대로 나눠 가지면
   빈 상자 두 개가 화면 절반씩 차지한다. 상자 폭에 상한을 둬 숫자와 라벨이
   서로 가까이 붙어 있게 한다. */
.usage-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 18rem));
    gap: 0.75rem;
    margin: 0;
}

.usage-cell {
    padding: 0.9rem 1rem;
    border: 1px solid var(--line-soft);
    border-radius: 0.25rem;
    background: var(--paper);
}

.usage-cell dt {
    margin: 0 0 0.25rem;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--ink-soft);
}

.usage-cell dd {
    margin: 0;
    font-size: 0.9rem;
    color: var(--ink);
}

.usage-cell dd strong {
    font-family: var(--mono);
    font-size: 1.45rem;
    font-weight: 700;
}

.usage-cell__meta {
    margin: 0.35rem 0 0;
    font-size: 0.74rem;
    color: var(--ink-soft);
}

/* 폐기된 키를 목록에서 지우는 버튼.
   폐기 버튼과 달리 위험색을 쓰지 않는다 — 이미 죽은 키를 치우는 정리 동작이라
   같은 무게로 보이면 어느 쪽이 되돌릴 수 없는 동작인지 구분이 흐려진다. */
/* 표 행 액션은 한 규격으로. radius가 0.18/0.2/0.25로 갈리면 한 행 안에서
   어긋남이 보인다(devdojo-btn의 0.18rem에 맞춘다). */
.key-delete-btn {
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--line-soft);
    border-radius: 0.18rem;
    background: transparent;
    color: var(--ink-soft);
    font-family: var(--sans);
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}

.key-delete-btn:hover {
    border-color: var(--line);
    background: var(--paper-muted);
    color: var(--ink);
}

.key-delete-btn:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 2px;
}

/* ---------- 확인 토스트 ----------
   브라우저 기본 confirm() 대신 쓴다. 기본 대화상자는 도메인만 보여주고 본문
   서식을 못 넣어서 "무엇이 사라지는지" 설명할 자리가 없는데, 되돌릴 수 없는
   동작에서는 그 설명이 확인 절차의 핵심이다. */

.auth-notice {
    display: block;
    margin: 0 0 1rem;
    padding: 0.7rem 0.95rem;
    border: 1px solid rgba(63, 108, 64, 0.35);
    border-radius: 0.5rem;
    background: rgba(63, 108, 64, 0.1);
    color: var(--success);
    font-size: 0.88rem;
}

.auth-notice > i:first-child {
    float: left;
    margin: 0.2rem 0.5rem 0 0;
}

/* 이 카드 안에서 새 하위 그룹이 시작된다는 걸 옅은 구분선으로도 보여준다.
   전에는 여백만으로 나뉘어 있어, 위 표(예: 사용량)와 아래 표(구성원)가
   같은 성격의 데이터처럼 이어져 보였다. */
.account-subtitle {
    margin: 1.9rem 0 0.6rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--line-soft);
    font-size: 0.95rem;
    letter-spacing: -0.02em;
}

.account-card--invite { border-color: var(--orange); }

.invite-list { margin: 0; padding: 0; list-style: none; }

.invite-list__item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--line-soft);
    font-size: 0.9rem;
}

.invite-list__item:last-child { border-bottom: none; }

.key-create__input--narrow { flex: 0 1 14rem; }

/* 프로젝트 탭.
 *
 * 이 화면의 키·사용량·활동은 전부 "지금 보고 있는 프로젝트" 기준이다. 그래서
 * 맨 위 탭줄이 가리키는 것도 프로젝트여야 한다. 계정 화면(프로필·API 관리·
 * 택배사 키) 사이 이동은 내비게이션의 계정 메뉴가 맡는다.
 *
 * 아래 카드들과 붙어 보이도록 탭줄 자체에 밑선을 깔고, 활성 탭만 그 선을
 * 끊어 카드 쪽으로 이어지게 한다. */
.project-tabs {
    display: flex;
    align-items: stretch;
    margin: 0 0 1.35rem;
    border-bottom: 1px solid var(--line);
}

/* 프로젝트 이름은 사용자가 짓고(최대 60자) 개수도 늘어난다. 줄바꿈으로 접으면
   탭줄 높이가 들쭉날쭉해지므로 가로로 스크롤한다. + 버튼은 스크롤 밖에 두어
   항상 같은 자리에 남는다.

   flex: 0 1 auto라서 탭이 적으면 스크롤 영역도 딱 그만큼만 차지한다. 1 1 auto로
   두면 탭이 셋뿐이어도 이 영역이 컨테이너(최대 72rem) 끝까지 늘어나, + 버튼이
   탭에서 한참 떨어진 오른쪽 끝에 혼자 떠 있게 된다. */
.project-tabs__scroll {
    display: flex;
    flex: 0 1 auto;
    min-width: 0;
    gap: 0.15rem;
    overflow-x: auto;
    scrollbar-width: none;
}

.project-tabs__scroll::-webkit-scrollbar { display: none; }

/* 조회 결과의 프로젝트 탭과 같은 묶음·삭제 버튼 구조를 쓴다. 삭제 버튼은
   app.css의 result-scope__remove 규칙을 공유하므로 두 화면의 동작이 어긋나지 않는다. */
.project-tab__item { min-width: 0; }
.project-tab__remove-form { margin: 0; }
.project-tab__item:has(.result-scope__remove) .project-tab { padding-right: 1.85rem; }

@media (hover: none), (pointer: coarse) {
    .project-tab__item:has(.result-scope__remove) .project-tab { padding-right: 2.1rem; }
}

.project-tab {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 0.45rem;
    max-width: 16rem;
    padding: 0.6rem 0.85rem;
    margin-bottom: -1px;
    border: 1px solid transparent;
    border-bottom: 2px solid transparent;
    border-radius: 0.3rem 0.3rem 0 0;
    color: var(--ink-soft);
    font-size: 0.88rem;
    font-weight: 600;
    letter-spacing: -0.02em;
    text-decoration: none;
    white-space: nowrap;
    transition: color 140ms ease, background 140ms ease;
}

.project-tab__icon { font-size: 0.75rem; opacity: 0.65; }

/* 이름만 잘린다. 아이콘과 권한 배지는 잘리면 뜻이 사라지므로 폭 계산에서 뺀다. */
.project-tab__name {
    overflow: hidden;
    text-overflow: ellipsis;
}

.project-tab:hover {
    background: var(--paper-muted);
    color: var(--ink);
}

.project-tab--active {
    background: var(--paper-strong);
    border-color: var(--line);
    border-bottom-color: var(--orange);
    color: var(--ink);
}

.project-tab--active .project-tab__icon { color: var(--orange); opacity: 1; }

.project-tab:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: -2px;
}

/* 같은 화면 아래 구성원 표의 권한은 .role-badge(배경 있는 알약)로 표시된다.
   여기만 다른 언어를 쓰면 같은 개념(권한)이 화면 안에서 두 모습으로 보인다. */
.project-tab__role {
    padding: 0.05rem 0.35rem;
    border-radius: 0.25rem;
    background: rgba(31, 41, 36, 0.08);
    color: var(--ink-soft);
    font-size: 0.66rem;
    font-weight: 700;
    line-height: 1.6;
}

/* 새 프로젝트 만들기.
 *
 * 탭이 아니라 동작이라 탭 모양(위쪽만 둥근 상자)을 흉내 내지 않는다. 대신
 * 마지막 탭 바로 옆에 붙여 탭 그룹의 일부로 읽히게 하고, 그 사이를 세로
 * 실선으로 끊어 "탭 하나 더"로 오인하지 않게 한다.
 *
 * 점선 테두리는 쓰지 않는다. 이 크기에서 점선은 '누를 것'이 아니라 '아직 안
 * 채운 자리'로 읽힌다. */
.project-tabs__new {
    position: relative;
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    padding-left: 0.4rem;
    margin-left: 0.4rem;
    border-left: 1px solid var(--line-soft);
}

.project-tabs__add {
    display: inline-grid;
    width: 2rem;
    height: 2rem;
    place-items: center;
    border-radius: 0.25rem;
    color: var(--ink-soft);
    font-size: 0.85rem;
    cursor: pointer;
    list-style: none;
    transition: background 140ms ease, color 140ms ease;
}

.project-tabs__add::-webkit-details-marker { display: none; }

.project-tabs__add:hover {
    background: var(--paper-muted);
    color: var(--ink);
}

.project-tabs__new[open] .project-tabs__add {
    background: var(--orange);
    color: #fffdf8;
}

.project-tabs__add:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 1px;
}

/* 버튼이 탭 바로 옆(줄 가운데쯤)에 있으므로 패널은 오른쪽 빈 공간으로 펼친다.
   right:0으로 두면 패널이 버튼 왼쪽에 매달려 어디서 열린 건지 거꾸로 읽힌다.
   좁은 화면에서는 탭이 넘쳐 버튼이 오른쪽 끝에 가므로 그때만 뒤집는다. */
.project-tabs__popover {
    position: absolute;
    z-index: 20;
    top: calc(100% + 0.5rem);
    left: 0;
    width: min(22rem, calc(100vw - 2.5rem));
    padding: 0.9rem 1rem 1rem;
    border: 1px solid var(--line);
    border-radius: 0.35rem;
    background: var(--paper-strong);
    box-shadow: var(--shadow);
}

.project-tabs__popover-title {
    margin: 0 0 0.6rem;
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--ink);
}

.project-tabs__popover-hint {
    margin: 0.6rem 0 0;
    font-size: 0.76rem;
    line-height: 1.55;
    color: var(--ink-soft);
}

@media (max-width: 48rem) {
    .project-tabs__popover { left: auto; right: 0; }
}

/* 표 제목줄. <caption>을 쓰면 min-width:46rem짜리 표 안쪽 요소가 되어 스크롤
   상자 테두리에 여백 없이 붙고, 가로 스크롤할 때 글자까지 같이 밀려 나간다.
   상자 밖에 두면 폭이 카드에 맞고 스크롤과 무관해진다. */
.key-table-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.3rem 1rem;
    margin: 0 0 0.5rem;
}

.key-table-head__counts,
.key-table-head__meta {
    margin: 0;
    font-size: 0.78rem;
    color: var(--ink-soft);
}

.key-table-head__counts strong { color: var(--ink); font-weight: 700; }

.key-table-note {
    margin: 0 0 0.6rem;
    font-size: 0.76rem;
    line-height: 1.55;
    color: var(--ink-soft);
}

/* 멤버 행은 버튼이 둘(소유권 넘기기·내보내기)일 수 있다.
   td에 display:flex를 주면 table-cell이 아니게 되어 열 너비 계산이 무너진다.
   셀은 그대로 두고 안쪽 폼만 inline-block으로 나란히 놓는다. */
.key-table__actions--stack { white-space: nowrap; text-align: right; }

.key-table__actions--stack form {
    display: inline-block;
    margin-left: 0.35rem;
}

.key-table__actions--stack form:first-child { margin-left: 0; }

/* 구성원 이름. 표에서 가장 먼저 읽히는 값이라 무게를 준다. */
.member-name { font-weight: 700; }

.member-you { margin-left: 0.35rem; }

/* 권한 배지. 소유자만 색을 주고 나머지는 조용하게 — 셋 다 색이 다르면
   표가 신호등이 되고 정작 중요한 "누가 소유자인가"가 묻힌다. */
/* 상태 라벨 기하는 한 벌로 맞춘다. 같은 행에 나란히 놓이면 어긋남이 그대로
   보인다(구성원 표의 권한 배지 + "나" 배지). 변형은 색만 바꾼다. */
.role-badge,
.member-you,
.key-status {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 0.3rem;
    background: var(--paper-muted);
    color: var(--ink-soft);
    font-size: 0.74rem;
    font-weight: 700;
    line-height: 1.45;
    white-space: nowrap;
}

.role-badge--owner {
    background: var(--orange-wash);
    color: var(--orange-deep);
}

.role-badge--admin {
    background: rgba(63, 108, 64, 0.12);
    color: var(--success);
}

/* 최근 활동. 표가 아니라 목록으로 둔다 — 행마다 길이가 크게 다르고
   "누가 / 무엇을 / 언제"만 읽히면 되므로 표의 정렬이 오히려 방해된다. */
.activity-list {
    max-height: 24rem;
    margin: 0;
    padding: 0 0.45rem 0 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
    list-style: none;
}

.activity-list:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 0.25rem;
}

.activity-list__item {
    display: grid;
    grid-template-columns: minmax(6rem, auto) 1fr auto;
    gap: 0.75rem;
    align-items: baseline;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--line-soft);
    font-size: 0.88rem;
}

.activity-list__item:last-child { border-bottom: none; }

/* 기록 문구에는 사용자가 지은 키·프로젝트 이름이 그대로 들어간다. grid 아이템
   기본 min-width:auto 라서 공백 없는 긴 이름이면 열이 min-content 폭을 요구해
   카드 밖으로 넘치고 이름 끝이 잘린다. */
.activity-list__who,
.activity-list__what,
.activity-list__when {
    min-width: 0;
    overflow-wrap: anywhere;
}

.activity-list__what { color: var(--ink-soft); }

.activity-list__when {
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--ink-soft);
    white-space: nowrap;
}

/* "이게 전부"로 읽히지 않게 목록 끝에 붙는 잘림 안내. */
.activity-list__more {
    margin: 0.6rem 0 0;
    font-size: 0.8rem;
}

/* 프로젝트 삭제. 전에는 '만들기' 폼 바로 아래 버튼 하나뿐이라 위험한 동작이
   일상적인 동작과 같은 무게로 보였다. account-card--danger와 같은 언어(위험색
   테두리 + 옅은 배경)로 눈에 띄는 구역을 만든다 — 되돌릴 수 없는 동작은
   지나칠 수 없어야 한다. */
.project-danger {
    margin: 1.5rem 0 0;
    padding: 1rem 1.1rem;
    border: 1px solid var(--danger);
    border-radius: 0.35rem;
    background: rgba(168, 59, 48, 0.05);
}

.project-danger__label {
    margin: 0 0 0.35rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--danger);
}

.project-danger__lede {
    margin: 0 0 0.9rem;
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--ink-soft);
}

.project-danger form { margin: 0; }

/* 이 카드 안에 위험 동작이 두 개(결과 삭제·프로젝트 삭제) 같이 들어갈 때,
   버튼끼리 바로 붙지 않도록 둘째 폼부터만 위 여백을 준다. */
.project-danger form + form { margin-top: 0.6rem; }

/* 구성원 표는 4열뿐이라 API 키 표(8열, min-width 46rem) 기준을 그대로 쓰면
   좁은 화면에서 필요 없는 가로 스크롤이 생긴다. 소유권 넘기기·내보내기 두
   버튼이 한 행에 같이 뜨는 행(owner가 다른 소유자 아닌 멤버를 볼 때)만
   폭이 필요한데, 그건 min-width를 늘리는 대신 버튼을 줄바꿈시켜 해결한다. */
.key-table--compact { min-width: 28rem; }

.key-table--compact td:nth-child(2) {
    white-space: normal;
    overflow-wrap: anywhere;
}

.key-table--compact .key-table__actions--stack { white-space: normal; }

/* margin-left(비-첫째 자식 간 간격)는 원래 규칙이 이미 처리한다. 여기서는
   줄바꿈했을 때 위 버튼과 붙지 않도록 margin-top만 더한다. */
.key-table--compact .key-table__actions--stack form { margin-top: 0.25rem; }

.key-table--compact .key-table__actions--stack form:first-child { margin-top: 0; }

@media (max-width: 40rem) {
    .activity-list__item { grid-template-columns: 1fr; gap: 0.15rem; }
}

/* 메일 링크로 들어온 초대. 목록에 여러 건이 있을 때 어느 것 때문에 왔는지
   바로 보여야 한다. */
.invite-list__item--highlight {
    margin: 0 -0.6rem;
    padding-left: 0.6rem;
    padding-right: 0.6rem;
    border-radius: 0.4rem;
    background: var(--orange-wash);
}

/* 초대 착지 화면. 결정 하나만 하는 화면이라 폭을 좁게 잡는다. */
.account-main--narrow { max-width: 34rem; }

.invite-card__eyebrow {
    margin: 0 0 0.35rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--orange-deep);
}

.invite-summary {
    margin: 1.25rem 0 1.5rem;
    padding: 0.9rem 1.05rem;
    border: 1px solid var(--line-soft);
    border-radius: 0.5rem;
    background: var(--paper-muted);
}

.invite-summary__row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.3rem 0;
    font-size: 0.9rem;
}

.invite-summary__row dt { color: var(--ink-soft); }
.invite-summary__row dd { margin: 0; text-align: right; }

/* 프로젝트 섹션 접기. 여러 사람이 함께 관리할 때만 쓰는 기능이라 기본은 닫는다.
   클릭 가능한 줄인데 hover/focus 피드백이 전혀 없었다 — 화살표 방향이 바뀌는
   것 말고는 "여기를 누를 수 있다"는 신호가 없었다. */
.project-details__summary {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: -0.3rem -0.4rem;
    padding: 0.3rem 0.4rem;
    border-radius: 0.3rem;
    cursor: pointer;
    list-style: none;
    transition: background 140ms ease;
}

.project-details__summary:hover { background: var(--paper-muted); }

.project-details__summary:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 2px;
}

.project-details__summary::-webkit-details-marker { display: none; }

.project-details__summary::before {
    content: "▸";
    color: var(--ink-soft);
    transition: transform 140ms ease;
}

.project-details[open] > .project-details__summary::before { content: "▾"; }

/* 접기 제목은 줄이지 않는다. 옆의 힌트(프로젝트 이름)가 길면 flex가 둘을 같이
   짜부라뜨려 '프로젝트'가 한 글자 폭으로 세로로 쏟아졌다. 양보하는 쪽은 힌트다. */
.project-details__summary .account-card__title {
    margin: 0;
    flex: 0 0 auto;
    white-space: nowrap;
}

/* 지금 보고 있는 프로젝트 · 구성원 수 — 칩으로 표시해 "이건 상태값이다"를
   글자색만이 아니라 형태로도 드러낸다. */
.project-details__hint {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    background: var(--paper-muted);
    color: var(--ink-soft);
    font-size: 0.78rem;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.project-details__hint i { color: var(--ink-soft); opacity: 0.75; }

.project-details__hint span {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* 키 값 셀. 기본은 가리고 눈 아이콘으로 연다. */
.key-value-cell { white-space: nowrap; }

.key-reveal-form { display: inline-block; margin-left: 0.3rem; }

.key-peek-btn {
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--line-soft);
    border-radius: 0.18rem;
    background: transparent;
    color: var(--ink-soft);
    cursor: pointer;
}

.key-peek-btn:hover { border-color: var(--line); color: var(--ink); }

.key-prefix--revealed {
    background: var(--orange-wash);
    color: var(--orange-deep);
    font-weight: 600;
}

/* 사용량 카드의 거절 건수(console.tera). 위 usage-grid가 성공한 호출만 세므로,
   한도에 부딪힌 뒤로는 그 숫자가 멈춘다. 얼마나 모자랐는지는 여기서만 보인다. */
.usage-rejected {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.85rem 0 0;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--orange);
    border-radius: 0.25rem;
    background: var(--orange-wash);
    color: var(--ink);
    font-size: 0.82rem;
    line-height: 1.6;
}

.usage-rejected > i { margin-top: 0.15rem; color: var(--orange-deep); }
