/* ════════════════════════════════════════════════════════════════
   maru — 팀 앱(학회 셸 body.has-sb) 표면. v5 P3: 값은 v5.css 토큰만(색·반경·그림자·시간·곡선·크기)
   잉크 한 색 · 헤어라인 · 알약 버튼 · 페이지 머리 하나(h1 32/26, 같은 x·top) · --ease-out 한 곡선
   app.css 뒤에 로드된다. 모든 규칙은 body.has-sb로 시작한다(예외: 토큰 폴백 한 줄).

   보호 구역 — has-sb 안에 있지만 손대면 안 되는 서브트리(기사 본문·에디터·썸네일 스튜디오):
     .art-head .art-facts .art-cover .art-prose .art-imgs .rel-paper
     .md-preview .ed .mdt .md-toolbar .thumb-field .ts [data-ts]
   범용 클래스(.btn .input .chip .avatar .field label .hint …)를 건드리는 규칙은
   전부 :not(:is(<보호 구역>) *)로 이 서브트리를 뺀다.
   ════════════════════════════════════════════════════════════════ */

/* 0. 토큰 폴백 — accent를 고르지 않은 학회(#fafafa 상속 버그)는 잉크. 학회색이 있으면 layout() 인라인 :root가 이긴다 */
:root:where(:has(> body.has-sb)) { --accent: var(--ink); --accent-soft: var(--wash-2); --primary: var(--ink); --primary-fg: #fff; --ring: rgba(23, 21, 15, .10); --link: var(--ink); }

/* 0-1. v4 토큰. 학회색은 --x-brand로 한 번 붙잡아 두고(주 CTA 전용), 셸 안의 --accent 계열은 잉크로 되돌린다.
   커스텀 속성은 선언한 요소에서 계산된 값이 상속되므로, body에서 잡은 --x-brand는 아래 재선언과 무관하게 학회색이다 */
body.has-sb {
  --x-ink: var(--ink); --x-ink-hover: var(--ink-hover);
  --x-muted: var(--ink-2); --x-subtle: var(--ink-3); --x-dim: var(--ink-3); --x-faint: var(--ink-5);
  --x-line: var(--line); --x-line-2: var(--line-2); --x-line-3: var(--line-3); --x-grid: var(--line);
  --x-wash: var(--wash-2); --x-wash-2: var(--wash-3); --x-wash-3: var(--wash-1);
  --x-canvas: var(--canvas);
  --x-new-bg: #fdece8; --x-new-fg: #c2361f;
  --x-danger: var(--danger); --x-danger-line: var(--danger-line); --x-danger-wash: var(--danger-wash);
  --x-ok: var(--ink); --x-online: var(--ink); --x-like: var(--ink); /* 상태색은 잉크(SPEC §2.1) */
  --x-r-xl: var(--r-xl); --x-r-lg: var(--r-lg); --x-r-md: var(--r-md); --x-r-sm: var(--r-sm);
  --x-lift: var(--e-2);
  --x-pop: var(--e-3);
  --x-focus: var(--ring-input);
  --x-brand: var(--tint); --x-brand-soft: var(--accent-soft); --x-brand-glow: var(--accent-glow);
  --x-brand-p: var(--primary); --x-brand-pfg: var(--primary-fg); --x-brand-ring: var(--ring); --x-brand-link: var(--link);
  --x-brand-hover: color-mix(in oklab, var(--tint) 88%, #000);
}
body.has-sb > * {
  --accent: var(--ink); --accent-soft: var(--wash-2); --accent-glow: rgba(23, 21, 15, .18);
  --primary: var(--ink); --primary-fg: #fff; --ring: rgba(23, 21, 15, .10); --link: var(--ink);
}
/* 보호 구역은 원래 토큰으로 되돌린다(기사 본문 링크·에디터·썸네일이 학회색을 그대로 쓰게) */
body.has-sb :is(.art-head, .art-facts, .art-cover, .art-prose, .art-imgs, .rel-paper, .md-preview, .ed, .mdt, .md-toolbar, .thumb-field, .ts, [data-ts]) {
  --accent: var(--x-brand); --accent-soft: var(--x-brand-soft); --accent-glow: var(--x-brand-glow);
  --primary: var(--x-brand-p); --primary-fg: var(--x-brand-pfg); --ring: var(--x-brand-ring); --link: var(--x-brand-link);
}


/* ═════════════════════════════════════════════════════════════════
   v5 P3 — 팀 앱 표면(사이드바 셸 · 피드 · 라운지 · DM · 아카이브 · 모임 · 캘린더 · 멤버 · 알림 · 글쓰기 · 글 상세 · 소모임)
   값은 전부 v5 토큰(SPEC §2). 리터럴 px는 격자(§2.3)·크기(§2.4) 안의 값만. 전환은 속성을 나열하고 --dur-*·--ease-*만.
   :not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) = 보호 구역(기사 본문·에디터·썸네일 스튜디오) 밖에서만
   ═════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────
   1. 셸 — 사이드바(§4.11) · 패널 · 모바일 탑바(§4.12) · 봇 FAB
   ───────────────────────────────────────────────────────────── */
body.has-sb .sb { --sb-hover: var(--wash-1); --sb-on: var(--wash-2); }
body.has-sb:not(.x-plat) .sb { width: var(--sb-w); padding: var(--s-3); background: var(--canvas); }
body.has-sb .sb-top { gap: var(--s-1); padding: 0 0 var(--s-2); }
body.has-sb .sb-ws > summary { height: var(--h-md); padding: 0 var(--s-2); gap: 10px; border-radius: var(--r-sm); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .sb-ws > summary > svg { width: var(--ic-sm); height: var(--ic-sm); color: var(--ink-4); transition: color var(--dur-1) var(--ease-out); }
body.has-sb .sb-logo { width: var(--av-xs); height: var(--av-xs); border-radius: var(--r-xs); }
body.has-sb .sb-logo-txt { font: 600 var(--t-caption)/1 var(--font); }
/* 워크스페이스 이름 — Pretendard 15/600(워드마크 서체 폐지, §4.11) */
body.has-sb .sb-ws-name { font: 600 var(--t-body)/1.2 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .sb-icon-btn { position: relative; width: var(--h-sm); height: var(--h-sm); border-radius: 50%; color: var(--ink-3); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .sb-icon-btn svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .sb-icon-btn:active { scale: var(--m-press-icon); transition-duration: var(--dur-1); }
/* 검색 — 32 알약, 헤어라인, ⌘K는 모노 kbd(§4.11). 검색 화면에서는 켬(테두리 잉크) */
body.has-sb .sb-search {
  height: var(--h-sm); margin: 0 0 var(--s-2); padding: 0 var(--s-1) 0 var(--s-3); gap: var(--s-2);
  border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--paper); box-shadow: none;
  color: var(--ink-3); font: 400 var(--t-footnote)/1 var(--font);
  transition: border-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
body.has-sb .sb-search svg { width: var(--ic-sm); height: var(--ic-sm); color: var(--ink-3); }
body.has-sb .sb-search .kbd { height: var(--h-xs); padding: 0 var(--s-2); display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: var(--r-xs); background: var(--canvas); color: var(--ink-3); font: 500 var(--t-micro)/1 var(--font-mono); }
body.has-sb .sb-search.on { border-color: var(--ink); color: var(--ink); }
body.has-sb .sb-search.on svg { color: var(--ink); }
/* 섹션 라벨 — 12/600 ink-3(한국어), 위 16 아래 4 */
body.has-sb .sb-label { margin: var(--s-4) 0 var(--s-1); padding: 0 10px; font: 600 var(--t-caption)/1.4 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .sb-nav > .sb-label:first-child { margin-top: var(--s-1); }
/* 행 — 32h · r8 · 0 10 · gap 10 · 아이콘 18 ink-3 · 라벨 14/500 ink-2. 켬 = wash-2 + ink(굵기 불변) */
body.has-sb .sb-nav { gap: 2px; }
body.has-sb .sb-link, body.has-sb .sb-back {
  height: var(--h-sm); padding: 0 10px; gap: 10px; border-radius: var(--r-sm);
  font: 500 var(--t-ui)/1 var(--font); letter-spacing: -0.01em; color: var(--ink-2);
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
body.has-sb .sb-link svg, body.has-sb .sb-back svg { width: var(--ic-md); height: var(--ic-md); color: var(--ink-3); transition: color var(--dur-1) var(--ease-out); }
body.has-sb .sb-link:active, body.has-sb .sb-back:active { background: var(--wash-2); }
body.has-sb .sb-nav .sb-link.on:not(.sb-link-danger), body.has-sb .sb-nav .sb-link.on:not(.sb-link-danger):hover { background: var(--sb-on); color: var(--ink); font-weight: 500; }
body.has-sb .sb-link.on svg { color: var(--ink); }
body.has-sb .sb-sub { height: var(--h-sm); padding-left: 10px; font-size: var(--t-ui); }
/* 채널 '#' — 아이콘 열(18) 가운데, Pretendard(모노 폐지) */
body.has-sb .sb-hash { width: var(--ic-md); margin: 0; text-align: center; flex: none; font: 500 var(--t-ui)/1 var(--font); color: var(--ink-3); }
body.has-sb .sb-sub.on .sb-hash { color: var(--ink); }
/* 카운트 배지 — 잉크(노랑 볼트 폐지, §4.5) */
body.has-sb .sb-badge { margin-left: auto; flex: none; animation: none; } /* 크롬은 다시 등장하지 않는다 — 불러올 때마다 튀지 않고, 새로 생길 때만 m-pop */
body.has-sb .sb-badge.is-new { animation: m-pop var(--dur-4) var(--spring-pop); }
body.has-sb .sb-link.sb-chat .sb-chat-ext { color: var(--ink-4); }
body.has-sb .sb-link.sb-chat .sb-chat-ext svg { width: 14px; height: 14px; }
body.has-sb .sb-lock { color: var(--ink-4); }
body.has-sb .sb-foot { gap: 2px; padding-top: var(--s-2); }
body.has-sb .sb-user-menu > summary { border-radius: var(--r-sm); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .sb-user { height: var(--h-md); padding: 0 var(--s-2); gap: 10px; }
body.has-sb .sb-user-name { font: 600 var(--t-footnote)/1.3 var(--font); color: var(--ink); }
body.has-sb .sb-user-sub { font: 400 var(--t-caption)/1.3 var(--font); color: var(--ink-3); }
body.has-sb .sb-user-gear { color: var(--ink-3); }
body.has-sb .sb-user-gear svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .sb-powered { padding: var(--s-1) var(--s-2) 0; font: 400 var(--t-caption)/1.4 var(--font); letter-spacing: 0; color: var(--ink-3); transition: color var(--dur-1) var(--ease-out); }
body.has-sb .sb-powered strong { font-weight: 600; }
body.has-sb .sb-cta .btn { border-radius: var(--r-pill); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .sb-ws > summary:hover, body.has-sb .sb-ws[open] > summary, body.has-sb .sb-user-menu > summary:hover, body.has-sb .sb-user-menu[open] > summary { background: var(--wash-1); }
  body.has-sb .sb-icon-btn:hover { background: var(--wash-2); color: var(--ink); }
  body.has-sb .sb-search:hover { border-color: var(--line-2); color: var(--ink-2); }
  body.has-sb .sb-link:hover, body.has-sb .sb-back:hover { background: var(--sb-hover); color: var(--ink); }
  body.has-sb .sb-link:hover svg, body.has-sb .sb-back:hover svg { color: var(--ink-2); }
  body.has-sb .sb-link:not(.on):hover:active, body.has-sb .sb-back:hover:active { background: var(--wash-2); }
  body.has-sb .sb-powered:hover { color: var(--ink); }
}

/* 패널 — 반경 16(앱 패널, §2.5), 헤어라인, 그림자 없음 */
body.has-sb .panel { border-color: var(--line); border-radius: var(--r-lg); box-shadow: none; }
body.has-sb .panel.page-chat { min-height: 0; }
body.has-sb .page:not(.page-chat):not(.page-thread):not(.page-article) { padding-bottom: var(--s-11); }

/* 봇 FAB — 48 원, 흰 면 + 헤어라인 + 떠 있는 그림자. 봇 로고의 파란 글로우 삭제(§5.12) */
body.has-sb .bot-fab { z-index: var(--z-fab); width: var(--h-lg); height: var(--h-lg); border: 1px solid var(--line); background: var(--paper); box-shadow: var(--e-3); transform: none; transition: translate var(--dur-2) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .bot-fab:hover { transform: none; }
body.has-sb .bot-fab:active { transform: none; scale: var(--m-press-icon); transition-duration: var(--dur-1); }
body.has-sb .bot-logo { animation: none; filter: none; }
body.has-sb .bot-fab .bot-logo { width: var(--ic-xl); height: var(--ic-xl); }
body.has-sb .bot-spark, body.has-sb .bot-fab .bot-spark { width: 8px; height: 8px; background: var(--ink); box-shadow: 0 0 0 2px var(--paper); }
body.has-sb .bot-think-dots i { background: var(--ink); }
body.has-sb .bot-island { border-radius: var(--r-xl); border: 1px solid var(--line); box-shadow: var(--e-3); }
body.has-sb .bot-hbtn { width: var(--h-sm); height: var(--h-sm); border-radius: 50%; color: var(--ink-3); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
body.has-sb .bot-hello { font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; }
body.has-sb .bot-chip { height: var(--h-sm); padding: 0 14px; border: 0; border-radius: var(--r-pill); background: var(--wash-2); color: var(--ink); font: 500 var(--t-footnote)/1 var(--font); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .bot-msg { font-size: var(--t-ui); color: var(--ink); }
body.has-sb .bot-msg.mine { border-radius: var(--r-lg); background: var(--wash-2); }
body.has-sb .bot-form { border-color: var(--line-2); border-radius: var(--r-pill); transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out); }
body.has-sb .bot-form:focus-within { border-color: var(--ink); box-shadow: var(--ring-input); }
body.has-sb .bot-form .input { height: var(--h-sm); font-size: var(--t-ui); }
body.has-sb .bot-send { width: var(--h-sm); height: var(--h-sm); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .bot-hbtn:hover, body.has-sb .bot-chip:hover { background: var(--wash-3); color: var(--ink); }
}

/* ─────────────────────────────────────────────────────────────
   2. 버튼(§4.1) — 기존 클래스 이름(.btn · .btn-sm · .btn-lg · .btn-ghost · .btn-danger)을 v5 크기·변형으로.
      sm 32 · md 40 · lg 48. .btn-ghost = 보조(secondary, 워시). 손을 떼면 스프링으로 돌아온다
   ───────────────────────────────────────────────────────────── */
body.has-sb .btn:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) {
  height: var(--h-md); padding: 0 18px; gap: var(--s-2); border: 0; border-radius: var(--r-pill);
  background: var(--ink); color: #fff; font: 500 var(--t-ui)/1 var(--font); letter-spacing: -0.01em; white-space: nowrap;
  transform: none;
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring);
}
body.has-sb .btn:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) svg { width: var(--ic-sm); height: var(--ic-sm); flex: none; }
body.has-sb .btn:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):active { transform: none; scale: var(--m-press); transition-duration: var(--dur-1); transition-timing-function: var(--ease-out); }
body.has-sb .btn.btn-ghost:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { background: var(--wash-2); color: var(--ink); border: 0; box-shadow: none; }
body.has-sb .btn.btn-danger:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { background: transparent; color: var(--danger); border: 0; box-shadow: inset 0 0 0 1px var(--danger-line); }
body.has-sb .btn.btn-sm:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { height: var(--h-sm); padding: 0 14px; font-size: var(--t-footnote); border-radius: var(--r-pill); }
body.has-sb .btn.btn-sm:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) svg { width: 14px; height: 14px; }
body.has-sb .btn.btn-lg:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { height: var(--h-lg); padding: 0 22px; font-size: var(--t-body); border-radius: var(--r-pill); }
body.has-sb .btn.btn-lg:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .btn:disabled:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), body.has-sb .btn[disabled]:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { background: var(--wash-2); color: var(--ink-4); cursor: default; scale: 1; box-shadow: none; }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .btn:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover { background: var(--ink-hover); }
  body.has-sb .btn.btn-ghost:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover { background: var(--wash-3); }
  body.has-sb .btn.btn-danger:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover { background: var(--danger-wash); }
  body.has-sb .btn:disabled:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover, body.has-sb .btn[disabled]:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover { background: var(--wash-2); }
}
body.has-sb :is(.btn, .send-btn, .fpill, .seg > a, .seg > button, .icon-act, .thread-backlink, .modal-x, .modal-close):focus-visible:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { outline: var(--focus); outline-offset: var(--focus-offset); }
body.has-sb :is(.nrow, .erow, .mu-card, .ch-item, .spot-pill, .spot-row, .jcard, .lcard-link, .art-back, .cal-nav a, .cal-today, .dmrow, .notif, .day-row):focus-visible { outline: var(--focus); outline-offset: var(--focus-offset); }
body.has-sb :is(.sb-link, .sb-back, .sb-search):focus-visible { outline: var(--focus); outline-offset: -2px; }

/* 주 CTA — 팀 앱 콘텐츠 화면의 주 행동 하나만 팀색(tint, §2.1): 페이지 머리 행동의 첫 버튼 · 모임 참가 · 글쓰기 제출.
   나머지는 잉크. 관리(.adm)의 제출은 17절이 잉크로 덮는다(P5) */
body.has-sb .page-actions > .btn:first-child:not(.btn-ghost):not(.btn-danger),
body.has-sb .form-page .form-actions > .btn[type=submit]:not(.btn-ghost):not(.btn-danger),
body.has-sb .mu-join .btn.mu-cta,
body.has-sb :is(.form-page, .form-card) .form-actions .btn[type=submit]:not(.btn-ghost):not(.btn-danger) {
  background: var(--tint); color: var(--tint-fg);
}
@media (hover: hover) and (pointer: fine) {
  body.has-sb .page-actions > .btn:first-child:not(.btn-ghost):not(.btn-danger):hover,
  body.has-sb .form-page .form-actions > .btn[type=submit]:not(.btn-ghost):not(.btn-danger):hover,
  body.has-sb .mu-join .btn.mu-cta:hover,
  body.has-sb :is(.form-page, .form-card) .form-actions .btn[type=submit]:not(.btn-ghost):not(.btn-danger):hover { background: color-mix(in oklab, var(--tint) 88%, #000); }
}
body.has-sb .set-head .btn:not(.btn-ghost):not(.btn-danger) { background: var(--x-brand); color: #fff; font-weight: 600; }
body.has-sb .set-head .btn:not(.btn-ghost):not(.btn-danger):hover { background: var(--x-brand-hover); }
body.has-sb .compose-modal button.btn[type=submit]:disabled { background: var(--wash-2); color: var(--ink-4); }

/* 아이콘 버튼 — 원형 32(행 안)·36(머리) · 투명 · 아이콘 ink-2(§4.1 icon). 누름 .92 */
body.has-sb .icon-act:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), body.has-sb .icon-btn:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) {
  position: relative; width: var(--h-sm); height: var(--h-sm); border-radius: 50%; color: var(--ink-2);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring);
}
body.has-sb .icon-act:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) svg, body.has-sb .icon-btn:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .icon-act.icon-act-sm:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { width: var(--h-sm); height: var(--h-sm); }
body.has-sb .icon-act.icon-act-sm:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) svg { width: 14px; height: 14px; }
body.has-sb :is(.icon-act, .icon-btn):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):active { scale: var(--m-press-icon); transition-duration: var(--dur-1); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb :is(.icon-act, .icon-btn):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover { background: var(--wash-2); color: var(--ink); }
  body.has-sb .icon-act.icon-act-danger:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover { background: var(--danger-wash); color: var(--danger); }
}
/* 닫기(모달) · 뒤로(스레드) — 원형 32·36, 워시 */
body.has-sb :is(.modal-x, .modal-close) { position: absolute; top: var(--s-4); right: var(--s-4); width: var(--h-sm); height: var(--h-sm); margin: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--wash-2); color: var(--ink-2); font-size: var(--t-body); line-height: 1; transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb :is(.modal-x, .modal-close) svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb :is(.modal-x, .modal-close)::after { content: ''; position: absolute; inset: -6px; }
body.has-sb :is(.modal-x, .modal-close):active { scale: var(--m-press-icon); }
body.has-sb .thread-backlink { position: relative; width: 36px; height: 36px; flex: none; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--wash-2); color: var(--ink); font-size: var(--t-body); transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .thread-backlink svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .thread-backlink::after { content: ''; position: absolute; inset: -4px; }
body.has-sb .thread-backlink:active { scale: var(--m-press-icon); }
@media (hover: hover) and (pointer: fine) { body.has-sb :is(.modal-x, .modal-close, .thread-backlink):hover { background: var(--wash-3); color: var(--ink); } }

