/* ============================================================
   장례식장 모듈 전용 스타일.

   [CSS isolation(.razor.css)을 쓰지 않는 이유]

   아래 클래스들은 화면 여럿이 함께 쓴다(빈소현황 카드 · 설정 줄 · 자료 목록).
   isolation 은 컴포넌트 하나에 묶이므로, 공유하려면 화면마다 같은 규칙을
   복사해야 한다. 그러면 어느 화면 하나만 여백이 달라진다.

   모듈 안에서만 쓰이므로 Blazor Common 으로 올리지 않는다 —
   올리면 이 스타일이 여섯 모듈 전체의 결합 지점이 된다.
   ============================================================ */

.fn-subhead {
  margin: 1.5rem 0 0.75rem;
  font-size: var(--jsini-fs-lg);
  font-weight: 700;
}

/* ── 빈소현황 카드판 ────────────────────────────────────── */

.fn-board {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr));
  gap: 1rem;
  align-items: stretch;
}

.fn-card {
  display: flex;
  min-width: 0;
  flex-direction: column;
  border: 1px solid var(--jsini-border);
  border-radius: 0.55rem;
  padding: 1rem;
  background: var(--jsini-surface-raised, var(--jsini-surface));
  box-shadow: 0 1px 2px rgb(20 35 55 / 7%);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.fn-card:hover { border-color: var(--jsini-accent); box-shadow: 0 4px 14px rgb(20 35 55 / 11%); }

/* 색은 빠른 훑기를 돕고, 아이콘·문구가 상태를 함께 전달한다. */
.fn-card--in-use { border-top: 3px solid var(--jsini-accent); }
.fn-card--empty { border-top: 3px solid var(--jsini-border); }
.fn-card--device-alert { border-color: color-mix(in srgb, #d32f2f 45%, var(--jsini-border)); }

.fn-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 2.5rem;
}

.fn-card__room-wrap { display: grid; gap: 0.2rem; min-width: 0; }
.fn-card__room { font-size: var(--jsini-fs-lg); font-weight: 750; }
.fn-card__occupancy,
.fn-equipment-status {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: var(--jsini-fs-xs);
  font-weight: 600;
}
.fn-card__occupancy { color: var(--jsini-text-muted); }
.fn-card__badges { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.25rem; }
.fn-equipment-status {
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 0.2rem 0.45rem;
  white-space: nowrap;
}
.fn-equipment-status--ok { color: #2e7d32; }
.fn-equipment-status--fault { color: #c62828; }
.fn-equipment-status__count { font-variant-numeric: tabular-nums; opacity: 0.8; }

.fn-card__body { display: flex; flex: 1; flex-direction: column; margin-top: 0.75rem; }

.fn-card__body--empty {
  color: var(--jsini-text-muted);
  font-size: var(--jsini-fs-md);
  gap: 0.55rem;
}

.fn-card__name { font-size: var(--jsini-fs-xl); font-weight: 700; }
.fn-card__person-info { min-width: 0; }

.fn-card__facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.2rem 0.75rem;
  margin: 0.5rem 0 0;
  font-size: var(--jsini-fs-sm);
}

.fn-card__facts dt { color: var(--jsini-text-muted); }
.fn-card__facts dd { margin: 0; }

.fn-status-summary { margin-bottom: 1rem; }
.fn-status-summary .jsini-stat__label { display: flex; align-items: center; gap: 0.35rem; }
.fn-stat--active { border-top: 3px solid #2e7d32; }
.fn-stat--empty { border-top: 3px solid var(--jsini-border); }
.fn-stat--online { border-top: 3px solid #2e7d32; }
.fn-stat--alert { border-top: 3px solid #c62828; }

.fn-board-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 1rem 0 0.75rem;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--jsini-border);
  border-radius: 0.45rem;
  background: var(--jsini-surface);
}
.fn-board-toolbar__result { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem; }
.fn-board-toolbar__result strong { font-size: var(--jsini-fs-lg); }
.fn-board-toolbar__hint { color: var(--jsini-text-muted); font-size: var(--jsini-fs-xs); }
.fn-board-toolbar .jsini-refresh-status { margin: 0; }
.fn-board-toolbar .jsini-refresh-status__error { display: inline-flex; align-items: center; gap: 0.25rem; }

.fn-board-empty {
  display: grid;
  justify-items: center;
  gap: 0.45rem;
  padding: 3rem 1rem;
  border: 1px dashed var(--jsini-border);
  border-radius: 0.55rem;
  color: var(--jsini-text-muted);
  text-align: center;
}
.fn-board-empty [class*='jsini-icon-'] { width: 1.75rem; height: 1.75rem; opacity: 0.65; }
.fn-board-empty strong { color: var(--jsini-text); }

/* ── 모바일 현황 ────────────────────────────────────────── */

.fn-mobile {
  display: grid;
  gap: 0.5rem;
}

.fn-mobile__card {
  border: 1px solid var(--jsini-border);
  padding: 0.75rem 0.9rem;
}

.fn-mobile__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.fn-mobile__room { font-weight: 700; }
.fn-mobile__name { margin-top: 0.4rem; font-size: var(--jsini-fs-xl); }

.fn-mobile__meta {
  margin-top: 0.2rem;
  font-size: var(--jsini-fs-sm);
  color: var(--jsini-text-muted);
}

/* ── 미리보기 ───────────────────────────────────────────── */

.fn-preview {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.75rem;
}

.fn-preview__item {
  margin: 0;
  border: 1px solid var(--jsini-border);
}

.fn-preview__item img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: #000;
}

/* 오프라인 자리를 그림과 같은 높이로 잡아 둔다 — 안 잡으면 장비가 끊길 때마다
   격자가 위아래로 출렁인다. */
.fn-preview__offline {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 9;
  background: color-mix(in srgb, var(--jsini-text-muted) 10%, transparent);
  color: var(--jsini-text-muted);
  font-size: var(--jsini-fs-md);
}

.fn-preview__caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  font-size: var(--jsini-fs-md);
}

/* ── 환경설정 ───────────────────────────────────────────── */

.fn-settings { margin-bottom: 1.5rem; }

.fn-setting {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--jsini-border);
}

.fn-setting__name { font-weight: 600; }

.fn-setting__desc {
  margin-top: 0.15rem;
  font-size: var(--jsini-fs-sm);
  color: var(--jsini-text-muted);
}

/* ── 도움말 ─────────────────────────────────────────────── */

.fn-faq { margin-bottom: 1.5rem; }

.fn-faq__item { border-bottom: 1px solid var(--jsini-border); }

.fn-faq__q {
  padding: 0.7rem 0;
  cursor: pointer;
  font-weight: 600;
}

.fn-faq__a {
  padding: 0 0 0.9rem;
  font-size: var(--jsini-fs-md);
  line-height: 1.7;
  color: var(--jsini-text-muted);
  white-space: pre-line;
}

.fn-qna { display: grid; gap: 0.5rem; }

/* 깊이를 CSS 변수로 받는다. 깊이마다 클래스를 만들면 몇 단계에서 바닥난다.
   여덟 단계에서 들여쓰기를 멈춰 좁은 화면에서 본문이 사라지지 않게 한다. */
.fn-qna__post {
  margin-left: calc(min(var(--depth), 8) * 1.25rem);
  border: 1px solid var(--jsini-border);
  border-left-width: 3px;
  padding: 0.7rem 0.9rem;
}

.fn-qna__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--jsini-fs-sm);
  color: var(--jsini-text-muted);
}

