/* Cloudflare Static Assets와 OCI fallback이 공유하는 단일 스타일 번들. */

/* --s1..--s8 은 자산 분류 색이며 cats.js 가 이름으로 참조한다. 값만 바꾸고 이름은 유지한다. */
:root {
  color-scheme: light;
  --surface-1: #ffffff;
  --page: #f2f4f6;
  --text-primary: #191f28;
  --text-secondary: #4e5968;
  /* 흰 카드가 아니라 --page 위(홈·관리 부제, 자산 갱신 시각)가 대비의 하한을 정한다. 4.58:1이며
     이보다 밝으면 그 안내문들이 AA에 미달한다. 카드 위에서는 5.05:1이다. */
  --muted: #64707d;
  --grid: #eef0f3;
  --baseline: #d1d6db;
  --border: rgba(25,31,40,0.06);
  /* 면 채움색. 카드가 테두리 없이 배경과의 밝기 차로만 구분되므로 입력칸·보조 버튼·목록 행은
     테두리 대신 이 색으로 위계를 만든다. */
  --fill: #f2f4f6;
  --fill-strong: #e5e8eb;
  --s1: #3182f6; /* 국내주식 */
  --s2: #00b786; /* 미국주식 */
  --s3: #ff9500; /* 암호화폐 */
  --s4: #1da65c; /* 예적금 */
  --s5: #7b61ff; /* 현금 */
  --s6: #f26fa6; /* 채권/단기상품 */
  --s7: #00a5c4; /* 부동산 */
  --s8: #8b95a1; /* 대출 */
  --gain: #d83a46; /* 국내 관례: 수익=빨강. 12.5px 손익 텍스트에 쓰여 4.5:1을 지키는 선까지만 밝힌다 */
  --loss: #1b64da; /* 손실=파랑 */
  --danger: #d8323f;
  /* 액센트는 국내주식 색과 같은 값이지만 역할이 달라 따로 둔다. 차트는 --s1, 버튼·포커스는 --accent만 쓴다.
     토스 원색 #3182f6은 흰 글자 대비가 3.7:1이라 15~16px 굵은 버튼 라벨이 AA에 미달한다.
     버튼 라벨은 18.66px 미만이라 큰 글자 예외를 받지 못하므로 4.5:1을 넘는 선까지 낮춘다. */
  --accent: #2272e8;
  --accent-press: #1b64da;
  /* 흰 배경 위에 놓이는 액센트 글자용. --accent도 4.53:1로 기준을 겨우 넘길 뿐이라 여유가 없다. */
  --accent-text: #1b64da;
  --accent-on: #ffffff; /* 액센트 위 글자색. 다크에서 뒤집힌다 */
  --accent-soft: #e8f3ff;
  --hover: rgba(25,31,40,0.045);
  --r-1: 10px;
  --r-2: 14px;
  --r-3: 20px;
  --r-4: 24px;
  --shadow-1: 0 1px 3px rgba(25,31,40,0.05);
  --shadow-2: 0 6px 24px -6px rgba(25,31,40,0.16), 0 2px 6px rgba(25,31,40,0.05);
  --shadow-3: 0 16px 48px -12px rgba(25,31,40,0.24), 0 4px 12px rgba(25,31,40,0.06);
}

[hidden] { display: none !important; }
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    /* 카드는 테두리 없이 --page보다 밝은 면으로만 구분된다. 두 값의 간격을 좁히면 카드가 사라진다. */
    --surface-1: #212228;
    --page: #17171c;
    --text-primary: #e8eaed;
    --text-secondary: #b0b8c1;
    --muted: #8b95a1;
    --grid: #2b2d34;
    --baseline: #3a3d45;
    --border: rgba(255,255,255,0.08);
    --fill: #2a2c33;
    --fill-strong: #33363e;
    --s1: #4e93f7;
    --s2: #1fcda0;
    --s3: #ffab33;
    --s4: #35c176;
    --s5: #9b85ff;
    --s6: #f78bb8;
    --s7: #2cc0dd;
    --s8: #97a1ad;
    --gain: #ff6b75;
    --loss: #6fa8ff;
    --danger: #ff6b75;
    --accent: #4e93f7;
    --accent-press: #6fa8ff;
    --accent-text: #6fa8ff;
    --accent-on: #10121a; /* 밝은 액센트 위에는 흰 글자가 대비 미달이라 어두운 글자를 쓴다 */
    --accent-soft: rgba(78,147,247,0.16);
    --hover: rgba(255,255,255,0.06);
    --shadow-1: 0 1px 3px rgba(0,0,0,0.32);
    --shadow-2: 0 6px 24px -6px rgba(0,0,0,0.66), 0 2px 6px rgba(0,0,0,0.38);
    --shadow-3: 0 16px 48px -12px rgba(0,0,0,0.76), 0 4px 12px rgba(0,0,0,0.46);
  }
}
* { box-sizing: border-box; margin: 0; }
body {
  /* Pretendard는 설치된 기기에서만 쓰인다. CSP의 default-src 'self'가 font-src까지 덮어 내려받지 못한다. */
  font-family: Pretendard, "Pretendard Variable", system-ui, -apple-system, "Segoe UI", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  background: var(--page); color: var(--text-primary);
  font-size: 14px; line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.02em;
  /* 한국어를 어절 안에서 끊지 않는다. 띄어쓰기가 없는 긴 토큰만 예외로 접는다. */
  word-break: keep-all;
  overflow-wrap: break-word;
}
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}

/* 공용 셸 (내비게이션·로그인·서비스 홈) */
/* 자산 화면은 이 블록을 쓰지 않는다. 폭·여백은 아래 #assetScreen 규칙이 단독으로 정한다. */
.global-nav {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--surface-1) 84%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.nav-inner { display: flex; align-items: center; gap: 10px; width: min(1000px, 100%); margin: 0 auto; padding: 12px 24px; }
.nav-links { display: flex; gap: 2px; margin-left: -14px; } /* 링크 안쪽 여백만큼 당겨 본문 제목과 좌측을 맞춘다 */
.global-nav a {
  padding: 8px 13px; border-radius: 999px; font-size: 14px; font-weight: 600;
  color: var(--muted); text-decoration: none; white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease;
}
/* 모든 :hover는 hover 가능한 포인터에서만 건다. 터치 기기는 :hover가 탭 뒤에도 남아 버튼이 눌린 색인 채로 굳는다. */
@media (hover: hover) { .global-nav a:hover { background: var(--fill); color: var(--text-primary); } }
.global-nav a[aria-current="page"] { background: var(--fill); color: var(--text-primary); }
/* 좁은 폭에서는 계정 이름이 먼저 줄어들어 링크와 로그아웃 버튼이 잘리지 않는다 */
.nav-user { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; color: var(--muted); }
#btnNavLogout { flex: none; }

