:root {
  color-scheme: light;

  /* 라이트는 파생이다. 다크(theme.css)를 정본으로 먼저 확정하고 역할을 보존한 채 명도만 뒤집는다.
     짝 규칙: --color-X 는 언제나 "읽히는 글자색", --color-X-soft 는 언제나 "그 뒤에 깔리는 면"이다.
     테마가 바뀌어도 역할이 고정되므로 대비가 자동으로 유지된다. */
  --color-canvas: #eceff4;
  --color-surface: #fbfcfd;
  --color-surface-soft: #f2f5f8;
  --color-surface-raised: #ffffff;
  --color-ink: #16191f;
  --color-ink-strong: #0a0c0f;
  --color-muted: #59616e;
  --color-muted-strong: #3b424d;
  --color-line: #e0e4ea;
  --color-line-strong: #c4cbd4;
  --color-brand: #0f766e;
  --color-brand-strong: #0b544e;
  --color-brand-soft: #d5f5f0;
  --color-info: #1d4ed8;
  --color-info-soft: #dbeafe;
  --color-success: #0f7a4d;
  --color-success-soft: #dcfce7;
  --color-warning: #92620a;
  --color-warning-soft: #fef3c7;
  --color-danger: #b3261e;
  --color-danger-soft: #fee2e2;
  /* 엔진 리포트(교육과정 진단)는 앱 명암과 무관하게 자체 다크 Bloom "문서" 팔레트를 쓴다 —
     정본 샘플과 같은 두톤(어두운 컨테이너 · 따뜻한 카드). [data-report-model]에서만 참조한다. */
  --report-canvas: #0a0d12;
  --report-card: #12161d;
  --report-card-soft: #161b23;
  --report-line: #232c39;
  --report-line-strong: #2a3546;
  --report-border: #1c2431;
  --report-shadow: 0 1px 2px rgba(0, 0, 0, .28), 0 8px 26px rgba(0, 0, 0, .3);
  --color-sidebar: #0f1115;
  --color-sidebar-ink: #f4f7fb;
  --color-sidebar-muted: #9aa0ab;
  --color-sidebar-line: rgba(255, 255, 255, 0.12);
  --color-focus: #0f766e;
  --color-shadow: rgba(10, 12, 15, 0.10);
  /* 한국고등직업교육학회(KOHVEA) 표지의 세 색 — 기관 정체성이라 명암과 무관하게 고정한다(작업 표지에서만 쓴다). */
  --kohvea-blue: #0071bc;
  --kohvea-gold: #bb9542;
  --kohvea-teal: #00a79d;

  --font-body: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
  /* 00은 칩·각주 전용, 7은 입장 티켓 표제 전용 — 그 사이 단계를 새로 만들지 않는다 */
  --font-size-00: 11px;
  --font-size-0: 12px;
  --font-size-1: 13px;
  --font-size-2: 14px;
  --font-size-3: 16px;
  /* 0~3은 본문 대역이라 값을 유지한다. 4~6은 보고서 표제용으로 넓히고 최상단만 유동으로 둔다. */
  --font-size-4: 19px;
  --font-size-5: 24px;
  --font-size-6: clamp(30px, 3.2vw, 42px);
  --font-size-7: 44px;

  --weight-normal: 400;
  --weight-medium: 600;
  --weight-bold: 700;
  --weight-heavy: 800;
  /* 한글은 큰 글씨에서 자간이 벌어져 보인다. 표제일수록 좁히고, 짧은 라벨은 벌린다. */
  --tracking-display: -0.025em;
  --tracking-tight: -0.01em;
  --tracking-normal: 0;
  --tracking-wide: 0.04em;
  /* small uppercase labels and stamps read spaced */
  --tracking-label: 0.18em;

  /* 세로 리듬 — 간격을 임의 px로 두지 않고 표제 위계에 묶는다. 이 세 값만 고치면 전 문서의 숨쉬기가 바뀐다. */
  --rhythm-tight: var(--space-3);
  --rhythm-block: var(--space-6);
  --rhythm-section: var(--space-8);

  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 100;
  --z-overlay: 500;
  --z-modal: 1000;
  --z-toast: 2000;

  --motion-fast: 120ms;
  --motion-normal: 200ms;
  --motion-slow: 320ms;
  /* a marker gliding to its place, and a bar or spine filling to its length */
  --motion-glide: 450ms;
  /* the gap between letters when a short line enters one letter at a time */
  --motion-stagger: 35ms;
  --motion-progress: 500ms;
  --motion-ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --opacity-disabled: .42;
  --line-none: 1;
  --line-tight: 1.2;
  --line-normal: 1.45;
  --line-body: 1.55;
  --line-reading: 1.72;
  /* report.css가 --line-height-body를 참조하는데 정의가 없어 본문 행간이 상속으로 떨어지고 있었다.
     이름을 지우지 않고 정본 토큰의 별칭으로 잇는다. */
  --line-height-body: var(--line-body);
  --text-measure: 72ch;

  /* 간격은 이 열한 단계뿐이다. 하드코딩된 px는 check-app-design-tokens가 막는다. */
  --space-0-5: 2px;
  --space-1: 4px;
  --space-1-5: 6px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 30px;
  --space-8: 40px;
  --space-9: 48px;

  --radius-1: 4px;
  --radius-2: 6px;
  --radius-3: 8px;
  --radius-4: 14px;
  --radius-5: 24px;
  --radius-pill: 999px;
  /* 선 두께 — 1px 머리카락선 위로는 이 두 단계, 포커스 고리는 따로 */
  --border-strong: 2px;
  --border-accent: 3px;
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;
  /* 그림자 — 높이 네 단계. 숫자로 그림자를 그리지 않는다 */
  --shadow-hairline: 0 1px 2px var(--color-shadow);
  --shadow-card: 0 8px 30px var(--color-shadow);
  --shadow-panel: 0 12px 40px var(--color-shadow);
  --shadow-float: 0 18px 48px var(--color-shadow);
  /* 입력 오류·포커스 같은 테두리 바깥 후광의 두께 */
  --halo-width: 3px;
  --control-height: 42px;
  /* the smallest thing a finger presses (Apple HIG 44pt) */
  --touch-target: 44px;
  /* THE APP IS A PAGE ON THE WEB NOW (2026-10-10): on a wide screen the shell stops growing and sits in the
     middle; the content column no longer stretches to a 1920px window */
  --shell-max: 1440px;
  --sidebar-width: 280px;
  /* 데스크톱 앱은 창을 채운다. 1280 상한이 남아 있으면 1920 창에서 가운데 정렬을 해도
     좌 296 / 우 608로 어긋난다 — 상한이 오른쪽에만 남기 때문이다. */
  --content-max: none;
  --panel-narrow: 720px;
  /* 읽기 폭은 카드가 아니라 필드가 지킨다: 이 폭 아래로는 열을 더 늘리지 않는다.
     280px인 이유는 1280×720에서 입구 화면이 스크롤 없이 들어가야 하기 때문이다 — 입력 항목이
     정해진 화면인데 첫 진입부터 스크롤을 시키면 안 된다. 877px 본문에서 3열이 되어 다섯 칸이
     두 줄에 들어가고, 한 줄(70px + 간격 16px)이 사라진다. */
  --field-measure: 264px;
  /* 입장 대화상자의 폭. 설계 기준 해상도는 1280x720이다 — 1366x768 노트북이 아직 흔해서 1920을
     기준으로 잡으면 그 화면에서 잘린다. 그 기준에서 880px이 창을 알맞게 채운다.
     다만 고정하면 1920 창에서 카드만 작게 남아 미아처럼 보이므로, 기준 위로는 창을 따라 커지되
     1200px에서 멈춘다 — 그 이상은 입력칸이 흩어지기만 한다. */
  --entry-width: clamp(880px, 64vw, 1200px);

  /* 모달 — 안내와 오류는 배너가 아니라 이 한 벌의 규격으로만 뜬다.
     폭·여백·반경·배경가림을 여기서 정하면 모든 안내창이 같은 몸을 쓴다. */
  --modal-width: 30rem;
  --modal-width-wide: 38rem;
  --modal-pad: var(--space-6);
  --modal-gap: var(--space-4);
  --modal-radius: var(--radius-3);
  --modal-backdrop: rgba(0, 0, 0, 0.6);

  /* 사이드바 리듬 — 섹션 사이·섹션 안·행동 앞 간격을 한 곳에서 정한다.
     이 세 값만 바꾸면 사이드바 전체의 숨쉬기가 바뀐다. */
  --sidebar-section-gap: var(--space-8);
  --sidebar-block-gap: var(--space-5);
  --sidebar-action-gap: var(--space-6);
  --sidebar-pad: var(--space-7);
}