.fn-qna__title {
  font-size: var(--jsini-fs-lg);
  font-weight: 700;
  color: var(--jsini-text, inherit);
}

.fn-qna__body {
  margin-top: 0.5rem;
  font-size: var(--jsini-fs-md);
  line-height: 1.7;
  white-space: pre-line;
}

/* ── 첨부 파일 목록 ─────────────────────────────────────── */

.fn-files {
  margin: 0;
  padding: 0.5rem 0;
  list-style: none;
}

.fn-files__item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.35rem 0;
}

.fn-files__size {
  font-size: var(--jsini-fs-sm);
  color: var(--jsini-text-muted);
}

/* F.A.Q 항목의 관리 단추. 답변 아래 오른쪽에 조용히 둔다 —
   읽으러 온 사람에게 먼저 보이면 안 되는 것들이다. */
.fn-faq__tools {
  display: flex;
  justify-content: flex-end;
  gap: 0.25rem;
  padding: 0 0.2rem 0.4rem;
}

/* Q&A 글의 단추 줄. 본문 아래 오른쪽에 조용히 둔다. */
.fn-qna__tools {
  display: flex;
  justify-content: flex-end;
  gap: 0.25rem;
  margin-top: 0.2rem;
}

/* 답글 창 맨 위의 「무엇에 답하는가」. 대상을 안 보여 주면 깊은 스레드에서
   엉뚱한 글에 답글을 단다. */