.login-screen { min-height: 100dvh; display: grid; place-items: center; align-content: center; padding: 24px; }
.login-card {
  width: min(400px, 100%); display: grid; gap: 14px; padding: 28px 24px 24px;
  border-radius: var(--r-4); background: var(--surface-1);
  box-shadow: var(--shadow-3);
}
.login-head h1 { font-size: 22px; font-weight: 700; letter-spacing: -0.035em; line-height: 1.35; }
.login-head p { margin-top: 8px; font-size: 14px; color: var(--muted); line-height: 1.6; }
.login-card label { display: grid; gap: 7px; font-size: 13.5px; font-weight: 600; color: var(--text-secondary); }
.login-card input {
  width: 100%; font: inherit; font-size: 15px; height: 48px; padding: 0 15px; border-radius: var(--r-2);
  border: 1px solid transparent; background: var(--fill); color: var(--text-primary);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.login-card input:focus { border-color: var(--accent); background: var(--surface-1); outline: none; }
.login-card button { width: 100%; height: 48px; padding: 0 15px; font-size: 15px; font-weight: 700; border-radius: var(--r-2); }
.form-error { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--danger); }
.form-error:empty { display: none; } /* 빈 줄을 예약하지 않아 오류 없는 폼에 빈 공간이 남지 않는다 */
.form-hint { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--muted); }
/* 로그인 카드보다 낮은 위계로 아래에 쌓는다. 두 카드가 겹치면 모서리가 서로를 자른다. */
.login-help-card { margin-top: 12px; box-shadow: var(--shadow-1); }
.login-help-card h2 { font-size: 16px; font-weight: 700; letter-spacing: -0.025em; }
.login-help-form { display: grid; gap: 12px; }
.login-help-form label { display: grid; gap: 7px; font-size: 13.5px; font-weight: 600; color: var(--text-secondary); }
.login-help-form input {
  width: 100%; font: inherit; font-size: 15px; height: 48px; padding: 0 15px; border-radius: var(--r-2);
  border: 1px solid transparent; background: var(--fill); color: var(--text-primary);
}
.login-help-form input:focus { border-color: var(--accent); background: var(--surface-1); outline: none; }
.login-help-form button { height: 48px; padding: 0 15px; font-size: 15px; font-weight: 700; }
#tokenError, #tokenComplete { width: min(400px, 100%); margin-top: 12px; text-align: center; }

.home-screen, .pill-screen { width: min(1000px, 100%); margin: 0 auto; padding: 40px 24px 56px; }
.home-heading h1 { font-size: 27px; font-weight: 700; letter-spacing: -0.04em; line-height: 1.35; }
.home-heading p { margin-top: 9px; font-size: 15px; color: var(--muted); }
/* auto-fill: 서비스가 하나뿐일 때 카드가 한 줄 전체로 늘어나지 않게 한다 */
.service-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; margin-top: 24px; }
.service-card {
  position: relative; display: grid; gap: 6px; align-content: start; padding: 21px 48px 21px 22px;
  color: inherit; text-decoration: none;
  border-radius: var(--r-3); background: var(--surface-1);
  transition: transform 0.16s ease, background-color 0.16s ease;
}
.service-card strong { font-size: 16px; font-weight: 700; letter-spacing: -0.025em; }
.service-card span { font-size: 13.5px; color: var(--muted); line-height: 1.6; }
.service-card .service-go { position: absolute; top: 24px; right: 22px; font-size: 17px; color: var(--muted); transition: transform 0.16s ease, color 0.16s ease; }
.service-card:active { transform: scale(0.985); }
/* 터치 기기는 :hover가 탭 뒤에도 남아 눌린 카드가 계속 떠 있는 것처럼 보인다 */
@media (hover: hover) {
  .service-card:hover { background: color-mix(in srgb, var(--surface-1) 92%, var(--accent)); }
  .service-card:hover .service-go { color: var(--accent); transform: translateX(3px); }
}

.admin-screen { width: min(1200px, 100%); margin: 0 auto; padding: 40px 24px 56px; }
.admin-page-head { align-items: flex-start; margin-bottom: 22px; }
/* basis를 0으로 둬야 좁은 화면에서 줄바꿈 대신 줄어든다. auto면 줄바꿈이 먼저 일어나 새로고침 버튼이 홀로 남는다. */
.admin-page-head > div { flex: 1 1 0; min-width: 0; }
.admin-page-head > button { flex: none; }
.admin-page-head h1 { font-size: 27px; font-weight: 700; letter-spacing: -0.04em; line-height: 1.35; }
.admin-subtitle { margin-top: 8px; color: var(--muted); font-size: 14px; }
.admin-layout { display: grid; grid-template-columns: minmax(260px, 0.8fr) minmax(0, 1.2fr); gap: 12px; margin-bottom: 12px; }
.admin-form { display: grid; gap: 2px; }
.admin-form .field { margin-bottom: 10px; }
.admin-form button { margin-top: 8px; }
.admin-catalog { display: grid; gap: 13px; font-size: 13.5px; }
.admin-catalog-solutions { display: flex; flex-wrap: wrap; gap: 6px; }
/* 알약은 한 줄일 때만 성립한다. 긴 솔루션 이름이 접히면 타원이 되므로 접지 않는다. */
.admin-chip { padding: 6px 12px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-text); font-size: 13px; font-weight: 600; white-space: nowrap; }
.admin-catalog-plans { display: grid; gap: 8px; }
.admin-catalog-row { display: flex; align-items: baseline; gap: 10px; padding-bottom: 9px; border-bottom: 1px solid var(--grid); }
.admin-catalog-row span { color: var(--muted); font-size: 13px; }
.admin-section-head { display: flex; align-items: baseline; gap: 10px; }
.admin-status { color: var(--muted); font-size: 13px; }
.admin-table-wrap { overflow-x: auto; }
.admin-table { min-width: 940px; }
.admin-table td small { display: block; margin-top: 4px; color: var(--muted); font-size: 12px; }
/* 화살표 자리(오른쪽 여백)까지 감안한 폭. 좁으면 플랜 이름이 두 줄로 접힌다. */
.admin-table select { min-width: 150px; min-height: 38px; padding: 8px 10px; border: 1px solid transparent; border-radius: var(--r-1); background-color: var(--fill); color: var(--text-primary); }
.admin-entitlements { color: var(--text-secondary); font-size: 13px; }
.admin-check { color: var(--text-secondary); font-size: 13px; white-space: nowrap; }
.admin-actions { white-space: nowrap; }
.admin-empty { padding: 28px 10px; text-align: center; color: var(--muted); }

