/* 캐릭터 목록은 공용 그리드를, 상세는 왼쪽 3:4 프로필과 오른쪽 blog-post를 쓴다. */
/* 목록 창은 그림/영화와 같은 공용 window-content 여백을 쓰고, 자체 패딩을
   가진 상세 화면만 바깥 패딩을 제거한다. */
/* 상세 화면일 때만 여백을 없앤다. 예전엔 :not([data-main="1"]) 만 봤는데,
   목록에서 상세로 넘어갈 때 data-main 이 먼저 지워지고 상세 내용은 조회가
   끝나야 들어와서(navigateWindowAddress) 그 사이 한 프레임 동안 아직 그려져
   있는 목록 그리드가 여백 없는 폭으로 다시 깔렸다 — 4열이 5열로 튀어 보이던 원인.
   실제 상세 내용(.profile-body)이 들어온 뒤에만 걸리게 조건을 바꾼다. */
.window[data-root="character"]:not([data-main="1"]) .window-content:has(> .profile-body) {
  padding: 0;
  /* container: profile-detail / size — profile.css에서 user/character 공통 정의 */
}

/* 사용자 프로필과 동일하게 상세 창을 좁게 리사이즈할 수 있게 한다. */
.window[data-root="character"]:not([data-main="1"]) {
  min-width: 360px;
  min-height: 360px;
}

/* 상세 창도 사용자 프로필과 같은 유동 너비 공통 레이아웃을 쓴다. */

.character-card-avatar-wrap {
  display: flex;
  justify-content: center;
  padding: 10px 0 6px;
}

.character-card-avatar {
  width: 150px;
  height: 150px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background-color: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  overflow: hidden;
  /* 외곽선 없음(요청) — 전역 *{border-color:…!important} 때문에 두께만 지워도
     되지만, 다른 아바타(.post-image-character-avatar)와 같은 표기로 맞춘다. */
  border: 0 !important;
}

.avatar-circle-empty svg {
  width: 60%;
  height: 60%;
}

.character-profile-card-meta {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--system-c-area-b-base-desc-font-color) !important;
}

.panel-card {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding: 10px;
  border-radius: 14px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
}

.panel-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
  padding-left: 5px;
}

.panel-card-head > strong {
  font-weight: 400;
}

/* 관계 수정은 버튼이 아니라 우클릭으로 연다(요청, 공유기록·페어와 같은 방식) —
   버튼은 기존 수정 모드 흐름이 그대로 쓰므로 지우지 않고 자리에서만 감춘다. */
[data-relations-edit-hidden] { display: none !important; }
.avatar-chip-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* 관계가 5개를 넘으면 목록만 스크롤한다(요청) — 행 높이(38px) + 사이 간격(3px)
   다섯 줄이 기준이고, 마지막 줄 아래 간격은 빼서 여섯 번째 줄이 살짝 보이지
   않게 딱 끊는다. 네이티브 스크롤바는 숨기고 창 공용 오버레이 스크롤바를 쓴다
   (다른 스크롤 영역과 같은 처리). */
.avatar-chip-list {
  max-height: calc(38px * 5 + 3px * 4);
  overflow-y: auto;
  scrollbar-width: none;
}

.avatar-chip-list::-webkit-scrollbar {
  display: none;
}

/* 이동 가능한 행은 content-input-box 대신 자체 배경(System C 컨텐츠)을 쓴다. */
.character-relation-edit-row {
  display: grid;
  grid-template-columns: 24px 34px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 3px;
  min-height: 38px;
  padding: 3px 2px 3px 5px;
  border-radius: 5px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
}

.character-relation-edit-row .avatar-circle {
  width: 34px;
}

.character-relation-edit-row .avatar-chip-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.character-relation-edit-row .avatar-chip-text > strong {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.character-relation-edit-row [data-character-relation-add],
.character-relation-edit-row [data-character-relation-remove] {
  min-width: 22px;
  padding-inline: 0;
}
.character-relation-search-dialog {
  width: min(560px, calc(100% - 24px));
  max-height: calc(100% - 24px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* 안의 내용이 영역 B 를 따르므로 판도 영역 B 테두리로 두른다(요청) — 아이콘
     피커(.icon-picker-dialog)와 같은 값. 관계 캐릭터 검색과 공유 기록의 사용자
     추가가 이 판을 함께 쓴다. */
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
}

.character-relation-search-head,
.character-relation-search-head > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 5px;
}

/* [hidden]이 위 display:flex보다 특이도가 낮아 무시되던 문제 — 캐릭터 선택 상태에서
   검색 도구줄을 확실히 숨긴다. */
[data-character-relation-search-tools][hidden] {
  display: none !important;
}

/* 다중 선택(그림 이미지 ↔ 캐릭터 연결)에서 고른 행 표시 — 관계 추가는 단일
   선택이라 없던 상태다. 버튼 강조 테두리를 한 겹 둘러 "골랐음"만 알린다. */
.character-relation-search-row > span > span {
  color: var(--system-c-area-b-base-desc-font-color);
}
.character-relation-search-row.is-selected,
.character-relation-search-row.is-selected * {
  color: var(--system-c-button-accent-font-color) !important;
}
.character-relation-search-row.is-selected > span > span {
  color: var(--system-c-area-b-accent-desc-font-color) !important;
}
.character-relation-search-row.is-selected {
  border-color: rgba(var(--system-c-button-accent-border-rgb), var(--system-c-button-accent-border-alpha)) !important;
  background-color: color-mix(in srgb, var(--system-c-button-accent-color) calc(var(--system-c-button-accent-alpha) * 100%), var(--system-c-button-base-color)) !important;
}

/* 높이를 고정한다 — 검색 결과가 오는 순간 팝업이 커지면서 가운데 정렬 때문에
   위로 밀려 올라가던 것을 막는다(요청: 팝업 안정화). 관계 캐릭터 검색과 공유 기록의
   사용자 초대·캐릭터 추가가 이 목록을 함께 쓴다. */
.character-relation-search-list {
  height: 300px;
  overflow-y: auto;
}

/* normal-button 으로 hover 효과를 받되 테두리는 그리지 않는다. */
.character-relation-search-row {
  width: 100%;
  min-height: 58px;
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  padding: 5px;
  border: 0 !important;
  border-radius: 7px;
  text-align: left;
}

.character-relation-search-row .avatar-circle {
  width: 46px;
}

.character-relation-search-row > span,
.character-relation-search-row > span > span,
.character-relation-search-selected > span {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.character-relation-search-selected:not([hidden]) {
  display: grid;
  justify-items: center;
  gap: 8px;
}

.character-relation-search-selected-actions {
  display: flex;
  gap: 6px;
}

.character-relation-search-avatar {
  width: 150px;
  height: 150px;
  border-radius: 50%;
  background-position: center;
  background-size: cover;
}

.avatar-chip {
  cursor: pointer;
  min-width: 0;
  display: grid;
  grid-template-columns: 10cqi minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  padding: 4px;
  border: 0 !important;
  text-align: left;
}

/* 관계 프로필은 누르면 그 캐릭터가 열리는 버튼이다 — 목록 셀(.grid-cell)과 같은
   강조 배경으로 눌리는 자리임을 알린다(요청). .transparent-button 의 hover 가
   background:transparent !important 라 그걸 되받으려면 !important 가 필요하다. */
button.avatar-chip:hover {
  background-color: color-mix(in srgb, var(--system-c-area-b-accent-color) calc(var(--system-c-area-b-accent-alpha) * 100%), rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha))) !important;
  color: var(--system-c-area-b-accent-font-color) !important;
  border-radius: 8px;
}
/* 이름/설명은 자기 색 규칙(.avatar-chip-label 은 !important)이 있어
   버튼 color 를 물려받지 않는다 — 목록 셀(.grid-cell:hover)과 같이 강조 테마의
   짝(일반/설명)으로 각각 바꿔 준다. 설명 규칙이 뒤에 와야 같은 특이도에서 이긴다. */
button.avatar-chip:hover .avatar-chip-text > span {
  color: var(--system-c-area-b-accent-font-color) !important;
}
button.avatar-chip:hover .avatar-chip-label {
  color: var(--system-c-area-b-accent-desc-font-color) !important;
}

.avatar-chip-text {
  min-width: 0;
}