.fn-qna__quote {
  margin-bottom: 0.6rem;
  padding: 0.5rem 0.7rem;
  background: var(--jsini-surface);
  border-left: 3px solid var(--jsini-border);
  font-size: var(--jsini-fs-sm);
}

.fn-qna__quote-label {
  display: block;
  font-weight: 600;
  opacity: 0.6;
  font-size: var(--jsini-fs-xs);
}

/* ── 자료 미리보기 ───────────────────────────────────────

   목록에 그림을 함께 보여 준다. 이름만으로는 어느 영상인지 알 수 없다.
   ---------------------------------------------------------- */

.fn-thumb {
  display: block;
  width: 64px;
  height: 36px;
  object-fit: cover;
  border-radius: 0.2rem;
  background: var(--jsini-surface);
}

/* 미리보기가 아직 없을 때. 「만들다 실패한 것」과 「방금 올린 것」이 같아
   보이므로 재처리 단추를 그 줄에 함께 둔다. */
.fn-thumb--none {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--jsini-fs-2xs);
  opacity: 0.5;
  border: 1px dashed var(--jsini-border);
}

/* ── 빈소 카드: 고인 줄 ───────────────────────────────────

   영정과 이름·성별·나이를 나란히 둔다. 사진이 없는 고인이 흔해서
   (아직 안 올렸거나 안 올리는 경우) **없는 것이 기본**으로 보여야 한다 —
   빈 자리를 남기지 않고 글자만 왼쪽으로 붙는다.
   ---------------------------------------------------------- */

.fn-card__person {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}

.fn-card__photo {
  flex: 0 0 auto;
  width: 48px;
  height: 60px;
  object-fit: cover;
  border-radius: 0.2rem;
  background: var(--jsini-surface);
}

.fn-card__sub {
  font-size: var(--jsini-fs-xs);
  opacity: 0.65;
}

.fn-card__sub > span { margin-left: 0.2rem; }

/* ── 기기 화면 표시 설정 ─────────────────────────────────

   칸이 마흔 개가 넘는다. 한 줄에 하나씩 쌓으면 화면 두 판을 넘어가고,
   그러면 「저장」이 어디 있는지 안 보인다. 격자로 접어 넣는다.
   ---------------------------------------------------------- */

.fn-note {
  margin-left: 0.4rem;
  font-size: var(--jsini-fs-xs);
  font-weight: 400;
  color: var(--jsini-text-muted);
}

.fn-devsec {
  margin-top: 0.9rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--jsini-border);
  border-radius: 0.3rem;
  background: var(--jsini-surface, #fff);
}

/* 이 기기 종류가 쓰는 묶음. 안 쓰는 묶음은 옅게 두어 뒤로 물러나게 한다 —
   숨기지 않는 이유는 유형을 잘못 넣은 장비를 고칠 길이 필요해서다. */
.fn-devsec.is-on {
  border-left: 3px solid #2e7d32;
}

.fn-devsec:not(.is-on) {
  opacity: 0.7;
}

.fn-devsec__head {
  margin: 0 0 0.5rem;
  font-size: var(--jsini-fs-md);
  font-weight: 700;
}

.fn-devsec__body {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.5rem 0.9rem;
}

.fn-field {
  display: grid;
  gap: 0.2rem;
  min-width: 0;
}

.fn-field--wide {
  grid-column: 1 / -1;
}

.fn-field__label {
  font-size: var(--jsini-fs-2xs);
  letter-spacing: 0.03em;
  color: var(--jsini-text-muted);
}

.fn-field__input {
  min-width: 0;
}

/* 상·하·좌·우 네 칸. 한 줄에 넷을 넣어야 「여백」 하나로 읽힌다. */
.fn-quad {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.25rem;
}

