/* ==========================================================================
   Homepage — canonical stylesheet

   01. Theme / global tokens
   02. Base / typography / scrollbar / SVG
   03. Desktop / taskbar / windows
   04. Content apps (gallery / diary / movie / guestbook)
   05. Popovers / previews / start menu
   06. Settings application
   07. Theme surfaces / interaction states
   08. Responsive rules

   NOTE: 같은 selector/property의 사망 선언(dead override)은 제거했습니다.
   Cascade 의미가 달라질 수 있는 서로 다른 selector 간 선언은 그대로 유지합니다.
   ========================================================================== */
:root {
  --taskbar-h: 50px;
  /* 화면 아래에 작업표시줄 몫으로 비워 두는 높이(요청) — 자동숨김으로 내려가 있으면
     0 이 되어 창·바탕화면이 그 자리까지 쓴다. 작업표시줄 자신의 높이는 --taskbar-h 그대로. */
  --desktop-bottom-h: var(--taskbar-h);

  /* 전역 툴팁 — 어느 시스템(A/B/C)에도 속하지 않는 하나의 톤이라 여기 둔다.
     실제 값은 서버 렌더 CSS(SettingCSS.go)와 homepage.js 가 덮어쓴다. */
  --tooltip-color: #fff;
  --tooltip-font-color: #000;
  --tooltip-border-color: #fff;
  --tooltip-border-rgb: 255, 255, 255;
  --tooltip-border-alpha: 1;

  /* 영역별 기본 투명도(0~1). 과거 표면 계층(surface-*-alpha)의 대표값을 그대로 이어받음.
     system-*-alpha는 그 영역의 배경/테두리 전체에 단일 값으로 적용됨(요소별 깊이감 차이 없음). */
  --surface-alpha: .60;
  --surface-strong-alpha: .75;
  --surface-solid-alpha: .95;

  --focus-color: #2b97ff;
  --focus-rgb: 43, 151, 255;
  --focus-font-color: #fff;
  --focus-font-rgb: 255, 255, 255;

  --desktop-background-image: none;
  --desktop-background-position-landscape: 50% 50%;
  --desktop-background-position-portrait: 50% 50%;
  --desktop-shortcut-font-color: #000;
  --desktop-shortcut-hover-color: #fff;
  --desktop-shortcut-hover-rgb: 255, 255, 255;
  --desktop-shortcut-hover-alpha: .6;
  --desktop-shortcut-hover-font-color: #000;
  --desktop-shortcut-hover-border-color: #2b97ff;
  --desktop-shortcut-hover-border-rgb: 43, 151, 255;
  --desktop-shortcut-hover-border-alpha: .16;

  --z-background: 0;
  --z-content: 10;
  --z-window: 100;
  --z-popup: 200;
  --z-preview: 300;
  --z-toast: 400;
  --z-dialog: 500;
  --z-debug: 1000;
}

/* transition: all은 "이 요소에 바뀔 수 있는 모든 CSS 속성(width/height/
   left/top/transform/filter/backdrop-filter까지 포함)을 매 프레임 감시하다
   바뀌면 애니메이션해라"는 뜻이라, 페이지에 있는 모든 엘리먼트 각각에서
   실제로 필요도 없는 감시 비용을 계속 문다 — DOM이 늘어날수록(실제 게시글이
   쌓인 운영 서버가 게시글 몇 개 없는 로컬 테스트보다 훨씬 큼) 그 비용도
   같이 늘어 창 드래그처럼 매 프레임 스타일이 바뀌는 상호작용에서 체감
   버벅임으로 드러난다. 이 프로젝트에서 실제로 쓰는 hover 전환은 전부
   배경/글자/테두리색·그림자·투명도뿐이라(width/height/transform을 hover로
   쓰는 곳은 없음, 각자 자기 selector에서 따로 transition을 선언해 이 전역
   규칙보다 우선함) 그 다섯 속성만 감시하도록 좁힌다. */
* {
  transition: background-color .2s ease, color .2s ease, border-color .2s ease, box-shadow .2s ease, opacity .2s ease;
}

/* pointermove로 매 프레임 left/top/width/height를 갱신하는 동안
   전역 transition이 매번 0.2s ease로 뒤쫓아가며 커서보다 느리게 보이는 문제를 막음. */
.window.dragging,
.window.resizing {
  transition: none !important;
}

/* 투명 테마에서 창을 끌 때 블러가 깜박이던 문제(요청). backdrop-filter 는 매
   프레임 "뒤에 있는 것"을 다시 샘플링한다 — 뒤가 배경화면 한 장이면 이미 합성된
   레이어라 그대로 가져다 쓰지만(그래서 배경화면 위에서는 안 깜박였다), 뒤가 다른
   창이면 그 창의 일반 HTML 을 매 프레임 다시 래스터화해야 한다. 그 래스터가 늦은
   프레임이 곧 깜박임이다.
   그래서 "끌고 있는 창"만이 아니라 열려 있는 모든 창을 드래그·리사이즈 동안
   각자 합성 레이어로 올려 둔다(homepage.ui.js 가 body 에 is-window-dragging 을
   붙였다 뗀다) — 블러는 그대로 두고 뒤 레이어만 안정시키는 방식이다.
   상시로 걸지 않는 이유는 창 수만큼 GPU 텍스처를 계속 물기 때문. */
body.is-window-dragging .window {
  will-change: transform;
}

/* 초기 설정 마법사(homepage.html #setupWizardOverlay) — user.css의
   .user-guest-overlay를 그대로 재사용하되(배경/블러/중앙정렬 다 그쪽 몫),
   거긴 특정 창 하나(.user-modal-root)만 덮는 position:absolute라 여기선
   데스크톱 전체(작업표시줄 포함)를 덮도록 fixed로 다시 잡는다. 창/팝업/
   토스트(--z-debug: 1000)보다도 위에 있어야 어떤 상태에서도 항상 최상단에서
   보인다. */
.setup-wizard-overlay {
  position: fixed !important;
  z-index: calc(var(--z-debug) + 10);
}
.setup-wizard-overlay[hidden] {
  display: none !important;
}

html {
  background-color: transparent;
}
html,
body {
  height: 100%;
  overflow: hidden;
}
body {
  background: transparent !important;
}

/* 창이 뜨기 전(비동기 로딩) 동안 로딩 커서 — guardWindowOpen(homepage.ui.js). */
body.is-window-opening,
body.is-window-opening * {
  cursor: progress !important;
}

input {
  border: 0;
}

.desktop {
  background: transparent !important;
  position: relative;
  height: calc(100vh - var(--desktop-bottom-h));
  overflow: hidden;
}

/* ==========================================================================
   바탕화면 바로가기(desktop shortcuts) — top/left/right/bottom 4영역
   각 영역(.desktop-region)은 padding/margin/gap 없이 아이콘이 필요로 하는
   만큼만 공간을 차지한다(flex: 0 0 auto). 영역이 공간을 차지하는 순서(우선순위)는
   JS(homepage.js의 getDesktopAreaOrder)가 계산해 .desktop-shortcuts와
   .desktop-region-remainder에 is-column/is-row(-reverse) 클래스를 중첩으로
   부여하는 방식으로 구현한다 — 먼저 배치되는 영역이 자기 축 전체를 차지하고,
   다음 영역은 "남은 사각형"(.desktop-region-remainder) 안에서만 배치된다.
   ========================================================================== */
.desktop-shortcuts {
  position: absolute;
  inset: 0;
  display: flex;
  padding: 3px;
}
.desktop-shortcuts.is-column,
.desktop-region-remainder.is-column {
  flex-direction: column;
}
.desktop-shortcuts.is-column-reverse,
.desktop-region-remainder.is-column-reverse {
  flex-direction: column-reverse;
}
.desktop-shortcuts.is-row,
.desktop-region-remainder.is-row {
  flex-direction: row;
}
.desktop-shortcuts.is-row-reverse,
.desktop-region-remainder.is-row-reverse {
  flex-direction: row-reverse;
}

.desktop-region {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  pointer-events: auto;
}
.desktop-region:empty {
  display: none;
}
.desktop-region--top,
.desktop-region--bottom {
  flex-direction: row;
}
.desktop-region--left,
.desktop-region--right {
  flex-direction: column;
}
.desktop-region--top.is-fill-reverse,
.desktop-region--bottom.is-fill-reverse {
  flex-direction: row-reverse;
}
.desktop-region--left.is-fill-reverse,
.desktop-region--right.is-fill-reverse {
  flex-direction: column-reverse;
}

.desktop-region-remainder {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: flex;
  pointer-events: none;
}

.desktop-shortcut {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 60px;
  height: 60px;
  padding: 8px 4px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  text-align: center;
  justify-content: center;
}

/* 바탕화면 아이콘 전용 hover(설정 > 화면 디자인 편집기 > 바탕화면 > Hover에서 지정) —
   그림자는 없앴다(요청). 배경·폰트·테두리 셋으로만 꾸민다. 아이콘 자체가
   border:0 + box-sizing:border-box 라 테두리가 생겨도 자리는 그대로다. */
.desktop-shortcut:not(.is-clicked):hover,
.desktop-shortcut:not(.is-clicked):focus,
.desktop-shortcut:not(.is-clicked):focus-within {
  background: rgba(var(--desktop-shortcut-hover-rgb), var(--desktop-shortcut-hover-alpha)) !important;
  border: 1px solid rgba(var(--desktop-shortcut-hover-border-rgb), var(--desktop-shortcut-hover-border-alpha)) !important;
  box-shadow: none !important;
}
.desktop-shortcut:not(.is-clicked):hover span,
.desktop-shortcut:not(.is-clicked):focus span,
.desktop-shortcut:not(.is-clicked):focus-within span {
  color: var(--desktop-shortcut-hover-font-color) !important;
}
/* svg 자체뿐 아니라 내부 path/g까지 같이 잡아야 한다 — body,body*{color:...}
   (아래 "--font-color Manage")가 특이도는 낮아도(0,0,1) svg 자식들을 직접
   지정하므로, svg 하나에만 색을 주면 상속이 아니라 그 body* 규칙이 자식에서
   그대로 이겨버린다(바로가기 아이콘이 테마 폰트색을 따르던 버그의 원인). */
.desktop-shortcut:not(.is-clicked):hover svg,
.desktop-shortcut:not(.is-clicked):focus svg,
.desktop-shortcut:not(.is-clicked):focus-within svg,
.desktop-shortcut:not(.is-clicked):hover svg *,
.desktop-shortcut:not(.is-clicked):focus svg *,
.desktop-shortcut:not(.is-clicked):focus-within svg * {
  color: var(--desktop-shortcut-hover-font-color) !important;
  stroke: var(--desktop-shortcut-hover-font-color) !important;
}

/* 임의의 배경사진 위에 놓이므로 테마 폰트색 대신 sound-popover와 같은 방식으로
   흰 글자 + 그림자로 고정해 가독성을 보장한다. */
.desktop-shortcut span {
  color: var(--desktop-shortcut-font-color);
  margin-top: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.desktop-shortcut svg,
.desktop-shortcut svg * {
  color: var(--desktop-shortcut-font-color);
  stroke: var(--desktop-shortcut-font-color)!important;
}

/* ==========================================================================
   z-index Manage
   ========================================================================== */
/* 배경 */
.desktop-background {
  z-index: var(--z-background);
}

/* 일반 콘텐츠 내부 */
.desktop,
.music-content,
.menu-admin-header,
.diary-weekdays,
.preview-close {
  z-index: var(--z-content);
}

/* 일반 모달 */
.window {
  z-index: var(--z-window);
  /* 따로 정하지 않은 창도 게시글 창과 같은 최소 크기를 쓴다(요청) — 예전엔 사용자·캐릭터
     창에만 있어서 나머지는 260px(JS 의 WINDOW_MIN_WIDTH)까지 줄어들며 안쪽이 무너졌다.
     화면이 그보다 좁으면 화면을 따른다. 창별 규칙(.window[data-root=…])이 더 세서 그대로 이긴다. */
  min-width: min(360px, calc(100vw - 8px));
  min-height: min(360px, calc(100vh - 8px));
}

/* 모달 위 편집 레이어 */
.settings-editor-layer {
  z-index: calc(var(--z-window) + 10);
}

/* 작업표시줄 위 팝업 */
.popover,
.search-suggest {
  z-index: var(--z-popup);
}

/* 작업표시줄 미리보기는 팝업보다 위 */
.preview-card,
.window.preview-peek {
  z-index: var(--z-preview);
}

/* 시스템 메시지 */
.system-message-stack,
.taskbar,
.display-theme-anchor {
  z-index: var(--z-toast);
}

/* 화면 정중앙 확인 알람: 무엇보다 위 */
.confirm-dialog-overlay {
  z-index: var(--z-dialog);
}

/* 창 가장자리 리사이즈 핸들 — .confirm-dialog-overlay.is-window-scoped(위
   z-dialog)도 같은 .window의 자식이라, 창 안에 뜬 팝업이 핸들을 덮어 리사이즈가
   막히면 안 된다. 팝업이 떠 있어도 가장자리 드래그로 창 크기를 바꿀 수 있게
   z-dialog보다 위에 둔다(핸들은 커서용 투명 스트립이라 시각적으로는 무영향). */
.resize-handle {
  z-index: calc(var(--z-dialog) + 1);
}

/* ==========================================================================
   --font-color Manage
   기본값은 System C(윈도우 컨텐츠영역) 폰트색. 작업표시줄/윈도우바는 각자 tier로 재정의.
   ========================================================================== */
body, body * {
  color: var(--system-c-area-b-base-font-color);
}
.taskbar-scope, .taskbar-scope *,
.calendar-title {
  color: var(--system-a-area-a-base-font-color);
}
.window-bar, .window-bar * {
  color: var(--system-b-area-a-base-font-color);
}

.grid-cell-meta, .grid-cell-meta *,
.entry-meta, .entry-meta *,
.entry-time,
.post-meta,.post-meta *,
.settings-panel-head span,
.settings-header-text span {
  color: var(--system-c-area-b-base-desc-font-color) !important;
}

/* System C: Title 폰트 (게시글/카드/섹션 제목류) */
h1, h2, h3,
.grid-cell-title,
.post-title,
.movie-card-title,
.settings-panel-head strong,
.settings-header-text strong,
.settings-editor-head strong,
.menu-admin-title,
.settings-music-title,
.music-title,
.diary-date-select {
  color: var(--system-c-area-b-base-font-color) !important;
}

/* 시작 버튼(✦)은 예전에 color:var(--focus-color)로 고정돼 있었지만, 다른
   작업표시줄 버튼과 똑같이 .sys-a-btn-a(영역 폰트/강조)를 따른다. */

.user-primary-button,.settings-form-actions .primary,
button:focus-visible:not(.settings-music-summary):not(.user-link-button):not(.app-btn):not(.task-square):not(.status-btn):not(.clock):not(.shortcut):not(.gallery-power-button):not(.panel-header-breadcrumb):not(.window-address-button):not(.youtube-detail-player-toggle) {
  color: var(--focus-font-color) !important;
}

/* ==========================================================================
   --font-size Manage
   홈페이지(/homepage)에서 로드되는 모든 CSS(이 파일 + web/static/css/modals/*.css,
   user.css 포함)의 font-size 단일 진입점. 새 font-size는 component 규칙에 직접
   선언하지 말고 이 구역 하단의 px 값별 묶음에 selector를 추가할 것 — 자세한
   내용은 AGENTS.md Frontend 섹션 참고.
   예외: gallery.css는 독립 `/gallery` 페이지에서 단독 로드되어 이 구역이 적용되지
   않으므로 대상이 아니다(그 파일 상단 주석 참고).
   ========================================================================== */
/* 제목 */
  .title,
  .start-menu-search input /*작업표시줄,시작메뉴: 검색*/,
  .diary-date-select,
  .profile-name, .profile-name-input,
  .calendar-title,
  .window-content-head,
  .calendar-head *,
  .settings-panel-head strong,
  .settings-header-text strong,
  .panel-header-title-row strong /*캐릭터·페어·공유기록 상단 제목: 환경설정과 같은 크기(요청)*/,
  .post-markdown-body h3, .post-markdown-body h3 *,
  .post-editor-content h3, .post-editor-content h3 *
  {
    font-size: 14px!important;
  }
/* 본문 */
  body, body *,
  .window-content *,
  .grid-cell-title /*window.grid.title*/,
  .side-nav-btn,
  .suggest-item,
  .mini-day,
  .activity-title,
  .post-editor-title-input
  {
    font-size: 12px;
  }
/* 작은글 */
  .clock,
  .grid-cell-meta /*window.grid.title*/,
  .post-meta /*게시글.meta*/,
  .post-admin-toolbar select,
  .modal-template-loading, .modal-template-error,
  .settings-card-label,
  .settings-info-value,
  .settings-music-title,
  .settings-editor-head strong,
  .post-editor-visibility-select, .post-editor-format-btn, .window-post-visibility,
  .post-editor-message,
  .window-address-input,
  .confirm-dialog-message,
  .settings-info-label,
  .mini-week span,
  .settings-theme-groups .theme-group-head-text strong,
  .settings-theme-groups .theme-row-label,
  .post-visibility-option,
  .entry-reply-input-wrap textarea,
  .diary-weekdays span,
  .diary-day,
  .close-all,
  .settings-empty,
  .menu-admin-title,
  .settings-form-field input[type=text], .settings-form-field input[type=url], .settings-form-field select,
  .settings-main-message,
  .suggest-item small,
  .desktop-shortcut span,
  .shortcut strong,
  .entry-meta,
  .entry-reply-toggle,
  .entry-reply-submit-btn,
  .preview-label,
  .settings-panel-head span,
  .settings-header-text span,
  .menu-admin-row,
  .settings-log-item, .settings-log-item strong,
  .settings-form-field>span,
  .specific-user-item strong,
  .settings-inline-message,
  .settings-theme-groups .theme-subsection-label,
  .settings-theme-groups .bg-region-tab,
  .menu-admin-header,
  .settings-pill,
  .user-admin-header,
  .specific-user-item span, .specific-user-item time,
  .menu-hub-card strong, .menu-hub-card span,
  .menu-order-name strong, .desktop-shortcut-name, .desktop-shortcut-group-title,
  .desktop-shortcut-group-body:empty::before,
  .field-required-message,
  .post-image-viewer-position,
  .post-image-lightbox-position,
  .post-thumb-image-badge,
  .post-thumb-live2d-badge,
  .live2d-badge,
  .profile-login-id,
  .character-relation-pending
  {
    font-size: 11px!important;
  }
/* ICON */
  .star-btn
  {
    font-size: 30px!important;
  }
  .window-actions > .window-minimize, .window-actions > .window-close,
  /* 좋아요 하트(사용자 활동 카드 / 목록 셀) — 자손까지 잡는 건 글리프가 span
     안에 있어서고, !important 는 위 "본문" 묶음의 `.window-content *` 를
     되받기 위해서다(그게 없으면 12px 로 깎인다). */
  .activity-unlike, .activity-unlike *,
  .grid-cell-like, .grid-cell-like * {
    font-size: 15px!important;
  }
/* 아래는 컴포넌트별 개별 font-size(전역 !important 규칙에 의해 덮이지 않는 요소들).
   px 값별로 묶어 두었으니 크기를 바꾸려면 값을 옮겨 적지 말고 해당 selector를
   다른 묶음으로 옮기면 됨. */
/* 22px */
  .server-stats-visitor-count
  {
    font-size: 22px;
  }
/* 20px */
  .preview-close
  {
    font-size: 20px;
  }
/* 18px */
  .desktop-area-sort-handle, .post-image-viewer-nav, .post-image-lightbox-nav
  {
    font-size: 18px;
  }
/* 16px */
  .desktop-shortcut-handle
  {
    font-size: 16px;
  }
/* 15px */
  .post-image-remove-btn
  {
    font-size: 15px;
  }
/* 13px */
  .panel-header-breadcrumb,
  .settings-form-actions button
  {
    font-size: 13px;
  }
/* 11.5px */
  .post-mention
  {
    font-size: 11.5px;
  }
/* 10px (홈페이지 계열 전체 진입점 — user.css의 로그인·프로필·활동 화면 크기 포함) */
  .server-stats-visitor-count small, .settings-toggle-text,
  .user-loading-state p, .auth-label,
  .user-primary-button, .user-link-button,
  .profile-actions .user-primary-button,
  .small-btn
  {
    font-size: 10px;
  }
/* 10px 아래로는 내려가지 않는다(요청) — 예전 9px 묶음. 설명 계열(.82em 등
   상대 크기로 잡힌 보조 문구)만 예외로 그대로 둔다. */
  .server-stats-chart-axis, .server-stats-disk-meta, .server-stats-updated,
  .user-auth-message, .profile-login-id, .profile-edit-message
  {
    font-size: 10px;
  }
/* ==========================================================================
   --border-color-color Manage
   기본값은 System C 영역 B의 "테두리" 값. 작업표시줄/윈도우바 tier 도 각각 자기
   영역의 테두리 변수를 쓰므로 세 tier가 같은 규칙이 된다 — 예전엔 System C 만
   영역 A의 "표면" 색을 테두리에 돌려 써서, 테마에서 테두리를 지정해도 창 안
   테두리엔 반영되지 않았다(영역 A 에는 테두리 값 자체가 없다).
   ========================================================================== */
* {
  border-color: rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
}
.start-menu-search.input-text-box,
.taskbar-scope, .taskbar-scope * {
  border-color: rgba(var(--system-a-area-a-base-border-rgb), var(--system-a-area-a-base-border-alpha)) !important;
}
.window-bar, .window-bar *,
.window-toolbar, .window-toolbar * {
  border-color: rgba(var(--system-b-area-a-base-border-rgb), var(--system-b-area-a-base-border-alpha)) !important;
}
/* ==========================================================================
   스크롤 Manage
   width/track는 common.css와 동일하므로 재선언하지 않음. thumb 색상만 테마색으로 교체.
   ========================================================================== */
/* thumb 은 어디에 있든 Focus 색 하나로 통일한다(요청) — 예전엔 작업표시줄/
   윈도우바/창이 각자 자기 영역의 글자색을 따르는 3단 구조라, 창을 옮길 때마다
   스크롤바 색이 달라졌다. 스크롤바는 "지금 어디를 보고 있는지"를 알려주는
   장치라 영역과 무관하게 같은 색이 낫다. 투명도(.75)는 그대로 둔다 —
   순색은 본문 위에서 지나치게 튄다. */
*::-webkit-scrollbar-thumb {
  background: rgba(var(--focus-rgb), .75);
  border-radius: 10px;
}
/* ==========================================================================
   window.grid
   ========================================================================== */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(max(240px, calc((100% - 48px) / 5)), 100%), 1fr));
  gap: 3px;
}

/* 그림/영화/캐릭터/유튜브 모달: 포스트(캐릭터) 수가 한 줄 최대 열 수보다 적어도
   카드 폭을 유지하고 남는 공간은 빈 칸으로 둔다 (auto-fit는 빈 트랙을 접어
   카드가 늘어남). */
.window[data-template="gallery"] [data-gallery-grid],
[data-movie-grid],
[data-character-grid], [data-youtube-grid] {
  grid-template-columns: repeat(auto-fill, minmax(min(max(240px, calc((100% - 48px) / 5)), 100%), 1fr));
}

/* 좁은 화면(모바일 등, 다른 곳과 같은 640px 기준)만 최소 카드 폭을 150px로
   낮춘다 — 기본 240px 그대로면 창 폭(모바일은 화면 전체, 패딩 빼고
   350~380px대)에 한 줄에 카드 1장만 들어간다. 데스크톱은 이 미디어쿼리
   밖이라 기본 240px를 유지한다. */
@media (max-width: 640px) {
  .window[data-template="gallery"] [data-gallery-grid],
  [data-movie-grid],
  [data-character-grid], [data-youtube-grid] {
    grid-template-columns: repeat(auto-fill, minmax(min(max(150px, calc((100% - 12px) / 5)), 100%), 1fr));
    gap: 3px;
  }
}

/* 패치 노트 메뉴(요청) — 같은 그림 글을 썸네일 없이 한 줄씩 쌓는 로그로 그린다. */
.window[data-template="gallery"] [data-gallery-grid].is-note-log {
  grid-template-columns: 1fr;
  gap: 6px;
}
/* 카드 제목 줄의 윗 여백(썸네일과 띄우는 7px)은 썸네일 없는 로그 줄에선 제목만 아래로 밀었다(요청). */
.window[data-template="gallery"] [data-gallery-grid].is-note-log .post-title-row {
  margin-top: 0;
}

/* 카드 우측 하단의 좋아요(homepage.ui.js bindGridCellActions 가 카드마다 얹는다)
   — 사용자 탭의 .activity-unlike 와 같은 모양/자리다. 하트를 기준 삼으려면
   카드가 position:relative 여야 한다. */
.grid-cell-like {
  position: absolute;
  right: 5px;
  top: 4px;
  z-index: 2;
  width: 28px;
  height: 28px;
  line-height: 1;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0 !important;
  background: transparent !important;
  color: var(--system-c-area-b-base-desc-font-color) !important;
  cursor: pointer;
}
/* 눌린 하트도 그 영역의 폰트색을 따른다(요청) — focus 파랑으로 고정돼 있어
   테마를 바꿔도 하트만 파랗게 남았다. 영역 C 셀 안에서는 system-c.css 의
   별칭 블록이 이 변수를 영역 C 값으로 바꿔 준다. */
.grid-cell-like.is-liked {
  color: var(--system-c-area-b-base-font-color) !important;
}
.grid-cell-like, .grid-cell-like * { line-height: 1; }
/* 게시물 관리(선택) 모드에선 좋아요를 감춘다 — 체크 표시(.grid-cell-select)와
   같은 자리라 겹쳐 보였다. 카드 종류(그림/영화/유튜브/캐릭터)가 전부 같은
   .is-selectable 을 달아서 한 줄로 끝난다. */
.grid-cell.is-selectable .grid-cell-like { display: none; }
/* 커서 위치에 뜨는 카드 우클릭 메뉴 — 껍데기(.post-admin-menu)는 그대로 쓰고
   기준만 화면 좌표로 바꾼다(주소줄 아래가 아니라 커서 옆에 떠야 한다). */
/* 커서 자리에 뜨는 카드 우클릭 메뉴. 껍데기는 .post-admin-menu 를 그대로 쓰되
   그 규칙의 right:0(폭이 화면 끝까지 벌어짐)과 z-index:7(창 뒤로 깔림)을
   되받아야 해서 두 클래스를 함께 적는다(특이도 0,2,0). 실제 z-index 는
   여는 창보다 1 높게 JS 가 인라인으로 찍는다(다른 팝오버와 같은 방식). */
.post-admin-menu.grid-context-menu {
  position: fixed !important;
  top: auto;
  right: auto;
  bottom: auto;
  width: max-content;
  max-width: 240px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 132px;
  /* 줄이 많으면 스스로 스크롤한다 — 높이는 JS 가 작업표시줄 위까지로 잡아 준다(요청). */
  overflow-y: auto;
}

/* 작업표시줄 아이콘 우클릭 메뉴 — 미리보기 카드(.preview-card)와 같은 자리에
   같은 너비로 뜬다(요청). 자리는 JS(placeAboveTaskButton)가, 너비는 여기가
   맞춘다. 위 규칙의 width:max-content/max-width:240px 를 되받아야 해서
   특이도를 한 단계 올린다(0,3,0). */
.post-admin-menu.grid-context-menu.task-context-menu {
  width: 238px;
  max-width: 238px;
  min-width: 0;
  /* 미리보기 카드와 같은 층 — .post-admin-menu 의 z-index:7 이면 창 뒤로 깔린다. */
  z-index: var(--z-preview);
}

.grid-cell {
  position: relative;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
  border-radius: 9px;
  cursor: pointer;
  padding: 7px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  user-select: none;
  -webkit-user-drag: none;
}

.grid-cell img {
  -webkit-user-drag: none;
}
.window[data-template="gallery"] .grid-cell {
  min-width: 0;
  padding: 7px;
  border-radius: 9px;
  cursor: pointer;
  background: transparent;
  transition: .15s;
}

/* 그림/영화 후기 등 .grid-cell 공용 hover — 기존 .normal-button:hover와 같은
   System C hover 배경/글자/그림자 변수를 그대로 재사용한다. 제목(.grid-cell-title/
   .post-title/.movie-card-title)은 자체적으로 !important 색을 고정해 두므로,
   상속만으로는 hover 글자색이 먹히지 않는다 — 더 높은 특이도의 !important 규칙으로
   명시적으로 덮어써야 한다. 아이콘(.post-visibility-icon)도 stroke:currentColor라
   같은 이유로 명시한다. 메타(.grid-cell-meta 및 그 안의 span/svg, 영화 후기의
   .movie-card-meta.grid-cell-meta 포함)는 반대로 hover 중에도 System C 설명색
   (--system-c-area-b-base-desc-font-color, 아래 --font-color Manage 규칙)을 유지해야 하므로 여기서
   재정의하지 않는다.
   .grid-cell.is-selected의 outline(선택 표시)은 별개 속성이라 그대로 유지된다. */
.grid-cell:hover {
  /* 강조 배경은 기본 배경 위에 얹은 결과를 color-mix 로 미리 합성한다 — 결과가
     background-color 한 개라 전역 transition 목록에 들어 있어 테두리·글자와 같은
     속도로 함께 움직인다(예전 linear-gradient 오버레이는 background-image 라
     명세상 discrete = 보간 불가여서 배경만 즉시 튀었다). 불투명 강조색을 강조
     투명도(%)만큼 섞으면 결과가 src-over 합성과 정확히 같아, 투명도가 100
     미만이어도 창 뒤가 비치지 않는다. */
  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;
  background-image: none !important;
  color: var(--system-c-area-b-accent-font-color) !important;
  border-color: rgba(var(--system-c-area-b-accent-border-rgb), var(--system-c-area-b-accent-border-alpha)) !important;
  box-shadow: inset 0 1px 0 1px rgb(0 0 0 / 10%),
    0 5px 14px rgba(var(--system-c-area-b-accent-border-rgb), .16) !important;
}
/* 강조 테마도 폰트가 3종(타이틀/일반/설명)이라 hover 시 셋 다 자기 짝으로
   바뀌어야 한다 — 예전엔 제목에 "일반" 강조 폰트를 걸었고 메타·설명은 아예
   규칙이 없어 기본 설명색(!important)에 그대로 잠겨 있었다. */
.grid-cell:hover .grid-cell-title,
.grid-cell:hover .post-title,
.grid-cell:hover .movie-card-title {
  color: var(--system-c-area-b-accent-font-color) !important;
}
.grid-cell:hover .grid-cell-meta,
.grid-cell:hover .grid-cell-meta *,
.grid-cell:hover .post-meta,
.grid-cell:hover .post-meta * {
  color: var(--system-c-area-b-accent-desc-font-color) !important;
}

.grid-cell-meta {
  margin-top: 4px;

}

.window[data-template="gallery"] .grid-cell-meta,
.window[data-template="youtube"] .grid-cell-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.window[data-template="gallery"] .grid-cell-meta span,
.window[data-template="youtube"] .grid-cell-meta span {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

/* 그리드↔리스트 전환("⋯ → 리스트로 전환") — 카드 마크업은 그대로 두고
   .grid-cell을 [썸네일 | 본문] 2열로 오버라이드한다. 제목/메타(영화는 별점
   포함)는 .grid-cell-body로 묶여 있고(그리드 뷰에선 display:contents로 투명),
   리스트 뷰에서만 세로 flex 컬럼이 된다. 썸네일과 본문 블록은 하단 정렬. */
/* 컨테이너 자체를 한 열로 바꾼다 — !important는 위 갤러리 전용
   `.window[data-template="gallery"] [data-gallery-grid]`(특이도가 이 클래스
   선택자보다 높음) 등 grid-template-columns를 정하는 기존 규칙들을 3개
   모달 공통으로 확실히 덮기 위함이다. */
.grid.is-list-view {
  grid-template-columns: 1fr !important;
}
.grid-cell-body {
  display: contents;
}
.grid.is-list-view .grid-cell {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: end;
  column-gap: 12px;
  padding: 6px 10px;
}
.grid.is-list-view .grid-cell > .grid-cell-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
/* 썸네일은 높이만 64px로 고정하고 폭은 각 메뉴 그리드 카드의 기본 비율
   (.post-thumb 16/9, .movie-poster 2/3, 캐릭터 아바타 1/1)을 그대로 따른다. */
.grid.is-list-view .grid-cell > .post-thumb-wrap,
.grid.is-list-view .grid-cell > .character-card-avatar-wrap {
  grid-column: 1;
  align-self: end;
  width: fit-content;
  height: 64px;
  padding: 0;
}
/* <img>/aspect-ratio가 있는 썸네일: 높이만 채우고 폭은 비율대로. */
.grid.is-list-view .grid-cell .post-thumb,
.grid.is-list-view .grid-cell .movie-poster,
.grid.is-list-view .grid-cell .image-area {
  width: auto;
  height: 100%;
  object-fit: cover;
}
/* 캐릭터 아바타는 배경이미지 div(고유 비율 없음) — 정사각으로 고정. */
.grid.is-list-view .grid-cell .character-card-avatar {
  width: 64px;
  height: 64px;
}
/* 포스트 메뉴(그림·후기·감상)의 리스트는 썸네일 없이 제목·메타·좋아요 버튼만(요청) —
   패치 노트 로그 줄과 같은 모양. 캐릭터 목록의 아바타는 그대로 둔다. */
.grid.is-list-view .grid-cell > .post-thumb-wrap {
  display: none;
}
.grid.is-list-view .grid-cell:has(> .post-thumb-wrap) {
  grid-template-columns: 1fr;
}
/* 제목/설명 줄 바짝. */
.grid.is-list-view .grid-cell > .grid-cell-body > .post-title-row {
  margin: 0;
  line-height: 1.2;
}
.grid.is-list-view .grid-cell > .grid-cell-body > .grid-cell-meta,
.grid.is-list-view .grid-cell > .grid-cell-body > .movie-card-rating {
  margin: 0;
}

/* ==========================================================================
   SVG Manage
   ========================================================================== */
svg, svg:not([fill="currentColor"]) {
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.medium-svg {
  width: 17px;
  height: 17px;
}

.big-svg {
  width: 22px;
  height: 22px;
}

/* 아이콘 자리에 올린 그림(메뉴 아이콘 업로드)도 같은 칸에 가둔다 — 원본이 크면
   바로가기 칸을 밀어 배치가 무너졌다(요청). 비율은 지키고 칸 안에 맞춘다. */
img.medium-svg, img.big-svg { object-fit: contain; flex: 0 0 auto; }
/* 크기 class 없이 쓰는 자리(창 제목·주소창 등)는 제 칸을 넘지 않게만 막아 둔다. */
.desktop-shortcut img, .app-btn img, .shortcut img { max-width: 100%; max-height: 100%; object-fit: contain; }

.input-text-box svg {
  flex: 0 0 auto;
}

/* ==========================================================================
   ETC
   ========================================================================== */

.taskbar { /* 작업표시줄 */
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--taskbar-h);
  /* 안쪽 한 줄에 실제로 남는 높이 — 전체 높이에서 윗 테두리(2px)와 상하
     패딩(3px씩)을 뺀 값. 안의 버튼들이 이걸 넘으면 .apps-viewport의
     overflow:hidden에 위·아래가 잘린다. 테두리/패딩을 바꾸면 여기도 같이. */
  --taskbar-row-h: calc(var(--taskbar-h) - 2px - 6px);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, .06);
  backdrop-filter: blur(20px) saturate(1.12);
  -webkit-backdrop-filter: blur(20px) saturate(1.12);
  /* 작업표시줄은 화면 아래에 꽉 차게 붙어 있어 좌·우·아래 테두리는 화면
     가장자리에 묻힌다 — 실제로 보이는 윗변에만 테두리를 둔다. 색은
     `.taskbar-scope`(영역 A 기본 테두리)가 준다. 예전엔 border-top-color만
     지정돼 있고 border-style이 없어 색만 있고 그릴 자리가 없었다. */
  border-top-width: 2px !important;
  border-top-style: solid !important;
}

/* 좁은 화면은 작업표시줄 공간을 상시 예약하지 않는다. 하단 스와이프로
   .is-mobile-visible이 붙는 동안만 전체화면 모달 위에 오버레이한다. */
@media (max-width: 640px) {
  .desktop {
    height: 100vh;
    height: 100dvh;
  }

  .taskbar {
    transform: translateY(100%);
    transition: transform .2s ease;
  }

  .taskbar.is-mobile-visible {
    transform: translateY(0);
  }

  .taskbar,
  .shortcut-popover,
  .search-suggest,
  .sound-popover,
  .calendar-popover,
  .preview-card {
    z-index: calc(var(--z-dialog) - 1) !important;
  }
}

@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  .taskbar {
    transition: none;
  }
}

/* 작업표시줄 좌측(시작+검색) / 우측(볼륨+시계) 묶음 — gap만 다름 */
.start-group, .status {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}
.start-group { gap: 4px; }
.status { gap: 1px; }

/* 작업표시줄 아이콘 버튼 공통 골격. 배경/글자/hover는 .sys-a-btn-a(§버튼)가 담당. */
.task-square, .app-btn, .status-btn, .gallery-power-button {
  border: 0;
  border-radius: 7px;
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
}
/* display:grid 가 [hidden] 기본값을 이기므로 숨김을 따로 건다(앱 설치 버튼은 조건부로만 보인다). */
.status-btn[hidden] {
  display: none;
}

/* 높이는 작업표시줄 안쪽에 실제로 남는 공간(--taskbar-row-h)을 넘지 않는다.
   예전엔 --taskbar-h의 90%를 그대로 써서 안쪽 여유(윗 테두리 2px + 상하
   패딩 3px씩)보다 커졌고, .apps-viewport가 overflow:hidden이라 넘친 만큼
   버튼의 위·아래 테두리가 잘려 강조 테두리가 좌우만 보였다. */
.status-btn, .task-square, .app-btn {
  width: calc(var(--taskbar-h)*.9);
  height: min(calc(var(--taskbar-h)*.9), var(--taskbar-row-h));
}

.task-square, .app-btn {
  position: relative;
  flex: 0 0 auto;
}

.star-btn {
  line-height: 1;
  text-align: center;
}
/* ✦ 글자를 SVG 로 바꿨다(요청: 모바일에서 시작 버튼만 아래로 치우침) — 글리프가
   글꼴마다 다른 높이에 앉던 문제가 사라진다. 크기는 옆 돋보기(.medium-svg)와 같다. */
.star-btn-icon {
  width: 20px;
  height: 20px;
  fill: currentColor;
  stroke: none;
}

.star-btn:after {
  content: "";
  position: absolute;
  left: 9px;
  right: 9px;
  bottom: 2px;
  height: 2px;
  border-radius: 99px;
  opacity: 0;
}

.input-text-box {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 12px;
  border-radius: 25px;
  /* 유리 효과의 세기 = 이 입력칸 배경의 투명도. 배경이 완전히 투명하면(알파 0)
     칠할 표면 자체가 없는 것이라 블러/채도도 걸지 않는다 — 안 그러면 뒤에 깔린
     영역 배경이 흐려지고 채도가 올라가, 투명한데도 주변과 다른 자국이 남는다. */
  --input-glass: var(--area-input-alpha, var(--system-c-area-b-base-alpha, 1));
  backdrop-filter: blur(calc(18px * var(--input-glass))) saturate(calc(1 + .12 * var(--input-glass)));
  -webkit-backdrop-filter: blur(calc(18px * var(--input-glass))) saturate(calc(1 + .12 * var(--input-glass)));
  cursor: text;
  flex: 0 0 auto;
  border: 1px solid rgb(0 0 0 / 30%) !important;
}

.input-text-box input {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
}

.search-suggest {
  position: fixed;
  display: none;
  overflow: auto;
}

.search-suggest.open {
  display: block;
}

.suggest-item {
  width: 100%;
  border: 0;
  border-radius: 7px;
  text-align: left;
  cursor: pointer;
}

.suggest-item small {
  display: block;
}

/* 검색어 강조 — <mark> 기본색(노랑) 대신 포커스 색을 쓴다(요청). 상세보기 검색의
   .search-highlight 와 같은 값이다. */
.suggest-item mark {
  border-radius: 2px;
  padding: 0 1px;
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}

.apps-viewport {
  position: relative;
  flex: 1;
  min-width: 0;
  height: 100%;
  overflow: hidden;
}

.apps {
  height: 100%;
  display: flex;
  align-items: center;
  /* 칸 간격은 좌우 안쪽 여백과 같은 값이어야 한다 — 한 칸 스크롤로 멈췄을 때
     직전 칸의 오른쪽 끝이 딱 화면 밖(0px)에 놓여 조각이 안 남는다(요청). */
  gap: 3px;
  padding: 0 3px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  touch-action: pan-x;
  /* 스크롤은 아이콘 한 칸 단위로 멈춘다(요청) — 예전엔 아무 데서나 멈춰
     양 끝 아이콘이 반쯤 잘린 채 남았다. 왼쪽 안쪽 여백(3px)만큼 scroll-padding
     을 줘야 멈춘 자리에서 첫 칸이 여백에 가려지지 않는다. */
  scroll-snap-type: x mandatory;
  scroll-padding-left: 3px;
}
/* 소유자라 끌어 차례를 바꿀 수 있는 줄에서는(bindIconReorder 가 표시한다) 아이콘 위 터치를
   브라우저가 가져가지 않는다 — 그래야 길게 누른 뒤 그대로 끌 수 있다(요청).
   줄 자체를 굴리는 건 아이콘 사이 빈 자리(.apps 의 pan-x)로 그대로 된다. */
.apps[data-reorder-bound="1"] > .app-wrap:not(.dynamic) { touch-action: none; }
.apps > .app-wrap {
  scroll-snap-align: start;
}

.apps::-webkit-scrollbar {
  display: none;
}

.app-wrap {
  position: relative;
  flex: 0 0 auto;
}

/* 안 읽은 채팅 메시지 알림이 있는 메뉴 — 아이콘 우측 위 포커스색 점(요청). UI.setTaskbarNotifDots
   ::after 는 아래 실행 중 창 밑줄이 쓰고 있어 ::before 로 그린다. */
.app-btn.has-notif-dot::before {
  content: '';
  position: absolute;
  top: 3px;
  right: 3px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--focus-color);
  pointer-events: none;
}

.app-btn, .window[data-root="user"] * {
  user-select: none;
  -webkit-user-drag: none;
}

.app-btn:after {
  content: "";
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 2px;
  height: 2px;
  border-radius: 99px;
  opacity: 0;
  transform: scaleX(0);
  transition: opacity .14s,transform .14s,left .14s,right .14s;
}

.app-btn.active:after {
  opacity: 1;
  transform: scaleX(1);
}

.app-btn.active.focused:after {
  left: 9px;
  right: 9px;
}

.app-btn.active.minimized:after {
  left: 18px;
  right: 18px;
}

.icon-click {
  animation: task-icon-bounce .24s ease;
}

@keyframes task-icon-bounce{
  0%{transform:translateY(0)}
  38%{transform:translateY(-4px)}
  68%{transform:translateY(1px)}
  100%{transform:translateY(0)}
}

.clock {
  border: 0;
  border-radius: 7px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 8px;
  white-space: nowrap;
  cursor: pointer;
}
/* 좁은 화면 전용 달력 아이콘(요청) — 넓은 화면에서는 시각/날짜 글자를 쓴다. */
.clock-calendar {
  display: none;
  flex: 0 0 auto;
}
.clock-calendar svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
}
.clock-datetime {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
}
/* 알림은 로그인해야 쓸 수 있어 비로그인 방문자에겐 감춘다(homepage.js). */
.clock-bell[hidden] {
  display: none;
}
/* 시계 버튼 안 날짜 오른쪽 종 아이콘 + 읽지 않은 알림 수 뱃지. */
.clock-bell {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}
.clock-bell svg {
  width: 15px;
  height: 15px;
}
.clock-bell-count {
  position: absolute;
  top: -6px;
  right: -8px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  box-sizing: border-box;
  border-radius: 8px;
  background: var(--focus-color);
  color: var(--focus-font-color);
  /* 테두리 없음(요청). 예전엔 작업표시줄 색과 같은 2px 링(box-shadow)으로
     종 아이콘에서 뱃지를 오려내듯 분리했다 — 테두리로 보이던 게 이것이다. */
  border: 0 !important;
  box-shadow: none;
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
}
.clock-bell-count[hidden] {
  display: none;
}
/* windows */

.window {
  position: fixed;
  display: none;
  flex-direction: column;
  overflow: hidden;
  min-width: 260px;
  min-height: 180px;
  width: 560px;
  height: 420px;
  border-radius: 12px;
  box-shadow: 0 6px 14px -2px rgb(0 0 0 / 0.2);
  backdrop-filter: blur(18px) saturate(1.08);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
  border: 2px solid;
}

.window.open {
  display: flex;
}

/* 상세 창의 "처음 열리는 크기"는 1000x700 이고(homepage.ui.js의
   resolveMainWindowSize) 여기 min-* 는 "더 줄일 수 없는 한계"다 — 예전엔 이
   값도 1000x700 이라 사실상 리사이즈가 막혀 있었다.
   폭 400px 근거: 댓글 헤드가 한 줄을 유지하는 데 필요한 폭의 합
   (이름+날짜+버튼 237 + 아바타·간격 55 + 덩어리 패딩 18 + 컨텐츠 패딩 28
   + 창 본문 패딩 16 + 창 테두리 4 ≒ 358) 에 이름이 몇 글자는 보이도록 여유.
   그보다 좁아지면 버튼 줄이 접혀 댓글 레이아웃이 무너진다. */
.window.post-detail-window {
  min-width: min(400px, calc(100vw - 4px));
  min-height: min(320px, calc(100dvh - var(--desktop-bottom-h) - 4px));
}

.window.comment-window {
  min-height: 220px;
}

.window.minimized,.window.preview-hidden {
  display: none !important;
}

/* 비활성 창은 화면에 그대로 남기되 CSS 애니메이션의 프레임 소비를 멈춘다.
   music/youtube는 JS 수명주기에서 is-suspended 자체를 붙이지 않는다. */
.window.is-suspended *,
.window.is-suspended *::before,
.window.is-suspended *::after {
  animation-play-state: paused !important;
}

.window.preview-peek {
  display: flex !important;
}

.window.maximized {
  top: 0 !important;
  left: 0 !important;
  width: 100vw !important;
  height: calc(100vh - var(--desktop-bottom-h)) !important;
  /* 모바일 브라우저의 100vh는 주소창이 접힌 "최대" 높이로 고정돼 있어,
     주소창이 떠 있는 실제 화면(더 작은 동적 뷰포트)보다 커진다 — 창
     하단이 그만큼 실제 화면 밖으로 밀려나 작업표시줄(고정 bottom:0)에
     가려 보인다. dvh(동적 뷰포트, 지원 브라우저에서 위 100vh를 덮어씀)로
     실제 보이는 높이만큼만 잡는다. */
  height: calc(100dvh - var(--desktop-bottom-h)) !important;
  border-radius: 0 !important;
  /* 전체모드에서는 창 테두리를 없앤다 — 화면 가장자리에 딱 붙어 있어
     테두리가 "창의 경계"가 아니라 화면 테두리처럼 보인다(모서리도 이미
     각지게 편 상태). 테두리 색은 그대로 두고 굵기만 0으로 하면
     .window의 border-color !important 규칙과 싸울 일이 없다. */
  border-width: 0 !important;
  /* 그림자도 없앤다(요청) — 화면에 꽉 찬 창 가장자리에 그림자가 남으면 그것이
     테두리처럼 보인다(특히 전체화면 모달). */
  box-shadow: none !important;
}

/* 창을 화면 가장자리/모서리로 끄는 동안 스냅될 영역을 미리 보여주는 오버레이
   (homepage.ui.js가 하나만 만들어 위치·크기·표시 여부를 계속 바꿔 쓴다).
   pointer-events:none이라 실제 드래그를 절대 가로채지 않고, z-index는 매번
   드래그 중인 창보다 1 낮게 다시 맞춰져 그 창 뒤에서만 보인다. */
.window-snap-preview {
  position: fixed;
  pointer-events: none;
  border-radius: 12px;
  background: rgba(var(--system-c-area-a-base-rgb), var(--system-c-area-a-base-alpha));
  border: 2px solid rgba(var(--system-c-area-b-accent-border-rgb), .16);
  box-shadow: 0 5px 14px -2px rgba(var(--system-c-area-b-accent-border-rgb), .16);
}

.window-snap-preview[hidden] {
  display: none;
}

.window-bar {
  flex: 0 0 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px 0 12px;
  user-select: none;
}

.window-title-group {
  min-width: 0;
  flex: 1;
  display: flex;
  align-items: center;
  gap: 5px;
}

.window-title-icon {
  flex: 0 0 auto;
  width: 1em;
  height: 1em;
  display: inline-flex;
  color: inherit;
}

.window-title-icon img,
.window-title-icon svg {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.window-title {
  min-width: 0;
  flex: 1;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* line-height 기본값(브라우저 "normal", 폰트마다 1.15~1.2배)이 아이콘의
     1em 정사각 박스보다 커서, .window-title-group의 align-items:center가 둘을
     "박스" 기준으로는 맞춰도 글자 자체의 광학 중심은 살짝 어긋나 보인다 —
     1로 낮춰 줄박스를 아이콘 박스 높이에 붙인다. */
  line-height: 1;
}

.window-actions {
  display: flex;
  align-items: center;
  gap: 2px;
}

.window-minimize,.window-close {
  width: 23px;
  height: 23px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
}

.window-minimize {
  line-height: 1;
  padding-top: 4px;
}

.window-content {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* 좌우 패딩만 변수로 빼둔다 — 아래 다이어리 캘린더처럼 이 패딩을 상쇄해
     창 폭 끝까지 채우는 요소가 데스크톱/모바일(아래 미디어쿼리에서 값만
     바뀜) 양쪽에서 항상 정확히 같은 값을 참조하게 하기 위함. */
  --window-content-padding-x: 14px;
  padding: 14px var(--window-content-padding-x);
  /* 네이티브 스크롤바 대신 아래 .window-content-scrollbar(다이어리 캘린더와
     같은 오버레이 방식)를 쓴다 — 콘텐츠 폭을 차지하지 않는다. */
  scrollbar-width: none;
  box-shadow: inset 0 10px 10px -18px rgba(var(--system-b-area-a-base-border-rgb), var(--system-b-area-a-base-border-alpha));
}

/* 모바일(창이 자동 최대화되는 폭, 다른 곳과 같은 640px 기준) — 어차피 화면
   전체를 쓰는 만큼 양옆 여백부터 줄여 실제 컨텐츠 폭을 넓힌다. 위아래는
   그대로(스크롤로 해결되니 급하지 않음). */
@media (max-width: 640px) {
  .window.maximized {
    height: 100vh !important;
    height: 100dvh !important;
  }

  .window.guestbook-window {
    max-width: none;
  }

  .window-content {
    --window-content-padding-x: 8px;
    padding-left: var(--window-content-padding-x);
    padding-right: var(--window-content-padding-x);
  }
}

.window-content::-webkit-scrollbar {
  display: none;
}

/* 로그인/회원가입 오버레이(user.js showView)가 떠 있는 동안 — 뒤에 항상
   렌더링돼 있는(로그인해야 보일) 프로필 본문이 이 창의 스크롤 높이를 그대로
   차지해, 오버레이 위에서 휠을 굴리면 오버레이째로 밀려다녔다(요청). */
.window-content.is-scroll-locked {
  overflow: hidden;
}

/* ==========================================================================
   window-content 오버레이 스크롤바 — 다이어리 캘린더(.diary-scroll-shell)와
   같은 패턴을 모든 창의 본문 스크롤에 공용으로 적용한 것(homepage.ui.js의
   bindWindowOverlayScrollbar). window-content는 창마다 한 번만 만들어지고
   이후 내용만 갈아 끼우므로, 이 dock은 그 형제로 한 번만 붙고 JS가
   ResizeObserver/MutationObserver로 위치·크기를 다시 잰다. 평소엔 투명하다가
   휠 스크롤 중/드래그 중에만 보인다(is-active) — 스크롤할 게 아예 없으면
   hidden으로 완전히 빠진다. */
.window-content-scrollbar {
  position: absolute;
  right: 2px;
  width: 12px;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s;
  touch-action: none;
}

.window-content-scrollbar[hidden] {
  display: none;
}

.window-content-scrollbar.is-active {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

/* 네이티브 thumb과 같은 규칙 — 그 영역의 글자색을 따른다. 창 본문은
   System C이고, 작업표시줄 팝오버(알림 목록)가 같은 오버레이를 재사용하므로
   .taskbar-scope 안에서는 영역 A 글자색으로 덮는다. */
.window-content-scrollbar-thumb {
  /* 막대는 얇게, 잡는 자리는 그대로(요청) — 트랙(12px)은 두고 thumb 만 줄이면서
     왼쪽 여백을 그만큼 늘려 오른쪽 끝 위치를 유지한다. */
  margin-left: 7px;
  width: 5px;
  min-height: 28px;
  border-radius: 10px;
  /* 네이티브 스크롤바와 같은 Focus 색(요청) — 작업표시줄 팝오버가 이 오버레이를
     재사용하지만 이제 그쪽도 같은 색이라 따로 덮지 않는다. */
  background: rgba(var(--focus-rgb), .75);
  cursor: grab;
}

.window-content-scrollbar.is-dragging .window-content-scrollbar-thumb {
  cursor: grabbing;
}

/* ==========================================================================
   주소 표시줄 + 관리자 선택 메뉴
   ========================================================================== */
.window-toolbar {
  --area-input-rgb: var(--system-b-area-b-base-rgb);
  --area-input-alpha: var(--system-b-area-b-base-alpha);
  --area-input-font-color: var(--system-b-area-b-base-font-color);
  --area-input-border-rgb: var(--system-b-area-b-base-border-rgb);
  --area-input-border-alpha: var(--system-b-area-b-base-border-alpha);
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 4px;
  /* 자동완성(.window-address-suggest)이 이 줄 전체를 덮는 기준이 된다. */
  position: relative;
  background: rgba(var(--system-b-area-a-base-rgb), var(--system-b-area-a-base-alpha)) !important;
  color: var(--system-b-area-a-base-font-color) !important;
}

/* 좁은 창에서 주소창 폭 확보 — 뷰포트가 아니라 "이 창"의 폭이 기준이라
   컨테이너 쿼리를 쓴다(데스크톱에서 창을 좁혀도 똑같이 동작해야 한다).
   .window 자체는 자기 컨테이너를 질의할 수 없으므로, 주소줄을 감싸는
   래퍼가 아니라 창을 컨테이너로 두고 그 자손인 주소줄을 겨냥한다. */
.window {
  container-type: inline-size;
  container-name: window;
}

/* 좁을 땐 포커스만 해도 주소창이 줄 전체를 쓴다 — 예전엔 자동완성이 열려야
   (=타이핑을 해야) 넓어져서, 정작 주소를 읽고 고치려는 순간엔 좁았다.
   넓은 창에서는 버튼이 계속 보이는 편이 낫기 때문에 폭 조건을 건다. */
@container window (max-width: 640px) {
  .window-toolbar:has(.window-address-field:focus-within) > .window-address-controls,
  .window-toolbar:has(.window-address-field:focus-within) > .window-more-menu {
    display: none;
  }
}

.window-toolbar * {
  color: var(--system-b-area-a-base-font-color);
}

.window-toolbar input:hover,
.window-toolbar input:focus,
.window-toolbar select:hover,
.window-toolbar select:focus {
  background-color: color-mix(in srgb, var(--system-b-area-b-accent-color) calc(var(--system-b-area-b-accent-alpha) * 100%), rgba(var(--system-b-area-b-base-rgb), var(--system-b-area-b-base-alpha))) !important;
  background-image: none !important;
  border-color: rgba(var(--system-b-area-b-accent-border-rgb), var(--system-b-area-b-accent-border-alpha)) !important;
  color: var(--system-b-area-b-accent-font-color) !important;
}

/* 창 주소 줄 — window-bar 바로 아래 고정 행. 새 글 작성/수정 창
   (openPostEditorWindow가 세팅하는 data-post-editing)에는 보이지 않는다. */
.window[data-post-editing="1"] [data-window-address-bar] {
  display: none;
}
.window-address-controls {
  flex: 0 0 auto;
  display: flex;
  gap: 2px;
}
.window-address-button {
  width: 26px;
  height: 26px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  /* 같은 창의 최소화·닫기(.window-minimize/.window-close)와 같은 모서리. */
  border-radius: 6px;
  background: transparent !important;
  color: var(--system-b-area-a-base-font-color) !important;
  box-shadow: none !important;
  cursor: pointer;
  outline: none;
}
.window-address-button:disabled {
  opacity: .35;
  cursor: default;
}
.window-address-button svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* 주소창과 그 아래로 이어지는 자동완성이 같은 모서리를 갖게 하는 값.
   주소창 높이(26px)의 절반이라 브라우저가 더 깎지 않는다 — 예전엔 둘 다
   15px를 선언했지만 주소창은 높이 제한에 걸려 실제로는 13px로 그려져서
   자동완성(15px)과 이음매가 어긋나 보였다. 높이를 바꾸면 이 값도 같이. */
:root {
  --window-address-radius: 13px;
  /* 주소 필드와 자동완성이 아이콘 칸을 같은 폭으로 맞추는 값. 예전엔
     .window-address-field 에만 선언돼 있었는데, 자동완성이 주소줄 기준으로
     옮겨지면서(필드 밖) 상속이 끊겨 그리드가 0px 칸으로 무너졌다. */
  --window-address-icon-column: 32px;
}

.window-address-field {
  flex: 1;
  min-width: 0;
  height: 26px;
  box-sizing: border-box;
  position: relative;
  display: grid;
  grid-template-columns: var(--window-address-icon-column) minmax(0, 1fr) auto;
  align-items: center;
  border-radius: var(--window-address-radius);
  border: 1px solid;
  border-color: rgba(var(--system-b-area-b-base-border-rgb), var(--system-b-area-b-base-border-alpha)) !important;
  background: rgba(var(--system-b-area-b-base-rgb), var(--system-b-area-b-base-alpha));
}
.window-address-lock {
  width: var(--window-address-icon-column);
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.window-address-lock svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.window-address-lock-icon {
  display: flex;
  align-items: center;
  justify-content: center;
}
.window-address-lock-icon img {
  width: 13px;
  height: 13px;
  object-fit: contain;
}
.window-address-search-icon {
  display: none;
}
.window-address-field.is-suggest-open .window-address-lock-icon {
  display: none;
}
.window-address-field.is-suggest-open .window-address-search-icon {
  display: block;
}
/* 자동완성이 열리면 주소 입력과 그 아이콘이 패널 위로 올라온다(요청: 한글이
   한 글자만 써졌다) — 패널이 자기 검색 입력을 따로 갖던 예전 방식은 조합(IME)
   중에 포커스가 오가며 음절을 날렸다. 이제 패널 맨 위 한 줄은 이 입력이 앉을
   빈 자리고, 입력은 제자리에 그대로 머문다. */
.window-address-field.is-suggest-open > .window-address-lock,
.window-address-field.is-suggest-open > .window-address-input {
  position: relative;
  z-index: 21;
}
/* 주소창 입력 — 자동완성이 열려도 이 칸 하나가 검색칸 노릇까지 한다. */
.window-address-input {
  min-width: 0;
  width: 100%;
  height: 26px;
  padding: 0 10px 0 0;
  box-sizing: border-box;
  border-radius: 0;
  border: 0 !important;
  outline: none;
  background: transparent !important;
  color: var(--system-b-area-b-base-font-color) !important;
}
.window-toolbar .window-address-input:hover,
.window-toolbar .window-address-input:focus {
  border: 0 !important;
  outline: none;
  background: transparent !important;
  color: var(--system-b-area-b-base-font-color) !important;
}
/* 브라우저 주소창처럼 주소줄 한 줄을 통째로 덮고 그 아래 본문 위로 펼쳐진다.
   기준은 .window-toolbar(position:relative) — 예전엔 주소 필드 안에 있어
   필드 폭·테두리 안쪽에 갇혔고, 뒤로/새로고침/⋯ 버튼이 옆으로 비쳤다.
   위아래로 툴바 패딩(4px)만큼 넘겨 그 줄을 완전히 가린다. .window이
   overflow:hidden 이라 창 밖으로는 넘치지 않는다. */
.window-address-suggest {
  position: absolute;
  z-index: 20;
  /* -1px 은 주소창 자신의 테두리 두께 — 패널이 그 테두리까지 정확히 덮어
     같은 자리에서 같은 모서리로 이어진다(툴바 기준 top:4px 과 같은 위치). */
  top: -1px;
  left: -1px;
  right: -1px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0px;
  max-height: min(430px, 65vh);
  padding: 0;
  overflow: auto;
  /* .window-address-field(주소창 입력)와 반지름을 통일 — 이전엔 아래쪽만 10px로
     좁혀서 열렸을 때 주소창과 라운딩이 미묘하게 어긋나 보였다. */
  border-radius: var(--window-address-radius);
  /* .window-address-field(주소창 입력)과 같은 System B 입력 테두리 테마 —
     자동완성이 그 아래로 이어지는 모양이라 테두리도 이어져야 한다. */
  border: 1px solid rgba(var(--system-b-area-b-base-border-rgb), var(--system-b-area-b-base-border-alpha)) !important;
  background-color: rgba(var(--system-b-area-a-base-rgb), var(--system-b-area-a-base-alpha)) !important;
  background-image: none !important;
  box-shadow: inset 0 0 0 9999px rgba(var(--system-b-area-b-base-rgb), var(--system-b-area-b-base-alpha));
  cursor: default;
}
.window-address-suggest[hidden] {
  display: none;
}
/* 창 위쪽을 위로 밀면 제목줄과 주소줄이 위로 미끄러져 사라지고 본문만 남는다(요청: 전체보기).
   같은 자리에서 아래로 밀면 다시 내려온다. 제목줄에 건 음수 margin 이 아래 줄들을 같이
   끌어올리므로 본문도 함께 따라 올라오고, 창은 overflow:hidden 이라 밀려난 줄은 잘린다.
   --window-chrome-h 는 접는 순간 잰 두 줄의 높이(homepage.ui.js setWindowChromeFolded). */
/* 제목줄·주소줄에서 시작하는 손짓은 스크롤이 아니라 창 조작(접기/펴기·이동)이다(요청). */
.window > .window-bar, .window > .window-toolbar { touch-action: none; }
.window > .window-bar { transition: margin-top .2s ease, opacity .2s ease; }
.window > .window-toolbar { transition: opacity .2s ease; }
.window.is-chrome-folded > .window-bar {
  margin-top: calc(-1 * var(--window-chrome-h, 68px));
}
.window.is-chrome-folded > .window-bar,
.window.is-chrome-folded > .window-toolbar {
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .window > .window-bar, .window > .window-toolbar { transition: none; }
}
/* 자동완성은 영역 B다 — 예전 --system-b-font-color(=영역 A) 를 그대로 물려받아
   패널 전체가 영역 A 글자색으로 잠겨 있었다. 검색 입력·항목까지 B로 맞춘다. */
.window-address-suggest,
.window-address-suggest * {
  color: var(--system-b-area-b-base-font-color) !important;
}
.window-address-suggest .window-address-suggest-item {
  width: 100%;
  min-height: 30px;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: var(--window-address-icon-column) minmax(0, 1fr);
  align-items: center;
  gap: 0;
  padding: 3px 10px 3px 0;
  border: 0 !important;
  border-radius: 0;
  background: rgba(var(--system-b-area-b-base-rgb), var(--system-b-area-b-base-alpha)) !important;
  color: var(--system-b-area-b-base-font-color) !important;
  text-align: left;
}
.window-address-suggest-query {
  position: sticky;
  z-index: 1;
  top: 0;
  flex: 0 0 auto;
  min-width: 0;
  height: 26px;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: var(--window-address-icon-column) minmax(0, 1fr);
  align-items: center;
  padding: 0;
  background: rgba(var(--system-b-area-b-base-rgb), var(--system-b-area-b-base-alpha)) !important;
  color: var(--system-b-area-b-base-font-color) !important;
}
.window-address-suggest .window-address-suggest-item *,
.window-address-suggest .window-address-suggest-item mark {
  color: var(--system-b-area-b-base-font-color) !important;
}
.window-address-suggest .window-address-suggest-item:hover,
.window-address-suggest .window-address-suggest-item[aria-selected="true"] {
  background-color: color-mix(in srgb, var(--system-b-area-b-accent-color) calc(var(--system-b-area-b-accent-alpha) * 100%), rgba(var(--system-b-area-b-base-rgb), var(--system-b-area-b-base-alpha))) !important;
  background-image: none !important;
  border-color: rgba(var(--system-b-area-b-accent-border-rgb), var(--system-b-area-b-accent-border-alpha)) !important;
  color: var(--system-b-area-b-accent-font-color) !important;
  outline: none;
  box-shadow: none !important;
}
.window-address-suggest .window-address-suggest-item:hover *,
.window-address-suggest .window-address-suggest-item[aria-selected="true"] * {
  color: var(--system-b-area-b-accent-font-color) !important;
}
.window-address-suggest-icon,
.window-address-suggest-icon svg,
.window-address-suggest-icon img {
  width: 12px;
  height: 12px;
}
.window-address-suggest-icon {
  width: var(--window-address-icon-column);
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.window-address-suggest-icon svg {
  fill: none;
  color: inherit !important;
  stroke: currentColor !important;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.window-address-suggest-icon img {
  object-fit: contain;
}
.window-address-suggest-text {
  min-width: 0;
  height: 100%;
  display: flex;
  align-items: center;
}
.window-address-suggest-meta {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.window-address-suggest mark {
  padding: 0;
  background: transparent !important;
  color: inherit !important;
  font-weight: 700;
}
.window-address-field > .window-post-like {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 9px;
  border: 0 !important;
  /* 주소창과 같은 높이(26px)라 같은 모서리 값을 쓴다 — 15px를 적어도
     브라우저가 13px로 깎으므로 애초에 실제 값으로 맞춘다. */
  border-radius: var(--window-address-radius);
  background: transparent !important;
  color: var(--system-b-area-b-base-font-color) !important;
  white-space: nowrap;
}

/* 주소창 내부의 입력값·검색 결과·좋아요·아이콘은 입력 테마가 아니라
   윈도우바(System B) 컨텐츠 폰트색을 공통으로 따른다. */
.window-address-field,
.window-address-field * {
  color: var(--system-b-area-b-base-font-color) !important;
}
.window-address-field svg {
  stroke: currentColor !important;
}
/* 주소줄 오른쪽 끝 "⋯" 버튼 + 드롭다운 — margin-left:auto로 같은 줄의
   뒤로가기/새로고침/주소창보다 항상 오른쪽 끝에 붙는다. 드롭다운 자체는
   .post-admin-menu 위치/배경/그림자 스타일을 그대로 물려쓴다(아래
   window-more-dropdown 클래스 추가). */
.window-more-menu {
  position: relative;
  margin-left: auto;
  flex: 0 0 auto;
}

/* 검색 입력창/게시물 관리 패널 공용 껍데기 — .window-more-menu(position:relative)
   기준으로 아래 .post-admin-menu와 똑같이 뜨는 절대위치 팝업이다(요청: 주소줄
   레이아웃에 끼어들지 않고 post-admin-menu처럼 떠 보여야 함). [hidden]에
   !important가 필요한 이유는 아래 .post-admin-menu[hidden]과 같다. */
.window-more-panel,
.post-admin-menu,
.post-visibility-dropdown {
  position: absolute;
  padding: 4px;
  border: 1px solid rgba(var(--system-b-area-b-base-border-rgb), var(--system-b-area-b-base-border-alpha));
  border-radius: 6px;
  background-color: rgba(var(--system-b-area-a-base-rgb), var(--system-b-area-a-base-alpha)) !important;
  background-image: none !important;
  /* 영역 B 오버레이와 바깥 그림자를 한 선언에 함께 쓴다 — 예전엔 box-shadow를
     두 번 선언해 뒤엣것(그림자)이 앞엣것(오버레이)을 통째로 덮어썼고, 그래서
     배경만 영역 A로 남아 테두리·글자(B)와 어긋나 보였다. */
  box-shadow:
    inset 0 0 0 9999px rgba(var(--system-b-area-b-base-rgb), var(--system-b-area-b-base-alpha)),
    0 8px 20px -4px rgba(0, 0, 0, .18);
  color: var(--system-b-area-b-base-font-color) !important;
  backdrop-filter: blur(18px) saturate(1.08);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
}
.window-more-panel,
.post-admin-menu {
  top: calc(100% + 5px);
}
.window-more-panel {
  right: 34px;
  z-index: 6;
}
.window-more-search-panel {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 240px;
  height: 34px;
  box-sizing: border-box;
}
/* 세로 메뉴형 패널(게시물 관리 툴바 / ⋯ 드롭다운 / 공개범위 서브메뉴) 공통. */
.post-admin-toolbar.window-more-panel,
.post-admin-menu,
.post-visibility-dropdown {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.post-admin-toolbar.window-more-panel,
.post-admin-menu {
  min-width: 125px;
}
.post-admin-menu {
  right: 0;
  z-index: 7;
}
.window-more-panel[hidden],
.post-admin-menu[hidden],
.post-visibility-dropdown[hidden] {
  display: none !important;
}
/* 창 안에서 뜨는 우클릭 팝업은 전부 일반 버튼 테마를 따른다(요청) — select 의 옵션
   목록(.post-editor-popover.custom-select-list)과 같은 표기다. 작업표시줄 메뉴는
   제 자리(시스템 A)를 따르므로 :not(.task-context-menu) 로 뺀다.
   껍데기의 영역 B 덧칠(inset)과 블러는 배경이 불투명해지는 만큼 끈다 — 남겨 두면
   버튼 색 위에 다른 톤이 한 겹 얹힌다. */
.post-admin-menu.grid-context-menu:not(.task-context-menu),
.post-editor-popover.shared-msg-toolbar {
  background: var(--system-c-button-base-color) !important;
  background-image: none !important;
  border: 1px solid rgba(var(--system-c-button-base-border-rgb), var(--system-c-button-base-border-alpha)) !important;
  color: var(--system-c-button-base-font-color) !important;
  box-shadow: 0 8px 20px -4px rgba(0, 0, 0, .18) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
/* 줄 hover 도 버튼 강조로 — .post-admin-menu-item 은 이미 .normal-button 이라
   저절로 따르고, 채팅 줄 메뉴의 항목만 같은 값을 맞춰 준다. */
.shared-msg-toolbar .post-editor-popover-item {
  color: var(--system-c-button-base-font-color) !important;
}
.shared-msg-toolbar .post-editor-popover-item:hover,
.shared-msg-toolbar .post-editor-popover-item.is-active {
  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;
  color: var(--system-c-button-accent-font-color) !important;
}
/* 우클릭 메뉴의 구분선 — 색은 테마(전역 border-color)를 그대로 따른다. */
/* 우클릭 메뉴의 묶음 이름줄(요청: 작업표시줄 "최신") — 누를 수 없는 머리글. */
.post-admin-menu-head {
  padding: 2px 10px;
  color: var(--system-c-area-b-base-desc-font-color);
  cursor: default;
}

.post-admin-menu-sep {
  margin: 4px 6px;
  border-top: 1px solid;
}
/* 히스토리 목록처럼 아이콘이 붙는 항목 — 아이콘과 글자를 한 줄로 세운다.
   아이콘이 없는 항목은 이 규칙이 있어도 모양이 달라지지 않는다. */
.post-admin-menu-item-icon {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 15px;
  height: 15px;
}

.post-admin-menu-item-icon :is(svg, img) {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.post-admin-menu-item:has(.post-admin-menu-item-icon) {
  display: flex;
  align-items: center;
  gap: 7px;
  text-align: left;
}

.post-admin-menu-item {
  width: 100%;
  height: 26px;
  padding: 0 8px;
  border: 0;
  border-radius: 6px;
  background: transparent !important;
  text-align: left;
}
.window-more-panel *,
.post-admin-menu.window-more-dropdown * {
  color: var(--system-b-area-b-base-font-color) !important;
}

/* 선택된 상태를 강조하는 토글 버튼(예: 라이브2D 트래킹 패널) 공용 —
   다이어리의 활성 도구 아이콘(.diary-tool-icon.is-active: 배경을 포커스색으로
   채움)과 같은 느낌으로 맞춘다. */
.small-btn.is-active {
  background: var(--focus-color) !important;
  border-color: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}

/* danger 버튼은 Focus 색을 쓴다(하드코딩 빨강 제거). */
.small-btn.danger {
  border-color: var(--focus-color) !important;
  color: var(--focus-color) !important;
}

.small-btn.danger:hover,
.small-btn.danger:focus-visible {
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}

/* 못 누르는 버튼은 어디서나 같은 표시 — 설정 폼의 [만들기] 처럼 조건이 갖춰져야
   열리는 버튼도 눌리는지 아닌지가 보여야 한다(요청). */
.small-btn:disabled,
.normal-button:disabled,
.primary-button:disabled {
  opacity: .4;
  cursor: default;
}

.post-visibility-editor {
  position: relative;
  display: inline-flex;
}

.post-visibility-dropdown {
  top: 0;
  right: 100%;
  left: auto;
  z-index: 7;
  min-width: max-content;
}

.post-visibility-option {
  width: 100%;
  height: 24px;
  padding: 0 8px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  text-align: left;
  cursor: pointer;
}

.grid-cell.is-selectable {
  position: relative;
}

.grid-cell-select {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 15px;
  height: 15px;
  border-radius: 4px;
  border: 1px solid;
  /* 카드(영역 B) 위에 얹히는 체크 표시라 바탕도 영역 B — 예전엔 흰색 고정이라
     어두운 테마에서 카드만 어둡고 이 점만 하얗게 남았다. */
  background: rgba(var(--system-c-area-b-base-rgb), .85);
  /* .post-thumb-wrap도 position:relative라 둘 다 z-index:auto인 채로는 DOM
     순서상 뒤에 오는 .post-thumb-wrap이 이 체크박스 위에 그려졌다(포지션드
     요소는 z-index:auto여도 비포지션드 요소보다 위, 같은 그룹 안에선 DOM
     순서로 쌓임). z-index를 줘서 명시적으로 위로 끌어올린다. */
  z-index: 1;
}

.grid-cell.is-selected {
  outline: 2px solid var(--focus-color);
  outline-offset: -2px;
}

.grid-cell.is-selected .grid-cell-select {
  background: var(--focus-color);
  border-color: var(--focus-color);
}

.post-title-row {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 7px;
}

.post-title-row .post-title,
.post-title-row .movie-card-title {
  margin-top: 0;
  min-width: 0;
}

/* 색은 자기가 놓인 자리에서 상속받는다 — 이 아이콘은 세 군데에 쓰인다:
   카드 제목 줄(.post-title-row, System C 영역 B), 주소창 아이콘 슬롯과
   공개범위 셀렉트(둘 다 System B). 예전엔 설명 폰트색을 못 박아 둬서 바로 옆
   제목과 색이 어긋났고, System B 자리에서도 System C 색이 새어 나왔다.
   stroke가 currentColor라 color만 상속되면 아이콘이 따라온다. */
.post-visibility-icon {
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: inherit;
}

/* 그리드 카드(그림/영화 후기) meta의 댓글 수 앞 아이콘 — 항상 .grid-cell-meta
   안에 있으므로 색은 그 부모의 !important 규칙(설명색, hover 중에도 유지)에 맡기고
   여기서는 크기·정렬만 잡는다. */
.grid-cell-comment {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.grid-cell-comment-icon {
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.resize-handle {
  position: absolute;
}

.resize-handle.n,.resize-handle.s {
  left: 12px;
  right: 12px;
  height: 8px;
}

.resize-handle.n {
  top: -3px;
  cursor: ns-resize;
}

.resize-handle.s {
  bottom: -3px;
  cursor: ns-resize;
}

.resize-handle.e,.resize-handle.w {
  top: 12px;
  bottom: 12px;
  width: 8px;
}

.resize-handle.e {
  right: -3px;
  cursor: ew-resize;
}

.resize-handle.w {
  left: -3px;
  cursor: ew-resize;
}

.resize-handle.nw,.resize-handle.ne,.resize-handle.sw,.resize-handle.se {
  width: 14px;
  height: 14px;
}

.resize-handle.nw {
  left: -3px;
  top: -3px;
  cursor: nwse-resize;
}

.resize-handle.ne {
  right: -3px;
  top: -3px;
  cursor: nesw-resize;
}

.resize-handle.sw {
  left: -3px;
  bottom: -3px;
  cursor: nesw-resize;
}

.resize-handle.se {
  right: -3px;
  bottom: -3px;
  cursor: nwse-resize;
}

.window.maximized .resize-handle {
  display: none;
}
.blog-post {
  box-sizing: border-box;
  max-width: 720px;
  margin: auto;
  padding: 10px;
  border-radius: 10px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
}

.blog-post h2 {
  margin: 0 0 5px;
}

.blog-post p {
  line-height: 1.85;
}

.blog-post + .post-comments {
  max-width: 720px;
  margin: 10px auto 0;
}

.comments {
  /* 댓글 덩어리(인용 줄 + 댓글) 사이 간격 — 배경도 테두리도 없는 평평한
     목록이라 간격이 좁으면 어디까지가 한 댓글인지 안 읽힌다(요청으로 넓힘). */
  margin-top: 3px;
  --comment-body-gap: 34px;
  display: flex;
  flex-direction: column;
  /* 간격은 gap 이 아니라 각 덩어리의 위아래 패딩이 만든다 — 그래야 사이에
     넣은 구분선이 두 댓글의 정확히 가운데 온다(gap 을 쓰면 선이 아래쪽
     덩어리에 붙는다). */
  gap: 0;
}

.comments-unsupported {
  display: none;
}

.comments h3 {
  margin: 0 0 10px;
}

/* 본문+댓글이 .post-sheet 라는 영역 B 덩어리 하나라, 댓글 항목은 자기 표면을
   따로 갖지 않는 평평한 행이다(요청). 배경/테두리는 아래 상태 표시(답글 대상,
   인용 이동 강조)에서만 잠깐 나타난다. */
.comment {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 15px;
  /* 패딩·테두리·강조는 껍데기(.comment-thread)가 갖는다 — 여기서 또 주면
     인용 줄과 여백이 어긋난다. */
  padding: 0;
}

/* 강조는 앞선(왼쪽 테두리) 하나로만 표시한다(요청) — 평소엔 같은 두께의
   투명 테두리가 자리를 잡고 있어 켜져도 글자가 밀리지 않는다.
   인용 줄을 눌러 원본으로 이동했을 때: 켤 때는 즉시, 뗄 때는 위
   transition(.45s)으로 천천히 풀린다. */
/* 강조는 덩어리(인용 줄 + 댓글) 전체에 한 번 칠한다(요청) — 상태 클래스는
   JS가 .comment 에 붙이므로 :has() 로 껍데기까지 끌어올린다. 배경은 다른
   강조와 같이 color-mix 로 미리 합성해 background-color 한 개로 만든다 —
   그래야 테두리·글자와 같은 속도로 함께 전환된다. */
.comment-thread:has(> .comment.is-revealed),
.comment-thread:has(> .comment.is-reply-target) {
  border-left-color: rgba(var(--system-c-area-b-accent-border-rgb), var(--system-c-area-b-accent-border-alpha)) !important;
  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;
}
/* 본문 글자까지 같이 강조색으로(요청) — 광역 body * 규칙이 자식을 "직접"
   잡아서, 위에서 스레드에만 color 를 줘도 상속으로는 안 내려간다.
   메타/시각 같은 설명 계열은 아래에서 다시 설명색으로 되돌린다. */
.comment-thread:has(> .comment.is-revealed) .entry-body,
.comment-thread:has(> .comment.is-revealed) .entry-body *,
.comment-thread:has(> .comment.is-reply-target) .entry-body,
.comment-thread:has(> .comment.is-reply-target) .entry-body * {
  color: var(--system-c-area-b-accent-font-color) !important;
}
.comment-thread:has(> .comment.is-revealed) .entry-meta,
.comment-thread:has(> .comment.is-revealed) .entry-meta *,
.comment-thread:has(> .comment.is-reply-target) .entry-meta,
.comment-thread:has(> .comment.is-reply-target) .entry-meta * {
  color: var(--system-c-area-b-accent-desc-font-color) !important;
}

/* 답글(=위에 인용 줄이 있는 댓글)을 강조하면 인용 줄까지 한 덩어리로 칠한다
   (요청) — 인용 줄과 댓글은 원래 같은 항목이라 강조 영역이 댓글에서만 시작하면
   토막나 보인다. 인용 줄은 .comment 의 형제라 상태 클래스가 안 붙으므로
   :has() 로 같은 덩어리 안의 강조를 본다(이 파일에서 이미 쓰는 방식).
   아래쪽 모서리는 .comment 가, 위쪽은 인용 줄이 맡아 둘이 이어진다. */
.comment-thread:has(> .comment.is-revealed) > .comment-quote,
.comment-thread:has(> .comment.is-revealed) > .comment-quote *,
.comment-thread:has(> .comment.is-reply-target) > .comment-quote,
.comment-thread:has(> .comment.is-reply-target) > .comment-quote * {
  color: var(--system-c-area-b-accent-desc-font-color) !important;
}

/* 인용 줄이 붙은 답글은 위 모서리를 인용 줄에 넘긴다 — 둘이 붙어 한 블록이 된다. */
.comment-thread:has(> .comment-quote) > .comment {
  border-radius: 0 0 10px 0;
}

/* 작성자 이름은 강조 타이틀, 날짜·버튼 줄은 강조 설명 — 기본 상태의 짝을
   그대로 따라간다. .entry-meta 는 기본 설명색이 !important 라 여기서 명시해야
   덮인다. */
.comment.is-revealed .entry-head > strong,
.comment.is-reply-target .entry-head > strong {
  color: var(--system-c-area-b-accent-font-color) !important;
}

.comment.is-revealed .entry-time,
.comment.is-reply-target .entry-time,
.comment.is-revealed .entry-meta,
.comment.is-revealed .entry-meta *,
.comment.is-reply-target .entry-meta,
.comment.is-reply-target .entry-meta * {
  color: var(--system-c-area-b-accent-desc-font-color) !important;
}

/* 켤 때는 즉시, 뗄 때만 위 transition(.45s)으로 천천히 풀린다. 인용 줄도 같이
   꺼야 한다 — 한쪽만 즉시 켜지면 나머지가 .45s 뒤따라와 두 영역이 순차적으로
   켜지는 것처럼 보인다. */
.comment-thread:has(> .comment.is-revealed) {
  transition: none;
}

.comment p {
  margin: 4px 0 0;
  line-height: 1.5;
  /* textarea에 입력한 줄바꿈(엔터)이 기본 white-space:normal에 의해 렌더링에서
     사라지던 문제 — 그림/영화/캐릭터/방명록 댓글이 모두 이 .comment 컴포넌트를
     공유하므로 여기 한 곳만 고치면 전부 반영된다. */
  white-space: pre-wrap;
  word-break: break-word;
}

/* ==========================================================================
   댓글(그림/영화/다이어리/방명록 공용 — 방명록도 같은 .comment 컴포넌트를
   그대로 쓴다): 아바타(좌) + 작성자/날짜/수정/삭제/답글(우) + 답글쓰레드
   ========================================================================== */

.entry-avatar {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  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: 0px solid;
}

.entry-avatar svg {
  width: 28px;
  height: 28px;
}

.entry-body {
  flex: 1;
  min-width: 0;
}

.entry-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

/* 이름은 내용만큼만 차지하고(길면 말줄임), 그 옆에 날짜가 붙는다(요청).
   버튼 묶음(.entry-meta)은 margin-left:auto 로 오른쪽 끝에 남는다 — 예전엔
   이름이 flex:1 로 남는 폭을 다 먹어서 그 역할을 대신했다. */
.entry-head > strong {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.entry-time {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* 댓글 작성자 아바타/닉네임 — 클릭하면 프로필 팝오버(setupMentionProfiles). */
.entry-avatar.is-profile-ref,
.entry-author.is-profile-ref {
  cursor: pointer;
}
.entry-author.is-profile-ref:hover {
  text-decoration: underline;
}

.entry-meta {
  flex: 0 0 auto;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
}

.entry-reply-toggle {
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
}

.entry-reply-toggle:hover,
.entry-reply-toggle:focus-visible {
  color: var(--system-c-area-b-accent-font-color) !important;
}

.entry-reply-form {
  margin-top: 6px;
}

.entry-reply-form[hidden] {
  display: none !important;
}

/* .comment는 display:flex를 지정하므로(위), 작성 폼/답글 폼처럼 .comment를
   그대로 쓰면서 hidden 속성으로 토글하는 요소는 이 규칙 없이는 hidden이
   무시된다(작성자 스타일시트가 UA 기본 [hidden] 규칙을 이긴다). */
.comment[hidden] {
  display: none !important;
}

/* 답글/수정 등록 버튼도 guest-form과 같은 이유로 절대배치 겹침 대신 textarea
   아래 별도 flex 행으로 분리한다 — 글이 길어지면(autoGrowTextarea) textarea
   자체가 커지고 버튼은 항상 그 아래에 그대로 있다. */
.entry-reply-input-wrap {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* 줄 안에서 바로 고치는 입력(댓글 수정·후기 댓글 수정·채팅 수정) — 입력 상자
   광역 입력 테마가 아니라 그 글이 놓인 판과 같은 영역 B 투명 입력이다(요청).
   전역 입력 테마는 마크업의 data-no-theme 으로 뺀다(채팅 작성칸과 같은 방식). */
/* .entry-reply-input-wrap textarea(0,1,1) 가 border:0·padding:0 을 !important 로
   박아 두므로 같은 자리에서 이기도록 요소까지 붙여 쓴다. */
.entry-reply-input-wrap textarea.inline-edit-input,
textarea.inline-edit-input {
  width: 100%;
  box-sizing: border-box;
  /* 크기조절 손잡이 없이 내용만큼 늘어난다(autoGrowTextarea, 20줄까지). */
  resize: none;
  padding: 4px 6px;
  border: 1px solid rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha)) !important;
  border-radius: 6px;
  background: transparent !important;
  color: var(--system-c-area-b-base-font-color);
  font: inherit;
  outline: none;
}
.entry-reply-input-wrap textarea.inline-edit-input:focus,
textarea.inline-edit-input:focus {
  border-color: var(--focus-color) !important;
}

/* min-height는 늘어나기 전 기본 크기의 바닥값, overflow-y:hidden은
   autoGrowTextarea가 height를 잴 때 스크롤바가 잠깐 끼어드는 걸 막는다 —
   실제 스크롤은 이 textarea 안이 아니라(생기지 않는다) 그 바깥 창에서
   생긴다. */
.entry-reply-input-wrap textarea {
  width: 100%;
  min-height: 50px;
  resize: none;
  overflow-y: hidden;
  /* border-box여야 autoGrowTextarea가 재는 scrollHeight(패딩 포함)를 그대로
     height에 넣어도 border/padding이 두 번 더해지지 않는다 — 아니면 실제
     필요한 높이보다 살짝 모자라 안에 스크롤이 도로 생긴다. */
  box-sizing: border-box;
  border-radius: 8px;
  padding: 0px;
  margin: 4px 0px 0px;
  border: 0px solid !important;
}

/* 위 border:0으로 테두리 자체는 이미 안 보이지만, .input-text-box:hover/focus의
   전역 box-shadow(테두리 안쪽 glow)는 별도 속성이라 따로 꺼야 한다 —
   :hover/:focus 의사클래스가 있어야 전역 규칙(.input-text-box:hover 등)보다
   우선한다. */
.entry-reply-input-wrap textarea:hover,
.entry-reply-input-wrap textarea:focus,
.entry-reply-input-wrap textarea:focus-within {
  box-shadow: none !important;
}

/* 답글 등록(버튼 1개)은 .entry-reply-submit-btn이 wrap의 직계 자식이라 여기서
   바로 우측 정렬한다. 수정 폼(버튼 2개)은 .entry-reply-actions가 그 자리를
   대신하는 직계 자식이다. */
.entry-reply-input-wrap > .entry-reply-submit-btn,
.entry-reply-actions {
  align-self: flex-end;
}

.entry-reply-submit-btn {
  height: 21px;
  padding: 0 8px;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}

.entry-reply-actions {
  display: flex;
  gap: 6px;
  margin-bottom: 5px;
}

.entry-replies {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.entry-replies:not(:empty) {
  margin-top: 3px;
}

/* 답글(1depth 초과)은 배경/그림자 없이, 우측 padding도 없애 날짜·좋아요·답글이
   상위 댓글과 동일한 우측 라인에 정렬되도록 함. 트리선 없이 프로필 사진 너비만큼만 들여쓴다. */
.entry-replies [data-entry] {
  position: relative;
  background: transparent !important;
  box-shadow: none !important;
  padding-right: 0 !important;
  padding-left: 0 !important;
}

/* 그림/일기 댓글(.comment-thread)은 guestbook(.entry-body 안에 중첩된
   .entry-replies)과 달리, 답글 목록이 부모 article과 형제로 분리되어 있어
   flex 중첩으로 저절로 들여써지지 않는다. 아바타 폭(40px)+간격(8px)만큼
   padding-left를 줘서 기존과 같은 시각적 들여쓰기를 재현하고, 이 padding이
   재귀적으로 중첩된 .entry-replies마다 쌓여 depth별 누적 들여쓰기가 된다.
   답글은 부모 카드 밖의 독립 항목이므로 배경/그림자는 .comment 기본값을
   그대로 유지한다(guestbook의 [data-entry] 스트리핑과 다른 지점). */
/* 답글 들여쓰기(.entry-replies)는 없앴다 — 댓글은 깊이 없이 평평하게 그리고,
   "누구에게 단 답글인지"는 항목 위 인용 줄(.comment-quote)이 대신한다(요청).
   .entry-replies 자체는 방명록(guestbook)이 아직 쓰므로 규칙을 남겨둔다. */

/* 답글 인용 — 원본 댓글을 한 줄로 미리 보여주고, 누르면 그리로 이동한다. */
/* 댓글 한 덩어리(인용 줄 + 댓글) — 인용 줄이 아래 댓글의 작성자 이름과
   같은 x 에서 시작하도록 그 오프셋을 여기 한 곳에서 정의한다. */
/* 댓글 한 덩어리(인용 줄 + 댓글)의 껍데기 — 패딩·앞선·모서리·강조를 여기서
   갖는다. 예전엔 .comment 가 갖고 있었는데, 인용 줄은 .comment 의 형제라
   그 패딩 밖에 놓여 "인용 있는 덩어리"만 위쪽 여백이 없어 보였다(요청).
   덩어리마다 껍데기가 똑같으니 인용 유무와 무관하게 간격이 같아진다. */
.comment-thread {
  /* 인용 줄의 내용이 아래 댓글의 작성자 이름과 같은 x 에서 시작하게 하는 값 —
     이제 패딩·앞선이 덩어리에 있으므로 아바타(40) + 간격(15)만 남는다. */
  --comment-name-indent: calc(40px + 15px);
  position: relative;
  padding: 14px 10px;
  border: 0 !important;
  /* 강조 시 켜질 앞선 자리를 미리 잡아 둔다(켜져도 내용이 안 밀리게).
     광역 `* { border-color: … !important }` 를 이기려면 !important 가 필요하다. */
  border-left: 2px solid transparent !important;
  /* 강조 배경에 라운딩을 두지 않는다(요청) — 목록이 구분선으로 나뉘는 구조라
     모서리가 둥글면 선과 배경의 끝이 어긋나 보인다. */
  border-radius: 0;
  /* 강조가 붙고 풀리는 전환 — 표시 시간(600ms)에 비해 길면 여운이 남아
     "오래 강조된다"고 느껴진다(요청). */
  transition: border-color .2s ease, background-color .2s ease, color .2s ease;
}

/* 댓글 위 구분선 — 설명 폰트색(요청). 첫 덩어리에도 그어 본문과 나눈다.
   border-top 이 아니라 절대 위치 가상 요소로 그리는 이유: border 는
   border-radius 를 따라 끝이 휘어서 우측이 곡선으로 보인다(요청: 선은 직선,
   라운딩은 유지). 절대 위치 자식은 부모의 radius 에 잘리지 않는다
   (overflow 를 숨기지 않는 한). */
.comment-thread::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha));
  pointer-events: none;
}

/* 위에 본문(.blog-post)이 없는 화면 — 캐릭터 상세의 댓글 팝업처럼 댓글만
   있는 경우 — 는 첫 덩어리 위 선을 긋지 않는다(요청). 나눌 대상이 없어
   선만 덩그러니 뜬다. */
[data-post-sheet]:not(:has(.blog-post)) .comments > .comment-thread:first-child::before {
  display: none;
}

.comment-quote {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  min-width: 0;
  /* 인용 내용(아바타·이름)이 아래 댓글의 "작성자 이름" 자리에서 시작하도록
     맞춘다(요청). 패딩·앞선은 껍데기(.comment-thread)가 갖는다. */
  margin: 0 0 2px;
  padding: 0 0 0 var(--comment-name-indent);
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

/* 인용 줄은 통째로 설명 폰트색(요청). 자손까지 명시해야 한다 — 광역
   `body *` 규칙이 이름/내용 요소를 "직접" 매치해 일반 폰트색을 씌우고,
   직접 매치는 부모에서 내려오는 상속을 항상 이긴다. */
.comment-quote,
.comment-quote * {
  color: var(--system-c-area-b-base-desc-font-color) !important;
}

.comment-quote:hover,
.comment-quote:hover *,
.comment-quote:focus-visible,
.comment-quote:focus-visible * {
  color: var(--system-c-area-b-accent-font-color) !important;
}

.comment-quote:focus-visible {
  outline: none;
}

.entry-avatar.comment-quote > .entry-avatar,
.comment-quote > .entry-avatar {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
}

.comment-quote > .entry-avatar svg {
  width: 9px;
  height: 9px;
}

.comment-quote-name {
  flex: 0 0 auto;
  font-weight: 700;
}

/* 원본이 길어도 한 줄 말줄임 — 인용은 "어디에 단 답글인지"만 알리면 된다. */
.comment-quote-content {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ==========================================================================
   게시글 상세 = 본문 + 구분선 + 댓글이 영역 B 한 덩어리(.post-sheet)이고,
   스크롤도 그 안에서 일어난다(요청). 작성 폼은 이 덩어리 밖의 푸터라
   덩어리와 함께 스크롤되지 않는다.
   ========================================================================== */
/* 컨텐츠 영역과 푸터가 형제 div라, 창 본문은 그 둘을 세로로 세우는 flex
   컨테이너가 되고 스크롤은 컨텐츠 영역만 갖는다(요청). :has()는 이 파일에서
   이미 쓰는 방식이다. */
.window-content:has(.post-comments > .post-content) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* padding-bottom 을 0으로 죽이지 않는다 — 도킹(position:absolute) 시절엔
     JS가 bottom:10px 으로 띄웠지만, 지금은 푸터가 흐름 안에 있으므로 창 본문의
     아래 패딩이 그 "하단 띄움"을 그대로 맡는다. */
}

/* 방명록은 템플릿의 래퍼([data-guestbook-root]) 한 겹을 더 거친다 — 그 래퍼가
   높이를 안 넘겨주면 푸터가 바닥에 안 붙고 스크롤도 컨텐츠 영역으로 안 간다.
   그래서 자손 선택자로 잡고, 중간 래퍼도 같이 세로로 늘려 준다. */
.window-content > [data-guestbook-root] {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.post-comments:has(> .post-content) {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 컨텐츠 영역 = 본문 + 구분선 + 댓글을 순서대로 담는 영역 B 한 판.
   댓글이 이 위에 "얹힌" 게 아니라 이 영역이 통째로 본문과 댓글을 차례로
   보여주는 형태라, 안쪽 항목은 자기 표면을 갖지 않는다(요청). */
.post-content {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  box-sizing: border-box;
  /* 폭 제한은 영역 자체가 갖는다(요청) — 안쪽 본문·댓글은 자기 폭을 정하지
     않고 이 영역을 꽉 채운다. */
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 14px;
  border-radius: 14px;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  /* 네이티브 스크롤바 대신 창 공용 오버레이 스크롤바를 쓰는 다른 영역과
     같은 처리(.window-content / .diary-scroll-shell). */
  scrollbar-width: none;
}

.post-content::-webkit-scrollbar {
  display: none;
}

/* 컨텐츠 영역 안의 항목은 자기 표면도 테두리도 갖지 않는다(요청) — 영역
   자체가 이미 영역 B 판이라, 안에서 또 칠하거나 두르면 블록이 나뉘어 보인다.
   폭도 영역이 정하므로 본문의 max-width 는 여기서 푼다. */
.post-content > .blog-post {
  max-width: none;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
}

/* 본문과 댓글 사이 여백 — 구분선을 없앴으므로(요청) 이 여백이 둘을 나눈다. */
.post-content > .comments {
  margin-top: var(--comment-body-gap, 34px);
}

/* 나눌 본문이 없으면(캐릭터 상세의 댓글 팝업) 그 여백도 필요 없다 — 위가
   비어 있는 채로 34px 만 남는다(요청). 첫 구분선/빈 안내와 같은 조건. */
[data-post-sheet]:not(:has(.blog-post)) > .comments {
  margin-top: 0;
}

/* 댓글이 하나도 없으면 본문과의 간격도 없앤다 — 빈 34px 만 남아 괜히 스크롤이 생긴다. */
.post-content > .comments:empty {
  margin-top: 0;
}

/* 푸터 = 댓글 작성 폼. 컨텐츠 영역과 형제라 함께 스크롤되지 않는다. */
.post-footer {
  flex: 0 0 auto;
}

/* ==========================================================================
   댓글 컴포즈 바 — 컨텐츠 영역과 형제인 푸터(.post-footer) 안에 그대로 있다.
   따로 위치를 잡을 게 없다: 컨텐츠 영역이 flex:1 로 남는 높이를 다 먹고
   이 바는 그 아래 자기 높이만큼 남는다. 최상위 댓글/답글 모두 이 입력창
   하나로 쓴다(homepage.ui.js의 setReplyTarget).
   ========================================================================== */
.comment-compose {
  box-sizing: border-box;
  /* 본문 폭에 맞춰 가운데 정렬 — 컨텐츠 영역 안의 본문/댓글과 같은 열. */
  max-width: 720px;
  margin: 0 auto;
  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));
  border-radius: 14px;
  padding: 8px 10px;
}

/* [hidden]인데도 위 규칙(작성자 스타일)이 네이티브 [hidden]의 display:none을
   이겨버려(.comment[hidden]과 같은 이유) 댓글 작성 권한이 없을 때
   (form.hidden=true) 이 바가 계속 보이던 버그가 있었다. */
.comment-compose[hidden] {
  display: none !important;
}

.comment-compose-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  box-sizing: border-box;
  border-radius: 14px;
  backdrop-filter: blur(18px) saturate(1.08);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
}
/* 답글을 달 때만 입력창 위에 붙는 얇은 바 — "OOO에게 답장하는 중"과 취소 ×.
   대상 댓글의 내용은 여기 넣지 않고 입력란 placeholder가 대신한다(요청). */
.comment-compose-replybar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  padding: 4px 4px 4px 10px;
  box-sizing: border-box;
  border-radius: 8px;
  font-size: 12px;
  background: 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)));
  color: var(--system-c-area-b-base-desc-font-color);
}

.comment-compose-replybar[hidden] {
  display: none !important;
}

/* 아바타 + "OOO에게 답장하는 중" 이 한 줄 — 아바타가 인라인으로 섞여야
   이름 바로 앞에 붙는다(요청). */
/* 누르면 대상 댓글로 이동하는 버튼이다(요청) — 버튼 기본 표면은 지우고
   답장 바 안에서 글자처럼 보이게 둔다. */
.comment-compose-reply-text {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}

.entry-avatar.comment-compose-reply-avatar {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}

.comment-compose-reply-avatar svg {
  width: 10px;
  height: 10px;
}

.comment-compose-reply-text strong {
  color: var(--system-c-area-b-base-font-color);
}

.comment-compose-reply-cancel {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
}

/* entry-avatar(내 프로필 사진)와 입력창 — 사진 상단과 입력창 첫 줄이
   맞도록 align-items:flex-start(요청). 입력창 높이는 homepage.ui.js의
   growCompose가 scrollHeight 기준으로 직접 조절한다. */
/* 접힌 상태(기본)에서는 아바타·입력창·[접기/펼치기][등록]이 한 줄이다(요청:
   닫기 시 작성영역과 등록 버튼을 같은 라인에 넣어 높이를 더 줄인다).
   펼치면 아래 .is-compose-expanded 규칙이 버튼 묶음을 다음 줄로 내린다. */
.comment-compose-body {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.comment-compose-actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

/* 펼친 상태 — 입력창이 여러 줄이라 아바타는 첫 줄에 맞추고 버튼은 아래 줄
   오른쪽으로 내린다(기존 푸터와 같은 모양). */
.comment-compose.is-compose-expanded .comment-compose-body {
  align-items: flex-start;
}

.comment-compose.is-compose-expanded .comment-compose-actions {
  width: 100%;
  justify-content: flex-end;
}

.comment-compose-body > .entry-avatar {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
}

.comment-compose-body > .entry-avatar svg {
  width: 20px;
  height: 20px;
}

.comment-compose-input {
  flex: 1 1 120px;
  min-width: 0;
  /* 한 줄 높이 — 여기서 시작해 growCompose 가 내용만큼 늘린다(예전 50px는
     접었을 때도 두 줄짜리 높이라 바가 두꺼웠다). */
  min-height: 34px;
  box-sizing: border-box;
  resize: none;
  border-radius: 8px;
  padding: 8px 10px;
  font: inherit;
  overflow-y: hidden;
  /* 입력창은 자기 표면을 갖지 않고 컴포즈 바 위에 그대로 얹힌다(요청) —
     data-no-theme 은 광역 input/textarea 테마 규칙의 opt-out 표식이다(그 규칙이
     특이도 0,2,1 에 !important 라 클래스 선택자로는 못 이긴다). —
     배경·테두리 없이 투명, 글자색만 영역 B 를 따른다. 예전엔 입력 상자
     테마를 칠해서 바 안에 또 하나의 상자가 들어앉은 모양이었다. */
  border: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  color: var(--system-c-area-b-base-font-color) !important;
}

/* 요청: 기본/hover/클릭(focus) 전부 테두리·box-shadow 없음 — 전역
   input/textarea:hover,:focus 규칙(homepage.css, border-color+box-shadow
   글로우를 !important로 켬)을 여기서 명시적으로 다시 꺼야 한다. */
/* 접혀 있을 땐 세로 패딩을 없앤다 — 패딩도 스크롤되는 영역이라, 패딩이 있으면
   높이를 한 줄에 맞춰도 그 패딩 자리에 위아래 이웃 줄이 8px씩 걸쳐 보인다.
   숨 쉴 공간은 컴포즈 바 자신의 padding 이 준다. */
.comment-compose:not(.is-compose-expanded) .comment-compose-input {
  padding-top: 0;
  padding-bottom: 0;
  min-height: 0;
}

.comment-compose-input:hover,
.comment-compose-input:focus,
.comment-compose-input:focus-within {
  border: 0 !important;
  outline: none !important;
  box-shadow: none !important;
  background: transparent !important;
  color: var(--system-c-area-b-base-font-color) !important;
}

.comment-compose-actions .small-btn {
  height: 27px;
  padding: 0 14px;
}

/* 공유기록 채팅(modals/shared.js)은 이 컴포즈 폼을 재사용하되 자기 마크업에
   푸터 줄(첨부 버튼 + 보내기)을 따로 둔다 — 게시글 댓글은 버튼을 입력 줄
   안으로 옮겼지만 이 규칙은 그쪽 때문에 남긴다. */
.comment-compose-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  padding-top: 6px;
}

.comment-compose-footer .small-btn {
  height: 27px;
  padding: 0 16px;
}
/* diary */

.window[data-root="diary"] .window-content {
  padding-bottom: 0;
}

.diary-layout {
  width: 100%;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  /* 우측 FAB(fab-dock)/좌하단 도구(diary-tool-dock)/스티커 툴팁을
     이 레이아웃 기준 절대 위치로 띄우기 위한 포지셔닝 컨텍스트. */
  position: relative;
}

.date-selects {
  display: flex;
  align-items: center;
  gap: 6px;
}

.diary-date-select {
  /* enhanceSelect가 만드는 .custom-select-wrap은 버튼(라벨)이 position:absolute라
     이 select 자신은 내용 폭에 전혀 기여를 못 한다 — min-width 없이는 padding만큼만
     남아 "2026년"/"9월"이 다 잘려 보인다(요청 확인). "2026년" 기준으로 잡는다. */
  min-width: 74px;
  height: 28px;
  padding: 0 8px;
  border: 1px solid;
  border-color: transparent !important;
  border-radius: 7px;
  font-weight: 750;
  background: transparent !important;
}

.diary-nav {
  display: flex;
  align-items: center;
  gap: 2px;
}

.diary-nav button {
  min-width: 25px;
  width: auto;
  height: 25px;
  padding: 0 7px;
  border: 0;
  background: transparent !important;
  border-radius: 6px;
  cursor: pointer;
}

/* 요일 머리글/달력 그리드만 .window-content 좌우 패딩을 음수 마진으로
   상쇄해 창 폭 끝까지 채운다(요청: "다이어리 캘린더는 여백 없이 창을
   가득 채우도록") — 위 연/월 선택·이동 버튼(.diary-head)은 그대로 패딩
   안쪽에 둔다. --window-content-padding-x는 .window-content가 정의하고
   모바일에서 8px로 바뀌므로(homepage.css 상단) 그 값을 그대로 물려받아
   항상 정확히 맞아떨어진다. */
.diary-weekdays,
.diary-scroll-shell {
  min-width: 0;
  margin-left: calc(var(--window-content-padding-x) * -1);
  margin-right: calc(var(--window-content-padding-x) * -1);
}

.diary-weekdays {
  display: grid;
  grid-template-columns: repeat(7,minmax(0,1fr));
  background: transparent;
  box-shadow: 0 3px 3px -2px rgba(0, 0, 0, .2);
}

.diary-weekdays span {
  text-align: center;
  padding: 7px 0;
}

.diary-scroll-shell {
  flex: 1;
  min-height: 0;
  position: relative;
}

.diary-scroll {
  width: 100%;
  min-width: 0;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
}

.diary-scroll::-webkit-scrollbar {
  display: none;
}

.diary-scrollbar {
  position: absolute;
  top: 0;
  right: 2px;
  bottom: 0;
  width: 12px;
  z-index: 850;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s;
  touch-action: none;
}

.diary-scroll-shell.is-wheel-scrolling .diary-scrollbar {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

/* 창 본문 스크롤바(*::-webkit-scrollbar-thumb)와 같은 Focus 색(요청). */
.diary-scrollbar-thumb {
  /* 창 본문 오버레이(.window-content-scrollbar-thumb)와 같은 두께(요청) — 트랙
     12px 은 그대로 두고 막대만 줄이면서 왼쪽 여백으로 오른쪽 끝을 맞춘다. */
  margin-left: 7px;
  width: 5px;
  min-height: 28px;
  border-radius: 10px;
  background: rgba(var(--focus-rgb),.75);
  cursor: grab;
}

.diary-scroll-shell.is-scrollbar-dragging .diary-scrollbar-thumb {
  cursor: grabbing;
}

.diary-grid {
  width: 100%;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(7,minmax(0,1fr));
  position: relative;
  /* 드래그로 날짜 범위를 고를 때(attachDragDateSelect) 브라우저 기본
     텍스트/이미지 선택이 함께 끼어들지 않도록 — 달력엔 어차피 사용자가
     따로 선택할 텍스트가 없다. */
  user-select: none;
  /* 내부 날짜뱃지와 꾸미기 스테이지의 z-index를 이 그리드 안에 가둔다. */
  z-index: 0;
}

/* 4:3로 고정 — 날짜 칸 자체는 빈 칸이고, 실제 꾸민 내용은 스티커(.diary-sticker)가
   같은 그리드 위에 겹쳐서 보여준다(아래). 날짜 숫자는 별도
   뱃지(.diary-day-num)로 배치하되 스티커보다 아래에 둔다. */
/* 평소엔(새로 만들기로 날짜를 고르는 중이 아니면) 완전히 비활성 — hover도
   클릭도 반응하지 않는다(pointer-events:none). 실제로 상호작용이 필요한 건
   .diary-grid.is-date-selecting일 때뿐이라 그때만 되살린다(아래). */
.diary-day {
  aspect-ratio: 4 / 3;
  padding: 6px;
  text-align: left;
  cursor: default;
  pointer-events: none;
  position: relative;
  background: transparent;
}

.diary-grid.is-date-selecting .diary-day {
  cursor: pointer;
  pointer-events: auto;
}

/* 날짜 범위를 여러 주에 걸쳐 세로로 드래그해서 고르는 제스처(attachDragDateSelect)라,
   터치에서 이 속성이 없으면 브라우저 기본 세로 스크롤이 같은 손가락 움직임을
   가로채 버려 한 주를 넘어가는 범위를 못 고른다. 날짜 선택 중일 때만 막고
   (평소 달력 스크롤은 그대로 터치로 되게) 좁힌다. */
.diary-grid.is-date-selecting {
  touch-action: none;
}

/* 새로 만들기로 날짜를 고르는 중엔 스티커(기존 게시글)를 클릭 대상에서
   완전히 빼서(pointer-events:none) 그 밑에 깔린 날짜 칸이 드래그를 그대로
   받게 한다 — 안 그러면 이미 게시글이 있는 날짜 위에서 드래그를 시작/통과할
   때 스티커의 <img>가 이벤트를 가로채 브라우저 기본 이미지 드래그가 뜨고
   (attachDragDateSelect의 cellSelector:'.diary-day' 매칭도 실패해) 그 날짜가
   선택 범위에서 빠지는 문제가 있었다. */
.diary-grid.is-date-selecting .diary-sticker {
  pointer-events: none;
}

/* 날짜 셀은 .normal-button 공통 규칙이 입히는 버튼 테마(배경/글자/테두리)
   대신 컨텐츠 테마를 쓴다. 격자선은 "칸을 나누는 선"이라 테두리가 아니라
   영역 B 구분선을 따른다(요청). */
.diary-grid .diary-day.normal-button.light-border {
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
  border-color: rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha)) !important;
}

/* 선택된 연/월과 다른 달의 날짜 칸은 사용자가 휠을 굴리거나 스크롤바를
   드래그하는 동안에만 흐리게 표시한다. 입력이 끝나면 셀은 전부 원래
   불투명도로 돌아간다. */
.diary-day.is-outside-selected-month {
  opacity: 1;
}

.diary-scroll-shell.is-diary-scrolling .diary-day.is-outside-selected-month {
  opacity: .5;
}

/* 오늘 셀은 더 이상 테두리(outline)로 표시하지 않는다 — 날짜 숫자 색만으로
   충분하다는 요청. 색상 변경은 아래 .diary-day-num.today가 그대로 담당한다. */

/* 선택 강조 배경은 위 .diary-grid .diary-day.normal-button.light-border(컨텐츠
   테마) 규칙과 특이도를 맞춰야 이긴다 — 같은 4-클래스로 선언하고 뒤에 둔다. */
.diary-grid .diary-day.normal-button.is-selected {
  background: rgba(var(--focus-rgb), .28) !important;
}
.diary-day.is-selected {
  outline: 2px solid var(--focus-color);
  outline-offset: -2px;
}

/* 날짜 숫자 뱃지 — .diary-grid의 형제 아이템으로 grid-row/grid-column을
   명시해 그 날짜 칸 위에 정확히 얹는다. 배경 없이 System C 폰트색만으로
   표시하고, pointer-events:none이라 클릭/hover는 아래로 그대로 전달된다
   (날짜 숫자 자체는 클릭 대상이 아니다). */
.diary-day-num {
  position: relative;
  align-self: start;
  justify-self: start;
  margin: 3px;
  padding: 1px 4px;
  font-size: 10px;
  line-height: 1.4;
  color: var(--system-c-area-b-base-font-color);
  pointer-events: none;
  z-index: 0;
}

.diary-day-num.today {
  color: var(--focus-color);
  font-weight: 700;
}

/* 캘린더꾸미기(beginDecorateMode) 중엔 실제 날짜 칸 위를 세그먼트(선택한 날짜가
   이어진 한 주 구간) 단위의 편집 스테이지(.diary-decorate-segment)가 통째로
   덮으므로, 밑에 깔린 날짜 칸 자체는 그냥 클릭 반응만 꺼둔다. */
.diary-day.is-decorating {
  cursor: default;
}

/* 캘린더꾸미기 중엔 지금 편집 중인 세그먼트(.is-decorating 날짜 칸/숫자)만
   또렷하게 남기고 나머지 달력(다른 주의 날짜 칸·숫자)은 반투명하게 낮춰
   편집 대상에 시선이 가게 한다(요청) — diary.js가
   beginDecorateMode/cleanupDom에서 .diary-grid에 is-decorate-mode를
   붙였다 뗀다. */
.diary-grid.is-decorate-mode .diary-day:not(.is-decorating),
.diary-grid.is-decorate-mode .diary-day-num:not(.is-decorating) {
  opacity: .4;
}

/* 이미 등록된 스티커는 새 꾸미기 결과와 겹침을 확인하는 배경 미리보기로
   그대로 보여주되, 선택·클릭·hover 대상에서는 완전히 제외한다. */
.diary-grid.is-decorate-mode .diary-sticker {
  opacity: 1;
  pointer-events: none;
}

/* 세그먼트(패딩 영역, .diary-decorate-segment)는 실제 날짜 칸 영역
   (.diary-decorate-segment-core)보다 세로 기준 10%만큼 사방으로 더 넓게
   잡아(padding) 레이어를 자유롭게 옮기거나 펜으로 그릴 여유를 주고, 포인터
   캡처(드래그 등)는 이 넓은 padded 영역 전체가 받는다. 등록 시 실제로
   저장되는 스티커 캔버스도 이 padded 영역 크기 그대로다(buildStickers) —
   그래서 눈에 보이는 배경/그림자도 core가 아니라 이 padded 영역 전체에
   준다(요청: 등록 후 스티커가 보일 최대 영역을 입력 중에도 그대로 확인할
   수 있어야 함). 테두리 대신 box-shadow로 편집 범위를 구분하고, 배경은
   인풋 테마를 쓰되 완전 불투명이 아니라서 그 아래 실제 날짜 칸 테두리가
   은은하게 비쳐 보인다. */
.diary-decorate-segment {
  position: absolute;
  z-index: 400;
  box-sizing: border-box;
  /* 이미지 레이어는 이 영역 바깥까지 확대/이동할 수 있어야 하므로(저장 시엔
     세그먼트 캔버스 크기 그대로 자동으로 잘려 보이지 않는다) 편집 중엔
     가려버리지 않고 그대로 보여준다. */
  overflow: visible;
  touch-action: none;
  /* 아래의 기존 스티커가 클릭 불가 미리보기 레이어로 비쳐 보이게 한다. */
  /* 스테이지 자신은 투명하다 — 영역 B 판은 달력 셀보다 아래 층에 깔리는
     .diary-decorate-backdrop 이 맡는다(요청). 스테이지에 칠하면 그 위를 덮어
     범위 안의 다른 날짜 스티커·날짜 숫자·칸 테두리가 가려진다. */
  background: transparent !important;
  box-shadow: 0 3px 10px -2px rgba(0, 0, 0, .28);
  border-radius: 6px;
}

/* 좌표 정규화(normPoint)의 기준이자 레이어가 실제로 배치되는 영역(=날짜
   칸 크기) — 그 자체는 안 보이는 히트/좌표 기준일 뿐이다(배경/그림자는
   위 .diary-decorate-segment가 이미 그린다). */
/* 좌표 기준이자 레이어가 실제로 배치되는 영역(=날짜 칸 크기) — 그 자체는
   안 보인다. 영역 B 표면은 아래 .diary-decorate-backdrop 이 그린다. */
.diary-decorate-segment-core {
  position: absolute;
  overflow: visible;
}

/* 꾸미기 중 그 주 구간에 깔리는 영역 B 판(요청) — 날짜 칸 바깥 여백까지 덮되
   달력 셀보다 "아래" 층이라, 그 위의 날짜 숫자·칸 테두리·다른 날짜 스티커는
   평소 모드와 똑같이 그대로 보인다. 스테이지(z-index:400)와 같은 사각형이며
   위치·clip-path 는 layoutStage 가 함께 맞춰 준다. */
.diary-decorate-backdrop {
  position: absolute;
  z-index: 0;
  box-sizing: border-box;
  pointer-events: none;
  border-radius: 6px;
  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)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
  box-shadow: 0 3px 10px -2px rgba(0, 0, 0, .28);
}

/* 판(z-index:0)보다 위에 그린다 — 둘 다 position 이 잡혀 있는데 판이 DOM 상
   뒤에 붙어, 층을 명시하지 않으면 판이 달력을 덮는다. 스티커는 자기 inline
   z-index(1 이상)를 이미 갖고 있다. */
.diary-day,
.diary-day-num {
  z-index: 1;
}

/* .diary-decorate-segment(패딩 포함 최대 영역) 사각형 자체는 구멍처럼
   비워두고(box-shadow는 자기 테두리 안쪽엔 안 퍼짐) 그 바깥 전체를 거대한
   spread의 box-shadow로 덮는 스포트라이트 기법 — 세그먼트 안(패딩 포함,
   요청대로 "diary-decorate-segment 영역 안")은 그대로, 세그먼트를 완전히
   벗어난 부분(다른 주/다른 게시글)만 이 그림자에 덮여 흐리게 보인다.
   createSegmentStage가 coreEl이 아니라 paddedEl(segment)의 자식으로
   붙인다 — 구멍 크기가 core가 아니라 segment 전체와 일치해야 하므로.
   .diary-scroll의 overflow:auto가 9999px 그림자를 화면에 보이는 만큼으로만
   잘라준다. */
.diary-decorate-dim-mask {
  position: absolute;
  inset: 0;
  z-index: 9000;
  pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(var(--system-c-area-b-base-rgb), .65);
}

/* 등록 건 하나(스티커)가 그 날짜 칸들 위에 정확히 겹쳐 보이는 그리드 아이템 —
   .diary-grid의 형제로 grid-row/grid-column을 명시해 배치한다(같은 좌표를
   여러 스티커가 겹쳐 차지할 수 있다). 스티커의 불투명한(실제로 꾸민) 부분을
   클릭해야 게시글이 열리고(투명한 여백·날짜 칸 클릭은 아무 일도 하지 않는다),
   그 불투명한 부분을 hover하면 제목 툴팁으로 클릭 대상을 알려준다.
   "맨위에 표시" 게시글은 작성일과 무관하게 일반 게시글보다 높은 z-index를
   받는다 — 완전히 겹치는 배치는 자동으로 어긋내지 않는다. */
.diary-sticker {
  position: relative;
  min-width: 0;
  cursor: pointer;
  overflow: visible;
  transition: none;
}

/* Grid 아이템은 날짜 열 크기를 그대로 유지하고, 저장 PNG의 10% 여백은
   이 내부 캔버스만 절대 배치로 넓혀 행 크기나 스크롤 폭에 관여하지 않게 한다. */
.diary-sticker-canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  border-radius: 6px;
  overflow: hidden;
}

.window-edit-cancel {
  padding: 0 7px;
  border: 1px solid;
  border-radius: 6px;
}

/* 주소줄 "⋯ → 이 페이지 내에서 검색"으로 여는 팝업(.window-more-search-panel)
   안의 아이콘/입력창 — 팝업 자체(배경/테두리/그림자)는 .window-more-panel이
   그리므로 여기선 내용물만 다룬다. */
.window-bar-search-icon {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
}

.window-bar-search-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  border: none;
  background: transparent;
  padding: 0;
  font: inherit;
  color: inherit;
}

.window-toolbar .window-bar-search-input:hover,
.window-toolbar .window-bar-search-input:focus {
  background: transparent !important;
  outline: none;
}

.window-bar-search-input::placeholder {
  color: rgba(var(--system-b-area-a-base-font-rgb), .5) !important;
}

/* 검색 진행 표시 — 목록 검색이 서버(?q=)를 거치므로 영화 검색 드롭다운의
   .movie-search-loading과 같은 스피너를 쓴다. 저기는 입력창 위에 absolute로
   얹지만 여기 패널은 flex 한 줄이라 그냥 flex 아이템으로 둔다. */
.window-bar-search-loading {
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  box-sizing: border-box;
  /* 이 스피너는 ⋯ 메뉴의 검색 패널(영역 B) 안에 있다 — 예전엔 System C
     설명색 + Focus 색을 쓰고 있었다. 옅은 링은 영역 B 글자색을 흐리게,
     도는 한 변만 강조 글자색으로. */
  /* !important: 주소줄의 광역 테두리 규칙(.window-toolbar *)이 영역 A 테두리색을
     !important로 밀고 있어, 그냥 두면 옅은 링이 그 색으로 덮인다. */
  border: 2px solid rgba(var(--system-b-area-b-base-font-rgb), .3) !important;
  border-top-color: var(--system-b-area-b-accent-font-color) !important;
  border-radius: 50%;
  animation: window-bar-search-spin .7s linear infinite;
  pointer-events: none;
}

@keyframes window-bar-search-spin {
  to { transform: rotate(360deg); }
}

.window-more-panel-close {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent !important;
  color: inherit !important;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.search-highlight {
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
  border-radius: 2px;
}
.diary-sticker.is-hover-active {
  filter: drop-shadow(0 1px 3px rgba(var(--system-c-area-b-base-font-rgb), .5));
}

.diary-sticker.is-selected {
  outline: 2px solid var(--focus-color);
  outline-offset: -2px;
}

.diary-sticker-bg {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.diary-sticker-gif {
  position: absolute;
  pointer-events: none;
}

/* 스티커 hover 시 게시글 제목을 보여주는 커스텀 툴팁 — 모달의 overflow에
   잘리지 않도록 body 직속 fixed 요소로 띄운다. 위치(left/top)는 diary.js가
   포인터의 화면 좌표로 계산하고, 생김새만 .preview-label을 재사용한다. */
.diary-sticker-tooltip.preview-label {
  position: fixed;
  bottom: auto;
  /* .window-tooltip 과 같은 전역 툴팁 톤 — 생김새(크기/자리)만 preview-label. */
  background: var(--tooltip-color) !important;
  border: 1px solid rgba(var(--tooltip-border-rgb), var(--tooltip-border-alpha)) !important;
  color: var(--tooltip-font-color) !important;
  z-index: 800;
  pointer-events: none;
}

.diary-sticker-tooltip[hidden] {
  display: none;
}

/* 모든 윈도우가 공유하는 포인터 추적 툴팁 — body 직속이라 창 밖에서도 보인다. */
/* 툴팁은 작업표시줄·윈도우바·창 어디에서 떠도 같은 톤이어야 한다(요청) —
   예전엔 System C 영역 B 를 빌려 써서, 작업표시줄 위에 뜬 툴팁이 창 테마를
   따라가 배경과 안 맞았다. 배경은 뒤가 비치면 글자가 안 읽혀 항상 불투명. */
.window-tooltip {
  position: fixed;
  z-index: calc(var(--z-debug) + 1);
  max-width: min(320px, calc(100vw - 16px));
  padding: 5px 7px;
  border-radius: 6px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  pointer-events: none;
  color: var(--tooltip-font-color) !important;
  background: var(--tooltip-color) !important;
  border: 1px solid rgba(var(--tooltip-border-rgb), var(--tooltip-border-alpha)) !important;
  box-shadow: 0 4px 12px -2px rgba(0, 0, 0, .18);
}

.window-tooltip[hidden] {
  display: none;
}

/* 터치 기기에서는 탭이 hover로 해석되며 툴팁이 클릭 대상을
   가리므로, 거친 포인터/호버 없는 환경에서 커스텀 툴팁을 모두 끄다. */
@media (hover: none), (pointer: coarse) {
  .window-tooltip,
  .diary-sticker-tooltip.preview-label {
    display: none !important;
  }
}

/* ==========================================================================
   새로 만들기(+) FAB — 창 우측단에 절대 위치로 떠 있다. 다이어리 전용이 아니라
   postable 메뉴(그림/영화 등, setupPostAdminToolbar가 postFabDockHTML로 삽입)와
   공유하는 클래스다. 다이어리에서는 평소 동그란 (+) 버튼(fab-button) 하나뿐이고,
   날짜를 고르기 시작하거나 캘린더 꾸미기 단계에 들어가면 그 자리에서
   fab-actions(다음/취소)로 바뀐다(diary.js가 hidden 속성만 토글 — 둘 다
   항상 DOM에 있는 정적 엘리먼트). 그림/영화는 fab-actions 없이 fab-button
   버튼 하나만 쓴다.
   ========================================================================== */
.fab-dock {
  position: absolute;
  right: 14px;
  bottom: 14px;
  z-index: 700;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

/* 다이어리는 fab-dock을 .diary-layout(높이 100%, 그 자체가 .window-content
   padding:14px 안쪽에서 시작) 밑에 두므로, 실제로는 14(window-content padding)
   + 14(fab-dock 자신의 inset) = 28px만큼 창 가장자리에서 들어와 보인다.
   그림/영화는 setupPostAdminToolbar가 .window-content에 fab-dock을 바로
   붙이므로(중간에 그런 래퍼가 없음) 14px만 들어가 다이어리보다 가장자리에
   더 붙어 보였다 — 다이어리와 같은 위치로 보이도록 여기서 28px로 맞춘다. */
[data-post-fab-dock] {
  right: 28px;
  bottom: 28px;
}

.fab-dock[hidden] {
  display: none;
}

/* 동그라미는 focus-color, 그 안의 +는 focus-font-color. */
.fab-button {
  width: 46px;
  height: 46px;
  border: 0;
  border-radius: 50%;
  background: var(--focus-color);
  color: var(--focus-font-color);
  display: grid;
  place-items: center;
  cursor: pointer;
  /* 강조(primary) 버튼과 같은 테두리(요청) — border:0 이면 그 값이 칠할 선이 없다. */
  border: 1px solid rgba(var(--system-c-button-primary-border-rgb), var(--system-c-button-primary-border-alpha)) !important;
  box-shadow: 0 4px 10px -2px rgba(0, 0, 0, .2);
}

.fab-button svg {
  color: var(--focus-font-color) !important;
  stroke: var(--focus-font-color) !important;
}

.fab-button[hidden] {
  display: none;
}

/* 날짜 선택 중(is-date-selecting)엔 (+) 자리 그대로 (X)로 바뀌어 "선택 취소"를
   뜻한다 — 생김새는 새로 만들기와 완전히 같게 두고 아이콘만 바뀐다(요청).
   그래서 .is-input-theme 에는 따로 색/크기를 주지 않는다. */

.fab-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
}

.fab-actions[hidden] {
  display: none;
}

.fab-actions button[hidden] {
  display: none;
}

/* 선택 취소 — 캘린더꾸미기 중(beginDecorateMode)에만 diary.js가 grid의
   자식으로 만들어 붙인다. 선택된 날짜의 마지막 세그먼트(.diary-decorate-segment)
   영역 밖, 그 우측하단에 오도록 매번 위치를 계산해서 얹는다(요청). 세그먼트의
   dim-mask(z-index:9000, 세그먼트 자신의 쌓임 맥락 안)보다 위에 그려지도록
   세그먼트(z-index:400)보다 큰 z-index를 준다. */
.diary-decorate-cancel {
  position: absolute;
  z-index: 500;
  /* 강조 버튼과 같은 테마(요청) — 배경·글자는 Focus, 테두리는 중요 버튼 값. */
  background: var(--focus-color);
  color: var(--focus-font-color);
  /* !important — 전역 *{border-color: 영역 B 테두리 !important} 를 되받아야 한다. */
  border: 1px solid rgba(var(--system-c-button-primary-border-rgb), var(--system-c-button-primary-border-alpha)) !important;
  border-radius: 7px;
  padding: 5px 12px;
  font-size: 13px;
  cursor: pointer;
  box-shadow: 0 4px 10px -2px rgba(0, 0, 0, .2);
}

/* ==========================================================================
   캘린더꾸미기 도구(선택/이미지/텍스트/선택삭제) — 다이어리 창
   좌측 하단에 절대 위치로 떠 있는 아이콘 줄. 꾸미는 동안에만 보인다.
   ========================================================================== */
.diary-tool-dock {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 700;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px;
  border-radius: 12px;
  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)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
  box-shadow: 0 6px 16px -3px rgba(0, 0, 0, .2);
}

/* 막대 안의 글자(구분선 라벨 등)도 영역 B 글자색을 따른다. 버튼/셀렉트는
   자기 클래스(normal-button/custom-select)가 이미 테마를 갖고 있어 건드리지 않는다. */
.diary-tool-dock > :is(span, small, label) {
  color: var(--system-c-area-b-base-font-color) !important;
}

.diary-tool-dock[hidden] {
  display: none;
}

.diary-tool-icon {
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--system-c-area-b-base-font-color);
  display: grid;
  place-items: center;
  cursor: pointer;
}

.diary-tool-icon.is-active {
  background: var(--focus-color);
  color: var(--focus-font-color);
}

.diary-tool-icon.danger {
  color: var(--focus-color);
}

.diary-tool-icon:disabled {
  opacity: .35;
  cursor: default;
}

.diary-text-controls {
  display: flex;
  align-items: center;
  gap: 4px;
}

.diary-text-controls[hidden] {
  display: none;
}

.diary-text-bold {
  font-weight: 700;
}

.diary-text-size {
  width: 52px;
  height: 26px;
  border: 1px solid;
  border-radius: 6px;
}

.diary-text-color {
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid;
  border-radius: 6px;
  cursor: pointer;
  background: transparent;
}

/* ==========================================================================
   다이어리 게시글작성 창 — 날짜선택·캘린더꾸미기는 이제 메인 달력 화면에서
   끝내고 오므로(diary.js beginDecorateMode), 이 창은 그림 게시글 에디터와
   똑같은 한 화면 폼(제목 옆 공개범위, 그 옆 등록 버튼 — UI.PostEditor.formHTML)
   이다. 별도 "확인" 단계 없이 바로 등록한다. 방금 꾸민 내용의 미리보기는
   이 창 안이 아니라 메인 달력 위에 그대로 남아 있다(beginDecorateMode의
   freezeForPreview) — 이 창이 닫힐 때(저장이든 취소든) 정리된다.
   ========================================================================== */

/* 레이어 하나는 위치/크기/회전을 갖는 래퍼(.diary-layer, transform:rotate가
   여기 걸린다)와 그 안을 꽉 채우는 실제 내용(.diary-layer-content)으로
   나뉜다 — 선택 시 핸들(.diary-layer-handle-*)도 이 래퍼의 자식이라 래퍼의
   회전을 그대로 물려받아 항상 레이어의 실제 모서리/윗변에 붙어 보인다. */
.diary-layer {
  position: absolute;
  box-sizing: border-box;
  margin: 0;
  border: 0;
  padding: 0;
  cursor: pointer;
}

.diary-layer-content {
  display: block;
  width: 100%;
  height: 100%;
}

.diary-layer-image .diary-layer-content {
  object-fit: cover;
  border-radius: 3px;
}

.diary-layer-text .diary-layer-content {
  overflow: hidden;
  line-height: 1.25;
  white-space: pre-wrap;
  word-break: break-word;
}

/* 텍스트 도구로 끄는 동안 보여주는 점선 사각형 — 여기까지가 박스가 된다(요청). */
.diary-textbox-preview {
  position: absolute;
  border: 1px dashed var(--focus-color);
  background: rgba(var(--focus-rgb), .08);
  pointer-events: none;
}
/* 편집 중인 텍스트 박스는 그림판처럼 점선 테두리로 경계를 보여준다(요청) —
   크기 조절 핸들은 레이어 공용(.diary-layer-handle-resize)이 그대로 담당한다. */
.diary-layer-text-input {
  outline: 1px dashed var(--focus-color) !important;
  outline-offset: 2px;
  box-sizing: border-box;
  padding: 0;
  border: 0 !important;
  resize: none;
  /* 입력칸 자체는 완전히 투명하다(요청) — 아래 스티커가 그대로 비쳐야 글이
     어디에 얹히는지 보인다. 광역 입력 테마는 마크업의 data-no-theme 으로 뺐고,
     여기서는 배경/그림자를 확실히 지운다. */
  background: transparent !important;
  box-shadow: none !important;
  font-family: inherit;
  user-select: text;
  cursor: text;
}

.diary-layer-pen .diary-layer-content {
  background: transparent;
}

.diary-layer.is-selected {
  outline: 2px dashed var(--focus-color);
  outline-offset: 1px;
}

/* 크기조절(오른쪽 아래 모서리, 종횡비 유지하며 중심 기준 확대/축소)과
   회전(윗변 중앙, 레이어 중심 기준 각도) 핸들 — 선택된 레이어에만 렌더링된다. */
.diary-layer-handle {
  position: absolute;
  width: 10px;
  height: 10px;
  background: var(--focus-color);
  /* Focus 배경 위에 얹는 테두리라 --focus-font-color("Focus 배경 위 글자색")를
     쓴다 — 예전엔 #fff 고정이라 Focus 색을 밝게 바꾸면 손잡이가 사라졌다. */
  border: 1px solid var(--focus-font-color);
  z-index: 10;
  pointer-events: auto;
}

.diary-layer-handle-resize {
  right: -5px;
  bottom: -5px;
  border-radius: 2px;
  cursor: nwse-resize;
}

/* 가로만 / 세로만 줄이고 늘리는 제어점(요청) — 모서리 손잡이는 종횡비를
   유지하므로 한 축만 바꿀 방법이 없었다. 변 가운데에 둔다. */
.diary-layer-handle-resize-x {
  right: -5px;
  top: 50%;
  margin-top: -5px;
  border-radius: 2px;
  cursor: ew-resize;
}

.diary-layer-handle-resize-y {
  bottom: -5px;
  left: 50%;
  margin-left: -5px;
  border-radius: 2px;
  cursor: ns-resize;
}

.diary-layer-handle-rotate {
  top: -20px;
  left: 50%;
  margin-left: -5px;
  border-radius: 50%;
  cursor: grab;
}

/* 다이어리 도구 막대의 글자색 스와치 — 테마 편집기(.theme-color-input)와 같은
   UI 를 쓰되(요청) 막대 높이에 맞춰 조금 크게 잡는다. 글자색은 투명도가 없어
   체커보드가 비칠 일이 없다. */
.diary-text-color.theme-color-input {
  width: 26px !important;
  height: 26px;
}

.light-border {
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
}
/* guestbook */

/* 크기는 JS(openSingletonTemplateWindow의 width/height)가 정한다 — 여기서
   또 못 박으면 그 값이 무시된다(1000x700로 바꿔도 500x430으로 그려지던 원인).
   max-width만 풀어 준다. */
.guestbook-window {
  max-width: none;
}

.guestbook-window .comment-compose {
  max-width: 720px;
}
.preview-card {
  position: fixed;
  width: 238px;
  max-height: 360px;
  display: none;
  padding: 7px;
  border-radius: 10px;
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: 0 8px 20px -4px rgba(0,0,0,.14);
  overflow: auto;
}

.preview-card.show {
  display: block;
}
.preview-item {
  position: relative;
  height: 112px;
  border-radius: 7px;
  overflow: hidden;
  margin-bottom: 6px;
  cursor: pointer;
}

.preview-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.preview-thumb {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: top left;
  pointer-events: none;
}

.preview-close {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  line-height: 1;
  font-family: Arial, sans-serif;
}

.preview-close::before {
  content: "×";
  display: block;
  line-height: 1;
  transform: translateY(-.25px);
}

.preview-label {
  position: absolute;
  left: 7px;
  bottom: 5px;
  max-width: 180px;
  padding: 3px 6px;
  border-radius: 4px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  color: var(--system-c-area-b-base-font-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.close-all {
  position: sticky;
  top: 0;
  z-index: 2;
  display: block;
  width: auto;
  height: 28px;
  margin: 0 0 6px auto;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}

.popover {
  position: fixed;
  display: none;
}

.popover.open {
  display: block;
}

/* 유리 팝업 공통 면 — 시작메뉴/볼륨 팝오버(.popover)와 시계 플라이아웃 카드가 공유.
   .calendar-popover(컨테이너)는 아래에서 border/shadow/backdrop 을 전부 끈다. */
/* 검색 제안 판(.search-suggest)도 시작메뉴와 같은 유리 면·그림자를 쓴다(요청). */
.popover,
.search-suggest,
.clock-flyout-calendar,
.clock-flyout-notifications {
  border: 1px solid;
  border-radius: 11px;
  box-shadow: 0 9px 22px -4px rgba(0, 0, 0, .13);
}
.popover,
.search-suggest,
.clock-flyout-calendar,
.clock-flyout-notifications {
  backdrop-filter: blur(22px) saturate(1.16);
  -webkit-backdrop-filter: blur(22px) saturate(1.16);
}

.shortcut-popover {
  left: 8px;
}

.shortcut-grid {
  display: grid;
  padding-top: 15px;
  justify-items: center;
}

.shortcut {
  border: 0;
  border-radius: 7px;
  text-align: center;
  cursor: pointer;
  width: 70px;
}

.shortcut strong {
  display: block;
}

/* 앱 바로가기 라벨은 바탕화면 바로가기(.desktop-shortcut span)와 같은 400 굵기. */
.shortcut strong {
  font-weight: 400;
}

.shortcut span {
  display: none;
}

.calendar-popover {
  right: 8px;
  border: 0 !important;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.calendar-popover.open {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 8px;
  height: calc(100vh - var(--taskbar-h) - 18px);
  height: calc(100dvh - var(--taskbar-h) - 18px);
}

/* 알림 카드가 없는 비로그인 상태에는 플라이아웃을 화면 높이만큼 늘리지 않는다.
   그러면 fixed bottom 기준으로 달력 카드 자체가 항상 작업표시줄 위에 붙는다. */
.calendar-popover.open:has(.clock-flyout-notifications[hidden]) {
  height: auto;
}

.clock-flyout-calendar,
.clock-flyout-notifications {
  width: 324px;
  padding: 12px;
}

.clock-flyout-calendar {
  flex: 0 0 auto;
}

.calendar-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.calendar-head button {
  width: 24px;
  height: 24px;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
  font-weight: bold;
}

.calendar-title {
  font-weight: 700;
}

.mini-week,.mini-grid {
  display: grid;
  grid-template-columns: repeat(7,1fr);
}

.mini-week span {
  text-align: center;
}

.mini-day {
  position: relative;
  justify-self: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}

.mini-day.today {
  font-weight: 700;
}

.mini-day.has:after {
  content: "";
  position: absolute;
  top: 4px;
  right: 4px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
}

/* 점 표시 클릭 시 그 날 올라온 게시글 목록 — 미니 그리드 아래 덧붙는다. */
/* 날짜별 글 목록은 달력 패널(영역 A) 위에 얹히는 영역 B 블록이다 —
   배경·테두리·글자를 B 기본 테마로 칠해 달력 본체와 구분한다. */
.mini-day-list {
  margin-top: 8px;
  padding: 8px;
  border-radius: 7px;
  background-color: rgba(var(--system-a-area-b-base-rgb), var(--system-a-area-b-base-alpha)) !important;
  border: 1px solid rgba(var(--system-a-area-b-base-border-rgb), var(--system-a-area-b-base-border-alpha)) !important;
  color: var(--system-a-area-b-base-font-color) !important;
}
.mini-day-list :is(strong, small, span, p, a, button) {
  color: var(--system-a-area-b-base-font-color) !important;
}
.mini-day-list svg,
.mini-day-list svg * {
  stroke: var(--system-a-area-b-base-font-color) !important;
}
.mini-day-list[hidden] { display: none !important; }
.mini-day-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
  margin-bottom: 6px;
}
.mini-day-list-head button {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}
.mini-day-list-items {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 180px;
  overflow-y: auto;
}
.mini-day-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
  text-align: left;
}
/* 목록 안 항목도 영역 B — 기본은 투명(패널이 이미 B 표면), 강조만 B 강조. */
.mini-day-item {
  border-width: 1px !important;
  border-style: solid !important;
  border-color: transparent !important;
  background-color: transparent !important;
}
.mini-day-item:hover,
.mini-day-item:focus-visible {
  background-color: color-mix(in srgb, var(--system-a-area-b-accent-color) calc(var(--system-a-area-b-accent-alpha) * 100%), rgba(var(--system-a-area-b-base-rgb), var(--system-a-area-b-base-alpha))) !important;
  border-color: rgba(var(--system-a-area-b-accent-border-rgb), var(--system-a-area-b-accent-border-alpha)) !important;
  color: var(--system-a-area-b-accent-font-color) !important;
}
.mini-day-item:hover :is(span, strong, small),
.mini-day-item:focus-visible :is(span, strong, small) {
  color: var(--system-a-area-b-accent-font-color) !important;
}
.mini-day-item:hover svg,
.mini-day-item:hover svg *,
.mini-day-item:focus-visible svg,
.mini-day-item:focus-visible svg * {
  stroke: var(--system-a-area-b-accent-font-color) !important;
}
.mini-day-item svg {
  width: 15px;
  height: 15px;
  flex: none;
}
.mini-day-item span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 시계 플라이아웃: 달력 위의 남은 화면 높이를 채우는 독립 알림 카드.
   표면/폰트/테두리는 .taskbar-scope 규칙으로 이미 System A를 따르고,
   각 항목만 System A 폰트색에서 파생한 콘텐츠 톤으로 한 단계 뗀다. */
.clock-flyout-notifications {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
}

.clock-flyout-notifications[hidden] {
  display: none;
}

.clock-flyout-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-weight: 700;
  margin-bottom: 8px;
}
.notification-settings-toggle {
  width: 24px;
  height: 24px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}
.notification-settings-toggle svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.notification-settings-toggle[hidden] { display: none !important; }

/* 톱니바퀴 왼쪽 "모두 지우기" — 제목 다음, 오른쪽 정렬 그룹의 첫 항목. */
.notification-clear-all {
  margin-left: auto;
  padding: 3px 7px;
  border: 0;
  border-radius: 7px;
  font-weight: 400;
  cursor: pointer;
}
.notification-clear-all[hidden] { display: none !important; }

.notification-list {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
  /* 창 본문과 같은 오버레이 스크롤바(homepage.js의 bindWindowOverlayScrollbar)를
     쓰므로 네이티브 스크롤바는 숨긴다. */
  scrollbar-width: none;
}
.notification-list::-webkit-scrollbar { display: none; }
.notification-list[hidden] { display: none !important; }

.notification-settings {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
  font-weight: 400;
}
.notification-settings[hidden] { display: none !important; }
.notification-settings-back {
  align-self: flex-start;
  height: 24px;
  padding: 0 6px 0 2px;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}
.notification-settings-group {
  margin: 0;
  padding: 10px;
  border: 1px solid rgba(var(--system-a-area-a-base-font-rgb), .16);
  border-radius: 7px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
/* fieldset 은 display:flex 라 [hidden] 이 안 먹는다 — 소유자에게 새 글 알림 칸을 감출 때 쓴다. */
.notification-settings-group[hidden] { display: none !important; }
.notification-settings-group legend {
  padding: 0 4px;
  font-weight: 700;
  opacity: .8;
}
.notification-settings label {
  display: flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
}
.notification-settings-filtered {
  margin-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.notification-settings-filtered[hidden] { display: none !important; }
.notification-settings-menus {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.notification-empty {
  text-align: center;
  padding: 20px 8px;
  opacity: .7;
}
.notification-item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 9px 10px;
  border-radius: 7px;
  cursor: pointer;
}

.notification-item.has-thumb {
  grid-template-columns: auto 1fr auto;
}

.notification-item-thumb {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  flex: none;
}

/* 빌트인 아이콘 썸네일 — 사진처럼 cover 로 깔면 글리프가 잘려 뭉개진다.
   .post-thumb-empty 와 같은 마스크 방식으로 찍어 크기를 맞추고 글자색을 따른다. */
.notification-item-thumb.is-glyph {
  background: currentColor;
  -webkit-mask: var(--notif-glyph) center / 20px 20px no-repeat;
  mask: var(--notif-glyph) center / 20px 20px no-repeat;
}

/* 안읽음도 다른 항목과 같은 영역 B 기본 테두리를 쓴다(요청) — 예전엔 강조
   테두리로 한 줄만 다르게 그렸다. 안읽음은 굵은 제목 + 불투명도로 구분된다
   (아래 :not(.is-unread) 참고). 테두리는 .sys-a-btn-b 가 그대로 그린다. */

/* 읽은 알림은 블럭 전체를 반투명하게. hover 시 복원. */
.notification-item:not(.is-unread) {
  opacity: .55;
}
.notification-item:not(.is-unread):hover {
  opacity: 1;
}

.notification-item-title {
  font-weight: 700;
}

/* 안읽은 알림 제목도 System A 입력 폰트색을 따른다(.sys-a-btn-b * 규칙과 특이도를
   맞춰 덮는다) — 굵기와 왼쪽 테두리(.is-unread)만으로 안읽음을 표시. */
.notification-item.is-unread .notification-item-title {
  color: var(--system-a-area-b-base-font-color) !important;
}

.notification-item-body {
  margin-top: 3px;
  font-size: .9em;
  opacity: .75;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.notification-item-body.is-title { -webkit-line-clamp: 1; }
.notification-item-time { display: block; margin-top: 3px; font-size: .78em; opacity: .6; }
.notification-item-actions { display: flex; gap: 6px; margin-top: 6px; }
/* ✕ 는 각 알림의 오른쪽 위(요청) — 목록 격자가 align-items:center 라 세로
   가운데에 걸려 있었다. 본문이 두 줄 이상(초대의 [수락][거절] 줄 등)일 때 특히 떠 보인다. */
.notification-item-delete {
  width: 22px;
  height: 22px;
  border-radius: 7px;
  line-height: 1;
  flex: none;
  align-self: start;
}

.clock {
  position: relative;
}

.sound-popover {
  right: 75px;
}

.timeline {
  margin-top: 8px;
  height: 4px;
  border-radius: 99px;
  overflow: hidden;
}

/* 재생 진행 막대도 Focus가 아니라 그 영역(볼륨 팝오버 = 영역 A)의 글자색. */
.timeline span {
  display: block;
  width: 42%;
  height: 100%;
  background: var(--system-a-area-a-base-font-color) !important;
}

/*@media(max-width:760px){.input-text-box{width:145px}*/
  .window{min-width:230px}

  .guestbook-window{max-width:calc(100vw - 18px)}
/* ==========================================================================
   Start menu gallery button
   ========================================================================== */

/* Windows 시작메뉴 하단 바(계정/전원)처럼 줄 전체가 System A 입력 톤 배경 한
   장이고, 그 위에 아이콘 버튼들이 투명하게 얹힌다(버튼 하나하나를 박스로
   감싸지 않음) — .shortcut-popover의 padding:14px를 좌우/아래로 상쇄해
   패널 가장자리까지 배경이 번지게 하고, 둥근 아래 모서리는 popover 자체의
   overflow 클리핑에 맡긴다(따로 border-radius 안 줘도 됨). */
.shortcut-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 9px;
  margin: 10px -14px -14px;
  padding: 8px 20px;
  background: rgba(var(--system-a-area-b-base-rgb), var(--system-a-area-b-base-alpha));
}
/* 안의 두 버튼(.shortcut-space-info/.gallery-power-button)은 .sys-a-btn-a라
   기본은 System A "일반" 폰트색(6535행 부근)을 쓰는데, 이 footer는 배경 자체가
   System A "입력" 톤이라 폰트도 입력 폰트색을 따라야 배경과 어울린다.
   버튼 자체에만 색을 주면 안 된다 — .taskbar-scope *(전역 System A 폰트색 규칙)가
   strong/small/span/svg 같은 자손을 "직접" 잡고 있어, 상속보다 그 직접 매치가
   항상 이긴다(상속은 캐스케이드에서 가장 낮은 우선순위). 그래서 자손까지
   똑같이 짚어줘야 한다. hover 시 강조색으로 바뀌는 동작은 그대로 둬야 하므로,
   hover 규칙과 같은 특이도(클래스 2개+타입/:is 1개)로 맞추고 그보다 앞(소스 순서)에
   둬서 hover가 계속 이기게 한다. */
.shortcut-footer .sys-a-btn-a,
.shortcut-footer .sys-a-btn-a :is(strong, small, span) {
  color: var(--system-a-area-b-base-font-color) !important;
}
.shortcut-footer .sys-a-btn-a svg,
.shortcut-footer .sys-a-btn-a svg * {
  color: var(--system-a-area-b-base-font-color) !important;
}

.gallery-power-button {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  padding: 0;
  /* 이 버튼은 다른 규칙이 display:flex 로 만든다 — place-items 의 justify-items 는 flex 에서
     안 먹어 아이콘이 왼쪽에 붙어 있었다(요청: hover 영역과 아이콘이 안 맞음). */
  justify-content: center;
  align-items: center;
}

/* 시작메뉴 스페이스 위젯(전원버튼 왼쪽) — 로그인 여부와 무관하게 지금 스페이스
   소유자 아바타+타이틀+닉네임@아이디를 보여주고, 스페이스가 2개 이상이면
   활성화돼 openSpaceSwitcherPopover로 전환 목록을 연다. border-radius는
   sys-a-btn-a hover 시 밝아지는 배경의 모서리용(버튼 자체는 평소 투명).
   좌우 padding은 없음 — 가장자리 여백은 .shortcut-footer의 좌우 padding이
   맡아서 아바타/전원 아이콘 둘 다 같은 기준으로 정렬된다. */
.shortcut-space-info {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  text-align: left;
  border-radius: 7px;
}
.shortcut-space-info[hidden] {
  display: none;
}
.shortcut-space-info:disabled {
  cursor: default;
  opacity: .85;
}
.shortcut-space-avatar {
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background-position: center;
  background-size: cover;
  background-color: rgba(var(--system-a-area-a-base-rgb), .2);
  display: grid;
  place-items: center;
}
.shortcut-space-avatar svg {
  width: 16px;
  height: 16px;
}
.shortcut-space-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}
.shortcut-space-text strong,
.shortcut-space-text small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.shortcut-space-text small {
  opacity: .75;
  font-size: .82em;
}

/* 스페이스 전환 목록(위 위젯 클릭 시) — .folder-popover와 같은 팝오버 베이스,
   그리드 대신 세로 리스트만 다르다. */
/* 스페이스 전환 목록은 트리거(.shortcut-space-info, 영역 A) 자리에 겹쳐
   열리는 커스텀 select 형태다 — 목록 자체는 영역 B를 따른다. 마크업상
   .shortcut-popover(영역 A 패널 배경)를 같이 쓰고 있어 여기서 B로 덮는다. */
.space-switcher-popover {
  width: min(300px, calc(100vw - 16px));
  padding: 10px;
}
.space-switcher-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 320px;
  overflow-y: auto;
}
.space-switcher-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  border-radius: 7px;
  text-align: left;
}
.space-switcher-row.is-current {
  cursor: default;
}
.space-switcher-avatar {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-position: center;
  background-size: cover;
  background-color: rgba(var(--system-a-area-a-base-rgb), .2);
  display: grid;
  place-items: center;
}
.space-switcher-avatar svg {
  width: 18px;
  height: 18px;
}
.space-switcher-text {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}
.space-switcher-text strong,
.space-switcher-text small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.space-switcher-text small {
  opacity: .75;
  font-size: .82em;
}
.space-switcher-current-badge {
  flex: 0 0 auto;
  font-size: .78em;
  opacity: .75;
}

/* ==========================================================================
   Layering / aligned taskbar popups
   ========================================================================== */

.preview-card {
  bottom: calc(var(--taskbar-h) + 5px) !important;
}

.search-suggest {
  bottom: calc(var(--taskbar-h) + 5px) !important;
}

.shortcut-popover,
.calendar-popover,
.sound-popover {
  bottom: calc(var(--taskbar-h) + 5px);
}

.shortcut-popover {
  max-height: min(520px, calc(100vh - var(--taskbar-h) - 18px));
  /* 세로만 넘칠 때 스크롤하면 되고, 가로는 그리드 폭 계산이 서브픽셀로
     빠듯해도(4열*70px 고정폭 아이콘 + gap) 절대 가로 스크롤바가 보이면
     안 되므로 x축은 아예 막는다. */
  overflow-x: hidden;
  overflow-y: auto;
}

.shortcut-grid-flat {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
/* 앱별 HTML 템플릿 로딩 상태 */

/* 어디서나 같은 로딩 표시(요청) — "불러오는 중..." 글자를 대신한다.
   원 자체는 .user-loading-spinner(user.css) 를 그대로 쓰고, 여기서는 자리만 잡는다. */
.loading-block {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  min-height: 90px;
  padding: 10px 0;
  box-sizing: border-box;
  /* 부모가 여러 열짜리 그리드(그림/캐릭터 목록 등)면 로딩원이 첫 칸에만 들어가
     왼쪽으로 치우친다 — 줄 전체를 가로질러야 가로도 가운데가 된다.
     그리드가 아닌 부모에서는 이 두 줄이 아무 영향도 주지 않는다. */
  grid-column: 1 / -1;
  grid-row: 1 / -1;
}

/* 로딩원만 들어 있는 상자는 부모 높이를 다 쓰게 만든다 — 목록/패널 컨테이너는
   대부분 "내용만큼" 높이가 정해져서, 원 한 개만 남으면 90px 로 쪼그라들어
   스크롤 본문 위쪽에 붙어 있었다(요청: 불러오는 영역 한가운데). 이렇게 상자를
   늘려 두면 위 .loading-block 의 height:100% 가 그 안을 채우고 원이 정가운데로
   온다. 조부모 높이가 정해지지 않은 경우엔 100% 가 auto 로 풀려 예전(90px)
   그대로라 손해가 없다. 글자 자리에 들어가는 is-inline 은 제외. */
:has(> .loading-block:only-child:not(.is-inline)) {
  min-height: 100%;
}

/* 글자 한 줄 자리에 들어가는 작은 원 — 제목/메시지 칸처럼 높이를 늘리면
   레이아웃이 흔들리는 곳에서 쓴다. */
.loading-block.is-inline {
  display: inline-grid;
  min-height: 0;
  padding: 0;
  vertical-align: middle;
}

.loading-block.is-inline .user-loading-spinner {
  width: 14px;
  height: 14px;
  border-width: 2px;
}

.modal-template-loading,
.modal-template-error {
  height: 100%;
  min-height: 120px;
  display: grid;
  place-items: center;
}

/* ==========================================================================
   Settings application
   ========================================================================== */

.settings-app {
  height: 100%;
  min-height: 0;
  /* 고정 앱 셸이라 스크롤은 .settings-panel-body 한 곳뿐이다 — 셸이 바깥 창까지 굴리면 스크롤바가 둘로 보였다(요청). */
  overflow: hidden;
}

.settings-view {
  display: none;
  height: 100%;
  min-height: 0;
}

.settings-view.is-active {
  display: flex;
  flex-direction: column;
}

/* 고정 앱 셸: 왼쪽 내비게이션은 항상 표시되고, 오른쪽 콘텐츠만 선택한 메뉴에 따라
   바뀐다(화면 전환 시 창 크기 변경 없음). 좁은 창에서는 내비게이션이 overlay
   drawer로 바뀌므로(아래 is-nav-small 관련 규칙), 그 드로어가 콘텐츠 위에 겹쳐
   그려지도록 position:relative로 기준 컨테이닝 블록을 만들어 둔다. */
.settings-shell {
  position: relative;
  display: flex;
  height: 100%;
  min-height: 0;
  gap: 14px;
}

/* 메뉴는 공유 기록·캐릭터 창의 사이드바와 같은 영역 B 판(.panel-card)에 담는다(요청) — 폭은 240px 로, 컨텐츠가 좁아져
   테마 패널이 한 열로 접히지 않을 만큼만 준다. */
.side-nav {
  flex: 0 0 240px;
  width: 240px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-content: start;
  gap: 3px;
  overflow-y: auto;
}
/* 항목은 판 폭을 꽉 쓰고, 글자 시작선만 다른 칸의 머리줄과 맞춘다(.shared-side 와 같은 셈). */
.side-nav.panel-card { padding-left: 0; padding-right: 0; }

/* 메뉴 항목의 모양(테두리 없음, 활성은 왼쪽 Focus 줄 하나, hover 강조)은 공유 기록·캐릭터 창의
   사이드바 메뉴와 같다 — 템플릿에서 .shared-nav-item 을 함께 달아 그 규칙(shared.css)을 그대로 쓴다(요청: 일관성). */
.side-nav-btn {
  flex: 0 0 auto;
  min-height: 35px;
  display: flex;
  align-items: center;
  text-align: left;
  cursor: pointer;
}

/* 넓은 창: ☰로 내비게이션 자체를 접어 콘텐츠에 공간을 더 준다. */
.settings-shell.is-nav-collapsed .side-nav {
  display: none;
}

/* 좁은 창: 내비게이션은 기본적으로 숨겨져 있다가, ☰를 누르면 콘텐츠를 밀지 않고
   그 위에 겹쳐지는 overlay drawer로 나타난다. */
.side-nav-backdrop {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 4;
  margin: 0;
  border: 0;
  padding: 0;
  background: rgba(0,0,0,.32);
  cursor: pointer;
}
.settings-shell.is-nav-small .side-nav {
  position: absolute;
  inset: -12px auto -12px -12px;
  width: 240px;
  max-width: 80%;
  padding: 10px 8px;
  z-index: 5;
  border-radius: 0 10px 10px 0;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  transform: translateX(-100%);
  transition: transform .18s ease;
}
/* 그림자는 펼쳤을 때만 — 접힌 서랍은 화면 밖인데 그림자만 본문 위로 새어 나온다(공유 창과 같은 값). */
.settings-shell.is-nav-small.is-nav-drawer-open .side-nav { box-shadow: 4px 0 18px rgba(0, 0, 0, .25); }
.settings-shell.is-nav-small.is-nav-drawer-open .side-nav {
  transform: translateX(0);
}
.settings-shell.is-nav-small.is-nav-drawer-open .side-nav-backdrop {
  display: block;
}

.settings-content {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-left: 4px;
  /* 좁은 창 규칙(@container settings)의 기준 상자 — 아래 "환경설정은 창 안의 앱이라" 참고. */
  container-type: inline-size;
  container-name: settings;
}

/* 모든 화면이 공유하는 고정 헤더(제목/설명 + ☰ 버튼 + 오른쪽 수정·적용 버튼)와,
   그 아래 화면 전환 영역. 헤더는 항상 고정이고 스크롤은 화면별 .settings-panel-body
   에서만 일어난다(아래 참고) — 화면에 저장 버튼이 없으면 .settings-header-actions
   안에 그 화면 키를 가진 그룹이 없으므로 자연히 아무 버튼도 보이지 않는다
   (updateHeader가 매 화면 전환마다 .is-active를 다시 정함). 메뉴 관리 하위 화면
   으로 돌아가는 동작은 별도 뒤로가기 버튼 대신, 제목 줄 앞의 "메뉴 관리 /"
   breadcrumb(.panel-header-breadcrumb) 클릭으로 대신한다. */
.settings-panel-header {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
  padding-bottom: 8px;
}

.settings-header-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* 제목 줄: 메뉴 관리 하위 화면에서는 얇은 글씨의 "메뉴 관리 /" breadcrumb 버튼과
   현재 하위 화면 제목(굵은 글씨, 기존 <strong>)이 한 줄에 나란히 보인다. 그 외
   화면은 breadcrumb이 hidden이라 상위 화면 제목만 보인다. */
.panel-header-title-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
  min-width: 0;
}

.panel-header-breadcrumb {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  font-weight: 400;
  color: var(--system-c-area-b-base-desc-font-color);
}

/* 마우스 hover는 시각 효과 없이 기본 색상·장식을 그대로 유지하고(요청: 호버 효과
   제거), 키보드 포커스(:focus-visible)에서만 클릭 가능함을 알리는 색상+밑줄을
   보여준다. 클릭으로 상위 메뉴 허브에 돌아가는 동작 자체는 변경하지 않는다. */
.panel-header-breadcrumb:focus-visible {
  color: var(--focus-color);
  text-decoration: underline;
}

.panel-header-title-row strong {
  min-width: 0;
}

.settings-header-text strong {
  display: block;
}

.settings-header-text span {
  display: block;
  margin-top: 3px;
}

.settings-header-actions {
  flex: 0 0 auto;
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 1px;
}

.settings-header-action-group {
  display: none;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.settings-header-action-group.is-active {
  display: flex;
}

.settings-views {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.settings-content .settings-view {
  flex: 1;
}

/* 화면별 본문: 이 안(.settings-panel-body)만 스크롤된다 — 적용·수정 버튼과
   메시지는 더 이상 화면마다 만들지 않고 공통 헤더(.settings-header-actions)에
   고정으로 존재한다. */
.settings-panel-body {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

/* 사용 메뉴 관리는 목록 테두리 안쪽에서 스크롤한다(요청) — 바깥이 같이
   스크롤되면 감싼 테두리가 위로 밀려 올라가고 머리줄 sticky 도 의미가 없다. */
[data-menu-sub-view="menus"] .settings-panel-body {
  overflow: hidden;
}

/* 모니터 열은 auto — 실제 폭은 .settings-pc-preview 의 aspect-ratio 가 "높이"로부터 역산한다. 그 높이는 이 grid row 의
   기본 정렬(align-items:stretch)로 .settings-info-list 의 실제 높이에 맞춰지므로, 정보 목록 줄 수가 바뀌어도 모니터가
   따라간다. 정보 목록 열은 minmax(0,1fr) 이라 남는 폭을 다 차지한다. 좁은 창은 @container settings 가 한 열로 쌓는다. */
.settings-home-grid {
  display: grid;
  align-content: start;
  grid-template-columns: auto minmax(0,1fr);
  gap: 10px;
}

.settings-pc-preview {
  position: relative;
  border-radius: 9px;
  overflow: hidden;
  box-shadow: 0 6px 20px rgba(0,0,0,.07);
}

.settings-pc-screen {
  position: relative;
  border-radius: 5px;
  overflow: hidden;
}

.settings-card-label {
  display: block;
  margin-top: 7px;
  font-weight: 700;
}

/* 환경설정 홈의 관리자 전용 서버 현황 대시보드(settings.js syncServerStats/
   loadServerStats). 라이브러리 없이 순수 CSS로 그리는 막대 차트(트래픽)와
   채움 바(디스크 사용량) — 각 막대/채움의 실제 크기는 JS가 인라인 style로 준다. */
.settings-server-stats,
.settings-portfolio-settings {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(120,120,120,.18);
}
.settings-portfolio-settings .settings-info-list {
  margin-top: 8px;
}

.server-stats-content {
  margin-top: 8px;
}

.server-stats-row {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,1fr) minmax(0,1fr);
  gap: 12px;
  align-items: start;
}

.server-stats-traffic,
.server-stats-disk,
.server-stats-visitors {
  min-width: 0;
  border: 1px solid rgba(120,120,120,.18);
  border-radius: 9px;
  padding: 8px;
  height: 100%;
}

.server-stats-chart {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 60px;
  margin-top: 6px;
}

.server-stats-bar {
  flex: 1;
  min-width: 2px;
  height: 2px;
  background: var(--focus-color);
  border-radius: 2px 2px 0 0;
  opacity: .8;
}

.server-stats-chart-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 3px;
  color: var(--system-c-area-b-base-desc-font-color);
}

.server-stats-disk-bar {
  margin-top: 8px;
  height: 8px;
  border-radius: 4px;
  background: rgba(120,120,120,.18);
  overflow: hidden;
  display: flex;
}

.server-stats-disk-fill {
  height: 100%;
  width: 0;
  flex: 0 0 auto;
  background: var(--focus-color);
}

/* 서비스(프로젝트+업로드+DB)/그 외 두 구간으로 나눠 그릴 때의 색 — 서비스는
   기존 단색 막대와 같은 focus-color, 그 외는 중립 회색으로 구분한다. */
.server-stats-disk-fill.is-other {
  background: rgba(120,120,120,.55);
}

.server-stats-disk-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-top: 5px;
  color: var(--system-c-area-b-base-desc-font-color);
}

.server-stats-disk-legend-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.server-stats-disk-legend-swatch {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex: 0 0 auto;
  background: var(--focus-color);
}

.server-stats-disk-legend-swatch.is-other {
  background: rgba(120,120,120,.55);
}

/* "디스크 사용량" 라벨 줄에 청소 아이콘을 오른쪽 끝에 띄운다 — 다른
   settings-info-label(폼 라벨 등)은 그냥 텍스트라 flex로 바뀌어도 시각적
   차이가 없지만, 혹시 몰라 이 카드 안으로만 스코프한다. */
.server-stats-disk .settings-info-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.server-stats-disk-cleanup-btn {
  padding: 2px;
  color: var(--system-c-area-b-base-desc-font-color);
  cursor: pointer;
}

.server-stats-disk-cleanup-btn svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.server-stats-disk-cleanup-btn:hover {
  color: var(--focus-color);
}

/* 디스크 사용량 관리 화면(홈 / 디스크 사용량 관리) */
.disk-cleanup-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin-bottom: 10px;
}

.disk-cleanup-select-all {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}

.disk-cleanup-summary {
  color: var(--system-c-area-b-base-desc-font-color);
  flex: 1;
  min-width: 0;
}

.disk-cleanup-message {
  margin: 0 0 10px;
  min-height: 14px;
  color: var(--system-c-area-b-base-desc-font-color);
}

.disk-cleanup-message.is-error {
  color: var(--focus-color);
}

.disk-cleanup-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px;
}

.disk-cleanup-item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  border-radius: 8px;
  cursor: pointer;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
}

.disk-cleanup-item:has(.disk-cleanup-checkbox:checked) {
  outline: 2px solid var(--focus-color);
  outline-offset: -2px;
}

/* 실제 <input>(.disk-cleanup-checkbox)는 :has(.disk-cleanup-checkbox:checked)
   선택 표시(위)를 위해 그대로 두고 시각적으로만 숨긴다(.settings-checkbox-input) —
   실제 체크 표시는 옆의 .disk-cleanup-checkbox-box(.settings-checkbox-box)가 그린다. */
.disk-cleanup-checkbox-box {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 1;
}

.disk-cleanup-thumb {
  width: 100%;
  aspect-ratio: 1/1;
  object-fit: cover;
  border-radius: 6px;
}

.disk-cleanup-thumb-generic {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--system-c-area-b-base-desc-font-color);
  background: rgba(120,120,120,.18);
  font-size: 11px;
}

.disk-cleanup-item-info {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.disk-cleanup-item-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.disk-cleanup-item-meta {
  color: var(--system-c-area-b-base-desc-font-color);
}

.server-stats-disk-meta {
  margin-top: 5px;
  color: var(--system-c-area-b-base-desc-font-color);
}

.server-stats-visitor-count {
  margin-top: 6px;
  font-weight: 700;
  color: var(--system-c-area-b-base-font-color);
}

.server-stats-visitor-count small {
  margin-left: 3px;
  font-weight: 400;
  color: var(--system-c-area-b-base-desc-font-color);
}

.server-stats-updated {
  margin-top: 8px;
  color: var(--system-c-area-b-base-desc-font-color);
  text-align: right;
}

.settings-info-list {
  display: grid;
  align-content: start;
  gap: 5px;
}

/* 정보 줄·허브 카드는 창 바탕 위의 영역 B 판이다 — 색을 박지 않고 테마 토큰을 따른다(다른 판·카드와 같은 면).
   테두리 색은 전역 `*{border-color: 영역 B 테두리 !important}` 가 칠한다. */
.settings-info-row {
  width: 100%;
  min-height: 35px;
  display: grid;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border: 1px solid;
  border-radius: 9px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  text-align: left;
}

.settings-info-row:not(button) {
  grid-template-columns: 105px minmax(0,1fr);
}
button.settings-info-row {
  cursor: pointer;
}

/* 포트폴리오 그림 출처 — 메뉴 × 공개범위를 여러 줄로 지정한다(요청). */
.settings-portfolio-sources {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.settings-portfolio-source {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* enhanceSelect 가 select 를 .custom-select-wrap 으로 감싸므로 둘 다 잡는다. */
.settings-portfolio-source > select,
.settings-portfolio-source > .custom-select-wrap {
  flex: 0 1 150px;
  min-width: 110px;
}

.settings-portfolio-vis-list {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.settings-portfolio-vis {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  cursor: pointer;
}

.settings-portfolio-add {
  align-self: flex-start;
  padding: 3px 8px;
}

.settings-info-value,
.settings-music-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-music-thumb {
  width: 48px;
  height: 27px;
  flex: 0 0 auto;
  border-radius: 4px;
  background: center/cover no-repeat;
}

.settings-panel-head {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
}

.settings-panel-head strong {
  display: block;
  font-weight: 700;
}

.settings-panel-head span {
  display: block;
  margin-top: 3px;
}

.settings-empty {
  grid-column: 1/-1;
  padding: 22px 10px;
  text-align: center;
}

.desktop-area-sort-list {
  display: grid;
  gap: 5px;
}

.desktop-area-sort-item {
  display: grid;
  grid-template-columns: 20px 1fr auto;
  align-items: center;
  gap: 7px;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid rgba(0,0,0,.13);
  border-radius: 7px;
  background: rgba(255,255,255,.48);
  cursor: grab;
  touch-action: none;
  transition: border-color .15s,background .15s,opacity .15s,transform .15s;
}
.desktop-area-direction-toggle {
  justify-self: end;
}

.desktop-area-sort-item:active { cursor: grabbing; }
.desktop-area-sort-item.is-drag-source { display: none; }
/* 길게 눌러 잡은 줄 — 끌 준비가 됐다(끌기)거나 메뉴가 열릴 참(떼기)이라는 표시(요청). */
.is-reorder-ready, .is-menu-ready {
  transform: scale(.99);
  transition: transform .12s ease;
}
.is-reordering {
  opacity: .75;
}
.desktop-area-sort-placeholder {
  height: 3px;
  margin: 1px 4px;
  border-radius: 999px;
  background: var(--focus-color);
  box-shadow: 0 0 0 1px rgba(var(--focus-rgb),.18), 0 0 7px rgba(var(--focus-rgb),.55);
  transition: none !important;
}
.desktop-area-sort-placeholder.is-horizontal {
  align-self: stretch;
  height: auto;
  width: 4px;
  min-height: 30px;
  margin: 0 3px;
}
/* 끌고 다니는 복제본은 document.body 로 옮겨 그려진다 — 그러면 원래 자리의
   컨테이너 질의(container-type) 밖이라 cqi 로 잡은 크기(캐릭터 칩 아바타 10cqi)가
   뷰포트 기준으로 커졌다(요청: 캐릭터 드래그 시 아바타가 커짐). 복제본 자신을
   컨테이너로 삼아 원래와 같은 폭 기준으로 계산되게 한다. */
.desktop-area-sort-ghost {
  container-type: inline-size;
  position: fixed;
  z-index: calc(var(--z-debug) + 1);
  margin: 0;
  pointer-events: none;
  cursor: grabbing;
  opacity: .94;
  transform: rotate(.5deg) scale(1.015);
  transition: none !important;
}
.desktop-area-sort-handle,
.desktop-shortcut-handle { color: #888; touch-action: none; user-select: none; }
.desktop-area-sort-item strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desktop-area-sort-item small { color: #888; }

/* ==========================================================================
   메뉴 관리: 첫 화면(4개 버튼) + breadcrumb + 하위 화면 4종
   ========================================================================== */
.menu-hub, .menu-sub-view {
  display: none;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.menu-hub.is-active, .menu-sub-view.is-active {
  display: flex;
}

.menu-hub-list {
  display: grid;
  gap: 8px;
  margin-top: 4px;
}
.menu-hub-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 10px 12px;
  border: 1px solid;
  border-radius: 9px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  text-align: left;
  cursor: pointer;
}
.menu-hub-card span { color: var(--system-c-area-b-base-desc-font-color); }

.menu-order-name {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.menu-order-icon {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 5px;
  background: #f0f0f0;
  overflow: hidden;
}
.menu-order-icon img,
.menu-admin-icon img { width: 100%; height: 100%; object-fit: cover; }

.menu-desktop-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
  min-height: 0;
  overflow: auto;
}

/* 바탕화면 바로가기 관리: 영역(top/left/right/bottom, 우선순위 손잡이+배치 방향
   토글 보유)과 "미표시"(둘 다 없음) 총 5개의 접이식 그룹을 하나의 목록으로
   렌더링한다. 펼침 = 이름이 보이는 세로 목록, 접힘 = 아이콘만 보이는 가로 목록이며,
   두 상태 모두 항목을 드래그해 순서 변경/영역 이동이 가능하다(그룹 헤더 클릭으로
   토글). 영역 행 자체도 손잡이(.desktop-area-sort-handle)를 드래그해 우선순위를
   바꿀 수 있다 — 소속 메뉴 항목의 손잡이(.desktop-shortcut-handle)와는 다른
   요소이므로 두 드래그가 서로 간섭하지 않는다. */
.desktop-shortcut-group {
  border: 1px solid rgba(0,0,0,.13);
  border-radius: 9px;
  background: rgba(255,255,255,.3);
  overflow: hidden;
  flex: 0 0 auto;
}
.desktop-shortcut-group.is-selected {
  outline: 2px solid var(--focus-color);
  outline-offset: -2px;
}
.desktop-shortcut-group.is-drag-source { display: none; }
.desktop-shortcut-group-head-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
}
.desktop-shortcut-group-head-row .desktop-area-sort-handle {
  cursor: grab;
}
.desktop-shortcut-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex: 1;
  min-width: 0;
  cursor: pointer;
}
.desktop-shortcut-group-title {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}
.desktop-shortcut-group-title small { color: #888; font-weight: 400; }
.desktop-shortcut-group-caret { color: #888; }

.desktop-shortcut-group-body {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 0 8px 8px;
}
.desktop-shortcut-group-body.is-collapsed {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: stretch;
}
.desktop-shortcut-group-body.is-drag-target {
  outline: 2px dashed var(--focus-color);
  outline-offset: -2px;
  border-radius: 6px;
}
.desktop-shortcut-group-body:empty {
  min-height: 34px;
}
.desktop-shortcut-group-body:empty::before {
  content: '항목을 여기로 드래그하세요';
  display: flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  color: #999;
}

.desktop-shortcut-item {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid rgba(0,0,0,.13);
  border-radius: 7px;
  background: rgba(255,255,255,.48);
  cursor: grab;
  touch-action: none;
  transition: border-color .15s,background .15s,opacity .15s,transform .15s;
}
.desktop-shortcut-item:active { cursor: grabbing; }
.desktop-shortcut-item.is-drag-source { display: none; }
.desktop-shortcut-group-body.is-collapsed .desktop-shortcut-item {
  padding: 5px;
}
.desktop-shortcut-group-body.is-collapsed .desktop-shortcut-name,
.desktop-shortcut-group-body.is-collapsed .desktop-shortcut-handle {
  display: none;
}
.desktop-shortcut-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.desktop-region.is-area-priority-selected {
  border-radius: 8px;
  background: rgba(var(--desktop-shortcut-hover-rgb), var(--desktop-shortcut-hover-alpha)) !important;
  color: var(--desktop-shortcut-hover-font-color) !important;
  border: 1px solid rgba(var(--desktop-shortcut-hover-border-rgb), var(--desktop-shortcut-hover-border-alpha)) !important;
  box-shadow: none !important;
}

/* 관리 목록은 판 위에 놓인 한 덩어리 — 영역 B 표면 + 테두리로 감싼다(요청).
   머리줄이 sticky 라 안쪽을 잘라내지 않게 overflow 는 auto 그대로 두고
   모서리만 둥글린다. */
/* 스페이스·사용자·사용자그룹 목록은 모두 윈도우 영역 B 판 위에 놓인다(요청). */
.menu-admin-list,.user-admin-list,.user-group-list,.settings-log-list {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  border: 1px solid;
  border-radius: 10px;
}

/* 관리 목록(메뉴/사용자/그룹) — 판 안쪽이라 영역 B 테마를 따른다(요청).
   예전엔 #f6f6f6/#ddd/#eee 하드코딩이라 테마를 바꿔도 이 목록만 회색으로 남았다. */
.menu-admin-header,.menu-admin-row {
  display: grid;
  /* 아이콘 | 이름 | 설명 | 공개범위 | 댓글 | 사용 토글(맨 오른쪽, 요청) — 줄마다 격자가 따로라
     칸 폭을 고정해 머리줄과 맞춘다. */
  grid-template-columns: 36px minmax(80px,.8fr) minmax(110px,1.4fr) 100px 108px 74px;
  gap: 8px;
  align-items: center;
}
.user-admin-row { cursor: pointer; }
/* 머리줄의 칸 이름은 눌러서 정렬하는 버튼이다(요청). */
.user-admin-sort { padding: 0; text-align: left; font: inherit; cursor: pointer; }
/* 스페이스 관리 줄(요청) — 슬러그·소유자·멤버·도메인·디스크·버튼 여섯 칸.
   고칠 수 있는 칸(슬러그·도메인·디스크)은 줄에서 바로 입력으로 바뀐다. */
.space-admin-row {
  /* 마지막 칸은 60px 고정 — auto 로 두면 버튼이 둘인 줄(루트가 아닌 스페이스)만 넓어져
     그 줄의 다른 칸이 전부 왼쪽으로 밀린다(줄마다 격자가 따로라 머리줄과도 어긋난다). */
  grid-template-columns: minmax(90px,.9fr) minmax(90px,1fr) 48px minmax(120px,1.3fr) 80px 60px;
}
/* 멤버 수는 배지 하나라 칸 가운데가 아니라 머리줄 글자와 같은 왼쪽에 선다. */
.space-admin-row > .settings-pill { justify-self: start; }
/* 마지막 칸 — 공유 메뉴는 ✎와 🗑 둘이 나란히. */
.menu-admin-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  align-items: center;
}

/* 머리줄 — 값이 아니라 열 이름이라 설명 폰트색 + 약간 작게. 구분선 색은 지정하지
   않는다: 전역 `*{border-color: 영역 B 테두리 !important}` 가 칠하므로 아래 줄
   구분선(.menu-admin-row …)과 저절로 같은 색이 된다. */
.menu-admin-header,
.user-admin-header,
.user-group-header {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 8px 7px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  border-bottom: 1px solid;
  color: var(--system-c-area-b-base-desc-font-color);
  font-size: 11px;
}

.menu-admin-row,
.user-admin-row,
.user-group-row {
  min-height: 48px;
  padding: 8px 7px;
  border-bottom: 1px solid;
}
.menu-admin-row:last-child,
.user-admin-row:last-child,
.user-group-row:last-child {
  border-bottom: 0;
}

.menu-admin-row:hover,
.user-admin-row:hover,
.user-group-row:hover {
  background: 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)));
}

/* 아이콘 타일·값 칩의 배경은 아래 "영역 B 표면" 규칙이 !important 로 못박는다 —
   판도 같은 표면이라 배경만으론 구분이 안 된다. 테두리 한 줄로 형태를 준다. */
.menu-admin-icon {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid;
  border-radius: 8px;
  color: var(--system-c-area-b-base-font-color);
  overflow: hidden;
}

.menu-admin-title {
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
}
.menu-admin-title > span {
  font-weight: 400;
}

.menu-admin-desc {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--system-c-area-b-base-desc-font-color);
}

.menu-admin-check {
  text-align: center;
}

/* 환경설정의 폼 팝업 — 공용 .confirm-dialog 위에 입력 줄이 들어가는 만큼만 넓힌다
   (확인 대화상자는 문구 한 줄이라 기본 폭이 좁다). */
.confirm-dialog.settings-dialog {
  width: min(420px, 100%);
  text-align: left;
}
.confirm-dialog.settings-dialog .settings-edit-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* 인라인 편집(줄에서 바로 고치기) — 칸 구성은 그대로 두고 표시값만 입력으로
   바꾼다. 입력은 칸을 꽉 채워 열 너비가 안 변한다(머리줄과 계속 맞는다). */
.menu-admin-cell {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
.menu-admin-input {
  width: 100%;
  min-width: 0;
  height: 28px;
  padding: 0 6px;
  border: 1px solid;
  border-radius: 6px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  color: var(--system-c-area-b-base-font-color);
}
.menu-admin-input:focus {
  outline: none;
  border-color: var(--focus-color) !important;
}
.menu-admin-cell .small-btn {
  flex: none;
  height: 28px;
  padding: 0 6px;
}
/* 편집 중인 줄은 배경으로 구분 — 어느 줄을 고치는 중인지 한눈에. */
.menu-admin-row[data-editing] {
  background: 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)));
}
/* 아이콘 칸은 버튼이다(눌러서 아이콘 변경 팝업). 이름은 누르면 그 자리 입력이 된다 —
   글자 커서로 "고칠 수 있는 글"임을 알린다(요청). 줄은 끌어서 순서를 바꾼다. */
button.menu-admin-icon {
  cursor: pointer;
  padding: 0;
}
button.menu-admin-icon:disabled {
  cursor: default;
}
.menu-admin-name.is-editable {
  cursor: text;
}
/* 공개범위·댓글 칩 — 넓은 창에선 각자 제 칸(display:contents), 누르면 설정 창(요청). */
.menu-admin-pills { display: contents; }
button.menu-admin-pill { cursor: pointer; background: transparent; font: inherit; }
button.menu-admin-pill:hover:not(:disabled) { border-color: var(--focus-color); color: var(--focus-color); }
button.menu-admin-pill:disabled { cursor: default; }
.menu-admin-row[data-drag-id] {
  cursor: pointer; /* 잡는 손 대신 클릭 포인터(요청) */
}
button.menu-admin-icon.is-changed {
  border-color: var(--focus-color) !important;
}

.menu-admin-edit {
  width: 27px;
  height: 27px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
}

.menu-admin-edit:hover {
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
}

/* 값 칩(공개범위·댓글·상태). */
.settings-pill {
  display: inline-block;
  max-width: 100%;
  padding: 3px 8px;
  border: 1px solid;
  border-radius: 999px;
  color: var(--system-c-area-b-base-font-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}

/* 아바타·이름·아이디·좋아요·댓글·가입일 여섯 칸(요청). */
.user-admin-header,.user-admin-row {
  display: grid;
  grid-template-columns: 34px minmax(90px,1.2fr) minmax(80px,1fr) 64px 64px 92px;
  gap: 7px;
  align-items: center;
}

.user-admin-row {
  min-height: 52px;
}

/* 사용자 그룹 목록 — menu-admin-row와 같은 스타일이지만 열 구성이 달라(이름/
   설명/인원/수정/삭제 5열) 별도 그리드로 둔다. */
.user-group-list {
  flex: 1;
  min-height: 0;
  border: 1px solid rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha)) !important;
  border-radius: 10px;
  overflow: auto;
}

/* 이름·설명·인원 세 칸(요청) — 수정·삭제는 줄 우클릭으로 옮겼다. */
.user-group-header,.user-group-row {
  display: grid;
  grid-template-columns: minmax(90px,1fr) minmax(120px,2fr) 70px;
  gap: 6px;
  align-items: center;
}
.user-group-row { cursor: context-menu; }

/* 머리줄·줄·hover 는 위 관리 목록 공통 규칙이 맡는다. */
/* 아바타가 없는 자리(UI.avatarHTML) — 어디서 쓰든 같은 모양이다(요청): 영역 B 색 원 +
   가운데 옅은 실루엣. 예전엔 .avatar-circle 을 쓴 자리만 원으로 보이고, 설정의 사용자 표·
   스페이스 소유자 검색처럼 제 클래스를 쓰는 자리는 아이콘만 덩그러니 떠 있었다. */
.avatar-circle-empty {
  display: grid;
  place-items: center;
  border-radius: 50%;
  overflow: hidden;
  /* 테두리가 있어야 바탕과 같은 색 테마에서도 아바타 자리가 보인다. 색은 전역
     *{border-color:...!important} 가 영역 B 구분선으로 칠해 준다. */
  border: 1px solid;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  /* 전역 body *{color:...!important} 를 되받아야 실루엣이 옅은 설명색으로 그려진다. */
  color: var(--system-c-area-b-base-desc-font-color) !important;
}
.avatar-circle-empty svg {
  width: 60%;
  height: 60%;
  /* 전역 svg 규칙이 stroke 를 글자색(검정)으로 칠해 실루엣이 진하게 나왔다 —
     여기서는 옅은 설명색으로 못 박는다. */
  fill: none !important;
  stroke: var(--system-c-area-b-base-desc-font-color) !important;
  stroke-width: 1.6;
  stroke-linecap: round;
}
.user-admin-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: 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))) center/cover no-repeat;
}

.settings-log-item {
  display: grid;
  grid-template-columns: 125px 90px 110px 1fr;
  gap: 8px;
  padding: 8px;
  border-bottom: 1px solid #eee;
}

.settings-log-item p {
  margin: 0;
}

.settings-log-ip {
  font-family: monospace;
  font-size: 11px;
  opacity: .72;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 서버 로그 — 표준 log 패키지가 그대로 찍은 텍스트 줄이라 구조화된 표 대신
   콘솔처럼 보여준다(어두운 배경은 테마와 무관하게 항상 고정 — 터미널 출력과
   같은 느낌을 유지하려는 의도적 선택). */
.settings-server-log {
  flex: 1;
  min-height: 0;
  margin: 0;
  padding: 10px 12px;
  overflow: auto;
  border-radius: 8px;
  background: #1a1a1a;
  color: #d8d8d8;
  font-family: monospace;
  font-size: 11px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-all;
}

/* 창 안에 뜨는 다른 팝업(.confirm-dialog-overlay.is-window-scoped)과 같은 막이다(요청) —
   같은 어둡기, 그리고 뒤 내용은 backdrop-filter 대신 직접 흐린다(글자까지 흐려지게). */
.settings-editor-layer {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  padding: 16px;
  background: rgba(0, 0, 0, .35);
}
.settings-app:has(> .settings-editor-layer.is-open) > .settings-shell { filter: blur(5px); }

.settings-editor-layer.is-open {
  display: grid;
}

.settings-editor-dialog {
  width: min(420px,100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(255,255,255,.75);
  border-radius: 11px;
  background: rgba(255,255,255,.95);
  box-shadow: 0 10px 28px -6px rgba(0,0,0,.14);
  overflow: hidden;
}

.settings-editor-head {
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px 0 13px;
  border-bottom: 1px solid #eee;
}

.settings-editor-head button {
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
}

.settings-editor-head button:hover {
  background: #eee;
}

.settings-editor-body {
  overflow: auto;
  padding: 12px;
}

.settings-edit-form {
  display: grid;
  gap: 10px;
}

.settings-form-field {
  display: grid;
  gap: 5px;
}

.settings-form-field>span {
  font-weight: 700
}

.settings-form-field input[type=text],.settings-form-field input[type=url],.settings-form-field select {
  width: 100%;
  height: 33px;
  padding: 0 9px;
  border: 1px solid;
  border-radius: 7px;
  outline: 0;
}

/* .post-editor(gallery/movie/character 등 각 편집기 마크업의 최상위 래퍼)가
   .window-content 높이를 그대로 채워야, 그 안의 .post-editor-form/-body가 쓰는
   flex:1;min-height:0 체인이 실제로 의미를 갖는다(퍼센트/flex 크기는 조상에게
   정해진 높이가 있어야 계산된다) — 이게 없으면 편집기가 내용이 없을 때
   쪼그라들고(아래 채움), 내용이 길어지면 .window-content 전체가 스크롤된다
   (아래 -content만 스크롤). detail 보기(openPostWindow, fitPostWindowHeight로
   내용에 맞춰 창 자체 높이를 재는 화면)는 이 클래스를 안 쓰므로 영향 없다.
   height:100%는 조상 높이가 아직 auto(fitPostWindowHeight가 재는 중)일 땐 그냥
   auto로 계산되므로(스펙상 퍼센트 높이는 조상이 확정 높이일 때만 적용) 그
   측정 로직과도 충돌하지 않는다. */
.post-editor {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.post-editor-form {
  border-radius: 10px;
  box-sizing: border-box;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 10px;
  /* 에디터 영역 자체를 영역 B 판 하나로 감싼다(요청) — 안쪽 부품(제목/작성란)은
     자기 상자를 그리지 않고 이 판 위에 그냥 놓인다(.profile-detail-main 과 같은 규칙). */
  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)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
}

.post-editor-head {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-bottom: 10px;
  margin-bottom: 10px;
}

/* 제목 input을 감싸는 래퍼 — .post-editor-head가 수평 flex 행이라, 필수값 안내
   (.field-required-message)가 input의 형제로 들어가면 같은 줄에 나란히 끼어버린다.
   이 래퍼가 대신 flex item이 되어(원래 input이 갖던 flex/min-width를 그대로 옮김)
   `data-message-host`로 표시해두면 homepage.ui.js의 showRequiredFieldMessage가
   메시지를 형제로 놓는 대신 이 래퍼 "내부"(input 다음)에 넣어 진짜로 input 아래에
   쌓이게 한다. position:relative + 아래 [data-message-host] > .field-required-message의
   absolute는 그 메시지가 래퍼의 문서 흐름 높이에 관여하지 않게 해, 메시지가
   뜨고 지고 해도 .post-editor-head의 align-items:center 정렬(공개범위 select/
   등록 버튼)이 흔들리지 않게 한다. */
.post-editor-title-wrap {
  flex: 1;
  min-width: 120px;
  position: relative;
}

.post-editor-title-input {
  width: 100%;
  height: 33px;
  padding: 0 9px;
  border: 0;
  border-radius: 7px;
  outline: 0;
}

/* 브라우저 기본 필수값 말풍선 대신 쓰는 공용 인라인 안내(homepage.ui.js
   validateRequiredFields/showRequiredFieldMessage) — 어떤 필드 아래에 붙든
   같은 모습이면 충분해 폼별로 따로 만들지 않는다. */
.field-required-message {
  margin: 4px 0 0;
  line-height: 1.3;
  color: var(--focus-color);
}

/* data-message-host 안(post-editor-title-wrap 등)에 붙는 경우만 절대배치로
   흐름에서 뺀다 — 위 주석 참고. 로그인/가입처럼 세로로 쌓인 폼(형제로 붙는
   경우)은 이 규칙 대상이 아니라 계속 문서 흐름에 남아 다음 필드를 밀어낸다. */
[data-message-host] > .field-required-message {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 2px;
}

/* 헤더 한 줄(제목·공개범위·등록)의 높이를 33px 로 맞춘다(요청) — select 는
   버튼 라벨이 position:absolute 라 자기 내용으로 높이를 못 얻고, 등록 버튼은
   .small-btn 기본 높이를 써서 셋이 제각각이었다.
   영화 에디터(.movie-editor-head)는 같은 클래스를 쓰지만 "한 줄"이 아니라
   포스터 + 오른쪽 4행짜리 grid 라 제외한다 — 33px 로 누르면 정보 블록이 한 줄
   높이로 찌그러지고, flex-end 정렬 때문에 넘친 내용이 위로 삐져나간다. */
.post-editor-head:not(.movie-editor-head) > *,
.post-editor-head:not(.movie-editor-head) > button,
.post-editor-head:not(.movie-editor-head) button[type="submit"] {
  height: 33px;
}
.post-editor-visibility-select {
  flex: 0 0 auto;
  height: 33px;
  padding: 0 8px;
  /* 제목/작성란과 같은 영역 B 판이니 테두리도 같이 그린다(요청) — border:0 이면
     아래 영역 B 규칙의 border-color 가 칠할 선 자체가 없었다. */
  border: 1px solid;
  border-radius: 7px;
  outline: 0;
  /* .custom-select-wrap 설명대로 wrap 자신은 내용(버튼이 position:absolute라
     흐름 밖)에서 폭을 못 얻는다 — 가장 긴 라벨 "특정사용자 공개"(아이콘 포함
     실측 101px + 이 padding 16px)가 안 잘리게 여기서 직접 잡아준다(요청). */
  min-width: 120px;
}
/* 커스텀 select 드롭다운(homepage.ui.js enhanceSelect/enhanceVisibilitySelect) —
   실제 <select>는 화면에서만 숨기고(값/이벤트/폼 직렬화용으로 유지), 버튼+목록을
   그 위에 얹는다. wrap은 원래 select의 class를 그대로 이어받으므로(예:
   .post-editor-visibility-select, .diary-date-select, .settings-inline-select)
   그 select가 원래 쓰던 크기/배경/테두리 규칙을 별도 작업 없이 그대로 따른다 —
   여기서는 구조(위치/겹침)만 정의한다. 열고 닫는 목록은 다른 에디터 팝업과 같은
   .post-editor-popover 틀을 그대로 쓴다. */
.custom-select-wrap {
  position: relative;
  display: flex;
  align-items: center;
  cursor: pointer;
  /* 노말 버튼과 같은 판(요청) — 접힌 select 가 그냥 글자처럼 보이지 않게
     버튼 기본 테마를 그대로 쓴다. 개별 select 클래스(예:
     .post-editor-visibility-select)가 !important 로 자기 값을 주면 그쪽이 이긴다. */
  min-height: 26px;
  padding: 0 8px;
  border-radius: 7px;
  /* !important 가 필요하다: 테두리색은 전역 *{border-color: 영역 B ...!important}
     가, 배경은 개별 select 클래스(.post-editor-visibility-select 등)가 각각
     !important 로 덮고 있었다 — 그래서 버튼 테마를 줘도 안 먹었다. */
  background: var(--system-c-button-base-color) !important;
  border: 1px solid rgba(var(--system-c-button-base-border-rgb), var(--system-c-button-base-border-alpha)) !important;
  color: var(--system-c-button-base-font-color) !important;
}
/* 펼친 동안(:focus-within)도 노말 버튼의 강조와 같은 값 — 열고 닫을 때 톤이
   갈리지 않게 한 곳에서 정한다(요청). */
/* :focus-within 을 쓰면 목록에서 고른 뒤에도(버튼에 포커스가 남아) 강조가
   풀리지 않았다(요청) — hover 와 "펼쳐진 동안"(aria-expanded)만 강조한다. */
.custom-select-wrap:hover,
.custom-select-wrap:has(> .custom-select-button[aria-expanded="true"]) {
  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;
  background-image: none !important;
  color: var(--system-c-button-accent-font-color) !important;
  border-color: rgba(var(--system-c-button-accent-border-rgb), var(--system-c-button-accent-border-alpha)) !important;
}
/* 투명 변형 — 배경/테두리 없이 글자와 화살표만(요청, 다이어리 연·월 선택).
   .transparent-button 과 같은 규칙이고, 강조는 글자색으로만 알린다. */
.custom-select-wrap.transparent-select {
  background: transparent !important;
  border-color: transparent !important;
  color: var(--system-c-area-b-base-font-color) !important;
}
.custom-select-wrap.transparent-select:hover,
.custom-select-wrap.transparent-select:has(> .custom-select-button[aria-expanded="true"]) {
  background: transparent !important;
  border-color: transparent !important;
  color: var(--system-c-area-b-accent-font-color) !important;
  box-shadow: none !important;
}

/* 접혀 있어도 select 라는 걸 알 수 있게 아래 방향 화살표를 둔다(요청).
   버튼은 inset:0 + overflow:hidden 이라 그 안에 넣으면 라벨과 함께 잘리므로
   wrap 의 가상요소로 얹고, 버튼 오른쪽에 그만큼 자리를 비워 둔다. */
.custom-select-wrap::after {
  content: '';
  position: absolute;
  right: 9px;
  top: 50%;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-70%) rotate(45deg);
  opacity: .6;
  pointer-events: none;
}
/* 펼친 동안은 위를 향하게 — 지금 열려 있다는 표시. */
.custom-select-wrap:has(> .custom-select-button[aria-expanded="true"])::after {
  transform: translateY(-20%) rotate(225deg);
}
/* 밑줄 select(요청) — 밑줄 입력칸(.auth-input)과 같은 줄: 배경/테두리 없이 아래선만,
   포커스(펼침)면 Focus 색 2px. 목록은 겹치지 않고 칸 아래에 뜬다(enhanceSelect). */
.custom-select-wrap.underline-select {
  min-height: 28px;
  padding: 0;
  border-radius: 0;
  background: transparent !important;
  border: 0 !important;
  border-bottom: 1px solid rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
}
.custom-select-wrap.underline-select:hover,
.custom-select-wrap.underline-select:has(> .custom-select-button[aria-expanded="true"]) {
  background: transparent !important;
  border-bottom: 2px solid var(--focus-color) !important;
}
.custom-select-wrap.underline-select > .custom-select-button {
  padding: 0 20px 0 0;
  font-size: 14px;
}
.custom-select-wrap.underline-select::after { right: 4px; }
/* 목록 판은 밑줄 select 에서도 버튼형과 같은 "일반 버튼" 테마를 쓴다(요청) —
   판/글자/강조 색은 위 .custom-select-list 규칙 그대로이고, 여기서는 줄 높이만
   닫힌 칸(28px)에 맞춘다. */
.custom-select-list.underline-select .custom-select-option {
  min-height: 28px;
  padding: 0 10px;
}
/* 라벨은 늘 떠 있는 자리에 고정 — select 는 값이 비는 일이 없다. */
.auth-field-select .auth-label { top: 0; font-size: 11px; }
.auth-field-select:focus-within .auth-label { color: var(--focus-color); }

.custom-select-wrap select {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
}
.custom-select-button {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  /* appearance:none 없이는 background:transparent/border:0을 줘도 크롬이 버튼
     네이티브 칠(옅은 회색 테두리 + 자체 border-radius)을 계속 그려서, wrap의
     둥근 테두리(.input-text-box, 25px)가 그 아래 깔린 작은 반경의 네이티브
     버튼 박스에 잘려 보였다(요청: "border는 span에 있는데 button에 라운딩이
     있어서 span의 border가 잘려보임"). appearance:none으로 네이티브 칠을 끈다. */
  appearance: none;
  -webkit-appearance: none;
  border-radius: 0;
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* 왼쪽은 브라우저 기본 버튼 패딩(6px)을 그대로 적되 값을 명시한다 — 펼친 목록의
     항목이 같은 값을 써야 글자가 제자리에서 이어진다(요청). 오른쪽은 화살표 자리. */
  padding: 0 14px 0 6px;
}
.custom-select-button:disabled {
  cursor: default;
  opacity: .6;
}
/* position/left/top/min-width는 homepage.ui.js의 enhanceSelect(openList)가
   버튼 위치를 기준으로 인라인으로 직접 계산해 찍는다(document.body에 붙는
   .post-editor-popover가 이미 position:fixed라 여기서 top:100% 같은 상대값을
   주면 "창 바로 아래"가 아니라 "뷰포트 100%"로 해석돼 화면 하단에 붙어버린다). */
/* 펼친 목록은 닫힌 select 자리에 그대로 겹쳐 이어진다 — 그래서 판/항목의 값을
   닫힌 wrap 과 같게 맞춘다(요청: 항목이 하나뿐이면 접힌 모습과 똑같이 보이게).
   .post-editor-popover(판)·-item(항목)의 값이 뒤에 정의돼 있어 클래스 하나로는
   못 이긴다 — 두 클래스를 겹쳐 특이도로 덮는다. */
.post-editor-popover.custom-select-list {
  max-height: 260px;
  overflow-y: auto;
  white-space: nowrap;
  padding: 0;
  border-radius: 7px;
  background: var(--system-c-button-base-color) !important;
  border: 1px solid rgba(var(--system-c-button-base-border-rgb), var(--system-c-button-base-border-alpha)) !important;
  color: var(--system-c-button-base-font-color) !important;
}
/* 펼친 동안의 화살표 — 닫힌 wrap 은 목록에 가려 안 보이므로 같은 자리(첫 줄
   오른쪽)에 위를 향한 같은 모양을 그린다. */
.post-editor-popover.custom-select-list::after {
  content: '';
  position: absolute;
  top: 10px;
  right: 9px;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(225deg);
  opacity: .6;
  pointer-events: none;
}
.post-editor-popover-item.custom-select-option {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  box-sizing: border-box;
  /* 닫힌 wrap(26px, 테두리 포함)에서 목록 자신의 테두리 2px 를 뺀 높이 —
     항목이 하나면 펼친 상자가 닫힌 상자와 정확히 같은 크기가 된다. */
  min-height: 24px;
  /* 닫힌 버튼(.custom-select-button)과 같은 안쪽 여백 — 글자가 제자리에서 이어진다. */
  padding: 0 14px 0 6px;
  border-radius: 0;
  color: var(--system-c-button-base-font-color) !important;
}
/* 지금 값인 줄은 펼친 wrap 과 같은 강조(버튼 accent)를 쓴다 — 영역 B accent 를
   쓰면 접힌 모습과 색 계열이 갈려 "다른 판"처럼 보였다. */
.post-editor-popover-item.custom-select-option:hover,
.post-editor-popover-item.custom-select-option.is-active {
  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;
}

.post-editor-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.post-editor-toolbar {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.post-editor-format-btn {
  height: 24px;
  padding: 0 8px;
  border: 1px solid;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
}

.post-editor-format-btn.is-bold { font-weight: 700; }
.post-editor-format-btn.is-italic { font-style: italic; }
.post-editor-format-btn.is-strike { text-decoration: line-through; }
.post-editor-format-btn.is-code { font-family: monospace; }

/* 민감한 이미지 — 블러 처리 + 안내문/표시 버튼 오버레이. 이미지 자체는
   filter:blur만 걸고(레이아웃 그대로 유지), 오버레이는 부모에 절대배치
   형제로 끼워 넣는다(homepage.ui.js applySensitiveOverlay 참고). */
/* 가려야 할 사진 — 블러는 이미지 자신에 걸고, 번져 나간 가장자리는 clip-path
   로 잘라 사각형을 그대로 유지한다(요청: 형태 유지, 내부만 블러).
   렌더 순서가 filter → clip 이라 "흐리게 만든 결과"를 원래 상자에 맞춰 자른다.
   크기·위치를 바꾸지 않아 앞뒤 텍스트에 겹치지 않고, 배경을 샘플링하는
   backdrop-filter 와 달리 스크롤해도 풀리지 않는다.
   background-color 는 가장자리에서 투명과 섞이며 비쳐 보이는 것을 메운다. */
.sensitive-image-blurred {
  filter: blur(20px) saturate(1.1);
  clip-path: inset(0);
  background-color: rgba(120, 120, 120, .35);
}
/* 크게 보기(라이트박스) 안의 민감 이미지 게이트 — 목록 쪽 오버레이는 JS가
   이미지 상자에 맞춰 좌표를 직접 넣지만, 여기선 라이트박스 한가운데 한 장뿐이라
   화면 전체를 덮으면 된다. 닫기/좌우 버튼(z-index 위)은 계속 눌려야 한다. */
.sensitive-image-overlay.post-image-lightbox-sensitive {
  inset: 0;
  width: auto;
  height: auto;
  /* 닫기/좌우 버튼(z-index:2)보다 아래 — 안 그러면 게이트가 버튼을 덮어
     크게 보기를 닫을 수 없다. */
  z-index: 1;
}
.post-image-lightbox-sensitive[hidden] {
  display: none;
}

.sensitive-image-overlay {
  position: absolute;
  /* 상자는 applySensitiveOverlay 가 이미지에 맞춰 직접 넣는다(부모 전체를 덮으면
     슬라이드 여러 장짜리 뷰어에서 범위를 넘친다) — 여기선 기준만 잡는다. */
  left: 0;
  top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px;
  text-align: center;
  background: rgba(0, 0, 0, .45);
  border-radius: inherit;
  /* 블러된 사진 위, 연결 캐릭터 아바타(z-index:3) 아래. */
  z-index: 2;
}
/* 블러 상태에서도 판은 클릭을 통과시킨다(요청) — 흐린 채로 눌러도 크게 보기가
   열리고, 거기선 라이트박스 자신의 게이트로 풀면 된다. 안내문 위 클릭이 사진에
   닿아야 하므로 판 전체를 통과시키고 버튼만 되살린다('표시' 뒤 상태(.is-revealed)가
   쓰던 것과 같은 방법이다). 라이트박스 게이트는 제외 — 거기선 판을 눌러 닫는다. */
.sensitive-image-overlay:not(.post-image-lightbox-sensitive) { pointer-events: none; }
.sensitive-image-overlay:not(.post-image-lightbox-sensitive) button { pointer-events: auto; }

.sensitive-image-overlay-text {
  color: #fff;
  font-size: 12px;
  line-height: 1.4;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}

/* "표시"를 누른 뒤 — 오버레이는 사진을 가리지 않고 왼쪽 위 "숨기기" 버튼만
   남긴다(요청). 판 자체는 클릭을 통과시켜야 사진 클릭(크게 보기)이 살아 있다. */
.sensitive-image-overlay.is-revealed {
  display: block;
  padding: 6px;
  /* 기본 판은 안내문을 가운데 두려고 text-align:center 라, 표시 상태에서는
     되돌려야 버튼이 왼쪽 위에 붙는다(요청). */
  text-align: left;
  background: transparent;
  pointer-events: none;
}

/* "숨기기"는 사진 위에 얹히는 단추라 글자 대신 눈 아이콘 하나로 둔다(요청) —
   글자 버튼(49x27)은 130px 썸네일에서 면적의 8%를 먹었다. 어떤 사진 위에서도
   보이게 어두운 반투명 바탕 + 흰 아이콘으로 고정한다(테마색을 따르면 밝은
   사진 위에서 사라진다). */
.sensitive-image-hide {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0 !important;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55) !important;
  color: #fff !important;
  cursor: pointer;
}

.sensitive-image-hide:hover {
  background: rgba(0, 0, 0, .75) !important;
}

/* 위 display 선언이 네이티브 [hidden] 의 display:none 을 이겨버려(.comment-compose
   와 같은 함정) 아직 가려진 사진에도 "숨기기"가 같이 보였다. */
.sensitive-image-hide[hidden] {
  display: none !important;
}

.sensitive-image-hide svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* 지금 캐럿/선택 위치에 적용돼 있는 서식(gallery.js syncToolbarState)을 눌린
   상태로 보여준다 — is-bold 등(버튼 글자 자체의 항상-표시 스타일)과는 별개다. */
.post-editor-format-btn.is-active {
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
  border-color: var(--focus-color) !important;
}

/* 본문은 <textarea>가 아니라 contenteditable — 서식 버튼이 document.execCommand로
   실제 <strong>/<em>/<blockquote>/<ul>/<ol>/<a>/<code>/<img> DOM을 만들어, 별도
   미리보기 화면 없이 입력과 동시에 이 영역 자체가 최종 렌더링과 같은 모습을 보인다
   (gallery.js insertImageNode/serializeEditorToMarkdown 참고). */
.post-editor-content {
  flex: 1;
  min-height: 0;
  width: 100%;
  border: 0px solid !important;
  border-radius: 7px;
  padding: 9px;
  line-height: 1.6;
  overflow: auto;
  /* window-content와 같은 이유로 네이티브 스크롤바를 숨긴다(postEditor.js
     bind()가 대신 window-content와 같은 오버레이 스크롤바를 붙인다) — 안
     숨기면 스크롤이 생길 때마다 네이티브 스크롤바 트랙 폭(15~17px)만큼
     입력 가능한 폭이 줄어 보인다("작성 영역이 좁아짐"). */
  scrollbar-width: none;
  outline: 0;
  transition: border-color .15s, background .15s;
}

.post-editor-content::-webkit-scrollbar {
  display: none;
}

/* 에디터의 제목·공개범위·작성란은 영역 B 를 따른다(요청) — 이 셋은 창 본문을
   가득 채우는 "컨텐츠 판" 자체라, 입력 상자 색을 칠하면 창 안에 또 다른
   상자가 들어앉은 것처럼 보인다. */
/* 판 안쪽 — 배경은 판이 이미 칠했고, 상자(테두리)는 그리지 않는다(요청).
   공개범위 select 는 예외다: 이건 판 조각이 아니라 "노말 버튼"이라(요청)
   자기 테두리를 갖는다 — .custom-select-wrap 규칙이 그 모양을 맡는다. */
.post-editor-title-input,
.post-editor-content {
  background: transparent !important;
  color: var(--system-c-area-b-base-font-color) !important;
  border: 0 !important;
}
/* 제목은 상자 대신 아래 선 하나(요청) — 홈페이지 배너 링크 입력과 같은 언어. */
/* 밑줄은 영역 B 구분선을 따른다(요청) — 이 판 위의 다른 구분선들과 같은 선이다. */
.post-editor-title-input {
  border-bottom: 1px solid rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha)) !important;
  border-radius: 0;
}

/* 제목은 카드 제목과 같은 성격이라 영역 B 의 Title 폰트를 쓴다(요청) —
   위 그룹 규칙이 !important 로 본문 폰트를 칠하므로 여기서 되받는다. */
.post-editor-title-input {
  color: var(--system-c-area-b-base-font-color) !important;
}
/* 링크 칩은 알약 태그라 밑줄까지 그으면 두 겹으로 보인다(요청) —
   .post-markdown-body a / .post-editor-content a 의 underline 이 칩 자신의
   규칙보다 특이도가 높아, 읽기 화면과 편집기 양쪽에서 칩을 명시해 되받는다. */
.post-markdown-body a.post-link-chip,
.post-editor-content a.post-link-chip {
  text-decoration: none;
}

.post-editor-content:empty::before {
  content: attr(data-placeholder);
  color: var(--system-c-area-b-base-desc-font-color);
  pointer-events: none;
}

/* 드래그해 온 이미지가 이 영역 위에 있을 때의 시각 피드백(gallery.js가 토글). */
.post-editor-content.is-drag-over {
  border-color: var(--focus-color) !important;
  background: rgba(var(--focus-rgb), .06);
}

.post-editor-message {
  flex: 0 0 auto;
  min-height: 14px;
  margin: 0;
}

.post-editor-message.is-error {
  color: var(--focus-color);
}

/* 새 글 [등록] 시점에만 뜨는 썸네일 출처 이미지 선택 목록 —
   .image-layout-dialog-options와 같은 패턴, 텍스트 버튼 대신 작은 미리보기 그리드.
   기본 .confirm-dialog(320px)로는 4열 그리드가 너무 좁아 살짝 넓힌다. */
.thumbnail-source-dialog {
  max-width: 420px;
}

/* 공개범위 "일부 사용자 공개" 대상(그룹+사용자) 선택 다이얼로그 —
   .specific-user-list 두 벌(그룹/사용자)이 나란히 들어가 기본
   .confirm-dialog(320px)로는 좁다. */
.visibility-grantee-dialog {
  max-width: 420px;
  text-align: left;
}

/* 메뉴/공유기록/기념일 아이콘 피커(UI.buildIconPicker) — PNG 업로드 / SVG 붙여넣기 탭. */
/* .confirm-dialog 가 이 파일 뒤쪽(7100줄대)에서 max-width:320px 를 같은 특이도로
   다시 선언해, 여기 420px 는 한 번도 적용된 적이 없었다 — 클래스를 하나 더 붙여
   특이도로 이긴다(규칙 순서에 기대지 않게). */
.confirm-dialog.icon-picker-dialog {
  /* max-width 만으로는 내용 크기까지만 커진다 — 탭/드롭영역이 좁게 접히지 않게
     폭을 직접 잡되, 좁은 창에서는 오버레이 안쪽으로 줄어들게 한다
     (.character-relation-search-dialog 와 같은 방식). */
  width: min(420px, calc(100% - 24px));
  max-width: 420px;
  text-align: left;
  /* 팝업 자체를 영역 B 테두리로 두른다(요청) — 안쪽 패널(드롭 영역/코드칸)이
     이미 같은 테두리를 쓰고 있어, 바깥 판만 테두리 없이 그림자로 떠 있었다. */
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
}

.icon-picker-title {
  margin-bottom: 10px;
  font-weight: 700;
  text-align: left;
}

/* 지금 걸려 있는 아이콘 + [기본 아이콘으로] 줄 — 무엇을 바꾸는 중인지 보여준다. */
.icon-picker-current {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.icon-picker-current[hidden] { display: none !important; }
.icon-picker-current-label {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  color: var(--system-c-area-b-base-desc-font-color);
}

/* 아이콘 한 칸(지금 아이콘 / 고른 아이콘 공용) — 실제로 얹히는 자리와 같은
   영역 B 판 위 28px 로 보여준다(예전 미리보기는 40px 투명 칸이라, 어두운 테마에서
   아이콘이 보일지 여기서는 알 수 없었다). */
.icon-picker-swatch {
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  color: var(--system-c-area-b-base-font-color);
}
.icon-picker-swatch[hidden] { display: none !important; }
.icon-picker-swatch svg { width: 20px; height: 20px; }
.icon-picker-swatch img { width: 22px; height: 22px; object-fit: contain; }

.icon-picker-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 10px;
}

/* 밑줄 탭 — 아래 .is-active 규칙까지 전부 !important 가 필요하다: 이 버튼들은
   .small-btn 이라 .small-btn.is-active {background/border/color: Focus색 !important}
   (이 파일 1833줄)에 눌려, 활성 탭이 밑줄이 아니라 통째로 칠해진 토글 버튼으로
   보였다(좌우 탭이 서로 다른 컴포넌트처럼 보이던 원인). */
.icon-picker-tabs button.small-btn {
  flex: 1;
  height: 30px;
  border: 0 !important;
  border-bottom: 3px solid transparent !important;
  border-radius: 0;
  background: transparent !important;
  color: var(--system-c-area-b-base-desc-font-color) !important;
  cursor: pointer;
}

.icon-picker-tabs button.small-btn.is-active {
  border-bottom-color: var(--focus-color) !important;
  color: var(--focus-color) !important;
}

/* PNG 고르기 — 네이티브 <input type=file> 위젯(“파일 선택 / 선택된 파일 없음”)은
   이 앱의 어떤 컨트롤과도 안 닮아서 숨기고, 다른 이미지 업로드 화면과 같이
   버튼 + 끌어다 놓기 영역으로 감싼다. */
.icon-picker-drop {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border: 1px dashed rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
  border-radius: 8px;
}
.icon-picker-drop.is-drop-target {
  border-color: var(--focus-color) !important;
}
.icon-picker-filename {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  color: var(--system-c-area-b-base-desc-font-color);
}

/* 코드칸은 .input-text-box 를 떼고 data-no-theme 을 달아 광역 입력 테마
   에서 뺐다(두 가지가 다 필요하다: 광역 선택자 목록의 첫 항목이 :not([data-no-theme])
   없는 맨 .input-text-box 다). 바로 옆 파일
   패널이 영역 B 점선 상자라, 여기만 입력 상자로 칠하면 한 다이얼로그 안에서 두
   패널이 서로 다른 컴포넌트처럼 보였다(요청). 같은 영역 B 판에 테두리만 실선. */
.icon-picker-textarea {
  width: 100%;
  box-sizing: border-box;
  resize: none;
  font-family: monospace;
  font-size: 12px;
  padding: 8px 10px;
  border-radius: 8px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
}

/* 무엇이 적용될지 — 두 탭이 함께 쓴다(예전엔 SVG 탭 안에만 있어 PNG 를 고르면
   파일명 말고는 볼 게 없었다). */
.icon-picker-result {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.icon-picker-result[hidden] { display: none !important; }
.icon-picker-result-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
}

.thumbnail-source-dialog-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin: 10px 0;
  max-height: 240px;
  overflow-y: auto;
}

.thumbnail-source-dialog-item {
  width: 100%;
  aspect-ratio: 1;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  background: transparent;
}

.thumbnail-source-dialog-item:hover,
.thumbnail-source-dialog-item:focus-visible {
  border-color: var(--focus-color) !important;
}

.thumbnail-source-dialog-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* 게시글 썸네일 16:9 크롭 다이얼로그 — 기존 .confirm-dialog을 재사용하되
   이미지 박스가 들어갈 만큼 폭만 넓힌다. */
.image-crop-dialog {
  width: min(720px, calc(100% - 28px));
  max-width: 720px;
  box-sizing: border-box;
}

.image-crop-box {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 8px;
  cursor: grab;
  touch-action: none;
  background: transparent;
}

.image-crop-box img {
  position: absolute;
  max-width: none;
  user-select: none;
  -webkit-user-drag: none;
}

/* 캐릭터 아바타 등 원형으로 표시될 크롭 영역 — 자르기 자체는 그대로 정사각
   Blob(캔버스)으로 나가고, 여기선 미리보기 박스만 원으로 마스킹해 보여준다. */
.image-crop-box.is-circle {
  aspect-ratio: 1 / 1;
  border-radius: 50%;
}

.image-crop-box.is-portrait {
  width: min(280px, 100%);
  margin-inline: auto;
}

/* 슬라이더는 얇게, 포커스 컬러를 따른다(요청) — .themed-range 를 붙인 것도 같이. */
.image-crop-zoom,
.themed-range {
  appearance: none;
  width: 100%;
  height: 8px;
  margin: 6px 0;
  background: transparent;
  accent-color: var(--focus-color);
}

.image-crop-zoom::-webkit-slider-runnable-track,
.themed-range::-webkit-slider-runnable-track {
  height: 2px;
  border-radius: 999px;
  background: var(--focus-color);
}

.image-crop-zoom::-webkit-slider-thumb,
.themed-range::-webkit-slider-thumb {
  appearance: none;
  width: 8px;
  height: 8px;
  margin-top: -3px;
  border: 0;
  border-radius: 50%;
  background: var(--focus-color);
}

.image-crop-zoom::-moz-range-track,
.image-crop-zoom::-moz-range-progress,
.themed-range::-moz-range-track,
.themed-range::-moz-range-progress {
  height: 2px;
  border-radius: 999px;
  background: var(--focus-color);
}

.image-crop-zoom::-moz-range-thumb,
.themed-range::-moz-range-thumb {
  width: 8px;
  height: 8px;
  border: 0;
  border-radius: 50%;
  background: var(--focus-color);
}

/* 게시글 마크다운 본문 스타일 — 편집 영역(.post-editor-content)과 실제 게시글
   보기(.post-markdown-body, UI.openPost) 양쪽에서 공용으로 써서 편집 결과와 실제
   렌더링 결과가 항상 같은 모습으로 보이게 한다. */
.post-markdown-body h3,
.post-markdown-body h4,
.post-markdown-body h5,
.post-editor-content h3,
.post-editor-content h4,
.post-editor-content h5 {
  /* 브라우저 기본 h1~h6는 font-weight:bold라 execCommand의 queryCommandState('bold')가
     명시적 <strong>/<b> 없이도 제목 안에서 항상 true를 반환해 Bold 버튼이 잘못
     활성화되고, 그 상태에서 Bold를 끄면 진짜 <strong>을 지우는 게 아니라 계산값만
     되돌리는 별도 override span이 생겨 저장 시 사라진다(gallery.js syncToolbarState/
     serializeInlineNode 참고). 제목의 기본 굵기를 여기서 normal로 리셋해 "제목이라
     계산상 굵어 보이는 것"과 "명시적으로 굵게 표시한 것"을 완전히 분리한다 — 제목의
     시각적 구분은 이미 h1,h2,h3 규칙(위쪽, --system-c-area-b-base-font-color)과 아래 font-size
     13px!important 규칙이 맡고 있어 굵기에 의존하지 않는다. 이 규칙 아래에서 만든
     명시적 <strong>/<b>(예: `# **굵은 제목**`)는 각 태그 자체의 굵은 기본 스타일이
     남아있어 여전히 굵게 보인다.
  */
  font-weight: normal;
  margin: .8em 0 .3em;
}

/* 인용구는 예전 그대로 — 왼쪽 Focus 색 선 + 설명 폰트, 배경 없음(요청).
   영역 C를 쓰는 건 아래 코드블록뿐이다. */
.post-markdown-body blockquote,
.post-editor-content blockquote {
  margin: .6em 0;
  padding: 2px 12px;
  border-left: 3px solid rgba(var(--focus-rgb), .6)!important;
  color: var(--system-c-area-b-base-desc-font-color);
}
/* 인용 중간에 엔터를 치면 execCommand가 형제 <blockquote>를 새로 만든다
   (postEditor.js onEditorKeydown) — 둘 사이 세로 여백을 없애 왼쪽 테두리가
   끊기지 않고 한 줄로 이어져 보이게 한다(요청). */
.post-markdown-body blockquote + blockquote,
.post-editor-content blockquote + blockquote {
  margin-top: 0;
}
.post-markdown-body blockquote:has(+ blockquote),
.post-editor-content blockquote:has(+ blockquote) {
  margin-bottom: 0;
}

.post-markdown-body ul,
.post-markdown-body ol,
.post-editor-content ul,
.post-editor-content ol {
  margin: .4em 0;
  padding-left: 22px;
}

.post-markdown-body li,
.post-editor-content li {
  margin: .2em 0;
}

/* ``` 코드 블록 — 인라인 코드와 같은 영역 C 톤이지만 여러 줄이라 줄바꿈/공백을
   그대로 보존하고 가로로만 스크롤된다. 테두리는 블록에만 있다(요청). */
.post-markdown-body pre.post-code-block,
.post-editor-content pre {
  margin: 8px 0;
  padding: 10px 12px;
  border: 1px solid rgba(var(--system-c-area-d-base-border-rgb), var(--system-c-area-d-base-border-alpha));
  border-radius: 8px;
  background: var(--system-c-area-d-base-color);
  color: var(--system-c-area-d-base-font-color);
  font-family: monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow-x: auto;
}
/* 블록 안의 <code> 는 알약 배경을 다시 그리지 않는다(블록 자체가 이미 판이다). */
.post-markdown-body pre.post-code-block code,
.post-editor-content pre code {
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
}

/* 인라인 코드(`이정도`) — 테두리 없이 배경/글자색만 준다(요청). 한 낱말을
   감싸는 알약이라 선까지 두르면 문장 안에서 과하게 튄다. 읽기 뷰와 에디터가
   같은 모양이어야 해서 두 selector 를 한 규칙으로 묶는다. */
.post-editor-content code,
.post-markdown-body code {
  font-family: monospace;
  background: var(--system-c-area-d-base-color);
  color: var(--system-c-area-d-base-font-color);
  border: 0;
  border-radius: 4px;
  padding: 1px 5px;
}

/* 마크다운 표식(**, *, ~~, `, ||)은 CSS 가상요소가 아니라 진짜 글자다
   (postEditor.js 의 "인라인 마크다운" 절) — 그래야 캐럿을 넣어 중간을 고치고,
   문법을 깨거나 새로 닫아서 서식을 켜고 끌 수 있다. 여기서는 본문 글자와
   구분되게 흐리게만 칠한다. 렌더된 게시글엔 표식 자체가 없다. */
.post-editor-content .md-mark {
  color: var(--system-c-area-b-base-desc-font-color);
  font-weight: 400;
  font-style: normal;
  font-family: monospace;
  text-decoration: none;
  opacity: .75;
}

.post-markdown-body a,
.post-editor-content a {
  color: var(--focus-color);
  text-decoration: underline;
}

/* @멘션 — 렌더된 글과 편집 중인 칩이 같은 톤을 쓴다. 렌더된 칩은 클릭하면
   body 직속 프로필 카드가 열리므로 윈도우 overflow에 잘리지 않는다. */
.post-mention,
.post-mention-chip,
.mention-pending {
  color: var(--focus-color);
  font-weight: 700;
}
.post-mention {
  padding: 0px 6px 2px;
  border-radius: 10px;
  border: 1px solid var(--focus-color) !important;
  margin: 4px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  cursor: pointer;
}
.post-mention.is-self {
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}
/* 링크 삽입 결과 — 사용자 태그(.post-mention)와 같은 언어지만 라운딩을 줄인
   사각 태그(요청)에, 아이콘(외부 링크 화살표)이 텍스트 앞에 붙는다. */
.post-link-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0px 6px 2px;
  border-radius: 4px;
  border: 1px solid var(--focus-color) !important;
  margin: 4px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  color: var(--focus-color);
  font-weight: 700;
  text-decoration: none;
}
.post-link-chip svg,
.post-link-chip svg * {
  color: inherit;
}
.post-link-chip svg {
  width: 11px;
  height: 11px;
  flex: 0 0 auto;
}
/* 링크 삽입 팝업 — 캐럿/선택 위치에 뜨는 텍스트+URL 입력 폼(postEditor.js
   insertLink). mention-dropdown과 같은 고정 위치 패널 언어. */
.post-link-insert-popup-title {
  margin: 0 0 2px;
  font-weight: 700;
  color: var(--system-c-area-b-base-font-color);
}
/* 팝업 안 두 입력은 프로필 이름 칸과 같은 "떠오르는 라벨 + 밑줄"이다(요청) —
   .auth-field/.auth-input/.auth-label 을 그대로 쓰되, 이 팝업은 영역 B 위라
   글자색만 맞춘다(밑줄/라벨 규칙은 user.css 공용). */
.post-link-insert-popup .auth-input,
/* 환경설정 편집 팝업의 칸도 같은 이유로 영역 B 글자색을 따른다(요청). */
.settings-editor-dialog .auth-input {
  color: var(--system-c-area-b-base-font-color) !important;
}

.post-link-insert-popup {
  position: fixed;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: min(260px, 90vw);
  padding: 8px;
  border-radius: 8px;
  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)) !important;
}
.post-link-insert-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
}
.mention-profile-popover {
  position: fixed;
  z-index: calc(var(--z-debug) + 2);
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 210px;
  max-width: min(280px, calc(100vw - 16px));
  padding: 10px;
  border-radius: 8px;
  color: var(--system-c-area-b-base-font-color) !important;
  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)) !important;
  box-shadow: 0 6px 18px -4px rgba(0, 0, 0, .24);
}
.mention-profile-popover[hidden] {
  display: none !important;
}
.mention-profile-avatar {
  flex: 0 0 42px;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background-position: center;
  background-size: cover;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
}
.mention-profile-avatar svg {
  width: 24px;
  height: 24px;
}
.mention-profile-summary {
  min-width: 0;
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
}
.mention-profile-summary strong {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.post-editor-content a.post-mention-chip {
  text-decoration: none;
  padding: 0px 6px 2px;
  border-radius: 10px;
  border: 1px solid var(--focus-color) !important;
  margin: 0 2px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  cursor: default;
}

/* 캐럿/클릭 위치에 뜨는 고정 패널 3종(@멘션 검색 드롭다운/이미지 클릭 메뉴/
   텍스트 선택 메뉴)이 공유하는 기본 틀 — 배경·테두리·모서리(패널)와 항목 하나의
   hover/active(post-editor-popover-item)까지 여기서 정하고, 각자는 자기만
   다른 부분(스크롤 목록이냐 가로 막대냐, 항목 정렬 등)만 따로 얹는다. */
/* 뜨는 판은 일반 버튼 테마를 따른다(요청) — 영역 B 가 유리(투명) 테마일 때
   뒤의 글이 비쳐 목록을 읽을 수 없었다. 버튼 배경은 언제나 불투명하다. */
.post-editor-popover {
  position: fixed;
  z-index: 20;
  padding: 4px;
  border-radius: 8px;
  overflow-y: auto;
  background: var(--system-c-button-base-color) !important;
  border: 1px solid rgba(var(--system-c-button-base-border-rgb), var(--system-c-button-base-border-alpha)) !important;
  color: var(--system-c-button-base-font-color) !important;
  box-shadow: 0 6px 16px -6px rgba(0, 0, 0, .3);
}
.post-editor-popover-item {
  padding: 6px 8px;
  border-radius: 6px;
  text-align: left;
  cursor: pointer;
  background: transparent !important;
  border: none;
  color: var(--system-c-area-b-base-font-color) !important;
}
.post-editor-popover-item:hover,
.post-editor-popover-item.is-active {
  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;
  background-image: none !important;
}

/* @멘션 검색 드롭다운 — document.body에 붙어(postEditor.js) 캐럿 span의
   getBoundingClientRect() 좌표를 그대로 쓰므로 position:fixed다(스크롤
   컨테이너 안에서도 항상 캐럿 바로 아래에 온다). */
.mention-dropdown {
  min-width: 180px;
  max-height: 220px;
  overflow-y: auto;
  scrollbar-width: none;
}
.mention-dropdown::-webkit-scrollbar {
  display: none;
}
.mention-dropdown-item {
  display: flex;
  width: 100%;
  gap: 8px;
  align-items: center;
}
.mention-dropdown-avatar {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  background-color: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
}
.mention-dropdown-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mention-match {
  color: var(--focus-color);
  font-weight: 700;
}

/* 민감한 내용(텍스트) — 에디터 안에서는 작성자가 계속 읽을 수 있어야 하니
   옅은 배경만 주고, 실제 게시글 보기(.post-markdown-body)에서만 블러를 걸어
   클릭 전까진 안 보이게 한다. */
.post-sensitive-text {
  padding: 0 2px;
  border-radius: 4px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
}
.post-markdown-body .post-sensitive-text {
  filter: blur(5px);
  cursor: pointer;
  transition: filter .15s ease;
}
.post-markdown-body .post-sensitive-text.is-revealed {
  filter: none;
  cursor: text;
}

/* 실제 게시글과 편집기가 항상 같은 모습이 되도록 원본 크기와 무관하게 콘텐츠
   가로폭 전체를 차지하게 하고, height:auto로 원본 비율은 그대로 유지한다. */
.post-markdown-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
  margin: 8px 0;
}

/* 다중 이미지 좌우 넘김 뷰어(gallery.js insertImageViewerNode / homepage.ui.js
   renderSafeMarkdown+bindImageViewers가 공유하는 마크업). 한 번에 한 장만 보이고
   (JS가 각 <img data-viewer-slide>의 display를 토글), 이전/다음 버튼과 위치
   표시는 이미지 위에 겹쳐 그린다. */
.post-image-viewer {
  position: relative;
  display: block;
  margin: 8px 0;
}

.post-image-viewer .post-markdown-image {
  margin: 0;
}

.post-image-viewer-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, .45);
  color: #fff;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.post-image-viewer-nav:disabled {
  opacity: .35;
  cursor: default;
}

.post-image-viewer-prev { left: 8px; }
.post-image-viewer-next { right: 8px; }

.post-image-viewer-position {
  position: absolute;
  bottom: 8px;
  right: 8px;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(0, 0, 0, .45);
  color: #fff;
}

/* 읽기용 게시글 본문에서만 켜지는 좌우 25%/가운데 50% 클릭 탐색·크게 보기
   (homepage.ui.js bindImageViewers) — 클릭 가능함을 커서로 알린다. */
.post-image-viewer-zoomable .post-markdown-image {
  cursor: pointer;
}

/* 뷰어 블록 밖의 낱장 이미지(영화 포스터 등, UI.makeImageZoomable)용 —
   위와 같은 커서 힌트만 이미지 자신에게 직접 준다. */
.img-zoomable {
  cursor: pointer;
}

/* 크게 보기 오버레이. .window(overflow:hidden, position:fixed)의 자식으로 붙여
   window-bar와 주소창 높이만큼 top을 실측해 띄우므로 창 밖이나 상단 UI를
   가리지 않고, 창 리사이즈/최대화에도 .window 크기를 그대로 따라간다. */
/* 아래 라이트박스·이미지 뷰어의 검정(rgba(0,0,0,.82) 바탕, .55 버튼, #fff 글자)은
   일부러 테마를 따르지 않는다(요청) — 사진을 보는 전체화면이라 어떤 테마에서든
   어두운 바탕이 사진 감상에 맞다. 테마 누락이 아니므로 건드리지 말 것. */
.post-image-lightbox {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* 팝업 안의 그림도 눌러 크게 본다(요청) — 그러려면 팝업(--z-dialog)보다 위여야 한다. */
  z-index: calc(var(--z-dialog) + 2);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, .82);
  /* 휠로 확대한 이미지는 transform 이라 상자 밖으로 그려진다 — 그대로 두면
     라이트박스 위쪽의 윈도우 바/주소창까지 덮었다(요청). 여기서 잘라낸다. */
  overflow: hidden;
}

.post-image-lightbox[hidden] {
  display: none;
}

.post-image-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 8px;
  transform-origin: center center;
  transition: transform .1s ease-out;
  touch-action: none;
  will-change: transform;
}

.post-image-lightbox.is-zoomed .post-image-lightbox-img {
  cursor: grab;
  border-radius: 0;
}

.post-image-lightbox.is-panning .post-image-lightbox-img {
  cursor: grabbing;
  transition: none;
}

.post-image-lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
}

.post-image-lightbox-nav:disabled {
  opacity: .3;
  cursor: default;
}

.post-image-lightbox-prev { left: 12px; }
.post-image-lightbox-next { right: 12px; }

/* 민감 게이트(.post-image-lightbox-sensitive, z-index:1)보다 위에 둔다 —
   가려진 상태에서도 닫기·좌우 이동은 계속 눌려야 한다. 셋 다 position:absolute
   에 z-index 가 없어 DOM 순서상 뒤에 오는 게이트에 덮이고 있었다. */
.post-image-lightbox-close,
.post-image-lightbox-nav,
.post-image-lightbox-position {
  z-index: 2;
}

.post-image-lightbox-position {
  position: absolute;
  right: 16px;
  bottom: 12px;
  padding: 3px 8px;
  border-radius: 10px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
}

/* "원본 글" — 확대 이미지 좌측 하단(요청). 장수 표시(우측 하단)와 좌우로
   마주 보고, 숨기기(좌측 상단)와는 같은 세로선에 놓인다. */
.post-image-lightbox-source {
  position: absolute;
  z-index: 2;
  left: 16px;
  bottom: 12px;
  padding: 3px 8px;
  border: 0;
  border-radius: 10px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  cursor: pointer;
}

.post-image-lightbox-source[hidden] {
  display: none !important;
}

.post-image-lightbox-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}

/* 라이브2D 모델이 연결된 본문 이미지 위에 겹치는 배지(homepage.ui.js
   bindLive2DBadges). 뷰어(다중이미지) 슬라이드는 이미 .post-image-viewer가
   position:relative라 배지를 바로 그 위에 얹지만, 단일(뷰어 아닌) <img>는
   감싸는 요소가 없어서 이 span으로 새로 감싼다. .post-markdown-image가 이미
   display:block;width:100%(에디터와 똑같이 한 줄에 하나, 포스트 폭 100%를
   차지)이므로 감싸개도 같은 block;width:100%여야 한다 — 예전에 inline-block;
   max-width:100%였을 때는 이미지가 자기 원본 크기로 쪼그라들어, 라이브2D
   배지가 뜨는 게시글(관리자에게는 배지 미연결 이미지에도 항상 뜬다)에서
   이미지 두 장이 폭에 따라 한 줄에 나란히 보이는 버그가 있었다. */
.post-markdown-image-wrap {
  position: relative;
  display: block;
  width: 100%;
}

.live2d-badge {
  position: absolute;
  right: 8px;
  top: 8px;
  width: auto;
  height: 26px;
  padding: 0 8px;
  /* 버튼 기본 테마를 따른다(요청) — 예전엔 Focus 배경 고정이라 이미지 위에서
     "지금 켜진 상태"처럼 보였다. */
  border: 1px solid rgba(var(--system-c-button-base-border-rgb), var(--system-c-button-base-border-alpha)) !important;
  border-radius: 10px;
  background: var(--system-c-button-base-color);
  color: var(--system-c-button-base-font-color);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .3);
}

/* 라이브2D 모델 뷰어 오버레이 — post-image-lightbox와 같은 패턴(.window의
   자식으로 붙어 window-bar 높이만큼 top을 실측해 띄운다). */
.live2d-viewer-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  background: rgba(0, 0, 0, .85);
}

.live2d-viewer-overlay[hidden] {
  display: none;
}

.live2d-viewer-canvas {
  flex: 1;
  min-height: 0;
  width: 100%;
  touch-action: none;
}

.live2d-viewer-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  z-index: 1;
}

.live2d-viewer-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  text-align: center;
  max-width: 80%;
}

.live2d-viewer-loading[hidden] {
  display: none;
}

/* flex 행으로 자기 자리를 차지해 캔버스 높이를 줄이던 걸, .live2d-viewer-close와
   같은 방식(overlay 자체가 이미 position:absolute라 그 안에서 바로 앵커된다)의
   오버레이로 바꿔 캔버스가 뷰어 전체 높이를 그대로 쓰게 한다. */
.live2d-viewer-toolbar {
  position: absolute;
  left: 12px;
  bottom: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 10px;
  background: rgba(0, 0, 0, .55);
  z-index: 1;
}

/* 조작 모드/트래킹 설정 패널은 뷰어 자체의 어두운 스크림과 달리
   .confirm-dialog와 같은 System C content 테마를 따른다. */
.live2d-viewer-params {
  position: absolute;
  right: 12px;
  bottom: 62px;
  width: 240px;
  max-height: min(340px, 60%);
  overflow-y: auto;
  padding: 10px;
  border-radius: 8px;
  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)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
}

.live2d-viewer-params[hidden] {
  display: none;
}

.live2d-param-row {
  display: flex;
  align-items: center;
  gap: 8px;
  color: inherit;
  font-size: 11px;
  margin-bottom: 6px;
}

.live2d-param-row span {
  flex: 0 0 90px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live2d-param-row input[type="range"] {
  flex: 1;
}

.live2d-viewer-tracking {
  position: absolute;
  right: 12px;
  bottom: 62px;
  width: 340px;
  max-height: min(360px, 60%);
  overflow-y: auto;
  padding: 10px;
  border-radius: 8px;
  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)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
}

.live2d-viewer-tracking[hidden] {
  display: none;
}

.live2d-tracking-hint {
  margin: 0 0 8px;
  color: var(--system-c-area-b-base-desc-font-color);
  font-size: 11px;
  line-height: 1.4;
}

.live2d-tracking-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 8px;
  color: inherit;
  font-size: 11px;
  padding: 4px 0;
  border-bottom: 1px solid rgba(var(--system-c-area-b-base-border-rgb), .2);
}

.live2d-tracking-name {
  flex: 1 0 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live2d-tracking-axis {
  display: flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
}

.live2d-tracking-visible {
  margin-left: auto;
  color: var(--focus-color, #ffd479);
}

[data-live2d-tracking-save] {
  margin-top: 6px;
  width: 100%;
}

/* 편집기에서만 쓰는 이미지 삭제(x) 버튼을 얹기 위한 감싸개(gallery.js
   wrapImageFrame). 실제 게시글 보기(post-markdown-body)에는 이 감싸개가 없고
   원본 <img>만 쓰이므로 이미지 자체의 여백(.post-markdown-image의 margin)은
   그대로 두고, 감싸개 안에서만 0으로 덮어써 겹치지 않게 한다. */
.post-image-frame {
  position: relative;
  display: block;
  width: 100%;
  margin: 8px 0;
}

.post-image-frame .post-markdown-image {
  margin: 0;
}

.post-image-viewer .post-image-frame {
  margin: 0;
}

.post-image-frame.is-selected-image {
  outline: 2px solid var(--focus-color);
  outline-offset: 2px;
  border-radius: 8px;
}

.post-image-remove-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 1;
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.post-image-remove-btn:hover {
  background: rgba(0, 0, 0, .75);
}

/* 이미지를 클릭하면 뜨는 메뉴(postEditor.js openImageMenu) — .post-editor-popover(위,
   5200행대) 공용 틀 + 목록 정렬만 얹는다. */
.post-image-menu {
  min-width: 150px;
}
.post-image-menu-item {
  display: block;
  width: 100%;
}
.post-image-menu-item:disabled {
  opacity: .5;
  cursor: default;
}

/* 텍스트를 드래그로 선택하면 뜨는 서식 막대(postEditor.js openSelectionMenu) —
   .post-editor-popover 공용 틀 + 가로 나열만 얹는다. */
.post-selection-menu {
  display: flex;
  align-items: center;
  gap: 2px;
}
.post-selection-menu-item {
  font-size: 13px;
  white-space: nowrap;
}
.post-selection-menu-item[data-selection-format="bold"] { font-weight: 700; }
.post-selection-menu-item[data-selection-format="italic"] { font-style: italic; }
.post-selection-menu-item[data-selection-format="strike"] { text-decoration: line-through; }
.post-selection-menu-item[data-selection-format="code"] { font-family: monospace; }
.post-selection-menu-item.is-sensitive { color: var(--focus-color) !important; }
.post-selection-menu-divider {
  width: 1px;
  height: 18px;
  background: rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  margin: 0 2px;
}

/* 프레임 좌상단 태그([민감한 내용]/Live2D) — .post-image-remove-btn과 같은
   중립 칩 톤(하드코딩 색상은 텍스트로만 구분, 앱 전체가 --focus-color 하나로만
   강조하는 원칙을 따른다 — .small-btn.danger 주석 참고). */
.post-image-tags {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 1;
  display: flex;
  gap: 4px;
}
.post-image-tag {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: rgba(0, 0, 0, .55);
}

/* 프레임 좌하단 연결된 캐릭터 아바타 행 — 겹쳐 쌓인 동그란 프로필사진들.
   누르면 캐릭터 연결 팝업으로 바로 간다(postEditor.js contentEl 클릭 위임). */
.post-image-characters:not(:empty) {
  cursor: pointer;
}
.post-image-characters {
  position: absolute;
  bottom: 6px;
  left: 6px;
  /* 민감 오버레이(z-index:2)보다 위 — 사진을 가린 상태에서도 어떤 캐릭터가
     연결됐는지는 보여야 한다(요청). */
  z-index: 3;
  display: flex;
  gap: 4px;
}

.post-image-characters[hidden] {
  display: none;
}

/* 읽는 화면의 아바타는 누르면 그 캐릭터 상세로 가는 버튼이다(요청). */
.post-image-characters.is-readonly .post-image-character-avatar {
  cursor: pointer;
}
/* 여러 명이 붙어도 서로 가리지 않게 나란히 둔다(요청) — 예전엔 margin -8px 로
   포개서 뒤쪽 캐릭터 얼굴이 앞 아바타에 잘려 보였다. 간격은 아래 행의 gap. */
.post-image-character-avatar {
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 50%;
  /* 테두리 없이 사진만(요청). 밝은 사진 위에서 묻히지 않게 하던 어두운 테두리는
     뺐고, 대신 아래 배경색이 그 역할을 이어받는다. */
  border: 0 !important;
  background-color: rgba(0, 0, 0, .3);
  background-size: cover;
  background-position: center;
}

/* 프로필 사진이 없는 캐릭터는 다른 화면(캐릭터 목록·활동 카드)과 같은 사람
   모양 아이콘을 보여준다(요청) — 예전엔 빈 어두운 동그라미만 남았다. */
.post-image-character-avatar.is-empty {
  display: grid;
  place-items: center;
}

.post-image-character-avatar.is-empty svg {
  width: 60%;
  height: 60%;
  fill: none;
  stroke: rgba(255, 255, 255, .85);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* "캐릭터와 연결" 팝업 — mention-dropdown-item과 같은 언어의 체크박스 목록. */
.character-link-picker {
  width: min(320px, 90vw);
}
/* 이미지 여러 장을 한번에 삽입할 때 세로 순차 표시/좌우 뷰어 중 하나를 고르는
   선택 다이얼로그(gallery.js chooseImageLayout)의 큰 선택 버튼 두 개. */
.image-layout-dialog-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 10px 0;
}

.image-layout-dialog-options .small-btn {
  width: 100%;
}

.confirm-dialog-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .35);
}

/* 게시글 작성 창의 썸네일 선택/크롭 단계만 브라우저 전체가 아니라 그 .window
   내부(작성 창의 position:fixed + overflow:hidden 박스)에 한정해서 덮는다 —
   .window에 직접 append되므로 position:absolute; inset:0만으로 창 경계·둥근
   모서리 안쪽에 자동으로 클리핑되고, 다른 창·브라우저 나머지 영역은 그대로 둔다. */
.confirm-dialog-overlay.is-window-scoped {
  position: absolute;
}

/* 창 안에 팝업이 떠 있는 동안은 창 내용 자체를 흐린다(요청: 팝업 뒤 글자가
   비쳐 보이지 않게). 팝업의 backdrop-filter 로는 안 된다 — 스크롤 컨테이너
   (.window-content / 채팅 로그)의 내용은 backdrop 스냅샷에 들어오지 않아
   이미지만 흐려지고 글자는 그대로 남았다(실측). 내용 쪽에 filter 를 직접 걸면
   글자까지 확실히 흐려진다. 팝업(.confirm-dialog-overlay)은 .window 의 형제라
   이 blur 를 안 받는다. */
.window:has(> .confirm-dialog-overlay.is-window-scoped) > .window-content {
  filter: blur(5px);
}
/* 떠 있는 + 버튼(.fab-dock, z-index 700)은 팝업 막(z-dialog 500) 위에 남아
   흐려지지도 가려지지도 않았고 그대로 눌리기까지 했다 — 팝업이 떠 있는 동안은 감춘다. */
.window:has(> .confirm-dialog-overlay.is-window-scoped) .fab-dock {
  display: none;
}

.confirm-dialog {
  min-width: 220px;
  max-width: 320px;
  padding: 18px;
  border-radius: 12px;
  text-align: center;
  /* 판은 테마의 영역 B 투명도를 그대로 따른다(요청) — 예전엔 여기만 알파 없는
     원색이라 테마를 반투명하게 맞춰도 팝업만 불투명했다. 뒤는 블러로 눌러 준다
     (작성 푸터 .comment-compose-panel 과 같은 값). 다만 내장 브라우저(WebView2)는
     backdrop-filter 에 글자 레이어를 넣지 않아 뒤 "글자"는 안 흐려진다 — 알파를
     아주 낮게 잡은 테마에서는 팝업 뒤 글이 비쳐 보일 수 있다(알려진 한계). */
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  /* 판 테두리도 영역 B 를 따른다(요청) — 예전엔 공유 기록의 폼 팝업
     (.shared-form-dialog)만 테두리가 있어 설정 모달의 확인 팝업과 모양이 달랐다. */
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
  /* backdrop-filter 는 쓰지 않는다(요청) — 뒤(창 내용)는 팝업이 떠 있는 동안 filter 로
     이미 흐려지는데, 여기에 또 걸면 판만 한 겹 더 어둡게 보였다. */
  box-shadow: 0 12px 28px -6px rgba(0, 0, 0, .22);
}

.confirm-dialog-message {
  margin: 0 0 16px;
  line-height: 1.6;
  /* 한글은 기본적으로 어절 중간에서도 줄바꿈이 허용돼(word-break:normal) 좁은
     다이얼로그 폭에서 단어가 쪼개지기 쉽다 — 공백 단위로만 넘어가게 고정. */
  word-break: keep-all;
}

.confirm-dialog-actions {
  display: flex;
  justify-content: center;
  gap: 8px;
}
.settings-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  padding-top: 4px;
}

.settings-form-actions button {
  height: 29px;
  padding: 0 12px;
  border: 1px solid #ddd;
  border-radius: 7px;
  background: #fff;
  cursor: pointer;
}

.specific-user-list {
  max-height: 150px;
  overflow: auto;
  border: 1px solid #eee;
  border-radius: 7px;
}

.specific-user-item {
  display: grid;
  grid-template-columns: 68px 1fr 70px;
  gap: 5px;
  align-items: center;
  padding: 6px;
  border-bottom: 1px solid #f0f0f0;
}

.specific-user-item:last-child {
  border-bottom: 0;
}
/* 스페이스 만들기의 소유자 칸(요청) — 친 글자로 사용자를 찾아 고른다. 칸 바로
   아래에 붙는 목록이라 칸을 기준으로 띄운다. */
.settings-user-pick { position: relative; }
.settings-user-suggest {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 2;
  display: flex; flex-direction: column; gap: 2px;
  margin-top: 2px; padding: 4px; border-radius: 8px;
  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)) !important;
  box-shadow: 0 8px 20px -8px rgba(0, 0, 0, .3);
}
.settings-user-suggest[hidden] { display: none; }
.settings-user-suggest-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 7px; border-radius: 6px; text-align: left; cursor: pointer;
}
/* 얼굴 + (이름 / @아이디) — 검색 줄과 고른 뒤 칸 안의 얼굴이 같은 크기다(요청). */
.settings-user-suggest-avatar { flex: 0 0 26px; width: 26px; height: 26px; }
.settings-user-suggest-text { display: flex; align-items: baseline; gap: 6px; min-width: 0; opacity: 1 !important; font-size: inherit !important; }
.settings-user-suggest-item span { font-size: 11px; opacity: .7; }
.settings-user-pick-avatar {
  position: absolute; left: 0; bottom: 5px; z-index: 1;
  width: 22px; height: 22px; pointer-events: none;
}
.settings-user-pick-avatar[hidden] { display: none; }
.settings-user-pick-avatar-img { width: 22px; height: 22px; }
/* 얼굴이 붙은 동안에는 글자가 그 위로 겹치지 않게 칸을 밀어 준다. */
.settings-user-pick:has(> .settings-user-pick-avatar:not([hidden])) .auth-input { padding-left: 28px; }

.settings-inline-message {
  min-height: 12px;
}

/* ==========================================================================
   설정 앱 공통 토글 버튼 (체크박스 대체). 실제 <input type="checkbox">는 시각적으로만
   숨기고(opacity:0) 그대로 두어 checked/disabled/change, name 기반 폼 직렬화가 기존
   체크박스와 동일하게 동작한다. 왼쪽 상태 텍스트(data-on/data-off)는 :checked 여부에
   따라 ::before로 즉시 전환되므로 별도 JS 동기화가 필요 없다.
   ========================================================================== */
.settings-toggle {
  display: inline-flex !important;
  flex-direction: row-reverse;
  align-items: center;
  gap: 6px;
  min-width: 0;
  cursor: pointer;
}
.settings-toggle-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  opacity: 0;
}
.settings-toggle-track {
  position: relative;
  flex: none;
  width: 30px;
  height: 17px;
  border-radius: 999px;
  background: rgba(0,0,0,.18);
  transition: background .15s ease;
}
.settings-toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.35);
  transition: transform .15s ease;
}
.settings-toggle-input:checked ~ .settings-toggle-track {
  background: var(--focus-color) !important;
}
.settings-toggle-input:checked ~ .settings-toggle-track .settings-toggle-thumb {
  transform: translateX(13px);
}
.settings-toggle-input:focus-visible ~ .settings-toggle-track {
  outline: 2px solid var(--focus-color);
  outline-offset: 2px;
}
.settings-toggle-input:disabled ~ .settings-toggle-track {
  opacity: .55;
  cursor: not-allowed;
}
.settings-toggle-input:disabled ~ .settings-toggle-text {
  cursor: not-allowed;
}
.settings-toggle-input:disabled {
  cursor: not-allowed;
}
.settings-toggle-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.settings-toggle-text::before {
  content: attr(data-off);
}
.settings-toggle-input:checked ~ .settings-toggle-text::before {
  content: attr(data-on);
}

/* .settings-toggle과 같은 기법(체크박스는 시각적으로만 숨기고 CSS로 손잡이를
   그림)의 라디오 버전 — 토글은 on/off 스위치라 3지선다 같은 배타 선택엔 안
   맞아서 따로 둔다(homepage.ui.js radioFieldHTML). */
.settings-radio {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.settings-radio-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  opacity: 0;
}
.settings-radio-dot {
  position: relative;
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(0,0,0,.3);
  transition: border-color .15s ease;
}
.settings-radio-dot::after {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--focus-color);
  transform: scale(0);
  transition: transform .15s ease;
}
.settings-radio-input:checked ~ .settings-radio-dot {
  border-color: var(--focus-color);
}
.settings-radio-input:checked ~ .settings-radio-dot::after {
  transform: scale(1);
}
.settings-radio-input:focus-visible ~ .settings-radio-dot {
  outline: 2px solid var(--focus-color);
  outline-offset: 2px;
}
.settings-radio-input:disabled ~ .settings-radio-dot {
  opacity: .55;
  cursor: not-allowed;
}

/* 같은 기법의 네모 체크(선택 목록용) — 스위치(.settings-toggle)는 on/off 설정에,
   이건 "여러 개 중 골라서 선택"(디스크 정리 파일 선택 등)에 쓴다. 사진 위에
   겹쳐 놓일 수도 있어(디스크 정리 썸네일) 배경 위에서도 항상 보이게
   반투명 흰 배경 + 그림자를 기본으로 깐다. */
.settings-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.settings-checkbox-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  opacity: 0;
}
.settings-checkbox-box {
  position: relative;
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  border: 2px solid rgba(0,0,0,.3);
  background: rgba(255,255,255,.85);
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
}
.settings-checkbox-box::after {
  content: '';
  position: absolute;
  left: 4px;
  top: 1px;
  width: 4px;
  height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform .1s ease;
}
/* 켜진 체크박스는 중요 버튼(.primary-button)과 같은 표면이다 — 배경은 Focus,
   테두리는 중요 버튼 전용 테두리값을 그대로 쓴다(요청). 광역 `* { border-color: … }`가
   !important 라 중요 버튼과 같은 무게로 써야 이긴다. */
.settings-checkbox-input:checked ~ .settings-checkbox-box {
  background: var(--focus-color);
  border-color: rgba(var(--system-c-button-primary-border-rgb), var(--system-c-button-primary-border-alpha)) !important;
}
.settings-checkbox-input:checked ~ .settings-checkbox-box::after {
  transform: rotate(45deg) scale(1);
}
.settings-checkbox-input:focus-visible ~ .settings-checkbox-box {
  outline: 2px solid var(--focus-color);
  outline-offset: 2px;
}
.settings-checkbox-input:disabled ~ .settings-checkbox-box {
  opacity: .55;
  cursor: not-allowed;
}

/* 환경설정은 창 안의 앱이라 뷰포트가 아니라 컨텐츠 영역(.settings-content, 컨테이너 "settings") 폭으로 접는다(요청:
   창 크기 조정·모바일 모두). 예전 @media(max-width:900px) 는 넓은 화면에서 창만 좁히면 안 걸려 목록이 가로로 잘렸다.
   기준 720px 는 사용 메뉴 관리의 일곱 칸(36+80+110+74+100+108+60 + 간격)이 들어가는 최소 폭이다. */
@container settings (max-width: 720px) {
  .menu-admin-header, .user-admin-header, .user-group-header { display: none; }
  .menu-admin-row { grid-template-columns: 32px 1fr 74px; }
  .menu-admin-row > *:not(.menu-admin-icon):not(.menu-admin-title):not(.menu-admin-check):not(.menu-admin-pills) { display: none; }
  /* 좁은 창에서도 공개범위·댓글은 보이고 고칠 수 있어야 한다(요청) — 이름 아래 둘째 줄로. */
  .menu-admin-row > .menu-admin-pills { display: flex; flex-wrap: wrap; gap: 4px; grid-column: 2 / 4; grid-row: 2; }
  .user-admin-row { grid-template-columns: 36px 1fr 65px auto; }
  /* 스페이스 줄은 슬러그와 버튼만 — 나머지 칸(소유자·멤버·도메인·디스크)은 줄을 눌러 고칠 때 본다. */
  .space-admin-row { grid-template-columns: minmax(0, 1fr) 60px; }
  .space-admin-row > *:not(:first-child):not(:last-child) { display: none; }
  /* 테마 관리의 바탕화면 | 색 목록 두 열은 한 열로 쌓는다 — 두 열이면 색 값이 잘렸다. */
  .theme-panel-columns { flex-direction: column; }
  /* 홈: 미리보기 아래로 입력 줄을 쌓는다 — 2열이면 auto 열이 미리보기로 다 차서 입력 줄이 0px 열로 밀렸다. */
  .settings-home-grid { grid-template-columns: minmax(0, 1fr); }
  .server-stats-row { grid-template-columns: 1fr; }
}

/* 최초 크기만 960x520(spawnTemplateWindow 호출부 width/height)이고, 그 외에는
   일반 창과 동일하게 테두리/모서리 드래그로 자유롭게 리사이즈된다 — 창 전용
   max-width/max-height, resize-handle 숨김 규칙을 두지 않는다. 공통 .window의
   min-width/min-height 및 뷰포트 경계 클램프(makeWindowInteractive)는 그대로 적용됨. */
/* 컨텐츠(환경설정/테마관리/메뉴관리/사용자관리/이력관리)가 창 크기 안에 다 들어오면
   그대로 보이고, 안 들어오면(작은 창 등) 잘리지 않고 스크롤되도록 한다. */
.window[data-root="settings"] .window-content {
  padding: 12px;
  overflow-y: auto;
  overflow-x: hidden;
}

/* 좁은 창의 내비게이션은 위 window-content의 안쪽 여백까지 덮어
   윈도우바 아래 콘텐츠 영역 전체를 가린다. */
.settings-shell.is-nav-small .side-nav-backdrop {
  inset: -12px;
}

.settings-header-action-group .settings-inline-message {
  max-width: 130px;
  text-align: right;
}

.settings-header-action-group button {
  height: 27px;
  padding: 0 10px;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  border-radius: 7px;
  cursor: pointer;
}

.settings-pc-preview {
  box-sizing: border-box;
  width: auto;
  aspect-ratio: 210 / 131;
  padding: 6px 6px 11px;
}

.settings-pc-screen {
  height: 100%;
}

.settings-info-label {
  font-weight: 700;
}

.settings-inline-input,.settings-inline-select, .settings-info-value {
  height: 27px;
}

.settings-music-summary {
  min-width: 0;
  height: 29px;
  display: flex;
  align-items: center;
  gap: 7px;
  border: 0;
  background: transparent;
  padding: 0 5px;
  text-align: left;
  cursor: text;
}

.settings-music-input {
  display: none;
  grid-column: 2;
}

.settings-music-row.is-editing .settings-music-summary {
  display: none;
}

.settings-music-row.is-editing .settings-music-input {
  display: block;
}

.settings-main-message {
  grid-column: 1/-1;
  min-height: 12px;
  color: rgba(80,80,80,.7);
}

.settings-panel-head {
  padding-bottom: 7px;
}

/* 시작/검색/날짜/재생목록 팝업은 기존 대비 약 120%, 아이콘 크기는 유지 */

.shortcut-popover {
  /* 시작 메뉴는 한 줄에 아이콘 4개(.shortcut-grid-flat 4열, .shortcut-footer와
     같은 열 수)에 맞춰 폭을 잡는다 — 위 섹션의 검색/날짜 팝업 120% 확대와는
     별개. 열이 부족하면 행이 늘어나 max-height를 넘겨 세로 스크롤이 생기므로,
     70px 고정폭 아이콘 4개+gap+padding이 다 들어갈 만큼 넓힌다(정확히 맞추면
     서브픽셀 반올림으로 가로 스크롤이 생길 수 있어 여유를 둔다). left:8px
     기준 양쪽 8px 여백을 넘지 않도록 좁은 뷰포트에서만 줄어들게 한다. */
  width: min(360px, calc(100vw - 16px));
  padding: 14px;
}

.search-suggest {
  width: 372px;
  max-height: 360px;
  padding: 9px;
  border-radius: 12px;
}

@media (max-width: 680px) {
  .calendar-popover.open {
    overflow: hidden;
  }

  .clock-flyout-calendar,
  .clock-flyout-notifications {
    width: min(324px, calc(100vw - 16px));
  }

}

.shortcut-grid-flat {
  gap: 9px;
}

.shortcut {
  padding: 10px 5px;
}

.shortcut strong {
  margin-top: 6px;
}

.suggest-item {
  padding: 10px;
}

.suggest-item small {
  margin-top: 3px;
}

.mini-week span {
  padding: 5px;
}

.mini-day,
.mini-day.today {
  width: 35px;
  height: 35px;
}
/* 작업표시줄 검색창 래퍼(<label id="searchBox">) */
.start-menu-search {
  height: 38px;
  display: flex;
  gap: 8px;
}

/* 돋보기 글리프는 <g style="fill:currentColor"> 라 stroke만으론 색이 안 바뀐다.
   게다가 .taskbar-scope * 가 그 <g>를 직접 잡아 색을 덮으므로 자손까지 지정한다. */
.start-menu-search.input-text-box svg,
.start-menu-search.input-text-box svg * {
  stroke: var(--area-input-font-color, var(--system-c-area-b-base-font-color)) !important;
  color: var(--area-input-font-color, var(--system-c-area-b-base-font-color)) !important;
}
/* 좁은 화면(모바일 등, 다른 곳과 같은 640px 기준)에서 작업표시줄 검색창 —
   입력칸 실측 243px가 작업표시줄 전체 폭(375px 기기 기준)의 65%를 먹어
   앱 아이콘/시계가 밀려난다. 아이콘만 남기고, 탭하면(기존 searchBox.onclick이
   이미 input을 focus시키므로 별도 JS 없이) :focus-within으로 펼쳐지게
   한다 — 접힌 상태에선 배경/테두리(.start-menu-search.input-text-box의
   System A 배경·테두리 !important 규칙들)도 같이 숨겨 순수 아이콘처럼
   보이게 하고, 펼쳤을 때만 되살린다. #searchBox(id)를 써서 클래스
   조합보다 특이도를 확실히 높게 잡는다 — 아래에서 끄는 배경/테두리
   규칙들이 파일 뒤쪽(!important, 클래스 2개)에 있어 클래스만으로는
   소스 순서상 질 수 있기 때문. */
@media (max-width: 640px) {
  .taskbar #searchBox {
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    /* background만 지워도 .input-text-box 기본의 backdrop-filter:blur(18px)가
       그대로 남아있어 뒤가 뿌옇게 흐려진 사각형이 계속 보였다(요청: "배경이
       남아있는데") — 접힌 상태에선 이것도 꺼야 진짜 아이콘만 남는다. */
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  /* 접힌 검색칸은 다른 작업표시줄 아이콘과 같은 정사각형이어야 한다(요청: 가운데
     아이콘이 중앙에서 벗어남) — 입력칸이 width:0 이 되어도 안쪽 gap(8px)과 좌우
     여백이 남아 돋보기가 칸 가운데서 왼쪽으로 밀렸고, 그래서 검색↔첫 앱 간격만
     12px 넓어 보였다. 펼치면(:focus-within) 원래대로 돌아간다. */
  .taskbar #searchBox:not(:focus-within) {
    width: calc(var(--taskbar-h) * .9);
    padding: 0;
    gap: 0;
    justify-content: center;
  }
  /* width:0 인 입력칸도 좌우 2px 여백은 남아 돋보기를 2px 왼쪽으로 밀었다. */
  .taskbar #searchBox:not(:focus-within) input {
    padding: 0;
  }
  .taskbar #searchBox:not(:focus-within) svg,
  .taskbar #searchBox:not(:focus-within) svg * {
    stroke: var(--system-a-area-a-base-font-color) !important;
    color: var(--system-a-area-a-base-font-color) !important;
  }
  .taskbar #searchBox:focus-within {
    background: rgba(var(--system-a-area-b-base-rgb), var(--system-a-area-b-base-alpha)) !important;
    border-color: rgba(var(--system-a-area-b-base-border-rgb), var(--system-a-area-b-base-border-alpha)) !important;
    backdrop-filter: blur(calc(18px * var(--input-glass, 1))) saturate(calc(1 + .12 * var(--input-glass, 1))) !important;
    -webkit-backdrop-filter: blur(calc(18px * var(--input-glass, 1))) saturate(calc(1 + .12 * var(--input-glass, 1))) !important;
  }
  .taskbar #searchBox input {
    width: 0;
    min-width: 0;
    opacity: 0;
    transition: width .18s ease, opacity .15s ease;
  }
  /* 검색을 누르면 작업표시줄 전체가 검색칸이 된다(요청) — 좁은 화면에선 110px 로
     펼쳐 봐야 글자가 몇 자 안 들어간다. 포커스를 잃으면 그대로 다시 접힌다. */
  .taskbar:has(#searchBox:focus-within) .start-group {
    flex: 1 1 auto;
    min-width: 0;
  }
  .taskbar:has(#searchBox:focus-within) #searchBox {
    flex: 1 1 auto;
    min-width: 0;
  }
  .taskbar #searchBox:focus-within input {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    opacity: 1;
  }
  /* 검색 중에는 가운데 앱 목록과 오른쪽 묶음을 접어 자리를 내준다. */
  .taskbar:has(#searchBox:focus-within) .apps-viewport,
  .taskbar:has(#searchBox:focus-within) .status {
    display: none;
  }

  /* 시계는 달력 아이콘 하나로 줄인다(요청) — 시각·날짜 두 줄이 101px 을 먹어
     가운데 앱 자리를 그만큼 빼앗았다. 알림 뱃지는 그 아이콘 위에 그대로 남는다. */
  .taskbar .clock {
    position: relative;
    width: calc(var(--taskbar-h)*.9);
    height: min(calc(var(--taskbar-h)*.9), var(--taskbar-row-h));
    padding: 0;
    gap: 0;
  }
  .taskbar .clock-datetime {
    display: none;
  }
  .taskbar .clock-calendar {
    display: inline-flex;
  }
  /* 종 아이콘은 감추고 뱃지만 남겨 달력 오른쪽 위에 붙인다. */
  .taskbar .clock-bell {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  .taskbar .clock-bell svg {
    display: none;
  }
  .taskbar .clock-bell-count {
    top: 2px;
    right: 2px;
  }

  /* 좌(시작·검색)·우(볼륨·시계)는 줄어들지 않는다 — 가운데 앱 목록만 남는 폭을
     가져간다(요청). */
  .taskbar .start-group,
  .taskbar .status {
    flex: 0 0 auto;
  }

  /* 아이콘 사이 간격을 전부 같게 한다(요청) — 넓은 화면에서는 묶음마다 값이
     달랐다(작업표시줄 4 / 시작 4 / 우측 1 / 앱 3 + 앱 목록 좌우 안치 3).
     앱 목록의 좌우 안치를 0 으로 두어야 검색칸↔첫 아이콘, 마지막 아이콘↔볼륨도
     같은 간격이 된다. 한 칸 스크롤(scroll-snap)은 "간격 = 안치"를 전제로 하는데,
     둘 다 0/같은 값이면 그대로 성립한다(멈춘 자리에서 직전 칸은 -gap 에 놓인다). */
  .taskbar {
    gap: var(--taskbar-gap, 4px);
  }
  .taskbar .start-group,
  .taskbar .status,
  .taskbar .apps {
    gap: var(--taskbar-gap, 4px);
  }
  .taskbar .apps {
    padding: 0;
    scroll-padding-left: 0;
  }
}
/* 검색창은 영역 B(입력 톤)이므로 placeholder도 영역 B 기본 폰트색을 옅게 쓴다.
   예전엔 var(--system-a-rgb)를 그대로 color에 넣어(=`255,255,255` 같은 숫자 3개)
   선언 자체가 무효였고, 브라우저 기본 placeholder 색이 나오고 있었다. */
.start-menu-search input::placeholder {
  color: rgba(var(--system-a-area-b-base-font-rgb), .5) !important;
}

/* 우측 하단 시스템 메시지 */

.system-message-stack {
  position: fixed;
  right: 14px;
  bottom: calc(var(--taskbar-h) + 12px);
  width: min(320px, calc(100vw - 28px));
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 7px;
  pointer-events: none;
}

/* 창 안 토스트 — 전역 스택(.system-message-stack)과 같은 .system-message
   항목을 쓰되, 그 창 안 오른쪽 아래에 붙는다. 창 하나에서 일어난 일(주소줄
   이동 실패 등)은 화면 구석이 아니라 그 창에서 알려야 어느 창인지 분명하다.
   .window가 position:fixed라 absolute의 기준이 되고, top은 JS가
   scopeWindowOverlay와 같은 방식으로 본문 시작 위치에 맞춘다. */
.window-message-stack {
  position: absolute;
  right: 12px;
  bottom: 12px;
  width: min(320px, calc(100% - 24px));
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 7px;
  pointer-events: none;
  z-index: var(--z-popup);
}

.system-message {
  min-height: 38px;
  display: flex;
  align-items: center;
  padding: 9px 12px;
  border-radius: 9px;
  box-shadow: 0 12px 30px -6px rgba(0,0,0,.16);
  backdrop-filter: blur(18px) saturate(1.12);
  -webkit-backdrop-filter: blur(18px) saturate(1.12);
  line-height: 1.45;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .18s ease, transform .18s ease;
  pointer-events: auto;
  cursor: pointer;
}

.system-message.show {
  opacity: 1;
  transform: translateY(0);
}

/* 토스트 글은 두 줄까지(요청) — 긴 오류 메시지가 화면 구석을 길게 덮지 않게, 넘치면 말줄임. */
.system-message-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* 시스템 컬러: 모달 외곽/상단바(System B) */

.window {
  border-color: rgba(var(--system-b-area-a-base-border-rgb), var(--system-b-area-a-base-border-alpha)) !important;
}

.window-bar {
  border-bottom-color: rgba(var(--system-b-area-a-base-border-rgb), var(--system-b-area-a-base-border-alpha)) !important;
}
/* 시스템 컬러 85%: 작업표시줄/시작메뉴/볼륨/날짜=System A, 그 외 컨텐츠영역=System C */

.taskbar,
.shortcut-popover,
.sound-popover,
.clock-flyout-calendar,
.clock-flyout-notifications,
.search-suggest,
.preview-card,
/* 작업표시줄 아이콘 우클릭 메뉴 — 바로 옆 미리보기 카드와 같은 테마(요청). */
.post-admin-menu.grid-context-menu.task-context-menu {
  background: rgba(var(--system-a-area-a-base-rgb), var(--system-a-area-a-base-alpha)) !important;
}

/* 영역 A 는 "창 바탕" 하나만 담당한다 — 예전엔 그 위에 올라가는 부품 15개가
   같은 색을 같이 써서 창 바탕과 구분이 안 됐다. 성격대로 나눠 준다. */
.window-content {
  background: rgba(var(--system-c-area-a-base-rgb), var(--system-c-area-a-base-alpha)) !important;
  /* 영역 A 자신의 테두리(요청). 전역 *{border-color:영역 B ...!important} 를
     되받아야 하므로 색도 !important 로 준다. */
  border: 1px solid rgba(var(--system-c-area-a-base-border-rgb), var(--system-c-area-a-base-border-alpha)) !important;
  /* 창 안쪽 라운딩(.window의 12px - 테두리 2px)에 맞춰 아래 두 모서리를 깎는다
     — 각진 채로 두면 창이 overflow:hidden 으로 잘라내서 테두리가 모서리에서
     끊겨 보인다. 전체모드는 창 자체가 각지므로(.window.maximized) 같이 편다. */
  border-radius: 0 0 10px 10px;
}
/* 윈도우바가 접혀 있으면(자동 숨김) 위쪽 테두리도 없앤다(요청) — 맞닿을 주소줄이
   사라진 자리라 그 1px 이 화면 맨 위의 선으로만 남는다. */
.window.is-chrome-folded > .window-content {
  border-top-width: 0 !important;
}
.window.maximized .window-content {
  border-radius: 0;
  /* 화면 끝에 닿는 테두리는 1px 흰 선으로만 보인다(요청) — 좌우·아래는 없애고
     주소줄과 맞닿는 위쪽만 남긴다. */
  border-left-width: 0 !important;
  border-right-width: 0 !important;
  border-bottom-width: 0 !important;
}

/* 모바일 우클릭(롱프레스) 메뉴는 화면을 덮는 판이다(요청) — 아래에서 올라와
   손가락이 닿기 쉬운 자리에 크게 선다. 바깥을 누르면 닫히는 규칙은 그대로다. */
.post-admin-menu.grid-context-menu.is-sheet {
  position: fixed;
  left: 0 !important;
  right: 0 !important;
  width: auto !important;
  max-width: none !important;
  top: auto !important;
  /* 작업표시줄은 비켜 주지 않고 화면 바닥에 그대로 붙인다(요청) — 작업표시줄 위에 덮인다.
     !important 는 작업표시줄 아이콘 메뉴 때문이다 — placeAboveTaskButton 이 인라인
     bottom 을 찍어 두면 시트가 그 자리로 끌려간다. */
  bottom: 0 !important;
  max-height: 70vh;
  /* 뒤에 깔리는 막(.grid-context-scrim) 바로 위 — 작업표시줄보다도 위다(요청). */
  z-index: calc(var(--z-dialog) + 1) !important;
  overflow-y: auto;
  /* 손가락으로 세로로 굴릴 수 있게 — 부모(작업표시줄)의 pan-x 를 물려받지 않는다(요청). */
  touch-action: pan-y;
  overscroll-behavior: contain;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom, 0px));
  border-radius: 14px 14px 0 0;
}

/* 시스템 알림도 같다(요청) — 작업표시줄이 내려가 있으면 그 높이를 비켜 줄 이유가 없다.
   좁은 화면에서만: 넓은 화면의 작업표시줄은 늘 자리를 차지한다. */
@media (max-width: 640px) {
  body:not(:has(.taskbar.is-mobile-visible)) .system-message-stack {
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  }
}

/* 시트 메뉴 뒤에 깔리는 막 — 다른 팝업(.confirm-dialog-overlay)과 같은 어둡기(요청). */
.grid-context-scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-dialog);
  background: rgba(0, 0, 0, .35);
}
.post-admin-menu.grid-context-menu.is-sheet .post-admin-menu-item {
  width: 100%;
  flex: 0 0 auto;
  min-height: 44px;
  justify-content: flex-start;
  font-size: 14px;
}

/* 창 바탕 위에 올라가는 패널·카드·썸네일·토스트 = 영역 B 표면 */
.settings-info-row,
.settings-pill,
.menu-admin-icon,
.user-admin-avatar,
.preview-thumb,
.settings-pc-preview,
.system-message,
.server-stats-traffic,
.server-stats-disk, .server-stats-visitors,
.settings-editor-dialog,
.activity-thumb,
.settings-shell.is-nav-small .side-nav {
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
}

/* 입력으로 동작하는 것도 영역 B 를 따른다 — 셀렉트/설정 폼 입력/글 작성기 본문·제목.
   .custom-select-wrap 안의 select 는 제외한다(요청) — enhanceSelect 가 만든
   버튼 뒤에 opacity:0 으로 숨어 있어 어차피 안 보이고, 색만 물고 있었다. */
select:not(.diary-date-select):not(.custom-select-wrap > select),
.settings-form-field input,
.settings-form-field select {
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
}

/* hover 는 영역 B 강조 */
.menu-admin-row: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;
  background-image: none !important;
}

/* System-color surfaces: previous values -0.05 alpha. (윈도우바=System B, 그 외=System C) */

/*.image-area,*/
/*.small-btn,*/
/*.menu-admin-header,*/
/*.user-admin-header,*/
/*.admin-action-button,*/
/*.settings-form-actions button,*/
/*.profile-avatar,*/
/*.close-all,*/
/*.timeline {*/
/*  background: rgba(var(--system-c-area-a-base-rgb), var(--system-c-area-a-base-alpha)) !important;*/
/*}*/

.mini-day.today,
.mini-day.has:after {
  background: var(--focus-color) !important;
  border-color: var(--focus-color) !important;
}
/* 중요(primary) 버튼은 배경·글자만 Focus 를 쓰고 테두리는 전용 값을 따른다(요청). */
.user-primary-button,
.settings-form-actions .primary {
  background: var(--focus-color) !important;
  border: 1px solid rgba(var(--system-c-button-primary-border-rgb), var(--system-c-button-primary-border-alpha)) !important;
}

/* 켜져 있는/활성 메뉴 밑줄은 Focus가 아니라 그 영역의 글자색을 따른다 —
   버튼 자체가 강조 상태(hover/focused)면 강조 글자색으로 같이 넘어간다. */
.app-btn:after {
  background: var(--system-a-area-a-base-font-color) !important;
  border-color: var(--system-a-area-a-base-font-color) !important;
}
.app-btn.sys-a-btn-a:hover:after,
.app-btn.sys-a-btn-a:focus-visible:after,
.app-btn.sys-a-btn-a.focused:after,
.app-btn.sys-a-btn-a.is-menu-open:after,
.app-btn.sys-a-btn-a.open:after {
  background: var(--system-a-area-a-accent-font-color) !important;
  border-color: var(--system-a-area-a-accent-font-color) !important;
}

/* Theme-derived error emphasis. */

.settings-main-message.is-error,
.settings-inline-message.is-error {
  color: var(--focus-color) !important;
}
/* Modal frame: top bar is opaque system;
   content is system @ .75. */

/* Buttons: normal background is opaque system. (윈도우바=System B, 그 외=System C) */

.window-bar,
.preview-thumb .window-bar,
.window-minimize,.window-close{
  background: rgba(var(--system-b-area-a-base-rgb), var(--system-b-area-a-base-alpha)) !important;
}

button:disabled {
  opacity: .55;
  pointer-events: none;
}

.profile-card,.user-auth-panel {
  background: transparent !important;
}

/* Fields with focus use focus border/shadow. */
textarea:hover,textarea:focus {
  border-color: var(--focus-color) !important;
  outline: none !important;
  box-shadow: 0 0 0 2px rgba(var(--focus-rgb),.28) !important;
}
.settings-card-label,.settings-info-value,.settings-music-title,.settings-panel-head strong {
  background: transparent !important;
  border-color: transparent !important;
}

.settings-music-thumb {
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
}

.menu-admin-header,.user-admin-header {
  color: var(--system-c-area-b-base-desc-font-color) !important;
}

.menu-admin-row,.user-admin-row,.settings-log-item,.specific-user-item {
  border-color: rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
}
.settings-music-summary {
  background: transparent !important;
  border-color: transparent !important;
}

/* Form/input fields: no shadow. Focus is expressed with the focus-color border only. */
input,
select,
.settings-inline-input,
.settings-inline-select,
.settings-form-field input,
.settings-form-field select {
  box-shadow: none !important;
}
input:hover,
select:hover,
input:focus,
select:focus,
.settings-inline-input:hover,
.settings-inline-input:focus,
.settings-inline-select:hover,
.settings-inline-select:focus,
.settings-form-field input:hover,
.settings-form-field input:focus,
.settings-form-field select:hover,
.settings-form-field select:focus {
  box-shadow: none !important;
  outline: none !important;
  border-color: var(--focus-color) !important;
}
/* Text selected by dragging follows the focus theme. */
::selection {
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}
::-moz-selection {
  background: var(--focus-color) !important;
  color: var(--focus-font-color) !important;
}
/* Display-settings preview: hover/highlight is intentionally visual-noop. */

/*hover, focus 관리*/

.input-text-box:hover,
.input-text-box:focus,
.input-text-box:focus-within {
  border-color: var(--focus-color) !important;
  box-shadow: inset 0 0 2px 1px var(--focus-color) !important;
}
.content-input-box,
.content-input-box:hover,
.content-input-box:focus,
.content-input-box:focus-within {
  box-sizing: border-box;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
  border-radius: 5px !important;
  outline: none !important;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  color: var(--system-c-area-b-base-font-color) !important;
  box-shadow: none !important;
}
/* 공통 입력 상자 크기 — 프로필·캐릭터·가계부 등 창 본문 어디서나 쓰는
   System C 입력 표면이라 위 테마 규칙과 같이 여기(공통)에 둔다. */
.content-input-box {
  width: 100%;
  min-height: 27px;
  padding: 6px;
}

.content-input-box > input,
.content-input-box > textarea,
.content-input-box > input:hover,
.content-input-box > textarea:hover,
.content-input-box > input:focus,
.content-input-box > textarea:focus {
  background: transparent !important;
  color: inherit !important;
  border-color: transparent !important;
  border-radius: inherit !important;
  outline: none !important;
  box-shadow: none !important;
}
/* 검색창 테두리는 평소에도 System A 입력 테두리 테마를 따른다(.taskbar-scope *의
   표면색 테두리 !important보다 특이도가 높아 이긴다). */
.start-menu-search.input-text-box {
  border-color: rgba(var(--system-a-area-b-base-border-rgb), var(--system-a-area-b-base-border-alpha)) !important;
}
.start-menu-search.input-text-box:hover,
.start-menu-search.input-text-box:focus,
.start-menu-search.input-text-box:focus-within {
  border-color: rgba(var(--system-a-area-b-base-border-rgb), var(--system-a-area-b-base-border-alpha)) !important;
  box-shadow: inset 0 0 2px 1px rgba(var(--system-a-area-b-base-border-rgb), var(--system-a-area-b-base-border-alpha)) !important;
}

/* ==========================================================================
   버튼 상호작용 (docs/click-event-buttons.md 분류 기준)
   - normal-button: 기본 System C content, hover/focus에 System C hover
   - transparent-button: 기본/hover 모두 투명, 글자색은 영역 font-color 고정(커서만 변함)
   - primary-transparent-button: 기본/hover 모두 투명, 글자색 focus-color 고정
   - primary-button: 기본/hover 모두 focus-color 배경 + focus-font-color 글자(변화 없음)
   기본 영역은 System C. 윈도우바는 .area-b를 추가로 붙인다.
   작업표시줄/시작메뉴/날짜/미리보기(System A)는 전용 클래스 sys-a-btn-* 사용 — 아래 참고.
   ========================================================================== */
/* 버튼은 영역 B 를 빌려 쓰지 않고 자기 테마를 갖는다(요청) — 배경은 버튼이라
   항상 불투명(투명도 없음), 테두리만 투명도를 갖는다. hover/focus 의 강조는
   기존대로 영역 B 강조를 그대로 쓴다(그 값은 따로 요청되지 않았다). */
.normal-button {
  background: var(--system-c-button-base-color) !important;
  border: 1px solid rgba(var(--system-c-button-base-border-rgb), var(--system-c-button-base-border-alpha)) !important;
  color: var(--system-c-button-base-font-color) !important;
}
/* hover/focus 는 버튼 강조 테마(요청). 강조 배경은 "덮어쓰기"가 아니라
   기본 배경 위에 강조 투명도만큼 얹는 오버레이다 — 강조 투명도가 100 미만이어도
   버튼 아래가 비쳐 보이면 안 되므로, 기본 배경(불투명)을 바탕으로 color-mix 해
   결과를 background-color 하나로 만든다(영역 A/B 강조와 같은 방식 —
   linear-gradient 를 덧대면 background-image 가 보간 불가라 배경만 즉시 튄다). */
.normal-button:hover,
.normal-button:focus-visible{
  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;
  background-image: none !important;
  color: var(--system-c-button-accent-font-color) !important;
  border-color: rgba(var(--system-c-button-accent-border-rgb), var(--system-c-button-accent-border-alpha)) !important;
}
/* 예전엔 hover 에 inset 그림자(rgb(0 0 0 / 10%))를 얹었는데, 테두리 투명도를
   0으로 놔도 그 그림자가 테두리와 내용 사이에 연한 선처럼 남았다(요청).
   강조 상태는 이제 강조 배경·테두리가 온전히 맡으므로 그림자는 없앤다. */
.normal-button:hover,
.normal-button:focus-visible{
  box-shadow: none !important;
}

/* ==========================================================================
   System A 전용 버튼 — bg/글자/stroke를 버튼 규칙에서 직접 선언하지 말고
   아래 클래스를 붙인다. 작업표시줄 테마는 "영역 × 테마"의 2×2 구조라
   (model/dao/Setting.go), 이 클래스들이 그 네 조합의 표면을 만든다.
   - sys-a-btn-a        : 영역 A. 배경은 투명(작업표시줄 표면이 이미 영역 A
                          배경이라 그 위에 다시 칠하지 않는다) + 영역 A 기본
                          폰트, hover/포커스에 영역 A 강조 테마.
                          .focused(최상단 창 아이콘, JS 부여)도 hover와 동일.
   - sys-a-btn-b        : 영역 B. 기본 테마 표면 + hover/포커스에 영역 B 강조.
   - sys-a-btn-a-static : 기본은 sys-a-btn-a와 동일, hover/focus 변화 없음.

   강조 배경은 기본 배경을 "교체"하지 않고 그 위에 오버레이로 합성한다
   (linear-gradient 한 겹 + 아래에 기본색) — 강조 투명도가 100 미만이어도
   영역 아래 바탕화면이 비쳐 보이면 안 되기 때문. System C의 .grid-cell:hover /
   .normal-button:hover 가 쓰는 것과 같은 방식이다.
   ========================================================================== */

/* 작업표시줄 구성요소는 전부 실선 테두리 골격을 갖는다 — 색/투명도는 테마가
   정하고, 여기서는 "테두리를 그릴 자리"만 확보한다. 예전에는 대부분
   border:0 이라 테마에서 테두리 색을 지정해도 그릴 곳이 없어 보이지 않았다.
   box-sizing:border-box가 전역(common.css)이라 1px이 늘어도 크기는 그대로다.
   패널(팝오버/카드)은 조금 더 뚜렷하게 2px. */
.taskbar .task-square,
.taskbar .app-btn,
.taskbar .status-btn,
.taskbar .clock,
.start-menu-search.input-text-box,
.shortcut,
.shortcut-space-info,
.gallery-power-button,
.space-switcher-row,
.suggest-item,
.mini-day,
.notification-item,
.notification-clear-all,
.notification-settings-toggle,
.notification-settings-back,
.notification-item-actions,
.notification-item-delete,
.preview-item,
.close-all,
#calPrev,
#calNext,
#calDayListClose {
  border-width: 1px !important;
  border-style: solid !important;
}

/* 알림 항목의 버튼 줄 — 원래 위 "테두리 골격" 선택자 목록 한가운데에 이 규칙이
   끼어 있어서 목록이 거기서 끊겼다. 그 바람에 작업표시줄 버튼들(.task-square /
   .app-btn / .status-btn / .clock / 검색칸 …)이 display:flex + margin-top:6px 를
   같이 받아, 아이콘이 버튼 가운데가 아니라 왼쪽에 붙고 6px 아래로 내려갔다. */
.notification-item-actions { display: flex; gap: 6px; margin-top: 6px; }

.shortcut-popover,
.search-suggest,
.sound-popover,
.clock-flyout-calendar,
.clock-flyout-notifications,
.preview-card {
  border-width: 2px !important;
  border-style: solid !important;
}

/* 폴더 팝오버(homepage.ui.js openFolderPopover)는 .shortcut-popover 클래스를
   테마 배경/테두리만 빌려 쓰려던 것인데, 그 클래스가 같이 주는
   bottom:calc(...)(위 .shortcut-popover,.calendar-popover,.sound-popover 규칙)와
   폭 360px(위 .shortcut-popover 규칙)까지 그대로 얹힌다. openFolderPopover는
   버튼 바로 아래(top)에 붙이는데 거기에 bottom까지 같이 걸리면 top~작업표시줄
   바로 위까지 세로로 쭉 늘어나는 빈 상자가 되고(요청 "폴더 기능 오동작"),
   가로도 실제 자식 아이콘 수와 상관없이 시작메뉴 전체 폭 그대로 남는다 —
   여기서 그 둘만 내용에 맞게 되돌린다. */
.folder-popover {
  bottom: auto;
  width: max-content;
}

/* 스페이스 전환 목록(.space-switcher-popover)도 같은 이유로 위
   .shortcut-popover 폭 규칙(360px)에 앞의 300px 지정이 도로 덮인다 —
   원래 의도한 300px을 여기서 되돌린다(요청: 스페이스 리스트 폭 줄이기). */
.space-switcher-popover {
  width: min(300px, calc(100vw - 16px));
}

/* 작업표시줄 바 위의 버튼(시작 ✦ / 볼륨 / 시계 / 앱)은 기본 상태에서 배경도
   테두리도 그리지 않는다 — 바 자체가 이미 영역 A 표면이라 그 위에 같은 색을
   또 칠하면 아이콘만 떠 보이기 때문(요청). 배경·테두리는 강조 테마에서만 나온다.
   같은 클래스를 쓰는 다른 영역 A 항목(바로가기/자동완성/날짜 칸)은 아래
   "영역 A 항목 표면" 블록이 기본 표면을 따로 칠한다. */
/* 강조 배경을 "기본색 위에 강조색을 얹은 결과"로 만들되, 그 결과가 배경색
   한 개여야 한다 — 예전엔 linear-gradient 한 겹을 덧대 합성했는데
   background-image 는 CSS 명세상 discrete(보간 불가)라 배경만 즉시 튀고
   테두리·글자만 0.2s에 걸쳐 바뀌는 어긋남이 생겼다.
   color-mix 로 미리 합성하면 결과가 background-color 하나라 전역 transition
   목록에 이미 들어 있어 나머지와 같은 속도로 함께 움직인다.
   불투명한 강조색을 강조 투명도(%)만큼 섞으면 결과 알파가
   αa + αb(1-αa) 로 src-over 합성과 정확히 같아진다 — 즉 강조 투명도가
   100 미만이어도 기본 배경이 아래에 그대로 남는다. */
.sys-a-btn-a,
.sys-a-btn-a-static {
  background-color: transparent !important;
  background-image: none !important;
  border-color: transparent !important;
  color: var(--system-a-area-a-base-font-color) !important;
}
/* 아이콘은 마크업에서 fill/stroke를 currentColor로 두므로, svg와 그 자손의
   color를 영역 폰트색에 맞추면 채움형·선형 아이콘이 모두 따라온다.
   자손까지 짚는 이유: `.taskbar-scope *`(전역 System A 폰트색)가 svg/g를
   "직접" 매치해 기본 폰트색으로 고정해 버려, 버튼이 강조 상태여도
   currentColor가 기본색으로 풀린다(상속은 직접 매치를 못 이긴다).
   stroke를 자손까지 !important로 밀면 안 된다 — 채움형 아이콘의 인라인
   stroke:none 을 덮어써서 윤곽선이 덧그려진다. color만 짚는다. */
.sys-a-btn-a svg,
.sys-a-btn-a svg *,
.sys-a-btn-a-static svg,
.sys-a-btn-a-static svg * {
  color: var(--system-a-area-a-base-font-color) !important;
}
.sys-a-btn-a svg,
.sys-a-btn-a-static svg {
  stroke: var(--system-a-area-a-base-font-color);
}
.sys-a-btn-b {
  background-color: rgba(var(--system-a-area-b-base-rgb), var(--system-a-area-b-base-alpha)) !important;
  background-image: none !important;
  border: 1px solid rgba(var(--system-a-area-b-base-border-rgb), var(--system-a-area-b-base-border-alpha)) !important;
  color: var(--system-a-area-b-base-font-color) !important;
}
.sys-a-btn-b * {
  color: var(--system-a-area-b-base-font-color) !important;
}
.sys-a-btn-b svg,
.sys-a-btn-b svg * {
  color: var(--system-a-area-b-base-font-color) !important;
}
/* 영역 B 강조 — 기본 표면 위에 강조색을 겹친다. */
.sys-a-btn-b:hover,
.sys-a-btn-b:focus-visible {
  background-color: color-mix(in srgb, var(--system-a-area-b-accent-color) calc(var(--system-a-area-b-accent-alpha) * 100%), rgba(var(--system-a-area-b-base-rgb), var(--system-a-area-b-base-alpha))) !important;
  background-image: none !important;
  border-color: rgba(var(--system-a-area-b-accent-border-rgb), var(--system-a-area-b-accent-border-alpha)) !important;
  color: var(--system-a-area-b-accent-font-color) !important;
}
/* 안에 든 버튼(.primary-button/.normal-button)은 영역 색을 빌리지 않고 자기
   테마를 쓴다 — 여기서 `*` 로 덮으면 특이도가 버튼 규칙보다 높아, 알림에 hover
   했을 때 [수락]의 글자색이 배경(Focus 색)과 같아져 글자가 사라졌다. */
.sys-a-btn-b:hover *:not(.primary-button, .primary-button *, .normal-button, .normal-button *),
.sys-a-btn-b:focus-visible *:not(.primary-button, .primary-button *, .normal-button, .normal-button *) {
  color: var(--system-a-area-b-accent-font-color) !important;
}
.sys-a-btn-b:hover svg:not(.primary-button, .primary-button *, .normal-button, .normal-button *),
.sys-a-btn-b:hover svg *:not(.primary-button, .primary-button *, .normal-button, .normal-button *),
.sys-a-btn-b:focus-visible svg:not(.primary-button, .primary-button *, .normal-button, .normal-button *),
.sys-a-btn-b:focus-visible svg *:not(.primary-button, .primary-button *, .normal-button, .normal-button *) {
  color: var(--system-a-area-b-accent-font-color) !important;
}

/* ==========================================================================
   영역 배정 — 어느 구성요소가 영역 A/B를 따르는지.

   .sys-a-btn-a 가 붙은 요소는 배정이 A든 B든 겉모양 규칙이 같다:
     기본  — 배경 투명 · 테두리 투명 · 글자는 그 영역의 "기본" 폰트
     강조  — 그 영역의 "강조" 테마(배경 오버레이 + 폰트 + 테두리)
   즉 영역이 정하는 건 "어느 쪽 값을 읽는가"뿐이고, 기본 상태에서 표면을
   칠하지 않는다는 점은 공통이다. 그래서 영역 A 항목(바로가기/자동완성 항목/
   달력 날짜 칸·월 이동)은 .sys-a-btn-a 기본 동작이 그대로 정답이라 여기서
   따로 덮을 게 없다 — 아래 블록은 "값을 B에서 읽어야 하는" 요소만 다룬다.

   클래스명을 바꾸면 homepage.js/homepage.ui.js/템플릿의 마크업을 여러 곳
   고쳐야 해서, 배정은 선택자로만 한다.
   ========================================================================== */

/* 영역 B 값을 읽는 버튼 — 시작메뉴 하단 바의 스페이스 위젯·전원 버튼,
   스페이스 전환 행, 창 미리보기 항목, 알림 삭제 버튼.
   배경·테두리는 .sys-a-btn-a 의 투명을 그대로 두고 글자색만 B로 바꾼다.
   마크업상 .sys-a-btn-a(영역 A)가 붙어 있어 같은 특이도로는 순서에 기대야
   하므로, 클래스를 함께 짚어 특이도를 한 단계 올려 확실히 이긴다. */
.shortcut-space-info.sys-a-btn-a,
.gallery-power-button.sys-a-btn-a,
.preview-item.sys-a-btn-a,
.notification-item-actions { display: flex; gap: 6px; margin-top: 6px; }
.notification-item-delete.sys-a-btn-a-static {
  color: var(--system-a-area-b-base-font-color) !important;
}
.shortcut-space-info.sys-a-btn-a :is(strong, small, span),
.preview-item.sys-a-btn-a :is(strong, small, span) {
  color: var(--system-a-area-b-base-font-color) !important;
}
.shortcut-space-info.sys-a-btn-a svg,
.gallery-power-button.sys-a-btn-a svg,
.preview-item.sys-a-btn-a svg,
.notification-item-delete.sys-a-btn-a-static svg {
  color: var(--system-a-area-b-base-font-color) !important;
}
/* 위 항목들의 강조도 영역 B — 기본 표면 위에 강조색을 겹친다. */
.shortcut-space-info.sys-a-btn-a:hover,
.shortcut-space-info.sys-a-btn-a:focus-visible,
.gallery-power-button.sys-a-btn-a:hover,
.gallery-power-button.sys-a-btn-a:focus-visible,
.preview-item.sys-a-btn-a:hover,
.preview-item.sys-a-btn-a:focus-visible {
  background-color: color-mix(in srgb, var(--system-a-area-b-accent-color) calc(var(--system-a-area-b-accent-alpha) * 100%), rgba(var(--system-a-area-b-base-rgb), var(--system-a-area-b-base-alpha))) !important;
  background-image: none !important;
  border-color: rgba(var(--system-a-area-b-accent-border-rgb), var(--system-a-area-b-accent-border-alpha)) !important;
  color: var(--system-a-area-b-accent-font-color) !important;
}
.shortcut-space-info.sys-a-btn-a:hover :is(strong, small, span),
.preview-item.sys-a-btn-a:hover :is(strong, small, span) {
  color: var(--system-a-area-b-accent-font-color) !important;
}
.shortcut-space-info.sys-a-btn-a:hover svg,
.gallery-power-button.sys-a-btn-a:hover svg,
.preview-item.sys-a-btn-a:hover svg {
  color: var(--system-a-area-b-accent-font-color) !important;
}

.sys-a-btn-a:hover,
.sys-a-btn-a:focus-visible,
.sys-a-btn-a.focused,
/* 그 버튼이 연 것이 떠 있는 동안은 hover 와 같은 모습으로 둔다(요청) —
   .is-menu-open 은 작업표시줄 아이콘 우클릭 메뉴, .open 은 시작메뉴·볼륨·시계
   팝업(세 버튼 모두 homepage.js 가 자기 자신에 .open 을 토글한다). */
.sys-a-btn-a.is-menu-open,
.sys-a-btn-a.open {
  /* 강조색을 "뒤에 이미 깔린 것"(작업표시줄·팝오버의 영역 A 표면) 위에 그대로
     얹는다. 예전엔 여기서 기본 배경을 바탕으로 color-mix 했는데, 이 버튼의 평소
     배경은 transparent 라 그게 같은 색을 두 번 칠하는 꼴이었다 — 강조 투명도가
     0이면 "기본 배경 그대로"가 남아 투명해야 할 자리에 흰 덩어리가 생겼다. */
  background-color: rgba(var(--system-a-area-a-accent-rgb), var(--system-a-area-a-accent-alpha)) !important;
  background-image: none !important;
  color: var(--system-a-area-a-accent-font-color) !important;
  border-color: rgba(var(--system-a-area-a-accent-border-rgb), var(--system-a-area-a-accent-border-alpha)) !important;
}
.sys-a-btn-a.is-menu-open svg,
.sys-a-btn-a.is-menu-open svg *,
.sys-a-btn-a.open svg,
.sys-a-btn-a.open svg *,
.sys-a-btn-a:hover svg,
.sys-a-btn-a:hover svg *,
.sys-a-btn-a:focus-visible svg,
.sys-a-btn-a:focus-visible svg *,
.sys-a-btn-a.focused svg,
.sys-a-btn-a.focused svg * {
  color: var(--system-a-area-a-accent-font-color) !important;
}
.sys-a-btn-a:hover svg,
.sys-a-btn-a:focus-visible svg,
.sys-a-btn-a.focused svg {
  stroke: var(--system-a-area-a-accent-font-color) !important;
}
.sys-a-btn-a:hover :is(small, strong, span),
.sys-a-btn-a:focus-visible :is(small, strong, span),
.sys-a-btn-a.focused :is(small, strong, span) {
  color: var(--system-a-area-a-accent-font-color) !important;
}
/* 알림 개수 뱃지는 Focus 색 배경 위에 얹혀 있어, 시계 버튼 hover 시 위 span
   규칙(System A hover 글자색)을 따라가면 배경에 묻혀 안 보인다 — Focus 글자색 유지. */
.sys-a-btn-a:hover .clock-bell-count,
.sys-a-btn-a:focus-visible .clock-bell-count,
.sys-a-btn-a.focused .clock-bell-count {
  color: var(--focus-font-color) !important;
}
/* 오늘 날짜 셀은 Focus 색 배경(공용 규칙) 위에 놓이므로 글자는 Focus-font 색.
   hover만 작업표시줄 강조색(위 규칙). */
.mini-day.today:not(:hover) {
  color: var(--focus-font-color) !important;
}
.transparent-button,
.primary-transparent-button,
.primary-button {
  box-shadow: none !important;
}
.transparent-button {
  background: transparent !important;
  border-color: transparent !important;
  color: var(--system-c-area-b-base-font-color) !important;
}
.transparent-button.area-b {
  color: var(--system-b-area-a-base-font-color) !important;
}
.transparent-button:hover,
.transparent-button:focus,
.transparent-button:focus-within {
  background: transparent !important;
  box-shadow: none !important;
  text-decoration: none;
}

.primary-transparent-button {
  background: transparent !important;
  border-color: transparent !important;
  color: var(--focus-color) !important;
}
.primary-transparent-button * {
  color: var(--focus-color) !important;
}
.primary-transparent-button:hover,
.primary-transparent-button:focus,
.primary-transparent-button:focus-within {
  background: transparent !important;
  box-shadow: none !important;
  color: var(--focus-color) !important;
}

.primary-button {
  background: var(--focus-color) !important;
  /* 테두리만 전용 값(요청) — 배경·글자는 Focus 그대로. */
  border: 1px solid rgba(var(--system-c-button-primary-border-rgb), var(--system-c-button-primary-border-alpha)) !important;
  color: var(--focus-font-color) !important;
}
.primary-button:hover,
.primary-button:focus,
.primary-button:focus-within {
  background: var(--focus-color) !important;
  border: 1px solid rgba(var(--system-c-button-primary-border-rgb), var(--system-c-button-primary-border-alpha)) !important;
  color: var(--focus-font-color) !important;
  box-shadow: none !important;
}

/* 작업표시줄 검색창 테마는 검색창에만 적용한다. 다른 System A 컨트롤은
   sys-a-btn-* 클래스를 그대로 쓴다. */
.start-menu-search.input-text-box {
  --area-input-rgb: var(--system-a-area-b-base-rgb);
  --area-input-alpha: var(--system-a-area-b-base-alpha);
  --area-input-font-color: var(--system-a-area-b-base-font-color);
  --area-input-border-rgb: var(--system-a-area-b-base-border-rgb);
  --area-input-border-alpha: var(--system-a-area-b-base-border-alpha);
}
:where(.window-bar, .area-b) {
  --area-input-rgb: var(--system-b-area-b-base-rgb);
  --area-input-alpha: var(--system-b-area-b-base-alpha);
  --area-input-font-color: var(--system-b-area-b-base-font-color);
  --area-input-border-rgb: var(--system-b-area-b-base-border-rgb);
  --area-input-border-alpha: var(--system-b-area-b-base-border-alpha);
}
.input-text-box,
/* data-no-theme 은 이 광역 테마에서 빠지겠다는 표식이다 — textarea 쪽엔
   원래 있었는데 input 에는 빠져 있어, 같은 표식을 달아도 input 만 계속
   입력 테마 색이 씌워졌다(이 선택자는 :not(#searchInput) 때문에 특이도가
   (1,7,1) 이라 클래스로는 못 이긴다). */
input:not([data-no-theme]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not(#searchInput):not(.window-bar-search-input):not(.window-address-input):not(.auth-input):not(.input-text-box *),
select:not([data-no-theme]):not(.input-text-box *):not(.custom-select-wrap > select),
textarea:not([data-no-theme]):not(.input-text-box *),
[contenteditable="true"]:not([data-no-theme]) {
  background: rgba(var(--area-input-rgb, var(--system-c-area-b-base-rgb)), var(--area-input-alpha, var(--system-c-area-b-base-alpha))) !important;
  color: var(--area-input-font-color, var(--system-c-area-b-base-font-color)) !important;
  border-color: rgba(var(--area-input-border-rgb, var(--system-c-area-b-base-border-rgb)), var(--area-input-border-alpha, var(--system-c-area-b-base-border-alpha))) !important;
}
:is(.window-more-panel, .post-admin-menu.window-more-dropdown, .post-visibility-dropdown) button {
  background: transparent !important;
}
/* 이 패널들의 표면은 윈도우바 "영역 A"다(아래 배경 규칙) — 그 위의 항목도
   같은 영역을 따라야 한다(요청). 예전엔 글자·hover 만 영역 B 를 써서, 영역 B
   배경 투명도가 낮은 테마에선 hover 가 거의 보이지 않았다. */
:is(.window-more-panel, .post-admin-menu.window-more-dropdown, .post-visibility-dropdown) :is(button, .post-admin-menu-item),
:is(.window-more-panel, .post-admin-menu.window-more-dropdown, .post-visibility-dropdown) :is(button, .post-admin-menu-item) * {
  color: var(--system-b-area-a-base-font-color) !important;
}
/* 패널 안의 삭제는 다른 항목과 같은 보통 버튼이다 — .small-btn.danger 의 Focus
   색 테두리(0,2,0)가 .post-admin-menu-item 의 transparent(0,1,0)를 이겨 목록
   한가운데 한 줄만 튀었다. 글자색·hover는 위아래 영역 B 규칙이 이미 잡는다. */
:is(.window-more-panel, .post-admin-menu, .post-visibility-dropdown) .small-btn.danger {
  border-color: transparent !important;
}
/* 강조(hover/포커스)도 같은 영역 A 를 따른다(요청). 항목의 평소 배경은
   transparent 라(위 규칙) 강조색을 패널 위에 그대로 얹는다 — 기본 배경을
   바탕으로 섞으면 강조 투명도가 0일 때 패널 색이 한 겹 더 칠해진다. */
:is(.window-more-panel, .post-admin-menu.window-more-dropdown, .post-visibility-dropdown) button:not(:disabled):is(:hover, :focus-visible) {
  background-color: rgba(var(--system-b-area-a-accent-rgb), var(--system-b-area-a-accent-alpha)) !important;
  background-image: none !important;
  border-color: rgba(var(--system-b-area-a-accent-border-rgb), var(--system-b-area-a-accent-border-alpha)) !important;
  color: var(--system-b-area-a-accent-font-color) !important;
}
:is(.window-more-panel, .post-admin-menu.window-more-dropdown, .post-visibility-dropdown) button:not(:disabled):is(:hover, :focus-visible) * {
  color: var(--system-b-area-a-accent-font-color) !important;
}
:is(.window-bar, .window-toolbar, .window-more-panel, .post-admin-menu.window-more-dropdown, .post-visibility-dropdown) button:is(:hover, :focus, :focus-visible, :focus-within) {
  box-shadow: none !important;
}

/* ==========================================================================
   윈도우바 테두리 골격 — 색/투명도는 테마가 정하고, 여기서는 "테두리를 그릴
   자리"만 확보한다. 대부분 border:0 이라 테마에서 테두리 색을 지정해도
   그릴 곳이 없었다(작업표시줄과 같은 처리). box-sizing:border-box가
   전역(common.css)이라 1px이 늘어도 크기는 그대로다.
   ========================================================================== */
.window-minimize,
.window-close,
.window-address-button,
.window-post-like,
.window-address-suggest-item,
.post-admin-menu-item,
.post-visibility-option,
.window-more-panel-close,
.window-bar-search-input {
  border-width: 1px !important;
  border-style: solid !important;
}

/* 아이콘은 fill/stroke를 currentColor로 두므로 svg와 그 자손의 color만
   영역 폰트색에 맞추면 채움형·선형 아이콘이 모두 따라온다. 자손까지 짚는
   이유는 작업표시줄과 같다 — `.window-bar *` / `.window-toolbar *` 같은
   광역 color 규칙이 svg/g를 "직접" 매치해 버려, 상속만으로는 강조 상태에서
   currentColor가 기본색으로 풀린다. stroke를 자손까지 !important로 밀면
   채움형 아이콘의 인라인 stroke:none을 덮어써 윤곽선이 덧그려지므로 안 된다. */
.window-bar svg,
.window-bar svg *,
.window-toolbar > .window-address-controls svg,
.window-toolbar > .window-address-controls svg *,
.window-more-menu > [data-window-more-toggle] svg,
.window-more-menu > [data-window-more-toggle] svg * {
  color: var(--system-b-area-a-base-font-color) !important;
}
.window-address-field svg,
.window-address-field svg *,
.window-address-suggest svg,
.window-address-suggest svg *,
.window-more-panel svg,
.window-more-panel svg *,
.post-admin-menu.window-more-dropdown svg,
.post-admin-menu.window-more-dropdown svg *,
.post-visibility-dropdown svg,
.post-visibility-dropdown svg * {
  color: var(--system-b-area-b-base-font-color) !important;
}

/* 버튼·항목의 기본 테두리는 투명이다 — 표면(제목줄/주소줄/메뉴 패널)이 이미
   그 영역 색이라, 그 위에 또 테두리를 두르면 칸막이처럼 보인다. 테두리는
   강조 상태에서만 나온다(작업표시줄 .sys-a-btn-a와 같은 규칙).
   패널·입력 필드(.window-address-field/.window-address-suggest/
   .post-admin-menu 등)는 여기 해당 없음 — 자기 영역 테두리를 그대로 그린다. */
.window-minimize,
.window-close,
.window-address-button,
.window-post-like,
.window-address-suggest-item,
.post-admin-menu-item,
.post-visibility-option,
.window-more-panel-close {
  border-color: transparent !important;
}

/* ==========================================================================
   영역 A 강조 — 제목줄/주소줄 표면 위의 버튼(최소화·닫기·뒤로·새로고침·⋯).
   예전 System B 에는 일반 hover 세트가 아예 없어(입력 hover 하나뿐) 이
   버튼들은 hover 시 아무 변화가 없었다. 2×2로 오면서 영역 A 강조가 생겼다.
   강조 배경은 기본 배경 위에 color-mix 로 미리 합성한다 — 결과가
   background-color 한 개라 전역 transition 목록에 이미 들어 있어 테두리·글자와
   같은 속도로 함께 움직이고, 강조 투명도가 100 미만이어도 창 뒤가 비치지 않는다.
   ========================================================================== */
.window-bar .window-minimize:hover,
.window-bar .window-minimize:focus-visible,
.window-bar .window-close:hover,
.window-bar .window-close:focus-visible,
.window-toolbar .window-address-button:not(:disabled):hover,
.window-toolbar .window-address-button:not(:disabled):focus-visible {
  background-color: color-mix(in srgb, var(--system-b-area-a-accent-color) calc(var(--system-b-area-a-accent-alpha) * 100%), rgba(var(--system-b-area-a-base-rgb), var(--system-b-area-a-base-alpha))) !important;
  background-image: none !important;
  border-color: rgba(var(--system-b-area-a-accent-border-rgb), var(--system-b-area-a-accent-border-alpha)) !important;
  color: var(--system-b-area-a-accent-font-color) !important;
}
/* 아이콘은 fill/stroke가 currentColor라 color만 짚으면 채움형·선형 모두 따라온다
   (System A와 같은 이유 — 상위의 광역 color 규칙이 svg/g를 직접 잡기 때문에
   자손까지 명시해야 한다). stroke를 자손까지 밀면 채움형 아이콘에 윤곽선이
   덧그려지므로 color만 짚는다. */
.window-bar .window-minimize:hover svg, .window-bar .window-minimize:hover svg *,
.window-bar .window-close:hover svg, .window-bar .window-close:hover svg *,
.window-toolbar .window-address-button:not(:disabled):hover svg,
.window-toolbar .window-address-button:not(:disabled):hover svg * {
  color: var(--system-b-area-a-accent-font-color) !important;
}
/* label.input-text-box처럼 실제 input을 감싸는 필드는 배경/테두리를 래퍼에 한 번만 그린다. */
.input-text-box > input:not([type="range"]):not([type="color"]):not([type="file"]):not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
.input-text-box > select:not([data-no-theme]),
.input-text-box > textarea:not([data-no-theme]) {
  background: transparent !important;
  color: inherit !important;
  border-color: transparent !important;
}
/* System C 안에서 별도 카드/본문으로 읽히는 표면은 컨텐츠 배경을 공유한다. */
/* 댓글 항목은 컨텐츠 영역 위에 얹힌 카드가 아니라 그 영역이 차례로 보여주는
   한 줄이다(요청) — 표면도 사방 테두리도 갖지 않는다. 다만 강조 포커스를
   위해 왼쪽 테두리 자리만 투명으로 들고 있다가, 강조될 때 그 앞선만 켠다
   (자리를 미리 잡아둬야 강조 순간에 글자가 밀리지 않는다). */
.comment {
  background: transparent !important;
  border: 0 !important;
  border-left: 2px solid transparent !important;
}
.focus-border {
  border-color: var(--focus-color) !important;
}
.focus-font {
  color: var(--focus-color) !important;
  stroke: var(--focus-color) !important;
}

.post-meta {
  margin-bottom: 16px;
  text-align: right;
}

/*임시*/

/* 썸네일·포스터가 없는 카드의 빈 자리 — 그림/영화/유튜브 목록이 공통으로 쓰는
   빈 <div class="... image-area"> 다. 여태 스타일이 없어 흰 여백만 크게 남았는데,
   포스터가 없는 영화가 많으면 화면이 통째로 비어 보였다. 영역 B 표면+테두리로
   "빈 자리"임을 읽히게 하고, 가운데에 사진 글리프를 CSS 로 그린다(마크업은
   빈 div 그대로라 세 목록에 한 번에 적용된다). */
.image-area {
  position: relative;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  border: 0 !important;
  overflow: hidden;
}

/* 사진 글리프 — 크기를 px 로 고정한 정사각형이라, 16:9(그림)든 2:3(영화 포스터)든
   같은 모양·같은 크기로 보인다. 예전엔 CSS 도형을 %로 그려서 상자 비율에 따라
   찌그러졌다(요청). mask 로 얹었기 때문에 색은 아래 background 가 정하고,
   그래서 영역 B 설명 폰트색을 그대로 따른다. */
.image-area::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 38px;
  height: 38px;
  transform: translate(-50%, -50%);
  background: var(--system-c-area-b-base-desc-font-color);
  opacity: .4;
  -webkit-mask: url("/static/icons/image-placeholder.svg") center / contain no-repeat;
  mask: url("/static/icons/image-placeholder.svg") center / contain no-repeat;
}

/* 상세 meta 줄 왼쪽의 "‹ 제목"(요청) — ‹ 를 누르면 목록으로 돌아간다.
   meta(날짜·조회수…)는 오른쪽 끝에 그대로 남는다. */
.post-meta.has-back-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.post-back-title {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.post-back-title-text {
  font-weight: 700;
  color: var(--system-c-area-b-base-font-color) !important;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ‹ 버튼 — 주소줄 뒤로가기와 같은 크기감의 아이콘 버튼. */
.post-back-btn {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0 !important;
  background: transparent !important;
  color: var(--system-c-area-b-base-desc-font-color) !important;
  cursor: pointer;
  line-height: 1;
}

.post-back-btn:hover {
  color: var(--system-c-area-b-base-font-color) !important;
}

.post-thumb-wrap {
  position: relative;
}

.post-thumb {
  width: 100%;
  aspect-ratio: 16/9;
  border-radius: 7px;
  box-shadow: 1px 1px 3px 0px rgba(0, 0, 0, .15);
  /* 썸네일이 지정된 카드는 <img>로 렌더링된다(비어있으면 여전히 배경만 채우는
     .image-area 빈 <div>) — 크롭 자체가 이미 16:9라 cover는 안전망일 뿐이다. */
  object-fit: cover;
  display: block;
}

/* 썸네일 우측 하단 배지 줄 — Live2D 배지가 있으면 장수 배지 왼쪽에 나란히
   붙는다(요청). 배지 폭이 글자 수에 따라 달라져 각자 좌표를 잡으면 어긋나므로,
   줄 하나를 우측 하단에 고정하고 그 안에서 나열한다. */
.post-thumb-badges {
  position: absolute;
  right: 6px;
  bottom: 6px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  pointer-events: none;
}

/* "이미지 N개" 배지(본문 이미지가 1장 이상일 때만 렌더링됨). */
.post-thumb-image-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  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)) !important;
  color: var(--system-c-area-b-base-font-color);
  pointer-events: none;
}

.post-thumb-image-badge-icon {
  width: 11px;
  height: 11px;
  /* imageCountIconHTML()의 svg/rect/circle/path엔 fill 속성이 없어 SVG 기본값인
     검정 채우기로 그려지고 있었다 — 배지 글자색(--system-b-area-a-base-font-color)을 직접
     선 색으로 지정한다. !important: homepage.css의 전역 `* { color: ... }`류
     리셋(다른 곳의 stroke/색 규칙들이 !important를 쓰는 것과 같은 이유)보다
     우선해야 한다. */
  fill: none;
  stroke: var(--system-c-area-b-base-font-color) !important;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.post-thumb-live2d-badge {
  padding: 2px 6px;
  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)) !important;
  color: var(--system-c-area-b-base-font-color);
  pointer-events: none;
}

.post-title {
  font-weight: 700;
  margin-top: 7px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.movie-poster {
  width: 100%;
  aspect-ratio: 2/3;
  border-radius: 7px;
}

.movie-card-title {
  font-weight: 700;
  margin-top: 7px;
}

.movie-card-rating {
  display: flex;
  align-items: center;
  margin-top: 4px;
}

.movie-card-rating .movie-star-rating-score {
  display: none;
}

.movie-detail-poster {
  width: 100%;
  aspect-ratio: 2/3;
  border-radius: 8px;
  box-shadow: 0 -4px 7px -4px rgba(var(--system-c-area-b-base-font-rgb), .18);
}

/* 영화 상세는 포스터+정보 2단이라 더 넓은 하한이 따로 필요하다. */
.movie-detail-window {
  min-width: min(550px, 100vw);
}

/* 댓글이 붙는 창의 하한은 위 .post-detail-window 와 같은 근거(댓글 헤드 한 줄).
   여기 값이 더 크면 상세 창을 아무리 줄여도 이 값에서 멈춘다. */
.comment-window {
  min-width: min(400px, calc(100vw - 4px));
}

/* 댓글 입력줄 아래 여백은 창 기본 padding(14px)이라 본문↔댓글 사이(8px)보다
   넓어 바닥이 허전했다 — 같은 간격으로 맞춘다(요청). */
.comment-window .window-content {
  padding-bottom: 8px;
}

/* 영화 등록·상세 정보블록은 포스터 + 오른쪽 4행 구조와 외곽 스타일을 공유한다. */
.movie-editor-head,
.movie-detail-info {
  display: grid;
  grid-template-columns: 120px 1fr;
  align-items: stretch;
  gap: 16px;
  margin-bottom: 16px;
  padding-bottom: 15px;
  box-shadow: 0 4px 5px -5px rgba(var(--system-c-area-b-base-font-rgb), .18);
}

.movie-editor-head {
  border-bottom: 0;
}

.movie-editor-head-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-bottom: 16px;
}

/* 공개범위 select·대상 선택·등록(수정 완료)의 높이를 맞춘다(요청) — select 는
   버튼 라벨이 position:absolute 라 자기 내용으로 높이를 못 얻고, 버튼들은
   .small-btn 기본 높이(27px)를 써서 제각각이었다. 그림 에디터는 한 줄짜리
   .post-editor-head 규칙이 같은 일을 하는데, 영화는 이 줄이 헤드 밖이라
   그 규칙이 닿지 않았다. */
.movie-editor-head-actions > *,
.movie-editor-head-actions > .small-btn {
  height: 33px;
}

/* 포스터 자리 — 배너 사진과 같은 방식(요청). 그리드 칸은 이 region 이 갖고,
   안에서 포스터 버튼과 "삭제" 오버레이가 겹친다(버튼 안에 버튼을 넣을 수 없다).
   align-self:start 라야 행 높이만큼 늘어나지 않고 2:3 비율을 지킨다. */
.movie-editor-poster-region {
  grid-row: 1;
  grid-column: 1;
  align-self: start;
  position: relative;
  display: block;
  width: 120px;
}

.movie-editor-poster {
  width: 100%;
  aspect-ratio: 2/3;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0;
  box-sizing: border-box;
  position: relative;
  overflow: hidden;
  border: 0;
  color: var(--system-c-area-b-base-font-color);
  font-size: 11px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
}

.movie-editor-poster-empty {
  padding: 8px;
}

.movie-editor-poster {
  cursor: pointer;
}

/* 포스터 위에 겹치는 "삭제" — 아래 절반. 위 "이미지 변경"과의 경계에 가는 선을
   그어 둘이 나뉘어 보이게 한다(배너는 가로로 넓어 오른쪽 띠였지만, 포스터는
   세로로 길어 위아래로 쌓는 편이 읽기 좋다 — 요청). */
.movie-editor-poster-remove-overlay {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 0;
  top: 50%;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0 !important;
  border-top: 1px solid rgba(255, 255, 255, .35) !important;
  border-radius: 0 0 8px 8px;
  background: rgba(0, 0, 0, .58) !important;
  color: #fff !important;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s;
}

.movie-editor-poster-remove-overlay[hidden] {
  display: none !important;
}

.movie-editor-poster-region:hover .movie-editor-poster-remove-overlay,
.movie-editor-poster-remove-overlay:focus-visible {
  opacity: 1;
}

.movie-editor-poster-region:hover .movie-editor-poster-upload {
  opacity: 1;
}

@media (hover: none) {
  .movie-editor-poster-remove-overlay {
    opacity: 1;
  }
}

/* 전역 button:disabled의 opacity는 유지하고, 선택된 포스터를 단순히
   비활성 버튼으로 표시하는 이 영역만 원본 명도로 보인다. */
.movie-editor-poster:disabled {
  opacity: 1 !important;
}

.movie-editor-poster-upload {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity .15s;
  background: rgba(0, 0, 0, .58);
  color: #fff;
  border-radius: 8px;
}

/* 삭제가 함께 뜰 때(=포스터가 있을 때)만 위 절반으로 물러난다. 포스터가 없으면
   삭제가 hidden 이라 위 규칙대로 전체를 덮는다. */
.movie-editor-poster-region:has(.movie-editor-poster-remove-overlay:not([hidden])) .movie-editor-poster-upload {
  bottom: 50%;
  border-radius: 8px 8px 0 0;
}

.movie-editor-poster:focus-visible .movie-editor-poster-upload {
  opacity: 1;
}

.movie-editor-poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
}

.movie-editor-title-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.movie-editor-title-row > .movie-info-field {
  width: 100%;
}

.movie-editor-meta-row.movie-info-pair-row,
.movie-detail-meta-row.movie-info-pair-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 16px;
}

/* 등록·상세 정보 모두 라벨/점/값 3열을 공유한다. 라벨 길이와 무관하게
   첫 번째 구분점이 같은 세로선에 놓인다. */
.movie-info-field {
  display: inline-grid;
  grid-template-columns: 3em auto minmax(0, 1fr);
  align-items: center;
  column-gap: 4px;
  min-width: 0;
}

.movie-info-label {
  white-space: nowrap;
}

.movie-info-separator {
  text-align: center;
}

.movie-info-value {
  min-width: 0;
  min-height: 24px;
  margin: 0;
  padding: 0 9px;
  line-height: 24px;
}

.movie-info-description {
  color: var(--system-c-area-b-base-desc-font-color);
}

.movie-info-description-field .movie-info-label,
.movie-info-description-field .movie-info-separator {
  color: var(--system-c-area-b-base-desc-font-color);
}

.movie-watch-value {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  white-space: nowrap;
}

.movie-editor-date-input {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding-block: 0;
  line-height: 24px;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  /* data-no-theme 이라 광역 입력 테마가 안 걸리는데, 그대로 두면
     date/number 는 브라우저 기본 흰 배경으로 남는다 — 뒤의 영역 B 가 비치게. */
  background: transparent;
}

.movie-editor-date-input::-webkit-datetime-edit {
  padding: 0;
}

.movie-editor-date-input::-webkit-calendar-picker-indicator {
  display: none;
  -webkit-appearance: none;
}

.movie-editor-episode-input {
  width: 3ch;
  height: 24px;
  padding-inline: 0;
  line-height: 24px;
  text-align: center;
  appearance: textfield;
  -moz-appearance: textfield;
  background: transparent;
}

.movie-editor-episode-input::-webkit-inner-spin-button,
.movie-editor-episode-input::-webkit-outer-spin-button {
  margin: 0;
  -webkit-appearance: none;
}

.movie-editor-title-controls .post-editor-title-input {
  height: 24px;
  padding-right: 32px;
  line-height: 24px;
}

.movie-search-loading {
  position: absolute;
  top: 50%;
  right: 9px;
  width: 14px;
  height: 14px;
  box-sizing: border-box;
  border: 2px solid var(--system-c-area-b-base-desc-font-color);
  border-top-color: var(--focus-color) !important;
  border-radius: 50%;
  transform: translateY(-50%);
  animation: movie-search-spin .7s linear infinite;
  pointer-events: none;
  z-index: 6;
}

.movie-search-loading[hidden] {
  display: none;
}

@keyframes movie-search-spin {
  to { transform: translateY(-50%) rotate(360deg); }
}

/* 제목 입력창 바로 아래 뜨는 검색 결과 드롭다운 — 입력창과 같은 폭(부모
   .post-editor-title-wrap 기준), 최대 3개까지 보이고 그 이상은 스크롤. */
.movie-search-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 5;
  margin-top: 4px;
  max-height: 192px;
  overflow-y: auto;
  scrollbar-width: none;
  border-radius: 8px;
  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)) !important;
}

.movie-search-dropdown::-webkit-scrollbar {
  display: none;
}

.movie-search-dropdown-message {
  padding: 10px;
  font-size: 12px;
  opacity: .7;
}

/* 별점 위젯 — 진짜 별 글리프(★) 두 겹을 겹쳐 채움 레이어를 %로 잘라
   half-star까지 표현한다(사각형 마스크가 아니라 별 모양 그대로 채워짐). */
.movie-star-rating {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  vertical-align: middle;
}

.movie-star-rating-score {
  display: inline-flex;
  align-items: center;
  height: 12px;
  font-weight: 700;
  line-height: 12px;
}

.movie-star-rating-stars {
  position: relative;
  display: inline-block;
  height: 12px;
  line-height: 12px;
  letter-spacing: 2px;
  cursor: pointer;
  user-select: none;
}

.movie-star-rating.is-readonly .movie-star-rating-stars {
  cursor: default;
}

.movie-star-rating-track,
.movie-star-rating-fill {
  display: block;
  font: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  white-space: nowrap;
}

.movie-star-rating-track {
  color: var(--system-c-area-b-base-desc-font-color);
}

.movie-star-rating-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  overflow: hidden;
  color: var(--focus-color);
}

/* 오른쪽 정보 영역과 각 행도 등록·상세에서 같은 레이아웃을 사용한다. */
.movie-detail-info-fields {
  grid-row: 1;
  grid-column: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 6px;
}

.movie-detail-meta-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

@media (max-width: 640px) {
  .movie-editor-head,
  .movie-detail-info {
    grid-template-columns: 1fr;
  }
  .movie-editor-poster {
    margin: 0 auto 8px;
  }
  .movie-detail-poster {
    width: 120px;
    margin: 0 auto 8px;
  }
  .movie-editor-meta-row.movie-info-pair-row,
  .movie-detail-meta-row.movie-info-pair-row {
    grid-template-columns: 1fr;
    row-gap: 6px;
  }
}

/* .confirm-dialog와 같은 System C content 테마 — 이 항목만 배경 없이
   창 바탕이 그대로 비쳐 보이던 걸 맞춘다. */
.movie-search-result-item {
  display: flex;
  width: 100%;
  gap: 10px;
  align-items: center;
  padding: 8px;
  border-radius: 8px;
  text-align: left;
  cursor: pointer;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  /* 항목 테두리는 두지 않는다(요청) — 드롭다운 판이 이미 테두리를 갖고 있어
     항목마다 선을 또 그으면 목록이 격자처럼 보인다. */
  border: 0 !important;
  color: var(--system-c-area-b-base-font-color) !important;
}

/* <img>(TMDB 매칭 성공)와 placeholder <div>(매칭 실패) 둘 다 이 클래스를
   쓴다 — object-fit은 div에는 그냥 무시되는 안전한 공통 규칙. */
.movie-search-result-poster {
  flex: 0 0 auto;
  width: 46px;
  aspect-ratio: 2/3;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  object-fit: cover;
}

/* TMDB에서 이 영화의 포스터를 찾지 못했을 때(제목/연도로 매칭, 항상 성공하는
   건 아님 — service/tmdbClient.go 참고)의 placeholder — 자리만 잡아두는
   대신 무엇이 비어있는지 짧게 알려준다. */
.movie-search-result-poster-label {
  font-size: 10px;
  text-align: center;
  opacity: .7;
}

.movie-search-result-info {
  min-width: 0;
}

.movie-search-result-title {
  font-weight: 700;
}

.movie-search-result-title-en {
  font-weight: 400;
  opacity: .7;
}

/* ==========================================================================
   유튜브 감상 후기 — 목록 카드는 그림 모달과 완전히 같은 .grid-cell/
   .post-thumb-wrap/.grid-cell-meta 마크업을 쓰며 위의 그림 목록 규칙과
   함께 선언한다. 별점 위젯(.movie-star-rating*)/정보 3열(.movie-info-field 등)/
   검색 드롭다운(.movie-search-*)은 영화 후기와 완전히 같은 모양이라 새
   클래스를 만들지 않고 그대로 재사용한다(위 규칙들 참고).
   ========================================================================== */
/* 유튜브 링크 미리보기 썸네일은 영화 포스터(2:3)와 달리 16:9라 별도
   비율만 덮어쓴다(마크업은 .movie-search-result-poster 그대로 재사용). */
.youtube-search-result-thumb {
  aspect-ratio: 16/9;
}

/* 에디터의 미리보기 플레이어 — post-editor-head와 post-editor-body 사이
   (요청), 헤드/툴바처럼 스크롤되지 않는 고정 자리다. 링크를 아직 못
   골랐으면 hidden. */
/* 미리보기 자리 = 제목 바 + 접히는 프레임(요청). 16:9·검정 배경·접힘 규칙은
   프레임이 상세보기의 .youtube-detail-player-frame 을 같이 달아 물려받고,
   여기는 바깥 상자 역할만 한다. */
.youtube-editor-player {
  flex: 0 0 auto;
  width: 100%;
  margin-bottom: 8px;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  border-radius: 8px;
}
.youtube-editor-player-frame {
  border-radius: 0 0 8px 8px;
}
.youtube-editor-player-bar {
  width: 100%;
  border: 0;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
}
/* 상세보기 미니바는 왼쪽에 썸네일이 있어 제목이 자연스레 왼쪽에 붙지만,
   여기는 제목이 첫 칸이라 버튼 기본 가운데정렬에 딸려간다. */
.youtube-editor-player-bar .youtube-detail-player-mini-title {
  text-align: left;
}
.youtube-editor-player.is-collapsed .youtube-editor-player-bar {
  border-radius: 8px;
}
.youtube-editor-player-caret {
  flex: 0 0 auto;
  transition: transform .15s;
}
.youtube-editor-player.is-collapsed .youtube-editor-player-caret {
  transform: rotate(-90deg);
}
.youtube-editor-player[hidden] {
  display: none;
}
[data-youtube-player-mount] {
  width: 100%;
  height: 100%;
}
.youtube-editor-player iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* 상세보기 플레이어 도크 — 상단 바는 확대 중 핀과 제목을, 축소 중에는
   썸네일과 재생 컨트롤을 표시한다. */
.youtube-detail-player-dock {
  position: sticky;
  top: 0;
  z-index: 3;
  /* .window-content 는 세로 flex 라, 가로 auto 마진이 stretch 를 꺼 버린다 —
     그러면 폭이 내용(미니바 제목) 크기로 쪼그라들어 게시글 판보다 훨씬 좁아진다.
     width:100% 로 다시 부모 폭을 받고, max-width 가 게시글 판(720px)에 맞춘다.
     아래 여백은 본문↔댓글 사이와 같은 8px 다(요청). */
  width: 100%;
  max-width: 720px;
  margin: 0 auto 8px;
  /* 게시글 판(.post-content)과 같은 영역 B 테두리를 두른다(요청) — 안쪽
     미니바/프레임이 아니라 바깥 상자가 가져야 접힘 상태에서도 한 겹이다. */
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  border-radius: 10px;
}
/* 접히면 미니바가 알약 모양(20px)이 되므로 테두리 반경도 같이 간다. */
.youtube-detail-player-dock.is-collapsed {
  border-radius: 20px;
}
.youtube-detail-player-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16/9;
  border-radius: 0 0 10px 10px;
  overflow: hidden;
  background: #000;
  box-shadow: 0 6px 14px -2px rgba(0, 0, 0, .18);
}
.youtube-detail-player-frame iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.youtube-detail-player-frame.is-collapsing {
  pointer-events: none;
  animation: youtube-detail-player-collapse .22s ease-in forwards;
}
@keyframes youtube-detail-player-collapse {
  from {
    clip-path: inset(0);
    transform: translateY(0);
    opacity: 1;
  }
  to {
    clip-path: inset(0 0 100% 0);
    transform: translateY(-18px);
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .youtube-detail-player-frame.is-collapsing {
    animation-duration: .01ms;
  }
}
/* 축소 상태 — iframe을 display:none 대신 2px로 시각적으로만 숨긴다.
   music.js의 .youtube-player-area와 같은 이유: display:none은 유튜브가
   "화면에서 사라짐"으로 판단해 재생을 바로 멈춘다(요청 — 영상이 가려져도
   멈추지 않아야 함). */
.youtube-detail-player-frame.is-collapsed {
  position: absolute;
  width: 2px;
  height: 2px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}
.youtube-detail-player-toggle {
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  color: var(--focus-color) !important;
  background: transparent !important;
  opacity: .7;
  cursor: pointer;
}
.youtube-detail-player-toggle[aria-pressed="true"] {
  opacity: 1;
}
.youtube-detail-player-toggle[aria-pressed="true"] svg path:last-child {
  fill: currentColor;
}
.youtube-detail-player-toggle svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.youtube-detail-player-mini {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 12px;
  border-radius: 10px 10px 0 0;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  box-shadow: 0 4px 12px -2px rgba(0, 0, 0, .18);
}
.youtube-detail-player-dock.is-collapsed .youtube-detail-player-mini {
  border-radius: 20px;
  cursor: pointer;
}
.youtube-detail-player-mini-thumb {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: center/cover no-repeat;
}

/* 영상 썸네일은 16:9 라 정사각형에 넣으면 좌우가 잘린다 — 목록 카드
   (.post-thumb)와 같은 비율로 둔다(요청). 같은 클래스를 공유하는 핀 버튼은
   아이콘이라 정사각형 그대로여야 해서, 썸네일 쪽만 따로 집는다. */
[data-youtube-mini-thumb],
[data-youtube-editor-player-thumb] {
  width: auto;
  aspect-ratio: 16 / 9;
}
.youtube-detail-player-toggle[hidden],
.youtube-detail-player-mini-thumb[hidden],
[data-youtube-mini-controls][hidden] {
  display: none !important;
}
[data-youtube-mini-controls] {
  display: contents;
}
.youtube-detail-player-mini-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.youtube-detail-player-mini-play {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border: 0;
  border-radius: 50%;
  background: transparent !important;
  cursor: pointer;
}
/* 재생바 — 브라우저 기본 트랙은 두껍고 색도 테마와 무관해서 직접 그린다(요청).
   지나온 구간은 포커스 색, 남은 구간은 영역 B 구분선 색이고, 경계는 JS 가
   넣어 주는 --played(0~100%)가 정한다. 요소 높이는 손잡이 크기라 트랙보다
   커야 하고(끌기 판정 영역), 트랙 자체는 3px 로 얇게 둔다. */
/* 재생 위치 / 전체 길이 — 재생바 옆에 붙는다(요청). 폭이 들쭉날쭉하면 재생바
   길이가 초 단위로 흔들려서, 숫자 폭이 일정한 글꼴 지표를 쓴다. */
.youtube-detail-player-mini-time {
  flex: 0 0 auto;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  opacity: .75;
}

.youtube-detail-player-mini-progress {
  flex: 1 1 80px;
  min-width: 60px;
  height: 11px;
  padding: 0;
  border: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}
.youtube-detail-player-mini-progress::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(to right,
    var(--focus-color) var(--played, 0%),
    rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha)) 0);
}
.youtube-detail-player-mini-progress::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 11px;
  height: 11px;
  margin-top: -4px;
  border: 0;
  border-radius: 50%;
  background: var(--focus-color);
}
.youtube-detail-player-mini-progress::-moz-range-track {
  height: 3px;
  border-radius: 999px;
  background: rgba(var(--system-c-area-b-base-divider-rgb), var(--system-c-area-b-base-divider-alpha));
}
.youtube-detail-player-mini-progress::-moz-range-progress {
  height: 3px;
  border-radius: 999px;
  background: var(--focus-color);
}
.youtube-detail-player-mini-progress::-moz-range-thumb {
  width: 11px;
  height: 11px;
  border: 0;
  border-radius: 50%;
  background: var(--focus-color);
}

/* 본문 안 타임라인 링크 — 실제로 저장된 마크다운은 평범한 [MM:SS](url)
   한 겹짜리 링크다(이중 대괄호를 텍스트에 직접 넣지 않음, 파서가 깨지는
   걸 피하기 위함) — 대괄호는 여기 pseudo-content로만 붙인다. */
.youtube-timeline-link::before {
  content: "[";
}
.youtube-timeline-link::after {
  content: "]";
}

/* 태그(칩)로 감싼 뒤로는 대괄호까지 두면 경계가 두 겹으로 보인다(요청) —
   편집기·읽기 화면 모두 칩일 때만 뗀다(칩이 아닌 옛 글은 대괄호 그대로). */
.youtube-timeline-link.post-link-chip::before,
.youtube-timeline-link.post-link-chip::after {
  content: none;
}

/* 타임라인은 영상 안 위치로 가는 내부 이동이라 "외부 링크" 화살표는 뺀다 —
   읽기 화면의 링크 렌더러가 모든 링크 칩에 그 아이콘을 붙인다. */
.youtube-timeline-link.post-link-chip svg {
  display: none;
}

.diary-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 9px;
}
.sound-popover {
  width: 250px;
}

/* 볼륨 팝오버는 항상 검은색 앨범아트 오버레이 위에 표시되므로 글자는
   System A 설정과 무관하게 흰색으로 고정한다. 다만 패널 바깥 테두리는
   다른 팝오버와 같이 테마(영역 A 기본 테두리)를 따른다 — 안쪽 요소만
   테두리를 끈다(예전엔 패널까지 꺼서 테두리 색을 지정해도 보이지 않았다). */
.sound-popover * {
  border: 0px solid transparent !important;
}
.sound-popover,
.sound-popover * {
  color: #fff !important;
}

/* display:none이면 iframe이 렌더 트리에서 제외되어 YouTube가 "화면에 보이지 않음"으로
   판단해 재생을 곧바로 멈춤. 렌더링은 유지한 채 시각적으로만 숨김. */
.youtube-player-area {
  position: absolute;
  width: 2px;
  height: 2px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* 커스텀 음악 UI */
.music-panel {
  position: relative;
  overflow: hidden;
  border-radius: 11px;
}

.music-background {
  position: absolute;
  inset: 0;

  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;

  transform: scale(1.02);
}

.music-overlay {
  position: absolute;
  inset: 0;
  background:linear-gradient(270deg, rgba(0, 0, 0, 50%), rgb(0 0 0 / 70%))
}

.music-content {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;

  padding: 10px;
}
.music-title {
  overflow: hidden;
  font-weight: 700;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin-bottom: 7px;
}

.music-progress-area {
  margin-top: auto;
}

#musicProgress {
  width: 100%;
  height: 5px;
}

.music-time {
  display: flex;
  justify-content: space-between;
  margin-top: 3px;
  opacity: .8;
}

.music-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.music-play-button,
.music-volume-button {
  border: 0;
  background: transparent;

  cursor: pointer;
}

.music-play-button {
  width: 38px;
  display: grid;
  place-items: center;
}

.music-volume-control {
  width: 80px;
  display: flex;
  align-items: center;
  gap: 7px;
}

.music-volume-button {
  width: 27px;
  height: 20px;
  display: grid;
  place-items: center;
}

.music-volume-button svg {
  width: 17px;
  height: 17px;
}

.music-volume-button .icon-muted {
  display: none;
}

.music-volume-button.is-muted .icon-unmuted {
  display: none;
}

.music-volume-button.is-muted .icon-muted {
  display: block;
}

#musicVolume {
  min-width: 0;
  flex: 1;
  height: 5px;
}

#musicVolume,
#musicProgress {
  height: 4px;
  border: 0;
  border-radius: 999px;
  outline: none;
  appearance: none;
  -webkit-appearance: none;

  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  cursor: pointer;
}

/* Chrome / Edge / Safari */
#musicVolume::-webkit-slider-thumb,
#musicProgress::-webkit-slider-thumb {
  width: 12px;
  height: 12px;

  border: 1px solid transparent;
  border-radius: 50%;

  background: var(--focus-color);

  appearance: none;
  -webkit-appearance: none;
}

/* Firefox */
#musicVolume::-moz-range-thumb,
#musicProgress::-moz-range-thumb {
  width: 12px;
  height: 12px;

  border: 1px solid transparent;
  border-radius: 50%;

  background: var(--focus-color);
}

#musicVolume::-moz-range-track,
#musicProgress::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
}

#musicVolume::-moz-range-progress,
#musicProgress::-moz-range-progress {
  height: 4px;
  border-radius: 999px;
  background: var(--focus-color);
}
/* ==========================================================================
   테마 관리 패널 (환경설정 셸의 "테마 관리" 탭 콘텐츠로 항상 내장됨)
   과거에는 모니터 클릭으로 열리는 전체 화면 오버레이였지만, 지금은 왼쪽
   내비게이션을 가리지 않는 일반 패널이라 position:fixed나 흰색 강제 배경이
   필요 없다 — 다른 관리 화면 카드류와 같은 방식으로 System C 톤을 따른다.
   ========================================================================== */
/* 테마 프리셋 바 — 저장된 프리셋 칩 목록 + "프리셋으로 저장" 버튼.
   .theme-panel-columns(flex:1) 위에 얹히는 고정 높이 줄이라 flex:1 없음. */
.theme-preset-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding-bottom: 10px;
}
.theme-preset-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1;
}
.theme-preset-chip {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 2px 4px 2px 10px;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  border-radius: 999px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  font-size: 13px;
}
.theme-preset-delete {
  width: 18px;
  height: 18px;
  line-height: 1;
  padding: 0;
}

/* 좌(바탕화면 배경 이미지 전용 패널)/우(System A~C·Focus·바탕화면 아이콘
   색상 아코디언 목록) 분할. 오른쪽만 내부 스크롤하고(.settings-theme-groups,
   기존 그대로) 왼쪽은 고정 높이 콘텐츠라 스크롤하지 않는다. */
.theme-panel-columns {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: 14px;
}

/* 바탕화면 / 테마 목록을 정확히 반씩 나눠 쓴다 — 예전엔 바탕화면이 200px
   고정이라 색 지정 목록이 남는 폭을 전부 먹어 지나치게 넓었다.
   min-width:0 이 있어야 flex 아이템이 내용 최소폭 밑으로도 줄어 반씩이 지켜진다. */
.theme-desktop-panel {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.theme-desktop-panel-head {
  font-weight: 700;
}

/* 배경 이미지 미리보기(.bg-region-stage)를 감싸는 모니터 베젤 — .settings-pc-preview와
   같은 System C 톤(밝은 테마에서는 흰색)/모서리/그림자를 그대로 따른다. */
.monitor-frame {
  box-sizing: border-box;
  width: 100%;
  padding: 10px;
  border-radius: 9px;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  box-shadow: 0 6px 20px rgba(0, 0, 0, .07);
}

/* 세로 모드에서는 .bg-region-stage.is-portrait가 폭을 110px로 좁히는데,
   베젤(padding)이 그대로 폭 100%를 유지하면 좌우 여백만 두꺼워져 보인다 —
   베젤 두께(10px)는 그대로 두고 프레임 자체를 스테이지 폭에 맞춰 좁힌 뒤
   영역 안에서 가운데로 옮긴다. */
.monitor-frame.is-portrait {
  width: 130px;
  margin: 0 auto;
}

.bg-region-stage.is-empty {
  display: grid;
  place-items: center;
  background: rgba(120, 120, 120, .18);
  cursor: default;
}

.bg-region-stage.is-empty::before {
  content: "이미지를 업로드하세요";
  padding: 0 10px;
  text-align: center;
  opacity: .6;
}

.theme-bg-upload-btn,
.theme-bg-remove-btn {
  width: 100%;
}

/* 색 지정 — 캐릭터 색 지정(.character-color-row)과 같은 모양: 네이티브 컬러
   스와치 바로 옆에 대문자 hex가 별도 입력창 테두리 없이 붙는다. */
/* 스와치 — 네이티브 <input type="color">는 투명도를 못 다뤄서 버튼으로 바꾸고
   클릭하면 직접 만든 팝오버 피커(.color-picker-pop)를 연다(요청). 반투명한 색이
   보이도록 체커보드를 깔고 그 위에 --swatch-color 를 얹는다. */
.theme-color-input {
  flex: 0 0 auto;
  position: relative;
  width: 23px !important;
  height: 23px;
  padding: 0;
  border: 1px solid rgba(120,120,120,.5) !important;
  border-radius: 4px;
  cursor: pointer;
  overflow: hidden;
  background-color: #fff !important;
  background-image:
    linear-gradient(45deg, #c9c9c9 25%, transparent 25%, transparent 75%, #c9c9c9 75%),
    linear-gradient(45deg, #c9c9c9 25%, transparent 25%, transparent 75%, #c9c9c9 75%) !important;
  background-size: 8px 8px !important;
  background-position: 0 0, 4px 4px !important;
}
.theme-color-input::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--swatch-color, transparent);
}

/* 팝오버 피커 — 개발자도구 것과 같은 구성(채도·명도 사각형 / 색상 띠 /
   투명도 띠). 창 밖으로 잘리지 않게 body 에 붙고 좌표는 JS 가 잡는다. */
.color-picker-pop {
  position: fixed;
  z-index: var(--z-dialog);
  width: 208px;
  box-sizing: border-box;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-radius: 8px;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha)) !important;
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha)) !important;
  box-shadow: 0 8px 20px -4px rgba(0, 0, 0, .22);
}
/* 가로는 채도(왼→흰색, 오른→순색), 세로는 명도(아래로 검정) — 두 그라데이션을
   겹쳐 만든다. --picker-hue 는 JS 가 현재 색상(hue)으로 바꿔 준다. */
.color-picker-sv {
  position: relative;
  height: 120px;
  border-radius: 5px;
  cursor: crosshair;
  touch-action: none;
  background:
    linear-gradient(to top, #000, rgba(0, 0, 0, 0)),
    linear-gradient(to right, #fff, var(--picker-hue, #f00));
}
.color-picker-sv-dot {
  position: absolute;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  border: 2px solid #fff !important;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .45);
  pointer-events: none;
}
.color-picker-sliders {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* 안 읽은 채팅 수 뱃지(요청) — 사이드바 하위 메뉴와 대화·세션 목록에 붙는다. */
.unread-badge {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; padding: 0 5px; margin-left: 6px;
  border-radius: 8px; background: var(--focus-color); color: #fff;
  font-size: 10px; line-height: 1; font-weight: 700; vertical-align: middle;
}
.color-picker-hex {
  width: 100%; box-sizing: border-box;
  padding: 1px 4px; font-size: 11px; line-height: 1.4; text-align: center; text-transform: uppercase;
  background: transparent; color: inherit;
  border: 1px solid rgba(120, 120, 120, .5); border-radius: 4px;
}
.color-picker-hex:focus { outline: none; border-color: var(--focus-color); }
.color-picker-drop {
  flex: 0 0 auto;
  width: 22px; height: 22px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: transparent; border: 1px solid currentColor; color: inherit;
}
.color-picker-bars {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
/* 미리보기도 스와치와 같이 체커보드 위에 얹는다. */
.color-picker-preview {
  flex: 0 0 auto;
  position: relative;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid rgba(120,120,120,.5) !important;
  background-color: #fff;
  background-image:
    linear-gradient(45deg, #c9c9c9 25%, transparent 25%, transparent 75%, #c9c9c9 75%),
    linear-gradient(45deg, #c9c9c9 25%, transparent 25%, transparent 75%, #c9c9c9 75%);
  background-size: 8px 8px;
  background-position: 0 0, 4px 4px;
}
.color-picker-preview i {
  position: absolute;
  inset: 0;
}
.color-picker-pop input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 10px;
  margin: 0;
  padding: 0;
  border: 0 !important;
  border-radius: 5px;
  outline: none;
  cursor: pointer;
}
.color-picker-hue {
  background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%) !important;
}
/* 투명도 띠는 체커보드 위에 "투명 → 현재 색" 그라데이션을 겹친다. */
.color-picker-alpha {
  background-color: #fff !important;
  background-image:
    linear-gradient(to right, transparent, var(--picker-solid, #000)),
    linear-gradient(45deg, #c9c9c9 25%, transparent 25%, transparent 75%, #c9c9c9 75%),
    linear-gradient(45deg, #c9c9c9 25%, transparent 25%, transparent 75%, #c9c9c9 75%) !important;
  background-size: 100% 100%, 8px 8px, 8px 8px !important;
  background-position: 0 0, 0 0, 4px 4px !important;
}
.color-picker-pop input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, .45);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
  cursor: pointer;
}
.color-picker-pop input[type="range"]::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, .45);
  cursor: pointer;
}

/* 투명도가 있는 행은 #RRGGBBAA 로 두 자 더 들어간다(요청) — 9자 기준 폭. */
.theme-hex-input {
  flex: 0 0 94px;
  width: 94px;
  height: 22px;
  padding: 0 2px;
  border: 0 !important;
  outline: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  font-family: monospace;
  text-transform: uppercase;
}

.theme-color-input:hover,
.theme-color-input:focus,
.theme-hex-input:hover,
.theme-hex-input:focus {
  border: 0 !important;
  outline: 0 !important;
  box-shadow: none !important;
}

/* 그룹 목록만 스크롤(드래그 없음). 수정/취소 버튼·메시지는 .settings-form-actions로 분리되어 있어 스크롤에 딸려가지 않음 */
.settings-theme-groups {
  /* basis를 0으로 둬야 바탕화면 패널과 정확히 반씩 나눠 갖는다 — auto(내용 기준)
     이면 색 지정 행들의 내용 폭만큼 먼저 차지해 버려 반반이 되지 않는다.
     min-width:0 은 그렇게 줄어든 폭 안에서 내용이 다시 밀어내지 못하게 막는다. */
  flex: 1 1 0;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 0, #000 100%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 0, #000 100%, transparent);
  transition: -webkit-mask-image .15s ease, mask-image .15s ease;
}

/* 스크롤 가능한 방향에만 위/아래 투명도 그라데이션 표시 */
.settings-theme-groups.can-scroll-up {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 100%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 100%, transparent);
}
.settings-theme-groups.can-scroll-down {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 0, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 0, #000 calc(100% - 28px), transparent);
}
.settings-theme-groups.can-scroll-up.can-scroll-down {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 calc(100% - 28px), transparent);
}

/* 테마 값 목록은 이 화면에서 바꾸는 색과 상관없이 늘 흰 바탕 + 검은 글씨다(요청) — 편집하는
   색이 편집기 자신의 가독성을 흔들면 안 된다. 실제 설정색은 스와치에서만 보여 준다. */
.theme-group {
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid rgba(0, 0, 0, .18) !important;
  background: #fff !important;
}
.settings-theme-groups :is(.theme-group-head, .theme-group-body, .theme-subsection) { background: #fff !important; }
.settings-theme-groups, .settings-theme-groups *:not(.theme-color-input) { color: #000 !important; }

.theme-group-head {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}

.theme-group-toggle {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 0;
  background: transparent !important;
  border: 0 !important;
  cursor: pointer;
  text-align: left;
}

/* 접힌 카드는 헤더 안 어디에 마우스를 올려도(토글 글자 위뿐 아니라 카드
   여백·초기화 버튼 위까지) 카드 전체가 다른 .normal-button과 동일한 System C
   hover 배경/글자색/그림자를 보이게 한다 — 트리거를 .theme-group-toggle이
   아니라 .theme-group.is-collapsed 자체의 :hover로 두고, 카드 안 어디를 눌러도
   포커스가 가는 토글 버튼의 :focus-visible은 :has()로 같은 카드 규칙을
   트리거하게 해 마우스/키보드 모두 카드 전체가 같은 모습으로 강조되게 한다.
   .is-collapsed로 범위를 좁혔으므로 펼친 카드에는 이 규칙 자체가 매치되지
   않아(별도의 "효과 없음" 규칙 없이도) 펼친 상태에는 전혀 적용되지 않는다.
   초기화 버튼(.theme-group-reset-btn) 위에 마우스가 있어도 이 카드 hover는
   그대로 유지되며, 초기화 버튼 자신의 독립적인 hover 규칙(아래, 항상 투명
   유지)도 함께 적용된다 — 서로 다른 요소를 대상으로 하므로 충돌하지 않는다. */
/* 접힌 무리 위에 마우스가 올라와도 흰 바탕·검은 글씨를 지킨다(요청) — 강조색을 쓰면 값이 안 읽힌다. */
.theme-group.is-collapsed:hover,
.theme-group.is-collapsed:has(.theme-group-toggle:focus-visible) {
  background: #f1f1f1 !important;
  border-color: rgba(0, 0, 0, .28) !important;
  box-shadow: none !important;
}

.theme-group.is-collapsed .theme-group-body {
  display: none;
}

.theme-group-head-text {
  min-width: 0;
}

.theme-group-head-text strong {
  display: block;
}

.theme-group-head-text small {
  display: block;
  margin-top: 1px;
  opacity: .72;
}

.theme-group-reset-btn {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  padding: 0;
  display: grid;
  place-items: center;
  background: transparent !important;
  border: 0 !important;
  border-radius: 6px;
  cursor: pointer;
  opacity: .85;
}

.theme-group-reset-btn svg {
  width: 13px;
  height: 13px;
}

/* 초기화 버튼은 hover 시각효과 없음 */
.theme-group-reset-btn:hover,
.theme-group-reset-btn:focus-visible {
  opacity: .85;
  background: transparent !important;
}

.theme-group-body {
  display: flex;
  flex-direction: column;
  margin-top: 5px;
}

/* 소섹션은 기본이 1열. 기본/강조가 짝을 이루는 묶음(.is-paired)만 2열로 두고,
   그 안에서 라벨이 같은 줄끼리 좌우로 나란히 온다(요청: 기본배경 | 강조배경). */
.theme-subsection {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2px 6px;
  align-content: start;
}

.theme-subsection.is-paired {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* 짝이 없어 홀로 남은 줄(예: 영역 B 기본의 "구분선")은 한 줄을 통째로 쓴다 —
   한 칸만 채우면 뒤따르는 짝이 오른쪽 열부터 시작해 정렬이 통째로 밀린다. */
.theme-subsection.is-paired .theme-row.is-solo,
.theme-subsection-label {
  grid-column: 1 / -1;
}

/* 창이 좁으면 짝지은 묶음도 1열로 되돌린다 — 좌우로 붙일 폭이 안 나온다. */
@container window (max-width: 720px) {
  .theme-subsection.is-paired {
    grid-template-columns: minmax(0, 1fr);
  }
}

.theme-subsection + .theme-subsection {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgba(120, 120, 120, .18);
}

.theme-subsection-label {
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .55;
  margin-bottom: 2px;
}

/* 이 화면 자체가 테마 색상(System A/B/C 등)을 편집하는 곳이라, 행 배경/글자색을
   그 변수들로 두면 사용자가 값을 바꾸는 동안 편집기 자신의 가독성이 흔들린다
   (예: System C 글자색을 흰색에 가깝게 바꾸면 이 화면 라벨도 함께 흐려짐). 그래서
   각 행은 항상 고정된 불투명 #fff 배경 + #000 글자로 두고, 실제 설정색은
   .theme-swatch(아래에서 원래 색을 그대로 유지)에서만 보여준다. */
.theme-row {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 6px;
  border-radius: 6px;
  background: #fff !important;
  color: #000 !important;
}

.bg-region-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 6px;
}

.bg-region-tab {
  flex: 1;
  height: 30px;
  border: 0px solid rgba(120, 120, 120, .3);
  border-radius: 0;
  background: transparent;
  cursor: pointer;
}

.bg-region-tab.is-active {
  border-color: var(--focus-color) !important;
  color: var(--focus-color);
  border-bottom: 3px solid;
}

.bg-region-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16/9;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid rgba(120, 120, 120, .3);
  cursor: crosshair;
  touch-action: none;
}

.bg-region-stage.is-portrait {
  aspect-ratio: 9/16;
  max-width: 110px;
  margin: 0 auto;
}

.bg-region-image {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

.bg-region-marker {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .4), 0 2px 6px rgba(0, 0, 0, .35);
  background: var(--focus-color);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.theme-row-label {
  flex: 0 0 84px;
  width: 84px;
  min-width: 0;
  font-weight: 600;
}

/* 라벨 영역(고정 150px) 대비 값 영역 — 남은 폭 전체를 쓰며, 스와치+hex
   그룹은 좌측정렬, 투명도(있으면)는 우측정렬. 그룹이 하나뿐(투명도 없음)이면
   space-between이 할 일이 없어 그대로 좌측에 남는다. */
.theme-row-value {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 7px;
}

/* 스와치와 hex 코드를 [■] #ffd561 처럼 붙여 보이게 하는 그룹 — 간격만 좁힌다. */
.theme-swatch-group {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 3px;
}

/* Main settings preview: show the settings modal only, not a desktop/taskbar mock. */
.settings-pc-screen {
  background-position: var(--desktop-background-position-landscape, center);
  background-size: cover;
  background-repeat: no-repeat;
}

/* ==========================================================================
   Desktop background layer / modal glass blur
   Keep the wallpaper as a real rendered layer so backdrop-filter on windows
   can blur it together with the desktop content behind each translucent window.
   ========================================================================== */

.desktop-background {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: #fff;
  background-image: var(--desktop-background-image) !important;
  background-position: var(--desktop-background-position-landscape, center) !important;
  background-size: cover!important;
  background-repeat: no-repeat!important;
  opacity: 0.95;
}

/* 세로(portrait) 비율의 브라우저에서는 세로용으로 선택한 위치를 보여준다. */
@media (orientation: portrait) {
  .desktop-background {
    background-position: var(--desktop-background-position-portrait, center) !important;
  }
}

/* 상단 .window-bar와 .window-toolbar는 부모 .window의 단일 블러 레이어를
   공유한다. 바에 개별 backdrop-filter를 다시 걸면 투명 테마에서 두 영역의
   질감이 분리돼 보인다. 본문은 별도 System C 표면이라 자체 블러를 유지한다. */
.window-content {
  backdrop-filter: blur(18px) saturate(1.08);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
}

/* Native color input remains near the legend button before showPicker() opens. */
.display-theme-anchor {
  position: fixed !important;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0 !important;
  opacity: .001;
  pointer-events: none;
}

/* 알림 설정의 기기 알림 안내 한 줄(요청) — 토글 아래 작은 글씨. */
.notification-settings-hint {
  margin: 4px 0 0;
  font-size: 11px;
  opacity: .65;
}

/* 채팅 줄의 캐릭터 아바타·이름 — 누르면 캐릭터 프로필 팝오버가 뜬다(요청, 댓글 작성자와 같은 길). */
.shared-chat-msg-name.is-profile-ref,
.avatar-circle.is-profile-ref {
  cursor: pointer;
}
.shared-chat-msg-name.is-profile-ref:hover {
  text-decoration: underline;
}

/* 끌어서 차례를 바꾸는 중인 아이콘(요청, 소유자만) — 지금 들고 있는 것임을 알린다. */
.app-wrap.is-reordering,
.shortcut.is-reordering,
.desktop-shortcut.is-reordering {
  opacity: .55;
}

/* 우클릭 메뉴 안의 슬라이더 줄(요청) — 투명도·흐림·표시영역을 새 팝업 없이 메뉴에서 바로 끈다. */
.post-admin-menu-slider {
  display: grid;
  grid-template-columns: 4em 3.2em 1fr;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  color: var(--system-c-button-base-font-color);
}
/* 이름·값 칸을 고정한 격자다(요청) — 어느 줄이든 막대가 같은 자리에서 시작하고 길이도 같다. */
.post-admin-menu-slider > span { min-width: 0; white-space: nowrap; }
.post-admin-menu-slider > output { text-align: right; opacity: .75; }
.post-admin-menu-slider > input { width: 100%; min-width: 96px; }

/* 작업표시줄 검색 제안 판(요청) — 시작메뉴와 같은 유리 면(위 .popover 그룹) 위에 종류별 무리. */
.search-suggest { width: min(420px, calc(100vw - 16px)); max-height: min(60vh, 520px); padding: 8px; box-sizing: border-box; }
.suggest-group + .suggest-group { margin-top: 6px; }
.suggest-group-head { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 6px 8px; font-size: 12px; font-weight: 700; cursor: pointer; opacity: .8; }
.suggest-group-caret { transition: transform .15s; }
.suggest-group.is-collapsed .suggest-group-caret { transform: rotate(-90deg); }
.suggest-group.is-collapsed .suggest-group-body { display: none; }
.suggest-group-body { display: flex; flex-direction: column; gap: 2px; }
.suggest-item { display: flex; align-items: center; gap: 10px; padding: 6px 8px; }
.suggest-icon { flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; }
.suggest-icon svg, .suggest-icon img { width: 20px; height: 20px; }
.suggest-text { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.suggest-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.suggest-text small { display: block; opacity: .7; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.suggest-empty { margin: 0; padding: 12px 8px; font-size: 12px; opacity: .7; }

/* 작업표시줄이 자동숨김으로 내려가 있는 동안은 그 자리를 창·바탕화면이 쓴다(요청). */
html.is-taskbar-hidden { --desktop-bottom-h: 0px; }
/* ==========================================================================
   본문 끼워넣기(요청) — 글 안에 다른 글/백업의 본문을 그대로 실은 칸. 폭은 글 폭을 다 쓰고
   높이는 정해 둔 만큼(--embed-h)만, 넘치면 칸 안에서 구른다. 마우스를 올리면 좌상단에
   "본문으로 이동", 우클릭에 새 창/이동. 끌기는 막는다. 댓글은 싣지 않는다.
   ========================================================================== */
.post-embed {
  position: relative;
  width: 100%;
  box-sizing: border-box;
  margin: 10px 0;
  border-radius: 10px;
  border: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
  background: rgba(var(--system-c-area-b-base-rgb), var(--system-c-area-b-base-alpha));
  overflow: hidden;
  -webkit-user-drag: none;
}
/* 머리줄 좌상단에는 본문 주소를 라벨로 둔다(요청) — 누르면 그 글로 간다. 제목은 그 뒤에. */
.post-embed-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid rgba(var(--system-c-area-b-base-border-rgb), var(--system-c-area-b-base-border-alpha));
}
/* 주소는 평소엔 숨고 마우스를 올렸을 때만 제목 자리에 뜬다(요청). */
.post-embed-url {
  position: absolute; left: 10px; top: 6px; z-index: 2; max-width: calc(100% - 20px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--system-c-area-b-base-desc-font-color); text-decoration: underline; cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity .12s;
}
.post-embed:hover .post-embed-url { opacity: 1; pointer-events: auto; }
.post-embed:hover .post-embed-title { opacity: 0; }
.post-embed-title { flex: 1 1 auto; min-width: 0; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: opacity .12s; }
/* 편집 중 고른 칸 — 이미지처럼 한 덩어리로 골라 Backspace/Del 로 지운다(요청). */
.post-embed.is-selected { border-color: var(--focus-color); box-shadow: 0 0 0 2px var(--focus-color); }
/* 높이는 정하지 않는다(요청) — 칸은 본문처럼 제 높이를 그대로 갖고, 스크롤은 글 전체가 맡는다. */
.post-embed-body { padding: 8px 10px; }
.post-embed-body > :first-child { margin-top: 0; }
/* 마우스를 올리면 어디까지가 끼워넣은 칸인지 포커스 테두리로 알린다(요청). */
.post-embed:hover { border-color: var(--focus-color); box-shadow: 0 0 0 1px var(--focus-color); }
/* 끼워넣은 백업 — 기본 뷰어처럼 아바타 + 이름 + 내용 한 줄씩(요청). */
.post-embed-chat-row { display: flex; align-items: flex-start; gap: 8px; padding: 3px 0; }
.post-embed-chat-row .entry-avatar { flex: 0 0 auto; width: 26px; height: 26px; }
.post-embed-chat-body { min-width: 0; }
.post-embed-chat-body strong { display: block; font-size: 12px; }
.post-embed-chat-body p { margin: 0; white-space: pre-wrap; }

/* 순서를 바꾸려고 끄는 동안에는 글자가 딸려 선택되지 않는다(요청) — bindVerticalReorder 가 켠다. */
html.is-reorder-dragging, html.is-reorder-dragging * {
  user-select: none !important;
  -webkit-user-select: none !important;
}

/* 테마 관리 화면의 입력은 지금 고치는 테마를 따르지 않는다(요청) — 늘 흰 바탕 + 검은 글씨.
   광역 입력 테마는 data-no-theme 으로 비켜 세우고(그 선택자가 id 를 물고 있어 클래스로는 못 이긴다),
   여기서 값을 못 박는다. 색 고르개(색 네모·슬라이더)는 제 색을 지켜야 하므로 뺀다. */
[data-theme-panel] :is(input, select, textarea):not([type="range"]):not([type="color"]):not([type="checkbox"]):not([type="radio"]) {
  background: #fff !important;
  color: #000 !important;
  border-color: rgba(0, 0, 0, .18) !important;
}

/* 우클릭 메뉴 한 줄은 26px 고정이라 두 줄이 되면 잘린다 — 넘칠 것 같으면 …로 줄인다(요청). */
.post-admin-menu.grid-context-menu .post-admin-menu-item {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.post-admin-menu.grid-context-menu .post-admin-menu-item > span:not(.post-admin-menu-item-icon) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* 아이콘 끌기 고스트(시작메뉴·작업표시줄·바탕화면) — 원래 칸과 같은 크기라 안의 아이콘은
   가운데에 놓는다(요청: 아이콘이 중앙이 아님). 바탕은 JS 가 그 판의 것을 복사한다. */
.shared-review-drag-ghost.is-icon-ghost {
  display: flex; align-items: center; justify-content: center;
}
.shared-review-drag-ghost.is-icon-ghost > * { margin: 0; }