[hidden] {
  display: none !important;
}

/* no orphan word alone on a paragraph's last line */
p, dd, li { text-wrap: pretty; }

/* THE ONE NOTICE BODY (2026-10-10): every dialog - a notice, a question, the AI key, the data notice - is a
   raised card that rises into place over a blurred page, with a head (eyebrow, title, lead), a body, and a
   footer bar that runs edge to edge so the actions always sit the same distance below the content. */
.modal {
  width: min(calc(100% - 2 * var(--space-4)), var(--modal-width));
  max-height: calc(100dvh - 2 * var(--space-8));
  overflow: auto;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-4);
  background: var(--color-surface-raised);
  color: var(--color-ink);
  box-shadow: var(--shadow-float);
  padding: var(--modal-pad) var(--modal-pad) 0;
}
.modal[open] { animation: modal-rise var(--motion-slow) var(--motion-ease) both; }
.modal::backdrop {
  background: var(--modal-backdrop);
  -webkit-backdrop-filter: blur(var(--space-1));
  backdrop-filter: blur(var(--space-1));
}
@keyframes modal-rise { from { opacity: 0; transform: translateY(var(--space-3)) scale(.98); } }
@media (prefers-reduced-motion: reduce) { .modal[open] { animation: none; } }

.modal-eyebrow {
  margin: 0 0 var(--space-1-5);
  color: var(--color-brand-strong);
  font-size: var(--font-size-00);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-label);
}
.modal h2 {
  margin-block: 0 var(--space-2);
  font-size: var(--font-size-5);
  font-weight: var(--weight-heavy);
  letter-spacing: var(--tracking-tight);
  line-height: var(--line-tight);
  text-wrap: balance;
}
.modal p {
  margin: 0 0 var(--modal-gap);
  color: var(--color-muted-strong);
  line-height: var(--line-body);
  /* a body may list several lines (one file per line) */
  white-space: pre-line;
}
.modal-actions {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  margin: var(--space-6) calc(-1 * var(--modal-pad)) 0;
  padding: var(--space-4) var(--modal-pad);
  border-top: 1px solid var(--color-line);
  background: var(--color-surface-soft);
}
.modal-actions > :first-child:not(button) { margin-right: auto; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* 주 실행 버튼과 부수 선택을 한 줄에 둔다. 동의는 사이드바에 상주하지 않고
   해당 화면의 행동 옆에서만 보인다. */
.action-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.consent-inline {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-muted);
  font-size: var(--font-size-1);
  line-height: var(--line-normal);
  cursor: pointer;
}

