/* 색은 전부 light-dark(밝을 때, 어두울 때) 한 줄로 둔다. 어느 쪽을 쓸지는 :root 의
   color-scheme 이 정한다 -- 기본은 브라우저(시스템) 설정을 따르고, 테마 단추로 라이트·다크를
   고르면 serve.py 가 <html data-theme> 를 심어 그 하나로 고정한다 (아래 :root[data-theme]).
   light-dark() 는 색 자리에만 쓴다. 밝기에 따라 길이·filter·opacity 처럼 색 아닌 값이
   달라져야 하면 그 칸만 @media (prefers-color-scheme: dark) { :root:not([data-theme=light]) … }
   와 :root[data-theme=dark] … 두 벌로 둔다. */
/* ---- 글꼴 (static/vendor/fonts, 출처·라이선스는 그 폴더의 README) ----
   라틴 글자는 Fira Sans / Fira Mono (beamer Metropolis 테마의 글꼴), 한글은 Pretendard.
   body 의 글꼴 차례가 "Fira Sans", "Pretendard Variable" 이라 글자마다 알아서 갈린다 --
   Fira 의 unicode-range 에 한글이 없으므로 한글은 Pretendard 로 넘어간다.
   사이트가 직접 내보내므로 내부망에서도, 운영체제가 달라도 같은 글꼴로 보인다.
   Fira 는 400·500·600(+400 기울임)만 둔다. 700 을 달라는 규칙은 600 으로 그려진다. */
@font-face {
  font-family: "Pretendard Variable";
  font-style: normal;
  font-weight: 45 920;
  font-display: swap;
  src: url("vendor/fonts/PretendardVariable-1.3.9.woff2") format("woff2-variations");
}