/* 카드에서 고치러 가는 길. 배지처럼 보이면 상태로 읽히므로 링크로 둔다. */
.fn-card__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: auto;
  padding-top: 0.75rem;
  border-top: 1px solid var(--jsini-border);
  font-size: var(--jsini-fs-xs);
}
.fn-card__links a { display: inline-flex; align-items: center; gap: 0.25rem; }
.fn-card__links a:focus-visible,
.fn-card button:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--jsini-accent) 55%, transparent);
  outline-offset: 2px;
}
.fn-empty-state { display: flex; align-items: center; gap: 0.4rem; color: var(--jsini-text); }
.fn-card__cancel-note { display: flex; align-items: center; gap: 0.3rem; color: #b26a00; font-size: var(--jsini-fs-xs); font-weight: 600; }

@media (max-width: 900px) {
  .fn-board { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 0.75rem; }
  .fn-board-toolbar { align-items: flex-start; flex-direction: column; }
}

@media (max-width: 575px) {
  .fn-board { grid-template-columns: 1fr; }
  .fn-card { padding: 0.85rem; }
  .fn-card__head { gap: 0.5rem; }
  .fn-card__badges { max-width: 52%; }
  .fn-equipment-status { white-space: normal; text-align: right; }
  .fn-board-toolbar { padding: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .fn-card { transition: none; }
}

/* 영정 사진 미리보기 (D5). 세로로 긴 사진이 많아 폭이 아니라 높이를 잡는다. */
.fn-memorial {
  display: block;
  max-height: 16rem;
  max-width: 100%;
  margin: 0 auto 0.75rem;
  border: 1px solid var(--jsini-border);
  border-radius: 0.35rem;
  object-fit: contain;
}

/* 자료실 첨부 목록 안의 「빼기」 단추 자리. */
.fn-upload {
  margin-bottom: 0.75rem;
}

/* ── 플레이어 내려받기 ────────────────────────────────────

   OS 별 카드 일곱 장. 넓은 화면에서 셋, 좁으면 하나씩 선다.
   카드 영역만 안에서 구른다 — 쪽 전체가 구르면 조건줄이 밀려난다. */

.fn-pd {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
  overflow-y: auto;
  padding-right: 0.25rem;
}

@media (width >= 768px) {
  .fn-pd { grid-template-columns: repeat(2, 1fr); }
}

@media (width >= 1280px) {
  .fn-pd { grid-template-columns: repeat(3, 1fr); }
}

.fn-pd__card {
  display: flex;
  flex-direction: column;
  padding: 1rem;
  border: 1px solid var(--jsini-border);
  border-radius: 0.6rem;
  background: var(--jsini-surface);
}

.fn-pd__title { font-size: var(--jsini-fs-lg); font-weight: 600; }

.fn-pd__sub {
  margin-top: 0.15rem;
  font-size: var(--jsini-fs-xs);
  color: var(--jsini-text-muted);
}

.fn-pd__reqs {
  margin: 0.9rem 0 0;
  padding-left: 1.1rem;
  font-size: var(--jsini-fs-xs);
  color: var(--jsini-text-muted);
}

.fn-pd__reqs li { padding: 0.1rem 0; }

.fn-pd__steps {
  margin-top: 0.9rem;
  padding: 0.6rem;
  border-radius: 0.4rem;
  background: var(--jsini-theme-hover);
}

.fn-pd__steps-title {
  margin-bottom: 0.3rem;
  font-size: var(--jsini-fs-2xs);
  font-weight: 600;
  color: var(--jsini-text-muted);
}

/* 명령어가 길다. 줄바꿈을 막으면 카드가 가로로 늘어난다. */
.fn-pd__step {
  font-size: var(--jsini-fs-2xs);
  line-height: 1.6;
  word-break: break-all;
}

/* 카드 높이가 제각각이라 단추를 바닥에 붙인다 — 줄이 맞아야 눈이 쉬어 간다. */
.fn-pd__foot { margin-top: auto; padding-top: 1rem; }

.fn-pd__download {
  display: block;
  text-align: center;
  text-decoration: none;
}

.fn-pd__download--off { opacity: 0.55; cursor: default; }

.fn-pd__asset {
  margin-top: 0.4rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  font-size: var(--jsini-fs-2xs);
  color: var(--jsini-text-muted);
}

.fn-pd__note {
  flex-shrink: 0;
  padding-top: 0.9rem;
  font-size: var(--jsini-fs-xs);
  color: var(--jsini-text-muted);
}

.fn-pd__tag { display: inline-flex; align-items: center; gap: 0.5rem; }

.fn-pd__link { text-decoration: none; }

/* 자료 재생 창. 창 폭에 맞추고 높이는 내용이 정한다 —
   세로 영상까지 한 크기로 잡으면 위아래가 검게 남는다. */
.fn-preview__player {
  display: block;
  width: 100%;
  max-height: 60vh;
  margin-bottom: 0.5rem;
  background: #000;
}

/* ── 영정사진 ─────────────────────────────────────────────
   3:4 세로. 빈소 화면이 그 비율로 띄우므로 여기서도 같은 틀로 보여 준다 —
   가로 사진을 올렸다는 것을 저장 전에 알아채야 한다. */

.fn-portrait {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.fn-portrait__img,
.fn-portrait__none {
  flex-shrink: 0;
  width: 8rem;
  height: 10.6rem;
  border: 1px solid var(--jsini-border);
  border-radius: 0.35rem;
  object-fit: cover;
}

.fn-portrait__none {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--jsini-surface);
  font-size: var(--jsini-fs-xs);
  color: var(--jsini-text-muted);
}

.fn-portrait__tools {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.fn-portrait__pick {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.35rem 0.8rem;
  border: 1px dashed var(--jsini-border);
  border-radius: 0.35rem;
  background: var(--jsini-surface);
  font-size: var(--jsini-fs-sm);
  cursor: pointer;
}

.fn-portrait__pick input[type='file'] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

/* 서식 편집기(Q&A · F.A.Q). 높이를 주지 않으면 한 줄로 접혀 나온다. */
.fn-editor {
  height: 18rem;
}

/* 미리보기 카드의 곁들이는 줄. 장비명·코드·유형·최근 접속이 한 줄씩 흐른다. */
.fn-preview__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.5rem;
  padding: 0.3rem 0.5rem 0.5rem;
  font-size: var(--jsini-fs-2xs);
  color: var(--jsini-text-muted);
}

/* ── 환경설정: 넓으면 상자들을 단으로 흘린다 (`fn-env`) ────

   이 화면에 있는 것은 스위치 열몇 · 상태 넷 · 길잡이 몇 줄이다. 세로로
   쌓으면 어느 것도 길지 않은데 화면은 끝까지 구르고 오른쪽 절반이 통째로
   빈다.

   [칸을 손으로 지정하다가 단으로 흘리기로 바꿨다]

   한동안 격자에 칸 셋을 잡고 **어느 묶음이 몇째 칸인지를 손으로** 적었다
   (`grid-column: 3` 따위). 그런데 칸에 든 것들의 키가 제각각이라 —
   「그 밖」 한 상자가 나머지 둘을 합친 것보다 길었다 — 셋째 칸만 화면
   두 배로 늘어나고 **왼쪽 둘은 1000px 넘게 빈 채**로 남았다.

   격자는 그것을 스스로 고치지 못한다. 한 줄에 놓인 칸들은 줄의 키를
   나눠 쓰므로, 짧은 칸 아래에 다음 것을 끌어올릴 방법이 없기 때문이다
   (`masonry` 는 아직 못 쓴다).

   그래서 **여러 단(multi-column)으로 흘린다.** 브라우저가 상자들을 차례로
   놓으면서 단의 키를 스스로 맞춘다 — 우리가 적을 것은 「몇 단인가」뿐이고,
   묶음이 늘거나 줄어도 다시 나눌 일이 없다.

       ┌ 알림 ────────┬ 홈 화면 ─────┬ 이 브라우저 ──┐
       │ (스위치·위치) │ 화면         │ 등록된 기기   │
       │              │ 휴대폰        │ 하단 네비게이션│
       │              │              │ 찾으시는 것…  │
       └──────────────┴──────────────┴───────────────┘
       (칸이 아니라 단이라 경계는 그때그때 달라진다)

   [상자가 쪼개지지 않게 한다]

   단은 기본적으로 **글처럼 흘러서** 상자 하나가 두 단에 걸쳐 잘린다 —
   스위치 목록이 반으로 갈려 다음 단 위에서 이어지면 무엇이 한 묶음인지
   읽을 수 없다. `break-inside: avoid` 로 상자를 통째로 옮기게 한다.

   [묶음마다 테두리를 준다]

   단으로 흘리면 **경계가 사라진다.** 격자에서는 칸의 자리가 경계였는데,
   단에서는 위아래로 이어 놓으므로 어디까지가 한 묶음인지 제목 글자
   크기로만 가려야 한다. 그래서 상자마다 옅은 테두리와 판 색을 준다 —
   좁은 화면(휴대폰)에서는 예전 그대로 테두리 없이 쌓인다.

   [왜 컨테이너 질의가 아닌가]

   본문 폭으로 재는 것이 더 옳다(사이드바를 접으면 자리가 는다). 그런데
   `container-type` 은 `contain: layout` 을 함께 걸고, 그 순간 그 상자가
   **떠 있는 창(`position: fixed`)의 기준**이 된다 — 이 판 안에 확인 창
   (`ConfirmDialog`)이 들어 있어 그것이 화면 가운데가 아니라 상자 가운데로
   간다. 그래서 화면 폭으로 잰다.

   [폭은 「등록된 기기」 표가 정한다]

   단을 나누는 자리(1300 · 1900)는 스위치 줄이 아니라 **그 표**가 정했다.
   표는 칸 셋의 바닥이 410px 이고(기기 260 · 등록 90 · 빼기 60), 단이 그보다
   좁으면 표가 가로로 굴러 **맨 오른쪽 「빼기」가 밀려난다** — 기기를 지울
   길이 없어진다. 단 하나가 450px 을 넘는 자리가 둘로는 1300px, 셋으로는
   1900px 이다(사이드바 330px 을 뺀 값 기준).

   그보다 좁으면 단을 아예 걸지 않는다 — 예전 그대로 위에서 아래로 쌓인다.
   ---------------------------------------------------------- */

@media (min-width: 1300px) {
  .fn-env {
    columns: 2;
    column-gap: 1.25rem;

    /* 아주 넓은 화면에서 단 하나가 700px 을 넘으면 설명 한 줄이 너무 길어
       눈이 되돌아올 자리를 잃는다. 왼쪽에 붙여 둔다 — 본문 가운데로 모으면
       사이드바를 접고 폈을 때 글이 통째로 미끄러진다. */
    max-width: 1800px;
  }

  /* 단으로 흘릴 상자들. **알림 판의 덩어리 셋은 이름으로 적는다** —
     그 판은 상자가 없어서(`display: contents`) `.fn-env > *` 로는 안 걸린다. */
  .fn-env .fn-env__group,
  .fn-env .jsini-npanel__prefs,
  .fn-env .jsini-npanel__browser,
  .fn-env .jsini-npanel__devices {
    break-inside: avoid;
    margin: 0 0 1.25rem;
    padding: 0.1rem 1.1rem 0.9rem;
    border: 1px solid var(--jsini-border);
    border-radius: var(--jsini-radius-lg);
    background: var(--jsini-surface);
  }

  /* 상자 안의 첫 제목은 위 여백을 줄인다 — 그 여백(1.5rem)은 묶음과 묶음
     사이를 가르라고 있던 것이고, 이제 그 일은 테두리가 한다. */
  .fn-env .fn-env__group > .jsini-subhead:first-child,
  .fn-env .jsini-npanel__prefs > .jsini-subhead:first-child,
  .fn-env .jsini-npanel__browser > .jsini-subhead:first-child,
  .fn-env .jsini-npanel__devices > .jsini-subhead:first-child {
    margin-top: 0.9rem;
  }

  /* 마지막 줄의 밑줄을 걷는다. 테두리 바로 위에 선이 한 겹 더 깔려
     「끊긴 표」처럼 보인다. */
  .fn-env .jsini-settings:last-child { margin-bottom: 0; }
  .fn-env .jsini-settings > .jsini-setting:last-child { border-bottom: 0; }

  /* 설정 줄의 컨트롤(단추, 콤보박스 등)은 **줄을 내려 아래에 둔다.**

     `.jsini-setting` 은 왼쪽 설명 · 오른쪽 단추로 나란히 서는데, 단이
     400px 로 좁아지면 단추가 눌려 글자가 「업무 / 설정 / 으로」 세 줄로
     쪼개진다. 단추를 안 줄게 묶으면 이번에는 설명이 두 글자씩 끊긴다 —
     둘 다 폭이 모자란 것이지 정렬의 문제가 아니라서, 가로로 나누는 것을
     그만두는 쪽이 맞다.

     **스위치는 그대로 오른쪽에 둔다**(`.jsini-setting:has(.dxbl-checkbox)`) —
     켜짐·꺼짐은 줄 끝에 나란히 서 있어야 위아래로 훑어 읽힌다. */
  .fn-env .jsini-setting:not(:has(> .dxbl-checkbox)) {
    display: block;
  }

  .fn-env .jsini-setting:not(:has(> .dxbl-checkbox)) .dxbl-btn,
  .fn-env .jsini-setting:not(:has(> .dxbl-checkbox)) .dxbl-editor {
    margin-top: 0.5rem;
  }

  /* **아래 띠 고르기의 줄만은 여기서 다시 감는다.**

     저 판은 `nowrap` 이다(아래 `fn-bnav__row` 머리말) — 휴대폰에서 줄이
     둘로 갈리지 않게. 그런데 **단으로 갈린 여기가 휴대폰보다 좁을 수
     있다**: 1200px 에서 한 단이 400px 남짓이다. 그대로 한 줄에 붙이면
     메뉴 고르개가 눌려 무엇을 골랐는지 한 글자도 안 남는다. */
  .fn-env .fn-bnav__row {
    flex-wrap: wrap;
  }

  /* 홈 화면 고르개는 줄을 내린 뒤 **단을 통째로 쓴다.** 이 목록의 이름은
     줄기까지 붙어서(「포털관리 › 알림 이력 조회」) 자리가 남는데도 잘리면
     무엇을 골랐는지 못 읽는다. */
  .fn-env .fn-home { width: 100%; }
}

@media (min-width: 1900px) {
  .fn-env { columns: 3; }
}

/* ── 환경설정: 휴대폰에서는 기기 표가 제 키로 선다 ─────────

   `CommGrd` 는 표를 58vh 에 묶는다(app.css 의 `--commgrd-max-height`). 업무
   화면에서는 그것이 맞다 — 조회 줄은 위에, 아래 띠는 아래에 붙박고 구르는
   것은 자료뿐이어야 한다.

   **그런데 이 화면은 그런 화면이 아니다.** `CommCont` 도 조회 줄도 없고,
   스위치와 안내 글이 위아래로 이어지는 그냥 구르는 쪽이다. 휴대폰에서는
   표가 카드로 펴져 줄 하나가 174px 이라 기기 다섯이면 870px 인데, 표는
   489px 에 묶여(844px 의 58%) **구르는 쪽 안에 또 구르는 칸**이 생긴다 —
   손가락이 그 위에 닿으면 쪽이 아니라 표가 구른다. 기기 목록 안에서
   끝까지 내려가야 비로소 쪽이 움직이고, 정작 쪽이 구를 몫은 77px 뿐이었다
   (390×844 에서 재었다).

   휴대폰에서는 상한을 푼다. 표는 제 키로 서고 구르는 것은 쪽 하나다.
   넓은 화면은 그대로 둔다 — 거기서는 표가 단 하나를 차지하고 있어 58vh 로
   묶어 두는 편이 낫다.
   ---------------------------------------------------------- */

@media (max-width: 767px) {
  .fn-env .commgrd {
    --commgrd-max-height: none;
  }
}

/* ── 환경설정: 홈 화면 고르개 (`fn-home`) ───────────────────

   좁은 화면에서는 설정 줄이 「왼쪽 설명 · 오른쪽 조작」으로 나란히 선다
   (app.css 의 `.jsini-setting`). 이 고르개에 폭을 안 주면 목록 이름이 길어
   (「포털관리 › 알림 이력 조회」) 왼쪽 설명을 밀어낸다.

   **줄일 몫을 이쪽에 둔다**(`flex: 0 1`) — 좁아지면 고르개가 먼저 준다.
   설명이 「고르지 않으면 환경설정이 열립니다」를 말하는 자리라 그것이 먼저
   끊기면 안 된다. `min-width` 로 바닥을 받쳐 글자가 아예 안 남는 것은 막는다
   (아래 `fn-bnav__name` 과 같은 수법).
   ---------------------------------------------------------- */

.fn-home {
  flex: 0 1 14rem;
  min-width: 8rem;
}

/* ── 환경설정: 휴대폰 아래 띠 고르기 (`fn-bnav`) ────────────

   줄 하나가 「아이콘 · 메뉴 · 이름 · 꺾쇠 둘 · 빼기」 여섯이다. 이 판이
   앉는 자리는 환경설정의 셋째 칸(넓은 화면에서 320px 남짓)이고 휴대폰에서는
   화면 폭 그대로라, 여섯을 놓을 자리가 넉넉한 적이 없다.

   [감싸지 않는다 — 줄을 **한 줄로 붙여 둔다**]

   한동안 감쌌다(`flex-wrap: wrap`). 그런데 감싸는 상자는 **넘치면 먼저
   줄을 내리고, 내린 뒤에야 줄인다** — 폭이 모자라도 고르개와 이름 칸은
   제 바탕 폭(11rem · 7rem)을 그대로 쥔 채 뒷것들을 아래로 떨어뜨린다.
   그래서 차례 바꾸기 꺾쇠 둘이 들어오자 휴대폰에서 줄이 통째로 하나 더
   생겼다(360px 에서 이름·꺾쇠 둘·빼기가 둘째 줄로 내려갔다). 칸 다섯이면
   판만 열 줄이다.

   `nowrap` 으로 두면 반대가 된다 — 줄을 못 내리니 **글상자가 줄어든다.**
   좁아져도 여섯이 한 줄에 남고, 좁힐 몫은 아래에서 나눈다.

   아이콘은 늘 맨 앞이다 — 고른 메뉴가 무슨 그림으로 띠에 설지를 그 자리에서
   보여 주는 것이 이 줄의 첫째 일이다.
   ---------------------------------------------------------- */

.fn-bnav {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

/* 「쓰지 않기」로 둔 동안. 조작은 부품마다 `Enabled` 로 이미 잠갔고,
   여기서 하는 일은 **잠겼다는 것을 보이게** 하는 것뿐이다 — 잠긴 판이
   멀쩡한 낯으로 있으면 사람은 눌러 보고 나서야 안다. */
.fn-bnav--off {
  opacity: 0.55;
}

.fn-bnav__row {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.4rem;
}

/* 아이콘 집안이 둘이라 크기를 양쪽 다 맞춰 둔다(app.css 의 띠 규칙과 같다). */
.fn-bnav__icon {
  --jsini-icon-size: 18px;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--jsini-text-muted);
}

/* 메뉴 고르개가 남는 폭을 다 먹는다. `min-width` 를 0 으로 안 두면
   flex 항목의 기본 최소 폭(내용 폭)이 버텨서 줄이 안 감긴다. */
.fn-bnav__menu {
  flex: 1 1 11rem;
  min-width: 0;
}

/* **좁아지면 이 칸이 먼저 준다**(줄임 몫 셋 대 하나). 여기 적는 이름은
   띠의 72px 칸에 들어갈 서너 글자라 반으로 줄어도 읽히지만, 메뉴 고르개는
   179건 중에 무엇을 골랐는지를 보여 주는 칸이라 같이 줄이면 둘 다 못 읽는다.

   `min-width` 로 바닥을 받쳐 둔다 — 여기가 없으면 320px 에서 이 칸이 20px
   까지 눌려 글자가 한 자도 안 남는다(대신 고르개가 그만큼 가져간다). */
.fn-bnav__name {
  flex: 0 3 7rem;
  min-width: 3.25rem;
}

.fn-bnav__drop {
  flex: 0 0 auto;
}

/* 순서 바꾸기 단추 둘 — 글자 없이 꺾쇠만 쓴다(줄이 이미 넷이다).

   **그림은 하나뿐이다.** 위를 보는 꺾쇠를 따로 두지 않고 뒤집어 쓴다 —
   둘을 따로 두면 각도가 갈린다(app.css 의 `jsini-icon-chevron-down` 머리말이
   접는 판에서 같은 말을 한다). */
.fn-bnav__move {
  flex: 0 0 auto;
}

.fn-bnav__move--up .jsini-icon-chevron-down {
  transform: rotate(180deg);
}

.fn-bnav__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.25rem;
}

/* 「5 / 3~8칸」 — 단추 둘 뒤에 붙는다. **오른쪽 끝으로 민다**(`margin-left:
   auto`): 단추 옆에 바싹 붙여 두면 「기본값으로」의 꼬리처럼 읽힌다. 줄이
   감기면(좁은 자리) 제 줄로 내려가 왼쪽에 선다 — 그때는 밀 자리가 없다. */
.fn-bnav__count {
  margin: 0;
  flex: 0 0 auto;
  margin-left: auto;
}

/* 「바로 넣기」 줄 — 메뉴가 아닌 넷(홈 · 설정 · 메뉴 단추 · 프로필 아바타).

   고르개는 메뉴 179건이 들어 있는 목록이라 **메뉴가 아닌 것은 줄기 이름으로
   찾을 수 없다.** 단추로 내놓아 한 번에 넣게 한다. 줄이 넘치면 감긴다 —
   이 판이 앉는 자리가 좁고(환경설정 셋째 칸) 단추가 넷이다. */
.fn-bnav__quick {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.4rem;
}

/* 「바로 넣기」 라는 말은 단추들의 라벨이라 위아래 여백을 뗀다 —
   `jsini-hint` 는 문단에 붙는 값을 들고 있다. */
.fn-bnav__quick > .jsini-hint {
  margin: 0;
  flex: 0 0 auto;
}