.consent-inline input {
  flex: none;
  margin: 0;
}


/* P06-T12는 교수가 자기 신호가 실제로 갔는지 확인할 수 있어야 한다고 요구한다.
   기능은 남기되 outbox·ACK·dead-letter 같은 운영자 용어는 쓰지 않는다. */

* {
  box-sizing: border-box;
}

html {
  min-width: 320px;
  background: var(--color-canvas);
}

body {
  margin: 0;
  min-height: 100vh;
  /* KOREAN BREAKS BETWEEN WORDS, NOT INSIDE THEM (2026-10-10): "다섯 / 가지로" split a word across lines;
     keep-all breaks only at spaces, and a token longer than the line (an address, a file name) still wraps */
  word-break: keep-all;
  overflow-wrap: break-word;
  overflow-x: hidden;
  background: var(--color-canvas);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--font-size-3);
  line-height: var(--line-body);
  letter-spacing: 0;
  word-break: keep-all;
  overflow-wrap: break-word;
}

button,
input,
select,
textarea {
  font: inherit;
  letter-spacing: 0;
}

button {
  cursor: pointer;
}

/* A LOCKED CONTROL LOOKS LOCKED (2026-10-10): it kept full colour and still answered the mouse while a run worked */
button:disabled, input:disabled, select:disabled, textarea:disabled {
  opacity: var(--opacity-disabled);
  pointer-events: none;
}

:focus-visible {
  outline: var(--border-accent) solid var(--color-focus);
  outline-offset: var(--focus-ring-offset);
}