#assetScreen { padding: 24px; max-width: 1180px; margin: 0 auto; }
header { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
header h1 { font-size: 24px; font-weight: 700; letter-spacing: -0.035em; line-height: 1.35; }
/* basis 0이어야 좁은 화면에서 제목 블록이 줄바꿈 대신 줄어들어 액션 그룹이 밀려나지 않는다 */
.hdr-title { flex: 1 1 0; min-width: 0; }
.title-row { display: flex; align-items: center; gap: 10px; }
.title-row h1 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 액션 버튼보다 낮은 위계지만 눌린다는 건 보여야 한다. 면을 지우고 크기·글자색만 낮춘다. 알약 모양은 필터 드롭다운과 같은 `보조 조작` 어휘다. */
.hdr-refresh {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 999px; font-size: 13px; font-weight: 600; color: var(--muted);
  background: transparent; border-color: transparent; white-space: nowrap;
}
@media (hover: hover) { .hdr-refresh:hover { color: var(--text-primary); background: var(--fill); border-color: transparent; } }
.spacer { flex: 1; }
/* 기본 버튼은 테두리 없는 회색 면이다. 강조는 채도로만 주고 선은 쓰지 않는다. */
button {
  font: inherit; font-size: 14px; font-weight: 600; padding: 9px 14px; border-radius: var(--r-2);
  border: 1px solid transparent; background: var(--fill); color: var(--text-secondary);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.08s ease;
}
button:active { transform: scale(0.97); }
button.primary { background: var(--accent); border-color: transparent; color: var(--accent-on); font-weight: 700; }
button.primary:active { background: var(--accent-press); }
@media (hover: hover) {
  button:hover { background: var(--fill-strong); color: var(--text-primary); }
  button.primary:hover { background: var(--accent-press); color: var(--accent-on); }
}
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-bottom: 12px; }
.card {
  background: var(--surface-1); border-radius: var(--r-3); padding: 18px 20px;
}
.card .label { font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 7px; }
.card .value { font-size: 25px; font-weight: 700; letter-spacing: -0.04em; font-variant-numeric: tabular-nums; line-height: 1.25; }
.card .sub { font-size: 13px; color: var(--muted); margin-top: 6px; }
.gain { color: var(--gain); }
.loss { color: var(--loss); }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }
/* auto-fit이 3열이 되는 폭에서는 요약 카드 4장이 3+1로 갈라져 마지막 한 장만 덩그러니 남는다 */
@media (max-width: 800px) {
  .grid2 { grid-template-columns: 1fr; }
  .cards { grid-template-columns: repeat(2, 1fr); }
}
.panel { background: var(--surface-1); border-radius: var(--r-3); padding: 20px; }
/* 제목을 대문자로 바꾸지 않는다. 패널·열 제목에는 사용자 데이터의 영문이 그대로 들어온다. */
.panel h2 { font-size: 15px; font-weight: 700; letter-spacing: -0.025em; color: var(--text-primary); margin-bottom: 15px; }
/* .panel h2와 특이도가 같다. 뒤에 와야 관리 화면 h2가 대시보드 패널 라벨 크기에 가려지지 않는다. */
.admin-panel h2 {
  font-size: 15px; color: var(--text-primary); letter-spacing: -0.025em; margin-bottom: 14px;
}
.donut-wrap { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.legend { flex: 1; min-width: 230px; display: flex; flex-direction: column; gap: 9px; }
.legend .row { display: flex; align-items: center; gap: 10px; font-size: 13.5px; }
.legend .dot { width: 10px; height: 10px; border-radius: 999px; flex: none; }
.legend .name { color: var(--text-secondary); white-space: nowrap; font-weight: 500; }
.legend .amt { margin-left: auto; font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 600; }
.legend .pct { color: var(--muted); width: 50px; text-align: right; font-variant-numeric: tabular-nums; }
.owner-rows { display: flex; flex-direction: column; gap: 14px; }
.owner-row .top { display: flex; font-size: 13.5px; margin-bottom: 7px; }
.owner-row .top .amt { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }
.owner-row .bar { height: 10px; background: var(--fill); border-radius: 999px; overflow: hidden; }
.owner-row .bar > div { height: 100%; background: var(--accent); border-radius: 999px; }
.panel.trend { margin-bottom: 12px; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th {
  text-align: left; font-weight: 600; color: var(--muted); font-size: 12.5px;
  letter-spacing: -0.01em;
  padding: 10px 10px; border-bottom: 1px solid var(--grid);
}
td { padding: 10px 10px; border-bottom: 1px solid var(--grid); vertical-align: middle; }
@media (hover: hover) { tbody tr:hover { background: var(--hover); } }
tr:last-child td { border-bottom: none; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.atable th, .atable td { white-space: nowrap; }
/* 모바일 카드형 자산 리스트 (좁은 화면에서 테이블 대체) */
.alist { display: none; }
.acard {
  border-radius: var(--r-2); padding: 12px 14px; cursor: pointer;
  background: var(--fill);
}
.acard[role="button"]:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; background: var(--surface-1);
}
.acard:active { background: var(--fill-strong); }
.acard .l1 { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 14px; }
.acard .l1 .aname { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acard .l1 .aright { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; flex: none; }
.acard .l1 .aval { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -0.03em; }
.acard .aqty { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.acard .l2 { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-top: 6px; font-size: 12.5px; color: var(--muted); }
.acard .l2 .ameta { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acard .pl { font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 13px; font-weight: 600; }
.alist-hint { font-size: 12px; color: var(--muted); text-align: center; padding: 6px 0 0; }
.holdings-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.holdings-head h2 { margin: 0; }
.holdings-sub { color: var(--muted); font-size: 12.5px; line-height: 1.55; margin-top: 5px; }
.holding-toggle { display: inline-flex; flex: none; border-radius: 999px; padding: 3px; background: var(--fill); }
.holding-toggle button {
  border: none; border-radius: 999px; background: transparent; color: var(--muted);
  padding: 7px 14px; font-size: 13px; font-weight: 600; white-space: nowrap; cursor: pointer;
}
@media (hover: hover) { .holding-toggle button:hover { background: transparent; color: var(--text-primary); } }
.holding-toggle button.active { background: var(--surface-1); color: var(--text-primary); font-weight: 700; box-shadow: var(--shadow-1); }
@media (hover: hover) { .holding-toggle button.active:hover { background: var(--surface-1); } }
.holding-toggle button:focus-visible, .holding-expand:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.holding-parent-row > td { vertical-align: top; }
.holding-summary-list { font-weight: 600; line-height: 1.45; }
.holding-meta, .holding-mobile-summary { color: var(--muted); font-size: 12px; line-height: 1.55; margin-top: 4px; }
.holding-inline-meta { margin-left: 5px; }
.holding-expand {
  border: none; border-radius: 999px; background: var(--fill); color: var(--text-secondary);
  padding: 6px 12px; font-size: 12.5px; font-weight: 600; white-space: nowrap; cursor: pointer;
}
@media (hover: hover) { .holding-expand:hover { color: var(--accent-text); background: var(--accent-soft); } }
.holding-detail-row > td { padding: 0; background: var(--page); }
.holding-detail { border-top: 1px solid var(--grid); padding: 14px 16px 16px; }
.holding-detail-title { color: var(--muted); font-size: 12.5px; font-weight: 600; margin-bottom: 10px; }
.holding-detail-list { display: flex; flex-direction: column; gap: 8px; }
.holding-constituent {
  display: grid; grid-template-columns: minmax(150px, 1.3fr) minmax(170px, 1fr) minmax(130px, 1fr) auto;
  align-items: center; gap: 10px; padding: 11px 12px;
  border-radius: var(--r-2); background: var(--surface-1);
}
.holding-constituent-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.holding-constituent-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.holding-constituent-owner, .holding-constituent-values, .holding-constituent-meta { color: var(--muted); font-size: 12.5px; line-height: 1.5; }
.holding-constituent-values { display: flex; flex-wrap: wrap; gap: 4px 10px; font-variant-numeric: tabular-nums; }
.holding-constituent-meta { min-width: 0; }
.holding-constituent-actions { white-space: nowrap; text-align: right; }
.integrated-card { cursor: default; }
.integrated-card:active { background: var(--fill); }
/* 카드가 --fill이라 같은 --fill 버튼은 면이 겹쳐 사라진다. 카드 위에서는 흰 면으로 세운다.
   폭을 꽉 채우는 조작이라 알약이 아니라 둥근 사각형을 쓴다. */
.holding-expand-mobile {
  display: block; width: 100%; margin-top: 10px;
  background: var(--surface-1); border-radius: var(--r-2);
}
@media (hover: hover) { .holding-expand-mobile:hover { background: var(--surface-1); color: var(--accent-text); } }
.holding-detail-mobile { border-top: 1px solid var(--grid); padding: 12px 0 0; margin-top: 12px; }
.holding-detail-mobile .holding-constituent { grid-template-columns: 1fr auto; gap: 5px 9px; padding: 10px; }
.holding-detail-mobile .holding-constituent-values, .holding-detail-mobile .holding-constituent-meta { grid-column: 1 / -1; }
.holding-detail-mobile .holding-constituent-actions { grid-column: 2; grid-row: 1; }
.holding-detail-mobile .holding-constituent-main { grid-column: 1; }
button.danger { color: var(--gain); }
@media (hover: hover) { button.danger:hover { color: var(--gain); background: color-mix(in srgb, var(--gain) 12%, transparent); } }
.chip { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-secondary); }
.chip .dot { width: 8px; height: 8px; border-radius: 999px; }
.sym { color: var(--muted); font-size: 12.5px; margin-left: 6px; }
.src { color: var(--muted); font-size: 12px; }
.warn { color: var(--muted); font-size: 12px; }
.rowbtn { padding: 6px 12px; font-size: 12.5px; margin-left: 4px; border-radius: 999px; }
.empty {
  max-width: 34em; margin: 0 auto; padding: 56px 20px;
  text-align: center; font-size: 14px; line-height: 1.85; color: var(--muted);
}
dialog {
  border: none; border-radius: var(--r-4); background: var(--surface-1); color: var(--text-primary);
  flex-direction: column; overflow: hidden;
  padding: 0; width: min(460px, 92vw); margin: auto; /* CSS 리셋이 기본 가운데 정렬을 지우므로 복원 */
  max-height: 88vh;
  max-height: 88dvh; /* 모바일 주소창이 접히기 전 vh는 화면보다 커서 다이얼로그 아래가 잘린다 */
  box-shadow: var(--shadow-3);
}
dialog:not([open]) { display: none; }
dialog[open] { display: flex; animation: dlgIn 0.22s cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes dlgIn { from { opacity: 0; transform: translateY(16px) scale(0.97); } }
dialog::backdrop { background: rgba(15,18,26,0.44); backdrop-filter: blur(3px); }
.dlg-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 22px 22px 12px;
}
.dlg-head h2 { font-size: 18px; font-weight: 700; letter-spacing: -0.03em; line-height: 1.35; }
.dlg-head .dsub { font-size: 13px; color: var(--muted); margin-top: 6px; line-height: 1.6; }
.dlg-close {
  border: none; background: none; color: var(--muted); font-size: 18px; line-height: 1;
  cursor: pointer; padding: 6px 10px; border-radius: 999px;
}
@media (hover: hover) { .dlg-close:hover { color: var(--text-primary); background: var(--fill); border: none; } }
.dlg-body {
  flex: 1 1 auto; min-height: 0;
  padding: 6px 22px 22px; overflow-y: auto; max-height: none;
  overscroll-behavior: contain;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--accent); background: var(--surface-1); outline: none;
}
.note-info, .note-warn {
  font-size: 13px; padding: 12px 14px; border-radius: var(--r-2); margin-bottom: 9px; line-height: 1.65;
}
.note-info { background: var(--accent-soft); color: var(--text-primary); }
.note-warn { background: color-mix(in srgb, var(--s3) 16%, transparent); color: var(--text-primary); }
.field { margin-bottom: 12px; }
/* label 자체가 .field인 폼(관리 계정 추가·초대 코드)은 안쪽 span이 라벨 역할을 한다 */
.field label, .field > span {
  display: block; font-size: 13.5px; font-weight: 600; color: var(--text-secondary); margin-bottom: 6px;
}
/* 높이는 고정값이 아니라 padding으로 만들고 min-height로만 하한을 준다. select는 아래 @supports
   에서 base-select가 되면 inline-flex 컨테이너로 바뀌는데, 고정 height에 세로 padding이 0이면
   UA가 만드는 내부 버튼 상자를 흡수할 여지가 없어 구현에 따라 글자가 위로 붙고 상자가 커진다. */
.field input, .field select {
  width: 100%; font: inherit; font-size: 15px; min-height: 46px; padding: 11px 13px; border-radius: var(--r-2);
  border: 1px solid transparent; background: var(--fill); color: var(--text-primary);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.field select, .imp-preview select, .admin-table select {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%238b95a1' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat; background-position: right 14px center; padding-right: 34px;
}
@media (hover: hover) { .field select:hover, .admin-table select:hover { background-color: var(--fill-strong); } }
.imp-preview select { background-position: right 6px center; padding-right: 22px; }
option { background: var(--surface-1); color: var(--text-primary); }
/* 최신 Chromium: 열린 드랍다운 목록까지 직접 스타일링 */
@supports (appearance: base-select) {
  .field select, .imp-preview select, .admin-table select {
    appearance: base-select;
    background-image: none; padding-right: 12px; /* base-select 자체 화살표를 쓰므로 커스텀 화살표 제거 */
    /* base-select는 select를 inline-flex로 만든다. 기본값 normal은 stretch라 내부 버튼이 늘어나
       글자가 위로 붙는다. 세로 가운데를 명시한다. */
    align-items: center;
  }
  .field select::picker-icon, .imp-preview select::picker-icon, .admin-table select::picker-icon { color: var(--muted); }
  .field select::picker(select), .imp-preview select::picker(select), .admin-table select::picker(select) {
    appearance: base-select;
    background: var(--surface-1); color: var(--text-primary);
    border: none; border-radius: var(--r-3);
    box-shadow: var(--shadow-3); padding: 8px; margin-top: 8px;
    max-height: 60dvh; overflow-y: auto; overscroll-behavior: contain;
  }
  /* 닫힌 필드가 50px인데 목록만 조밀하면 같은 조작으로 읽히지 않는다. 행을 손가락 크기로 맞춘다.
     gap을 두지 않는다. 미선택 행의 ::checkmark는 폭 0인 flex 항목으로 남아 gap만큼 글자를 민다. */
  .field select option, .imp-preview select option, .admin-table select option {
    display: flex; align-items: center;
    min-height: 48px; padding: 11px 13px; border-radius: var(--r-2);
    font-size: 15px; cursor: pointer;
  }
  .field select option:hover, .field select option:focus,
  .imp-preview select option:hover, .imp-preview select option:focus,
  .admin-table select option:hover, .admin-table select option:focus { background: var(--fill); }
  /* UA 기본 포커스 링은 검은 사각형이라 목록 위에서 이물감이 크다. 색과 반경을 행에 맞춘다.
     offset을 음수로 둬야 링이 행 안쪽에 그려져 이웃 행을 덮지 않는다. */
  .field select option:focus-visible, .imp-preview select option:focus-visible,
  .admin-table select option:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
  .field select option:checked, .imp-preview select option:checked,
  .admin-table select option:checked { color: var(--accent-text); font-weight: 700; }
  /* 선택 표시는 UA가 만드는 ::checkmark 하나만 쓰고 오른쪽으로 보낸다. 직접 ::after를 더하면
     체크가 둘이 되고, 생성 콘텐츠라 선택 상태가 스크린리더에 두 번 읽힌다. */
  .field select option::checkmark, .imp-preview select option::checkmark,
  .admin-table select option::checkmark { order: 1; margin-left: auto; color: var(--accent-text); }

  /* 좁은 화면에서는 필드에 붙는 드롭다운이 아니라 화면 아래에서 올라오는 시트다. UA가 anchor
     positioning으로 잡아둔 위치를 position-area부터 지워야 inset이 먹는다. */
  @media (max-width: 640px) {
    .field select::picker(select), .imp-preview select::picker(select), .admin-table select::picker(select) {
      position-area: none;
      position: fixed; inset: auto 0 0 0; margin: 0;
      width: 100%; max-width: none; max-height: 62dvh;
      border-radius: var(--r-4) var(--r-4) 0 0;
      padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
    }
    .field select option, .imp-preview select option, .admin-table select option {
      min-height: 52px; padding: 13px 15px; font-size: 16px;
    }
    /* 시트가 화면 절반을 덮으므로 뒤를 덮어 초점을 옮긴다. 데스크톱 드롭다운에는 걸지 않는다. */
    .field select::picker(select)::backdrop, .imp-preview select::picker(select)::backdrop,
    .admin-table select::picker(select)::backdrop { background: rgba(15,18,26,0.44); }
    /* 아래에서 올라오는 동작. @starting-style을 모르는 구현에서는 그냥 즉시 나타난다. */
    .field select::picker(select), .imp-preview select::picker(select), .admin-table select::picker(select) {
      translate: 0 0;
      transition: translate 0.22s cubic-bezier(0.16, 1, 0.3, 1), overlay 0.22s allow-discrete, display 0.22s allow-discrete;
    }
    @starting-style {
      .field select::picker(select), .imp-preview select::picker(select), .admin-table select::picker(select) {
        translate: 0 100%;
      }
    }
  }
}
/* 직접 만든 자동완성 드랍다운 (datalist 대체 — 네이티브 팝업은 스타일 불가) */
.cbox { position: relative; }
.cbox-list {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 30;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--r-2);
  box-shadow: var(--shadow-2); padding: 6px; max-height: 220px; overflow-y: auto;
}
.cbox-item { padding: 9px 12px; border-radius: var(--r-1); font-size: 13.5px; cursor: pointer; }
/* .sel은 키보드로 고른 항목이라 hover 가드 밖에 둔다 */
.cbox-item.sel { background: var(--fill); }
@media (hover: hover) { .cbox-item:hover { background: var(--fill); } }
/* .field 밖(다이얼로그 안내문·빈 목록)에서도 같은 크기로 보이도록 후손 선택자를 쓰지 않는다 */
.hint { font-size: 12.5px; color: var(--muted); margin-top: 6px; line-height: 1.7; }
.frow { display: flex; gap: 10px; }
.frow .field { flex: 1; }
.actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 20px; }
.actions button { height: 44px; padding: 0 18px; font-size: 14px; }
#tooltip {
  position: fixed; pointer-events: none; z-index: 50; display: none;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--r-1);
  padding: 10px 12px; font-size: 13px; line-height: 1.5; box-shadow: var(--shadow-2);
}
/* 필터 드롭다운 (분류 / 소유자 / 회사 / 메모 / 관리) */
.filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.fdrop {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 7px 13px; border-radius: 999px; font-size: 13px; font-weight: 600; white-space: nowrap;
  border: 1px solid transparent; background: var(--fill); color: var(--text-secondary);
}
@media (hover: hover) { .fdrop:hover { background: var(--fill-strong); color: var(--text-primary); } }
/* inline 요소에는 transform이 걸리지 않아 inline-block으로 둔다. */
.fdrop .fdcaret { display: inline-block; font-size: 8px; color: var(--muted); transition: transform 0.15s ease; }
/* 펼친 상태를 삼각형 방향으로 알린다. 상태는 aria-expanded가 이미 들고 있으므로 클래스를 더 만들지 않는다. */
.fdrop[aria-expanded="true"] .fdcaret { transform: rotate(180deg); }
.fdrop.active { background: var(--accent); border-color: transparent; color: var(--accent-on); }
@media (hover: hover) { .fdrop.active:hover { background: var(--accent-press); color: var(--accent-on); } }
.fdrop.active .fdcaret { color: color-mix(in srgb, var(--accent-on) 75%, transparent); }
/* 드롭다운 메뉴 (헤더 ⋯ 와 공용) */
.menu { position: relative; }
.menu-list {
  position: fixed; z-index: 40; min-width: 168px;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--r-2);
  box-shadow: var(--shadow-2); padding: 6px; display: none;
}
.menu-list.open { display: block; }
.menu-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; padding: 11px 12px;
  border: none; background: none; border-radius: var(--r-1); font-size: 13.5px; font-weight: 500;
  color: var(--text-primary); text-decoration: none; cursor: pointer; white-space: nowrap;
}
@media (hover: hover) { .menu-item:hover { background: var(--fill); border: none; color: var(--text-primary); } }
.menu-sep { height: 1px; margin: 6px 6px; background: var(--grid); }
.menu-item .dot { width: 8px; height: 8px; border-radius: 999px; flex: none; }
.menu-item.sel { color: var(--accent-text); font-weight: 700; }
.menu-item.sel::after { content: '✓'; font-size: 12px; }
.meta-line { margin-top: 6px; }
.meta-line #meta { color: var(--muted); font-size: 13px; }
/* 시세 새로고침 버튼 — 제목 줄에 위치, 아이콘은 로딩 중 회전 */
#btnRefresh .micon { display: block; width: 14px; height: 14px; flex: none; }
#btnRefresh.loading { color: var(--muted); }
#btnRefresh.loading .micon { animation: spin 0.9s linear infinite; color: var(--accent); }
@keyframes spin { to { transform: rotate(360deg); } }
.field textarea {
  width: 100%; font: inherit; font-size: 13.5px; padding: 11px 13px; border-radius: var(--r-2);
  border: 1px solid transparent; background: var(--fill); color: var(--text-primary);
  resize: vertical; font-variant-numeric: tabular-nums;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.imp-preview { overflow-x: auto; margin-top: 6px; border-radius: var(--r-2); background: var(--fill); padding: 4px; }
.imp-preview table { font-size: 12.5px; }
.imp-preview th { padding: 8px; }
.imp-preview td { padding: 7px 8px; white-space: nowrap; }
.imp-preview select {
  font: inherit; font-size: 12px; min-height: 28px; padding: 4px 6px; border-radius: var(--r-1);
  border: 1px solid transparent; background: var(--surface-1); color: var(--text-primary);
}
.imp-note { font-size: 13px; color: var(--text-secondary); margin-top: 10px; }
#toast {
  /* 홈 인디케이터가 있는 기기에서 토스트가 그 위에 겹치지 않게 안전 영역을 더한다 */
  position: fixed; bottom: calc(24px + env(safe-area-inset-bottom)); left: 50%;
  transform: translateX(-50%); z-index: 60; display: none;
  background: var(--text-primary); color: var(--surface-1); padding: 12px 18px;
  /* 알약(999px)은 한 줄일 때만 성립한다. 동기화 결과처럼 pre-line으로 여러 줄이 들어오면
     타원이 된다. 한 줄에서는 알약에 가깝고 여러 줄에서는 둥근 사각형이 되는 값을 쓴다. */
  border-radius: var(--r-3);
  font-size: 13.5px; font-weight: 600; max-width: 90vw; white-space: pre-line; box-shadow: var(--shadow-2);
}
svg text { font-family: inherit; }