.avatar-chip-text > span {
  display: block;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.avatar-chip-label {
  color: var(--system-c-area-b-base-desc-font-color) !important;
}

.avatar-circle {
  width: 10cqi;
  height: auto;
  aspect-ratio: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background-position: center;
  background-size: cover;
  overflow: hidden;
}

.character-color-groups {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-self: end;
  gap: 0;
  margin: 0;
}

.profile-character-extra {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.character-color-square {
  position: relative;
  display: inline-block;
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  border: 0;
}

/* 이름(+공개범위 아이콘)은 첫 줄, 설명(bio)은 다음 줄로 내린다.
   둘 다 가운데 정렬한다(요청) — 카드가 아바타 중심이라 왼쪽 정렬이면 축이 어긋난다. */
.character-card-title-row {
  flex-wrap: wrap;
  justify-content: center;
  text-align: center;
}

.character-card-title-row .grid-cell-title,
.character-card-inline-meta {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.character-card-title-row .grid-cell-title {
  flex: 0 1 auto;
  font-weight: 700;
}

.character-card-inline-meta {
  flex: 1 1 100%;
  margin-top: 1px;
  text-align: center;
}
.character-tab-toolbar {
  display: flex;
  margin-bottom: 10px;
}

/* 이미지 탭 */
.character-images-grid {
  margin-top: 0;
}

.character-image-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.character-image-thumb {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 8px;
  object-fit: cover;
}

/* 셀 좌하단 출처 라벨 — sys-c 컨텐츠 테마(.window-tooltip과 같은 레시피). */
.character-image-source-label {
  position: absolute;
  left: 6px;
  bottom: 6px;
  /* 글자가 상자 안에서 아래로 쏠려 보였다(요청) — line-height 로 어림잡는 대신
     flex 로 가운데에 놓고 위아래 여백을 같게 준다. */
  display: inline-flex;
  align-items: center;
  min-height: 18px;
  padding: 0 6px;
  font-size: 11px;
  line-height: 1;
  border-radius: 6px;
  pointer-events: none;
  color: var(--system-c-area-b-base-font-color);
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
}

/* 상세 이미지 탭 그리드 — 사용자 활동 탭(.activity-list)과 완전히 같은
   마스너리 방식: 한 줄 최대 5개(그 이상 폭이 남으면 썸네일이 넓어짐),
   각 이미지는 원본 비율 그대로 유지하고 세로 위치는 JS가 grid-row 스팬을
   계산해 채운다(layoutCharacterImagesGrid) — CSS 다단(column-*)은 이미지가
   적고 비율 편차가 크면 뒤쪽 열을 비워서 아마리 3장 케이스가 깨졌다. */
[data-character-images-grid] {
  display: grid;
  width: 100%;
  grid-template-columns: repeat(auto-fill, minmax(min(max(230px, calc((100% - 12px) / 5)), 100%), 1fr));
  grid-auto-flow: row dense;
  grid-auto-rows: 1px;
  align-items: start;
  gap: 3px;
}

[data-character-images-grid] > .character-image-cell {
  position: relative;
  display: block;
  margin: 0;
  padding: 0;
  border: 0 !important;
  border-radius: 0;
  background: transparent !important;
  box-shadow: none !important;
}

[data-character-images-grid] > .character-image-cell:hover {
  background: transparent !important;
  box-shadow: none !important;
}

[data-character-images-grid] .character-image-thumb {
  display: block;
  height: auto;
  aspect-ratio: auto;
  border-radius: 0;
}

/* '이미지 연결하기' 모달 — 그리드/체크박스 자체는 목록 창 선택모드 CSS
   (.grid-cell.is-selectable 등, homepage.css)를 그대로 재사용하고, 여기선
   취소/연결 버튼을 스크롤을 따라오는 하단 고정 바로 둔다. */
.character-image-link-actions {
  position: sticky;
  bottom: 0;
  z-index: 6;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin: 8px 0 0;
  padding: 10px;
  border-radius: 10px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* Shift+클릭 범위 선택 시 이미지/텍스트가 드래그 선택되지 않게. */
[data-character-image-link-grid] {
  user-select: none;
  -webkit-user-select: none;
}

/* 소유자 "이미지 관리" 팝업 */
.character-owner-image-manager {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 100%;
  /* 우측 하단 고정 툴바에 마지막 줄이 가리지 않게. */
  padding-bottom: 52px;
}
/* 추가/삭제 버튼만 우측 하단에 띄운다(요청) — 감싸는 판(배경·테두리)은 없다.
   position:fixed 는 창이 transform 을 갖는 순간 기준이 어긋나므로, 스크롤되는
   .window-content 가 아니라 그 안의 래퍼(.character-owner-image-manager,
   position:relative)를 기준으로 삼는다. */
.character-owner-image-actions {
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 3;
  display: flex;
  gap: 6px;
}
.character-owner-image-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(max(150px, calc((100% - 16px) / 5)), 100%), 1fr));
  gap: 4px;
  align-content: start;
  user-select: none;
  -webkit-user-select: none;
}
.character-owner-image-cell {
  position: relative;
  padding: 0;
  border: 2px solid transparent !important;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  background: transparent !important;
}
.character-owner-image-cell.is-linked { border-color: var(--focus-color) !important; }
/* 출처 입력 팝업 — 밑줄 입력과 버튼 줄이 붙어 보여 사이를 띄운다(요청). */
.character-image-source-dialog .confirm-dialog-actions {
  margin-top: 14px;
}
.character-owner-image-cell.is-checked { outline: 2px solid var(--focus-color); outline-offset: -2px; }
.character-owner-image-thumb {
  display: block;
  width: 100%;
  /* 원본 비율 유지(요청) — 행 높이는 layoutCharacterImagesGrid 가 계산한다.
     이미지 탭(.character-image-thumb)과 같은 방식. */
  height: auto;
  aspect-ratio: auto;
  object-fit: contain;
}
.character-owner-image-check {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 18px;
  height: 18px;
  margin: 0;
  pointer-events: none; /* 셀 클릭이 선택을 처리 — 체크박스는 표시만 */
  accent-color: var(--focus-color);
}
.character-relation-target {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 10px;
  border: 0 !important;
}
/* 탭 헤더 고정은 profile.css .profile-tabs / .profile-activity-panes 규칙. */

/* 캐릭터 탭 버튼은 탭 개수와 무관하게 최대 1/3 폭 — 이미지 탭 하나만 남아도
   전폭으로 늘어나지 않고 좌측 1/3만 채우며 가장 먼저 표시된다. */
.window[data-root="character"] .profile-tabs .bg-region-tab {
  flex: 1 1 0;
  max-width: 33.333%;
}

/* 이미지 탭 연결/해제 버튼 — 스크롤되는 이미지 팬 안에서 상단에 고정되고 상시
   표시된다. height:0 이라 그리드 레이아웃은 건드리지 않는다. 권한 없으면 hidden. */
.character-images-admin-actions {
  position: sticky;
  top: 6px;
  z-index: 5;
  height: 0;
  overflow: visible;
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  padding-right: 6px;
}
/* 이미지 위에서도 버튼이 떠 보이게 그림자만 살짝. */
.character-images-admin-actions > button {
  box-shadow: 0 1px 6px -2px rgba(var(--system-c-area-b-base-font-rgb), .4);
}
.character-images-admin-actions[hidden] {
  display: none;
}
/* 좁은 창: 이미지 팬이 .window-content와 함께 스크롤되고 탭은 sticky top:0 이므로
   버튼은 탭 높이만큼 내려 붙는다(넓은 창은 팬이 독립 스크롤이라 top:6px).
   탭 줄이 41px 이라 36px 은 오히려 겹쳤다 — 그 아래로 내리고 사이를 띄운다(요청). */
@container profile-detail (max-width: 840px) {
  .character-images-admin-actions { top: 50px; }
}

/* 붙어 있던 탭 줄과 버튼 사이 간격(요청) — 버튼줄은 height:0 이라 자기
   margin 이 뒤따르는 그리드까지 같이 밀어 준다(둘이 같은 자리에 떠 있는 구조라
   따로 벌리면 오히려 어긋난다). */
@container profile-detail (max-width: 840px) {
  .character-images-admin-actions:not([hidden]) {
    margin-top: 14px;
  }
}

.character-image-unlink-actions {
  position: sticky;
  right: 12px;
  bottom: 12px;
  z-index: 5;
  display: flex;
  justify-content: flex-end;
  pointer-events: none;
}

.character-image-unlink-actions > button {
  pointer-events: auto;
}
/* 타임라인 탭 */
.character-timeline-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.character-entry-card {
  padding: 10px 15px;
  border-radius: 5px;
  box-shadow: 0 0 5px -2px rgba(0, 0, 0, .14);
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  border: 2px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
}

.character-entry-card .post-markdown-body {
  margin-top: 8px;
}

.character-entry-date-input {
  flex: 0 1 180px;
  min-width: 120px;
}

.character-timeline-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.character-timeline-title {
  margin: 0;
  font-size: 13px;
  flex: 1 1 auto;
  min-width: 0;
}

.character-timeline-admin-actions:not([hidden]) {
  display: flex;
  gap: 6px;
  margin-left: auto;
}
.character-color-editor {
  width: 100%;
  margin-bottom: 0;
}

.character-color-rows {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* 이동 가능한 행은 content-input-box 대신 자체 배경(System C 컨텐츠)을 쓴다. */
.character-color-row {
  display: grid;
  grid-template-columns: 24px 23px minmax(50px, 1fr) auto auto;
  align-items: center;
  gap: 0;
  width: 100%;
  box-sizing: border-box;
  min-height: 30px;
  padding: 2px 2px 2px 8px;
  border-radius: 5px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  user-select: none;
}
.character-color-row [data-character-color-add-after],
.character-color-row [data-character-color-remove] {
  min-width: 40px;
  padding-inline: 4px;
}
.character-color-row.is-drag-source { display: none; }

/* 카드 하단 줄의 "댓글 N" — 눌러서 댓글 팝업을 여는 자리라 밑줄로 표시한다(요청). */
/* 검색칸 오른쪽 로딩 표시(요청) — 원 자체는 .user-loading-spinner(user.css)와
   같은 방식이되, 입력 줄 안에 들어가는 크기(14px)로 둔다. .auth-field 는
   position:relative 라 이 자리 기준이 된다.
   오른쪽 끝은 지우기(×) 자리이고 로딩 원은 그 왼쪽이다(요청). 26px = 지우기 버튼
   폭(.auth-clear 22px) + 여백. 브라우저 기본 지우기는 자리를 우리가 못 정해
   (padding-right 만큼 안쪽으로 들어와 로딩 원보다 왼쪽에 놓였다) 감추고 앱의
   .auth-clear 를 쓴다. */
.character-relation-search-field .inline-spinner {
  position: absolute;
  right: 26px;
  bottom: 8px;
  width: 14px;
  height: 14px;
  box-sizing: border-box;
  border: 2px solid var(--system-c-area-b-base-desc-font-color) !important;
  border-top-color: var(--focus-color) !important;
  border-radius: 50%;
  animation: user-spinner 700ms linear infinite;
  pointer-events: none;
}
.character-relation-search-field .inline-spinner[hidden] {
  display: none !important;
}
/* 글자가 로딩 원·지우기 둘 다와 겹치지 않게 오른쪽을 비워 둔다. */
.character-relation-search-field .auth-input {
  padding-right: 48px;
}
/* 브라우저 기본 지우기 단추는 감춘다 — 앱의 .auth-clear 와 둘이 겹쳐 보였다. */
.character-relation-search-field .auth-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}
/* 아직 프로필이 작성되지 않은 상대는 이름 앞에 작은 태그로 알린다(요청). */
.character-relation-pending {
  display: inline-flex;
  align-items: center;
  min-height: 16px;
  margin-right: 4px;
  padding: 0 5px;
  border-radius: 5px;
  font-weight: 400;
  color: var(--system-c-area-b-base-desc-font-color);
  border: 1px solid var(--system-c-area-b-base-desc-font-color) !important;
  background: transparent;
}

/* 관계 설명 — 떠오르는 라벨 없이 밑줄 입력만(요청). placeholder 가 라벨 역할. */
.character-relation-label-input {
  width: 100%;
  padding: 2px 0 4px;
  font-size: inherit;
}

/* 포커스로 밑줄이 1px→2px 이 되는 만큼 아래 여백에서 되돌린다(합이 5px 로 같음). */
.character-relation-label-input:focus {
  padding-bottom: 3px;
}

/* ==========================================================================
   정보 탭 — 활동 탭과 같은 마스너리 그리드에 카드를 늘어놓는다(요청).
   자유 입력 글과 크툴루의 부름 시트가 같은 칸에 섞여 놓인다.
   ========================================================================== */
.character-entry-cell {
  display: flex;
  flex-direction: column;
  gap: 6px;
  cursor: pointer;
}
.character-entry-cell-head { display: flex; align-items: baseline; gap: 6px; }
.character-entry-cell-title { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; }
/* 시트임을 알리는 작은 칩 — 판정 칩과 같은 방식으로 제 글자색을 옅게 깐다. */
.character-entry-kind {
  flex: 0 0 auto;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 10px;
  background: color-mix(in srgb, currentColor 14%, transparent);
}
.character-entry-preview { margin: 0; font-size: 12px; line-height: 1.5; opacity: .75; }
.character-sheet-brief { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.character-sheet-brief-head { opacity: .75; }
.character-sheet-brief-stats { display: flex; flex-wrap: wrap; gap: 4px 10px; }
.character-sheet-brief-stats b { font-weight: 700; opacity: .6; margin-right: 2px; }

/* 시트/글 읽기 창 — 시트는 작성 화면과 같은 칸을 고칠 수 없는 상태로 보여 준다(요청). */
.character-entry-view { display: flex; flex-direction: column; gap: 8px; padding: 12px; }

/* 시트 작성 서식 */
.character-sheet-editor { display: flex; flex-direction: column; gap: 12px; padding: 9px; overflow-y: auto; }
/* 시트에서는 인풋 안의 글자만 끌어 고른다(요청) — 제목줄·여백을 끌어도 잡히지 않게
   판이 아니라 폼 전체에 건다. */
.character-sheet-form,
.character-entry-view.is-sheet { user-select: none; }
.character-sheet-form input,
.character-sheet-form textarea { user-select: text; }
/* 라벨도 본문 글자색으로 — 설명용 흐린 색을 쓰지 않는다(요청, CoC 시트 한정). */
.character-sheet-editor .auth-label { color: var(--system-c-area-b-base-font-color); }
.character-sheet-editor .auth-input:focus + .auth-label { color: var(--focus-color); }
/* 특성치 주사위 — 그 칸을 만지고 있을 때만 오른쪽 아래에 나타난다(요청). */
/* 주사위는 숫자 바로 오른쪽에, 숫자와 같은 크기로 선다(요청). 값이 오른쪽 정렬이라
   칸 오른쪽 끝에 두고 그만큼 숫자를 물리면 늘 숫자 옆에 붙는다. */
.character-sheet-roll {
  position: absolute;
  right: 0;
  bottom: 10px;
  padding: 0;
  /* 숫자와 같은 높이로 세운다(요청) — 칸 글자 크기 그대로, 글자 바닥(베이스라인)에 맞춰
     올린다. 인풋 아래 여백 6px + 내림값 약 4px 만큼 띄우면 숫자 밑선과 나란해진다. */
  width: 14px;
  height: 14px;   /* .auth-input 의 글자 크기 */
  font-size: 14px;
  display: grid;
  place-items: center;
  opacity: 0;
  /* 안 보일 땐 잡히지도 않게 — 숨은 채로 이름표(툴팁)가 뜨던 문제(요청). */
  pointer-events: none;
  transition: opacity .12s ease;
}
.character-sheet-field.is-stat:focus-within .character-sheet-roll { opacity: .75; pointer-events: auto; }
.character-sheet-roll:hover { opacity: 1 !important; }
.character-sheet-roll .character-sheet-icon { width: 14px; height: 14px; opacity: 1; }
/* 주사위 자리를 비워 둔다 — 값이 버튼 밑으로 들어가지 않게. */
.character-sheet-field.is-stat:focus-within .auth-input { padding-right: 18px; }
.character-sheet-fieldset { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px; }
/* 특성치는 셋씩 늘어놓되, 좁아지면 열을 줄인다(요청) — 칸이 눌려 글자가 잘리지 않게.
   열 사이는 넉넉히 띄운다(요청) — 옆 칸의 수준도와 이름이 붙어 보이지 않게. */
/* 넓을 땐 셋, 한 칸이 190px 아래로 눌릴 만큼 좁아지면 둘·하나로 줄어든다 —
   최소 너비를 "세 열로 나눈 폭" 과 190px 중 큰 쪽으로 잡으면 넷으로 벌어지지 않는다. */
.character-sheet-fieldset.is-stats {
  grid-template-columns: repeat(auto-fit, minmax(max(190px, calc((100% - 40px) / 3)), 1fr));
  gap: 10px 20px;
}
/* 값은 오른쪽에 붙여 적는다(요청) — 자릿수가 달라도 눈이 한 줄에 선다.
   .auth-input 의 오른쪽 여백 20px 은 로그인 폼의 지우기(×) 자리라 여기선 쓸모가 없다.
   그대로 두면 숫자만 20px 안쪽으로 들어가 위의 수준도와 오른쪽 끝이 어긋난다. */
.character-sheet-field.is-stat .auth-input { text-align: right; padding-right: 0; }
/* 수준도 — 떠오른 라벨과 같은 줄 오른쪽 끝. */
.character-sheet-field.is-stat { position: relative; padding-left: 26px; }
/* 아이콘 — 특성·기능마다 제 그림을 왼쪽에 둔다(요청). 칸 안에서는 라벨과 입력칸을
   합친 높이를 그대로 차지하고(위아래 0), 그림은 그 안에서 가운데에 선다. */
.character-sheet-icon { width: 16px; height: 16px; flex: 0 0 auto; opacity: .6; }
/* 창 테마가 `body *` 로 모든 요소에 color 를 박아 둔다 — 그대로면 아이콘 속 <g>(fill:currentColor)
   가 아이콘 색이 아니라 본문 색으로 풀려, svg 에 color 를 줘도 그림이 안 물든다.
   안쪽은 아이콘 색을 물려받게 해 아이콘 한 벌의 색을 svg 의 color 하나로 정한다. */
.character-sheet-icon * { color: inherit; }
/* 칸 안에서는 라벨+입력칸을 합친 높이를 그대로 차지한다(요청) — 그림 자체는
   viewBox 비율을 지켜(preserveAspectRatio 기본값) 그 안에서 가운데에 선다. */
.character-sheet-field.is-stat > .character-sheet-icon { position: absolute; left: 0; top: 0; width: 20px; height: 100%; }
/* 라벨은 절대 배치라 아이콘 자리만큼 오른쪽에서 시작해야 겹치지 않는다. */
.character-sheet-field.is-stat .auth-label { left: 26px; }
.character-sheet-level {
  position: absolute;
  right: 0;
  top: 0;
  font-size: 11px;
  color: var(--system-c-area-b-base-font-color);
  pointer-events: none;
  /* 라벨 자리를 남기고, 좁은 창에서 넘치면 말줄임한다. */
  max-width: calc(100% - 56px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 칸은 떠오르는 라벨 밑줄 인풋(.auth-field) — 라벨이 뜰 자리만 위에 비워 둔다. */
.character-sheet-field { font-size: 12px; }
.character-sheet-field textarea.auth-input { resize: none; }
.character-sheet-skill-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; }
.character-sheet-skill-head > strong { margin-right: auto; }
/* 기능도 특성치와 같은 칸이라 같은 배치를 쓴다(요청) — 좁아지면 열이 줄어든다. */
.character-sheet-skill-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(190px, calc((100% - 40px) / 3)), 1fr));
  gap: 10px 20px;
}
/* 기능 칸 — 값이 늘 있으므로 라벨(기능 이름)은 떠 있는 자리에 고정한다.
   밑줄 너비는 특성치와 같아야 하므로 칸에 오른쪽 여백을 두지 않는다(요청) —
   ± 는 그 위에 얹고, 만지는 동안에만 숫자를 그만큼 왼쪽으로 물린다. */