.skip-link {
  position: absolute;
  left: var(--space-3);
  top: calc(-1 * var(--space-9));
  z-index: var(--z-toast);
  border-radius: var(--radius-2);
  background: var(--color-ink-strong);
  color: var(--color-surface);
  padding: var(--space-2) var(--space-3);
}

.skip-link:focus {
  top: var(--space-3);
}

/* overflow-x:hidden을 여기 두면 셸이 스크롤 컨테이너가 되어 사이드바 sticky가 죽는다.
   가로 넘침 차단은 body와 html의 min-width가 담당한다. */
.app-shell {
  display: grid;
  grid-template-columns: minmax(240px, var(--sidebar-width)) minmax(0, 1fr);
  gap: var(--space-4);
  min-height: 100vh;
  min-height: 100dvh;
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding: var(--space-4);
}
/* the narrow-screen bar and the drawer's scrim exist only below the tablet's portrait width (responsive.css) */
.mobile-bar, .drawer-scrim { display: none; }

/* 사이드바는 창을 채운다. 예전엔 동의 설명 7줄이 안에 있어 "내용 높이로 두라"가 맞았지만, 지금은
   브랜드와 3단계뿐이라 353px에서 끝나고 그 아래로 399px이 비어 본문 카드와 끝나는 선이 달랐다.
   내용은 위에 쌓이고 남는 높이는 판이 가진다 — 데스크톱 앱의 두 기둥은 같은 선에서 끝난다.
   sticky는 유지한다: 분석 보드처럼 오른쪽이 길어져 스크롤할 때 메뉴가 따라 올라가면 안 된다. */
.sidebar {
  position: sticky;
  top: var(--space-4);
  align-self: stretch;
  max-height: calc(100vh - var(--space-4) * 2);
  max-height: calc(100dvh - var(--space-4) * 2);
  display: flex;
  flex-direction: column;
  gap: var(--sidebar-section-gap);
  border: 1px solid var(--color-sidebar-line);
  border-radius: var(--radius-3);
  background: var(--color-sidebar);
  color: var(--color-surface-soft);
  box-shadow: var(--shadow-panel);
  padding: var(--sidebar-pad);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.brand-mark {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border-radius: var(--radius-3);
  background: transparent;
  color: var(--color-brand-strong);
  font-weight: var(--weight-heavy);
  overflow: hidden;
}

/* 로고는 흰 배경을 가진 불투명 PNG다. 로고가 자기 판을 들고 있으므로 판을 겹치지 않고
   border-radius + overflow:hidden 으로 모서리만 다듬는다. */
.brand-mark img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.brand span {
  display: block;
  color: var(--color-sidebar-muted);
  font-size: var(--font-size-1);
}

.brand strong {
  color: var(--color-sidebar-ink);
}

.step-nav {
  display: grid;
  gap: var(--space-3);
}

.step {
  display: flex;
  width: 100%;
  min-height: var(--control-height);
  align-items: center;
  gap: var(--space-3);
  border: 1px solid var(--color-sidebar-line);
  border-radius: var(--radius-3);
  background: transparent;
  color: var(--color-surface-soft);
  padding: var(--space-2) var(--space-3);
  text-align: left;
}

/* 번호와 라벨은 역할이 다른데 한 셀렉터가 둘 다 12px(--font-size-0, 스케일 최소값)로 묶고 있었다.
   그건 캡션용 크기지 주 내비게이션 크기가 아니다 — 화면에서 이 세 항목만 유독 작게 보이던 이유다.
   번호는 자리를 지키는 배지라 작아도 되지만 라벨은 읽는 글자이므로 본문 크기를 준다. */
.step span {
  color: var(--color-sidebar-muted);
}

.step > span:first-child {
  min-width: 22px;
  font-size: var(--font-size-1);
  font-weight: var(--weight-heavy);
  font-variant-numeric: tabular-nums;
}

.step > span:last-child {
  font-size: var(--font-size-3);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
}

.step.is-active {
  border-color: var(--color-brand-soft);
  background: var(--color-brand-soft);
  color: var(--color-ink-strong);
}

/* active step has a LIGHT background, so its number badge + label spans (muted light on
   the dark sidebar) must flip to dark ink — otherwise the active label is unreadable. */
.step.is-active span {
  color: var(--color-ink-strong);
}

/* 셸이 이미 바깥 여백을 주므로 작업영역은 세로 여백을 줄여 화면 안에 들어오게 한다. */
/* 행은 내용 높이로 쌓는다. 기본값(stretch)이면 app-shell의 min-height:100vh가 이 그리드까지
   내려와 행들이 화면 높이만큼 늘어난다 — 접속 인증 화면에서 제목 줄(내용 75px)이 276px을 차지하고
   카드가 화면 한참 아래에서 시작해, PC 창에서 위아래가 텅 빈 채 균형이 무너져 보였다.
   내용보다 긴 화면은 그대로 스크롤되므로 잃는 것은 없다. */
.workspace {
  display: grid;
  align-content: start;
  width: 100%;
  max-width: var(--content-max);
  min-width: 0;
  gap: var(--space-4);
  /* 세로 여백은 셸이 이미 준다. 여기서 20px을 더 넣으면 사이드바는 창에서 16px, 본문 카드는 36px
     떨어져 두 기둥의 끝선이 어긋난다 — 창 전체가 하나의 테두리를 갖도록 세로는 셸에 맡긴다. */
  /* THE CONTENT SITS IN THE MIDDLE OF ITS COLUMN (2026-10-10): the sidebar gap was 46px and the window
     edge 16px, so every screen leaned right. The shell gives 16px on both sides of the content (its gap on
     the left, its padding on the right); the same step on each side here makes both 24px. */
  padding-inline: var(--space-2);
}

.topbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
}