/* 모바일 반응형 */
@media (max-width: 640px) {
  .nav-inner { gap: 6px; padding: 10px 14px; }
  .nav-links { margin-left: -10px; }
  .global-nav a { padding: 8px 10px; font-size: 14px; }
  .nav-user { font-size: 13px; }
  .login-card { padding: 24px 20px 22px; }
  .home-screen, .pill-screen { padding: 26px 15px 38px; }
  .home-heading h1 { font-size: 23px; }
  .service-grid { grid-template-columns: 1fr; margin-top: 18px; }
  .admin-screen { padding: 26px 15px 38px; }
  .admin-page-head h1 { font-size: 23px; }
  .admin-layout { grid-template-columns: 1fr; }
  .admin-page-head { gap: 10px; }
  #assetScreen { padding: 12px; }
  header { gap: 10px; margin-bottom: 14px; }
  header h1 { font-size: 20px; }
  /* 터치 높이는 .toolbar가 44px로 따로 못박는다. 여기서는 가로 폭만 줄여 검색창에 넘긴다. */
  button { padding: 8px 11px; font-size: 13px; }
  /* 툴바 넷이 한 줄이라 남는 폭이 곧 검색창 폭이다. 액션 라벨을 줄여 검색창에 넘긴다. */
  .toolbar { gap: 6px; }
  #btnAdd .label-tail { display: none; }
  /* 요약 카드는 좁은 화면에서 2열로 접혀 한 장의 폭이 절반이다. 보조 설명이 두 줄로 접히면서
     같은 행의 다른 카드까지 끌어올려 덩어리가 커 보인다. 라벨·보조를 최소 크기로 내리고
     안쪽 간격을 줄여 두 줄이 되어도 덜 불어나게 한다. */
  .cards { grid-template-columns: repeat(2, 1fr); gap: 7px; }
  .card { padding: 11px 13px; border-radius: var(--r-2); }
  .card .label { font-size: 12.5px; margin-bottom: 5px; }
  .card .value { font-size: 18px; }
  .card .sub { font-size: 12.5px; margin-top: 4px; line-height: 1.45; }
  .panel { padding: 15px; border-radius: var(--r-2); }
  .holdings-head { flex-direction: column; gap: 10px; }
  .holding-toggle { width: 100%; }
  .holding-toggle button { flex: 1; }
  .grid2 { gap: 8px; }
  .cards, .grid2, .panel.trend { margin-bottom: 8px; }
  table { font-size: 12.5px; }
  th, td { padding: 8px 6px; }
  /* 좁은 화면에선 테이블 대신 카드형 리스트 */
  .atable-wrap { display: none; }
  .alist { display: flex; flex-direction: column; gap: 8px; }
  /* 필터는 접어둔다. 6개가 3줄을 차지해 총자산이 첫 화면 밖으로 밀린다.
     여는 버튼의 display는 뒤쪽 .filter-toggle 선언에 가리므로 그 아래에서 정한다. */
  .filters { display: none; gap: 6px; }
  .filters.open { display: flex; }
  .filters .menu { flex: 1 1 calc(50% - 3px); }
  .filters .fdrop { width: 100%; justify-content: space-between; }
  .donut-wrap { justify-content: center; }
  /* 좁은 화면의 다이얼로그는 아래에서 올라오는 시트다. 아래 모서리는 화면 밖이라 각지게 둔다. */
  dialog {
    width: 100%; max-width: none; margin: auto auto 0;
    border-radius: var(--r-4) var(--r-4) 0 0;
    max-height: 92dvh;
    padding-bottom: env(safe-area-inset-bottom);
  }
  @keyframes dlgIn { from { opacity: 0; transform: translateY(28px); } }
  .dlg-head { padding: 18px 16px 10px; }
  .dlg-head h2 { font-size: 17px; }
  .dlg-body { padding: 4px 16px 18px; }
  .frow { flex-direction: column; gap: 0; }
  .actions { gap: 8px; }
  .actions button { flex: 1; height: 48px; }
}