.character-sheet-field.is-skill .auth-label { top: 0; font-size: 11px; }
.character-sheet-field.is-skill .auth-input { cursor: ew-resize; }
.character-sheet-field.is-skill:focus-within .auth-input { padding-right: 16px; }
.character-sheet-field.is-skill.is-locked .auth-input { cursor: default; }
/* 기능 이름이 길어 수준도가 절반을 넘지 않게 묶어 둔다 — 넘치면 말줄임. */
.character-sheet-field.is-skill .character-sheet-level { max-width: 56%; }
/* 값이 있는 기능은 아이콘을 강조색으로 물들인다(요청) — 숫자는 본문 색 그대로.
   아이콘 안쪽 <g> 는 창 테마가 color 를 따로 박아 두어 currentColor 가 검정으로
   풀린다 — 그래서 색만 바꾸지 않고 fill 을 직접 칠한다. */
.character-sheet-skill-row.is-valued > .character-sheet-icon { opacity: 1; }
.character-sheet-skill-row.is-valued > .character-sheet-icon,
.character-sheet-skill-row.is-valued > .character-sheet-icon * {
  color: var(--focus-color);
  fill: var(--focus-color);
}
/* 기능 추가 줄 — 이름만 받는 칸이라 ± 도 수준도도 없다. */
.character-sheet-skill-row.is-blank .auth-input { cursor: text; }
/* 직접 넣은 기능은 라벨 자리가 곧 이름 입력칸이다 — 라벨과 같은 글자·자리로 맞춘다. */
.character-sheet-skill-name-input {
  position: absolute;
  left: 26px;
  top: 0;
  width: calc(100% - 40px);
  padding: 0;
  border: 0 !important;
  background: transparent !important;
  font-size: 11px;
  line-height: 1.4;
  color: var(--system-c-area-b-base-desc-font-color);
}
/* ± 는 오른쪽에 세로로 붙고, 그 칸을 만지고 있을 때만 나타난다(요청). */
.character-sheet-skill-steps {
  position: absolute;
  right: 0;
  bottom: 2px;
  display: flex;
  flex-direction: column;
  opacity: 0;
  /* 안 보일 땐 잡히지도 않게 — 숨은 버튼에 이름표가 뜨던 문제(요청). */
  pointer-events: none;
  transition: opacity .12s ease;
}
.character-sheet-field.is-skill:focus-within .character-sheet-skill-steps { opacity: 1; pointer-events: auto; }
.character-sheet-field.is-skill.is-locked .character-sheet-skill-steps { display: none; }
.character-sheet-skill-steps button { padding: 0; width: 14px; height: 12px; line-height: 1; font-size: 11px; opacity: .6; }
.character-sheet-skill-steps button:hover { opacity: 1; }
/* 성장 기록 칸 — 그 줄 바로 아래에 열리고 열 하나를 통째로 쓴다. */
.character-sheet-grow-form {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 6px 2px 8px;
  border-bottom: 1px solid rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha)) !important;
}
.character-sheet-grow-form input[data-grow-value] { width: 62px; }
.character-sheet-grow-form input[data-grow-note] { flex: 1 1 120px; }
.character-sheet-grow-past { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 4px; font-size: 11px; }
.character-sheet-grow-item { display: inline-flex; align-items: center; gap: 2px; }
.character-sheet-grow-item button { padding: 0 2px; line-height: 1; }
.character-sheet-points-left { font-size: 11px; opacity: .7; white-space: nowrap; }
.character-sheet-points-left b { font-size: 13px; }
.character-sheet-points-left b.is-over { color: #e0483a; }
/* 탭 줄과 내용 사이 여백 — 사용자 활동 탭(.activity-list)과 같은 값이 없어 붙어 있었다(요청). */
.character-images-grid,
.character-timeline-list { padding-top: max(10px, var(--panel-pad, 0px)); }
/* 이미지 탭의 [+] 도 정보 탭과 같은 자리에 둔다 — 그 탭일 때만 보인다. */
.window:not(:has([data-profile-pane="images"].is-active)) > .character-entry-fab.is-images { display: none; }
/* 정보 탭의 [+] — 다른 목록 화면의 FAB 와 같은 자리(창 우측 하단). bindCharacterEntries 가
   창에 바로 붙이므로(스크롤하지 않는 판) absolute 로 제자리에 남는다.
   (.window-content 의 backdrop-filter 때문에 fixed 는 그 스크롤 판 기준이 되어 밀렸다.) */
.character-entry-fab { position: absolute; }
/* 타임라인 탭의 [+] 도 같은 자리에 둔다 — 그 탭일 때만 보인다. */
.window:not(:has([data-profile-pane="timeline"].is-active)) > .character-entry-fab.is-timeline { display: none; }
/* 다른 탭을 보고 있을 땐 숨긴다 — 판 밖으로 나왔으므로 탭 상태를 직접 본다. */
.window:not(:has([data-profile-pane="info"].is-active)) > .character-entry-fab:not(.is-images):not(.is-timeline) { display: none; }

/* ==========================================================================
   캐릭터 상세 — 공유 기록과 같은 사이드바 레이아웃(shared.css .shared-*) 위의 홈 화면.
   ========================================================================== */
.shared-main.is-home,
/* 관계 화면도 같은 한 장짜리 판이다(요청) — 본문 판이 판 안에 또 생기지 않게. */
.shared-main.is-relation { display: flex; flex-direction: column; overflow: hidden; container-type: inline-size; }
/* 전신 이미지는 홈 칸(.character-home)까지만 덮는다(요청) — 그 아래로 이어지는 댓글은
   배경 밖이라 보통 판(영역 B)을 그대로 따른다. */
/* 본문은 넘칠 때만 스크롤한다 — 안 넘치면 홈 전체가 한 화면에 들어온다(요청). */
.shared-main.is-home .post-comments { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.shared-main.is-home [data-post-sheet] { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.shared-main.is-home > .profile-activity-pane,
.shared-main.is-relation > .profile-activity-pane { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
/* 댓글 입력줄은 컨텐츠 판 바깥에서 그 아래 칸을 차지한다(요청) — 채팅 푸터와 같은 자리. */
.shared-content > .post-footer { flex: 0 0 auto; padding: 0; }
/* 입력 카드는 본문 폭을 그대로 따른다(요청) — 공용 규칙의 720px 가운데 정렬은
   본문이 720px 로 묶인 게시글 상세용이라 여기선 본문과 어긋난다(페어 채팅 푸터와 같은 처리). */
.shared-content > .post-footer .comment-compose { max-width: none; margin-inline: 0; }
/* 본문 판(.post-content)이 이미 판(.shared-main) 안이라 테두리·배경을 벗긴다. */
.shared-main.is-home [data-post-sheet],
.shared-main.is-relation [data-post-sheet] { max-width: none; padding: 0 4px; border: 0 !important; border-radius: 0; background: transparent !important; }
/* 홈 본문(요청) — 전신 이미지는 판 전체(.shared-main.is-home)를 덮고, 프로필만 그 위
   오른쪽에 얹힌다. 그래서 여기엔 높이를 따로 주지 않는다 — 내용만큼만 차지한다. */
/* 위엔 메타(+보는 화면의 한마디), 아래엔 기본 프로필 — 둘 다 오른쪽에 붙는다(요청). */
.character-home {
  position: relative; min-height: 100%;
  /* 자리를 따로 정하지 않았으면 메타 → 한마디 → 기본 프로필 차례로 우측 상단부터 쌓인다(요청).
     흐름 배치라 서로 겹칠 일이 없다. 자리를 정한 칸만 아래 규칙으로 띄운다. */
  display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-start;
}
/* 무대(3:4)가 칸이 좁아 작아지면 그 위의 글씨도 같은 비율로 줄인다(요청) — fitPortrait 가
   --stage-scale 을 넣는다. 공용 규칙(body * → 12px)을 되받아야 해서 자손까지 직접 적는다.
   버튼 줄(수정 모드)은 제 크기를 지킨다. */
.character-home :is(.character-home-head, .character-home-quote, .character-home-info),
.character-home :is(.character-home-head, .character-home-quote, .character-home-info)
  *:not(.character-home-message):not(.character-home-form-head):not(.character-home-form-head *) {
  font-size: calc(12px * var(--stage-scale, 1));
}
/* 글자 자리 지정(요청) — 소유자가 정한 세로 자리(칸 높이 비율)로 띄운다. 가로는 오른쪽 고정이라
   left 는 건드리지 않는다. 자리를 정한 칸만 절대 배치가 되고, 나머지는 원래 흐름 그대로다. */
/* 메타 줄(.character-home-head)은 늘 우측 상단 고정이라 여기 끼지 않는다(요청). */
/* 수정 폼(.character-home-form)은 보는 화면의 기본 프로필과 같은 클래스를 쓰지만 훨씬 길다 —
   정해 둔 자리에 띄우면 화면 아래로 꽂혀 잘린다(요청). 자리는 보는 화면으로 잡는다. */
/* 수정 폼도 보기의 기본 프로필과 똑같이 정해 둔 자리에 띄운다(요청) — 폼이 길어 잘리면
   그대로 끌어 올리면 된다(수정 모드에서는 늘 끌 수 있다). */
.character-home.is-msg-placed .character-home-quote,
.character-home.is-info-placed .character-home-info {
  position: absolute; right: var(--stage-right, 0px); left: auto; margin-right: 0;
}
/* 띄운 한마디는 메타 자리를 비워 둘 이유가 없다 — 글 두 줄만큼만 잡는다(요청). */
.character-home.is-msg-placed .character-home-quote { top: calc(var(--home-msg-y) * 100%); padding-top: 0; }
.character-home.is-info-placed .character-home-info { top: calc(var(--home-info-y) * 100%); }
/* 수정 폼은 보기 판보다 길다 — 흐름에 두면 홈 칸이 세로로 늘어나 무대(3:4)까지 커진다(요청:
   보기와 같게). 띄워서 보기 판이 있던 자리(아래 오른쪽)에 세우고, 자리를 정했으면 그 자리로. */
.character-home.is-editing [data-character-form] {
  position: absolute; right: var(--stage-right, 0px); left: auto;
  top: var(--home-form-top, auto); bottom: auto; margin-right: 0;
}
.character-home.is-editing.is-info-placed [data-character-form] { top: calc(var(--home-info-y) * 100%); }
/* 버튼 줄이 메타 자리로 올라오면 그 줄만큼 층을 올린다 — 프로필 판을 그 위로 끌어도 눌린다. */
.character-home.is-editing .character-home-head { z-index: 3; }
/* 수정 중에는 메타를 감춘다(요청) — 그 자리는 버튼 줄이 쓴다. 등록 중(is-editing 이 아직
   없는 새 캐릭터)에도 같게 보이도록 폼 유무로도 건다. */
.character-home.is-editing .character-home-head .post-meta,
.character-home:has([data-character-form]) .character-home-head .post-meta { display: none; }
/* 메타(날짜·조회수·좋아요·댓글)는 늘 우측 상단이다(요청) — 한마디를 어디로 옮겨도 그대로. */
.character-home-head {
  position: absolute; top: 0; right: 0; z-index: 1;
  box-sizing: border-box; width: min(var(--stage-width, 100%), 460px); padding: 10px 12px 0; text-align: right;
}
/* 한마디는 메타 아래에서 시작한다(메타가 떠 있으므로 그 높이만큼 비워 둔다) — 끌면 옮겨진다. */
.character-home-quote {
  position: relative; z-index: 1; right: var(--stage-right, 0px);
  box-sizing: border-box; width: min(var(--stage-width, 100%), 460px); padding: 34px 12px 0; text-align: right;
}
/* 수정 중에도 한마디는 보기와 같은 자리에서 고친다(요청) — 칸 안의 <textarea> 가 곧 그 글이다. */
.character-home-quote textarea.character-home-message {
  display: block; width: 100%; box-sizing: border-box;
  text-align: right; resize: none; outline: none;
  font-family: inherit;
}
/* 보는 화면의 한마디는 메타 바로 밑 큰 글씨다(요청). */
/* 보는 화면의 한마디는 말풍선이 아니라 인용구다(요청) — 바탕 없이 양 옆에 쌍따옴표를 달고
   굵게·기울여 쓴다. NotoSansKR 에는 기울임 꼴이 없어 브라우저가 기울여 그린다(합성 oblique)
   — 글꼴 파일을 더 받지 않으려고 그대로 둔다. */
.character-home-quote .character-home-message {
  font-size: calc(20px * var(--stage-scale, 1)); line-height: 1.4; margin: 6px 0 0; padding: 0;
  /* 두 줄로 넘어가도 오른쪽에 붙는다(요청) — 말풍선 규칙의 text-align:left 를 되받는다. */
  text-align: right;
  font-weight: 700; font-style: italic;
  background: transparent !important;
  border: 0 !important;
  color: inherit !important;
}
.character-home-quote .character-home-message::before { content: '\201C'; }
.character-home-quote .character-home-message::after { content: '\201D'; }
/* 그림 위의 흰 그라데이션 띠는 없앴다(요청) — 오른쪽 1/3 을 덮어 글씨를 읽히게 하던 판이다.
   글씨는 아래 규칙대로 여전히 검정이라, 밝은 그림 위에서 읽히는지는 그림마다 확인이 필요하다. */
/* 글씨 색은 그림 위에 놓인 "본문" 에만 준다 — 버튼 줄(공개범위 select·이미지 추가·저장·취소)은
   제 버튼 테마를 그대로 따른다(요청). 색 네모도 제 색을 지킨다. */
.character-home:has(.character-portrait-stack img) .character-home-info,
.character-home:has(.character-portrait-stack img) .character-home-head,
.character-home:has(.character-portrait-stack img) .character-home-quote,
.character-home:has(.character-portrait-stack img) .character-home-head *:not(.character-home-message):not(.character-home-form-head):not(.character-home-form-head *),
.character-home:has(.character-portrait-stack img) .character-home-quote *:not(.character-home-message),
.character-home:has(.character-portrait-stack img) .character-home-info *:not(.character-color-square):not(.character-home-form-head):not(.character-home-form-head *):not(.profile-bio-input):not(.character-home-message),
.character-portrait-preview .character-home-info,
.character-portrait-preview .character-home-info *:not(.character-color-square):not(.character-home-message) { color: #000 !important; }
.character-home:has(.character-portrait-stack img) .character-home-info ::placeholder,
.character-portrait-preview .character-home-info ::placeholder { color: rgba(0, 0, 0, .55) !important; }
/* 보는 화면에서는 글(메타·한마디·기본 프로필)이 그림 클릭을 가로채지 않는다(요청) —
   글이 덮은 자리를 눌러도 전신 뷰어가 열린다. 누를 것(고르개·버튼·링크)만 되살린다. */
.character-home:not(.is-editing):not(:has([data-character-form]))
  :is(.character-home-head, .character-home-quote, .character-home-info) { pointer-events: none; }
.character-home:not(.is-editing):not(:has([data-character-form]))
  :is(.character-home-head, .character-home-quote, .character-home-info)
  :is(a[href], button, input, textarea, select, .custom-select-wrap) { pointer-events: auto; }
/* 프로필은 배경 없이 그림 위에 바로 얹힌다(요청) — 색 네모만 제 색을 지킨다. */
.character-home-info {
  position: relative; z-index: 1;
  width: min(var(--stage-width, 100%), 460px); max-width: none; margin: 0 var(--stage-right, 0px) 0 0; padding: 10px 12px; text-align: right;
  background: transparent !important; border: 0 !important; box-shadow: none !important;
}
/* 편집 폼도 보는 화면과 같이 오른쪽으로 붙는다(요청) — 입력 글씨와 떠오르는 라벨,
   지우기(×) 자리, 색 줄까지. */
.character-home-info :is(input, textarea, select) { text-align: right; }
.character-home-info .auth-label { left: auto; right: 0; }
.character-home-info .auth-clear { right: auto; left: 0; }
/* .auth-input 의 오른쪽 20px 은 지우기(×) 자리였다 — ×를 왼쪽으로 옮겼으니 여백도 같이
   옮긴다. 안 그러면 값이 오른쪽 끝에서 20px 떠 있다(요청: 완전히 우측에 붙게). */
.character-home-info .auth-input { padding-right: 0; padding-left: 20px; }
/* 색 줄도 오른쪽에서부터 쌓는다 — 그리드의 1fr 칸이 폭을 다 먹어 색·코드가 왼쪽에 남아 있었다. */
.character-home-info .character-color-row {
  display: flex; justify-content: flex-end; align-items: center; gap: 6px; padding-right: 0;
}
/* 한마디 말풍선도 오른쪽을 보게 — 꼬리(각진 모서리)를 왼쪽 아래에서 오른쪽 아래로(요청). */
.character-home-info .profile-bio-input { border-radius: 14px 14px 4px 14px; }
/* 한마디 말풍선(.profile-bio-input)은 뺀다 — 제 영역 D 바탕을 지킨다(요청). */
.character-home-info :is(input:not([type="color"]), textarea:not(.profile-bio-input), select, .auth-field, .post-meta,
.character-profile-entry-row, .character-color-row, .character-profile-entry-editor, .character-color-editor) {
  background: transparent !important;
}
.character-home-avatar { display: flex; justify-content: flex-end; margin: 0 0 8px; }
.character-home-avatar-img {
  /* 무대가 작아지면 얼굴도 같이 줄인다(요청) — --stage-scale 은 fitPortrait 가 넣는다. */
  width: calc(96px * var(--stage-scale, 1)); height: calc(96px * var(--stage-scale, 1)); border-radius: 50%;
  display: grid; place-items: center; overflow: hidden;
  background-color: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  background-position: center; background-size: cover; background-repeat: no-repeat;
}
/* 판 안의 컨텐츠도 판처럼 모서리를 깎는다(요청) — 그림·채움·흰 그라데이션이 함께 잘린다. */
/* z-index 를 주어 스택이 제 층 세상을 갖는다 — 안쪽(채움판 0 / 그림 1 / 흰 그라데이션 2)은
   서로 겹쳐도, 판 전체는 글(.character-home-head/.character-home-info, z-index:1) 아래다.
   안 그러면 그라데이션(2)이 글까지 덮는다. */
.character-portrait-stack { position: absolute; inset: 0; z-index: 0; border-radius: 10px; overflow: hidden; }
/* 비어 있으면 볼 때는 자리를 차지하지 않고, 고칠 수 있는 사람에게만 보인다(요청). */
.character-portrait-stack.is-empty { display: none; }
.window.is-character-owner .character-portrait-stack.is-empty,
/* 등록 화면에서도 전신을 미리 정할 수 있게 빈 칸을 보여 준다(요청). */
.window.is-character-creating .character-portrait-stack.is-empty { display: block; }
/* 등록 중에는 그림을 눌러도 크게 보기가 열리지 않는다(요청) — 커서도 그대로 둔다. */
.window.is-character-creating .character-portrait-img { cursor: default; }
/* 등록 중에는 메뉴와 댓글을 감춘다(요청) — 아직 저장 전이라 갈 곳도 달 곳도 없다. */
.window.is-character-creating [data-character-nav],
.window.is-character-creating .post-comments .comments,
.window.is-character-creating .post-comments .comments-unsupported,
.window.is-character-creating .shared-content > .post-footer { display: none !important; }
/* 그림은 판 위에 바로 놓인다(요청) — 테두리도 바탕도 두지 않는다. 칸은 본문 전체다. */
.character-portrait-box {
  position: absolute; inset: 0; overflow: hidden;
  /* 무대 아무 데나 눌러도 크게 보기가 열린다(요청) — 그림은 3:4 칸으로 잘려 있어서
     그 밖(배경만 있는 자리)은 그림에 안 닿는다. */
  cursor: zoom-in;
  background: transparent;
  border: 0 !important;
  border-radius: 0;
  display: grid; place-items: center;
}
/* 칸이 그림보다 넓으면(전체를 다 써도 남으면) 그 빈자리를 같은 그림을 늘려·흐려서 채운다
   (요청) — 그림을 더 확대하지 않고도 판이 비지 않는다. 늘 뒤에 깔아 두고, 앞의 선명한
   그림이 덮는 자리는 어차피 안 보인다. */
.character-portrait-fill {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  /* 자리·크기는 fitPortrait 가 그림과 같은 기준점으로 계산해 넣는다(요청: 가로/세로에
     맞게 같이 늘고 움직인다) — 여기서는 되풀이 없이 한 장만 깔리게만 해 둔다. */
  background-repeat: no-repeat;
  filter: blur(2px) saturate(1.1); /* 요청으로 세 번 줄임(24 → 14 → 9 → 2px) */
  opacity: .55;
  /* 배경이 끊기는 자리는 fitPortrait 가 실제로 깔린 범위를 재서 마스크로 넣는다(요청) —
     칸을 다 못 채워도, 넘쳐 잘려도 끝이 부드럽게 사라진다. */
}
.character-portrait-fill[hidden] { display: none; }
.character-portrait-img { z-index: 1; }
.character-portrait-img { position: absolute; max-width: none; cursor: zoom-in; }
/* 버전 고르기(요청) — 무대 좌상단의 투명 select. 버전 목록과 [+ 버전 추가]가 들어 있고,
   추가를 고르면 빈 캔버스 자리가 생긴다(그림을 넣으면 정식 버전이 된다). */
/* 버전 고르기(요청) — 기본 프로필의 아바타 바로 위, 아바타와 같이 오른쪽 끝에 붙는다.
   네이티브 select 는 appearance:auto 라 배경을 못 비우고 드롭다운도 창 테마를 안 따라서,
   다이어리 연·월 고르기와 같은 투명 커스텀 select(UI.enhanceSelect + .transparent-select)를 쓴다. */
.character-home-info .custom-select-wrap.character-portrait-version {
  /* .custom-select-wrap 은 속의 select·버튼이 둘 다 absolute 라 제 폭이 0 이다 —
     버튼을 제자리(static)에 두어 버전명만큼 넓어지게 한다(아래 규칙). */
  width: max-content; max-width: 100%; min-height: 24px; margin: 0 0 4px auto;
  padding: 0 6px; font-size: 12px;
}
.character-home-info .custom-select-wrap.character-portrait-version .custom-select-button { position: static; }
.character-home-info .custom-select-wrap.character-portrait-version[hidden] { display: none; }
/* 버전명은 select 우클릭으로 고친다(요청) — 그 자리에 잠깐 서는 입력칸. */
.character-home-info .character-portrait-version-input { width: 100%; text-align: right; margin: 0 0 4px; }
/* 표정 줄(요청) — 기본 프로필 맨 아래에 아바타 + 그 아래 표정명, 누르면 그 표정으로 바뀐다.
   무대 우하단에 얹었더니 프로필과 겹쳐서 흐름 안으로 들였다. */
.character-face-strip {
  margin: 8px 0 0;
  display: flex; justify-content: flex-end; gap: 6px;
  max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
/* 표정이 셋 이상일 때 여는 목록의 작은 얼굴. */
.character-face-menu-img {
  display: inline-block; width: 20px; height: 20px; border-radius: 50%;
  background-size: cover; background-position: center top;
}
.character-face-strip::-webkit-scrollbar { display: none; }
.character-face-strip[hidden] { display: none; }
.character-face-chip {
  /* 아바타/이름을 칸 오른쪽에 붙인다(요청) — 가운데 두면 44px 그림이 56px 칸 안에서
     6px 안쪽에 앉아 위의 기본 프로필 아바타와 오른쪽 끝이 어긋나 보였다. */
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
  flex: 0 0 auto; width: 56px; padding: 2px 0 2px 2px; cursor: pointer;
  background: transparent; border: 0; color: inherit;
}
.character-face-chip-img {
  width: 44px; height: 44px; border-radius: 50%;
  background-size: cover; background-position: center top;
  border: 2px solid rgba(255, 255, 255, .35);
}
.character-face-chip.is-active .character-face-chip-img { border-color: var(--focus-color); }
.character-face-chip-name { font-size: 11px; max-width: 56px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 관계 화면(요청) — 프로필 | 무대(두 전신) | 프로필. 무대에선 발끝이 한 바닥에 선다. */
/* 전신 팝업(요청): 왼쪽 무대 + 오른쪽 모드 차례. 무대는 정사각이다 — 표시 영역이
   가로(16:9)·세로(9:16) 두 캔버스라 어느 쪽도 치우치지 않게. */
.character-portrait-stage {
  position: relative; justify-self: stretch;
  /* 팝업 안에서 남는 높이를 그대로 쓴다(요청: 스크롤 없이) — 비율은 안 고정한다. */
  height: 100%; width: 100%; min-height: 0; max-width: 100%;
  overflow: hidden; border-radius: 8px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  touch-action: none;
}
.character-portrait-stage.is-picking { cursor: pointer; }
.character-portrait-stage.is-moving { cursor: grab; }
.character-portrait-stage-empty { position: absolute; inset: 0; display: grid; place-items: center; font-size: 12px; opacity: .7; }
.character-portrait-stage-empty[hidden] { display: none; }
/* 표시 영역 단계에서 안 고른 쪽을 뒤에 깔아 같이 본다(요청) — 배경일 땐 더 흐리게. */
.character-portrait-ghost {
  position: absolute; pointer-events: none; opacity: .6;
  background-size: 100% 100%; background-repeat: no-repeat;
}
.character-portrait-ghost.is-behind { opacity: .35; filter: blur(var(--portrait-fill-blur, 2px)); }
.character-portrait-ghost[hidden] { display: none; }
/* 배경을 고른 동안엔 앞뒤를 바꾼다(요청) — 끌고 있는 배경이 흐린 채 뒤에 있고, 전신이 앞에 또렷하게 선다. */
.character-portrait-frame { z-index: 1; }
.character-portrait-ghost { z-index: 0; }
.is-fill-target .character-portrait-frame { z-index: 0; opacity: .35; filter: blur(var(--portrait-fill-blur, 2px)); }
.is-fill-target .character-portrait-ghost { z-index: 1; opacity: 1; filter: none; }
/* 무엇을 만질지 고르는 줄 + 크기 슬라이더(요청). */
.character-portrait-targets { display: flex; gap: 6px; flex-wrap: wrap; }
/* 이름 칸을 고정한 격자다(요청) — 이름이 길든 짧든 막대 길이가 늘 같다. */
.character-portrait-zoom { display: grid; grid-template-columns: 4.5em 1fr; align-items: center; gap: 10px; }
/* 라벨은 한 줄로(요청) — 좁은 팝업에서 "크 기"처럼 접히지 않게. */
.character-portrait-zoom > span { min-width: 0; white-space: nowrap; }
.character-portrait-zoom input { width: 100%; min-width: 0; }
.character-portrait-frame { position: absolute; user-select: none; }
.character-portrait-frame > img { display: block; width: 100%; height: 100%; }
/* 아바타 모드: 가운데 정사각 자리만 남기고 덮는다. */
.character-portrait-avatar-mask {
  /* 그림(.character-portrait-frame)이 z-index:1 이라 그 위로 올려야 원형 구멍이 보인다 —
     안 올리면 그림이 덮어 오버레이가 통째로 안 보인다(요청: 아바타 단계에서 원이 안 뜸).
     자리·크기는 자를 칸(viewport)과 같아야 해서 JS(paintStage)가 넣는다 — 무대에 꽉
     채우면 위아래가 잘린다(요청). */
  z-index: 2;
  position: absolute; border-radius: 50%; pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .5);
}
/* 표시 영역 모드(요청) — 캔버스 테두리 안이 홈에서 그림이 보일 자리, 그 위에 프로필
   미리보기를 얹어 실제로 어떻게 보일지 그대로 확인한다. 밖은 어둡게 덮는다. */
.character-portrait-canvas {
  position: absolute; z-index: 3; pointer-events: none; overflow: hidden;
  outline: 2px solid var(--focus-color);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .45);
}
.character-portrait-canvas[hidden] { display: none; }

/* 보이는 폭(표시영역) 가이드 — 어느 단계에서나 늘 보인다(요청). 표시 영역 단계의
   캔버스(.character-portrait-canvas)가 떠 있을 때는 그 테두리가 대신하므로 숨긴다. */
.character-portrait-guide {
  position: absolute; left: 0; right: 0; z-index: 3; pointer-events: none;
  border-top: 2px solid var(--focus-color);
  border-bottom: 2px solid var(--focus-color);
}
.character-portrait-guide[hidden] { display: none; }
/* 폭·자리 칸(요청) — 단계 칸 아래에 늘 붙는다. */

/* 홈 본문을 기준 크기로 그대로 그린 뒤 캔버스만큼 줄인다(요청) — 작은 글씨로 흉내 내면
   여백·줄바꿈이 실제와 달라진다. 크기·색·글씨는 전부 홈 규칙(.character-home*)이 정한다. */
.character-portrait-preview {
  position: absolute; left: 0; top: 0; transform-origin: top left; pointer-events: none;
}
.character-portrait-preview > .character-home { width: 100%; height: 100%; min-height: 0; }

.character-portrait-modes { display: flex; flex-direction: column; gap: 4px; }
.character-portrait-mode-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
/* 표정 추가 — 자른 아바타 미리보기 + 열 자 설명. */
.character-portrait-faces { display: flex; flex-direction: column; gap: 6px; max-height: 240px; overflow-y: auto; }
.character-portrait-face { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 8px; }
.character-portrait-face-crop {
  width: 44px; height: 44px; border-radius: 50%;
  background-repeat: no-repeat;
  background-color: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
}

.character-home-name { margin: 0 0 4px; display: flex; align-items: center; justify-content: flex-end; gap: 6px; min-width: 0; }
/* 이름이 칸보다 길면 자른다(요청) — 관계 화면의 좁은 칸에서 글씨가 넘치던 자리. */
.character-home-name-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.character-home-info .profile-bio-input,
.character-home-message {
  display: inline-block; box-sizing: border-box; max-width: 100%;
  margin: 0 0 10px; padding: 7px 10px; white-space: pre-wrap; text-align: left;
  border: 1px solid rgba(var(--system-c-area-d-base-border-rgb), var(--system-c-area-d-base-border-alpha)) !important;
  border-radius: 14px 14px 4px 14px;
  background: var(--system-c-area-d-base-color) !important;
  color: var(--system-c-area-d-base-font-color) !important;
}
.character-home-entries { margin: 0 0 10px; display: grid; grid-template-columns: max-content max-content; justify-content: end; gap: 4px 12px; }
.character-home-info .character-color-groups { justify-content: flex-end; }
.character-home-entry { display: contents; }
.character-home-entries dt { color: var(--system-c-area-b-base-desc-font-color); }
.character-home-entries dd { margin: 0; white-space: pre-wrap; }
/* 줄 간격은 보기 판과 같게 — 칸마다 제 아래 여백(아바타 8 / 이름 4 / 설명 10)을 갖고 있어
   여기서 gap 을 또 주면 수정 모드만 길어진다(요청: 보기와 같은 포맷). */
.character-home-form { display: flex; flex-direction: column; gap: 0; }
/* 알림 줄은 할 말이 있을 때만 자리를 차지한다 — 빈 줄이 판을 14px 늘렸다(요청). */
.character-home-form .post-editor-message:empty { min-height: 0; }
.character-home-form-head { display: flex; justify-content: flex-end; align-items: center; gap: 6px; flex-wrap: wrap; }
.character-home-message-input { width: 100%; box-sizing: border-box; }
/* 이름·설명 칸은 보기 화면과 같은 글자 크기·여백으로 둔다(요청) — 칸 이름표는 없애고
   이름은 placeholder 로, 설명은 보기의 dl(4px 12px)과 같은 간격으로 늘어놓는다. */
/* 이름 칸은 보기의 <h2>(.character-home-name)와 같은 크기·여백으로 둔다(요청). */
.character-home-info .character-home-name-input {
  font-size: inherit; font-weight: 700; line-height: 1.3; text-align: right; margin: 0 0 4px;
}
/* 설명 줄도 보기의 dl(.character-home-entries)처럼 오른쪽에서부터 두 칸으로 쌓는다(요청). */
.character-profile-entry-editor { display: flex; flex-direction: column; margin: 0 0 10px; }
.character-profile-entry-rows { display: flex; flex-direction: column; gap: 4px; }
.character-profile-entry-row { display: grid; grid-template-columns: max-content max-content; justify-content: end; gap: 4px 12px; align-items: center; }
.character-profile-entry-row .character-profile-entry-label { color: var(--system-c-area-b-base-desc-font-color); width: 5em; }
.character-profile-entry-row .character-profile-entry-content { width: 11em; }
/* 칸 높이도 보기 글줄에 맞춘다(요청) — 위아래 여백(4/6px)과 큰 글씨가 수정 모드만 길게 만들었다. */
.character-home-info :is(.character-home-name-input, .character-profile-entry-label, .character-profile-entry-content),
.character-home-info :is(.character-home-name-input, .character-profile-entry-label, .character-profile-entry-content):focus {
  /* 밑줄도 없앤다(요청) — 보기 화면엔 줄이 없다. .auth-input 쪽이 !important 라 여기도 필요하다. */
  border-bottom: 0 !important;
  /* 높이도 보기 줄과 같아야 한다(요청) — 보기의 dt/dd 는 line-height:normal 에 여백이 없다. */
  padding: 0; font-size: inherit; line-height: normal;
}
/* [+] 칸 — 보기의 색 네모와 같은 크기, 눌러서 색 고르개를 연다(요청). */
.character-color-square.character-color-add {
  display: inline-flex; align-items: center; justify-content: center;
  margin-left: 4px; cursor: pointer; line-height: 1; font-size: 12px;
  border: 1px dashed currentColor !important; background: transparent;
}
.native-color-picker-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.character-relation-pending { font-size: 11px; opacity: .6; }
/* 전신 추가/수정 다이얼로그 — 점 두 개(정수리·발끝)를 끌어 놓는다. */
/* 가로로 놓는다(요청) — 왼쪽은 그림, 오른쪽은 버전명·자세·표시 영역·고르기. */
/* 팝업은 스크롤 없이 안에서 나눠 갖는다(요청) — 높이를 정해 두고 본문이 남는 자리를 쓴다. */
.character-portrait-dialog {
  width: min(880px, 96%); max-width: min(880px, 96%);
  /* 폭이 줄면(작은 창·작은 브라우저) 세로도 같은 비율로 줄여 팝업 모양을 지킨다(요청) —
     창이 낮을 때는 90% 에서 멈춘다. */
  aspect-ratio: 880 / 565; height: auto; max-height: none; /* 실제 가로·세로는 JS(fitDialog)가 넣는다 */
  display: flex; flex-direction: column; gap: 10px; text-align: left; overflow: hidden;
}
/* 팝업은 미리보기 한 판이다(요청) — 단계 버튼도 슬라이더도 그 판 위에 떠 있다. */
.character-portrait-body { position: relative; display: block; min-height: 0; flex: 1 1 auto; }
.character-portrait-body > .character-portrait-stage { position: absolute; inset: 0; height: auto; }
.character-portrait-side {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px; padding: 8px;
  --portrait-side-w: calc(34px * 4 + 6px * 3);
}
.character-portrait-side > * { pointer-events: auto; cursor: grab; }
/* 툴바를 잡아 네 귀퉁이로 옮긴다(요청) — 그림에서 가려진 곳을 잠깐 보려는 것이라 저장하지 않는다. */
.character-portrait-side.is-left { align-items: flex-start; }
.character-portrait-side.is-bottom { justify-content: flex-end; }
.character-portrait-side.is-left .character-portrait-modes { justify-content: flex-start; }
.character-portrait-side.is-moving > * { cursor: grabbing; }
/* 단계 버튼은 동그란 아이콘 버튼이다(요청) — 이름은 툴팁으로만 준다. */
.character-portrait-mode-btn {
  width: 34px; height: 34px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}
.character-portrait-modes { gap: 6px; }
/* 여기 안내문은 "빈 목록" 문구가 아니라 곁줄이다 — 공용 여백을 걷고 왼쪽에 붙인다. */
.character-portrait-side .settings-empty { margin: 0; padding: 0; text-align: left; }
.character-portrait-modes { flex-direction: row !important; flex-wrap: wrap; justify-content: flex-end; }
/* 조작 줄은 판 아래 가운데에 뜬다 — 그림을 가리지 않게 넓이를 묶고, 없으면 자리도 없다. */
.character-portrait-mode-body {
  width: var(--portrait-side-w); max-height: 60%;
  padding: 8px; border-radius: 10px; overflow-y: auto; flex: 0 0 auto;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
}
.character-portrait-mode-body:empty { display: none; }
/* 자리·폭 칸(요청) — 단계 칸과 같은 폭·같은 바탕으로 그 아래에 붙는다. */
.character-portrait-stagebar {
  width: var(--portrait-side-w); flex: 0 0 auto;
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px; border-radius: 10px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
}
/* 목록(이미지·표정)은 버튼 폭으로는 못 본다 — 그 단계에서만 넓힌다. */
.character-portrait-mode-body:has(.character-portrait-gallery, .character-portrait-faces) { width: min(100%, 300px); }
/* 단계 칸이 넓어지는 단계(이미지·표정)에서는 자리·폭 칸도 같이 넓어진다(요청: 같은 너비). */
.character-portrait-side:has(.character-portrait-gallery, .character-portrait-faces) .character-portrait-stagebar { width: min(100%, 300px); }
/* 고른 것(전신/배경/한마디/기본 프로필)을 포커스 컬러 네모로 두른다(요청). */
.character-portrait-sel {
  position: absolute; z-index: 4; pointer-events: none;
  outline: 2px solid var(--focus-color); outline-offset: 1px; border-radius: 4px;
}
.character-portrait-sel[hidden] { display: none; }
.character-portrait-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 4px; max-height: 40vh; overflow-y: auto; }
.character-portrait-gallery img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 6px; cursor: pointer; border: 2px solid transparent; box-sizing: border-box; }
.character-portrait-gallery img.is-selected { border-color: var(--system-c-area-b-accent-color); }

/* 관계 신청(요청) — 사용자를 고른 뒤 그 사람의 캐릭터 목록. 기본 검색 목록(300px 고정)보다 짧게. */
.character-relation-search-list.is-owned { width: 100%; height: auto; max-height: 220px; }

/* ==========================================================================
   관계 무대(요청) — 자유 배치 캔버스. 가로(16:9)/세로(9:16) 두 벌, 요소는 비율 좌표.
   ========================================================================== */
.character-stage-wrap { display: flex; flex-direction: column; gap: 8px; align-items: stretch; }
.character-stage-toolbar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.character-stage-modes { display: inline-flex; gap: 4px; margin: 0 6px; }
.character-stage-toolbar-spacer { flex: 1 1 auto; }
/* 관계 무대 v2 — 캔버스(16:9) 안의 3:4 표시영역. z-index 로 제 층 세상을 닫는다(요소 앞뒤가 1000+z 라
   바깥 서랍 위로 새지 않게). 배경 그림은 없고 단색(place 가 backgroundColor 로 깐다)만. */
.character-stage {
  position: relative; z-index: 0; overflow: hidden; margin: 0 auto; box-sizing: border-box; border-radius: 14px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  touch-action: none;
}
.character-stage-items { position: absolute; inset: 0; }
/* 표시영역 밖으로 넘쳐 잘리는 가장자리는 칼같이 끊지 않고 부드럽게 사라지게 한다(요청) —
   최대뷰어 전신 감싸개(.shared-chat-stage-bust-wrap)와 같은 방식이다. 띠 너비는 place()가
   변마다 따로 넣는다(안 잘리는 변은 0px 이라 그대로 또렷하다). 편집 중에는 실제 경계를
   봐야 하므로 걸지 않는다. */
.character-stage:not(.is-editing) .character-stage-items {
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 var(--stage-fade-l, 0px), #000 calc(100% - var(--stage-fade-r, 0px)), transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 var(--stage-fade-t, 0px), #000 calc(100% - var(--stage-fade-b, 0px)), transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent 0, #000 var(--stage-fade-l, 0px), #000 calc(100% - var(--stage-fade-r, 0px)), transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 var(--stage-fade-t, 0px), #000 calc(100% - var(--stage-fade-b, 0px)), transparent 100%);
  mask-composite: intersect;
}
/* 표시영역 밖(초과 영역)은 편집할 때만 어둡게 덮는다(요청) — 보기 모드에서는 그대로 보인다. */
.character-stage-shade { position: absolute; top: 0; bottom: 0; z-index: 2000; background: rgba(0, 0, 0, .38); pointer-events: none; }
.character-stage:not(.is-editing) .character-stage-shade { display: none; }
/* 편집 모드의 표시영역 틀 — 자리는 툴바 슬라이더로 옮긴다(요청). 틀이 안쪽 요소를 가로채지 않게 뚫어 둔다. */
.character-stage-frame {
  position: absolute; z-index: 2001; box-sizing: border-box; pointer-events: none;
  border: 2px dashed var(--system-c-area-b-accent-color); border-radius: 6px;
}
.character-stage-frame span { position: absolute; left: 6px; top: 4px; font-size: 11px; padding: 2px 6px; border-radius: 6px; background: rgba(0, 0, 0, .5); color: #fff; pointer-events: none; }
.character-stage-item { position: absolute; box-sizing: border-box; transform-origin: center; }
.character-stage-item img { display: block; width: 100%; height: auto; max-width: none; user-select: none; pointer-events: none; }
/* 프로필 카드 — 간단(아바타 | 이름)과 상세(홈 기본 프로필, 한마디 제외). 좌/우 정렬은 카드 안 배치 방향. */
.character-stage-profile {
  width: 240px; box-sizing: border-box; padding: 12px; border-radius: 14px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px; text-align: left;
  /* 배경 없이 무대 위에 바로 얹힌다(요청) — 홈의 기본 프로필과 같이. */
  background: transparent;
  color: var(--system-c-area-b-base-font-color);
}
.character-stage-profile.is-align-right { align-items: flex-end; text-align: right; }
.character-stage-profile.is-simple { flex-direction: row; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 999px; }
.character-stage-profile.is-simple.is-align-right { flex-direction: row-reverse; }
.character-stage-profile-avatar { width: 96px; height: 96px; border-radius: 50%; background-size: cover; background-position: center; display: grid; place-items: center; overflow: hidden; flex: 0 0 auto; }
.character-stage-profile.is-simple .character-stage-profile-avatar { width: 44px; height: 44px; }
.character-stage-profile strong { font-size: 16px; }
.character-stage-profile .character-home-entries { width: 100%; }
.character-stage-profile.is-align-right .character-home-entry { flex-direction: row-reverse; }
.character-stage.is-editing { outline: 2px dashed var(--system-c-area-b-accent-color); outline-offset: -2px; }
.character-stage.is-editing .character-stage-item { cursor: move; outline: 1px dashed transparent; }
.character-stage.is-editing .character-stage-item:hover,
.character-stage.is-editing .character-stage-item.is-selected { outline-color: var(--system-c-area-b-accent-color); }
/* 손잡이(다이어리 꾸미기와 같이): 오른쪽 아래 = 크기, 위 가운데 = 회전. */
.character-stage-handle, .character-stage-rotate { position: absolute; display: none; background: var(--system-c-area-b-accent-color); }
.character-stage-handle { right: -7px; bottom: -7px; width: 14px; height: 14px; border-radius: 3px; cursor: nwse-resize; }
.character-stage-rotate { left: 50%; top: -22px; width: 14px; height: 14px; margin-left: -7px; border-radius: 50%; cursor: grab; }
.character-stage-rotate::before { content: ''; position: absolute; left: 6px; top: 14px; width: 2px; height: 8px; background: var(--system-c-area-b-accent-color); }
.character-stage.is-editing .character-stage-item.is-selected .character-stage-handle,
.character-stage.is-editing .character-stage-item.is-selected .character-stage-rotate,
.character-stage.is-editing .character-stage-item:hover .character-stage-handle,
.character-stage.is-editing .character-stage-item:hover .character-stage-rotate { display: block; }
/* 고르기 팝업 — 전신/프로필/이미지. */
.character-stage-pick-dialog { width: min(640px, 96%); max-width: min(640px, 96%); max-height: 88%; overflow-y: auto; text-align: left; display: flex; flex-direction: column; gap: 10px; }
.character-stage-pick-group { display: flex; flex-direction: column; gap: 6px; }
.character-stage-pick-row { display: flex; flex-wrap: wrap; gap: 6px; }
.character-stage-pick-tabs { display: flex; gap: 6px; }
.character-stage-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 6px; }
.character-stage-pick button { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 4px; cursor: pointer; }
.character-stage-pick img { width: 100%; aspect-ratio: 3 / 4; object-fit: contain; border-radius: 6px; background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)); }
.character-stage-pick span { font-size: 11px; }
.character-stage-modes input[type="range"] { width: 120px; }
/* 화면 폭(요청) — 캔버스 비율을 넓히는 슬라이더. 지금 비율을 앞에 적어 둔다. */
.character-stage-ratio { display: inline-flex; align-items: center; gap: 6px; margin: 0 6px; }
.character-stage-ratio > span { min-width: 3.2em; text-align: right; opacity: .8; }
.character-stage-ratio input[type="range"] { width: 100px; }

/* 타임라인 직선(요청) — 본선/분기 선, 노드 점, 위아래 카드, 아래 상세. --tl-color 는 분기 색(없으면 강조색). */
/* 타임라인 세로 시간선(요청) — 컨텐츠 영역 높이를 채우는 세로 선, 위아래로 연해진다. 가운데 줄 = 지금 보는 줄,
   다른 줄은 좌우에 연하게(분기가 있다는 것만 알 정도). 노드 오른쪽에 본문, 고른 노드만 또렷하고 나머지는 흐리다. */
.character-tl { position: relative; display: flex; flex-direction: column; min-height: 0; height: 100%; outline: none; }
/* 위아래 56px 은 마스크로 흐려지는 띠다 — 그만큼 안쪽 여백을 둬 내용이 그 안으로 들어가지 않게 한다(요청). */
.character-tl-scroll { position: relative; flex: 1 1 auto; min-height: 0; overflow: auto; padding: 56px 0; overscroll-behavior: contain; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%); }
.character-tl-scroll::-webkit-scrollbar { display: none; }
.character-tl-canvas { position: relative; min-height: 100%; }
/* 시간선은 영역 A 의 설명 글씨색, 노드는 영역 A 의 글씨색(요청). 분기에 색을 정해 두면 그 색이 이긴다.
   선은 얇게, 점은 작게(요청). 선을 잡고 끌면 판은 그대로 두고 시간선만 미끄러진다. */