.eyebrow {
  margin: 0 0 var(--space-1);
  color: var(--color-brand);
  font-size: var(--font-size-1);
  font-weight: var(--weight-heavy);
}

/* 활자 위계 — 크기·행간·자간·굵기를 한 곳에서 정한다.
   이전에는 h1만 크기가 있고 h2~h4는 브라우저 기본값(부모 상대 em)으로 떨어져
   같은 h2가 위치마다 다른 크기로 나왔다. 그래서 위계가 읽히지 않았다.
   한글은 큰 글씨에서 자간이 벌어져 보이므로 표제일수록 자간을 좁힌다. */
h1,
h2,
h3,
h4 {
  margin: 0;
  color: var(--color-ink-strong);
  line-height: var(--line-tight);
  text-wrap: balance;
  word-break: keep-all;
}

h1 {
  font-size: var(--font-size-6);
  font-weight: var(--weight-heavy);
  letter-spacing: var(--tracking-display);
}

h2 {
  font-size: var(--font-size-5);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
}

h3 {
  font-size: var(--font-size-4);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--line-normal);
}

h4 {
  font-size: var(--font-size-3);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-normal);
  line-height: var(--line-normal);
}

/* 세로 리듬 — 표제 앞 여백은 크게, 뒤는 작게. 표제가 다음 본문에 붙어 보이게 한다. */
h2 { margin-block-start: var(--rhythm-section); }
h3 { margin-block-start: var(--rhythm-block); }
h2 + *, h3 + *, h4 + * { margin-block-start: var(--rhythm-tight); }

p,
li,
figcaption {
  text-wrap: pretty;
  word-break: keep-all;
}

/* 라벨·배지처럼 짧은 대문자성 텍스트는 자간을 벌려야 읽힌다. */
.eyebrow,
.status-badge,
.trace {
  letter-spacing: var(--tracking-wide);
}


/* 파일 선택 버튼은 브라우저 기본 모양이 새어 나오던 자리다. 모든 파일 입력을 ghost-action과 같은 토큰에 묶는다. */
input[type="file"] { font-family: inherit; color: var(--color-muted); }
input[type="file"]::file-selector-button {
  margin-right: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-2);
  background: var(--color-surface);
  color: var(--color-brand-strong);
  font-family: inherit;
  font-size: var(--font-size-1);
  font-weight: var(--weight-bold);
  cursor: pointer;
  transition: border-color var(--motion-fast) var(--motion-ease), background var(--motion-fast) var(--motion-ease);
}
input[type="file"]::file-selector-button:hover { border-color: var(--color-brand); background: var(--color-brand-soft); }
input[type="file"]:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }

.theme-pill { display: inline-flex; padding: var(--space-0-5); border: 1px solid var(--color-line-strong); border-radius: var(--radius-pill); background: var(--color-surface); cursor: pointer; font: inherit; }
.theme-pill-option { padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); font-size: var(--font-size-0); font-weight: var(--weight-bold); color: var(--color-muted); white-space: nowrap; transition: background var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease); }
.theme-pill-option.is-active { background: var(--color-brand); color: var(--color-surface); }
.theme-pill:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }

.status-strip,
.status-controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}



@keyframes status-badge-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.72); }
}
.trace {
  color: var(--color-muted);
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
}

/* the line under a screen title keeps the body size; its ink meets WCAG AA 4.5:1 in both themes (it was the lighter
   muted grey) and it wraps balanced instead of leaving one word on a line */
.screen-note {
  margin: var(--space-2) 0 0;
  color: var(--color-muted-strong);
  text-wrap: balance;
}

.view {
  display: none;
  min-width: 0;
}

.view.is-active {
  display: block;
}


/* 카드는 제 내용만큼만 높다. 창 높이까지 늘려봤더니 안이 642px 비어 — 빈 상자를 키운 것일 뿐이고,
   내용을 위로 모으든 벌리든 둘 다 나빴다. 창을 채우는 것은 사이드바(항상 있는 뼈대)의 몫이고,
   본문 카드는 담긴 것만큼만 차지한다. 카드 아래 남는 어두운 면은 빈칸이 아니라 창 바탕이다. */




.view-grid,
.control-grid,
.result-grid {
  display: grid;
  min-width: 0;
  gap: var(--space-5);
}

.view-grid {
  grid-template-columns: minmax(0, 1fr) minmax(300px, 420px);
}

.panel {
  min-width: 0;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-3);
  background: var(--color-surface);
  box-shadow: var(--shadow-panel);
  padding: var(--space-5);
}



/* 최초 입장 화면에서는 사이드바를 뺀다. 아직 인증 전이라 3단계 메뉴는 눌리지도 않는 상태이고
   (2·3단계는 disabled), 브랜드는 상단 제목이 이미 말한다 — 들어가기 전에는 고를 것이 없으니
   창 전체를 입력에 쓴다. 인증이 끝나 작업공간으로 넘어가면 사이드바가 돌아온다. */
.app-shell:has(#authView.view.is-active) {
  grid-template-columns: minmax(0, 1fr);
}

.app-shell:has(#authView.view.is-active) > .sidebar {
  display: none;
}

/* 사이드바가 없는 입장 화면은 앱 셸이 아니라 하나의 대화상자다 — 제목과 카드를 한 덩어리로 묶어
   창 가운데에 놓는다. 왼쪽 기준은 사이드바가 있을 때의 규칙이고, 기둥이 하나뿐이면 기준 삼을
   왼쪽이 없다. 내용보다 창이 짧아지면 safe가 가운데 정렬을 포기하고 위에서 시작한다. */
.app-shell:has(#authView.view.is-active) .workspace {
  padding-inline: 0;
  width: min(100%, var(--entry-width));
  margin-inline: auto;
  align-content: safe center;
}

/* 제목은 카드 가운데, 밝기 전환·상태는 카드 오른쪽 끝 — 둘을 한 줄 가운데에 붙여 두면 제목이 왼쪽으로 밀려 보였다 */
.app-shell:has(#authView.view.is-active) .topbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: end;
  text-align: center;
}
.app-shell:has(#authView.view.is-active) .topbar > :first-child { grid-column: 2; grid-row: 1; }
/* the admin crossing sits LEFT of the title, the theme and status RIGHT - kept in the right column
   together they outgrew it and ran over the title (2026-10-06, admin session) */
.app-shell:has(#authView.view.is-active) .topbar > .status-strip { display: contents; }
.app-shell:has(#authView.view.is-active) .status-controls { grid-column: 3; grid-row: 1; justify-self: end; flex-wrap: wrap; justify-content: flex-end; min-width: 0; }

/* 다섯 칸을 3열에 넣으면 둘째 줄 셋째 칸이 빈다. 마지막 칸을 늘려 메워봤더니 그 칸만 두 배로 넓어져
   더 어긋나 보였다 — 빈 칸 하나보다 크기가 제각각인 칸이 나쁘다. 모든 칸은 같은 폭을 쓴다. */