/* API 키 만료 임박 등 알림 배너 */
.notice-bar {
  background: color-mix(in srgb, var(--s3) 14%, transparent);
  border-radius: var(--r-2); padding: 13px 16px; margin-bottom: 12px;
  font-size: 13.5px; line-height: 1.8; color: var(--text-primary);
}

.share-section { border-top: 1px solid var(--grid); margin-top: 24px; padding-top: 22px; }
/* 첫 구획의 h3에는 클래스가 없다. 다이얼로그 안 구획 제목은 한 규칙으로 맞춘다. */
.dlg-body h3 { margin: 0 0 9px; font-size: 15px; font-weight: 700; letter-spacing: -0.025em; }
/* 구획 설명은 라벨 크기 보조문구가 아니라 읽는 문단이다 */
.share-section > .hint { font-size: 13.5px; line-height: 1.75; margin-top: 0; margin-bottom: 14px; }
.share-form { display: flex; align-items: end; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
/* align-items:end는 margin box 기준이라 .field의 아래 여백만큼 버튼이 내려간다 */
.share-form .field { flex: 1 1 220px; margin-bottom: 0; }
.share-section > .share-code + button { margin-top: 12px; }
.share-code {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; padding: 16px;
  border-radius: var(--r-2); background: var(--fill);
}
.share-code .hint { flex-basis: 100%; }
.share-code code { font-size: 18px; font-weight: 700; letter-spacing: 1px; color: var(--accent-text); user-select: all; font-variant-numeric: tabular-nums; }
.share-badge { display: inline-block; margin: 2px 0; color: var(--accent-text); font-size: 12px; font-weight: 700; }
.readonly-label { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.shared-card { cursor: default !important; }

/* 검색·필터·액션 한 줄 (헤더 아래 고정 — 입력 중 포커스 유지). */
.toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
/* 높이를 패딩·글자크기가 아닌 고정값으로 못박는다. 검색창은 확대 방지로 16px가 필요해 버튼과 글자크기를 맞출 수 없고, 패딩만 맞추면 플랫폼별 줄높이 차이로 다시 벌어진다. */
.toolbar > * { flex: none; height: 44px; }
/* ⋯는 .menu로 감싸여 있어 위 규칙이 래퍼까지만 닿는다. flex로 만들어 안쪽 버튼이 44px를 채우게 한다. */
.toolbar > .menu { display: flex; }
/* 네 조작의 모서리를 알약으로 통일한다. .menu-list 안의 메뉴 항목에는 닿지 않도록 직계만 고른다. */
.toolbar > input, .toolbar > button, .toolbar > .menu > button { border-radius: 999px; }
/* ⋯만 글자가 짧아 세로로 긴 타원이 된다. 높이와 같은 폭을 줘 정원으로 맞춘다. */
.toolbar > .menu > button { width: 44px; padding: 0; }
/* 필터를 접는 버튼은 좁은 화면에서만 쓴다. 넓은 화면은 필터 줄이 한 줄에 다 보인다. */
.filter-toggle { display: none; }
@media (max-width: 640px) { .filter-toggle { display: inline-flex; } }
.toolbar input {
  flex: 1; min-width: 0; font: inherit; font-size: 14px; padding: 0 16px; border-radius: 999px;
  border: 1px solid transparent; background: var(--surface-1); color: var(--text-primary);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.toolbar input::placeholder { color: var(--muted); }
.toolbar input:focus { border-color: var(--accent); outline: none; }
@media (max-width: 640px) { .toolbar input { padding: 0 14px; } }
@media (max-width: 480px) {
  .toolbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas: "search search search" "filters add more";
    align-items: center;
  }
  .toolbar > input { grid-area: search; width: 100%; }
  #btnFilters { grid-area: filters; }
  #btnAdd { grid-area: add; }
  .toolbar > .menu { grid-area: more; justify-self: end; }
}

/* 보조 버튼의 회색 면은 카드 위에서만 보인다. page 배경 위에 직접 놓이는 조작(툴바·필터·관리
   헤더)은 배경과 같은 색이 되어 사라지므로 검색창과 같은 흰 면으로 세운다. 액센트가 칠해진
   상태는 그대로 둔다. */
.toolbar > button:not(.primary), .toolbar > .menu > button, .admin-page-head > button, .fdrop:not(.active) {
  background: var(--surface-1); box-shadow: var(--shadow-1); color: var(--text-secondary);
}
@media (hover: hover) {
  .toolbar > button:not(.primary):hover, .toolbar > .menu > button:hover,
  .admin-page-head > button:hover, .fdrop:not(.active):hover { background: var(--fill); color: var(--text-primary); }
}

/* 터치 기기 자동 확대 방지. iOS Safari는 16px 미만 입력칸에 포커스하면 확대하고 되돌리지 않는다. viewport로 막으면 접근성을 해치므로 글자 크기로 해결한다. 앞선 선언을 덮어야 하므로 파일 끝에 둔다. */
@media (pointer: coarse) {
  .login-card input, .login-help-form input,
  .field input, .field select, .field textarea,
  .toolbar input, .admin-table select, .imp-preview select { font-size: 16px; }
  /* 손가락으로 누르는 최소 크기. 표 행 버튼과 닫기 버튼이 특히 작다. */
  .rowbtn { padding: 8px 14px; }
  .dlg-close { padding: 10px 14px; }
  .menu-item { padding: 13px 12px; }
}

@media (max-width: 560px) {
  /* 이 폭에서는 내비게이션이 두 줄로 접혀 고정하면 화면을 너무 많이 가리므로 본문과 함께 스크롤한다. */
  .global-nav { position: static; }
  .nav-inner { flex-wrap: wrap; row-gap: 4px; }
  .nav-inner .spacer { display: none; }
  .nav-links { flex: 1 1 100%; flex-wrap: wrap; min-width: 0; }
  .nav-user { display: block; flex: 1 1 auto; }
}

/* 알약 검색 화면은 공용 내비게이션 아래에 놓이며 선택칩은 패널 위라 --fill 면을 쓴다. */
.pill-screen { padding-top: 16px; }
.pill-title { margin-bottom: 10px; font-size: 20px; font-weight: 700; letter-spacing: -0.035em; line-height: 1.4; }
.pill-panel { padding: 16px; }
.pill-form { margin-top: 16px; }
.pill-upload-button { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 40px; padding: 0 16px; font-size: 15px; }
.pill-upload-button:disabled { opacity: 0.7; cursor: default; }
.pill-upload-icon { flex: none; width: 20px; height: 20px; }
.pill-upload-hint { margin-top: 8px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.pill-upload-status { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.pill-upload-status:empty { display: none; }
.pill-upload-preview { flex: none; width: 40px; height: 40px; border-radius: var(--r-1); background: var(--fill); object-fit: cover; }
.pill-upload-message { min-width: 0; font-size: 13px; line-height: 1.5; color: var(--text-secondary); }
.pill-upload-message.pill-upload-error { color: var(--danger); }
/* 사진 제공 설정과 기록 진입은 한 줄에 두고 설명은 title과 스크린리더 설명으로만 둔다. */
.pill-feedback { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 6px; }
.pill-feedback-toggle { display: inline-flex; align-items: center; gap: 6px; min-width: 0; min-height: 44px; font-size: 13px; font-weight: 600; color: var(--text-secondary); white-space: nowrap; cursor: pointer; }
.pill-feedback-toggle input { flex: none; width: 18px; height: 18px; margin: 0; accent-color: var(--accent); }
.pill-feedback-records { flex: none; min-height: 44px; margin-right: -10px; padding: 0 10px; font-size: 13px; background: transparent; color: var(--accent-text); white-space: nowrap; }
@media (hover: hover) { .pill-feedback-records:hover { background: var(--accent-soft); color: var(--accent-text); } }
@media (pointer: fine) { .pill-feedback-toggle, .pill-feedback-records { min-height: 34px; } }
.pill-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.pill-fieldset:disabled { opacity: 0.7; }
/* 마크 미체크의 뜻은 화면에 줄을 더하지 않고 스크린리더 설명으로만 둔다. */
.pill-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.pill-group { margin-top: 12px; }
.pill-faces { margin-top: 0; }
.pill-group-label { margin-bottom: 6px; font-size: 13px; font-weight: 600; color: var(--text-secondary); }
.pill-group-label span { font-weight: 500; color: var(--muted); }
.pill-face { display: flex; align-items: center; gap: 10px; }
.pill-face + .pill-face { margin-top: 6px; }
.pill-face .field { flex: 1; min-width: 0; margin: 0; }
.pill-face .field input { min-height: 40px; padding: 8px 12px; font-size: 14px; }
.pill-check { flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 40px; font-size: 13.5px; font-weight: 600; color: var(--text-secondary); cursor: pointer; }
.pill-check input { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); }
/* 선택지는 고정 열 격자라 가로 스크롤 없이 모두 보인다. */
.pill-chips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
/* 색은 견본과 두 글자 라벨이라 칸을 좁혀 한 줄에 더 많이 둔다. */
.pill-chips-colors { grid-template-columns: repeat(auto-fill, minmax(54px, 1fr)); }
/* 칸 너비를 채우는 조작이라 알약 모서리 대신 고정 반경을 쓰고 라벨은 줄바꿈하지 않는다. */
.pill-chip { display: flex; align-items: center; justify-content: center; gap: 5px; min-width: 0; min-height: 44px; padding: 0 6px; border-radius: var(--r-1); font-size: 13.5px; font-weight: 600; white-space: nowrap; }
.pill-chips-colors .pill-chip { padding: 0 4px; }
/* 마우스에서만 칩을 낮추고 터치 기기는 44px 손가락 기준선을 지킨다. */
@media (pointer: fine) { .pill-chip { min-height: 34px; } }
.pill-chip[aria-pressed="true"] { background: var(--accent); color: var(--accent-on); }
@media (hover: hover) { .pill-chip[aria-pressed="true"]:hover { background: var(--accent-press); color: var(--accent-on); } }
/* 하양 견본이 흰 면에서 사라지지 않게 안쪽 윤곽만 그린다. */
.pill-swatch { flex: none; width: 12px; height: 12px; border-radius: 999px; background: var(--swatch); box-shadow: inset 0 0 0 1px rgba(25,31,40,0.2); }
.pill-swatch-clear { background: repeating-conic-gradient(#c9ced4 0 25%, #ffffff 0 50%) 50% / 8px 8px; }
.pill-form .form-error { margin-top: 12px; }
.pill-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.pill-actions button { min-height: 44px; padding: 0 20px; }
/* 고정된 내비게이션에 결과 제목과 조건 영역이 가리지 않도록 스크롤 위치를 띄운다. */
.pill-results, .pill-conditions { scroll-margin-top: 72px; }
/* 결과 목록의 열 수는 화면 폭이 아니라 결과 영역 폭으로 정한다. */
.pill-results { container-type: inline-size; }
.pill-results-head { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 10px; margin: 20px 0 10px; }
.pill-results-head h2 { font-size: 16px; font-weight: 700; letter-spacing: -0.03em; }
.pill-results-head h2:focus { outline: none; }
.pill-basis { font-size: 12.5px; color: var(--muted); }
/* page 배경 위의 글자 버튼이라 면과 그림자 없이 액센트 글자로만 세운다. */
.pill-edit, .pill-back { margin-left: auto; min-height: 36px; padding: 0 10px; font-size: 13px; background: transparent; color: var(--accent-text); }
.pill-back + .pill-edit { margin-left: 0; }
@media (hover: hover) { .pill-edit:hover, .pill-back:hover { background: var(--accent-soft); color: var(--accent-text); } }
.pill-results .note-info, .pill-results .note-warn { margin-bottom: 8px; padding: 7px 12px; font-size: 13px; line-height: 1.5; border-radius: var(--r-1); }
.pill-results .empty { padding: 28px 16px; }
/* 사진의 알약 고르개는 줄을 바꿔 모든 알약을 숨기지 않고, 고정 크기 썸네일이라 그림이 와도 배치가 흔들리지 않는다. */
.pill-picker { display: flex; flex-wrap: wrap; gap: 8px; margin: 20px 0 12px; }
.pill-pick { position: relative; flex: none; width: 64px; height: 64px; padding: 4px; border: 0; border-radius: var(--r-2); background: var(--surface-1); }
.pill-pick-thumb { display: block; width: 56px; height: 56px; border-radius: var(--r-1); background: var(--fill); object-fit: cover; }
.pill-pick-number { position: absolute; top: 6px; left: 6px; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; background: var(--surface-1); font-size: 12.5px; font-weight: 700; line-height: 20px; color: var(--text-primary); text-align: center; white-space: nowrap; }
.pill-pick[aria-pressed="true"], .pill-pick[aria-pressed="true"] .pill-pick-number { background: var(--accent); color: var(--accent-on); }
/* 아직 받지 못한 알약의 진행 표시는 썸네일 아래쪽에 한 줄로 얹는다. */
.pill-pick-state { position: absolute; left: 4px; right: 4px; bottom: 4px; height: 20px; border-radius: 0 0 var(--r-1) var(--r-1); background: var(--surface-1); font-size: 12.5px; font-weight: 600; line-height: 20px; color: var(--text-secondary); text-align: center; white-space: nowrap; overflow: hidden; }
@media (hover: hover) { .pill-pick[aria-pressed="false"]:hover { background: var(--fill-strong); } }
.pill-list { list-style: none; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
@container (min-width: 720px) { .pill-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pill-card {
  width: 100%; height: 100%; display: grid; grid-template-columns: 112px minmax(0, 1fr); align-items: center; gap: 12px;
  padding: 8px 12px; border-radius: var(--r-2); background: var(--surface-1); color: var(--text-primary); font-weight: 400; text-align: left;
}
.pill-card:active { transform: scale(0.985); }
@media (hover: hover) { .pill-card:hover { background: color-mix(in srgb, var(--surface-1) 92%, var(--accent)); color: var(--text-primary); } }
.pill-thumb { display: block; width: 112px; height: 62px; border-radius: var(--r-1); background: var(--fill); object-fit: contain; }
.pill-img-empty { display: flex; align-items: center; justify-content: center; font-size: 12px; color: var(--muted); text-align: center; }
.pill-card-body { display: grid; gap: 1px; min-width: 0; }
/* 긴 품목명은 두 줄까지만 보여 카드 높이를 고르게 둔다. */
.pill-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; font-size: 14px; line-height: 1.35; letter-spacing: -0.025em; }
.pill-name strong { font-weight: 700; }
.pill-rank { font-size: 13px; font-weight: 700; color: var(--accent-text); }
.pill-attrs, .pill-meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.4; }
.pill-attrs { font-size: 13px; color: var(--text-secondary); }
.pill-meta { font-size: 12.5px; color: var(--muted); }
.pill-safety { margin-top: 12px; font-size: 12.5px; line-height: 1.6; color: var(--muted); text-align: center; }
.pill-idle { display: none; }
.pill-retry { margin-top: 14px; }
@media (min-width: 641px) { .pill-dialog { width: min(560px, 92vw); } }
.pill-facts { display: grid; grid-template-columns: 5.5em minmax(0, 1fr); gap: 7px 12px; font-size: 13.5px; line-height: 1.6; }
.pill-facts > div { display: contents; }
.pill-facts dt { font-weight: 600; color: var(--muted); }
.pill-facts dd { margin: 0; }
.pill-detail-pill { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--grid); }
.pill-photo { display: block; width: 100%; max-width: 360px; height: auto; aspect-ratio: 16 / 9; margin-bottom: 12px; border-radius: var(--r-2); background: var(--fill); object-fit: contain; }
.pill-dialog .pill-safety { text-align: left; }
/* 확정 버튼은 낱알 사진을 실물과 비교하며 누르도록 상세 본문이 스크롤돼도 아래에 남긴다. */
.pill-confirm { display: flex; flex-wrap: wrap; justify-content: flex-end; padding: 12px 22px 18px; }
.pill-confirm button { min-height: 44px; padding: 0 20px; }
.pill-confirm button:disabled { opacity: 0.7; cursor: default; }
/* 확정·삭제 결과 줄은 비어 있으면 높이가 없어 배치를 바꾸지 않고, 확정 줄에서는 버튼 위 한 줄을 따로 차지한다. */
.pill-dialog-status { flex: none; margin: 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
.pill-dialog-status:not(:empty) { margin-bottom: 8px; }
.pill-dialog-status-error { color: var(--danger); }
.pill-confirm .pill-dialog-status { flex: 0 0 100%; }
#pillRecordsStatus { padding: 0 22px; }
.pill-records-tools { display: flex; justify-content: flex-end; margin-bottom: 8px; }
.pill-records { list-style: none; padding: 0; display: grid; gap: 6px; }
.pill-record { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 8px 8px 12px; border-radius: var(--r-2); background: var(--fill); }
.pill-record-body { display: grid; gap: 1px; min-width: 0; }
.pill-record-body strong { font-size: 14px; font-weight: 700; line-height: 1.4; }
.pill-record-meta { font-size: 12.5px; line-height: 1.4; color: var(--muted); }
/* 목록 행이 --fill 면이라 같은 면의 버튼이 사라지지 않게 흰 면으로 세운다. */
.pill-record-delete { flex: none; min-height: 44px; padding: 0 12px; background: var(--surface-1); }
.pill-records-tools button { min-height: 44px; }
@media (pointer: fine) { .pill-record-delete, .pill-records-tools button { min-height: 34px; } }
@media (max-width: 640px) {
  .pill-confirm { padding: 10px 16px calc(14px + env(safe-area-inset-bottom)); }
  .pill-confirm button { flex: 1; }
  #pillRecordsStatus { padding: 0 16px; }
}
/* 960px 기준은 pill/consts.js의 PILL_WIDE_MEDIA와 같아야 검색 뒤 스크롤 여부가 배치와 맞는다. */
@media (min-width: 960px) {
  .pill-screen { width: min(1200px, 100%); }
  .pill-layout { display: grid; grid-template-columns: 340px minmax(0, 1fr); gap: 20px; align-items: start; }
  /* 조건 열은 내비게이션(67px)과 화면 위 여백 16px 바로 아래 시작 위치에 그대로 붙고, 창이 낮을 때만 따로 스크롤한다. */
  .pill-conditions { position: sticky; top: 83px; max-height: calc(100vh - 99px); max-height: calc(100dvh - 99px); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
  /* 사진 제공 줄의 34px 조작 영역이 위아래 여백을 겸하므로 바깥 여백을 줄여 조건 열이 1280×860에서 한 화면에 들게 한다. */
  .pill-title { margin-bottom: 8px; }
  .pill-feedback { margin: 0 0 -8px; }
  .pill-form { margin-top: 12px; }
  .pill-attributes .pill-group { margin-top: 10px; }
  /* 각인 두 칸을 한 줄에 두고 마크 체크는 입력칸 오른쪽 안에 얹어 조건 열이 한 화면에 들게 한다. */
  .pill-faces { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 8px; }
  .pill-faces .pill-group-label { grid-column: 1 / -1; }
  .pill-face { position: relative; }
  .pill-face + .pill-face { margin-top: 0; }
  .pill-face .field input { padding-left: 10px; padding-right: 60px; }
  .pill-face .pill-check { position: absolute; top: 0; right: 10px; bottom: 0; gap: 4px; min-height: 0; }
  .pill-group-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 12px; }
  .pill-group-pair .pill-chips { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pill-results-head, .pill-picker { margin-top: 0; }
  .pill-edit { display: none; }
  .pill-results:empty + .pill-idle { display: block; padding: 6px 2px; font-size: 13.5px; color: var(--muted); }
}
@media (max-width: 640px), (min-width: 960px) {
  /* 검색 버튼이 폼 맨 아래에만 있으면 찾기 어려워 폼이 보이는 동안 화면이나 조건 열 아래에 붙인다. */
  .pill-actions {
    position: sticky; bottom: 0; z-index: 2;
    margin: 12px -16px -16px; padding: 12px 16px 16px;
    background: var(--surface-1); border-radius: 0 0 var(--r-3) var(--r-3);
  }
  /* 선을 긋지 않고 위로 흐려지는 면으로 아래에 지나가는 선택지와 구분한다. */
  .pill-actions::before {
    content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 16px;
    background: linear-gradient(to bottom, transparent, var(--surface-1)); pointer-events: none;
  }
  .pill-actions button { flex: 1; }
}
@media (max-width: 640px) {
  .pill-actions { padding-bottom: calc(12px + env(safe-area-inset-bottom)); border-radius: 0 0 var(--r-2) var(--r-2); }
  .pill-actions button { min-height: 48px; }
}
/* 이 폭에서는 내비게이션이 고정되지 않으므로 결과 제목과 조건 영역 위 여백만 남긴다. */
@media (max-width: 560px) {
  .pill-results, .pill-conditions { scroll-margin-top: 12px; }
}
/* 터치 기기는 입력칸 자동 확대를 막는 16px 글자와 44px 손가락 기준선을 지킨다. */
@media (pointer: coarse) {
  .pill-face .field input { min-height: 44px; font-size: 16px; }
  .pill-check, .pill-edit, .pill-back, .pill-upload-button { min-height: 44px; }
}