.character-tl-line { position: absolute; width: 2px; border-radius: 2px; transform: translateX(-50%); cursor: grab; touch-action: none;
  background: var(--tl-color, var(--system-c-area-a-base-desc-font-color)); }
.character-tl-line.is-panning { cursor: grabbing; }
.character-tl-line.is-side { width: 1px; opacity: .35; }
.character-tl-line.is-side:hover { opacity: .6; }
.character-tl-fork { position: absolute; height: 1px; opacity: .35; transform: translateY(-50%); pointer-events: none;
  background: var(--tl-color, var(--system-c-area-a-base-desc-font-color)); }
.character-tl-node { position: absolute; width: 9px; height: 9px; border-radius: 50%; z-index: 2; cursor: pointer; transform: translate(-50%, -50%);
  background: var(--tl-color, var(--system-c-area-a-base-font-color)); transition: transform .12s, box-shadow .12s; }
.character-tl-node.is-fork { border-radius: 2px; transform: translate(-50%, -50%) rotate(45deg); }
.character-tl-node:not(.is-side):hover, .character-tl-node.is-selected { transform: translate(-50%, -50%) scale(1.3); }
.character-tl-node.is-fork:not(.is-side):hover, .character-tl-node.is-fork.is-selected { transform: translate(-50%, -50%) rotate(45deg) scale(1.3); }
/* 고른 이벤트/분기는 포커스 색으로 알린다(요청). */
.character-tl-node.is-selected { background: var(--focus-color); box-shadow: 0 0 0 4px rgba(var(--system-c-area-a-base-rgb), .6); }
.character-tl-node.is-side { width: 5px; height: 5px; opacity: .45; }
.character-tl-node.is-dragging { opacity: .75; z-index: 5; cursor: grabbing; }
/* 분기에서 아래로 막혔을 때 살짝 흔들어 알린다. */
.character-tl.is-blocked .character-tl-node.is-selected { animation: character-tl-blocked .3s; }
@keyframes character-tl-blocked { 0%, 100% { margin-top: 0; } 40% { margin-top: 5px; } 70% { margin-top: -3px; } }
/* 제목·내용은 영역 B 판(.panel-card)에 담는다(요청) — 자리는 JS 가 겹치지 않게 재서 넣고,
   층(z-index)도 고른 판에서 멀어질수록 뒤로 보낸다. */