/* 전송 — 40 원. 라운지·DM·댓글에서 그 화면의 주 행동(tint), 비활성은 워시 */
body.has-sb .send-btn { position: relative; width: var(--h-md); height: var(--h-md); flex: none; border-radius: 50%; background: var(--tint); color: var(--tint-fg); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .send-btn::after { content: ''; position: absolute; inset: -2px; }
body.has-sb .send-btn svg { width: var(--ic-sm); height: var(--ic-sm); margin: 0; }
body.has-sb .send-btn:active:not(:disabled) { scale: var(--m-press-icon); transition-duration: var(--dur-1); }
body.has-sb .send-btn:disabled { opacity: 1; background: var(--wash-2); color: var(--ink-4); }
body.has-sb .bot-send, body.has-sb .bot-send:hover:not(:disabled) { background: var(--ink); color: #fff; }
body.has-sb .bot-send:disabled { background: var(--wash-2); color: var(--ink-4); }
@media (hover: hover) and (pointer: fine) { body.has-sb .send-btn:hover:not(:disabled):not(.bot-send) { background: color-mix(in oklab, var(--tint) 88%, #000); } }

/* ─────────────────────────────────────────────────────────────
   3. 입력 · 필드(§4.2) — 폼 48 · r12 · 15px(≤699 16) · 헤어라인 line-2 · focus 잉크 + 링
   ───────────────────────────────────────────────────────────── */
body.has-sb .input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), body.has-sb select.input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), body.has-sb textarea.input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) {
  height: var(--h-lg); padding: 0 var(--s-4); background: var(--paper); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: var(--r-md); font: 400 var(--t-body)/1.45 var(--font); letter-spacing: -0.01em;
  transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out);
}
body.has-sb .input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):focus, body.has-sb .input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):focus-visible { outline: none; border-color: var(--ink); box-shadow: var(--ring-input); }
body.has-sb .input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::placeholder { color: var(--ink-3); }
body.has-sb .input[aria-invalid="true"]:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { border-color: var(--danger); box-shadow: var(--ring-danger); }
body.has-sb textarea.input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { height: auto; min-height: 120px; padding: var(--s-3) var(--s-4); line-height: 1.6; resize: vertical; }
body.has-sb textarea.input.input-deck:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { min-height: 96px; }
body.has-sb select.input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) {
  appearance: none; padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6965' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6.5 9.5 5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
  background-position: right var(--s-4) center; background-size: 12px 12px; background-repeat: no-repeat;
}
@media (hover: hover) and (pointer: fine) { body.has-sb .input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover:not(:focus):not(:disabled) { border-color: var(--line-3); } }
@media (max-width: 699px) { body.has-sb :is(.input, select.input, textarea.input):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { font-size: 16px; } }
body.has-sb input[type=file].input:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), body.has-sb input[type=file]:not(.input):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) {
  height: auto; min-height: 56px; padding: var(--s-2) var(--s-3); line-height: 40px;
  border: 1px solid var(--line-2); border-radius: var(--r-md); background: var(--paper);
  font: 400 var(--t-footnote)/40px var(--font); color: var(--ink-3); width: 100%;
}
body.has-sb input[type=file]:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::file-selector-button {
  height: var(--h-sm); margin-right: var(--s-3); padding: 0 14px; border: 0; border-radius: var(--r-pill);
  background: var(--wash-2); color: var(--ink); font: 500 var(--t-footnote) var(--font); cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out);
}
body.has-sb input[type=file]:focus-visible:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { border-color: var(--ink); box-shadow: var(--ring-input); outline: none; }
body.has-sb .input-prefix:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { background: var(--paper); border: 1px solid var(--line-2); border-radius: var(--r-md); transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out); }
body.has-sb .input-prefix:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > input { height: 46px; }
body.has-sb .input-prefix:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):focus-within { border-color: var(--ink); box-shadow: var(--ring-input); }
body.has-sb .field:not(.thumb-field):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { margin-bottom: var(--s-6); }
body.has-sb .field > label:not(.feat-toggle):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), body.has-sb .field > .field-label:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { display: block; margin-bottom: var(--s-2); font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink); }
body.has-sb .hint:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { margin-top: var(--s-2); font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .form-row:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { gap: var(--s-3); }
body.has-sb input[type=checkbox]:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), body.has-sb input[type=radio]:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { accent-color: var(--ink); width: 18px; height: 18px; }
body.has-sb .check-row { display: flex; align-items: center; gap: var(--s-2); cursor: pointer; font: 500 var(--t-ui)/1.45 var(--font); color: var(--ink); }
body.has-sb .form-err { display: flex; align-items: center; gap: var(--s-2); margin-bottom: var(--s-6); padding: var(--s-3) var(--s-4); border: 0; border-radius: var(--r-md); background: var(--danger-wash); color: var(--danger); font: 500 var(--t-ui)/1.45 var(--font); }
body.has-sb .feat-toggle { display: inline-flex; align-items: center; margin: 0; height: var(--h-sm); padding: 0 14px; border: 0; border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
body.has-sb .field:not(.thumb-field):has(> label.feat-toggle):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { margin-bottom: var(--s-6); }
body.has-sb .feat-toggle:has(input:checked) { background: var(--ink); color: #fff; }
body.has-sb .code-pill { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-1) var(--s-1) var(--s-1) var(--s-4); border: 0; border-radius: var(--r-md); background: var(--wash-2); font: 400 var(--t-footnote)/1.45 var(--font-mono); letter-spacing: 0; color: var(--ink); }
body.has-sb .code-pill > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.has-sb .code-pill button { flex: none; height: var(--h-sm); padding: 0 14px; border-radius: var(--r-pill); background: var(--paper); color: var(--ink); font: 500 var(--t-footnote)/1 var(--font); box-shadow: inset 0 0 0 1px var(--line); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb:not(.x-plat) .invite-row { gap: var(--s-3) var(--s-4); }
body.has-sb:not(.x-plat) .invite-row + .invite-row { margin-top: var(--s-3); }
body.has-sb:not(.x-plat) .invite-row .lbl { font: 600 var(--t-footnote)/1.45 var(--font); color: var(--ink); width: 88px; }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .feat-toggle:hover { background: var(--wash-3); color: var(--ink); }
  body.has-sb .feat-toggle:has(input:checked):hover { background: var(--ink-hover); color: #fff; }
  body.has-sb .code-pill button:hover { background: var(--canvas); }
  body.has-sb input[type=file]:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::file-selector-button:hover { background: var(--wash-3); }
}
/* 공개 범위 세그먼트(/meetups/new와 같은 마크업, §4.2 — 선택지가 둘이면 세그먼트) */
body.has-sb:not(.x-plat) .mu-scope { border: 0; padding: 0; min-width: 0; }
body.has-sb:not(.x-plat) .mu-scope > legend { padding: 0; }
body.has-sb:not(.x-plat) .mu-scope-seg { display: inline-flex; }
body.has-sb:not(.x-plat) .mu-scope-seg > label { position: relative; display: inline-flex; align-items: center; justify-content: center; min-width: 96px; height: 100%; margin: 0; font: 500 var(--t-footnote)/1 var(--font); color: var(--ink-3); transition: color var(--dur-1) var(--ease-out); }
body.has-sb:not(.x-plat) .mu-scope-seg > label:has(input:checked) { color: var(--ink); }
body.has-sb:not(.x-plat) .mu-scope-seg input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
body.has-sb:not(.x-plat) .mu-scope-seg > label:has(input:focus-visible) { outline: var(--focus); outline-offset: var(--focus-offset); }
body.has-sb:not(.x-plat) .mu-scope:has(input[value="open"]:checked) .mu-scope-h-soc,
body.has-sb:not(.x-plat) .mu-scope:has(input[value="society"]:checked) .mu-scope-h-open { display: none; }

/* ─────────────────────────────────────────────────────────────
   4. 칩 · 배지 · 태그 · kbd(§4.5) — 상태 칩 한 종: 24h · 0 10 · 12/500 · 워시. 강조(잉크)는 하나
   ───────────────────────────────────────────────────────────── */
body.has-sb .chip:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) {
  display: inline-flex; align-items: center; gap: 6px; height: var(--h-xs); padding: 0 10px; border: 0; border-radius: var(--r-pill);
  background: var(--wash-2); color: var(--ink-2); font: 500 var(--t-caption)/1 var(--font); letter-spacing: 0; white-space: nowrap;
}
body.has-sb :is(.chip-soft, .chip-tag, .chip-accent):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { background: var(--wash-2); color: var(--ink-2); border: 0; }
body.has-sb :is(.chip.strong, .chip.chip-pin):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { background: var(--ink); color: #fff; font-weight: 500; }
body.has-sb .chip.outline:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { background: transparent; box-shadow: inset 0 0 0 1px var(--line-2); color: var(--ink-2); }
body.has-sb a.chip-tag:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { position: relative; transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb a.chip-tag:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):active { scale: var(--m-press-chip); transition-duration: var(--dur-1); }
@media (hover: hover) and (pointer: fine) { body.has-sb a.chip-tag:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *):hover { background: var(--wash-3); color: var(--ink); } }
body.has-sb .kbd:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { font: 500 var(--t-micro)/18px var(--font-mono); padding: 0 6px; border: 1px solid var(--line); border-radius: var(--r-xs); background: var(--paper); color: var(--ink-3); }
body.has-sb .me-avatar .avatar-txt { display: inline-flex; }
body.has-sb .online-dot, body.has-sb .notif-dot, body.has-sb .mcard-on { width: 8px; height: 8px; border-radius: 50%; background: var(--ink); box-shadow: 0 0 0 2px var(--paper); }
body.has-sb .dot:not(:empty) { color: var(--ink-4); margin: 0 6px; }
body.has-sb .num { font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* ─────────────────────────────────────────────────────────────
   5. 페이지 폭 · 머리(§2.9 · §4.10) — 한 기둥이 패널 가운데(패널 폭과 무관하게 좌우 여백 대칭, axis).
      기둥 폭은 화면 성격대로 세 단: 목록·그리드·표·달력 = wide 1012 · 읽기·상세·설정·글쓰기 = main 720(.c-main) ·
      짧은 폼 = form 560(.c-form). 머리(h1)는 기둥의 왼쪽 — 위(top)는 모든 화면이 같고, x는 기둥 폭이 바뀔 때만
      vt-title 모핑으로 미끄러진다. 기둥 안 요소는 기둥을 꽉 채운다(왼쪽에 붙은 좁은 칸 없음)
   ───────────────────────────────────────────────────────────── */
body.has-sb:not(.x-plat) .panel :is(.container, .form-page, .pf) {
  width: 100%; max-width: calc(var(--w-wide) + 2 * var(--gutter)); margin: 0 auto;
  padding-left: var(--gutter); padding-right: var(--gutter);
}
body.has-sb:not(.x-plat) .panel :is(.container.c-main, .container.cx-home, .form-page) { max-width: calc(var(--w-main) + 2 * var(--gutter)); }
body.has-sb:not(.x-plat) .panel .container.c-form { max-width: calc(var(--w-form) + 2 * var(--gutter)); }
body.has-sb:not(.x-plat) .panel :is(.container.c-main, .container.c-form, .form-page) :is(.form-stack, .form-plain, .form-card) { max-width: none; }
body.has-sb:not(.x-plat) .panel .form-page { padding-top: 0; padding-bottom: var(--s-11); }

/* 페이지 머리 — 위 48(≤699 24) · h1 title-2(32/26) · 리드 15 ink-3 · 행동 md(첫 버튼 tint) · 아래 32.
   자식이 곧 진입 안무 순서([data-enter]). 행동·날짜 타일은 오른쪽 열 */
body.has-sb:not(.x-plat) .page-head:has(> .page-title) {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s-6); align-items: end;
  margin: 0 0 var(--s-7); padding: var(--s-9) 0 0;
}
body.has-sb:not(.x-plat) .page-head:has(> .page-title) > * { grid-column: 1; min-width: 0; }
body.has-sb:not(.x-plat) .page-head > .page-actions { grid-column: 2; grid-row: 1 / span 4; align-self: end; display: flex; align-items: center; gap: var(--s-2); }
body.has-sb:not(.x-plat) .page-head > .page-tile { grid-column: 2; grid-row: 1 / span 4; align-self: start; }
body.has-sb:not(.x-plat) .page-head > .eyebrow { margin-bottom: var(--s-2); }
body.has-sb .page-title { font: 600 var(--t-title-2)/1.1 var(--font); letter-spacing: -0.035em; color: var(--ink); text-wrap: balance; }
body.has-sb .page-title .sec-count { margin-left: var(--s-2); font: 500 var(--t-ui)/1 var(--font); letter-spacing: 0; color: var(--ink-3); vertical-align: 0.35em; }
body.has-sb .page-lead { margin-top: var(--s-2); max-width: 560px; font: 400 var(--t-body)/1.65 var(--font); letter-spacing: -0.01em; color: var(--ink-3); text-wrap: pretty; }
body.has-sb:not(.x-plat) .page-head:has(> .page-title) + .page-body, body.has-sb:not(.x-plat) .page-head:has(> .page-title) ~ .page-body { padding-top: 0; }
/* 옛 머리(모집 관리 등 다른 패키지 화면) — 크기만 v5 */
body.has-sb:not(.x-plat) :is(.page-head, .set-head, .admin-head):not(:has(> .page-title)) { padding: var(--s-9) 0 var(--s-2); margin-bottom: 0; }
body.has-sb:not(.x-plat) :is(.page-head, .set-head, .admin-head):not(:has(> .page-title)) h1 {
  font: 600 var(--t-title-2)/1.1 var(--font); letter-spacing: -0.035em; color: var(--ink); text-wrap: balance;
}
body.has-sb:not(.x-plat) :is(.page-head, .set-head, .admin-head) h1 .sec-count { font: 500 var(--t-ui)/1 var(--font); color: var(--ink-3); margin-left: var(--s-2); letter-spacing: 0; }
body.has-sb:not(.x-plat) :is(.page-head, .set-head, .admin-head):not(:has(> .page-title)) p { margin-top: var(--s-2); max-width: 560px; font: 400 var(--t-body)/1.65 var(--font); color: var(--ink-3); letter-spacing: -0.01em; }
body.has-sb:not(.x-plat) .set-head { align-items: flex-end; }
body.has-sb:not(.x-plat) .set-head + * { margin-top: 28px; }
body.has-sb .page-body { padding-top: var(--s-6); }

/* 섹션 — 앱 섹션 제목 headline 20/600, 섹션 사이 48(§2.3) */
body.has-sb .sec-head { margin-bottom: var(--s-4); align-items: baseline; flex-wrap: wrap; row-gap: var(--s-1); }
body.has-sb .sec-head h2, body.has-sb .sec-h, body.has-sb .mgroup-h, body.has-sb .vgroup-head h2 { font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; color: var(--ink); text-wrap: balance; }
body.has-sb .sec-h { margin-bottom: var(--s-4); }
body.has-sb .sec-head-gap { margin-top: var(--s-9); }
body.has-sb .sec-count { font: 500 var(--t-ui)/1 var(--font); letter-spacing: 0; color: var(--ink-3); margin-left: 6px; font-variant-numeric: tabular-nums; }
body.has-sb .sec-more { position: relative; display: inline-flex; align-items: center; gap: 2px; font: 500 var(--t-ui)/1.45 var(--font); color: var(--ink-2); transition: color var(--dur-1) var(--ease-out); }
body.has-sb .sec-more svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .sec-eyebrow, body.has-sb .pf-sec-eyebrow { font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
body.has-sb .sec { padding-top: var(--s-9); }
body.has-sb .page-body > .sec:first-child { padding-top: 0; }
body.has-sb .sec-note { margin: calc(-1 * var(--s-2)) 0 var(--s-4); }
@media (hover: hover) and (pointer: fine) { body.has-sb .sec-more:hover { color: var(--ink); } }

/* ─────────────────────────────────────────────────────────────
   6. 컨트롤(§4.6) — 세그먼트(보기 전환: 알약 하나가 미끄러진다) · 필터 칩 · 밑줄 탭(하위 페이지: 막대 하나, vt-tab)
   ───────────────────────────────────────────────────────────── */
body.has-sb .seg { height: 36px; padding: 3px; gap: 0; border-radius: var(--r-pill); background: var(--wash-2); }
body.has-sb .seg > a, body.has-sb .seg > button {
  position: relative; z-index: 1; height: 100%; padding: 0 14px; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; font: 500 var(--t-footnote)/1 var(--font); color: var(--ink-3);
  background: transparent; box-shadow: none;
  transition: color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring);
}
body.has-sb .seg > .on { color: var(--ink); font-weight: 500; }
/* JS 전(인디케이터 없음)에는 켠 항목이 제 알약을 칠한다 */
body.has-sb .seg:not(.is-ready) > .on { background: var(--paper); box-shadow: var(--e-1), 0 0 0 .5px var(--line); }
body.has-sb .seg > :is(a, button):active { scale: var(--m-press-chip); transition-duration: var(--dur-1); }
body.has-sb .fbar { gap: var(--s-2); margin-bottom: var(--s-4); }
body.has-sb .fpill {
  position: relative; height: var(--h-sm); padding: 0 14px; gap: 6px; border: 0; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; background: var(--wash-2); color: var(--ink-2); font: 500 var(--t-footnote)/1 var(--font);
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring);
}
body.has-sb .fpill:active { scale: var(--m-press-chip); transition-duration: var(--dur-1); }
body.has-sb .fpill.on, body.has-sb .fpill.on:hover { background: var(--ink); color: #fff; }
body.has-sb .fpill .n { margin: 0; font-size: inherit; color: inherit; opacity: .6; }
body.has-sb .utabs { position: relative; display: flex; gap: var(--s-6); margin-bottom: var(--s-6); box-shadow: inset 0 -1px var(--line); }
body.has-sb .utabs[data-tabs] { height: auto; padding: 0; border-radius: 0; background: none; }
body.has-sb .utabs > a { position: relative; z-index: 1; height: var(--hit); display: inline-flex; align-items: center; padding: 0; font: 500 var(--t-body)/1 var(--font); color: var(--ink-3); transition: color var(--dur-1) var(--ease-out); }
body.has-sb .utabs > a.on { color: var(--ink); font-weight: 500; }
body.has-sb .arch-bar { min-height: 36px; margin-bottom: var(--s-6); gap: var(--s-4); }
body.has-sb .arch-tools { gap: var(--s-2); }
body.has-sb .menu.grp > summary { height: 36px; padding: 0 var(--s-3); gap: 6px; border-radius: var(--r-pill); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
body.has-sb .menu.grp > summary svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .menu.grp[open] > summary { background: var(--wash-2); color: var(--ink); }
body.has-sb .cal-bar { margin-bottom: var(--s-6); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .seg > a:hover, body.has-sb .seg > button:hover, body.has-sb .utabs > a:hover { color: var(--ink); }
  body.has-sb .fpill:not(.on):hover { background: var(--wash-3); color: var(--ink); }
  body.has-sb .menu.grp > summary:hover { background: var(--wash-2); color: var(--ink); }
}

/* ─────────────────────────────────────────────────────────────
   7. 빈 상태 · 토스트 · 메뉴 · 모달 · 스포트라이트(§4.7 · §4.8)
   ───────────────────────────────────────────────────────────── */
/* 빈 상태는 기둥(또는 그것이 든 칸)의 가운데 — 왼쪽에 붙은 420 상자로 뜨지 않게(axis) */
body.has-sb .empty { padding: var(--s-9) var(--s-6); margin: 0 auto; border: 0; background: none; }
body.has-sb .empty-ico { width: var(--h-md); height: var(--h-md); border-radius: 50%; background: var(--wash-2); color: var(--ink-3); margin: 0 auto; display: grid; place-items: center; }
body.has-sb .empty-ico svg { width: var(--ic-lg); height: var(--ic-lg); stroke-width: 1.7; }
body.has-sb .empty-title { margin-top: var(--s-4); font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .empty-sub { margin: 6px auto 0; max-width: 36ch; font: 400 var(--t-ui)/1.65 var(--font); color: var(--ink-3); }
body.has-sb .empty > .btn, body.has-sb .empty .btn { margin-top: var(--s-5); min-width: 0; }
body.has-sb .feed-empty, body.has-sb .chat-empty { padding: var(--s-5) 0; }

body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { min-width: 200px; padding: 6px; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--paper); box-shadow: var(--e-3); }
body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > a, body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > form > button, body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > button, body.has-sb .menu-pop .mi {
  min-height: 36px; display: flex; align-items: center; gap: 10px; padding: 0 var(--s-3); border-radius: var(--r-sm);
  font: 500 var(--t-ui)/1.45 var(--font); color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
body.has-sb .menu-pop .menu-head { padding: var(--s-2) var(--s-3) 10px; margin-bottom: 6px; border-bottom-color: var(--line); }
body.has-sb .menu-pop .menu-head strong { font: 600 var(--t-ui)/1.45 var(--font); color: var(--ink); }
body.has-sb .menu-pop .menu-head span { font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .menu-sep { background: var(--line); margin: 6px 0; }
body.has-sb .menu.more > summary { border-radius: 50%; }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > a:hover, body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > form > button:hover, body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > button:hover, body.has-sb .menu-pop .mi:hover { background: var(--wash-2); color: var(--ink); }
}
@media (pointer: coarse) { body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > :is(a, button), body.has-sb .menu-pop:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) > form > button { min-height: var(--hit); } }

/* 모달(작성 · 채널 · 새 메시지 · 그날 일정) — 폭 min(640, 100vw-32), r22, 패딩 24, top 12vh. 제목 17/600, 닫기 32 원(오른쪽 위) */
body.has-sb .modal-backdrop, body.has-sb .confirm-back { background: var(--scrim); backdrop-filter: var(--scrim-blur); -webkit-backdrop-filter: var(--scrim-blur); }
body.has-sb .compose-modal, body.has-sb .confirm-box { position: relative; border: 0; border-radius: var(--r-xl); box-shadow: var(--e-3); background: var(--paper); }
body.has-sb .compose-modal { width: min(640px, 100vw - 32px); max-width: 640px; padding: var(--s-6); }
body.has-sb .compose-modal .modal-title { margin: 0 0 var(--s-4); padding-right: var(--s-9); font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .compose-modal .composer-input { min-height: 104px; font: 400 var(--t-lead)/1.65 var(--font); letter-spacing: -0.012em; color: var(--ink); }
body.has-sb .compose-modal .composer-input::placeholder { color: var(--ink-3); }
body.has-sb .compose-modal .composer-post-row { gap: var(--s-3); }
body.has-sb .drop-hint {
  flex-direction: row; justify-content: center; gap: 10px; width: 100%;
  padding: var(--s-4); margin: var(--s-2) 0 var(--s-1); border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--canvas);
  font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3);
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
body.has-sb .drop-hint svg { width: var(--ic-lg); height: var(--ic-lg); color: var(--ink-3); }
body.has-sb .composer-post-foot { border-top: 1px solid var(--line); margin-top: var(--s-4); padding-top: var(--s-4); gap: var(--s-2); }
body.has-sb .composer-post-sp { flex: 1; }
body.has-sb .compose-modal button.btn[type=submit] { height: var(--h-md); padding: 0 18px; font-size: var(--t-ui); }
body.has-sb .attach-btn { position: relative; width: 36px; height: 36px; border-radius: 50%; color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .attach-btn svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .attach-btn:active { scale: var(--m-press-icon); }
body.has-sb .modal-sm { max-width: 440px; }
body.has-sb .modal-list { margin: 0 calc(-1 * var(--s-3)); max-height: 60vh; overflow-y: auto; }
body.has-sb .modal-foot { display: flex; justify-content: flex-end; gap: var(--s-2); margin-top: var(--s-6); }
body.has-sb .confirm-box { padding: var(--s-6); }
body.has-sb .confirm-msg { font: 500 var(--t-body)/1.65 var(--font); color: var(--ink); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .drop-hint:hover { background: var(--wash-1); border-color: var(--line-2); }
  body.has-sb .attach-btn:hover { background: var(--wash-2); color: var(--ink); }
}
/* 그날 일정 시트(캘린더) */
body.has-sb .day-list { display: flex; flex-direction: column; margin: 0 calc(-1 * var(--s-3)); }
body.has-sb .day-row { display: flex; align-items: center; gap: var(--s-4); min-height: var(--row); padding: var(--s-2) var(--s-3); border-radius: var(--r-md); color: var(--ink); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .day-row + .day-row { box-shadow: inset 0 1px var(--line); }
body.has-sb .day-t { flex: none; width: 44px; font: 500 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .day-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
body.has-sb .day-main strong { font: 500 var(--t-body)/1.45 var(--font); color: var(--ink); }
body.has-sb .day-main span { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .day-row:active { background: var(--wash-2); }
@media (hover: hover) and (pointer: fine) { body.has-sb .day-row:hover { background: var(--wash-1); } body.has-sb .day-row:hover:active { background: var(--wash-2); } }

/* 스포트라이트 ⌘K — 모달과 같은 면, 결과 행은 스태거 없음 */
body.has-sb .spot-back { background: var(--scrim); }
body.has-sb .spot { width: min(640px, 100% - 32px); border: 0; border-radius: var(--r-xl); box-shadow: var(--e-3); }
body.has-sb .spot-head { height: var(--row); padding: 0 var(--s-4) 0 var(--s-5); gap: var(--s-3); border-bottom-color: var(--line); }
body.has-sb .spot-head > svg { width: var(--ic-md); height: var(--ic-md); color: var(--ink-3); }
body.has-sb .spot-input { font: 400 var(--t-lead)/1.45 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .spot .kbd { font: 500 var(--t-micro)/20px var(--font-mono); padding: 0 6px; border-radius: var(--r-xs); background: var(--paper); border: 1px solid var(--line); color: var(--ink-3); }
body.has-sb .spot-body { padding: var(--s-2); }
body.has-sb .spot-group-label { padding: var(--s-3) var(--s-3) 6px; font: 600 var(--t-caption)/1.4 var(--font); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
body.has-sb .spot-row { min-height: var(--row); padding: var(--s-2) var(--s-3); border-radius: var(--r-md); gap: var(--s-3); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .spot-row.on, body.has-sb .spot-row:hover { background: var(--wash-2); }
body.has-sb .spot-ic { width: var(--h-sm); height: var(--h-sm); border-radius: var(--r-sm); border: 0; background: var(--wash-2); color: var(--ink); }
body.has-sb .spot-ic svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .spot-ic-av { background: transparent; }
body.has-sb .spot-hash { font: 500 var(--t-body)/1 var(--font); color: var(--ink-3); }
body.has-sb .spot-main strong { font: 500 var(--t-body)/1.45 var(--font); color: var(--ink); }
body.has-sb .spot-main span { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .spot-row .chip { background: var(--wash-3); }
body.has-sb .spot-row-all { border-top-color: var(--line); }
body.has-sb .spot-empty { padding: var(--s-6); font: 400 var(--t-ui)/1.45 var(--font); color: var(--ink-3); text-align: center; }
body.has-sb .spot-quick { padding: 6px var(--s-2) var(--s-4); }
body.has-sb .spot-pills { gap: var(--s-2); padding: var(--s-1) var(--s-3) 0; }
body.has-sb .spot-pill { height: var(--h-md); padding: 0 14px; gap: var(--s-2); border: 1px solid var(--line); border-radius: var(--r-md); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out); }
body.has-sb .spot-pill svg { width: var(--ic-sm); height: var(--ic-sm); color: var(--ink-3); }
body.has-sb .spot-foot { height: var(--h-md); align-items: center; padding: 0 var(--s-5); gap: 18px; background: var(--paper); border-top-color: var(--line); font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
@media (hover: hover) and (pointer: fine) { body.has-sb .spot-pill:hover { background: var(--wash-1); border-color: var(--line-2); color: var(--ink); } }

/* 공유 버튼(§4.15) — 아이콘 버튼 36 원(share). navigator.share가 없으면 팝오버('링크 복사' · '단톡방에 보내기') */
body.has-sb .share-btn { position: relative; width: 36px; height: 36px; padding: 0; gap: 0; flex: none; border: 0; border-radius: 50%; background: transparent; color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .share-btn::after { content: ''; position: absolute; inset: -4px; }
body.has-sb .share-btn svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .share-btn > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; font-size: var(--t-footnote); }
body.has-sb .share-btn:active { scale: var(--m-press-icon); transform: none; transition-duration: var(--dur-1); }
body.has-sb .share-btn[aria-expanded="true"] { background: var(--wash-2); color: var(--ink); }
@media (hover: hover) and (pointer: fine) { body.has-sb .share-btn:hover { background: var(--wash-2); border-color: transparent; color: var(--ink); } }
.share-pop { position: fixed; z-index: var(--z-popover); min-width: 200px; animation: m-popover-in var(--dur-2) var(--ease-out); }

/* ─────────────────────────────────────────────────────────────
   8. 목록 행(§4.4) — 박스 없이 헤어라인. hover는 --wash-1 알약 하나(인접 헤어라인은 숨김), 누름 --wash-2
      한 줄 56 · 두 줄+아바타40 64 · 날짜 타일 64 행
   ───────────────────────────────────────────────────────────── */
body.has-sb .nlist, body.has-sb .mu-list, body.has-sb .dm-list, body.has-sb .notif-list { display: flex; flex-direction: column; gap: 0; border: 0; border-radius: 0; box-shadow: none; overflow: visible; background: none; }
body.has-sb .nlist, body.has-sb .mu-list { border-bottom: 1px solid var(--line); }
body.has-sb :is(.nrow, .erow, .mu-card, .dmrow, .pending-card) {
  position: relative; margin: 0 calc(-1 * var(--s-4)); padding-left: var(--s-4); padding-right: var(--s-4);
  background: transparent; border: 0; border-radius: var(--r-md); box-shadow: none; color: inherit;
  transition: background-color var(--dur-1) var(--ease-out);
}
body.has-sb :is(.nrow, .erow, .mu-card, .dmrow, .pending-card)::before {
  content: ''; position: absolute; left: var(--s-4); right: var(--s-4); top: 0; height: 1px; background: var(--line);
  pointer-events: none; transition: opacity var(--dur-1) var(--ease-out);
}
body.has-sb :is(.nrow, .erow, .mu-card, .dmrow, .pending-card):first-child::before { opacity: 0; }
body.has-sb :is(.nrow, .erow, .mu-card, .dmrow):active { background: var(--wash-2); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb :is(.nrow, .erow, .mu-card, .dmrow):hover { background: var(--wash-1); }
  body.has-sb :is(.nrow, .erow, .mu-card, .dmrow):hover:active { background: var(--wash-2); }
  body.has-sb :is(.nrow, .erow, .mu-card, .dmrow):hover::before,
  body.has-sb :is(.nrow, .erow, .mu-card, .dmrow):hover + :is(.nrow, .erow, .mu-card, .dmrow)::before { opacity: 0; }
}
/* 공지 행 — 56, 제목 15/500, 메타 13 ink-3(모노 폐지), chevron 16 ink-4 */
body.has-sb .nrow { display: flex; align-items: center; min-height: var(--row); padding-top: var(--s-3); padding-bottom: var(--s-3); gap: var(--s-3); }
body.has-sb .nrow-title { flex: 1; min-width: 0; font: 500 var(--t-body)/1.45 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .nrow-meta { flex: none; font: 400 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .nrow-chev { flex: none; width: var(--ic-sm); height: var(--ic-sm); color: var(--ink-4); }
body.has-sb .nrow .chip-pin { flex: none; }

/* 날짜 타일(§4.5) — 64×64(≤699 56) · r12 · 워시 · 월 12/500 ink-3 위, 일 24/600 ink 아래. 목록·상세·레일 모두 이 하나 */
body.has-sb :is(.mu-date, .erow-date) {
  flex: none; width: 64px; height: 64px; border: 0; border-radius: var(--r-md); background: var(--wash-2);
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
}
body.has-sb :is(.mu-date, .erow-date) > span { margin: 0; font: 500 var(--t-caption)/1.2 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb :is(.mu-date, .erow-date) > b { font: 600 var(--t-title-3)/1 var(--font); letter-spacing: 0; color: var(--ink); font-variant-numeric: tabular-nums; }

/* 일정 행 */
body.has-sb .elist { display: flex; flex-direction: column; gap: 0; }
body.has-sb .erow { display: flex; align-items: center; gap: var(--s-4); padding-top: var(--s-3); padding-bottom: var(--s-3); }
body.has-sb .erow-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
body.has-sb .erow-title { font: 600 var(--t-body)/1.45 var(--font); letter-spacing: -0.01em; color: var(--ink); white-space: normal; }
body.has-sb .erow-sub { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .erow-arrow { flex: none; margin-left: auto; color: var(--ink-4); opacity: 1; font-size: 0; transition: color var(--dur-1) var(--ease-out), translate var(--dur-2) var(--ease-out); }
body.has-sb .erow-arrow svg { width: var(--ic-sm); height: var(--ic-sm); }
@media (hover: hover) and (pointer: fine) { body.has-sb .erow:hover .erow-arrow { color: var(--ink); translate: 2px 0; } }

/* 모임 행 — 날짜 타일 64 · 제목 17/600 · 메타 13 · 정원 '3 / 12'(15/600 + 13/400) · 상태 칩 */
body.has-sb .mu-card { display: flex; align-items: center; gap: var(--s-5); padding-top: var(--s-4); padding-bottom: var(--s-4); }
body.has-sb .mu-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--s-1); }
body.has-sb .mu-title { font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .mu-meta { display: flex; align-items: center; flex-wrap: wrap; font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .mu-meta .dot { margin: 0 6px; }
body.has-sb .mu-topics { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s-1); }
body.has-sb .mu-going { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; max-width: none; font: 400 var(--t-footnote)/1.2 var(--font); color: var(--ink-3); }
body.has-sb .mu-cap { display: inline-block; white-space: nowrap; }
body.has-sb .mu-cap b { font: 600 var(--t-body)/1 var(--font); color: var(--ink); }
body.has-sb .mu-cap > span { font: 400 var(--t-footnote)/1 var(--font); color: var(--ink-3); }
body.has-sb .mu-open { flex-basis: auto; }

/* DM·멤버 행 — 64(아바타 40) · 이름 15/600 · 시간 12 · 한 줄 13 ink-3 · 읽지 않음 카운트 배지 */
body.has-sb .dmrow { display: flex; align-items: center; gap: var(--s-3); min-height: var(--row-2); padding-top: var(--s-3); padding-bottom: var(--s-3); }
body.has-sb .dmrow-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
body.has-sb .dmrow-head { display: flex; align-items: baseline; gap: var(--s-2); }
body.has-sb .dmrow-head strong { font: 600 var(--t-body)/1.45 var(--font); color: var(--ink); }
body.has-sb .dmrow-head time { margin-left: auto; flex: none; font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .dmrow-head .fcard-role { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .dmrow-body { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.has-sb .dmrow .badge { flex: none; }
body.has-sb .modal-list .dmrow { margin: 0; }
body.has-sb .search-bar { position: relative; display: block; height: auto; margin: 0 0 var(--s-2); padding: 0; border: 0; background: none; box-shadow: none; }
body.has-sb .search-bar > svg { position: absolute; left: var(--s-4); top: 50%; translate: 0 -50%; width: var(--ic-md); height: var(--ic-md); color: var(--ink-3); pointer-events: none; }
body.has-sb .search-bar .search-in:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { padding-left: 44px; border-radius: var(--r-pill); }
body.has-sb .search-sec { margin: var(--s-7) 0 var(--s-2); padding: 0; font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }

/* ─────────────────────────────────────────────────────────────
   9. 카드(§4.3) — 흰 면 · 헤어라인 · r22 · 패딩 24(≤699 20) · 쉴 때 그림자 없음.
      링크 카드 hover: 테두리 line-2 + 2px 떠오름 + ::after e-2 불투명도(그림자 자체는 애니메이션하지 않는다)
   ───────────────────────────────────────────────────────────── */
body.has-sb:not(.x-plat) .poster-grid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--s-4); align-items: stretch; }
body.has-sb .lcard {
  position: relative; display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--r-xl); background: var(--paper); padding: var(--s-6);
  box-shadow: none;
  transition: translate var(--dur-2) var(--ease-out), border-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring);
}
body.has-sb .lcard::after { content: ''; position: absolute; inset: -1px; border-radius: inherit; box-shadow: var(--e-2); opacity: 0; pointer-events: none; transition: opacity var(--dur-2) var(--ease-out); }
body.has-sb .lcard:has(.lcard-link:active) { translate: 0 0; scale: var(--m-press-card); transition-duration: var(--dur-1); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .lcard:hover { border-color: var(--line-2); translate: 0 -2px; box-shadow: none; }
  body.has-sb .lcard:hover::after { opacity: 1; }
}
body.has-sb .lcard:has(.lcard-link:focus-visible) { outline: var(--focus); outline-offset: var(--focus-offset); }
body.has-sb .lcard-ic { color: var(--ink-3); }
body.has-sb .lcard-ic svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .lcard-dash { display: none; }
body.has-sb .lcard-cover, body.has-sb .pc-cover { display: block; aspect-ratio: 16 / 10; margin: 0 0 var(--s-4); overflow: hidden; border-radius: var(--r-md); background: var(--canvas-2); }
body.has-sb .lcard-cover img, body.has-sb .pc-cover img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; }
body.has-sb .lcard-body { margin: var(--s-4) 0 var(--s-5); display: flex; flex-direction: column; gap: var(--s-2); }
body.has-sb .lcard-body strong { font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .lcard-desc { font: 400 var(--t-ui)/1.6 var(--font); color: var(--ink-2); -webkit-line-clamp: 3; }
body.has-sb .lcard-meta { margin-top: auto; padding-top: var(--s-3); border-top: 1px solid var(--line); display: flex; justify-content: space-between; gap: var(--s-2); font: 400 var(--t-caption)/1.4 var(--font); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
body.has-sb .lcard-meta .dot { margin: 0 4px; }
body.has-sb .lcard.pcard2 { padding: var(--s-6); }
/* 프로젝트 상태 — 진행 중 = 잉크 점, 완료 = ink-4 점(초록 폐지) */
body.has-sb .pc-status { height: var(--h-xs); padding: 0 10px 0 var(--s-2); gap: 6px; border: 0; border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-caption)/1 var(--font); color: var(--ink-2); }
body.has-sb .pc-status::before { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-4); box-shadow: none; }
body.has-sb .pc-status.on { color: var(--ink); border: 0; }
body.has-sb .pc-status.on::before { background: var(--ink); }
body.has-sb .pc-title { margin-top: var(--s-4); font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .pc-desc { font: 400 var(--t-ui)/1.6 var(--font); color: var(--ink-2); }
body.has-sb .pc-foot { margin-top: auto; padding-top: var(--s-4); }
body.has-sb .pc-period { font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .pc-role { font: 500 var(--t-footnote)/1.45 var(--font); color: var(--ink-2); }
body.has-sb .lcard-acts .menu.more > summary { width: var(--h-sm); height: var(--h-sm); }

/* 멤버 카드 — 4:5 포트레이트 r22(사진 없으면 워시 + 이니셜), 이름 15/600 · 직함 13 ink-3 · 소개 13 ink-2 두 줄. 온라인 = 잉크 점 */
body.has-sb .mgroups { display: flex; flex-direction: column; gap: var(--s-9); }
body.has-sb .mgroup-h { display: flex; align-items: baseline; margin-bottom: var(--s-5); padding-top: var(--s-5); border-top: 1px solid var(--line); }
body.has-sb .mgrid { --mg: var(--s-4); gap: var(--s-7) var(--mg); }
body.has-sb .mcard { border-radius: var(--r-xl); }
body.has-sb .mcard:focus-visible { outline: var(--focus); outline-offset: var(--focus-offset); }
body.has-sb .mcard-ph { border-radius: var(--r-xl); transition: translate var(--dur-2) var(--ease-out); }
body.has-sb .mcard-ph:not(.is-mono):not(.is-small) { background: var(--wash-3); }
body.has-sb .mcard-ph img { transition: scale var(--dur-4) var(--ease-out); }
body.has-sb .mcard-mono { color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .mcard:hover .mcard-ph { translate: 0 -2px; box-shadow: none; }
}
body.has-sb .mcard:active .mcard-ph { scale: var(--m-press-card); }
body.has-sb .mcard-on { position: absolute; top: var(--s-3); right: var(--s-3); z-index: 2; }
body.has-sb .mcard-body { padding: var(--s-3) 0 0; }
body.has-sb .mcard-nm { font: 600 var(--t-body)/1.35 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .mcard-title { min-height: 20px; margin-top: 2px; font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .mcard-major { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .mcard-bio { margin-top: 6px; font: 400 var(--t-footnote)/1.55 var(--font); color: var(--ink-2); }
body.has-sb .mcard .mcard-tags { gap: var(--s-1); max-height: var(--h-xs); margin-top: var(--s-2); }
body.has-sb .mcard .mcard-tags .chip { line-height: var(--h-xs); }
body.has-sb .mcard .chip.mcard-badge { height: var(--h-xs); padding: 0 var(--s-2); }

/* 저널(칼럼) — 표지·썸네일(jt-*)은 팀 콘텐츠(보호). 메타 12 ink-3(모노 폐지), 제목 17/600, 텍스트 화살표는 숨긴다 */
body.has-sb .jhero { gap: var(--s-8); }
body.has-sb .jhero-text { gap: var(--s-3); }
body.has-sb .jhero-text strong { font: 600 var(--t-title-3)/1.3 var(--font); letter-spacing: -0.03em; color: var(--ink); text-wrap: balance; }
body.has-sb .jhero-ex { font: 400 var(--t-body)/1.65 var(--font); color: var(--ink-2); }
body.has-sb .jhero-more { height: var(--h-md); padding: 0 18px; border: 0; border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-ui)/1 var(--font); color: var(--ink); transition: background-color var(--dur-1) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { body.has-sb .jhero:hover .jhero-more { background: var(--wash-3); } }
body.has-sb .jgrid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--s-8) var(--s-5); }
body.has-sb .jcard { gap: var(--s-3); }
body.has-sb .jcard-thumb:not(.thumb-live):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { border-radius: var(--r-lg); }
body.has-sb .jcard-thumb-lg { border-radius: var(--r-xl); }
body.has-sb .jcard-meta:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { font: 400 var(--t-caption)/1.4 var(--font); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
body.has-sb .jcard-title:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .jcard-arrow { display: none; }
body.has-sb .jcard { transition: scale var(--dur-3) var(--spring); }
body.has-sb .jcard:active { scale: var(--m-press-card); transition-duration: var(--dur-1); }

/* 카드뉴스 캐러셀 */
body.has-sb .cards-stack { display: flex; flex-direction: column; gap: var(--s-9); }
body.has-sb .car-item { border-radius: var(--r-lg); border-color: var(--line); }
body.has-sb .car-btn { width: 36px; height: 36px; border: 1px solid var(--line); background: var(--paper); color: var(--ink); box-shadow: var(--e-2); font-size: var(--t-card); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .car-caption { font: 600 var(--t-ui)/1.45 var(--font); color: var(--ink); }
body.has-sb .car-count { font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
@media (hover: hover) and (pointer: fine) { body.has-sb .car-btn:hover { background: var(--canvas); } }

/* 논문 테이블 뷰 — 관리 표와 같은 뼈대, 날짜는 한국어 */
body.has-sb .arch-table .at-dim { color: var(--ink-3); }

/* ─────────────────────────────────────────────────────────────
   10. 홈 피드 · 레일 · 단톡방 행(§4.15)
   ───────────────────────────────────────────────────────────── */
/* 피드 + 레일도 패널 가운데 한 기둥(wide 1012) — 예전 뷰포트 기준(50vw) 왼쪽 패딩을 버리고, 피드 왼쪽·레일 오른쪽이 기둥 양 끝(axis) */
body.has-sb .feed-layout { width: 100%; max-width: calc(var(--w-wide) + 2 * var(--gutter)); margin: 0 auto; padding: var(--s-7) var(--gutter) 0; gap: var(--s-9); justify-content: center; }
body.has-sb .feed-layout > .feed:not(.chat-col) { flex: 1 1 0; width: auto; max-width: 640px; min-width: 0; margin: 0; }
@media (min-width: 1081px) { body.has-sb .feed-layout:has(> .rail) { justify-content: space-between; } } /* 레일이 보일 때만(≤1080은 레일이 숨고 피드가 가운데) */
body.has-sb .fcard { padding: var(--s-5) 0; border-bottom: 1px solid var(--line); background: transparent; }
body.has-sb .feed-body-flat > .fcard:first-child, body.has-sb .feed-body-flat > .fcard.is-new:first-child { padding-top: var(--s-2); }
body.has-sb .fcard-grid { gap: 0 var(--s-3); grid-template-columns: var(--av-md) 1fr; }
body.has-sb .fmain { gap: var(--s-3); }
body.has-sb .fcard-head { gap: var(--s-2); }
body.has-sb .fcard-name { position: relative; font: 600 var(--t-body)/1.3 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .fcard-role { font: 400 var(--t-footnote)/1.3 var(--font); color: var(--ink-3); }
body.has-sb .fcard-meta { gap: var(--s-2); }
body.has-sb .fcard-meta time { font: 400 var(--t-footnote)/1 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .fcard-text.prose { font: 400 var(--t-body)/1.65 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .fcard-obj { gap: 6px; }
body.has-sb .fcard-obj strong { font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .fcard-obj p { font: 400 var(--t-body)/1.65 var(--font); color: var(--ink-2); }
body.has-sb .fcard-sub, body.has-sb .fcard-mono { font: 400 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .fcard-quote { border-left: 2px solid var(--ink); padding-left: var(--s-3); font: 400 var(--t-body)/1.65 var(--font); color: var(--ink-2); }
body.has-sb .fcard-more { display: inline-flex; align-items: center; gap: 2px; font: 500 var(--t-ui)/1.45 var(--font); color: var(--ink); }
body.has-sb .fcard-more svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .fcard-src { width: fit-content; }
body.has-sb .fcard-src svg { width: 14px; height: 14px; }
body.has-sb .fcard-body .chip { vertical-align: 0.15em; }
body.has-sb .paper-cover { display: block; aspect-ratio: 16 / 10; overflow: hidden; border-radius: var(--r-lg); border: 1px solid var(--line); background: var(--canvas-2); }
body.has-sb .paper-cover img { width: 100%; height: 100%; object-fit: cover; }
body.has-sb .fcard-imgs-post { border-radius: var(--r-lg); outline-color: var(--line); }
body.has-sb .fcard-imgs img { border-radius: var(--r-md); border-color: var(--line); }
/* 반응 줄 — 32 알약(답글 · 좋아요) + 조회. 좋아요는 잉크 하트(빨강 폐지), 켤 때 m-pop(--spring-pop, ≤64px) */
body.has-sb .fcard-foot { margin-left: -10px; gap: var(--s-1); }
body.has-sb :is(.fcard-reply, .fcard-like, .fcard-views) {
  position: relative; height: var(--h-sm); padding: 0 10px; gap: 6px; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; background: transparent;
  font: 500 var(--t-footnote)/1 var(--font); letter-spacing: 0; color: var(--ink-3);
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring);
}
body.has-sb :is(.fcard-reply, .fcard-like, .fcard-views) span { font: inherit; font-variant-numeric: tabular-nums; }
body.has-sb :is(.fcard-reply, .fcard-like) svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .fcard-views svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb :is(.fcard-reply, .fcard-like):active { scale: var(--m-press-chip); transition-duration: var(--dur-1); }
body.has-sb .fcard-like.on, body.has-sb .fcard-like.on span { color: var(--ink); }
body.has-sb .fcard-like svg { transition: fill var(--dur-1) var(--ease-out); }
body.has-sb .fcard-like.on svg { fill: currentColor; stroke: currentColor; animation: none; }
body.has-sb .fcard-like.pop svg { animation: heartPop var(--dur-4) var(--spring-pop); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb :is(.fcard-reply, .fcard-like):hover { background: var(--wash-2); color: var(--ink); }
}
body.has-sb .fcard-ev .ev-ico { width: var(--av-md); height: var(--av-md); border-radius: var(--r-md); background: var(--wash-2); color: var(--ink); display: grid; place-items: center; }
body.has-sb .fcard-ev .ev-ico svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .fcard .btn.btn-ghost.btn-sm { height: var(--h-sm); padding: 0 14px; font-size: var(--t-footnote); }
body.has-sb .frow-main { font: 400 var(--t-ui)/1.65 var(--font); color: var(--ink); }
body.has-sb .frow-name { position: relative; font-weight: 600; color: var(--ink); }
body.has-sb .frow-reply { font: 500 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .fline { width: 2px; background: var(--line-2); border-radius: 0; }
body.has-sb .freply-more { font: 500 var(--t-footnote)/1.45 var(--font); color: var(--ink-2); }
body.has-sb .rel-chip { font: 500 var(--t-footnote)/1.45 var(--font); color: var(--ink-2); }
/* 동적으로 들어온 카드·행 — 스태거 없이 m-rise 200ms(§5.5) */
body.has-sb .feed-body > .fcard.is-new { animation: m-rise var(--dur-2) var(--ease-out); animation-delay: 0s; }

/* 레일 — 축적의 면. 헤어라인으로만 나눈다 */
body.has-sb .rail { gap: 0; top: var(--s-7); width: 300px; margin-left: 0; }
body.has-sb .rcard { background: none; border-radius: 0; padding: var(--s-6) 0; border-top: 1px solid var(--line); }
body.has-sb .rail > .rcard:first-child { padding-top: 0; border-top: 0; }
body.has-sb .rcard-ident { gap: var(--s-3); margin-bottom: var(--s-3); }
body.has-sb .rcard-ident-t { min-width: 0; }
body.has-sb .rcard-logo { width: var(--av-md); height: var(--av-md); border-radius: var(--r-sm); }
body.has-sb .rcard-ident strong { font: 600 var(--t-body)/1.3 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .rcard-ident span { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .rcard-stats { display: flex; flex-wrap: wrap; align-items: baseline; margin-bottom: var(--s-4); font: 400 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .rcard-stats b { margin-left: 3px; font-weight: 600; color: var(--ink); }
body.has-sb .rcard-stats .dot { margin: 0 6px; }
body.has-sb .rcard-acts { display: flex; flex-direction: column; gap: var(--s-2); }
body.has-sb .rcard .btn-block { height: var(--h-sm); width: 100%; }
body.has-sb .rcard-title { margin-bottom: var(--s-2); font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .rcard-more { margin-top: var(--s-3); }
body.has-sb .ch-list { margin: 0 calc(-1 * var(--s-2)); }
body.has-sb .ch-item { height: var(--h-sm); padding: 0 var(--s-2); gap: var(--s-2); border-radius: var(--r-sm); font: 500 var(--t-ui)/1 var(--font); color: var(--ink); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .ch-hash { width: 14px; color: var(--ink-3); font: 500 var(--t-ui)/1 var(--font); }
body.has-sb .ch-n { font: 400 var(--t-caption)/1 var(--font); color: var(--ink-3); }
body.has-sb .rail .erow { padding: var(--s-2); margin: 0 calc(-1 * var(--s-2)); gap: var(--s-3); }
body.has-sb .rail .erow::before { left: var(--s-2); right: var(--s-2); }
body.has-sb .rail .erow-title { font: 500 var(--t-ui)/1.45 var(--font); }
body.has-sb .rail .erow-sub { font: 400 var(--t-caption)/1.4 var(--font); }
body.has-sb .rail .erow-arrow { display: none; }
body.has-sb .rmini { padding: 10px 0; border-bottom-color: var(--line); }
body.has-sb .rmini-t { font: 500 var(--t-ui)/1.45 var(--font); color: var(--ink); }
body.has-sb .rmini-m { font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .rmini-m .dot { margin: 0 4px; }
body.has-sb .rail .tag-row { gap: 6px; }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .ch-item:hover { background: var(--wash-1); }
  body.has-sb .rmini-t:hover { text-decoration: underline; text-underline-offset: 3px; }
}
body.has-sb .welcome .welcome-go { margin-left: auto; }

/* 단톡방 — 홈 맨 위 목록 행(§4.15): 아이콘 타일 32 + '단톡방' + 부제 + arrowUpRight 16. 브랜드 색 없음 */
body.has-sb .chat-strip { display: block; padding: 0 0 var(--s-4); }
body.has-sb .chat-pill {
  display: grid; grid-template-columns: var(--h-sm) minmax(0, 1fr) var(--ic-sm); grid-template-rows: auto auto; column-gap: var(--s-3); align-items: center;
  width: 100%; min-height: var(--row); padding: var(--s-2) var(--s-4); border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--paper); color: var(--ink);
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
body.has-sb .chat-pill-ic { grid-column: 1; grid-row: 1 / span 2; width: var(--h-sm); height: var(--h-sm); border-radius: var(--r-sm); background: var(--wash-2); display: grid; place-items: center; color: var(--ink); }
body.has-sb .chat-pill-ic svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .chat-pill-k { grid-column: 2; grid-row: 1; font: 500 var(--t-body)/1.3 var(--font); color: var(--ink); }
body.has-sb .chat-pill-n::before { content: none; display: none; }
body.has-sb .chat-pill-n { grid-column: 2; grid-row: 2; font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.has-sb .chat-pill-setup .chat-pill-n { grid-row: 1 / span 2; font: 500 var(--t-body)/1.3 var(--font); color: var(--ink); }
body.has-sb .chat-pill-go { grid-column: 3; grid-row: 1 / span 2; color: var(--ink-4); }
body.has-sb .chat-pill-go svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .chat-pill:active { background: var(--wash-2); }
@media (hover: hover) and (pointer: fine) { body.has-sb .chat-pill:hover { background: var(--wash-1); border-color: var(--line-2); } body.has-sb .chat-pill:hover:active { background: var(--wash-2); } }
body.has-sb .chat-welcome { border-radius: var(--r-xl); border: 1px solid var(--line); background: var(--paper); box-shadow: none; }

/* ─────────────────────────────────────────────────────────────
   11. 라운지 · DM — 공통 .chat-head(sticky 56 · 유리 · 하단 선 · 제목 17/600 · 뒤로 36 원 + 44 hit) · 채팅 행 · 입력 도크
   ───────────────────────────────────────────────────────────── */
body.has-sb .page-chat .feed-layout { padding-top: 0; gap: 0; }
body.has-sb .chat-col { width: 100%; max-width: var(--w-main); margin: 0 auto; }
body.has-sb .chatmode .feed { max-width: var(--w-main); }
body.has-sb .chat-head {
  position: sticky; top: 0; z-index: var(--z-sticky); display: flex; align-items: center; gap: var(--s-3);
  height: var(--row); padding: 0 var(--s-6); flex: none;
  background: var(--glass); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--line);
}
body.has-sb .chat-title { min-width: 0; display: inline-flex; align-items: baseline; font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.has-sb .chat-hash { margin-right: 2px; color: var(--ink-3); font-weight: 500; }
body.has-sb .chat-name { position: relative; }
body.has-sb .chat-role { flex: none; font: 400 var(--t-footnote)/1 var(--font); color: var(--ink-3); }
body.has-sb .chat-meta { display: inline-flex; align-items: center; gap: var(--s-2); min-width: 0; font: 400 var(--t-footnote)/1 var(--font); color: var(--ink-3); white-space: nowrap; }
body.has-sb .chat-meta a { color: var(--ink-3); transition: color var(--dur-1) var(--ease-out); }
body.has-sb .chat-meta .dot { margin: 0 4px; }
body.has-sb .chat-back { position: relative; flex: none; width: 36px; height: 36px; margin-left: calc(-1 * var(--s-2)); display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--wash-2); color: var(--ink); transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .chat-back svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .chat-back::after { content: ''; position: absolute; inset: -4px; }
body.has-sb .chat-back:active { scale: var(--m-press-icon); }
body.has-sb .chat-head .online-row { margin-left: auto; display: inline-flex; align-items: center; gap: var(--s-2); white-space: nowrap; flex: none; }
body.has-sb .chat-head .online-dot { flex: none; }
body.has-sb .online-n { font: 400 var(--t-footnote)/1 var(--font); color: var(--ink-3); }
body.has-sb .chat-add { flex: none; }
body.has-sb .chat-add svg { width: 14px; height: 14px; }
/* 아바타 스택 — 24 세 개(흰 2px 링, 6px 겹침) + '+N' 알약 */
body.has-sb .avatar-stack { display: inline-flex; align-items: center; }
body.has-sb .avatar-stack > span { display: inline-flex; }
body.has-sb .avatar-stack > span + span { margin-left: -6px; }
body.has-sb .avatar-stack .avatar { box-shadow: 0 0 0 2px var(--paper); }
body.has-sb .stack-more { height: var(--h-xs); min-width: var(--h-xs); padding: 0 6px; border-radius: var(--r-pill); background: var(--wash-2); box-shadow: 0 0 0 2px var(--paper); align-items: center; justify-content: center; font: 500 var(--t-caption)/1 var(--font); color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .chat-meta a:hover { color: var(--ink); }
  body.has-sb .chat-back:hover { background: var(--wash-3); }
}
body.has-sb .chat-day { padding: var(--s-6) var(--s-6) var(--s-2); }
body.has-sb .chat-day::before, body.has-sb .chat-day::after { border-top-color: var(--line); }
body.has-sb .chat-day span { padding: 0 var(--s-1); background: none; font: 500 var(--t-caption)/1.4 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .chatrow { padding: var(--s-2) var(--s-6) var(--s-1); gap: var(--s-3); animation: none; }
body.has-sb .chatrow.is-new { animation: m-rise var(--dur-2) var(--ease-out); }
body.has-sb .chatrow-follow { padding: 2px var(--s-6); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .chatrow-head { gap: var(--s-2); align-items: baseline; }
body.has-sb .chatrow-head .frow-name { font: 600 var(--t-ui)/1.45 var(--font); color: var(--ink); }
body.has-sb .chatrow-head .fcard-role { font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .chatrow-head time, body.has-sb .chatrow-gutter time { font: 400 var(--t-caption)/1.4 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .chatrow-body { font: 400 var(--t-body)/1.6 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .chat-imgs .fimg, body.has-sb .chat-imgs img { border-radius: var(--r-md); }
body.has-sb .mention { color: var(--ink); font-weight: 600; background: var(--wash-2); border-radius: var(--r-xs); padding: 0 3px; }
@media (hover: hover) and (pointer: fine) { body.has-sb .chatrow-follow:hover { background: var(--wash-1); } }
/* 입력 도크 — 아바타 32 · 사진 36 · 입력 48(textarea 자체가 48, 테두리는 바깥 링) · 전송 40 */
body.has-sb .composer-dock { padding: var(--s-2) var(--s-6) var(--s-4); background: var(--paper); border-top: 0; }
body.has-sb .composer { gap: var(--s-2); align-items: flex-end; padding: 0; }
body.has-sb .composer > .avatar { margin-bottom: var(--s-2); }
body.has-sb .composer > .attach-btn, body.has-sb .composer > .send-btn { margin-bottom: var(--s-1); }
body.has-sb .composer-field {
  flex: 1; min-width: 0; min-height: var(--h-lg); padding: 0; border: 0; border-radius: var(--r-xl); background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--line-2);
  transition: box-shadow var(--dur-1) var(--ease-out);
}
body.has-sb .composer-field:focus-within { box-shadow: inset 0 0 0 1px var(--ink), var(--ring-input); }
body.has-sb .composer-field .composer-input { display: block; width: 100%; min-height: var(--h-lg); height: var(--h-lg); padding: var(--s-3) var(--s-4); border: 0; background: transparent; font: 400 var(--t-body)/24px var(--font); color: var(--ink); resize: none; }
body.has-sb .composer-input::placeholder { color: var(--ink-3); }
body.has-sb .attach-strip { padding: var(--s-2) var(--s-3) 0; }
body.has-sb .attach-btn-inline { width: 36px; height: 36px; color: var(--ink-2); }
body.has-sb .dock-ctx { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2) var(--s-4) 0; border-bottom: 0; font: 500 var(--t-caption)/1.4 var(--font); color: var(--ink-2); }
body.has-sb .dock-ctx-x { position: relative; width: var(--h-xs); height: var(--h-xs); display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--wash-2); color: var(--ink-2); }
body.has-sb .dock-ctx-x svg { width: var(--ic-xs); height: var(--ic-xs); }
body.has-sb .dock-ctx-x::after { content: ''; position: absolute; inset: -10px; }
body.has-sb .ch-name-wrap { display: flex; align-items: center; gap: var(--s-2); }
body.has-sb .ch-name-wrap > span { font: 500 var(--t-card)/1 var(--font); color: var(--ink-3); }

/* ─────────────────────────────────────────────────────────────
   12. 캘린더 · 주간 · 일정·모임 상세 · 일정 잡기
   ───────────────────────────────────────────────────────────── */
body.has-sb .cal-head { gap: var(--s-2); margin-bottom: var(--s-4); }
body.has-sb .cal-head h2 { min-width: 0; margin-right: var(--s-2); font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; color: var(--ink); }
body.has-sb .cal-nav { gap: var(--s-1); }
body.has-sb .cal-nav a { position: relative; width: 36px; height: 36px; border: 0; border-radius: 50%; background: var(--wash-2); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .cal-nav a svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .cal-nav a::after { content: ''; position: absolute; inset: -4px; }
body.has-sb .cal-nav a:active { scale: var(--m-press-icon); }
body.has-sb .cal-today { position: relative; height: 36px; display: inline-flex; align-items: center; padding: 0 14px; border: 0; border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink); transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .cal-today::after { content: ''; position: absolute; inset: -4px 0; }
body.has-sb .cal-today:active { scale: var(--m-press-chip); }
@media (hover: hover) and (pointer: fine) { body.has-sb :is(.cal-nav a, .cal-today):hover { background: var(--wash-3); color: var(--ink); } }
body.has-sb .cal { border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: none; background: var(--paper); overflow: hidden; }
body.has-sb .cal-wd { padding: var(--s-3) 0 10px; background: var(--paper); border-bottom: 1px solid var(--line); font: 600 var(--t-caption)/1.4 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .cal-cell { position: relative; min-height: 104px; padding: var(--s-2); border-color: var(--line); gap: var(--s-1); }
body.has-sb .cal-cell.out { background: var(--canvas); }
body.has-sb .cal-num { width: var(--h-xs); height: var(--h-xs); border-radius: 50%; font: 500 var(--t-footnote)/1 var(--font); letter-spacing: 0; color: var(--ink-2); }
body.has-sb .cal-cell.out .cal-num { color: var(--ink-4); }
body.has-sb .cal-cell.sun .cal-num { color: var(--ink-3); }
body.has-sb .cal-cell.today .cal-num { background: var(--ink); color: #fff; font-weight: 600; }
body.has-sb .cal-ev { display: block; padding: 3px var(--s-2); border: 0; border-radius: var(--r-xs); background: var(--wash-2); font: 500 var(--t-caption)/1.4 var(--font); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .cal-more { padding: 0 var(--s-2); font: 500 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .cal-day { display: none; }
body.has-sb .cal-dots { display: none; }
body.has-sb .cal-foot { margin-top: var(--s-7); }
@media (hover: hover) and (pointer: fine) { body.has-sb a.cal-ev:hover { background: var(--wash-3); } body.has-sb .cal-more:hover { color: var(--ink); } }
body.has-sb .wk { border: 1px solid var(--line); border-radius: var(--r-lg); }
body.has-sb .wk-head { border-bottom-color: var(--line); }
body.has-sb .wk-day { padding: 10px 0; font: 500 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .wk-day b { font-weight: 600; color: var(--ink); }
body.has-sb .wk-day.on b { background: var(--ink); color: #fff; border-radius: var(--r-pill); padding: 2px var(--s-2); }
body.has-sb .wk-col { border-left-color: var(--line); }
body.has-sb .wk-col.wk-today { background: var(--wash-1); }
body.has-sb .wk-slots { height: var(--wk-h); background-image: repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px 44px); }
body.has-sb .wk-hours { height: var(--wk-h); }
body.has-sb .wk-hours span { top: var(--top); font: 400 var(--t-micro)/1 var(--font); color: var(--ink-3); }
body.has-sb .wk-ev { top: var(--top); background: var(--ink); color: #fff; border-radius: var(--r-sm); font: 500 var(--t-caption)/1.4 var(--font); }
body.has-sb .wk-ev b { font: 600 var(--t-micro)/1.3 var(--font); opacity: 1; }
body.has-sb .wk-ev-allday { background: var(--wash-2); color: var(--ink); }
body.has-sb .wk-now { top: var(--top); background: var(--ink); height: 2px; }
body.has-sb .wk-now::before { background: var(--ink); box-shadow: 0 0 0 2px var(--paper); }

/* 모임·일정 상세 머리 — h1은 기준선, 날짜 타일(64)은 오른쪽 위. 칩 줄 · 참가 줄 · 기록 */
body.has-sb .mu-head .mu-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s-4); }
body.has-sb .mu-hero-meta { display: flex; flex-wrap: wrap; align-items: baseline; }
body.has-sb .mu-hero-meta .dot { margin: 0 6px; }
body.has-sb .mu-join { display: flex; align-items: center; gap: var(--s-4); margin: 0; padding: var(--s-4) 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
body.has-sb .mu-join .share-btn { margin-left: auto; }
body.has-sb .mu-count { display: inline-block; white-space: nowrap; font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .mu-count b { margin-right: 1px; font: 600 var(--t-body)/1 var(--font); color: var(--ink); }
body.has-sb .mu-sec { margin-top: var(--s-9); }
body.has-sb .mu-people { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0 var(--s-4); }
body.has-sb .mu-person { display: flex; align-items: center; gap: var(--s-3); min-height: var(--row-2); padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
body.has-sb .mu-person-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
body.has-sb .mu-person-main strong { font: 600 var(--t-ui)/1.45 var(--font); color: var(--ink); }
body.has-sb .mu-person-main span { font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .mu-tools { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-top: var(--s-9); padding-top: var(--s-4); border-top: 1px solid var(--line); }
body.has-sb .mu-sec .prose, body.has-sb .ev-prose { font: 400 var(--t-body)/1.7 var(--font); color: var(--ink); }
body.has-sb .page-body > .mu-sec:first-child, body.has-sb .page-body > .prose:first-child { margin-top: 0; }
body.has-sb .ck-hook { margin: var(--s-4) 0 0; border-radius: var(--r-lg); border-color: var(--line); }
body.has-sb .ck-hook-btn { height: var(--h-md); padding: 0 18px; border-radius: var(--r-pill); font: 500 var(--t-ui)/1 var(--font); }
body.has-sb .ck-hook-link { position: relative; }
body.has-sb .ev-poster { margin: var(--s-6) 0 0; border-radius: var(--r-lg); border-color: var(--line); overflow: hidden; }
body.has-sb .ev-prose { margin-top: var(--s-6); }
body.has-sb .ev-empty { margin-top: var(--s-6); font: 400 var(--t-ui)/1.65 var(--font); color: var(--ink-3); }

/* 일정 잡기 — 섹션 · 공강 히트맵(잉크 계단 6단, 인라인 색 폐지) · 구독 */
body.has-sb .sched-sec + .sched-sec { margin-top: var(--s-9); }
body.has-sb .sched-steps { margin: var(--s-3) 0 0 18px; font: 400 var(--t-ui)/1.9 var(--font); color: var(--ink-2); }
body.has-sb .sched-steps strong { font-weight: 600; color: var(--ink); }
body.has-sb .tt-heat { max-width: 460px; }
body.has-sb .tt-grid:has(> .tt-free) { grid-template-columns: 28px repeat(7, minmax(0, 1fr)); gap: 5px; --accent: var(--ink); }
body.has-sb .tt-grid:has(> .tt-free) :is(.tt-head, .tt-h) { font: 500 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .tt-free { height: var(--h-xs); aspect-ratio: auto; border: 0; border-radius: var(--r-xs); box-shadow: inset 0 0 0 1px var(--line); font: 500 var(--t-caption)/1 var(--font); color: var(--ink); background: var(--paper); transition: color var(--dur-1) var(--ease-out); }
body.has-sb .tt-free.l1 { background: var(--wash-1); }
body.has-sb .tt-free.l2 { background: var(--wash-2); }
body.has-sb .tt-free.l3 { background: var(--wash-3); }
body.has-sb .tt-free.l4 { background: var(--line-2); }
body.has-sb .tt-free.l5 { background: var(--ink); box-shadow: none; color: transparent; }
@media (hover: hover) and (pointer: fine) { body.has-sb .tt-free.l5:hover { color: #fff; } }
body.has-sb .tt-free.l0 { color: var(--ink-3); }

/* ─────────────────────────────────────────────────────────────
   13. 알림 — 행 64(아바타 40 + 종류 배지 18) · 한 줄 14 · 발췌 13 · 새 알림 = wash-1 면 + 잉크 점 배지
   ───────────────────────────────────────────────────────────── */
body.has-sb .page-body .notif-sec { margin: 0; padding: var(--s-6) 0 var(--s-2); font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .page-body .notif-sec:first-child { padding-top: var(--s-1); }
body.has-sb .page-body .notif { display: flex; align-items: flex-start; gap: var(--s-3); min-height: var(--row-2); padding: var(--s-3) var(--s-4); margin: 0 calc(-1 * var(--s-4)); border: 0; border-radius: var(--r-md); color: inherit; transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .page-body .notif-new { background: var(--wash-1); }
body.has-sb .page-body .notif:active { background: var(--wash-2); }
@media (hover: hover) and (pointer: fine) { body.has-sb .page-body .notif:hover { background: var(--wash-2); } }
body.has-sb .notif-av { position: relative; flex: none; }
body.has-sb .notif-badge { position: absolute; right: -3px; bottom: -3px; width: 18px; height: 18px; display: grid; place-items: center; border: 2px solid var(--paper); border-radius: 50%; background: var(--ink); color: #fff; box-sizing: content-box; font: 600 var(--t-micro)/1 var(--font); }
body.has-sb .notif-badge svg { width: var(--ic-xs); height: var(--ic-xs); }
body.has-sb :is(.nb-reply, .nb-like, .nb-at, .nb-meet) { background: var(--ink); color: #fff; }
body.has-sb .nb-like svg { fill: currentColor; }
body.has-sb .notif-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
body.has-sb .notif-line { font: 400 var(--t-ui)/1.5 var(--font); color: var(--ink); }
body.has-sb .notif-main strong { font-weight: 600; }
body.has-sb .notif-snippet { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .notif-side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: var(--s-2); }
body.has-sb .notif-side time, body.has-sb .notif-time { font: 400 var(--t-caption)/1.4 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .chat-notif-act { display: inline-flex; align-items: center; gap: 6px; margin: 0 0 var(--s-2) 52px; height: var(--h-sm); padding: 0 14px; border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink); }
body.has-sb .chat-notif-act svg { width: 14px; height: 14px; }

/* ─────────────────────────────────────────────────────────────
   14. 프로필(멤버 · 나의 페이지) — 이름(h1 title-1 40/30)은 기준선 x, 4:5 포트레이트(240)는 오른쪽(vt-person)
   ───────────────────────────────────────────────────────────── */
body.has-sb:not(.x-plat) .panel .pf { padding-top: var(--s-9); padding-bottom: var(--s-11); }
body.has-sb .pf > .art-back { margin-bottom: var(--s-6); }
body.has-sb:not(.x-plat) .pf-head {
  display: grid; grid-template-columns: minmax(0, 1fr) 240px; grid-template-areas: "id portrait" "acts portrait"; column-gap: var(--s-9); row-gap: var(--s-5); align-items: start;
}
body.has-sb:not(.x-plat) .pf-head > .pf-portrait { grid-area: portrait; width: 240px; margin: 0; }
body.has-sb:not(.x-plat) .pf-head > .pf-id { grid-area: id; min-width: 0; }
body.has-sb:not(.x-plat) .pf-head > .pf-actions { grid-area: acts; align-self: start; }
body.has-sb .pf-portrait .mcard-mono { font-size: 96px; font-size: 40cqi; }
body.has-sb .pf-eyebrow { display: block; margin-bottom: var(--s-3); font: 500 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
body.has-sb .pf-eyebrow .dot { margin: 0 6px; color: var(--ink-4); }
body.has-sb .pf-name-row { gap: var(--s-3); }
body.has-sb .pf-name { font: 600 var(--t-title-1)/1.1 var(--font); letter-spacing: -0.04em; color: var(--ink); }
body.has-sb .pf-bio { margin-top: var(--s-4); max-width: 560px; font: 400 var(--t-lead)/1.65 var(--font); letter-spacing: -0.012em; color: var(--ink-2); }
body.has-sb .pf-major { margin-top: var(--s-2); font: 400 var(--t-ui)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .pf-tags { gap: 6px; margin-top: var(--s-4); }
body.has-sb .pf-actions { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: var(--s-2); min-width: 0; max-width: none; }
body.has-sb .pf-actions .btn:not(:first-child) { background: var(--wash-2); color: var(--ink); box-shadow: none; border: 0; }
body.has-sb .cchip { position: relative; display: inline-flex; align-items: center; gap: 6px; height: var(--h-sm); padding: 0 14px; border: 0; border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .cchip svg { width: 14px; height: 14px; }
body.has-sb .contact-row { gap: var(--s-2); margin-top: var(--s-4); }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .pf-actions .btn:not(:first-child):hover, body.has-sb .cchip:hover { background: var(--wash-3); color: var(--ink); }
}
/* 통계 — 0인 칸은 서버가 뺀다. 24/600 .num + 13 라벨 */
body.has-sb .pf-stats { margin-top: var(--s-8); border: 1px solid var(--line); border-radius: var(--r-lg); grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); overflow: hidden; }
body.has-sb .pf-stats > div { display: flex; flex-direction: column; gap: 2px; padding: var(--s-5); border-right: 1px solid var(--line); }
body.has-sb .pf-stats > div:last-child { border-right: 0; }
body.has-sb .pf-stats b { font: 600 var(--t-title-3)/1.1 var(--font); letter-spacing: 0; color: var(--ink); }
body.has-sb .pf-stats span { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .pf-sec { margin-top: var(--s-9); }
body.has-sb .pf-sec-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-4); }
body.has-sb .pf-sec-head h2 { margin-top: 2px; font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; color: var(--ink); }
body.has-sb .pf-sec-note { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .pf-note { font: 400 var(--t-ui)/1.65 var(--font); color: var(--ink-2); }
body.has-sb .pf-list { border-top: 1px solid var(--line); }
body.has-sb .pf-row { min-height: var(--row); gap: var(--s-3); padding: var(--s-2) 0; border-bottom-color: var(--line); }
body.has-sb .pf-row-main { position: relative; align-items: baseline; gap: var(--s-4); }
body.has-sb .pf-row-main time { width: 88px; flex: none; font: 400 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .pf-row-type { width: 64px; flex: none; font: 500 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .pf-row-main strong { min-width: 0; font: 500 var(--t-body)/1.45 var(--font); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.has-sb .pf-row-stat { display: inline-flex; gap: var(--s-2); font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .pf-row-stat > span { display: inline-flex; align-items: center; gap: 3px; }
body.has-sb .pf-row-stat svg { width: 14px; height: 14px; }
/* 포트폴리오 공개 스위치 — 32 칩(상태 점 잉크 · 끔 ink-4) */
body.has-sb .pf-tg { position: relative; height: var(--h-sm); padding: 0 14px 0 var(--s-3); gap: 6px; border: 0; border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .pf-tg::before { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-4); box-shadow: none; }
body.has-sb .pf-tg.on { color: var(--ink); background: var(--wash-2); }
body.has-sb .pf-tg.on::before { background: var(--ink); }
body.has-sb button.pf-tg:active { scale: var(--m-press-chip); }
body.has-sb .pf-tg.is-static { height: var(--h-xs); padding: 0 10px 0 var(--s-2); font-size: var(--t-caption); }
@media (hover: hover) and (pointer: fine) { body.has-sb button.pf-tg:hover { background: var(--wash-3); color: var(--ink); } }
body.has-sb .pf .fbar { margin-bottom: var(--s-2); }
body.has-sb .pf .jgrid { grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: var(--s-7) var(--s-4); }

/* 시간표 — 칸 r8, 켬 = 잉크. ≤699에서는 행=시간·열=요일로 눕혀 칸을 44로(아래 모바일) */
body.has-sb .tt-cell { border: 0; border-radius: var(--r-sm); background: var(--wash-2); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .tt-cell.busy { background: var(--ink); }
body.has-sb .tt-grid:not(:has(> .tt-free)) :is(.tt-head, .tt-h) { font: 500 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .tt-grid.tt-sm .tt-cell { border-radius: var(--r-xs); }
body.has-sb .tt-legend { display: flex; align-items: center; gap: 6px; margin-top: var(--s-4); font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .tt-lg { width: 12px; height: 12px; border-radius: var(--r-xs); }
body.has-sb .tt-lg-free { background: var(--wash-2); }
body.has-sb .tt-lg-busy { background: var(--ink); margin-left: var(--s-2); }
body.has-sb .tt-card { width: fit-content; max-width: 100%; border: 1px solid var(--line); border-radius: var(--r-xl); padding: var(--s-6); }
/* 나의 시간표 — 카드가 기둥(main 720)을 꽉 채우고 칸이 늘어난다(오른쪽 40px 빈 틈으로 왼쪽에 붙어 보이지 않게, axis) */
@media (min-width: 700px) { /* 휴대폰은 요일이 열인 세로 격자(아래 ≤699) — 건드리지 않는다 */
  body.has-sb .tt-card:has(> .tt-grid[data-tt]) { width: 100%; }
  body.has-sb .tt-card > .tt-grid[data-tt] { grid-template-columns: 32px repeat(13, minmax(0, 1fr)); }
}
@media (hover: hover) and (pointer: fine) {
  body.has-sb .tt-cell:hover { background: var(--wash-3); }
  body.has-sb .tt-cell.busy:hover { background: var(--ink-hover); }
}
/* 내 프로필 편집 */
body.has-sb:not(.x-plat) .me-id { display: flex; align-items: center; gap: var(--s-4); margin-bottom: var(--s-7); }
body.has-sb .me-id-t { flex: 1; min-width: 0; }
body.has-sb .me-id-name { font: 600 var(--t-card)/1.3 var(--font); color: var(--ink); }
body.has-sb .me-id-mail { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .me-avatar { position: relative; cursor: pointer; }
body.has-sb .me-avatar-badge { position: absolute; right: -2px; bottom: -2px; width: var(--h-xs); height: var(--h-xs); display: grid; place-items: center; border: 2px solid var(--paper); border-radius: 50%; background: var(--ink); color: #fff; box-shadow: none; }
body.has-sb .me-avatar-badge svg { width: var(--ic-xs); height: var(--ic-xs); }
body.has-sb .me-more, body.has-sb .me-mcp, body.has-sb .me-sec { border-top: 1px solid var(--line); }
body.has-sb .me-mcp { margin-top: var(--s-9); padding-top: var(--s-7); }
body.has-sb .me-mcp h2, body.has-sb .me-sec h2 { display: flex; align-items: center; gap: var(--s-2); margin-bottom: var(--s-2); font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; }
body.has-sb .me-mcp-lead { margin: 0 0 var(--s-4); }
body.has-sb .me-mcp-act { margin-top: var(--s-3); }

/* ─────────────────────────────────────────────────────────────
   15. 글 상세 크롬(본문 밖) — 머리는 --w-wide 컨테이너 전폭(h1 x = 기준선), 제목 display 56/36. 본문(.art-prose)은 보호 구역.
   쓰기 캔버스(body.x-write)도 같은 규칙을 쓴다 — 캔버스·미리보기 = 읽기 화면
   ───────────────────────────────────────────────────────────── */
:is(body.has-sb, body.x-write):not(.x-plat) .art.art-x { --art-w: var(--w-wide); --art-pad: var(--gutter); --col: var(--w-main); padding-top: var(--s-6); }
:is(body.has-sb, body.x-write):not(.x-plat) .art-x .art-title { max-width: none; margin: var(--s-4) 0 0; font: 600 var(--t-display)/1.1 var(--font); letter-spacing: -0.045em; color: var(--ink); text-wrap: balance; }
:is(body.has-sb, body.x-write):not(.x-plat) .art-x .art-title-long { font: 600 var(--t-title-1)/1.1 var(--font); letter-spacing: -0.04em; }
body.has-sb .art-top { gap: var(--s-2); min-height: 36px; }
body.has-sb .art-back { position: relative; flex: none; display: inline-flex; align-items: center; gap: 6px; height: var(--h-sm); padding: 0 14px 0 var(--s-2); border-radius: var(--r-pill); background: var(--wash-2); font: 500 var(--t-footnote)/1 var(--font); color: var(--ink); white-space: nowrap; transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
body.has-sb .art-back svg { width: var(--ic-sm); height: var(--ic-sm); flex: none; }
body.has-sb .art-back:active { scale: var(--m-press-chip); }
@media (hover: hover) and (pointer: fine) { body.has-sb .art-back:hover { background: var(--wash-3); color: var(--ink); } }
body.has-sb .art-top-date { font: 400 var(--t-footnote)/1 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .art-top .article-actions { opacity: 1; gap: var(--s-1); display: flex; align-items: center; }
body.has-sb .art-top .icon-act { width: var(--h-sm); height: var(--h-sm); }
body.has-sb .art-top .btn-sm { height: var(--h-sm); padding: 0 14px; font-size: var(--t-footnote); }
:is(body.has-sb, body.x-write) .art-eyebrow { gap: var(--s-2); font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
:is(body.has-sb, body.x-write) .art-eyebrow a { color: var(--ink-3); transition: color var(--dur-1) var(--ease-out); }
:is(body.has-sb, body.x-write) .art-eyebrow a:hover { color: var(--ink); }
:is(body.has-sb, body.x-write) .art-sep { color: var(--ink-4); }
:is(body.has-sb, body.x-write) .art-pin { color: var(--ink); }
:is(body.has-sb, body.x-write):not(.x-plat) .art-x .art-deck { margin-top: var(--s-5); font: 400 var(--t-lead)/1.65 var(--font); letter-spacing: -0.012em; color: var(--ink-2); }
:is(body.has-sb, body.x-write) .article-byline:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *), :is(body.has-sb, body.x-write) .art-byline { gap: var(--s-2); font: 400 var(--t-ui)/1.45 var(--font); color: var(--ink-3); }
:is(body.has-sb, body.x-write) .art-byline-name { position: relative; font-weight: 600; color: var(--ink); }
:is(body.has-sb, body.x-write) .art-byline-read { font: 400 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; }
:is(body.has-sb, body.x-write) .art-byline-role::before, :is(body.has-sb, body.x-write) .art-byline-read::before { color: var(--ink-4); }
:is(body.has-sb, body.x-write) .art-facts { border-color: var(--line); }
:is(body.has-sb, body.x-write) .art-fact { grid-template-columns: 96px 1fr; border-top-color: var(--line); padding: var(--s-3) 0; }
:is(body.has-sb, body.x-write) .art-fact dt { font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
:is(body.has-sb, body.x-write) .art-fact dd { font: 400 var(--t-body)/1.55 var(--font); color: var(--ink); }
:is(body.has-sb, body.x-write) .art-facts-link { position: relative; display: inline-flex; align-items: center; gap: 2px; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-3); }
:is(body.has-sb, body.x-write) .art-facts-link svg { width: 14px; height: 14px; }
:is(body.has-sb, body.x-write) .art-cover img, :is(body.has-sb, body.x-write):not(.x-plat) .art-x .art-cover img { aspect-ratio: 16 / 10; max-height: none; object-fit: cover; border-radius: var(--r-xl); border: 1px solid var(--line); }
/* 논문 초록 — 팩트 표 아래 조용한 한 덩어리(글 상세·홍보 상세·쓰기 캔버스·미리보기 공용) */
.art-x > .art-abstract { margin-bottom: var(--s-9); }
/* 홍보 사이트 글 상세 — 팩트 표가 아래 여백 없이 끝나므로(v5-public) 초록은 표지와 같은 간격을 둔다 */
body.x-pub .art-x > .art-facts + .art-abstract { margin-top: var(--s-7); }
.art-abstract-t { margin: 0 0 var(--s-3); font: 600 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
.art-abstract-p { margin: 0; font: 400 var(--t-body)/1.7 var(--font); letter-spacing: -0.01em; color: var(--ink-2); white-space: pre-line; text-wrap: pretty; overflow-wrap: break-word; }
:is(body.has-sb, body.x-write) .rel-paper { border-radius: var(--r-lg); }
:is(body.has-sb, body.x-write) .rel-paper-tag { font: 600 var(--t-caption)/1.4 var(--font); letter-spacing: 0; text-transform: none; }
:is(body.has-sb, body.x-write) .linked-col-arrow { color: var(--ink-4); }
:is(body.has-sb, body.x-write) .linked-col-arrow svg { width: var(--ic-sm); height: var(--ic-sm); }
:is(body.has-sb, body.x-write) .art-foot { border-top-color: var(--line); gap: var(--s-3); }
body.has-sb .art-foot .fcard-like { background: var(--wash-2); color: var(--ink); padding: 0 14px; }
body.has-sb .art-foot .fcard-like.on { color: var(--ink); }
body.has-sb .like-form { display: inline-flex; }
body.has-sb .art-views { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .art-linked, body.has-sb .art .author-box, body.has-sb .art .pn-nav { border-top-color: var(--line); }
body.has-sb .linked-col { border-radius: var(--r-md); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .linked-col-main strong { font: 500 var(--t-body)/1.45 var(--font); color: var(--ink); }
body.has-sb .linked-col-main span { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .pn { border-color: var(--line); border-radius: var(--r-lg); transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out); }
/* 댓글 · 스레드 */
body.has-sb .art-cmts { border-top-color: var(--line); }
body.has-sb .art-cmts-head { gap: var(--s-2); margin-bottom: var(--s-5); align-items: baseline; }
body.has-sb .art-cmts-head h2, body.has-sb .cmts-head { font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; color: var(--ink); }
body.has-sb .cmts-head { margin-bottom: var(--s-3); }
body.has-sb .cmt { gap: var(--s-3); }
body.has-sb .cmt-top { gap: var(--s-2); align-items: center; font: 400 var(--t-ui)/1.45 var(--font); }
body.has-sb .cmt-top strong { font-weight: 600; color: var(--ink); }
body.has-sb .cmt-role { font: 400 var(--t-caption)/1.4 var(--font); color: var(--ink-3); }
body.has-sb .cmt-dot { color: var(--ink-4); }
body.has-sb .cmt-top time { font: 400 var(--t-caption)/1.4 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .cmt-del { margin-left: auto; }
body.has-sb .cmt-body { margin-top: var(--s-1); font: 400 var(--t-body)/1.65 var(--font); letter-spacing: -0.01em; color: var(--ink); }
body.has-sb .cmt-reply-btn { position: relative; height: var(--h-xs); margin: var(--s-1) 0 0 -8px; padding: 0 var(--s-2); border-radius: var(--r-pill); font: 600 var(--t-caption)/1 var(--font); color: var(--ink-3); transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { body.has-sb .cmt-reply-btn:hover { background: var(--wash-2); color: var(--ink); } }
body.has-sb .cmt:not(:last-child) .cmt-rail::after, body.has-sb .cmt-children .cmt::before, body.has-sb .cmt-children .cmt:not(:last-child)::after { border-color: var(--line); }
body.has-sb .cmt:not(:last-child) .cmt-rail::after { background: var(--line); }
body.has-sb .cmts-empty, body.has-sb .cmt-hint { font: 400 var(--t-ui)/1.65 var(--font); color: var(--ink-3); }
body.has-sb .cmt-hint { padding: var(--s-4) 0; }
body.has-sb .art-cmt-form .cmt-form, body.has-sb .cmt-form { gap: var(--s-2); border-top-color: var(--line); border-bottom-color: var(--line); }
body.has-sb .cmt-form > .avatar { margin-bottom: var(--s-2); }
body.has-sb .page-thread .thread-top { position: sticky; top: 0; z-index: var(--z-sticky); min-height: var(--row); padding: 0; gap: var(--s-3); background: var(--glass); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur); font: 600 var(--t-card)/1.3 var(--font); }
body.has-sb .thread { max-width: var(--w-main); padding: 0 var(--gutter); }
body.has-sb .thread-date { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .tweet { gap: var(--s-3); }
body.has-sb .tweet .fcard-name { font: 600 var(--t-body)/1.3 var(--font); }
body.has-sb .tweet-title { font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; color: var(--ink); }
body.has-sb .tweet-prose { font: 400 var(--t-lead)/1.65 var(--font); color: var(--ink); letter-spacing: -0.012em; }
body.has-sb .tweet-time { padding-bottom: var(--s-3); border-bottom-color: var(--line); font: 400 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; color: var(--ink-3); }
body.has-sb .tweet-stats { padding: var(--s-3) 2px; gap: var(--s-5); border-bottom-color: var(--line); font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .tweet-stats b { font-weight: 600; color: var(--ink); margin-right: 2px; }
body.has-sb .tweet-actions { border-bottom-color: var(--line); padding: var(--s-1) 0; gap: var(--s-1); }
body.has-sb .tweet-actions .share-btn { margin-left: auto; }
body.has-sb .tweet-linked { border-bottom-color: var(--line); }
body.has-sb .cmt-dock { background: var(--paper); }
body.has-sb .article-head-c { text-align: center; }
body.has-sb .article-head-c .article-byline { justify-content: center; }
body.has-sb .article-head h1 { font: 600 var(--t-title-2)/1.1 var(--font); letter-spacing: -0.035em; color: var(--ink); }
body.has-sb .cards-prose { margin-top: var(--s-7); }

/* ─────────────────────────────────────────────────────────────
   16. 글쓰기 · 폼 — 머리는 페이지 머리 하나. 제출은 그 화면의 주 CTA(tint, lg 48) + 보조 '취소'
   ───────────────────────────────────────────────────────────── */
body.has-sb .form-card { border: 0; box-shadow: none; background: transparent; padding: 0; border-radius: 0; }
body.has-sb .form-actions { display: flex; align-items: center; gap: var(--s-2); margin-top: var(--s-7); padding-top: var(--s-6); border-top: 1px solid var(--line); }
body.has-sb:not(.x-plat) :is(.form-page, .c-form, .c-main) .form-actions > .btn { height: var(--h-lg); padding: 0 22px; font-size: var(--t-body); }
body.has-sb .form-actions .hd-link { display: inline-flex; align-items: center; height: var(--h-md); padding: 0 18px; border-radius: var(--r-pill); background: var(--wash-2); color: var(--ink); font: 500 var(--t-ui)/1 var(--font); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .hint-block { margin: 0 0 var(--s-4); }
body.has-sb .md-label { margin: 0; }
body.has-sb .upload-previews img { border-radius: var(--r-md); border-color: var(--line); }
body.md-focus .form-page > .page-head { display: none; }

/* ─────────────────────────────────────────────────────────────
   17. 관리 — Apple 설정 문법(그룹 목록 · v5.css .gl-*). 가운데 한 기둥(멤버·채널·설정·위험 구역 main 720, 링크 · 초대 wide 1012),
   큰 제목(title-2) + 한 줄 설명. 탭 안은 머리(13) · 둥근 묶음(r16 헤어라인 행) · 꼬리(13) 하나. 편집은 행 → 시트(dialog,
   ≤699 아래 시트), 저장은 즉시 + 토스트(되돌리기). 주 버튼은 잉크(팀색 없음) · 스위치 하나 · 컨트롤 32/40/48 · 관리 탭은 휴대폰에서 sticky 세그먼트
   ───────────────────────────────────────────────────────────── */
body.has-sb .adm { padding-bottom: var(--s-11); }
body.has-sb .adm-body { margin-top: 0; }
/* 관리 사이드바 '위험 구역' — 위험 한 색(--danger), 켬은 --danger-wash · 굵기 불변(§4.11) */
body.has-sb .sb-nav .sb-link-danger, body.has-sb .sb-nav .sb-link-danger svg { color: var(--danger) !important; }
body.has-sb .sb-nav .sb-link.on.sb-link-danger { background: var(--danger-wash); font-weight: 500; }
/* 머리 행동('사이트 보기')은 보조 워시 — 제목 첫 줄에 맞춘다(§4.10 관리) */
body.has-sb .adm-head > .page-actions { align-self: start; }
body.has-sb .adm-head .page-lead .num { color: var(--ink-2); font-weight: 500; }

/* 공용 — 행 안 버튼·폼 · 행 오른쪽 행동 묶음 · 폼 아래 행동 줄 */
body.has-sb .adm .gl-row .btn { flex: none; }
body.has-sb .adm-row-acts { flex: none; display: flex; align-items: center; gap: var(--s-2); }
body.has-sb .adm-row-acts form { margin: 0; }
body.has-sb .adm-form-acts { display: flex; justify-content: flex-end; gap: var(--s-2); margin-top: var(--s-3); }
body.has-sb .adm .gl-h .badge { animation: none; }
/* 스위치 — v5 스위치 하나(40×24). 앱 셸의 체크박스 크기 규칙(18px)을 이긴다. 누르는 자리는 행 전체(label) */
body.has-sb .gl input.switch[type=checkbox] { flex: none; width: 40px; height: 24px; margin: 0 0 0 auto; border-radius: var(--r-pill); }
/* 위험 채움 버튼 — 확인 시트의 주 버튼만(§4.1 danger-fill) */
body.has-sb .adm-sheet .btn.adm-fill-danger:not(:disabled), body.has-sb .adm .btn.adm-fill-danger:not(:disabled) { background: var(--danger); color: #fff; box-shadow: none; }
@media (hover: hover) and (pointer: fine) {
  body.has-sb .adm-sheet .btn.adm-fill-danger:not(:disabled):hover { background: color-mix(in oklab, var(--danger) 88%, #000); }
}

/* ── 멤버 — 검색(알약 40) + 역할 세그먼트 · 멤버 행 · 가입 신청 행 ── */
body.has-sb .adm-tools { display: flex; align-items: center; gap: var(--s-3); margin: 0 0 var(--s-3); }
body.has-sb .adm-search { position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: center; margin: 0; }
body.has-sb .adm-search > svg { position: absolute; left: 14px; width: var(--ic-sm); height: var(--ic-sm); color: var(--ink-3); pointer-events: none; }
body.has-sb .adm-search > input {
  width: 100%; height: var(--h-md); padding: 0 16px 0 40px; border: 1px solid var(--line-2); border-radius: var(--r-pill); background: var(--paper);
  font: 400 var(--t-ui)/1 var(--font); letter-spacing: -0.01em; color: var(--ink); outline: none; appearance: none;
  transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out);
}
body.has-sb .adm-search > input::placeholder { color: var(--ink-3); }
body.has-sb .adm-search > input:focus { border-color: var(--ink); box-shadow: var(--ring-input); }
/* 지우기(x) — 크롬 기본 파랑 대신 흑백 원형 x(ink-4, 가리키면 ink-3) */
body.has-sb .adm-search > input::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none; width: 16px; height: 16px; margin: 0 -4px 0 var(--s-2); cursor: pointer;
  background: var(--ink-4); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1Zm2.47 3.97a.75.75 0 0 1 .06 1l-.06.06L9.06 8l1.41 1.47a.75.75 0 0 1-1 1.1l-.06-.06L8 9.06l-1.41 1.41a.75.75 0 0 1-1.1-1l.06-.06L6.94 8 5.53 6.53a.75.75 0 0 1 1-1.1l.06.06L8 6.94l1.41-1.41a.75.75 0 0 1 1.06 0Z'/%3E%3C/svg%3E") center / 16px no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1Zm2.47 3.97a.75.75 0 0 1 .06 1l-.06.06L9.06 8l1.41 1.47a.75.75 0 0 1-1 1.1l-.06-.06L8 9.06l-1.41 1.41a.75.75 0 0 1-1.1-1l.06-.06L6.94 8 5.53 6.53a.75.75 0 0 1 1-1.1l.06.06L8 6.94l1.41-1.41a.75.75 0 0 1 1.06 0Z'/%3E%3C/svg%3E") center / 16px no-repeat;
}
body.has-sb .adm-search > input::-webkit-search-cancel-button:hover { background: var(--ink-3); }
@media (hover: hover) and (pointer: fine) { body.has-sb .adm-search > input:hover:not(:focus) { border-color: var(--line-3); } }
body.has-sb .adm-seg { flex: none; }
body.has-sb .adm-seg > button .num { margin-left: 5px; color: var(--ink-3); font-weight: 500; }
body.has-sb .adm-seg > button.on .num { color: var(--ink-2); }
body.has-sb .adm-m .gl-t { display: flex; align-items: baseline; gap: var(--s-2); }
body.has-sb .adm-m-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.has-sb .adm-m-ttl { flex: none; font: 400 var(--t-footnote)/1.45 var(--font); letter-spacing: -0.005em; color: var(--ink-3); }
body.has-sb .adm-m.is-new { animation: m-rise var(--dur-2) var(--ease-out); }
/* 가입 신청 — 두 줄 메시지(더 보기로 펼침) · 거절(보조)·승인(주) sm */
body.has-sb .adm-app { align-items: flex-start; padding-top: var(--s-4); padding-bottom: var(--s-4); }
body.has-sb .adm-app > .avatar { margin-top: 2px; }
body.has-sb .adm-app-msg {
  margin-top: var(--s-2); font: 400 var(--t-ui)/1.65 var(--font); letter-spacing: -0.01em; color: var(--ink-2); white-space: normal;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
body.has-sb .adm-app-msg.is-open { display: block; -webkit-line-clamp: unset; }
body.has-sb .adm-app-more { align-self: flex-start; position: relative; margin-top: 2px; padding: 0; border: 0; background: none; font: 500 var(--t-footnote)/1.45 var(--font); color: var(--ink); cursor: pointer; }
body.has-sb .adm-app-more::after { content: ''; position: absolute; inset: -12px -8px; }
@media (hover: hover) and (pointer: fine) { body.has-sb .adm-app-more:hover { text-decoration: underline; text-underline-offset: 3px; } }
body.has-sb .adm-app-acts { flex: none; display: flex; align-items: center; gap: var(--s-2); }
body.has-sb .adm-app-acts form { margin: 0; }
body.has-sb .adm-pending .gl-h .badge { margin-left: 2px; }
/* 혼자인 팀 — 멤버 묶음(나 한 줄) 아래 초대로 이어지는 빈 상태(가입 링크 복사 · 초대 탭) */
body.has-sb .adm-solo .empty { padding: var(--s-8) var(--s-6) var(--s-4); }
body.has-sb .adm-solo .empty-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2); margin-top: var(--s-5); }

/* ── 라운지 채널 — ⠿ 손잡이 · # 타일 · 이름(행 안 입력) · 메시지 수 · ⋯. 끌면 떠오르고 나머지는 스프링으로 비켜난다(reorder.js) ── */
body.has-sb .adm-chbox { overflow: visible; }
body.has-sb .adm-chlist { position: relative; list-style: none; margin: 0; padding: 0; }
body.has-sb .adm-ch { --gl-inset: 80px; gap: var(--s-2); padding-left: var(--s-2); background: var(--paper); }
body.has-sb .adm-chlist > .adm-ch:first-child { border-radius: calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0; }
body.has-sb .adm-ch > .gl-ic { margin-right: var(--s-1); }
body.has-sb .adm-hash { font: 600 var(--t-body)/1 var(--font); color: var(--ink-2); }
body.has-sb .adm-ch-f { flex: 1 1 auto; min-width: 0; display: flex; margin: 0; }
body.has-sb .adm-ch .gl-in { font-weight: 500; }
body.has-sb .adm-ch .gl-v { font-size: var(--t-footnote); }
body.has-sb .adm-chlist > .adm-ch:only-child .adm-ch-del { display: none; }
body.has-sb .adm-ch-add { gap: var(--s-2); padding-left: 40px; border-top: 1px solid var(--line); border-radius: 0 0 calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px); background: var(--canvas); }
body.has-sb .adm-ch-add > .gl-ic { margin-right: var(--s-1); background: var(--paper); box-shadow: inset 0 0 0 1px var(--line); color: var(--ink-2); }
body.has-sb .adm-chlist:empty + .adm-ch-add { border-top: 0; border-radius: calc(var(--r-lg) - 1px); }
body.has-sb .adm .ro-grip {
  position: relative; flex: none; align-self: stretch; display: grid; place-items: center; width: 24px; min-height: 40px; padding: 0; border: 0;
  border-radius: var(--r-sm); background: transparent; color: var(--ink-4); cursor: grab; touch-action: none;
  transition: color var(--dur-1) var(--ease-out), background-color var(--dur-1) var(--ease-out);
}
body.has-sb .adm .ro-grip svg { width: var(--ic-sm); height: var(--ic-sm); }
body.has-sb .adm .ro-grip::after { content: ''; position: absolute; inset: -8px -10px; }
body.has-sb .adm .ro-grip:focus-visible { outline: var(--focus); outline-offset: -2px; color: var(--ink); }
/* 손잡이는 늘 보인다(쉴 때 ink-4 흐리게 — 꼬리의 '손잡이를 끌어'가 가리킬 자리가 비지 않게). 행을 가리키면 ink-3, 손잡이를 가리키면 워시 */
@media (hover: hover) and (pointer: fine) {
  body.has-sb .adm .ro-row:hover .ro-grip { color: var(--ink-3); }
  body.has-sb .adm .ro-grip:hover { color: var(--ink-2); background: var(--wash-2); }
}
@media (hover: none) { body.has-sb .adm .ro-grip { color: var(--ink-3); } }
body.has-sb .adm .ro-row::after { content: ''; position: absolute; inset: 0; border-radius: var(--r-md); box-shadow: var(--e-3); opacity: 0; pointer-events: none; transition: opacity var(--dur-2) var(--ease-out); }
body.has-sb .adm .ro-row.is-lifted { z-index: 3; scale: 1.02; border-radius: var(--r-md); cursor: grabbing; transition: scale var(--dur-2) var(--ease-out); }
body.has-sb .adm .ro-row.is-lifted::before, body.has-sb .adm .ro-row.is-lifted + .ro-row::before { opacity: 0; }
body.has-sb .adm .ro-row.is-lifted::after { opacity: 1; }
body.has-sb .adm .ro-row.is-lifted .ro-grip { opacity: 1; color: var(--ink); cursor: grabbing; }
body.has-sb .adm .ro-row.is-kbd, body.has-sb .adm .ro-row.ro-shift, body.has-sb .adm .ro-row.ro-land { transition: translate var(--dur-3) var(--spring), scale var(--dur-2) var(--ease-out); }
body.has-sb .adm .ro-list.ro-still > * { transition: none !important; }
body.has-sb .adm .ro-slot { position: absolute; left: 0; right: 0; z-index: 0; background: var(--wash-1); pointer-events: none; transition: translate var(--dur-3) var(--spring); }
body.has-sb .adm .is-sorting { -webkit-user-select: none; user-select: none; }
body.has-sb .ro-live { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
body.has-sb .adm-off { align-items: center; padding-top: var(--s-4); padding-bottom: var(--s-4); }
body.has-sb .adm-off .gl-s { white-space: normal; }
/* ⋯ 메뉴 — 32 원형(§4.4). 메뉴는 v5 .menu-pop, 위험 항목은 --danger */
body.has-sb .adm-more { position: relative; display: inline-block; flex: none; }
body.has-sb .adm-more-b {
  position: relative; display: grid; place-items: center; width: var(--h-sm); height: var(--h-sm); border-radius: 50%; list-style: none; cursor: pointer; color: var(--ink-3);
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring);
}
body.has-sb .adm-more-b::-webkit-details-marker { display: none; }
body.has-sb .adm-more-b::after { content: ''; position: absolute; inset: -6px; }
body.has-sb .adm-more-b svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .adm-more-b:active { scale: var(--m-press-icon); transition-duration: var(--dur-1); }
body.has-sb .adm-more[open] > .adm-more-b { background: var(--wash-2); color: var(--ink); }
body.has-sb .adm-more > .menu-pop { position: absolute; right: 0; top: calc(100% + 6px); z-index: var(--z-popover); text-align: left; }
body.has-sb .adm-more .menu-pop form { margin: 0; }
body.has-sb .adm-more .menu-pop :is(a, button) { display: flex; align-items: center; gap: var(--s-3); width: 100%; min-height: 36px; padding: 0 12px; border: 0; border-radius: var(--r-sm); background: none; font: 500 var(--t-ui)/1.45 var(--font); color: var(--ink-2); cursor: pointer; transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .adm-more .menu-pop .mi-danger { color: var(--danger); }
body.has-sb .adm-more .menu-pop svg { width: var(--ic-sm); height: var(--ic-sm); }
@media (hover: hover) and (pointer: fine) { body.has-sb .adm-more-b:hover { background: var(--wash-2); color: var(--ink); } body.has-sb .adm-more .menu-pop :is(a, button):hover { background: var(--wash-2); color: var(--ink); } body.has-sb .adm-more .menu-pop .mi-danger:hover { background: var(--danger-wash); color: var(--danger); } }

/* ── 설정 — 값 행(→ 시트) · 세그먼트 행 · 가입 코드 행(모노) · 스위치 행(설명 줄바꿈) ── */
body.has-sb .gl-seg-row .adm-seg { margin-left: auto; }
body.has-sb .gl-v.is-empty { color: var(--ink-3); }
body.has-sb .adm-code .gl-v { max-width: none; margin-left: auto; }
body.has-sb .adm-code .gl-v.is-empty { font-family: var(--font); color: var(--ink-3); }
body.has-sb .adm-copy .gl-s { font-size: var(--t-footnote); }
body.has-sb .gl-row.is-busy { pointer-events: none; }
body.has-sb .gl-row.is-busy > :not(.gl-t) { opacity: .5; }

/* ── 링크 · 초대 — 초대 · 우리 단톡방(src/chatlink.js)도 같은 그룹 문법. 편집기 왼쪽 칸 맨 아래 ── */
body.has-sb .adm .lp-main > .gl { margin-top: var(--s-7); }
body.has-sb .adm .adm-chat .gl-box + .chat-form, body.has-sb .adm .adm-chat .chat-form + .gl-box { margin-top: var(--s-3); }
body.has-sb .adm .adm-chat .chat-now { margin: 0; padding: var(--s-2) var(--s-4); border: 0; border-radius: 0; background: none; }
body.has-sb .adm .adm-chat .chat-now-ic, body.has-sb .adm .adm-chat .chat-url-ic { position: static; transform: none; width: 32px; height: 32px; border-radius: var(--r-sm); background: var(--wash-2); color: var(--ink); pointer-events: none; }
body.has-sb .adm .adm-chat .chat-url-ic svg, body.has-sb .adm .adm-chat .chat-now-ic svg { width: var(--ic-md); height: var(--ic-md); }
body.has-sb .adm .adm-chat .chat-now .btn svg { width: 14px; height: 14px; }
body.has-sb .adm #chat-url { padding: 0 10px; font-size: var(--t-body); }
body.has-sb .adm .adm-chat .gl-field > .gl-in { text-align: left; }
body.has-sb .adm .adm-chat .gl-field > .gl-t { width: 32px; text-align: center; font-size: var(--t-footnote); font-weight: 600; color: var(--ink-2); }
body.has-sb .adm .adm-chat .chat-form .hint { margin-top: var(--s-2); font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .adm .adm-chat .chat-form .hint.is-err { color: var(--danger); }
body.has-sb .adm .adm-chat .chat-private { display: flex; align-items: flex-start; gap: 6px; margin: var(--s-3) 0 0; padding: 0 var(--s-4); font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .adm .adm-chat .chat-private svg { flex: none; width: 14px; height: 14px; margin-top: 2px; color: var(--ink-4); }
body.has-sb .adm .adm-chat { scroll-margin-top: var(--s-10); }
/* 이미 걸린 방은 칸을 벗어나면 바로 저장(public/admin.js) — 저장 버튼 줄을 접는다. 처음 걸 때는 '단톡방 걸기' 그대로 */
body.has-sb .adm .adm-chat .chat-form.is-live .adm-form-acts { display: none; }

/* ── 시트 — <dialog class="modal adm-sheet"> 480 · r22 · 패딩 24(≤699 아래 시트, 손잡이) ── */
body.has-sb dialog.adm-sheet { width: min(480px, 100vw - 32px); padding: var(--s-6); color: var(--ink); overscroll-behavior: contain; }
body.has-sb dialog.adm-sheet .sheet-grip { display: none; }
@media (min-width: 700px) { body.has-sb dialog.adm-sheet.is-wide { width: min(640px, 100vw - 32px); } }
/* 열린 시트는 변형(scale·translate)을 none으로 둔다 — 그래야 시트 안에 둔 토스트(position: fixed)가 시트가 아니라 화면 아래에 붙는다.
   등장은 같은 값(--m-pop · --m-rise)으로 여기서 다시 시작한다(v5 @starting-style보다 세게) */
body.has-sb dialog.adm-sheet[open] { scale: none; translate: none; }
@starting-style { body.has-sb dialog.adm-sheet[open] { opacity: 0; scale: var(--m-pop); translate: 0 var(--m-rise); } }
body.has-sb .adm-sheet .modal-title { margin: 0 0 var(--s-2); padding-right: var(--s-9); font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
body.has-sb .adm-sheet .adm-danger-t { color: var(--danger); }
body.has-sb .adm-sh-lead { margin: 0 0 var(--s-5); font: 400 var(--t-ui)/1.65 var(--font); letter-spacing: -0.01em; color: var(--ink-3); text-wrap: pretty; }
body.has-sb .adm-sheet .gl + .gl { margin-top: var(--s-6); }
body.has-sb .adm-sheet .modal-foot { margin-top: var(--s-6); }
body.has-sb .adm-sheet .field-label { display: block; margin: 0 0 var(--s-2); font: 600 var(--t-footnote)/1.45 var(--font); color: var(--ink); }
body.has-sb .adm-sheet .field-label strong { font-weight: 600; }
body.has-sb .adm-sheet .hint { margin-top: var(--s-2); font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .adm-sheet .field-err { margin-top: var(--s-2); }
body.has-sb .adm-sheet .field-err[hidden] { display: none; }
body.has-sb .adm-fs-field textarea.input { min-height: 240px; max-height: 52vh; }
body.has-sb .adm-pick { max-height: min(56vh, 520px); overflow-y: auto; overscroll-behavior: contain; }
body.has-sb .adm-pick > .gl-row { min-height: var(--row-2); }
body.has-sb .adm-pick > label.gl-row:has(input:checked), body.has-sb .adm-pick > .gl-row[aria-checked="true"] { background: var(--wash-1); }
/* 멤버 시트의 머리 — 아바타 64 · 이름 20/600 · 이메일·전공 13 */
body.has-sb .adm-hero { display: flex; flex-direction: column; align-items: center; gap: var(--s-1); padding: var(--s-2) var(--s-7) var(--s-6); text-align: center; }
body.has-sb .adm-hero-av { display: grid; }
body.has-sb .adm-hero-name { margin-top: var(--s-3); font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; color: var(--ink); }
body.has-sb .adm-hero-sub { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); overflow-wrap: anywhere; }

/* 휴대폰 탭 — 탑바 아래 sticky 세그먼트(드로어 없이 오간다) */
body.has-sb .adm-tabs { display: none; }
@media (max-width: 879px) {
  body.has-sb .adm-tabs {
    display: block; position: sticky; top: 0; z-index: var(--z-sticky); margin: 0; padding: var(--s-2) var(--gutter); /* 본문(.panel)이 스크롤 칸이다 */
    background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); border-bottom: 1px solid var(--line);
    overflow-x: auto; scrollbar-width: none;
  }
  body.has-sb .adm-tabs::-webkit-scrollbar { display: none; }
  body.has-sb .adm-tabs-in { height: 36px; }
  body.has-sb .adm-tabs-in > a { height: 100%; }
}
@media (max-width: 699px) {
  body.has-sb:not(.x-plat) .adm-head.page-head > .page-actions { display: none; } /* '사이트 보기'는 탑바 36 원형 아이콘 */
  body.has-sb .adm-tabs-in > a::after { content: ''; position: absolute; inset: -7px 0; }
  /* 행 전체 폭 · 세그먼트는 라벨 아래 한 줄 전체 · 손가락은 44 */
  body.has-sb .adm-tools { flex-direction: column; align-items: stretch; gap: var(--s-2); }
  body.has-sb .adm-search > input { height: 44px; font-size: 16px; }
  body.has-sb .adm-tools .adm-seg, body.has-sb .gl-seg-row .adm-seg { display: flex; width: 100%; height: 40px; margin-left: 0; }
  body.has-sb :is(.adm-tools, .gl-seg-row) .adm-seg > button { flex: 1 1 0; min-width: 0; padding: 0 8px; }
  /* 세그먼트 알약(34)의 누르는 자리 — 위아래로 늘려 44(§1-5) */
  body.has-sb .adm-seg > button::after { content: ''; position: absolute; inset: -5px 0; }
  /* 시트 안 토스트 — 아래에 붙은 취소·저장 줄(48 + 여백) 위로 띄운다(버튼을 가리지 않게) */
  body.has-sb dialog.adm-sheet > .m-toast { bottom: calc(var(--h-lg) + var(--s-3) + var(--s-4) + var(--s-3) + env(safe-area-inset-bottom)); }
  body.has-sb .gl-seg-row { flex-wrap: wrap; row-gap: var(--s-2); padding-top: var(--s-3); padding-bottom: var(--s-3); }
  body.has-sb .gl-seg-row > .gl-t { flex-basis: 100%; }
  body.has-sb .adm-app { flex-wrap: wrap; }
  body.has-sb .adm-app > .gl-tx { flex: 1 1 calc(100% - 52px); }
  body.has-sb .adm-app-acts { width: 100%; padding-left: 52px; }
  body.has-sb .adm-app-acts form { flex: 1 1 0; }
  body.has-sb .adm-app-acts .btn { width: 100%; height: 44px; }
  body.has-sb .adm .gl-row .btn.btn-sm { height: 36px; }
  body.has-sb .adm-code { flex-wrap: wrap; }
  body.has-sb .adm-code > .gl-v { flex: 1 1 auto; text-align: right; }
  body.has-sb .adm-code .adm-row-acts { width: 100%; justify-content: flex-end; }
  body.has-sb .adm-more-b { width: 44px; height: 44px; }
  body.has-sb .adm-more-b::after { inset: 0; }
  body.has-sb .adm-ch .gl-v { display: none; }
  body.has-sb .adm-off { flex-wrap: wrap; }
  body.has-sb .adm-off > form { width: 100%; padding-left: 44px; }
  body.has-sb .adm-off > form .btn { width: 100%; height: 44px; }
  body.has-sb .gl input.switch[type=checkbox] { width: 44px; height: 44px; padding: 10px 2px; background-clip: content-box; }
  body.has-sb .gl input.switch[type=checkbox]::before { top: 12px; left: 4px; }
  /* 시트 — 전폭 아래 시트, 손잡이 36×5, 안전 영역 */
  body.has-sb dialog.adm-sheet { width: 100%; max-width: none; padding: 0 var(--gutter) calc(var(--s-4) + env(safe-area-inset-bottom)); border-radius: var(--r-xl) var(--r-xl) 0 0; }
  @starting-style { body.has-sb dialog.adm-sheet[open] { opacity: 1; scale: none; translate: 0 100%; } }
  body.has-sb dialog.adm-sheet .sheet-grip { display: block; margin: var(--s-2) auto var(--s-4); touch-action: none; }
  body.has-sb dialog.adm-sheet .modal-close { top: var(--s-4); right: var(--s-4); }
  body.has-sb .adm-sheet .modal-foot { position: sticky; bottom: 0; z-index: 1; margin: var(--s-5) calc(-1 * var(--gutter)) calc(-1 * (var(--s-4) + env(safe-area-inset-bottom))); padding: var(--s-3) var(--gutter) calc(var(--s-4) + env(safe-area-inset-bottom)); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
  body.has-sb .adm-sheet .modal-foot .btn { flex: 1 1 0; height: var(--h-lg); }
  body.has-sb .adm-sheet .input { height: var(--h-lg); font-size: 16px; }
  body.has-sb .adm-hero { padding-top: 0; }
}
/* 로고 미리보기 — 56px 흰 타일(인라인 52px를 이긴다) · 일정 잡기 안내 목록(인라인 13px/muted를 이긴다) — P3 이전 값 그대로 옮김 */
body.has-sb .field img[alt="현재 로고"][style] { width: 56px !important; height: 56px !important; padding: 8px; border-radius: 14px; background: #fff; box-shadow: inset 0 0 0 1px var(--x-line); }
body.has-sb .sec:has(.code-pill) ul[style] { font-size: 14px !important; line-height: 1.9 !important; color: var(--x-muted) !important; }
body.has-sb .sec:has(.code-pill) ul strong { color: var(--x-ink); font-weight: 600; }
/* 가입(회원이 보는 화면) */
body.has-sb .auth-wrap { padding-top: 88px; max-width: 440px; }
body.has-sb .auth-card { border: 0; box-shadow: none; background: transparent; padding: 0; text-align: center; }
body.has-sb .auth-card h1 { font-family: var(--font-display); font-size: 28px; font-weight: 700; letter-spacing: -0.035em; color: var(--x-ink); word-break: keep-all; }
body.has-sb .auth-card .auth-sub, body.has-sb .auth-sub { font-size: 15px; line-height: 1.6; color: var(--x-muted); word-break: keep-all; }
body.has-sb .auth-card .btn { height: 50px; font-size: 15.5px; }

/* ─────────────────────────────────────────────────────────────
   18. 좁은 화면 — ≤879 드로어 셸(탑바 56 유리) · ≤699 모바일(거터 20 · 머리 24 · 탭 타깃 44)
   ───────────────────────────────────────────────────────────── */
@media (max-width: 879px) {
  body.has-sb .topbar {
    display: grid; grid-template-columns: minmax(44px, 1fr) auto minmax(44px, 1fr); align-items: center;
    flex: none; height: var(--row); padding: 0 var(--s-2); gap: var(--s-2);
    background: var(--glass); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
    border-bottom: 1px solid var(--line);
  }
  body.has-sb .tb-burger { position: relative; justify-self: start; width: var(--h-md); height: var(--h-md); border-radius: 50%; color: var(--ink); transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
  body.has-sb .tb-burger svg { width: var(--ic-lg); height: var(--ic-lg); }
  body.has-sb .tb-burger::after { content: ''; position: absolute; inset: -2px; }
  body.has-sb .tb-burger:active { scale: var(--m-press-icon); background: var(--wash-2); }
  body.has-sb .tb-title { justify-self: center; max-width: 56vw; gap: 0; font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; color: var(--ink); }
  body.has-sb .tb-title > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  body.has-sb .tb-actions { justify-self: end; margin: 0; }
  body.has-sb .tb-actions .btn.tb-post { position: relative; height: var(--h-sm); padding: 0 14px; font-size: var(--t-footnote); }
  body.has-sb .tb-actions .btn.tb-post::after { content: ''; position: absolute; inset: -6px -2px; }
  body.has-sb .tb-icon { position: relative; width: var(--h-md); height: var(--h-md); display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; color: var(--ink-2); transition: background-color var(--dur-1) var(--ease-out), scale var(--dur-3) var(--spring); }
  body.has-sb .tb-icon svg { width: var(--ic-md); height: var(--ic-md); }
  body.has-sb .tb-icon::after { content: ''; position: absolute; inset: -2px; }
  body.has-sb .tb-icon:active { scale: var(--m-press-icon); background: var(--wash-2); }
  body.has-sb .sb { background: var(--canvas); border-right-color: var(--line); }
  body.has-sb .sb.open { box-shadow: var(--e-3); }
  body.has-sb .sb-backdrop { background: var(--scrim); }
  body.has-sb .bot-fab { right: var(--s-4); bottom: calc(var(--s-4) + env(safe-area-inset-bottom)); }
  body.has-sb:has(.page-chat, .page-thread .cmt-dock) .bot-fab { bottom: calc(84px + env(safe-area-inset-bottom)); }
  body.has-sb .sb:not(.open) { visibility: hidden; transition: translate var(--dur-2) var(--ease-in), visibility 0s linear var(--dur-2); }
  body.has-sb .sb.open { visibility: visible; transition: translate var(--dur-3) var(--ease-out), visibility 0s; }
}
/* 큰 제목 접힘(§5.6, 선택) — 페이지 제목(.page-title)이 화면 위로 지나가면 탑바 가운데 제목이 나타난다. 모션 최소화면 늘 보인다 */
@supports (animation-timeline: view()) {
  @media (max-width: 879px) and (prefers-reduced-motion: no-preference) {
    body.has-sb { timeline-scope: --page-title; }
    body.has-sb .page-title { view-timeline: --page-title block; }
    body.has-sb .topbar.tb-collapse .tb-title { animation: m-fade linear both; animation-timeline: --page-title; animation-range: exit 40% exit 100%; }
  }
}
@media (max-width: 1080px) { body.has-sb .feed-layout { padding-top: var(--s-4); padding-left: var(--gutter); } }
@media (max-width: 720px) {
  body.has-sb .feed-layout { padding: var(--s-2) var(--gutter) 0; }
  body.has-sb .page-chat .feed-layout { padding: 0; }
}
@media (max-width: 699px) {
  body.has-sb:not(.x-plat) .page-head:has(> .page-title) { grid-template-columns: minmax(0, 1fr); padding-top: var(--s-6); margin-bottom: var(--s-6); }
  body.has-sb:not(.x-plat) .page-head > .page-actions { grid-column: 1; grid-row: auto; justify-self: start; margin-top: var(--s-4); flex-wrap: wrap; }
  body.has-sb:not(.x-plat) .page-head.mu-head { grid-template-columns: minmax(0, 1fr) auto; }
  body.has-sb:not(.x-plat) .page-head.mu-head > .page-tile { grid-column: 2; grid-row: 1 / span 4; }
  body.has-sb:not(.x-plat) :is(.page-head, .set-head, .admin-head):not(:has(> .page-title)) { padding: var(--s-6) 0 var(--s-1); }
  body.has-sb .page-head[style] { flex-direction: column; align-items: flex-start !important; gap: var(--s-4) !important; }
  body.has-sb:not(.x-plat) .set-head { flex-direction: column; align-items: flex-start; gap: var(--s-4); }
  body.has-sb .page-body { padding-top: var(--s-5); }
  body.has-sb .arch-bar > .fbar { flex-basis: calc(100% + 2 * var(--gutter)); margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter); }
  /* 필터 칩 줄이 넘치면 가로 스크롤 + 스냅 + 양끝 20px 페이드(§4.6) */
  body.has-sb .fbar { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none; scroll-padding-inline: var(--gutter);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--s-5), #000 calc(100% - var(--s-5)), transparent); mask-image: linear-gradient(90deg, transparent, #000 var(--s-5), #000 calc(100% - var(--s-5)), transparent); }
  body.has-sb .fbar::-webkit-scrollbar { display: none; }
  body.has-sb .fbar > * { flex: none; scroll-snap-align: start; }
  body.has-sb .fbar:not(.arch-bar > .fbar) { margin-left: calc(-1 * var(--gutter)); margin-right: calc(-1 * var(--gutter)); padding-inline: var(--gutter); }
  body.has-sb .fbar { padding-block: var(--s-2); margin-top: calc(-1 * var(--s-2)); margin-bottom: var(--s-2); } /* 칩의 44 히트 영역(::after)이 스크롤 상자에 잘리지 않게 */
  body.has-sb .sec, body.has-sb .pf-sec, body.has-sb .mu-sec { padding-top: 0; margin-top: var(--s-9); }
  body.has-sb .page-body > .sec:first-child { margin-top: 0; }

  /* 목록 */
  body.has-sb .nrow { flex-wrap: wrap; row-gap: 6px; column-gap: var(--s-2); align-items: flex-start; }
  body.has-sb .nrow-title { flex: 1 1 0; min-width: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  body.has-sb .nrow-meta { flex: 1 1 100%; order: 3; }
  body.has-sb .nrow-chev { display: none; }
  body.has-sb :is(.mu-date, .erow-date) { width: 56px; height: 56px; }
  body.has-sb .mu-card { gap: var(--s-3); align-items: flex-start; }
  body.has-sb .mu-going { align-items: flex-end; }
  body.has-sb .page-body .notif { margin: 0 calc(-1 * var(--s-3)); padding: var(--s-3); }

  /* 셸·패널 */
  body.has-sb .panel { border: 0; border-radius: 0; }
  /* 모달 → 아래 시트(§4.7): 전폭 · 위 모서리만 22 · 하단 안전 영역 */
  body.has-sb .modal-backdrop > :is(.compose-modal, .confirm-box) { width: 100%; max-width: none; border-radius: var(--r-xl) var(--r-xl) 0 0; padding: var(--s-6) var(--s-5) calc(var(--s-4) + env(safe-area-inset-bottom)); }

  /* 채팅 */
  body.has-sb .chat-head { padding: 0 var(--gutter); gap: 10px; } /* 휴대폰 거터 20 하나(axis) */
  body.has-sb .chat-back { margin-left: 0; }
  body.has-sb .chat-meta, body.has-sb .online-row .avatar-stack, body.has-sb .online-n { display: none; }
  body.has-sb .chatrow, body.has-sb .chatrow-follow, body.has-sb .chat-day { padding-left: var(--gutter); padding-right: var(--gutter); }
  body.has-sb .composer-dock { padding: var(--s-2) var(--gutter) calc(var(--s-3) + env(safe-area-inset-bottom)); }
  body.has-sb .composer > .avatar { display: none; }
  body.has-sb:has(.page-chat) .bot-fab { display: none; }

  /* 캘린더 — 날짜 칸 전체가 단추(50×64), 6px 점 대신 칸 아래 점 셋. 칩은 숨기고 '그날 일정' 시트로 */
  body.has-sb .cal-cell { min-height: 64px; padding: 6px var(--s-1); align-items: center; }
  body.has-sb .cal-num { width: 26px; height: 26px; }
  body.has-sb .cal-cell .cal-ev, body.has-sb .cal-cell .cal-more { display: none; }
  body.has-sb .cal-day { display: block; position: absolute; inset: 0; z-index: 1; border-radius: 0; }
  body.has-sb .cal-day:active { background: var(--wash-2); }
  body.has-sb .cal-dots { display: flex; gap: 3px; margin-top: var(--s-1); }
  body.has-sb .cal-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink); }
  body.has-sb .cal-head { flex-wrap: wrap; }
  body.has-sb .wk-day { display: flex; flex-direction: column; align-items: center; gap: 3px; white-space: nowrap; }
  body.has-sb .wk-day.on b { padding: 1px 6px; }
  body.has-sb .wk-ev::after { content: ''; position: absolute; inset: -4px -2px; }
  body.has-sb .wk-ev { min-height: 36px; }

  /* 시간표 편집 — 행 = 시간(9~21), 열 = 요일 7. 칸 44(마크업 순서를 grid-auto-flow: column이 눕힌다) */
  body.has-sb .tt-grid[data-tt] { grid-auto-flow: column; grid-template-columns: 24px repeat(7, minmax(0, 1fr)); grid-template-rows: auto repeat(13, var(--h-lg)); gap: 2px; }
  body.has-sb .tt-grid[data-tt] .tt-cell { width: auto; height: var(--h-lg); aspect-ratio: auto; border-radius: var(--r-xs); }
  body.has-sb .tt-grid[data-tt] .tt-cell::after { content: ''; position: absolute; inset: 0 -3px; }
  body.has-sb .tt-card:has(> [data-tt]) { padding: var(--s-3); }
  body.has-sb .tt-grid[data-tt] .tt-cell { position: relative; }
  body.has-sb .tt-grid:not([data-tt]):not(:has(> .tt-free)) { grid-template-columns: 22px repeat(13, minmax(0, 1fr)); gap: 3px; }
  body.has-sb .tt-grid:not([data-tt]):not(:has(> .tt-free)) .tt-cell { width: auto; height: auto; aspect-ratio: 1; }
  body.has-sb .tt-card { padding: var(--s-4); width: 100%; }
  body.has-sb .tt-grid:has(> .tt-free) { grid-template-columns: 24px repeat(7, minmax(0, 1fr)); gap: var(--s-1); }

  /* 프로필 — 포트레이트는 이름 위(작게), 이름 x = 거터 */
  body.has-sb:not(.x-plat) .pf-head { grid-template-columns: minmax(0, 1fr); grid-template-areas: "portrait" "id" "acts"; row-gap: var(--s-5); }
  body.has-sb:not(.x-plat) .pf-head > .pf-portrait { width: 160px; }
  body.has-sb .pf-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  body.has-sb .pf-stats > div { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: var(--s-4); }
  body.has-sb .pf-stats > div:nth-child(3n), body.has-sb .pf-stats > div:last-child { border-right: 0; }
  body.has-sb .pf-stats > div:nth-last-child(-n+3):nth-child(3n+1), body.has-sb .pf-stats > div:nth-last-child(-n+3):nth-child(3n+1) ~ div { border-bottom: 0; }
  body.has-sb .pf-row-main { flex-wrap: wrap; row-gap: 2px; }
  body.has-sb .pf-row-main strong { flex: 1 1 100%; white-space: normal; }

  /* 글 상세 — '← 칼럼'은 한 줄(아이콘 + 라벨), '포트폴리오 비공개' 칩은 상태 점만 */
  body.has-sb .art-back { flex: none; gap: 6px; }
  body.has-sb .art-top .pf-tg { width: var(--h-sm); padding: 0; justify-content: center; }
  body.has-sb .art-top .pf-tg > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  body.has-sb .art-top .pf-tg::before { margin: 0; }
  body.has-sb .page.page-article { padding-bottom: var(--s-10); }
  body.has-sb .mu-hero { gap: var(--s-4); }
  body.has-sb .mu-people { grid-template-columns: minmax(0, 1fr); }
  body.has-sb .mu-join { flex-wrap: wrap; }

  /* 폼 */
  body.has-sb .form-row:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { gap: 0; }
  body.has-sb .fcard { padding: var(--s-4) 0; }

  /* 탭 타깃 44(§1.5) — 키울 수 있는 것은 키우고, 줄 안 링크·칩은 보이지 않는 히트 영역(::after)을 넓힌다 */
  body.has-sb :is(.btn-sm, .icon-act, .icon-btn, .sb-icon-btn, .attach-btn, .fpill, .seg > a, .seg > button, a.chip, .chip-tag, .fcard-reply, .fcard-like, .fcard-name, .frow-name, .chat-name, .art-byline-name, .cmt-reply-btn, .pf-tg, .cchip, .sec-more, .code-pill button, .feat-toggle, .art-facts-link, .ck-hook-link, .ck-hook-btn, a.fcard-obj, .menu.grp > summary, .menu.more > summary, .rel-chip, .freply-more, .frow-reply, .jhero-more):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { position: relative; }
  body.has-sb :is(.btn-sm, .icon-act, .icon-btn, .sb-icon-btn, .code-pill button, .feat-toggle, .menu.more > summary):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -6px; }
  body.has-sb :is(.fpill, .fcard-reply, .fcard-like, .pf-tg, .cchip):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -6px -2px; }
  body.has-sb :is(.seg > a, .seg > button):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -7px 0; }
  body.has-sb :is(.menu.grp > summary, .ck-hook-btn, .jhero-more):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -4px -2px; }
  body.has-sb .attach-btn::after { content: ''; position: absolute; inset: -4px; }
  body.has-sb :is(a.chip, .chip-tag, .cmt-reply-btn):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -10px -4px; }
  body.has-sb :is(.fcard-name, .frow-name, .chat-name, .art-byline-name, .sec-more, .rel-chip, .freply-more, .frow-reply):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -14px -8px; }
  body.has-sb :is(.art-facts-link, .ck-hook-link):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -14px -6px; }
  body.has-sb a.fcard-obj:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -8px 0; }
  body.has-sb .chatrow .plink { position: relative; }
  body.has-sb .chatrow .plink::after { content: ''; position: absolute; inset: -6px; }
  body.has-sb .pf-row-main { min-height: var(--hit); }
  body.has-sb .art-back::after { content: ''; position: absolute; inset: -6px -2px; }
}

/* 체크 행 — 눈에 보이는 상자는 18, 누르는 자리는 줄 전체 44(네이티브 체크박스가 줄을 덮는다) */
body.has-sb .check-row { position: relative; min-height: var(--hit); }
body.has-sb .check-row::before { content: ''; flex: none; width: 18px; height: 18px; border: 1.5px solid var(--line-3); border-radius: var(--r-xs); background: var(--paper) center / 12px no-repeat; transition: background-color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out); }
body.has-sb .check-row:has(> input:checked)::before { border-color: var(--ink); background-color: var(--ink); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.5 12.5 5 5L19.5 7'/%3E%3C/svg%3E"); }
body.has-sb .check-row > input[type=checkbox] { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
body.has-sb .check-row:has(> input:focus-visible) { outline: var(--focus); outline-offset: var(--focus-offset); border-radius: var(--r-sm); }

/* ─────────────────────────────────────────────────────────────
   19. 모션 — 진입 안무는 v5.css [data-enter]·[data-enter-list]. 여기는 앱 몫의 마이크로만. 모션 최소화면 v5.css §6이 줄인다
   ───────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  body.has-sb .erow-arrow { transition: none; }
  body.has-sb .fcard-like.pop svg, body.has-sb .chatrow.is-new, body.has-sb .feed-body > .fcard.is-new { animation: none; }
}


/* ─────────────────────────────────────────────────────────────
   21. 마무리 — 측정에서 나온 남은 값(모노·곡선·크기·탭 타깃)을 토큰으로
   ───────────────────────────────────────────────────────────── */
body.has-sb h1.sr-only { font: 600 var(--t-title-2)/1.1 var(--font); }
body.has-sb .sb-powered strong { font-family: var(--font); }
body.has-sb :is(.fpill .n, .sec-count, .ch-n, .stack-more, .badge) { font-family: var(--font); }
body.has-sb .fpill:not(.on) .n, body.has-sb .chip:not(.strong):not(.on) .num { opacity: 1; color: var(--ink-3); }
body.has-sb .chip:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
body.has-sb .lcard-acts { transition: opacity var(--dur-1) var(--ease-out); }
body.has-sb :is(.menu, details) > summary { transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
body.has-sb .art-top .article-actions, body.has-sb .article-actions { transition: opacity var(--dur-1) var(--ease-out); }
body.has-sb .me-avatar-badge { transition: none; }
body.has-sb .ck-hook-stat { font: 400 var(--t-footnote)/1.45 var(--font); color: var(--ink-3); }
body.has-sb .ck-hook-stat b { font: 600 var(--t-body)/1 var(--font); color: var(--ink); }
body.has-sb .prose-sm :is(p, li) { font-size: var(--t-body); }
body.has-sb .hint strong, body.has-sb .hint b { font-weight: 600; }
body.has-sb .jcard-meta:not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { overflow-wrap: break-word; }
body.has-sb .tt-grid[data-tt] .tt-cell { height: var(--h-lg); }
@media (max-width: 699px) {
  body.has-sb .plink { position: relative; }
  body.has-sb .plink::after { content: ''; position: absolute; inset: -2px; }
  body.has-sb .chatrow .frow-name { position: relative; }
  body.has-sb .chatrow .frow-name::after { content: ''; position: absolute; inset: -14px -8px; }
  body.has-sb .art-head .art-eyebrow a, body.has-sb .art-byline-name, body.has-sb .art-facts-link { position: relative; }
  body.has-sb .art-head .art-eyebrow a::after, body.has-sb .art-byline-name::after, body.has-sb .art-facts-link::after { content: ''; position: absolute; inset: -14px -12px; }
  body.has-sb .utabs > a::after { content: ''; position: absolute; inset: 0 -6px; }
  body.has-sb:not(.x-plat) .mu-scope-seg input { inset: -7px 0; height: auto; }
  body.has-sb .btn:not(.btn-sm):not(.btn-lg):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *) { position: relative; }
  body.has-sb .btn:not(.btn-sm):not(.btn-lg):not(:is(.art-head,.art-facts,.art-cover,.art-prose,.art-imgs,.rel-paper,.md-preview,.ed,.mdt,.md-toolbar,.thumb-field,.ts,[data-ts]) *)::after { content: ''; position: absolute; inset: -2px; }
  body.has-sb .wk-ev::after { inset: -4px -5px; }
  body.has-sb .wk-ev-t { display: none; }
  body.has-sb .art-top .pf-tg::after { inset: -6px; }
}

/* 사이드바 활성 면 — 행 안의 .sb-on(워시)이 vt-sb-on 이름으로 행 사이를 미끄러진다. 크롬(vt-sb)은 즉시 바뀌고 이 면만 --dur-3 */
body.has-sb .sb-link { position: relative; isolation: isolate; }
body.has-sb .sb-on { position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--sb-on); view-transition-name: vt-sb-on; pointer-events: none; }
body.has-sb .sb-nav .sb-link.on:not(.sb-link-danger):has(> .sb-on), body.has-sb .sb-nav .sb-link.on:not(.sb-link-danger):has(> .sb-on):hover { background: transparent; }
::view-transition-group(vt-sb-on) { animation-duration: var(--dur-3); animation-timing-function: var(--ease-out); z-index: 4; }
/* 드로어(≤879)에서는 끈다 — 열린 드로어에서 이동하면 새 화면의 드로어는 닫혀 있어, 옛 면만 떠서 사라지는 잔상이 생긴다 */
@media (max-width: 879px) { body.has-sb .sb-on { view-transition-name: none; } }
/* 카드·피드 안 사용자 마크다운 — h2 17/600, h3 15/600(기사 본문 보호 구역은 제외) */
body.has-sb :is(.fcard-text, .tweet-prose, .mu-sec .prose, .ev-prose, .ar-prose, .cards-prose, .pf .prose-sm) :is(h1, h2) { margin: 1.2em 0 .4em; font: 600 var(--t-card)/1.3 var(--font); letter-spacing: -0.015em; }
body.has-sb :is(.fcard-text, .tweet-prose, .mu-sec .prose, .ev-prose, .ar-prose, .cards-prose, .pf .prose-sm) :is(h3, h4) { margin: 1em 0 .3em; font: 600 var(--t-body)/1.45 var(--font); letter-spacing: -0.01em; }
@media (hover: hover) and (pointer: fine) { body.has-sb .page-body .notif:not(.notif-new):hover { background: var(--wash-1); } body.has-sb .page-body .notif:not(.notif-new):hover:active { background: var(--wash-2); } }

/* ─────────────────────────────────────────────────────────────
   20. P3 → P4 인계 — routes-society.js의 인라인 style을 옮긴 클래스(잠금·가입·랜딩 대기 칩). 값은 옮기기 전과 같다.
       공개 셸(.intro-page)에서도 쓰이므로 body.has-sb로 묶지 않는다. P4가 공개 표면 규칙으로 흡수한다
   ───────────────────────────────────────────────────────────── */
.gate-page { padding-top: 52px; }
.chip.chip-wait { height: 38px; padding: 0 16px; font-size: 13px; }
.chip.chip-wait-lg { height: 40px; padding: 0 18px; }
.join-wrap { max-width: 440px; }
.join-head { text-align: center; margin-bottom: 26px; }
.join-logo { width: 64px; height: 64px; object-fit: contain; margin: 0 auto 16px; }
.join-title { font-size: 24px; letter-spacing: -0.03em; }
.join-tag { color: var(--muted); font-size: 14px; margin-top: 8px; }
.join-code-hint { color: var(--dim); font-size: 12.5px; margin-bottom: 12px; }

/* ─────────────────────────────────────────────────────────────
   20-b. P3 → P4 인계 — P3가 바꾼 공용 마크업(페이지 머리 · 날짜 타일 · 포트레이트 · 선 아이콘 · 밑줄 탭)이
         홍보 셸(.intro-page)에서도 깨지지 않게 하는 바탕값. 명시도 0(:where)이라 P4의 공개 표면 규칙이 그대로 이긴다
   ───────────────────────────────────────────────────────────── */
:where(body:not(.has-sb)) :where(.sec-more, .art-back, .erow-arrow, .art-facts-link, .linked-col-arrow, .fcard-more, .fcard-src, .cchip, .nrow-chev, .mu-tools, .chat-back, .pf-actions, .rel-paper) svg { width: var(--ic-sm); height: var(--ic-sm); flex: none; }
:where(body:not(.has-sb)) :where(.sec-more, .art-back, .art-facts-link, .fcard-more, .cchip) { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
:where(body:not(.has-sb)) :where(.art-back) { height: var(--h-sm); padding: 0 14px 0 var(--s-2); border-radius: var(--r-pill); background: var(--wash-2); color: var(--ink); font: 500 var(--t-footnote)/1 var(--font); }
.utabs[data-tabs] { height: auto; padding: 0; border-radius: 0; background: none; }
:where(body:not(.has-sb)) :where(.page-head:has(> .page-title)) { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s-6); align-items: end; }
:where(body:not(.has-sb)) :where(.page-head:has(> .page-title)) > * { grid-column: 1; min-width: 0; }
:where(body:not(.has-sb)) :where(.page-head) > :where(.page-actions, .page-tile) { grid-column: 2; grid-row: 1 / span 4; display: flex; gap: var(--s-2); }
:where(body:not(.has-sb)) :where(.page-head) > :where(.page-tile) { align-self: start; }
:where(body:not(.has-sb)) :where(.page-head) > :where(.page-actions) { align-self: end; }
:where(body:not(.has-sb)) :where(.page-title) { font: 600 var(--t-title-1)/1.1 var(--font); letter-spacing: -0.04em; color: var(--ink); }
:where(body:not(.has-sb)) :where(.page-lead) { margin-top: var(--s-2); font: 400 var(--t-body)/1.65 var(--font); color: var(--ink-3); }
:where(body:not(.has-sb)) :where(.mu-chips) { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s-4); }
:where(body:not(.has-sb)) :where(.mu-join) { display: flex; align-items: center; gap: var(--s-4); margin-top: var(--s-7); padding: var(--s-4) 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
:where(body:not(.has-sb)) :where(.mu-join) :where(.share-btn) { margin-left: auto; }
:where(body:not(.has-sb)) :where(.mu-count, .mu-cap) { display: inline-block; white-space: nowrap; }
:where(body:not(.has-sb)) :where(.mu-sec) { margin-top: var(--s-9); }
:where(body:not(.has-sb)) :where(.sec-h) { margin-bottom: var(--s-4); font: 600 var(--t-headline)/1.3 var(--font); letter-spacing: -0.02em; }
:where(body:not(.has-sb)) :where(.mu-people) { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0 var(--s-4); }
:where(body:not(.has-sb)) :where(.mu-tools) { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-top: var(--s-9); padding-top: var(--s-4); border-top: 1px solid var(--line); }
:where(body:not(.has-sb)) :where(.mu-date, .erow-date) { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; width: 64px; height: 64px; border-radius: var(--r-md); background: var(--wash-2); }
:where(body:not(.has-sb)) :where(.mu-date, .erow-date) > span { font: 500 var(--t-caption)/1.2 var(--font); color: var(--ink-3); }
:where(body:not(.has-sb)) :where(.mu-date, .erow-date) > b { font: 600 var(--t-title-3)/1 var(--font); color: var(--ink); font-variant-numeric: tabular-nums; }
:where(body:not(.has-sb)) :where(.pf-head:has(> .pf-portrait)) { display: grid; grid-template-columns: minmax(0, 1fr) 240px; grid-template-areas: "id portrait" "acts portrait"; column-gap: var(--s-9); row-gap: var(--s-5); align-items: start; }
:where(body:not(.has-sb)) :where(.pf-head) > :where(.pf-portrait) { grid-area: portrait; width: 240px; border-radius: var(--r-xl); }
:where(body:not(.has-sb)) :where(.pf-head) > :where(.pf-id) { grid-area: id; min-width: 0; }
:where(body:not(.has-sb)) :where(.pf-head) > :where(.pf-actions) { grid-area: acts; }
:where(body:not(.has-sb)) :where(.pf-eyebrow) { display: block; font: 500 var(--t-footnote)/1.45 var(--font); letter-spacing: 0; text-transform: none; }
:where(body:not(.has-sb)) :where(.dot:not(:empty)) { margin: 0 6px; color: var(--ink-4); }
@media (max-width: 699px) {
  :where(body:not(.has-sb)) :where(.pf-head:has(> .pf-portrait)) { grid-template-columns: minmax(0, 1fr); grid-template-areas: "portrait" "id" "acts"; }
  :where(body:not(.has-sb)) :where(.pf-head) > :where(.pf-portrait) { width: 160px; }
  :where(body:not(.has-sb)) :where(.mu-date, .erow-date) { width: 56px; height: 56px; }
}
:where(body:not(.has-sb)) :is(.pf > .art-back, .art-top .art-back) { display: inline-flex; flex-direction: row; }

/* ─────────────────────────────────────────────────────────────
   드로어(≤879) 행 — 터치 타깃 44(§1.5). 데스크톱 사이드바 32h(§4.11)는 그대로, 손가락으로 여는 드로어에서만 키운다
   (앱 사이드바·/me 드로어 공통. 행 사이 2px 유지 → 행 간격 46)
   ───────────────────────────────────────────────────────────── */
@media (max-width: 879px) {
  body.has-sb .sb :is(.sb-link, .sb-back, .sb-util, .sb-search) { height: auto; min-height: var(--hit); }
  body.has-sb .sb .sb-back { margin-bottom: var(--s-2); }
  body.has-sb .sb .sb-icon-btn { position: relative; }
  body.has-sb .sb .sb-icon-btn::after { content: ''; position: absolute; inset: -6px; }
  body.has-sb .sb .sb-powered { display: flex; align-items: center; justify-content: center; min-height: var(--hit); padding-top: 0; }
  body.has-sb .sb .sb-ws > summary, body.has-sb .sb .sb-user-menu > summary { min-height: var(--hit); }
  body.has-sb .sb .sb-head .menu > summary { position: relative; } /* /me 드로어 머리의 계정 아바타(32) — hit 44 */
  body.has-sb .sb .sb-head .menu > summary::after { content: ''; position: absolute; inset: -6px; }
}

/* 스포트라이트 — 닫기 버튼은 터치(≤699 시트)에서만. 데스크톱은 esc 힌트 */
body.has-sb .spot-x { display: none; }
@media (max-width: 699px) {
  /* ≤699: 모달 → 아래 시트(§4.7). 입력 행 전체가 label(56h), 닫기 32 원(+hit 44), 키보드 힌트·foot 숨김, 바로가기 44 */
  body.has-sb .spot-back { align-items: flex-end; padding: 0; }
  body.has-sb .spot { width: 100%; max-height: 92svh; border-radius: var(--r-xl) var(--r-xl) 0 0; padding-bottom: calc(var(--s-4) + env(safe-area-inset-bottom)); animation: m-sheet-in var(--dur-3) var(--ease-out); }
  body.has-sb .spot-back.closing .spot { animation: m-sheet-out var(--dur-2) var(--ease-in) both; }
  body.has-sb .spot-head { min-height: var(--row); padding: 0 var(--s-3) 0 var(--s-5); cursor: text; }
  body.has-sb .spot-input { align-self: stretch; min-height: var(--hit); font-size: 16px; }
  body.has-sb .spot-head .kbd, body.has-sb .spot-foot { display: none; }
  body.has-sb .spot-x { position: relative; flex: none; display: inline-flex; align-items: center; justify-content: center; width: var(--h-sm); height: var(--h-sm); border: 0; border-radius: 50%; background: var(--wash-2); color: var(--ink-2); }
  body.has-sb .spot-x::after { content: ''; position: absolute; inset: -6px; }
  body.has-sb .spot-x svg { width: var(--ic-sm); height: var(--ic-sm); }
  body.has-sb .spot-x:active { scale: var(--m-press-icon); }
  body.has-sb .spot-pill { height: var(--hit); }
  body.has-sb .spot-body { max-height: 60svh; }
}

/* 워크스페이스 행 → 바로 '내 팀' 전환 목록(Slack·Linear 문법). 지금 팀은 체크, 팀이 많으면 목록만 스크롤 */
body.has-sb .ws-pop { min-width: 272px; max-width: 320px; }
body.has-sb .ws-pop .ws-lab { padding: var(--s-2) 10px 6px; font: 500 var(--t-caption)/1.3 var(--font); color: var(--ink-3); }
body.has-sb .ws-pop .ws-list { display: flex; flex-direction: column; gap: 2px; max-height: min(360px, 50vh); overflow-y: auto; overscroll-behavior: contain; }
body.has-sb .ws-pop .ws-team { display: flex; align-items: center; gap: var(--s-3); min-height: 48px; padding: 6px 10px; border-radius: var(--r-md); color: var(--ink); transition: background-color var(--dur-1) var(--ease-out); }
body.has-sb .ws-pop .ws-team.on { background: var(--wash-2); }
body.has-sb .ws-pop .ws-logo { flex: none; width: 28px; height: 28px; border-radius: var(--r-sm); object-fit: contain; background: var(--paper); box-shadow: inset 0 0 0 1px var(--line); }
body.has-sb .ws-pop .ws-logo-txt { display: grid; place-items: center; background: var(--wash-2); box-shadow: none; font: 600 var(--t-ui)/1 var(--font); color: var(--ink-2); }
body.has-sb .ws-pop .ws-team-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
body.has-sb .ws-pop .ws-team-t strong { overflow: hidden; font: 600 var(--t-ui)/1.3 var(--font); letter-spacing: -0.01em; white-space: nowrap; text-overflow: ellipsis; }
body.has-sb .ws-pop .ws-team-t span { overflow: hidden; font: 400 var(--t-caption)/1.3 var(--font); color: var(--ink-3); white-space: nowrap; text-overflow: ellipsis; }
body.has-sb .ws-pop .ws-check { flex: none; display: grid; color: var(--ink); }
body.has-sb .ws-pop .ws-check svg { width: var(--ic-md, 18px); height: var(--ic-md, 18px); }
body.has-sb .ws-pop .ws-sep { height: 1px; margin: 6px 4px; background: var(--line); }
body.has-sb .ws-pop .ws-act { display: flex; align-items: center; gap: 10px; }
body.has-sb .ws-pop .ws-act svg { flex: none; width: var(--ic-sm, 16px); height: var(--ic-sm, 16px); color: var(--ink-3); }
@media (hover: hover) and (pointer: fine) { body.has-sb .ws-pop .ws-team:not(.on):hover { background: var(--wash-1); } }
body.has-sb .ws-pop .ws-team:active { background: var(--wash-2); }
body.has-sb .ws-pop .ws-team:focus-visible { outline: var(--focus); outline-offset: -2px; }
@media (pointer: coarse) { body.has-sb .ws-pop .ws-team { min-height: var(--hit); } }