@font-face {
  font-family: "Fira Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/FiraMono-v16-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fira Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/FiraMono-v16-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fira Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("vendor/fonts/FiraMono-v16-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fira Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("vendor/fonts/FiraMono-v16-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fira Sans";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-400i-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fira Sans";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-400i-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fira Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fira Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fira Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fira Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fira Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fira Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("vendor/fonts/FiraSans-v18-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* 팔레트는 beamer Metropolis 에서 왔다: 짙은 청록(mDarkTeal #23373b)이 구조, 주황
     (mLightBrown #eb811b)이 표시. 라이트의 회색은 청록 쪽으로 기울였다. 다크의 바탕은 거의 무채색인
     먹색이다 -- 청록을 깔면 화면 전체가 초록으로 뜨고, 하이라이트·링크의 청록이 바탕에 묻힌다.
     세 갈래로 나눠 쓴다 --
       --ink     채운 것: 기본 단추, 켜진 탭·칩·세그먼트, 알약. 한 화면에 몇 개 안 둔다.
       --accent  글자·선·옅은 바탕: 링크, 포커스 테두리, 마우스 올림, 고른 줄, 막대 그래프.
       --mark    "지금·여기" 표시: 메뉴의 지금 칸 밑줄, 화면 제목 밑 선, 다가온 마감.
                 주황은 흰 바탕에서 2.6:1 이라 선과 점에만 쓰고, 글자는 --mark-text 로. */
  --bg: light-dark(#fafafa, #141618);
  --surface: light-dark(#ffffff, #1b1e21);
  --border: light-dark(#e2e6e6, #30353a);
  --text: light-dark(#23373b, #e4e7ea);
  --text-muted: light-dark(#5d6e71, #9ca3aa);
  --accent: light-dark(#1b6670, #76bcc5);
  --accent-hover: light-dark(#134e56, #a3d6dc);
  --ink: light-dark(#23373b, #b9c0c7);
  --ink-hover: light-dark(#34525a, #d5dade);
  --on-ink: light-dark(#ffffff, #141618);
  --mark: #eb811b;
  --mark-text: light-dark(#a9560a, #f3a65a);
  --danger: light-dark(#dc2626, #f87171);
  /* 바닥에 놓인 것(카드·목록 칸)에는 그림자를 두지 않는다 -- 칸은 가는 선으로 나눈다.
     --shadow 는 그래서 none 이고, 떠 있는 것(말풍선·자동완성·끌고 있는 칸)만
     --shadow-float 를 쓴다. 길이는 같고 색만 다르다 (어두울 때 진하게). */
  --shadow: none;
  --shadow-float: 0 1px 2px light-dark(rgba(0, 0, 0, 0.06), rgba(0, 0, 0, 0.3)),
                  0 4px 14px light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.32));
  /* 맨 위 메뉴 막대: Metropolis 의 frametitle 처럼 짙은 띠. 다크에서는 바탕보다 한 단계 더 짙게. */
  --band: light-dark(#23373b, #0d0f11);
  --on-band: #ffffff;
  --on-band-muted: rgba(255, 255, 255, 0.7);

  /* 모양 스케일. 카드는 --radius, 버튼·입력·칩 같은 작은 요소는 --radius-sm,
     --radius-pill 은 진행 막대·사람 표시처럼 정말 둥근 것에만 (칩·배지는 --radius-sm).
     이 셋 밖의 둥글기는 쓰지 않는다. */
  --radius: 6px;
  --radius-sm: 4px;
  --radius-pill: 999px;

  /* 글자 스케일. 본문 1rem 아래로 네 단계만 둔다.
     0.7~0.92rem 사이에 열몇 가지 값이 흩어져 있던 것을 여기로 모았다. */
  --fs-xs: 0.74rem;   /* 표 머리글, 축 눈금, 아주 작은 배지 */
  --fs-sm: 0.8rem;    /* 칩, 보조 설명, 표 본문 */
  --fs-md: 0.87rem;   /* 힌트, 라벨, 목록 메타 */
  --fs-base: 0.92rem; /* 버튼, 입력, 본문에 가까운 보조 글 */

  /* 고정폭 글꼴. 차례가 중요하다 -- 한글 고정폭 글꼴(굴림체 같은 것)은
     역슬래시(U+005C)를 **원화 기호(₩)** 로 그린다. 옛 한국어 코드 페이지에서
     그 자리가 원화였던 흔적이고, 그래서 `\section` 이 `₩section` 으로 보인다.
     글자는 늘 U+005C 이고 보이는 모양만 그런 것이라 조용히 헷갈린다. 역슬래시가
     밥줄인 화면(LaTeX 편집기)에서는 두고 볼 수 없어, 사이트가 직접 내보내는
     Fira Mono 를 맨 앞에, 그것이 못 받아졌을 때 역슬래시를 제대로 그리는 글꼴을
     운영체제마다 하나씩 두고 generic monospace 는 맨 뒤로 뺀다.
     한글은 이 글꼴들에 없으므로 브라우저가 글자마다 알아서 되돌아간다. */
  --mono: "Fira Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "DejaVu Sans Mono",
          "Liberation Mono", "Courier New", monospace;
  /* 본문 글꼴. 위 @font-face 가 못 받아졌을 때를 위해 시스템 글꼴을 뒤에 둔다. */
  --sans: "Fira Sans", "Pretendard Variable", -apple-system, BlinkMacSystemFont, "Segoe UI",
          "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", sans-serif;

  /* 반응형 기준점은 CSS 변수로 미디어 쿼리를 쓸 수 없어 주석으로 못 박는다.
     560px(폰) · 880px(태블릿/좁은 창) · 1000px(두 칸 레이아웃 시작). 이 셋만 쓴다. */

  /* 브라우저에 "다크는 내가 직접 처리한다"고 알린다.
     이 선언이 없으면 크롬의 강제 다크모드가 아래 팔레트를 무시하고
     색을 기계적으로 반전시켜서 대비가 무너진다. light-dark() 도 이 값을 보고 고른다. */
  color-scheme: light dark;

  /* 상태색과 보조 표면. gpu/calendar/disk 페이지 CSS가 같이 쓴다.
     여기 한 곳만 고치면 네 화면의 다크 대응이 같이 움직인다.
     어두운 바탕에서는 채도보다 명도가 대비를 만든다.
     #16a34a 나 #dc2626 을 어두울 때도 그대로 두면 글자가 배경에 묻힌다. */
  --ok: light-dark(#16a34a, #4ade80);
  --ok-text: light-dark(#047857, #4ade80);
  --warn: light-dark(#d97706, #fbbf24);
  --warn-text: light-dark(#b45309, #fbbf24);
  --crit: light-dark(#dc2626, #f87171);
  --track: light-dark(#e2e6e6, #30353a);
  --surface-2: light-dark(#f4f6f6, #22262a);
  --border-subtle: light-dark(#eef1f1, #262a2e);
  /* 내 줄·고른 항목·코멘트 칸. 다크는 먹색 위에서 바로 갈리도록 옅은 주황(호박색)이다. */
  --highlight: light-dark(#eef4f4, #3a2b1a);
  /* 글 선택(원고 편집기). 하이라이트보다 한 단계 진해야 고른 줄 위에서도 보인다. */
  --selection: light-dark(#cbe0e3, #5a4022);
  --text-strong: light-dark(#1a2b2e, #f4f5f7);
  --text-faint: light-dark(#627275, #858c94);   /* 흐리게 두는 글자도 4.5:1 은 넘긴다 */
  --tick: light-dark(#34474b, #c9ced4);
  /* 색이 깔린 위에 얹는 글자색. 다크에서 --accent/--danger 가 밝아지므로
     흰 글자를 그대로 두면 대비가 3:1 아래로 떨어진다. */
  --on-accent: light-dark(#ffffff, #0f1a1c);
  --on-danger: light-dark(#ffffff, #240a0a);
  --tag-bg: var(--ink);
  --tag-fg: var(--on-ink);
  --chip-bg: light-dark(#eaeeee, #2a2f34);
  --chip-fg: light-dark(#3f5357, #c5cad0);
  /* 배너는 어두울 때 밝은 판을 깔지 않고 반투명 색조로 얹는다 */
  --warn-bg: light-dark(#fffbeb, rgba(251, 191, 36, 0.12));
  --warn-border: light-dark(#fcd34d, rgba(251, 191, 36, 0.45));
  --warn-fg: light-dark(#92400e, #fcd34d);
  --crit-bg: light-dark(#fef2f2, rgba(248, 113, 113, 0.12));
  --crit-border: light-dark(#fca5a5, rgba(248, 113, 113, 0.45));
  --crit-fg: light-dark(#991b1b, #fca5a5);
  --info-bg: light-dark(#f4f6f6, #1f2326);
  --info-border: light-dark(#e2e6e6, #30353a);
  --info-fg: light-dark(#3f5357, #bcc2c8);
  --code-bg: light-dark(rgba(35, 55, 59, 0.07), rgba(255, 255, 255, 0.09));
  --fill-neutral: light-dark(#c9d3d4, #4b5258);
  --fill-muted: light-dark(#8fa1a3, #7d858d);
  --trend-fill: light-dark(rgba(143, 161, 163, 0.35), rgba(143, 161, 163, 0.28));
}

/* 테마 단추로 고른 값 (serve.py 의 _with_theme, static/theme.js). 없으면 위의 light dark. */
:root[data-theme="light"] {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

/* 키보드로 옮겨 다닐 때 지금 어디에 있는지 보이게 한다.
   마우스 클릭에는 :focus-visible 이 붙지 않아 평소 화면은 그대로다.
   버튼·링크·칩·세그먼트 토글까지 한 규칙으로 덮는다. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 움직임을 줄여 달라고 한 사용자에게는 전환·애니메이션을 끈다 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

html, body {
  margin: 0;
  padding: 0;
}

/* [hidden] 은 브라우저 기본 스타일이라 .button {display:inline-flex} 같은
   author 규칙에 진다. 여러 화면이 hidden 으로 요소를 여닫으므로 여기서 눌러 둔다. */
[hidden] {
  display: none !important;
}

/* 모든 글자 크기가 rem 이라 여기 한 줄이 전체 화면의 기준이 된다.
   브라우저 기본 16px 은 모니터에서 작다는 말이 있어 한 단계(17px) 올렸다. */
html {
  font-size: 106.25%;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.55;
}

/* 입력칸·단추는 브라우저가 body 글꼴을 물려주지 않는다 (시스템 글꼴로 그린다).
   체크박스·라디오·범위 막대의 채움색도 브라우저 파랑 대신 우리 색으로. */
button,
input,
select,
textarea {
  font-family: inherit;
  accent-color: var(--accent);
}

/* 본문 폭. 기본(.page)은 폼·로그인처럼 한 줄이 짧아야 읽기 좋은 화면용이고,
   목록·상세·홈·갤러리처럼 옆으로 펼칠 게 있는 화면은 .page.wide 를 쓴다.
   좌우 여백은 화면 폭에 따라 늘어나서 16:9 모니터에서도 답답하지 않게 한다. */
.page {
  max-width: 760px;
  margin: 0 auto;
  padding: 2.5rem clamp(1.25rem, 3vw, 2.5rem) 4rem;
}

.eyebrow {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0 0 0.4rem;
}

/* 제목은 굵기 대신 크기로 가른다. 굵게(700)는 경고·숫자 몇 곳에만 남긴다. */
h1 {
  font-size: 1.75rem;
  font-weight: 500;
  margin: 0 0 1.5rem;
  letter-spacing: -0.015em;
  color: var(--text-strong);
}

h2,
h3,
h4 {
  font-weight: 500;
}

/* 화면 제목 밑의 짧은 주황 선 (Metropolis 표지의 그 선). 마크다운 본문(.md)의 h1 과
   화면에 안 보이는 제목, 파일 이름을 제목으로 쓰는 보기 화면은 뺀다. 제목 줄이 flex(+wrap)
   여도 선은 다음 줄로 간다 -- 오른쪽 여백으로 줄을 다 채워 혼자 한 줄을 차지한다. */
h1:not(.sr-only, .wk-filename)::after {
  content: "";
  display: block;
  flex: none;
  width: 2.25rem;
  margin-right: calc(100% - 2.25rem);
  height: 2px;
  margin-top: 0.55rem;
  background: var(--mark);
}

.md h1::after {
  content: none;
}

/* ---- 맨 위 메뉴 막대 ----
   templates.site_nav 가 그리고 serve.py 가 요청마다 끼워 넣는다. 화면 폭과
   상관없이 가로로 끝까지 깔리고, 좌우 여백은 .page 와 같은 식이라 폭 제한이
   없는 작업 화면에서는 본문과 줄이 맞는다. 좁은 화면에서는 칸 줄만 옆으로
   밀린다 (이름·계정은 오른쪽에 붙어 있다). */
.sitenav {
  display: flex;
  align-items: center;
  gap: 0 1rem;
  padding: 0 clamp(1.25rem, 3vw, 2.5rem);
  background: var(--band);
}

.sitenav a:hover {
  text-decoration: none;
}

.sitenav-brand {
  flex: none;
  color: var(--on-band);
  font-weight: 500;
  letter-spacing: 0.12em;
}

.sitenav-links {
  display: flex;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

.sitenav-links::-webkit-scrollbar {
  display: none;
}

.sitenav-links a {
  flex: none;
  padding: 0.85rem 0.65rem 0.7rem;
  border-bottom: 3px solid transparent;
  color: var(--on-band-muted);
  font-size: var(--fs-base);
  white-space: nowrap;
}

.sitenav-links a:hover {
  color: var(--on-band);
}

/* 지금 칸: 주황 밑줄 (--mark 는 "지금·여기" 표시에만 쓴다) */
.sitenav-links a[aria-current="page"] {
  border-bottom-color: var(--mark);
  color: var(--on-band);
  font-weight: 500;
}

/* 짙은 띠 위에서는 청록 포커스 테두리가 묻힌다 */
.sitenav :focus-visible {
  outline-color: var(--mark);
}

.sitenav-side {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.75rem;
}

.sitenav-me {
  color: var(--on-band-muted);
  font-size: var(--fs-md);
  white-space: nowrap;
}

a.sitenav-me:hover,
a.sitenav-me[aria-current="page"],
button.sitenav-me:hover {
  color: var(--on-band);
}

/* 로그아웃은 POST 라 form 안의 button 이다. 옆의 이름 링크와 똑같이 보이게 한다 */
button.sitenav-me {
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  font-size: var(--fs-md);
  line-height: inherit;
  cursor: pointer;
}

/* 화면 테마 단추 (templates.theme_button, static/theme.js). 그림은 지금 값의 것 하나만
   보인다. 메뉴 막대에서는 옆의 이름 링크와 같은 얼굴이다. */
.theme-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  border: 0;
  background: transparent;
  padding: 0;
  color: var(--text-muted);
  font: inherit;
  font-size: var(--fs-md);
  line-height: inherit;
  white-space: nowrap;
  cursor: pointer;
}

.theme-btn:hover {
  color: var(--accent);
}

.sitenav .theme-btn {
  color: var(--on-band-muted);
}

.sitenav .theme-btn:hover {
  color: var(--on-band);
}

.theme-ico {
  display: none;
  flex: none;
  width: 1em;
  height: 1em;
}

.theme-btn[data-theme-value="system"] .theme-ico-system,
.theme-btn[data-theme-value="light"] .theme-ico-light,
.theme-btn[data-theme-value="dark"] .theme-ico-dark {
  display: block;
}

/* 막대 밑에서는 위 여백을 줄인다 (막대가 이미 자리를 띄운다) */
.sitenav + .page {
  padding-top: 1.5rem;
}

@media (max-width: 560px) {
  .sitenav {
    gap: 0 0.5rem;
  }

  /* 칸 줄 양 끝을 흐리게: 글자가 칼로 자른 듯 잘려 보이지 않고, 옆으로 더
     밀린다는 것이 보인다 */
  .sitenav-links {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 0.9rem, #000 calc(100% - 0.9rem), transparent);
    mask-image: linear-gradient(to right, transparent, #000 0.9rem, #000 calc(100% - 0.9rem), transparent);
  }

  .sitenav-links a {
    padding-inline: 0.5rem;
  }

  /* 폰에서는 그림만 (이름은 aria-label·title 에 있다). 칸 줄이 덜 밀린다. */
  .sitenav .theme-btn-label {
    display: none;
  }
}

/* 제목은 왼쪽, 계정 관리 같은 부수 링크는 오른쪽 위 */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.page-head h1 {
  margin-bottom: 1.5rem;
}

.corner-link {
  flex: none;
  color: var(--text-muted);
  font-size: var(--fs-md);
  padding-top: 0.15rem;
  white-space: nowrap;
}

.corner-link:hover {
  color: var(--accent);
}

.topbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

.topbar h1 {
  margin: 0;
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--text-muted);
  font-size: var(--fs-md);
  margin-bottom: 1.25rem;
}

.back-link:hover {
  color: var(--text);
  text-decoration: none;
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.42rem 0.95rem;
  background: var(--ink);
  color: var(--on-ink);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s ease;
}

.button:hover {
  background: var(--ink-hover);
  text-decoration: none;
}

.button.secondary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
}

.button.secondary:hover {
  background: var(--surface);
  border-color: var(--accent);
  color: var(--accent);
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.card + .card {
  margin-top: 1.25rem;
}

.card-pad {
  padding: 1.25rem 1.4rem;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.list-item {
  padding: 0.95rem 1.4rem;
  border-bottom: 1px solid var(--border);
}

.list-item:last-child {
  border-bottom: none;
}

.list-item-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.list-item-title {
  font-weight: 500;
  font-size: 1.02rem;
}

.list-item-meta {
  color: var(--text-muted);
  font-size: var(--fs-md);
  white-space: nowrap;
}

.list-item-controls {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

.list-item-controls form {
  display: inline;
}

.edit-tags-form {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.edit-tags-form input[type="text"] {
  flex: 1;
}

.badge {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: 500;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text-muted);
  border: 1px solid var(--border);
  margin-left: 0.5rem;
}

/* 색이 깔린 배경은 토큰을 color-mix 로 옅게 한다.
   rgba 리터럴을 두면 다크에서 라이트 값이 그대로 남아 대비가 무너진다. */
.badge.public {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
  border-color: transparent;
}

.badge.tag {
  background: var(--chip-bg);
  color: var(--chip-fg);
  border-color: transparent;
}

/* 태그 칩은 <a> 라서 링크 기본 스타일을 지워준다 */
a.badge {
  text-decoration: none;
}

a.badge:hover {
  filter: brightness(0.95);
}

/* 업로더 아이디 태그 (업로드할 때 자동으로 붙는다) */
.badge.tag.owner {
  background: color-mix(in srgb, var(--ok) 14%, transparent);
  color: var(--ok-text);
}

.badge.tag.active {
  background: var(--ink);
  color: var(--on-ink);
}

.search-bar {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.search-bar input[type="text"] {
  flex: 1;
}

.search-bar select {
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--fs-sm);
  padding: 0.22rem 0.65rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  text-decoration: none;
}

.chip:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.chip.active {
  background: var(--ink);
  border-color: transparent;
  color: var(--on-ink);
}

.chip-count {
  font-size: var(--fs-xs);
  opacity: 0.7;
}

.filter-summary {
  margin: 0 0 1rem;
  font-size: var(--fs-md);
  color: var(--text-muted);
}

.filter-summary a {
  margin-left: 0.5rem;
}

.button.small {
  padding: 0.22rem 0.6rem;
  font-size: var(--fs-sm);
}

.button.danger {
  background: transparent;
  color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent);
}

.button.danger:hover {
  background: color-mix(in srgb, var(--danger) 8%, transparent);
}

.empty {
  padding: 2.5rem 1.4rem;
  text-align: center;
  color: var(--text-muted);
}

.hint {
  color: var(--text-muted);
  font-size: var(--fs-md);
}

form {
  margin: 0;
}

fieldset {
  border: none;
  padding: 0;
  margin: 0;
}

label {
  display: block;
  font-weight: 500;
  font-size: var(--fs-md);
  margin: 0 0 0.35rem;
}

label.mt {
  margin-top: 1rem;
}

input[type="text"],
input[type="search"],
input[type="url"],
input[type="password"],
input[type="file"] {
  width: 100%;
  padding: 0.55rem 0.7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: var(--fs-base);
}

/* 여러 줄 입력칸도 한 줄 입력칸과 같은 모양이다. 지정하지 않으면 브라우저가
   고정폭 글꼴과 회색 테두리를 써서, 노트·코멘트 칸이 코드 편집기처럼 보인다.
   코드·마크다운을 쓰는 편집칸(잡북·리부탈·원고)은 각자 var(--mono) 로 덮는다. */
textarea {
  width: 100%;
  padding: 0.55rem 0.7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-base);
  line-height: 1.5;
  resize: vertical;
}

/* 입력칸은 마우스로 눌러도 포커스 테두리를 보여준다 (어디에 쓰는지 알아야 하므로) */
input[type="text"]:focus,
input[type="search"]:focus,
input[type="url"]:focus,
input[type="password"]:focus,
input[type="file"]:focus,
select:focus,
input[type="date"]:focus,
input[type="month"]:focus,
textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.upload-tabs {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 1.25rem;
}

.tab {
  flex: 1;
  font: inherit;
  text-align: center;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--fs-md);
  font-weight: 500;
  cursor: pointer;
}

.tab.active {
  background: var(--ink);
  color: var(--on-ink);
  border-color: var(--ink);
}

.upload-pane {
  display: none;
}

.upload-pane.active {
  display: block;
}

.upload-pane .button {
  margin-top: 1rem;
  width: 100%;
  justify-content: center;
  border: none;
}

/* ---- 알림 상자 ----
   사이트 전체의 배너는 이 한 벌만 쓴다. 등급은 네 가지:
     .info    조용한 안내 (기본. 수집기 멈춤, 읽기 전용 설명)
     .success 방금 한 일이 잘 됐다
     .warn    주의. 한도에 가까움, 자료가 오래됨 (주황)
     .error   실패 · 위험. 로그인 실패, 한도 초과, 파티션 위험 (빨강)
   홈 경고(alerts.js)·디스크(disk.js)·캘린더 마감 안내도 이 클래스를 쓴다. */
.notice {
  padding: 0.8rem 1rem;
  border: 1px solid var(--info-border);
  border-radius: var(--radius-sm);
  background: var(--info-bg);
  color: var(--text);
  font-size: var(--fs-md);
  line-height: 1.5;
  margin-bottom: 1.25rem;
}

.notice.success {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

.notice.warn {
  background: var(--warn-bg);
  border-color: var(--warn-border);
  color: var(--warn-fg);
}

.notice.error {
  background: var(--crit-bg);
  border-color: var(--crit-border);
  color: var(--crit-fg);
}

/* 상자 안의 제목 줄 (본문과 줄을 나눈다) */
.notice-title {
  display: block;
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.notice code {
  background: var(--code-bg);
  padding: 0 0.25rem;
  border-radius: 0.2rem;
  font-size: 0.9em;
}

footer.note {
  margin-top: 2rem;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

/* ---- 공용 레이아웃 조각 ----
   여러 화면이 같이 쓰는 것은 여기 한 곳에만 둔다. 페이지 전용 css 에서
   같은 클래스를 다시 정의하지 않는다 (그러면 화면마다 다르게 그려진다). */

.page.wide {
  max-width: 1240px;
}

/* GPU 대시보드처럼 표·차트가 옆으로 긴 화면 */
.page.wide.xl {
  max-width: 1400px;
}

/* 원고·편집·파일 보기처럼 옆으로 나란히 놓고 일하는 화면. 폭 제한이 없다.
   (page_open(full=True). 화면마다 max-width 를 따로 덮어쓰지 않는다 --
   .page.wide 와 선택자 세기를 겨루다 지는 일이 생긴다.) */
.page.full {
  max-width: none;
}

/* 카드 머리: 왼쪽 제목, 오른쪽 힌트나 토글 */
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  flex-wrap: wrap;
  margin: 0 0 0.9rem;
}

.section-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.section-head .hint {
  margin: 0;
}

/* 세그먼트 토글 (7일/14일/30일 같은 배타 선택) */
.seg {
  display: inline-flex;
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  /* 칸이 폭보다 많으면 글자를 한 자씩 세로로 꺾지 않고 옆으로 민다 (폰) */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  background: var(--surface);
}

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

.seg button,
.seg a {
  flex: none;
  white-space: nowrap;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  padding: 0.35rem 0.75rem;
  cursor: pointer;
}

.seg button + button,
.seg a + a {
  border-left: 1px solid var(--border);
}

.seg button.active,
.seg button[aria-pressed="true"],
.seg a.active {
  background: var(--ink);
  color: var(--on-ink);
}

/* overflow:hidden 안에서는 바깥 outline 이 잘리므로 안쪽으로 그린다 */
.seg button:focus-visible,
.seg a:focus-visible {
  outline-offset: -2px;
}

/* 서버 관리(GPU · 디스크 · Codex) 화면을 오가는 탭 줄. 링크지만 세그먼트
   토글과 같은 모양이라 밑줄은 긋지 않는다. */
.seg-tabs {
  margin-bottom: 1.25rem;
}

.seg-tabs a {
  padding: 0.4rem 1rem;
}

.seg-tabs a:hover {
  text-decoration: none;
  color: var(--text);
}

.seg-tabs a.active:hover {
  color: var(--on-accent);
}

/* 데이터 표. 순위표(disk)·job 이력(gpu)이 같이 쓴다 */
.table-scroll {
  overflow-x: auto;
}

/* booktabs 처럼: 위아래는 굵은 선, 머리글 밑은 중간 선, 줄 사이는 옅은 선 */
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  border-top: 1.5px solid var(--text);
  border-bottom: 1.5px solid var(--text);
}

table.data th,
table.data td {
  text-align: left;
  padding: 0.45rem 0.7rem;
  border-bottom: 1px solid var(--border-subtle);
  white-space: nowrap;
}

table.data th {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: 500;
  border-bottom: 1px solid var(--text-muted);
}

table.data tbody tr:last-child td {
  border-bottom: none;
}

table.data td.num,
table.data th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

table.data tr.mine-row,
table.data tr.is-me {
  background: var(--highlight);
}

/* "나" 표시. 사용자 이름 옆에 붙는다 (gpu·disk) */
.me-tag {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.4rem;
  border-radius: var(--radius-sm);
  background: var(--tag-bg);
  color: var(--tag-fg);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.4;
  vertical-align: middle;
}

.mt {
  margin-top: 1rem;
}

/* 화면에는 안 보이고 보조기기만 읽는 글 (편집 화면의 h1 등) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.topbar-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

select,
input[type="date"],
input[type="month"] {
  width: 100%;
  padding: 0.55rem 0.7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-base);
}

.search-bar select {
  width: auto;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}

/* ---- 목록 ---- */

.list-item-sub {
  margin-top: 0.3rem;
  color: var(--text-muted);
  font-size: var(--fs-md);
}

.list-item-sub .snippet {
  color: var(--text-faint);
}

.row-open {
  margin-left: 0.7rem;
  font-size: var(--fs-sm);
  white-space: nowrap;
}

/* ---- 쪽 이동 ---- */

.pager {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

.page-btn {
  display: inline-block;
  min-width: 2rem;
  padding: 0.35rem 0.6rem;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-md);
  text-decoration: none;
}

.page-btn:hover {
  border-color: var(--accent);
  text-decoration: none;
}

.page-btn.active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--on-ink);
  font-weight: 700;
}

.page-btn.disabled {
  color: var(--text-faint);
  opacity: 0.55;
}

.page-gap {
  color: var(--text-muted);
  padding: 0 0.1rem;
}

.page-total {
  margin-left: auto;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

/* ---- 상세 ---- */

.detail-badges {
  margin: -0.5rem 0 1rem;
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.detail-head {
  display: flex;
  gap: 1.4rem;
  align-items: flex-start;
  flex-wrap: wrap;
}

.detail-thumb {
  width: 360px;
  max-width: 100%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
}

.detail-info {
  flex: 1 1 280px;
  min-width: 0;
}

.detail-summary {
  margin: 0 0 0.9rem;
  font-size: 1rem;
}

.kv-list {
  display: grid;
  gap: 0.35rem;
}

.kv {
  display: flex;
  gap: 0.8rem;
  font-size: var(--fs-base);
  align-items: baseline;
}

/* 상세 화면은 넓은 화면에서 두 칸으로 벌어진다.
   왼쪽: 썸네일·속성·열기 버튼과 CSP 안내, 오른쪽: 파일 목록과 관리 폼.
   칸 안에서는 카드 사이 간격을 gap 으로 주므로 .card + .card 여백은 끈다. */
.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}

.detail-main,
.detail-side {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  min-width: 0;
}

.detail-main > .card + .card,
.detail-side > .card + .card {
  margin-top: 0;
}

.detail-main > .notice {
  margin-bottom: 0;
}

@media (min-width: 1000px) {
  .detail-grid {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  }
}

.kv .k {
  flex: 0 0 5.5rem;
  color: var(--text-muted);
}

.kv .v {
  min-width: 0;
  overflow-wrap: anywhere;
}

.detail-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 1.1rem;
  align-items: center;
}

.detail-actions form {
  display: inline;
}

.file-list,
.version-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--fs-base);
}

.file-list li,
.version-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border-subtle);
}

.file-list li:last-child,
.version-list li:last-child {
  border-bottom: none;
}

.file-list a {
  overflow-wrap: anywhere;
}

/* ---- 갤러리 ---- */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 1rem;
}

.slide-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  color: var(--text);
  text-decoration: none;
}

.slide-card:hover {
  border-color: var(--accent);
  text-decoration: none;
}

.card-thumb {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: top center;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}

.empty-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-faint);
  font-size: 2rem;
  font-weight: 700;
}

.card-body {
  padding: 0.75rem 0.85rem 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  flex: 1;
}

.card-title {
  font-weight: 500;
  font-size: var(--fs-base);
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.card-summary {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  /* 카드 높이가 요약 길이에 따라 들쭉날쭉해지지 않게 두 줄에서 자른다 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-meta {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

/* ---- D-day 배지 · 예상 표시 (캘린더·홈이 같이 쓴다) ---- */

.badge.est {
  flex: none;
  white-space: nowrap;   /* "작년 기준" 이 좁은 칸에서 한 글자씩 꺾이지 않게 */
  background: var(--warn-bg);
  color: var(--warn-text);
  border-color: transparent;
  margin-left: 0.35rem;
}

.dday {
  flex: none;
  font-size: var(--fs-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text-muted);
  border: 1px solid var(--border);
}

.dday.soon {
  background: var(--crit-bg);
  color: var(--danger);
  border-color: transparent;
}

.dday.near {
  background: var(--warn-bg);
  color: var(--warn-text);
  border-color: transparent;
}

.dday.today {
  background: var(--danger);
  color: var(--on-danger);
  border-color: transparent;
}

/* ---- 홈 ----
   기능 카드가 폰에서는 한 줄에 하나, 노트북에서 둘, 16:9 모니터에서 셋씩 놓인다.
   발표자료 카드는 대표 기능이라 항상 한 줄을 다 쓴다. */

/* 기능 목록은 상자를 늘어놓지 않고 가는 선으로 나눈 목록이다. 칸마다 아래 선 하나,
   목록 맨 위에 선 하나. 위의 "내 현황"·"사이트 관리" 칸(상자)과 무게가 겹치지 않는다. */
.home-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 0 2rem;
  border-top: 1px solid var(--border);
}

.home-grid > .home-card {
  padding: 1.1rem 0.15rem 1.15rem;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
}

.home-grid > .card + .card {
  margin-top: 0;
}

/* 카드 전체가 하나의 링크다(.home-go 의 덮개). 버튼을 따로 두지 않는다. */
.home-card {
  display: flex;
  flex-direction: column;
  position: relative;
}

.home-card:hover .home-go,
.home-card:focus-within .home-go {
  color: var(--accent);
}

.home-go {
  color: inherit;
  text-decoration: none;
}

/* 제목 링크를 카드 크기로 늘린다. 설명 글 위 빈 자리를 눌러도 이동한다. */
.home-go::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.home-card.primary {
  grid-column: 1 / -1;
}

.home-card h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* 기능 카드의 아이콘. 순서가 바뀌어도 모양으로 찾을 수 있게 제목 앞에 둔다.
   선을 currentColor 로 그리므로 라이트/다크 색을 따로 맞출 필요가 없다
   (색을 따로 주지 않는 이유는 README "화면 규칙" 표에 적어 두었다). */
.home-icon {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--text-muted);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.home-card:hover .home-icon,
.home-card:focus-within .home-icon {
  color: var(--accent);
}

.home-card p {
  margin: 0 0 1rem;
}

/* 버튼이 없는 카드(대부분)는 설명 글이 마지막 줄이라 아래 여백을 뺀다. */
.home-card p:last-child {
  margin-bottom: 0;
}

/* 카드 링크 말고 따로 갈 곳이 더 있는 카드. 덮개 위로 올려야 눌린다. */
.home-card .home-actions {
  margin-top: auto;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  position: relative;
  z-index: 1;
}

/* 홈 본문: 기능 카드 그리드 + 옆에 다가오는 일정.
   일정 칸은 기능 카드의 폭을 빼앗지 않는다. 카드 그리드는 평소 폭(1240px)을
   그대로 쓰고, 화면이 그보다 20rem+여백만큼 더 넓을 때만 본문 폭을 늘려
   오른쪽 남는 자리에 일정 칸을 세운다. 그보다 좁으면 일정 칸은 숨긴다. */
.home-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}

.home-side {
  display: none;
}

@media (min-width: 1700px) {
  .page.home {
    max-width: calc(1240px + 20rem + 1.25rem);
  }
  .home-layout {
    grid-template-columns: minmax(0, 1fr) 20rem;
  }
  /* DOM 순서는 aside 가 먼저라, 칸을 명시하지 않으면 aside 가 넓은 첫 칸을
     차지하고 카드 그리드가 20rem 칸에 밀려 한 줄에 하나씩 나온다. */
  .home-layout > .home-grid {
    grid-column: 1;
    grid-row: 1;
  }
  .home-side {
    display: block;
    grid-column: 2;
    grid-row: 1;
    position: sticky;
    top: 1.25rem;
  }
}

.home-side .section-head {
  margin-bottom: 0.4rem;
}

.home-side .section-head .hint {
  font-size: var(--fs-sm);
}

/* 홈 "내 현황": 내 것만 담은 작은 칸 묶음 (static/home-me.js).
   기능 카드 그리드 위, 경고 배너 아래에 한 장. 칸마다 통째로 링크다.
   폰에서는 두 칸씩, 넓으면 한 줄에 다 놓인다. 보여 줄 것이 없으면 카드째 숨는다. */
/* 묶음 자체는 상자가 아니다 (제목 + 칸들). 상자는 안의 칸 하나하나뿐이다. */
.home-me {
  margin: 0 0 1.75rem;
}

.card.home-me {
  padding: 0;
  background: transparent;
  border: 0;
}

.home-me .me-title {
  margin: 0 0 0.6rem;
  font-size: 1.05rem;
  font-weight: 500;
}

.me-tiles {
  display: grid;
  /* auto-fit: 칸이 서너 개뿐일 때 오른쪽에 빈 자리를 남기지 않고 나눠 쓴다 */
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.6rem;
}

.me-tile {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.12s ease;
}

.me-tile:hover,
.me-tile:focus-visible {
  border-color: var(--accent);
  text-decoration: none;
}

.me-k {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* 폰의 좁은 칸에서 "12건" 이 "12 / 건" 으로 갈리지 않게 한글은 낱말 단위로만
   줄을 바꾼다. 잡 이름처럼 긴 영문은 break-word 가 칸 안에서 끊는다. */
.me-v,
.me-s {
  word-break: keep-all;
  overflow-wrap: break-word;
}

.me-v {
  font-weight: 500;
}

.me-s {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.me-dday {
  color: var(--mark-text);
}

/* 넓은 화면에서는 옆 칸 "다가오는 일정" 이 마감을 보여 준다. 두 번 말하지 않는다.
   마감 칸 하나만 있던 카드는 그러면 빈 껍데기가 되므로 카드째 숨긴다. */
@media (min-width: 1700px) {
  .me-tile.me-deadline,
  .home-me.only-deadline {
    display: none;
  }
}

@media (max-width: 560px) {
  .me-tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
  }
  .me-tile {
    padding: 0.5rem 0.6rem;
  }
  .me-v {
    font-size: var(--fs-base);
  }
  /* 칸 수가 홀수면 마지막 칸이 한 줄을 다 쓴다 (반쪽 칸 옆에 빈 자리가 남지 않게) */
  .me-tile:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
  /* 한 줄을 다 쓰는 목록 칸(연구실 현황) 뒤로는 짝이 하나씩 밀린다 */
  .role-wide ~ .me-tile:last-child:nth-child(odd) {
    grid-column: auto;
  }
  .role-wide ~ .me-tile:last-child:nth-child(even) {
    grid-column: 1 / -1;
  }
}

/* 홈 역할 카드 (static/home-roles.js): 사이트 관리 · 연구실 현황.
   칸 모양은 "내 현황" 을 그대로 쓰고, 손볼 칸만 테두리와 값 색으로 짚는다.
   링크가 아닌 칸(div.me-tile)은 hover 테두리를 주지 않는다 -- 누를 수 있어 보이면 안 된다. */
div.me-tile:hover {
  border-color: var(--border);
}

.me-tile.me-warn {
  box-shadow: inset 3px 0 0 var(--warn);
}

.me-tile.me-warn .me-v {
  color: var(--warn-text);
}

.me-tile.me-bad {
  box-shadow: inset 3px 0 0 var(--crit);
}

.me-tile.me-bad .me-v,
.me-s .me-flag {
  color: var(--crit-fg);
}

/* 값은 멀쩡하고 아랫줄 하나만 손볼 때 (계정 칸): 왼쪽 줄과 그 줄만 칠한다 */
.me-tile.me-edge-warn {
  box-shadow: inset 3px 0 0 var(--warn);
}

.me-tile.me-edge-bad {
  box-shadow: inset 3px 0 0 var(--crit);
}

.me-s .me-flag-warn {
  color: var(--warn-text);
}

/* 사이트 관리는 칸이 여섯이라 넓은 화면에서 셋씩 두 줄로 (5+1 로 끊기지 않게).
   폰(560px 아래)은 다른 카드처럼 두 칸씩이라 여기서 건드리지 않는다. */
@media (min-width: 561px) {
  #ops-root .me-tiles {
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }
}

/* 학생 연구 폴더: 줄이 여럿이라 한 줄을 다 쓴다 */
.me-tile.role-wide {
  grid-column: 1 / -1;
}

.role-list {
  list-style: none;
  font-size: var(--fs-md);
  margin: 0.3rem 0 0.1rem;
  padding: 0;
  display: grid;
  gap: 0.35rem;
}

.role-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.1rem 0.5rem;
  min-width: 0;
}

.role-list a {
  min-width: 0;
  color: inherit;
  overflow-wrap: anywhere;
}

.role-who {
  font-weight: 700;
}

.role-when {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
}

/* 이번 업데이트 내용: 한 줄을 넘기면 줄임표 (전문은 프로젝트 화면에) */
.role-note {
  flex-basis: 100%;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-upcoming {
  list-style: none;
  margin: 0;
  padding: 0;
}

.home-upcoming li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.45rem 0;
  border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-md);
}

.home-upcoming li:first-child {
  border-top: none;
}

.home-upcoming .when {
  flex: none;
  width: 4.4rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-sm);
}

/* 기간 일정의 끝 날짜는 좁은 칸에서 줄이 깨지지 않게 아래 줄에 작게 */
.home-upcoming .when .span {
  display: block;
  font-size: var(--fs-xs);
  color: var(--text-faint);
}

.home-upcoming .when .dow.sun { color: var(--danger); }
.home-upcoming .when .dow.sat { color: var(--accent); }

.home-upcoming .what {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.home-upcoming .what .dot {
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--k, var(--text-muted));
  transform: translateY(-0.05em);
}

.home-upcoming .what .title {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.home-upcoming .what .sub {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.home-upcoming a {
  color: inherit;
}

.home-upcoming a:hover .title {
  text-decoration: underline;
}

.home-upcoming .none {
  color: var(--text-muted);
  border-top: none;
}

@media (max-width: 560px) {
  .card-pad {
    padding: 1rem;
  }
  /* 탭이 다섯 개(데이터셋 포함)라 360 폭에서도 옆으로 밀리지 않게 좁힌다.
     밀리면 오른쪽 끝 탭이 잘려서, 그 탭에 있을 때 제 이름이 안 보인다. */
  .seg-tabs a {
    padding-inline: 0.55rem;
  }
  .form-row {
    grid-template-columns: 1fr;
  }
  .detail-thumb {
    width: 100%;
  }
  .home-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