/* 타임라인 칸에서는 컨텐츠 영역의 B 판을 벗긴다(요청) — 영역 A 바탕 위에 이벤트/분기 판(B)만 뜬다. */
.shared-main.is-timeline { background: transparent !important; border-width: 0 !important; box-shadow: none !important; }
/* 판은 컨텐츠 영역을 넘지 않는다 — 넘치면 판 안에서 구른다(요청, --tl-max-h 는 JS 가 넣는다). */
.character-tl-entry { position: absolute; left: var(--tl-text-x, 84px); right: 16px; width: auto; cursor: pointer; transition: opacity .18s;
  max-height: var(--tl-max-h, 420px); overflow: auto; overscroll-behavior: contain; scrollbar-width: none; }
/* 안쪽 스크롤바는 다른 칸(.post-content/.post-editor-content)과 같이 감춘다(요청) — 기본 스크롤바가 보이면 안 된다. */
.character-tl-entry::-webkit-scrollbar, .character-tl-compose::-webkit-scrollbar { display: none; }
.character-tl-entry.is-dim { opacity: .55; }
.character-tl-entry.is-dim:hover { opacity: .85; }
/* 안 고른 판은 제목 줄만 남긴다(요청: 제목은 다 보이게) — 본문은 고른 판만 펼쳐 이웃을 덮는다. */
.character-tl-entry.is-dim :is(.character-tl-body, .character-tl-chars, .character-tl-backup, .character-tl-choices) { display: none; }
/* 감춘(비친) 노드는 어느 상태에서도 반투명하게 — 고른 상태(우클릭 [활성화])여도 표가 난다. */
.character-tl-entry.is-mirror-hidden, .character-tl-entry.is-mirror-hidden:hover, .character-tl-node.is-mirror-hidden { opacity: .35; cursor: default; }
.character-tl-entry.is-selected { border-color: var(--focus-color); box-shadow: 0 0 0 1px var(--focus-color); }
.character-tl-entry-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.character-tl-title { font-size: 14px; line-height: 1.3; }
.character-tl-entry.is-selected .character-tl-title { color: var(--focus-color); }
.character-tl-body { margin-top: 4px; }
.character-tl-chars { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0; }
.character-tl-char { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; }
.character-tl-char .profile-avatar-img, .character-tl-chip .profile-avatar-img { width: 20px; height: 20px; border-radius: 50%; }
.character-tl-choices { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.character-tl-choice { display: flex; align-items: baseline; gap: 6px; width: 100%; text-align: left; font: inherit; padding: 4px 8px; border-radius: 8px; cursor: pointer; }
/* 선택지에 마우스를 올리면 포커스 색으로 또렷하게(요청) — 누를 수 있는 줄임을 알린다.
   .transparent-button 이 hover 배경을 !important 로 지워 버려서 여기서도 !important 로 되받는다. */
.character-tl-choice { transition: background .12s, color .12s; }
.character-tl-entry .character-tl-choice:hover,
.character-tl-entry .character-tl-choice:focus-visible {
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}
.character-tl-entry .character-tl-choice:hover :is(.character-tl-choice-no, .character-tl-choice-kind) { color: inherit !important; opacity: 1; }
.character-tl-choice-no { opacity: .7; }
.character-tl-choice-kind { font-weight: 700; }
/* 아무것도 없을 때 — 시간선은 판 높이를 다 쓰고 가운데에 안내를 둔다(요청). */
.character-tl-empty { position: absolute; left: 0; right: 0; top: 50%; margin: 0; text-align: center; transform: translateY(-50%); }
/* 작성·수정 판(요청) — 시간선 위 그 자리에 서는 포스트 편집기. 판 안이 곧 편집기 본문이다. */
.character-tl-compose { cursor: default; max-height: var(--tl-max-h, 420px); overflow: auto; overscroll-behavior: contain; scrollbar-width: none; }
.character-tl-compose-form { display: flex; flex-direction: column; gap: 8px; }
.character-tl-compose-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.character-tl-compose-title {
  flex: 1 1 140px; min-width: 0; height: 26px; padding: 0 4px;
  border: 0; border-bottom: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  background: transparent; font: inherit; font-weight: 700; outline: none;
}
.character-tl-compose-chars { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.character-tl-compose .character-tl-chip-list { flex: 0 1 auto; }
.character-tl-compose .character-tl-chip { cursor: pointer; }
.character-tl-compose .post-editor-body { min-height: 160px; display: flex; flex-direction: column; }
.character-tl-compose .post-editor-message:empty { display: none; }
.character-tl-charpick { width: min(420px, 94%); display: flex; flex-direction: column; gap: 10px; }
.character-tl-field { display: flex; flex-direction: column; gap: 6px; }
.character-tl-field > span { font-size: 12px; color: var(--system-c-area-b-base-desc-font-color); }
.character-tl-chip-list { display: flex; flex-wrap: wrap; gap: 4px; }
.character-tl-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px 2px 2px; border-radius: 999px; font-size: 12px;
  background: rgba(var(--system-c-area-b-base-border-rgb), .25); }
.character-tl-chip-pick { padding: 0; cursor: pointer; }
.character-tl-choice-rows { display: flex; flex-direction: column; gap: 4px; }
/* 줄을 바로 끌어 순서를 바꾼다(요청) — 손잡이 칸이 없어 두 칸이다. */
.character-tl-choice-row { display: grid; grid-template-columns: 5.5em 1fr; gap: 8px; align-items: center; cursor: grab; }
/* 구분 select 은 min-width:120px 가 기본이라 제 칸을 넘어 설명 칸을 덮었다(요청) — 칸에 맞춘다. */
.character-tl-choice-row > select { min-width: 0; width: 100%; }
.character-tl-choice-row:active { cursor: grabbing; }
/* 설명 칸은 다른 폼과 같은 떠오르는 라벨 + 밑줄 입력(요청) — 격자 칸 안에서 폭을 다 쓴다. */
.character-tl-choice-row > .auth-field { min-width: 0; margin: 0; }

/* 홈 글자 좌우 반전(요청) — 거울이 아니라 붙는 쪽을 바꾼다. 한마디와 기본 프로필은 따로 논다.
   메타(날짜·조회수)는 늘 우측 상단이라 그대로 둔다. */
.character-home.is-msg-left .character-home-quote { right: auto; left: var(--stage-left, 0px); }
.character-home.is-msg-left .character-home-quote,
.character-home.is-msg-left .character-home-quote .character-home-message,
.character-home.is-msg-left .character-home-quote textarea.character-home-message { text-align: left; }
.character-home.is-info-left .character-home-info,
.character-home.is-info-left.is-editing [data-character-form] {
  right: auto; left: var(--stage-left, 0px); margin: 0 0 0 var(--stage-left, 0px); text-align: left;
}
.character-home.is-info-left.is-info-placed .character-home-info,
.character-home.is-info-left.is-editing [data-character-form] { margin-left: 0; }
/* 판 안의 요소가 전부 그 쪽에 붙어야 한다(요청) — 오른쪽 정렬이 하나하나 박혀 있어 글만
   왼쪽으로 가고 아바타·이름·설명·색칩·표정 줄·버전 고르개는 오른쪽에 남았다. */
.character-home.is-info-left .character-home-info
  :is(.character-home-avatar, .character-home-name, .character-color-groups, .character-face-strip, .character-color-row) { justify-content: flex-start; }
.character-home.is-info-left .character-home-info :is(.character-home-entries, .character-profile-entry-row) { justify-content: start; }
.character-home.is-info-left .character-home-info :is(input, textarea, select) { text-align: left; }
.character-home.is-info-left .character-home-info .auth-label { right: auto; left: 0; }
.character-home.is-info-left .character-home-info .auth-clear { left: auto; right: 0; }
.character-home.is-info-left .character-home-info .auth-input { padding-left: 0; padding-right: 20px; }
.character-home.is-info-left .character-home-info .profile-bio-input { border-radius: 14px 14px 14px 4px; }
.character-home.is-info-left .character-home-info .custom-select-wrap.character-portrait-version { margin: 0 auto 4px 0; }
