/* ═══════════════════════════════════════════════════════════════════════════
   StarNote Archive — 공통 스타일  (web/src/style.css 를 이 파일로 통째로 바꾼다)

   컨셉(기획 2 확정, 그대로 지킨다)
     사막 지평선 위의 밤하늘. 위 = 밤하늘(별·유성), 물결선 = 모래 언덕 지평선,
     아래 = 사막 모래. 박스는 최소, 게시판 괘선으로 구분.

   이번에 고친 것 (지적 세 가지)
     ① 밤하늘  — <span> 90개 → <canvas> 한 장(nightsky.js). 별 1,100여 개·은하수·
                 회절상. 화면이 넓어지면 별도 그만큼 는다.
     ② 모래    — 알갱이 타일을 다시 굽고(빛 방향·광물색·틈새 그늘),
                 지평선 아래에 되풀이하지 않는 사구 띠를 한 장 깐다.
     ③ 글자    — 웹폰트를 실제로 불러온다(제목 명조·본문 Pretendard).
                 본문 17px·행간 1.75. 크기 21종 → 9단 계단. 여백 4px 배수 한 벌.
                 둥근 카드·그림자를 걷어내 앱 티를 없앤다.

   구조
     0 웹폰트 · 1 값 체계 · 2 바탕 · 3 밤하늘(머리) · 4 모래(본문) · 5 괘선
     6 단추·칩·입력 · 7 푸터 · 8 홈 · 9 도감 · 10 천체 상세 · 11 추천
     12 목록·계획 · 13 담기 바 · 14 접근성 · 15 반응형 · 16 인쇄
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── 0. 웹폰트 ─────────────────────────────────────────────────────────────
   전부 자체 호스팅(/font/). 남의 CDN 을 쓰지 않으므로 그쪽이 흔들려도 안전하고,
   요즘 브라우저는 사이트별로 캐시를 나눠 두어 CDN 공유 이점도 이미 사라졌다.
   파일은 tools/build-fonts.js 가 "이 사이트가 실제로 쓰는 글자"만 담아 굽는다.

     한국어 화면  pretendard-ko-400 + 700 (223 KB) + maruburi-600 (80 KB) = 303 KB
     영어 화면    pretendard-latin (47 KB) + maruburi-600 (80 KB)         = 127 KB
     일본어 화면  pretendard-latin + notoserifjp-600 + maruburi-600       = 322 KB
   두 번째 화면부터는 1년 캐시라 사실상 0. 셋 다 SIL OFL — /font/OFL.txt 동봉. */

@font-face {
  font-family: 'Pretendard KR';
  src: url('/font/pretendard-ko-400.woff2') format('woff2');
  font-weight: 300 500;
  font-style: normal;
  font-display: swap;      /* 폰트가 늦어도 글은 바로 읽힌다 */
}
@font-face {
  font-family: 'Pretendard KR';
  src: url('/font/pretendard-ko-700.woff2') format('woff2');
  font-weight: 501 900;    /* 600 을 요구해도 이 파일이 쓰인다(가짜 굵은 글씨 방지) */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Pretendard Latin';
  src: url('/font/pretendard-latin.woff2') format('woff2');
  font-weight: 45 920;     /* 가변 — 라틴·숫자·그리스 문자(ζ UMa)만 담았다 */
  font-style: normal;
  font-display: swap;
  /* 담긴 글자 범위를 적어 둔다. 이게 없으면 한국어 화면에서도 이 파일을 받는다 —
     로고의 일본어(星見ノート)처럼 앞 글꼴에 없는 글자를 만나면 브라우저가
     "다음 글꼴에 있나" 확인하려고 통째로 내려받기 때문이다(실측으로 48 KB 낭비 확인). */
  unicode-range: U+0000-024F, U+0370-03FF, U+2000-27BF;
}
@font-face {
  font-family: 'Serif KR';
  src: url('/font/maruburi-600.woff2') format('woff2');
  font-weight: 600;        /* 굵기 하나만. 명조는 큰 글자에서 굵기 차이가 잘 안 드러난다 */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Serif JA';
  src: url('/font/notoserifjp-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* 웹폰트가 도착하는 순간 글자가 튀지 않도록 대체 글꼴의 크기를 맞춰 둔다.
   (Pretendard x높이 53.03% · 맑은 고딕 51.27% 를 재서 구한 값) */
@font-face {
  font-family: 'Sans Fallback';
  src: local('Pretendard'), local('Apple SD Gothic Neo'), local('Malgun Gothic'), local('맑은 고딕');
  size-adjust: 103.4%;
  ascent-override: 92.1%;
  descent-override: 23.3%;
  line-gap-override: 0%;
  font-display: swap;
}


/* ── 1. 값 체계 ────────────────────────────────────────────────────────────
   "12랑 14 중 뭘 쓰지"를 없애는 것이 목적이다. 아래 목록 밖의 숫자는 되도록 안 쓴다. */
:root {
  /* 색 — 기획 2 확정 팔레트 */
  --sand: #F8F5EC;          /* 노트 속지 — 밝은 아이보리(회색기 없이) */
  --sand-deep: #F0ECDF;     /* 한 톤 진한 종이(표 머리·칸) */
  --line: #D9D2BE;          /* 노트 괘선 — 종이와 같은 계열 */
  --line-soft: #E8E3D3;     /* 옅은 괘선(행 구분) */
  --ink: #2B2823;           /* 볼펜 먹빛 — 종이 위 12.9:1 */
  --ink-sub: #55504A;       /* 보조                     7.0:1 */
  --ink-dim: #6B655C;       /* 흐린 글자                4.9:1 */
  --ink-faint: #6B655C;     /* --ink-dim 과 같다 */
  --red: #9A4632;           /* 인주 — 채움·테두리·큰 글자 */
  --red-ink: #8B3F2C;       /* 인주 — 작은 글자용(종이 위 6.4:1) */
  --paper: #FDFCF7;         /* 더 밝은 종이(칩·버튼 채움) */
  --night-0: #070a20;       /* 밤하늘 그라데이션 — nightsky.js 가 이 값을 읽어 간다 */
  --night-1: #0a0e2c;
  --night-2: #101636;
  --night-txt: #dbe4f5;
  --night-sub: #aab4d4;
  --night-dim: #8891b8;
  --gold: #ffd76a;

  /* 서체 */
  /* 한국어 화면 — 'Pretendard KR' 한 벌에 한글·라틴·숫자·기호가 다 들어 있다.
     여기에 'Pretendard Latin' 을 뒤에 두면, 앞 글꼴에 없는 글자를 만날 때마다
     브라우저가 확인하려고 그 파일(61 KB)을 받는다. 두지 않는다. */
  --sans: 'Pretendard KR', 'Sans Fallback',
          -apple-system, BlinkMacSystemFont, system-ui,
          'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
  --serif: 'Serif KR', 'Nanum Myeongjo', Batang, serif;
  --mono: 'SFMono-Regular', ui-monospace, Menlo, Consolas, 'D2Coding', monospace;

  /* 글자 크기 — 1.1~1.25 배씩 커지는 계단. clamp() 로 폰~PC 를 부드럽게 잇는다 */
  --fs-100: 0.8125rem;                                     /* 13px  꼬리표·개수 */
  --fs-200: 0.875rem;                                      /* 14px  보조 설명 */
  --fs-300: 0.9375rem;                                     /* 15px  표·목록·단추 */
  --fs-400: 1.0625rem;                                     /* 17px  본문 ★기준 */
  --fs-500: 1.1875rem;                                     /* 19px  도입 문장 */
  --fs-600: clamp(1.25rem, 1.13rem + 0.38vw, 1.375rem);    /* 20→22 h3 */
  --fs-700: clamp(1.375rem, 1.16rem + 0.68vw, 1.6875rem);  /* 22→27 h2 */
  --fs-800: clamp(1.625rem, 1.24rem + 1.22vw, 2.125rem);   /* 26→34 h1 */
  --fs-900: clamp(2rem, 1.28rem + 2.3vw, 3.25rem);         /* 32→52 히어로 */

  /* 행간 — 한글은 라틴보다 넉넉해야 읽힌다 */
  --lh-display: 1.24;
  --lh-heading: 1.38;
  --lh-snug: 1.5;
  --lh-body: 1.75;
  --lh-prose: 1.9;

  /* 자간 — 한글은 아주 살짝 좁혀야 덩어리져 보인다 */
  --ls-display: -0.022em;
  --ls-heading: -0.015em;
  --ls-body: -0.003em;
  --ls-caps: 0.06em;

  /* 간격 — 4px 배수 한 벌. 이름 = 실제 px */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;  --s-5: 24px;
  --s-6: 32px;  --s-7: 48px;  --s-8: 64px;  --s-9: 96px;

  /* 폭 — 머리·본문·발이 모두 이 선에 맞는다(옛날엔 1180 과 1280 이 섞여 어긋났다) */
  --shell: 1280px;
  --wrap: var(--shell);     /* 옛 이름 호환 */
  --measure: 66ch;          /* 읽는 글 최대 폭(한글 한 줄 약 36자) */
  --gutter: var(--s-6);
  --rail-w: 264px;          /* 도감 왼쪽 필터 단 */
  --side-w: 320px;          /* 천체 상세 오른쪽 단 */

  /* 모서리 — 앱은 12px, 웹 문서는 거의 각지게 */
  --r-sm: 2px;   --r-md: 4px;   --r-pill: 999px;

  /* 선 — 굵기 세 단계뿐 */
  --rule-hair: 1px solid var(--line-soft);
  --rule: 1px solid var(--line);
  --rule-strong: 1.5px solid var(--ink-sub);

  /* 모래 그림 */
  --sand-tile: url('/img/sand.jpg');
  --sand-tile-size: 320px;   /* 타일 원본 크기와 1:1 — 늘이면 알갱이가 뭉개진다 */
  /* 사구 띠 — 알갱이 위에 겹쳐 얹는 '그늘·빛 막'이라 반드시 알파가 있는 PNG 다.
     불투명 JPEG 으로 두면 이 띠가 깔린 위쪽 300px 의 알갱이를 통째로 덮어,
     위는 매끈하고 아래만 오돌토돌한 화면이 된다(만들다 겪었다). */
  --dune: url('/img/dune.png');
  --dune-sand: #E6D6B0;      /* 사구 띠 안쪽 모래색 — 이 위에 물결선이 드러난다 */
  --dune-edge: #C3B189;      /* 사구가 끝나는 선(뚜렷하게) */
  --dune-h: 52px;    /* 지평선 아래 모래 띠 — 얇게 */
}

/* 영어 화면 — 한글 파일(223 KB)을 아예 안 받는다 */
html[lang="en"] {
  --sans: 'Pretendard Latin', 'Sans Fallback', -apple-system, BlinkMacSystemFont,
          system-ui, 'Segoe UI', sans-serif;
}
/* 일본어 화면 — 라틴은 Pretendard, 가나·한자는 기기 글꼴(0 KB). 제목만 일본어 명조 */
html[lang="ja"] {
  --sans: 'Pretendard Latin', 'Hiragino Sans', 'Yu Gothic', 'Noto Sans JP',
          system-ui, sans-serif;
  --serif: 'Serif JA', 'Serif KR', 'Hiragino Mincho ProN', 'Yu Mincho', serif;
  --ls-display: 0; --ls-heading: 0; --ls-body: 0;   /* 가나는 좁히면 붙어 읽기 어렵다 */
}


/* ── 2. 바탕 ───────────────────────────────────────────────────────────── */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; font-size: 100%; }

body {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;      /* 짧은 페이지에서도 푸터가 화면 아래에 붙는다 */

  /* 노트 속지 — 질감은 아주 옅은 결만. 모래 타일은 지평선 아래 띠에서만 쓴다 */
  background-color: var(--sand);
  background-image: var(--paper-grain);
  background-repeat: repeat;
  background-size: 220px 220px, 260px 260px, 190px 190px, 230px 230px;

  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-400);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  font-weight: 400;
  font-optical-sizing: auto;
  font-synthesis-weight: none;   /* 가짜 굵은 글씨 금지 */
  overflow-wrap: break-word;     /* 긴 카탈로그 번호·URL 은 끊어도 된다 */
  -webkit-text-size-adjust: 100%;
}
/* 한글·영어는 단어 단위로 끊는다. 일본어는 띄어쓰기가 없어 이 값을 주면 줄바꿈이 안 된다 */
html[lang="ko"] body, html[lang="en"] body { word-break: keep-all; }

a { color: inherit; text-decoration: none; }
img { max-width: 100%; }
button, input, select, textarea { font: inherit; }

/* 표·제원의 숫자를 자릿수 맞춰 세로로 정렬 */
table, .spec, .quick, .magIn, .cnt, .ccCnt, .pager, time, [data-num] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* 제목은 명조 한 벌로 */
h1, h2, h3, h4,
h2.sec, .head h1, .hero h1, .railHead h2, .sbox h2, .guide h3, .ccName, .conRow {
  font-family: var(--serif);
  font-weight: 600;
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  text-wrap: balance;            /* 제목 끝줄에 한 단어만 남는 것을 막는다 */
}

/* 화면 폭 통일 */
.head, .hero, .wrap, .layout, .foot {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* 띠(메뉴·푸터 선)는 화면 끝까지 긋고, 안의 글자만 본문 선에 맞춘다.
   width:100% + margin-inline:0 을 꼭 되돌려야 한다 — body 가 세로 flex 라
   위 규칙의 margin-inline:auto 가 남아 있으면 띠가 글자 폭으로 쪼그라들고
   가운데로 몰린다(실측: 푸터 선이 화면 중앙 679px 만 그어졌다). */
.nav, .foot {
  max-width: none;
  width: 100%;
  margin-inline: 0;
  padding-inline: max(var(--gutter), calc((100% - var(--shell)) / 2 + var(--gutter)));
}


/* ── 3. 위쪽 밤하늘 ─────────────────────────────────────────────────────── */
.top {
  position: relative;
  overflow: hidden;
  color: var(--night-txt);
  /* 자바스크립트가 막혀도 하늘색은 남는다(캔버스가 이 위에 덮인다) */
  background: linear-gradient(180deg, var(--night-0) 0%, var(--night-1) 55%, var(--night-2) 100%);
}
/* 캔버스가 들어갈 자리 — nightsky.js 가 이 안에 <canvas> 두 장을 깐다 */
.stars { position: absolute; inset: 0; pointer-events: none; }

/* 어두운 바탕 위 글자는 얇게 그려야 번지지 않는다 */
.top, .top * { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

/* 메뉴 — 글자만 나열하지 않는다. 칸을 나눠 무엇이 있는지 한눈에 보이게 */
.nav {
  display: flex; align-items: stretch; gap: 0;
  position: relative; z-index: 3;
  padding: 0 32px; max-width: none;
  font-size: 14px;
  border-bottom: 1px solid rgba(96, 108, 160, .38);
  background: rgba(6, 9, 26, .35);
  backdrop-filter: blur(2px);
}
.logo { display: flex; align-items: center; gap: 9px; padding: 12px 0; white-space: nowrap; }
/* 이름표(로고) — 세 이름은 **하나의 고정 표식**이다.
   화면 언어를 무엇으로 골라도 글자도 모양도 바뀌지 않는다. 옮기지도 않는다(고유명사).
   한때 지금 언어만 진하게 하고 눌러서 언어를 바꾸게 했는데, 그러면 언어마다 모양이 달라져
   표식 노릇을 못 한다. 언어는 오른쪽 드롭다운이 맡고, 여기는 누르면 첫 화면으로 간다. */
.logoNames { display: flex; align-items: center; gap: 8px; }
.logoNames .ln {
  /* 글꼴도 못 박는다 — var(--serif) 는 화면 언어를 타서(Serif KR ↔ Serif JA)
     같은 '星見ノート' 가 언어마다 다른 모양으로 찍힌다. 표식은 늘 같은 획이라야 한다. */
  font-family: 'Serif JA', 'Serif KR', 'Nanum Myeongjo', Batang, serif;
  font-size: 17px; font-weight: 700;
  color: var(--gold); letter-spacing: .01em; line-height: 1.2;
}
/* 지금 언어인 이름만 또렷하게 — 나머지는 옅게 두어 눌러서 바꿀 수 있음을 알린다.
   (글자·글꼴·크기·색은 그대로다. 달라지는 것은 밝기뿐이고, 번역은 절대 되지 않는다.) */
.logoNames .ln { opacity: .5; transition: opacity .12s; border-bottom: 1px solid transparent; }
.logoNames .ln:hover { opacity: .9; border-bottom-color: rgba(255, 215, 106, .5); }
.logoNames .ln.on { opacity: 1; }
.logoNames .ln.on:hover { border-bottom-color: transparent; }
.logoNames i { font-style: normal; color: rgba(255, 215, 106, .42); font-size: 14px; }

.navLinks { display: flex; align-items: stretch; gap: 0; margin-left: auto; }
.nav .navLinks a {
  display: flex; align-items: center;
  padding: 0 18px; color: var(--night-sub); white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color .12s, background-color .12s;
}
.nav .navLinks a + a { box-shadow: inset 1px 0 0 rgba(120, 132, 180, .22); }
.nav .navLinks a:hover { color: #fff; background: rgba(255, 255, 255, .05); }
.nav .navLinks a.on {
  color: var(--gold); font-weight: 700;
  border-bottom-color: var(--gold); background: rgba(255, 215, 106, .07);
}
.navRight { display: flex; align-items: center; gap: 14px; margin-left: 20px; padding: 12px 0; }
.langSel {
  background: transparent; border: 1px solid rgba(120, 132, 180, .5); border-radius: var(--r-md);
  color: var(--night-sub); font-size: var(--fs-200); padding: 5px var(--s-2); cursor: pointer;
}
.langSel option { color: #222; }
.navToggle { display: none; background: none; border: 0; color: var(--night-sub); font-size: 20px; cursor: pointer; }

/* 페이지 머리 — 옛 26/30px 여백에 25px 제목이라 메뉴 띠와 키가 비슷해 '머리'로 안 읽혔다 */
.head { position: relative; z-index: 2; padding-block: var(--s-7) var(--s-8); }
.head h1 {
  font-size: var(--fs-800); line-height: var(--lh-display);
  color: #fff; margin-bottom: var(--s-3);
}
.head h1 small {
  font-family: var(--sans); font-size: var(--fs-300); font-weight: 400;
  letter-spacing: 0; color: var(--night-sub); margin-left: var(--s-3);
}
.head .sub { font-size: var(--fs-300); line-height: var(--lh-snug); color: var(--night-sub); max-width: 56ch; }
.head .chips { margin-top: var(--s-4); }

/* 지평선(모래 언덕) */
/* 사막여우 — 왼쪽 사구 능선 위. 장식이라 화면 낭독기에는 안 읽힌다 */
/* 여우와 망원경 — 왼쪽 사구 위에 나란히. 밤이라 어둡되 눈에는 띈다 */
.duo {
  position: absolute; z-index: 3;      /* 지평선(.wave, z-index 2) 보다 앞 */
  left: 8%; bottom: 26px;              /* 왼쪽 사구 능선 높이 */
  display: flex; align-items: flex-end; gap: 2px;
  pointer-events: none;
}
.fox {
  width: 41px; height: 34px;
  transform: scaleX(-1);          /* 머리를 오른쪽으로 — 곁의 망원경을 본다 */
  color: #8C7A56;
}
.scope {
  width: 39px; height: 42px;
  color: #8A7854;
}
.wave {
  display: block; width: 100%; height: 44px;
  position: relative; z-index: 2; margin-bottom: -1px;
  color: var(--dune-sand);      /* path fill=currentColor — 사구와 같은 모래색 */
}


/* ── 4. 본문(사막) ─────────────────────────────────────────────────────────
   알갱이(고주파)는 body 의 타일이, 지형(저주파)은 여기가 담당한다.
   지형을 타일에 넣으면 320px 마다 되풀이돼 도배지가 된다. */
.bodyk {
  flex: 1 0 auto;
  padding-bottom: var(--s-8);
  background-color: transparent;   /* 타일은 body 가 그린다 */
  /* 사구는 ::before 가 그린다 — 모래색·알갱이·물결을 한 겹에 담아야 물결이 보인다 */
}
/* 사구 띠 — 지평선 아래 모래. 카드 바로 위에서 선을 그으며 끝난다.
   (dune.png 는 물결선만 있는 반투명 그림이라, 여기서 모래색을 깔아 줘야 물결이 드러난다) */
.bodyk { position: relative; }
.bodyk::before {
  content: '';
  position: absolute; inset: 0 0 auto; height: var(--dune-h);
  background-color: var(--dune-sand);
  background-image:
    /* 바람이 판 물결 한 겹뿐 — 알갱이 타일을 겹치면 되풀이가 드러나 '타일 바닥'처럼 보인다 */
    var(--dune);
  background-repeat: repeat-x;
  background-size: auto 100%;
  background-position: 0 0;
  border-bottom: 1px solid var(--dune-edge);   /* 경계선 */
  /* 아래 끝에서 종이색으로 살짝 녹인다 — 모래와 종이가 맞닿는 선이 딱딱해 보이지 않게 */
  box-shadow: inset 0 -14px 14px -14px var(--sand);
  pointer-events: none;
  z-index: 0;
}
.bodyk > * { position: relative; z-index: 1; }
/* 사구 아래에서 본문 시작 — 첫 칸이 사구와 겹치면 내용이 모래에 잘려 보인다.
   칸 이름을 하나하나 적어 두면(옛날엔 .wrap·.layout 둘뿐이었다) 새 화면을 만들 때마다
   그 목록에 넣는 것을 잊어 겹친다. 그래서 **첫 자식이면 무엇이든** 띄운다. */
/* 숨긴 것은 반드시 사라진다 — .pExp·.selBar 처럼 display:flex 를 준 칸은
   [hidden] 을 걸어도 기본 규칙(display:none)을 이겨 **빈 박스가 자리를 차지**했다. */
[hidden] { display: none !important; }

.bodyk > :first-child { padding-top: calc(var(--dune-h) + var(--s-5)); }

.wrap { padding-block: var(--s-5) 0; }


/* ── 5. 게시판 괘선 ────────────────────────────────────────────────────────
   옛 h2.sec 는 padding-top 22px 으로 간격을 흉내 내고 :first-child 로 다시 지웠다.
   간격은 margin 이 맡고 padding 은 밑줄까지의 거리만 맡는다. */
h2.sec {
  display: flex; align-items: baseline; gap: var(--s-3);
  font-size: var(--fs-700);
  line-height: var(--lh-heading);
  color: var(--ink);
  margin: var(--s-7) 0 0;
  padding: 0 2px var(--s-3);
  border-bottom: var(--rule-strong);
}
h2.sec:first-child,
.wrap > h2.sec:first-of-type,
.main > h2.sec:first-of-type { margin-top: var(--s-6); }
h2.sec .sub2 {
  font-family: var(--sans); font-size: var(--fs-200); font-weight: 400;
  letter-spacing: 0; color: var(--ink-dim);
}
h2.sec .tail {
  font-family: var(--sans); font-size: var(--fs-200); font-weight: 600; letter-spacing: 0;
  margin-left: auto; color: var(--red-ink); cursor: pointer;
  padding-bottom: 2px; border-bottom: 1px solid transparent;
}
h2.sec .tail:hover { border-bottom-color: currentColor; }
/* 제목 바로 아래 첫 덩어리와의 거리 */
h2.sec + * { margin-top: var(--s-4); }
h2.sec + .row, h2.sec + table.list, h2.sec + div > .row:first-child { margin-top: 0; }

/* 목록 줄 — 11px 위아래 여백은 폰(손가락) 기준이다. PC 는 눈으로 훑으므로 줄을 키운다 */
.row {
  display: flex; align-items: center; gap: var(--s-4);
  padding: var(--s-4) 2px;
  font-size: var(--fs-300); line-height: var(--lh-snug);
  border-bottom: var(--rule-hair);
  transition: background-color .1s;
}
.row:hover { background: rgba(154, 70, 50, .055); }   /* 옛 흰 물칠 → 인주 연한 톤 */
.row b { font-weight: 600; }
a.row { color: inherit; }
.muted { color: var(--ink-dim); font-size: var(--fs-200); line-height: var(--lh-snug); }
.row .muted { font-size: var(--fs-300); }


/* ── 6. 단추 · 칩 · 입력칸 ─────────────────────────────────────────────────
   옛날엔 .btn / .hb / .cta .big / .store / .pickBar button / .tail / .fmore 일곱 가지가
   제각각 반경(6~12px)과 크기를 갖고 있었다. 한 벌로 모은다. */
.btn, .hb, .pickBar button {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  border-radius: var(--r-md);
  padding: 10px var(--s-5);
  min-height: 40px;
  font-size: var(--fs-300); font-weight: 600; line-height: var(--lh-snug);
  cursor: pointer;
  transition: background-color .12s, border-color .12s;
}
.btn { border: 1px solid var(--line); background: rgba(255, 255, 255, .28); color: var(--ink); }
.btn:hover { background: rgba(255, 255, 255, .55); border-color: var(--ink-dim); }
.btn.primary { background: var(--red); border-color: var(--red); color: var(--paper); font-weight: 700; }
.btn.primary:hover { background: #8b3f2d; }

/* 칩 — 알약은 꼬리표 성격이라 그대로 두되, 흰 물칠을 빼고 높이를 맞춘다 */
.chips, .chips2 { display: flex; flex-wrap: wrap; gap: var(--s-2); padding-block: var(--s-4) var(--s-1); }
.chip, .memberChip {
  display: inline-block;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 7px var(--s-4);
  font-size: var(--fs-300); line-height: 1.3;
  background: transparent; color: var(--ink);
}
.chip:hover, .memberChip:hover { background: rgba(255, 255, 255, .45); border-color: var(--ink-dim); }
.memberChip { margin: 0 var(--s-1) var(--s-1) 0; }

/* 입력칸 */
.srch, .nameIn {
  display: inline-flex; align-items: center; gap: var(--s-2);
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: rgba(255, 255, 255, .34);
  padding: 9px var(--s-3);
  font-size: var(--fs-300); color: var(--ink-dim);
}
.srch input, .nameIn input {
  border: 0; background: transparent; outline: none;
  font-size: var(--fs-300); color: var(--ink); width: 100%;
}


/* ── 7. 푸터 ──────────────────────────────────────────────────────────────── */
.foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-5);
  border-top: var(--rule);
  padding-block: var(--s-6) var(--s-8);
  font-size: var(--fs-200); line-height: var(--lh-snug);
  color: var(--ink-dim);
}
.foot .right { margin-left: auto; }
.foot a { text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: 1px; }


/* ── 8. 홈 ────────────────────────────────────────────────────────────────
   ※ .hero 는 flex 를 유지해야 한다 — 앱 설명서를 펼칠 때 index.html 의 스크립트가
     .heroSide 의 width 를 직접 바꾼다. grid 로 바꾸면 그 폭이 먹히지 않는다. */
.hero {
  display: flex; align-items: flex-start; gap: var(--s-8);
  padding-block: var(--s-8) var(--s-9);
  position: relative; z-index: 2;
}
.hero-txt { flex: 1 1 0; min-width: 0; }
.hero h1 {
  font-size: var(--fs-900);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: #fff;
  margin-bottom: var(--s-4);
}
.hero h1 .us { color: var(--gold); }
.hero .heroLead {
  font-family: var(--serif); font-size: var(--fs-600); font-weight: 600;
  color: var(--gold); letter-spacing: .01em;
  margin: 0 0 var(--s-4);
}
.heroDesc {
  font-size: var(--fs-400); line-height: var(--lh-prose);
  color: var(--night-sub); max-width: 90%;
  margin-bottom: var(--s-6);
  text-wrap: pretty;
}
.cta { display: flex; gap: var(--s-3); margin-bottom: var(--s-5); flex-wrap: wrap; }
.cta .big, .cta .subBtn {
  padding: 14px var(--s-6); border-radius: var(--r-md);
  font-size: var(--fs-400); line-height: var(--lh-snug);
}
.cta .big { background: var(--gold); color: #1a1f3d; font-weight: 700; }   /* 옛 노란 광채 제거 */
.cta .big:hover { background: #ffe08a; }
.cta .subBtn {
  background: rgba(255, 255, 255, .06); color: var(--night-txt);
  border: 1px solid #4a5382; font-weight: 600;
}
.cta .subBtn:hover { background: rgba(255, 255, 255, .12); }
.storeline { font-size: var(--fs-200); font-weight: 700; color: var(--night-txt); margin-bottom: var(--s-3); }
.btns { display: flex; gap: var(--s-2); }
.store { padding: 9px var(--s-4); border-radius: var(--r-md); font-size: var(--fs-200); font-weight: 600; }
.store.g { background: var(--gold); color: #1a1f3d; }
.store.a { background: transparent; color: var(--night-txt); border: 1px solid #4a5382; }
.phone { width: 300px; flex-shrink: 0; padding: var(--s-2); border-radius: 22px; background: #1a1f3d; box-shadow: 0 18px 40px rgba(0, 0, 0, .45); }
.phone img { display: block; width: 100%; height: auto; border-radius: 16px; }

/* 지평선 빛 — 이제 nightsky.js 가 캔버스에 함께 그린다. 두 번 겹치면 띠가 생겨 숨긴다 */
.horizonGlow { display: none; }

/* 홈 카드 3개 — 둥근 반투명 카드가 앱 티의 절반이었다.
   채움·테두리·반경을 빼고 각 단의 머리에 굵은 선을 그어 신문 단처럼 세운다 */
.cards {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--s-6); margin-top: var(--s-6);
}
.card {
  display: block; color: inherit;
  background: none; border: 0; border-radius: 0;
  border-top: 2px solid var(--ink-sub);
  padding: var(--s-4) 0 var(--s-2);
}
.card b {
  display: inline-block;
  font-family: var(--serif); font-size: var(--fs-600); font-weight: 600;
  color: var(--ink); margin-bottom: var(--s-3);
  border-bottom: 1px solid transparent;
}
.card:hover b { color: var(--red-ink); border-bottom-color: currentColor; }
.card span {
  display: block;
  font-size: var(--fs-300); line-height: var(--lh-body);
  color: var(--ink-sub); max-width: 34ch;
}

/* 앱 설명서 — 평소엔 제목 줄만, 누르면 이 자리에서 넓게 펼친다 */
.heroSide { flex: none; width: 340px; display: flex; flex-direction: column; gap: var(--s-4); align-self: flex-start; transition: width .2s ease; }
.heroSide.open { width: 840px; }
.storeBox { padding-top: 2px; }

/* 내 폰 앱과 연동 — 제작 2(페어링) 자리 */
.linkBox {
  border: 1px dashed rgba(120, 132, 180, .5);
  padding: 14px 16px; background: rgba(255, 255, 255, .03);
}
.linkTitle { font-family: var(--serif); font-size: 14.5px; color: var(--gold); font-weight: 700; margin-bottom: 7px; }
.linkDesc { font-size: 13px; line-height: 1.7; color: var(--night-dim); margin-bottom: 11px; }
.linkBtn {
  border-color: rgba(120, 132, 180, .55); background: rgba(255, 255, 255, .06);
  color: var(--night-sub); font-size: 12px;
}
.linkBtn:hover { background: rgba(255, 255, 255, .12); color: #fff; }
/* 앱 설명서 제목 앞 앱 아이콘 */
.agIcon { width: 51px; height: 51px; border-radius: 8px; flex-shrink: 0; box-shadow: 0 2px 8px rgba(0,0,0,.35); }
.appGuide {
  width: 100%;
  background: rgba(255, 255, 255, .045);
  border: 1px solid rgba(120, 132, 180, .38);
  border-radius: var(--r-md); overflow: hidden;
  backdrop-filter: blur(3px);
}
.agHead {
  width: 100%; display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-4) var(--s-5); background: none; border: 0; cursor: pointer;
  text-align: left; color: inherit;
}
.agHead:hover { background: rgba(255, 255, 255, .05); }
.agHead h2 { font-family: var(--serif); font-size: var(--fs-500); color: var(--gold); font-weight: 600; line-height: 1.35; }
.agCaret { margin-left: auto; color: var(--night-dim); font-size: var(--fs-200); transition: transform .18s ease; }
.appGuide.open .agCaret { transform: rotate(180deg); }
.appGuide.open .agHead { border-bottom: 1px solid rgba(120, 132, 180, .3); }
.agBody { display: flex; align-items: stretch; }
.agBody[hidden] { display: none; }
.agNav {
  width: 190px; flex-shrink: 0; padding: var(--s-2) 0;
  border-right: 1px solid rgba(120, 132, 180, .28);
  display: flex; flex-direction: column;
}
.agNav button {
  text-align: left; background: none; border: 0; cursor: pointer;
  color: var(--night-sub); font-size: var(--fs-300); padding: 9px var(--s-4);
  border-left: 2px solid transparent; line-height: 1.4;
}
.agNav button:hover { color: #fff; background: rgba(255, 255, 255, .05); }
.agNav button.on { color: var(--gold); font-weight: 700; border-left-color: var(--gold); background: rgba(255, 215, 106, .09); }
.agPane { flex: 1; min-width: 0; padding: var(--s-5); display: flex; gap: var(--s-5); }
.agPane.empty { align-items: center; justify-content: center; color: var(--night-dim); font-size: var(--fs-300); text-align: center; padding: var(--s-7) var(--s-5); }
.agText { flex: 1; min-width: 0; }
.agText h3 { font-family: var(--serif); font-size: var(--fs-600); color: #fff; margin-bottom: var(--s-3); }
.agText p { font-size: var(--fs-300); line-height: var(--lh-prose); color: var(--night-sub); margin-bottom: var(--s-3); }
.agText ul { list-style: none; font-size: var(--fs-300); line-height: var(--lh-prose); color: var(--night-sub); }
.agText li { padding-left: var(--s-3); position: relative; }
.agText li::before { content: '·'; position: absolute; left: 3px; color: var(--gold); }
.agShot {
  width: 280px; flex-shrink: 0; border-radius: var(--r-md); overflow: hidden;
  background: #11162e; border: 1px solid rgba(120, 132, 180, .35); align-self: flex-start;
}
.agShot img { display: block; width: 100%; height: auto; }


/* ── 9. 도감(찾아보기) ────────────────────────────────────────────────────── */
.searchBar {
  display: flex; align-items: center; gap: var(--s-3);
  background: rgba(255, 255, 255, .07); border: 1px solid #4a5382; border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4); margin-top: var(--s-5); max-width: 640px;
}
.searchBar .q { font-size: var(--fs-500); color: var(--night-dim); }
.searchBar input {
  flex: 1; border: 0; background: transparent; outline: none;
  font-size: var(--fs-400); color: var(--night-txt);
}
.searchBar input::placeholder { color: var(--night-dim); }

.layout { display: flex; gap: var(--s-7); align-items: flex-start; padding-block: var(--s-5) 0; }

/* 왼쪽 필터 단 — 250px 짜리 둥근 상자를 없애고 두 단을 가르는 괘선만 남긴다 */
.rail {
  width: var(--rail-w); flex-shrink: 0;
  position: sticky; top: var(--s-5);
  background: none; border: 0; border-right: var(--rule); border-radius: 0;
  padding: 0 var(--s-6) var(--s-7) 0;
  max-height: calc(100vh - var(--s-8)); overflow-y: auto;
}
.railHead { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--s-4); }
.railHead h2 { font-size: var(--fs-600); color: var(--ink); }
.railHead a { font-size: var(--fs-100); color: var(--ink-dim); cursor: pointer; border-bottom: 1px solid transparent; }
.railHead a:hover { border-bottom-color: currentColor; }
.fg { border-top: var(--rule-hair); padding-block: var(--s-4); }
.fg:first-of-type { border-top: 0; padding-top: 0; }
.fg h3 {
  font-family: var(--sans); font-size: var(--fs-100); font-weight: 700;
  letter-spacing: var(--ls-caps); color: var(--ink-dim); margin-bottom: var(--s-2);
}
.fitem {
  display: flex; align-items: center; gap: var(--s-3);
  font-size: var(--fs-300); line-height: var(--lh-snug); color: var(--ink);
  padding: 7px 0; cursor: pointer;                 /* 누르는 높이 ≈ 32px */
}
.fitem:hover { color: var(--red-ink); }
.fitem .cnt { margin-left: auto; font-size: var(--fs-100); color: var(--ink-dim); }
.cb, .rb { width: 16px; height: 16px; border: 1.4px solid var(--line); display: inline-block; position: relative; flex-shrink: 0; }
.cb { border-radius: var(--r-sm); }
.rb { border-radius: 50%; }
.cb.on { background: var(--red); border-color: var(--red); }
.cb.on::after { content: '✓'; color: var(--paper); font-size: 11px; position: absolute; left: 2px; top: -1px; }
.rb.on::after { content: ''; position: absolute; inset: 3px; border-radius: 50%; background: var(--red); }
.magRow { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-300); color: var(--ink-sub); }
.magIn {
  width: 64px; border: 1px solid var(--line); border-radius: var(--r-sm); padding: 6px var(--s-2);
  font-size: var(--fs-300); background: rgba(240, 230, 205, .8); color: var(--ink); text-align: center;
}
.fmore {
  display: inline-block; font-size: var(--fs-100); font-weight: 600; color: var(--red-ink);
  margin-top: var(--s-1); cursor: pointer; border-bottom: 1px solid transparent;
}
.fmore:hover { border-bottom-color: currentColor; }

.main { flex: 1; min-width: 0; padding-bottom: var(--s-7); }
.resultLine { display: flex; align-items: baseline; gap: var(--s-4); margin-bottom: var(--s-5); flex-wrap: wrap; }
.resultLine .sum { font-size: var(--fs-500); color: var(--ink); }
.resultLine .sum b { color: var(--red-ink); }
.sortSel {
  margin-left: auto; font-size: var(--fs-300); color: var(--ink-sub);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 7px var(--s-3);
  background: rgba(240, 230, 205, .8); cursor: pointer;
}

/* 별자리 칸 — 4칸 고정이라 넓은 화면에서 글자 하나에 300px 을 썼다 */
.grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--s-3); margin-bottom: var(--s-4);
}
.cc {
  display: block; color: inherit; cursor: pointer;
  background: rgba(255, 255, 255, .22); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s-3) var(--s-4);
}
.cc:hover { background: rgba(255, 255, 255, .5); border-color: var(--ink-dim); }
.cc.on { border-color: var(--red); background: rgba(154, 70, 50, .08); }
.ccName { font-size: var(--fs-300); color: var(--ink); margin-bottom: 2px; }
.ccCnt { font-size: var(--fs-100); color: var(--ink-dim); }

/* 표 — 사이트에서 가장 오래 보는 화면. 여기가 작으면 사이트 전체가 작아 보인다 */
table.list { width: 100%; border-collapse: collapse; font-size: var(--fs-300); border-top: var(--rule-strong); }
table.list thead th {
  text-align: left; font-size: var(--fs-100); font-weight: 700;
  letter-spacing: var(--ls-caps); color: var(--ink-dim);
  padding: var(--s-3); border-bottom: var(--rule); white-space: nowrap; cursor: pointer;
}
table.list thead th:hover { color: var(--red-ink); }
table.list thead th.sorted { color: var(--red-ink); }
table.list tbody td { padding: var(--s-3); border-bottom: var(--rule-hair); color: var(--ink); line-height: var(--lh-snug); }
table.list tbody tr { cursor: pointer; }
table.list tbody tr:hover td { background: rgba(154, 70, 50, .055); }
table.list .tName { font-weight: 600; }
.tName b { color: var(--red-ink); }
.tAlt { font-weight: 600; color: var(--ink); text-align: right; }
/* 숫자 칸은 자릿수 고정폭 — 위아래로 자리가 흔들리지 않게 */
table.list td:nth-last-child(-n+3), table.list th:nth-last-child(-n+3) { font-variant-numeric: tabular-nums; }

.pager { text-align: center; padding: var(--s-5) 0 0; font-size: var(--fs-300); color: var(--ink-dim); }
.pager b { color: var(--red-ink); }
.pager span, .pager b { display: inline-block; min-width: 32px; padding: 6px var(--s-2); }
.pager span { cursor: pointer; }
.pager span:hover { color: var(--red-ink); background: rgba(154, 70, 50, .08); border-radius: var(--r-sm); }


/* ── 10. 천체 상세 ────────────────────────────────────────────────────────── */
.crumb { font-size: var(--fs-200); color: var(--night-dim); margin-bottom: var(--s-4); letter-spacing: 0; }
.crumb a:hover { color: var(--night-txt); }
.chip2 {
  display: inline-block;
  font-size: var(--fs-100); padding: 5px var(--s-3); border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .08); border: 1px solid #4a5382; color: var(--night-txt);
}
.chip2.alt { color: var(--gold); border-color: rgba(255, 215, 106, .45); }
.quick { font-size: var(--fs-300); line-height: var(--lh-body); color: var(--night-sub); margin-top: var(--s-4); }
.quick b { color: #fff; }
.headBtns { display: flex; gap: var(--s-3); margin-top: var(--s-6); flex-wrap: wrap; }
.hb { border: 1px solid #4a5382; background: rgba(255, 255, 255, .06); color: var(--night-txt); }
.hb.p { background: var(--gold); border-color: var(--gold); color: #1a1f3d; font-weight: 700; }
.hb.p:hover { background: #ffe08a; }
.hb.s:hover { background: rgba(255, 255, 255, .12); }

.cols { display: flex; gap: var(--s-8); align-items: flex-start; }
.colMain { flex: 1; min-width: 0; }
.colMain > * + * { margin-top: var(--s-7); }
.colSide { width: var(--side-w); flex-shrink: 0; }

/* 오른쪽 곁상자 — 상자를 벗기고 제목 밑줄로 구분한다 */
.sbox { background: none; border: 0; border-radius: 0; padding: 0; margin-bottom: var(--s-7); }
.sbox h2 {
  font-family: var(--sans); font-size: var(--fs-100); font-weight: 700;
  letter-spacing: var(--ls-caps); color: var(--ink-dim);
  margin-bottom: var(--s-3); padding-bottom: var(--s-2); border-bottom: var(--rule);
}
table.spec { width: 100%; border-collapse: collapse; font-size: var(--fs-300); }
table.spec td { padding: 7px 0; border-bottom: var(--rule-hair); color: var(--ink); vertical-align: top; line-height: var(--lh-snug); }
table.spec td:first-child { color: var(--ink-dim); width: 42%; letter-spacing: 0; }
table.spec td:last-child { font-variant-numeric: tabular-nums; }
table.spec tr:last-child td { border-bottom: none; }

/* 안시 가이드 — 이 사이트에서 가장 오래 읽는 글. 산문만 좁힌다 */
.guide {
  font-size: var(--fs-400); line-height: var(--lh-prose);
  color: var(--ink); max-width: var(--measure); padding: 0;
}
.guide p { margin: 0 0 var(--s-5); text-wrap: pretty; }
.guide h3 {
  font-size: var(--fs-600); color: var(--ink);
  margin: var(--s-7) 0 var(--s-4); padding-bottom: var(--s-2); border-bottom: var(--rule-hair);
}
.guide > h3:first-child { margin-top: 0; }
.guide b, .guide strong { font-weight: 700; color: #1f1a12; }
.guide a, .pt a {
  text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: 1px;
  color: var(--red-ink);
}
.pt {
  display: flex; gap: var(--s-3);
  padding: var(--s-4) 2px; border-bottom: var(--rule-hair);
  font-size: var(--fs-300); line-height: var(--lh-body); color: var(--ink);
  max-width: var(--measure);
}
.pt .n { color: var(--red-ink); font-weight: 700; flex-shrink: 0; font-variant-numeric: tabular-nums; }


/* ── 11. 추천 ─────────────────────────────────────────────────────────────── */
.skyline { font-size: var(--fs-300); color: var(--night-sub); margin-top: var(--s-4); }
.skyline b { color: var(--gold); }
.lv {
  display: inline-block; font-size: var(--fs-100); font-weight: 700;
  padding: 2px var(--s-2); border-radius: var(--r-sm);
  white-space: nowrap; border: 1px solid; line-height: 1.5;
}
.lv.exp { background: rgba(154, 70, 50, .14); color: var(--red-ink); border-color: rgba(154, 70, 50, .5); }
.lv.walk { background: rgba(90, 81, 66, .12); color: var(--ink-sub); border-color: var(--line); }
.lv.deep { background: rgba(40, 50, 90, .1); color: #3c4670; border-color: #99a0bd; }


/* ── 12. 목록 · 계획 ──────────────────────────────────────────────────────── */
.tag {
  display: inline-block;
  font-size: var(--fs-100); font-weight: 700; line-height: 1.5;
  padding: 2px var(--s-2); border-radius: var(--r-sm); margin-left: var(--s-2);
  border: 1px solid var(--line); color: var(--ink-dim); vertical-align: middle;
}
.tag.mine { color: var(--red-ink); border-color: rgba(154, 70, 50, .5); }
.tag.preset { color: #3c4670; border-color: #99a0bd; }
.rmX { color: var(--ink-dim); cursor: pointer; padding: var(--s-1) var(--s-2); font-size: 1rem; }
.rmX:hover { color: var(--red); }
.draftBar { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; padding: var(--s-4) 0 var(--s-2); }
.draftBar .grow { flex: 1; }
.nameIn .lb { font-size: var(--fs-200); color: var(--ink-dim); white-space: nowrap; }
.nameIn input { width: 220px; }
.conRow {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-4) 2px var(--s-3); margin-top: var(--s-5);
  border-bottom: var(--rule);
  font-size: var(--fs-600); color: var(--ink);
}
.conRow .cnt { font-family: var(--sans); font-size: var(--fs-100); color: var(--red-ink); font-weight: 700; }
.planRow a { color: inherit; }
.planRow a:hover b { color: var(--red-ink); }


/* ── 13. 담기 액션 바 ─────────────────────────────────────────────────────── */
.pickBar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  background: rgba(46, 40, 32, .95); color: var(--paper);
  display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap;
  padding-block: var(--s-3);
  padding-inline: max(var(--gutter), calc((100% - var(--shell)) / 2 + var(--gutter)));
  box-shadow: 0 -2px 12px rgba(0, 0, 0, .2);
  font-size: var(--fs-300);
}
.pickBar .n { font-weight: 700; color: var(--gold); font-variant-numeric: tabular-nums; }
.pickBar .grow { flex: 1; }
.pickBar button { border: 1px solid rgba(240, 230, 205, .5); background: transparent; color: var(--paper); }
.pickBar button:hover { background: rgba(255, 255, 255, .12); }
.pickBar button.go { background: var(--gold); border-color: var(--gold); color: #2b2418; font-weight: 700; }
.pickBar button.go:hover { background: #ffe08a; }
.pickCell { width: 36px; }
.pickBox {
  width: 16px; height: 16px; border: 1.4px solid var(--line); border-radius: var(--r-sm);
  display: inline-block; position: relative; cursor: pointer; vertical-align: middle;
}
.pickBox.on { background: var(--red); border-color: var(--red); }
.pickBox.on::after { content: '✓'; color: var(--paper); font-size: 11px; position: absolute; left: 2px; top: -2px; }


/* ── 14. 상태 표현 · 접근성 ───────────────────────────────────────────────────
   옛 파일은 입력칸 세 곳에서 outline:none 만 하고 대체 표시를 안 넣어,
   키보드로 다니면 지금 어디에 있는지 알 수 없었다. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
.top :where(a, button, input, select):focus-visible { outline-color: var(--gold); }
.srch:focus-within, .nameIn:focus-within { outline: 2px solid var(--red); outline-offset: 1px; }
.searchBar:focus-within { outline: 2px solid var(--gold); outline-offset: 1px; }

/* 카탈로그 번호·좌표는 고정폭으로 — 자릿수가 눈에 들어온다 */
.desig, .coord, code, kbd {
  font-family: var(--mono); font-size: 0.94em; letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  html { scroll-behavior: auto; }
}


/* ── 15. 반응형 ────────────────────────────────────────────────────────────
   옛 파일은 끊는 지점이 860 / 1000 / 1240 으로 갈려, 그 사이 폭(예: 900px)에서
   머리는 좁은 여백(16px)·본문은 넓은 여백(32px)이 되어 좌우 선이 어긋났다.
   여백을 --gutter 하나로 모으고 끊는 지점을 한 벌(1600/1200/980/640)로 맞춘다. */

@media (min-width: 1600px) {
  :root { --shell: 1360px; --rail-w: 288px; --side-w: 340px; }
}

@media (max-width: 1200px) {
  :root { --gutter: var(--s-5); }
  .heroSide, .heroSide.open { width: 100%; }
  .hero { flex-direction: column; }
}

@media (max-width: 980px) {
  .layout, .cols { flex-direction: column; gap: var(--s-6); }
  .rail {
    width: 100%; position: static; max-height: none;
    border-right: 0; border-bottom: var(--rule); padding: 0 0 var(--s-5);
  }
  .colSide { width: 100%; }
  .colMain > * + * { margin-top: var(--s-6); }
  .cards { grid-template-columns: 1fr 1fr; gap: var(--s-5); }
  .head { padding-block: var(--s-6) var(--s-7); }
  .hero { padding-block: var(--s-6) var(--s-7); gap: var(--s-6); }
  .phone { width: 240px; align-self: center; }
}

@media (max-width: 640px) {
  :root {
    --gutter: 20px;             /* 옛 16px 은 글자가 화면 끝에 붙어 답답했다 */
    --fs-400: 1rem;             /* 16px — 이보다 작으면 사파리가 입력칸에서 화면을 확대한다 */
    --fs-300: 0.9375rem;
    --lh-prose: 1.82;
    --measure: 100%;
    --dune-h: 200px;
  }
  .nav { flex-wrap: wrap; align-items: center; }
  .logo { padding: 10px 0; }
  .logoNames .ln { font-size: var(--fs-400); }
  .nav .navLinks a { padding: var(--s-2) 0; }
  .nav .navLinks a + a { box-shadow: none; }
  .navToggle { display: block; order: 2; margin-left: auto; }
  .nav .navLinks { display: none; order: 4; width: 100%; flex-direction: column; gap: var(--s-3); padding: var(--s-2) 0 var(--s-1); }
  .nav .navLinks.open { display: flex; }
  .navRight { order: 3; margin-left: var(--s-3); }
  .cards { grid-template-columns: 1fr; gap: var(--s-5); }
  .card { padding-bottom: 0; }
  .cta { flex-direction: column; align-items: stretch; }
  .cta .big, .cta .subBtn { text-align: center; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  table.list { font-size: var(--fs-200); }
  table.list thead th, table.list tbody td { padding: var(--s-3) var(--s-2); }
  table.list .hideSm { display: none; }
  h2.sec { margin-top: var(--s-6); }
  .heroDesc { max-width: none; }
  .agBody { flex-direction: column; }
  .agNav { width: 100%; flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid rgba(120, 132, 180, .28); }
  .agNav button { border-left: 0; border-bottom: 2px solid transparent; white-space: nowrap; }
  .agNav button.on { border-left: 0; border-bottom-color: var(--gold); }
  .agPane { flex-direction: column; }
  .agShot { width: 100%; max-width: 220px; align-self: center; }
  .pickBar { padding-inline: var(--s-4); }
}


/* ── 16. 인쇄 — 관측 계획을 종이에 뽑아 들고 나가는 사람이 있다 ─────────────── */
@media print {
  body { background: #fff; color: #000; font-size: 11pt; line-height: 1.6; display: block; }
  .top, .nav, .pickBar, .foot, .rail { display: none !important; }
  .bodyk { background: none; }
  .layout, .cols { display: block; }
  h2.sec { font-size: 14pt; }
  a { text-decoration: none; }
}


/* ── 노트 손질 ────────────────────────────────────────────────────────────
   개인이 쓰는 기록 노트의 인상 — 종이 위에 자로 그은 선, 도장처럼 찍힌 강조,
   각진 모서리(둥근 앱 카드가 아니라 종이에 그린 상자). */

/* 칸(카드·박스) — 그림자 없이 얇은 선과 종이 톤만 */
.card, .sbox, .rail, .cc, .linkBox, .appGuide {
  border-radius: 3px;
  box-shadow: none;
}
.card, .sbox, .cc { background: rgba(255, 255, 255, .55); border-color: var(--line); }
.rail { background: rgba(255, 255, 255, .45); }

/* 단추 — 종이에 그린 네모. 눌리면 살짝 눌러 앉는다 */
.btn, .sortSel, .magIn, .nameIn, .srch {
  border-radius: 3px;
  background: rgba(255, 255, 255, .62);
  border-color: var(--line);
}
.btn:hover { background: #fff; border-color: var(--ink-dim); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--red); border-color: var(--red); color: #fff; }

/* 칩 — 종이 라벨 */
.chip, .memberChip, .chip2, .tag { border-radius: 3px; }

/* 표 — 노트 괘선. 머리줄만 진하게 긋고 나머지는 옅게 */
table.list { border-top-width: 2px; border-top-color: var(--ink-sub); }
table.list thead th { border-bottom: 1.5px solid var(--line); background: rgba(255, 255, 255, .35); }
table.list tbody td { border-bottom: 1px solid var(--line-soft); }
table.list tbody tr:hover td { background: rgba(255, 255, 255, .6); }

/* 섹션 제목 — 노트에 제목 쓰고 밑줄 긋듯 */
h2.sec { border-bottom-width: 2px; border-bottom-color: var(--ink-sub); }

/* 행 구분 — 공책 줄 */
.row { border-bottom-color: var(--line-soft); }
.row:hover { background: rgba(255, 255, 255, .5); }

/* ── 홈 미니 게시판 — 들어올 때마다 달라지는 것을 바로 보여 준다 ────────── */
.boards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-top: 4px; }
@media (max-width: 1150px) { .boards { grid-template-columns: repeat(2, 1fr); } }

/* 검색 게시판 — 도감 필터의 축약판 */
.bsQ {
  width: 100%; box-sizing: border-box;
  font-family: inherit; font-size: var(--fs-200); color: var(--ink);
  background: rgba(255, 255, 255, .62); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 8px 10px; margin-bottom: 6px;
}
.bsQ:focus { outline: none; border-color: var(--red); }
.bsFilters { display: flex; gap: 6px; margin-bottom: 4px; }
.bsFilters select {
  flex: 1; min-width: 0;
  font-family: inherit; font-size: var(--fs-100); color: var(--ink-sub);
  background: rgba(255, 255, 255, .62); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 5px 4px;
}
.board {
  background: rgba(255, 255, 255, .5);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 12px 14px 10px;
  display: flex; flex-direction: column;
  min-height: 168px;
}
.board h2 {
  font-family: var(--serif); font-size: 15.5px; color: var(--ink);
  display: flex; align-items: baseline; gap: 7px;
  padding-bottom: 7px; margin-bottom: 6px;
  border-bottom: 1.5px solid var(--ink-sub);
}
.board h2 a { color: inherit; }
.board h2 a:hover { color: var(--red); }
.bCount { font-family: var(--sans); font-size: 12px; font-weight: 700; color: var(--red); }
.bBody { flex: 1; }
.bRow {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 1px; border-bottom: 1px solid var(--line-soft);
  font-size: 13.5px; color: var(--ink);
}
.bRow:last-child { border-bottom: 0; }
.bRow:hover { background: rgba(255, 255, 255, .7); }
.bName { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bSide { color: var(--ink-dim); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.bEmpty { font-size: 12.5px; line-height: 1.75; color: var(--ink-dim); padding: 6px 1px; }
.bRest { font-size: 12px; color: var(--ink-dim); padding: 5px 1px 0; }
.bMore { font-size: 12.5px; color: var(--red); font-weight: 700; padding-top: 8px; align-self: flex-start; }
.bMore:hover { text-decoration: underline; }

@media (max-width: 900px) { .boards { grid-template-columns: 1fr; } }

/* ── 관측 기록(나눔터) ─────────────────────────────────────────────────── */
.recTabs { display: flex; gap: 0; border-bottom: 1.5px solid var(--line); margin-top: var(--s-2); }
.recTabs button {
  background: none; border: 0; cursor: pointer; font-family: inherit;
  font-size: var(--fs-300); color: var(--ink-dim);
  padding: 10px 18px; border-bottom: 2px solid transparent; margin-bottom: -1.5px;
}
.recTabs button:hover { color: var(--ink); }
.recTabs button.on { color: var(--red); font-weight: 700; border-bottom-color: var(--red); }

.soonGrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-6); margin-top: var(--s-5); }
/* 아직 열지 않은 자리 — 카드와 같은 결(위쪽 선)이되, 준비 중이라 선과 글자를 옅게 */
.soonCard { padding: var(--s-4) 0 var(--s-2); border-top: 2px solid var(--line); }
.soonCard b {
  display: block; font-family: var(--serif); font-size: var(--fs-500); font-weight: 600;
  color: var(--ink-sub); margin-bottom: var(--s-3);
}
.soonCard span { display: block; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--ink-dim); }

@media (max-width: 900px) { .soonGrid { grid-template-columns: 1fr; gap: var(--s-4); } }

/* ── 천체 상세 — 이전/다음 걷기 · 칩 강조 ── */
.objNav { display: flex; align-items: center; gap: 10px; margin: 4px 0 8px; }
.onBtn {
  font-size: var(--fs-200); color: var(--gold); cursor: pointer;
  border: 1px solid rgba(255, 215, 106, .35); border-radius: var(--r-sm); padding: 3px 12px;
}
.onBtn:hover { background: rgba(255, 215, 106, .12); }
.onBtn.off { opacity: .3; cursor: default; border-color: transparent; }
.onPos { font-size: var(--fs-100); color: var(--night-sub); }
.chip2[data-copy] { cursor: pointer; }
.chip2.sky { border: 1px solid var(--gold); }
/* 추천 표 — 필터 필수 배지 */
.fneed {
  font-size: var(--fs-100); color: var(--red); border: 1px solid var(--red);
  border-radius: var(--r-sm); padding: 0 5px; white-space: nowrap;
}

/* ==== patch:catalog ==== */
/* 천체 도감 — style.css 에 없는 것만.
   다른 페이지로 새지 않게 본문 것은 #catPage 안에 두고, 이름도 ct- 로 시작한다.
   (머리말 밑 안내 .ctSolar 계열만 밤하늘 영역이라 #catPage 밖이다.) */

/* ── 머리말 밑 안내 — 태양계로 가는 길 · 자판 도움말 ── */
.ctSolar {
  display: inline-block; margin-right: var(--s-3);
  color: var(--gold); font-weight: 700;
  border-bottom: 1px solid transparent;
}
.ctSolar:hover { border-bottom-color: currentColor; }
.ctQuickNote { color: var(--night-dim); }
/* 자판 도움말은 손이 자판에 있는 사람에게만 쓸모 있다 — 좁은 화면에서는 자리만 차지해 감춘다 */
.ctKbd { display: inline-block; margin-left: var(--s-4); color: var(--night-dim); font-size: var(--fs-100); }

/* ── 왼쪽 필터 ── */
/* 조건이 물러났을 때·해당 값이 없을 때의 한 줄 설명 */
#catPage .ctNote {
  font-size: var(--fs-100); line-height: var(--lh-snug); color: var(--ink-dim);
  padding: var(--s-2) 0 0;
}
/* 폴더 여닫기 ▸ — 하위 없는 목록과 글자가 어긋나지 않게 자리를 늘 잡아 둔다 */
#catPage .ctCaret {
  display: inline-block; width: 14px; flex-shrink: 0; margin-left: -2px;
  color: var(--red-ink); font-size: var(--fs-200); text-align: left;
}
#catPage .ctCaret:not(.ctCaretOff):hover { color: var(--red); }
#catPage .ctCaretOff { color: transparent; }
/* 폴더 하위 — 들여쓰기와 왼쪽 괘선으로 '이 폴더 안'임을 보인다 */
#catPage .ctKids {
  margin: 0 0 var(--s-2) 7px; padding-left: var(--s-4);
  border-left: 1px solid var(--line-soft);
}
#catPage .ctKids .fitem { padding-block: 5px; font-size: var(--fs-200); }

/* ── 별자리 칸 머리 ── */
#catPage .ctSecNote {
  font-family: var(--sans); font-size: var(--fs-100); font-weight: 400;
  letter-spacing: 0; color: var(--ink-dim); margin-left: var(--s-3);
}
#catPage .ctHint { color: var(--ink-dim); }
#catPage .ctClear {
  color: var(--red-ink); cursor: pointer; margin-left: var(--s-2);
  border-bottom: 1px solid transparent;
}
#catPage .ctClear:hover { border-bottom-color: currentColor; }

/* ── 검색어가 태양계와 맞았을 때 ── */
#catPage .ctSolarHit {
  font-size: var(--fs-300); line-height: var(--lh-snug); color: var(--ink-sub);
  background: rgba(255, 255, 255, .35); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s-3) var(--s-4); margin-bottom: var(--s-5);
}
#catPage .ctSolarHit b { color: var(--ink); }
#catPage .ctSolarGo { color: var(--red-ink); font-weight: 700; margin-left: var(--s-2); }
#catPage .ctSolarGo:hover { border-bottom: 1px solid currentColor; }

/* ── 표 ── */
/* 이름은 진짜 링크지만 표에서는 밑줄 없이 — 행 전체가 이미 누를 수 있는 자리다 */
#catPage .ctLink { color: inherit; }
#catPage tbody tr:hover .ctLink { color: var(--red-ink); }
/* 그룹(묶음) 표식 — 앱과 같이 유형 자리에 인주색 글자로 */
#catPage .ctGrp {
  display: inline-block; margin-right: var(--s-2);
  font-family: var(--sans); font-size: var(--fs-100); font-weight: 700;
  letter-spacing: var(--ls-caps); color: var(--red-ink);
  border: 1px solid rgba(154, 70, 50, .45); border-radius: var(--r-sm);
  padding: 1px 5px; vertical-align: 1px;
}
/* 난이도 — 네 단계가 한눈에 갈리되 종이 위에서 튀지 않게 옅은 테두리만 */
#catPage .ctDif {
  display: inline-block; font-size: var(--fs-100); font-weight: 700; line-height: 1.5;
  padding: 2px var(--s-2); border-radius: var(--r-sm); border: 1px solid; white-space: nowrap;
}
#catPage .ctDif.d1 { color: #2f6b4f; border-color: #9ec4ae; background: rgba(47, 107, 79, .07); }
#catPage .ctDif.d2 { color: var(--ink-sub); border-color: var(--line); background: rgba(90, 81, 66, .07); }
#catPage .ctDif.d3 { color: #7a5320; border-color: #cbae7e; background: rgba(122, 83, 32, .07); }
#catPage .ctDif.d4 { color: var(--red-ink); border-color: rgba(154, 70, 50, .45); background: rgba(154, 70, 50, .08); }

/* 결과가 없을 때의 줄 — 머리글은 남겨 두므로(열 조건을 풀 자리) 그 아래 한 줄만 안내한다.
   갈 곳이 없는 줄이라 손 모양·덧칠을 걷어 낸다. */
#catPage tbody tr.ctEmptyRow { cursor: default; }
#catPage tbody tr.ctEmptyRow:hover td { background: none; }
#catPage tbody tr.ctEmptyRow td { padding: 18px var(--s-3); }

/* 좁은 화면 — 표에서 감춘 칸이 많아지므로 안내 글도 줄인다 */
@media (max-width: 720px) {
  .ctKbd { display: none; }
  #catPage .ctSecNote { display: block; margin: 3px 0 0; }
}

/* ─────────────────────────────────────────────────────────────
   표 열 도구 (tablesort.js) — 여러 페이지가 함께 쓰므로 여기 한 벌만 둔다.
   열 머리에서 바로 줄을 세우고 그 칸만 거르는 자리라, 표 머리글의 결(작은 대문자 느낌의
   흐린 글자)을 그대로 따르고 도구는 눈에 거슬리지 않을 만큼만 드러낸다.
   ───────────────────────────────────────────────────────────── */

/* 열 머리 전체가 아니라 제목 글자만 누를 수 있다 — 손 모양도 그 자리에만 준다.
   (:has 를 못 알아듣는 브라우저에서는 손 모양이 칸 전체에 남을 뿐, 동작은 같다) */
table.list thead th:has(.ttH) { cursor: default; }
table.list thead th:has(.ttH):hover { color: var(--ink-dim); }

.ttH { cursor: pointer; }
.ttH:hover { color: var(--red-ink); }
/* 화살표 자리는 늘 잡아 둔다 — 세울 때마다 머리글 너비가 흔들리면 표가 들썩인다 */
.ttArr {
  display: inline-block; width: 13px; margin-left: 3px;
  font-size: 11px; color: var(--red-ink); vertical-align: 1px;
}
/* 거르기 세모 — 평소엔 있는 듯 없는 듯, 조건이 걸리면 인주색으로 또렷하게 */
.ttF {
  display: inline-block; margin-left: var(--s-1); padding: 1px 5px;
  font-size: 15px; line-height: 1; color: var(--ink-dim); opacity: .7; cursor: pointer;
  border: 1px solid transparent; border-radius: var(--r-sm);
}
.ttF:hover { color: var(--red-ink); opacity: 1; background: rgba(154, 70, 50, .08); }
/* 조건이 걸린 칸은 테두리까지 둘러 한눈에 보이게 */
.ttF.on { color: var(--red-ink); opacity: 1; border-color: var(--red-ink); background: rgba(154, 70, 50, .08); }

/* 거르기 상자 — 머리글 바로 아래에 뜬다(자리는 tablesort.js 가 잡는다).
   본문 위에 얹히지만 담기 바(z-index 30)보다 앞, 모달(60)보다는 뒤에 둔다. */
.ttPanel {
  position: absolute; z-index: 40;
  min-width: 200px; max-width: 240px; max-height: 260px; overflow-y: auto;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: 0 6px 18px rgba(46, 40, 32, .18);
  padding: var(--s-2) var(--s-2) 0;
  /* 머리글 안이 아니라 화면 맨 위에 붙으므로, 글자 결은 여기서 따로 정해 준다 */
  font-family: var(--sans); font-size: var(--fs-200); font-weight: 400;
  letter-spacing: 0; line-height: var(--lh-snug); color: var(--ink); text-align: left;
  white-space: normal; cursor: default;
}
.ttRow { display: flex; align-items: center; gap: 6px; padding: var(--s-2) 2px; color: var(--ink-dim); }
.ttNum, .ttTxt {
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 5px var(--s-2);
  font-size: var(--fs-200); background: rgba(240, 230, 205, .55); color: var(--ink);
}
.ttNum { width: 72px; text-align: center; font-variant-numeric: tabular-nums; }
.ttTxt { width: 100%; }
.ttNum:focus, .ttTxt:focus { outline: none; border-color: var(--red-ink); }

/* 값 고르기 — 이름이 길어도 개수는 오른쪽에 붙어 있게 */
.ttItem {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 3px; border-radius: var(--r-sm); cursor: pointer;
}
.ttItem:hover { background: rgba(154, 70, 50, .07); }
.ttItem input { accent-color: var(--red); flex-shrink: 0; margin: 0; }
.ttItem > span:not(.ttCnt) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ttCnt { color: var(--ink-dim); font-size: var(--fs-100); font-variant-numeric: tabular-nums; }

/* 아래 줄은 목록이 길어 굴러도 늘 보이게 — 조건을 푸는 길이 화면 밖으로 나가면 안 된다 */
.ttFoot {
  position: sticky; bottom: 0; display: flex; justify-content: space-between; gap: var(--s-3);
  margin-top: var(--s-1); padding: var(--s-2) 2px;
  background: var(--paper); border-top: 1px solid var(--line-soft);
}
.ttFoot a {
  font-size: var(--fs-100); font-weight: 600; color: var(--red-ink);
  cursor: pointer; border-bottom: 1px solid transparent;
}
.ttFoot a:hover { border-bottom-color: currentColor; }

/* 좁은 화면 — 상자가 화면 폭을 넘지 않게 */
@media (max-width: 720px) {
  .ttPanel { min-width: 0; max-width: min(240px, calc(100vw - 24px)); }
}

/* '○○ 목록에 담는 중' 띠 — 도감을 목록 담기용으로 쓸 때 무엇에 담는지 늘 보이게 */
.catAddBar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 var(--s-4); padding: 8px 12px;
  border: 1px solid var(--red-ink); border-radius: 8px;
  font-size: var(--fs-200); font-weight: 600;
}
.catAddBar .catAddHint { font-weight: 400; color: var(--ink-dim); }
.catAddBar .catAddBack { margin-left: auto; color: var(--red-ink); font-weight: 600; }

/* 왼쪽 '관측 목록' 필터의 폴더 여닫기 세모 — 웹 전체를 17px 로 키운 손질에서 빠져 있었다 */
#catPage .ctCaret { font-size: 17px; padding: 2px 4px; }
/* ==== /patch:catalog ==== */

/* ==== patch:common ==== */
/* 공용 부품 — 담기 창 · 화면 안 알림 · 관측 위치. pick.js 가 만드는 것들만.
   페이지에 상관없이 뜨므로 이름을 pk- / whr- 로 시작해 다른 화면과 섞이지 않게 한다. */

/* ── 창(모달) 껍데기 ─────────────────────────────────────────────────────── */
.pkWrap { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: var(--s-4); }
.pkWrap[hidden] { display: none; }
.pkBack { position: absolute; inset: 0; background: rgba(28, 24, 18, .55); }
.pkBox {
  position: relative; width: 100%; max-width: 560px; max-height: min(84vh, 780px);
  display: flex; flex-direction: column;
  background: var(--sand); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .32);
}
body.pkOpen { overflow: hidden; }   /* 창이 떴을 때 뒤 종이가 같이 굴러다니지 않게 */

.pkHead {
  display: flex; align-items: baseline; gap: var(--s-3);
  padding: var(--s-4) var(--s-5); border-bottom: var(--rule);
}
.pkHead b { font-family: var(--serif); font-size: var(--fs-600); letter-spacing: var(--ls-heading); }
.pkHead .pkSub { font-size: var(--fs-200); color: var(--ink-dim); }
.pkX {
  margin-left: auto; border: 0; background: none; cursor: pointer;
  color: var(--ink-dim); font-size: var(--fs-400); line-height: 1; padding: var(--s-1) var(--s-2);
}
.pkX:hover { color: var(--red-ink); }

.pkBody { overflow-y: auto; padding: var(--s-4) var(--s-5); }
.pkFoot {
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-5); border-top: var(--rule); background: var(--sand-deep);
}
.pkGrow { flex: 1; }
.pkGo { background: var(--red); border-color: var(--red); color: var(--paper); font-weight: 700; }
.pkGo:hover { background: #8a3e2c; }
.pkGo[disabled] { opacity: .4; cursor: default; }
.pkGo[disabled]:hover { background: var(--red); }

/* ── 담기 창 안쪽 ────────────────────────────────────────────────────────── */
.pkSec + .pkSec { margin-top: var(--s-5); }
.pkSec h4 {
  font-size: var(--fs-100); font-weight: 700; color: var(--red-ink);
  letter-spacing: var(--ls-caps); text-transform: none;
  padding-bottom: var(--s-2); margin-bottom: var(--s-2); border-bottom: var(--rule-hair);
}
.pkLead { font-size: var(--fs-200); color: var(--ink-sub); line-height: var(--lh-snug); margin-bottom: var(--s-4); }
.pkEmpty { font-size: var(--fs-200); color: var(--ink-dim); padding: var(--s-3) 2px; }
.pkRows { display: flex; flex-direction: column; gap: 2px; }

.pkRow {
  display: flex; align-items: center; gap: var(--s-3);
  padding: 7px var(--s-3); border: 1px solid transparent; border-radius: var(--r-sm);
  cursor: pointer; font-size: var(--fs-300);
}
.pkRow:hover { background: rgba(154, 70, 50, .06); }
.pkRow.on { background: rgba(154, 70, 50, .1); border-color: rgba(154, 70, 50, .4); }
.pkRow input { accent-color: var(--red); width: 15px; height: 15px; flex-shrink: 0; }
.pkName { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pkSubName { font-style: normal; font-size: var(--fs-100); color: var(--ink-dim); margin-left: var(--s-2); }
.pkCnt { font-size: var(--fs-100); color: var(--ink-dim); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.pkChild { margin-left: var(--s-5); }

/* 프리셋 폴더에서 불러온 목록 묶음 — 한 번에 하나만 펼친다 */
.pkFoldHead {
  display: flex; align-items: center; gap: var(--s-3); width: 100%;
  padding: 7px var(--s-3); border: 0; background: none; cursor: pointer;
  font: inherit; font-size: var(--fs-300); color: var(--ink); text-align: left;
}
.pkFoldHead:hover { background: rgba(154, 70, 50, .06); }
.pkCaret { width: 14px; color: var(--red-ink); flex-shrink: 0; }

.pkNew { display: flex; gap: var(--s-2); margin-top: var(--s-2); }
.pkNew input {
  flex: 1; min-width: 0; font: inherit; font-size: var(--fs-300);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper); color: var(--ink); padding: 6px var(--s-3);
}
.pkDash {
  display: block; width: 100%; margin-top: var(--s-2);
  border: 1px dashed rgba(154, 70, 50, .6); border-radius: var(--r-sm); background: none;
  color: var(--red-ink); font: inherit; font-size: var(--fs-300); font-weight: 600;
  padding: var(--s-3); cursor: pointer;
}
.pkDash:hover { background: rgba(154, 70, 50, .07); }

.pkField { display: block; margin-bottom: var(--s-3); }
.pkField > span { display: block; font-size: var(--fs-100); color: var(--ink-dim); margin-bottom: var(--s-1); }
.pkField input, .pkField textarea {
  width: 100%; font: inherit; font-size: var(--fs-300); resize: vertical;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper); color: var(--ink); padding: 7px var(--s-3);
}

/* ── 화면 안 알림 ────────────────────────────────────────────────────────── */
.pkToast {
  position: fixed; left: 50%; bottom: var(--s-5); transform: translate(-50%, 12px); z-index: 70;
  max-width: min(92vw, 560px);
  background: rgba(43, 40, 35, .96); color: var(--paper);
  border-radius: var(--r-md); padding: var(--s-3) var(--s-4);
  font-size: var(--fs-300); line-height: var(--lh-snug);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .28);
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
}
.pkToast.on { opacity: 1; transform: translate(-50%, 0); }
.pkToast.up { bottom: 76px; }   /* 담기 바가 떠 있을 때 그 위로 */

/* ── 관측 위치 ───────────────────────────────────────────────────────────── */
.whrNow {
  display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap;
  background: var(--sand-deep); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: var(--s-3) var(--s-4); margin-bottom: var(--s-3);
}
.whrLabel { font-size: var(--fs-400); font-weight: 700; }
.whrCoord { font-family: var(--mono); font-size: var(--fs-100); color: var(--ink-dim); }
.whrManual { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--s-3); margin-top: var(--s-4); }
.whrManual .pkField:last-child { grid-column: 1 / -1; }
.whrMsg {
  font-size: var(--fs-200); color: var(--red-ink); line-height: var(--lh-snug);
  border-left: 0; background: rgba(154, 70, 50, .08);
  border-radius: var(--r-sm); padding: var(--s-2) var(--s-3); margin-bottom: var(--s-3);
}
.whrHint { font-size: var(--fs-100); color: var(--ink-dim); line-height: var(--lh-snug); margin-top: var(--s-3); }
.whrFoot {
  border: 0; background: none; font: inherit; font-size: var(--fs-200);
  color: var(--ink-dim); cursor: pointer; padding: 0;
  text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: 1px;
}
.whrFoot:hover { color: var(--red-ink); }

@media (max-width: 560px) {
  .whrManual { grid-template-columns: 1fr; }
  .pkBox { max-height: 90vh; }
}
@media print { .pkWrap, .pkToast { display: none !important; } }

/* ── 접었다 폈다 하는 삼각 화살표를 키운다 ─────────────────────────────────
   10~11px 은 손으로 겨누기에도, 눈으로 찾기에도 너무 작았다(사용자 지적).
   글자 크기와 함께 누를 자리도 넓힌다 — 화살표만 커지고 판이 좁으면 여전히 안 눌린다. */
.sCaret, .skCaret, .snCaret, .agCaret, .lstCaret {
  font-size: 17px !important; line-height: 1;
  padding: 2px 4px; color: var(--ink-dim);
}
.lstCaret { cursor: pointer; }
/* 표 열 머리의 거르기 세모도 같은 몫이다 */
.ttF { font-size: 17px; padding: 2px 5px; }

/* 천체 찾아 담기 상자 — 검색 결과 줄 */
.pkFindList { max-height: 300px; overflow: auto; margin-top: var(--s-2); }
.pkFindNote { padding: 14px 4px; color: var(--ink-dim); font-size: var(--fs-200); }
.pkFindRow {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 6px; border-radius: 6px; cursor: pointer;
  font-size: var(--fs-200);
}
.pkFindRow:hover { background: rgba(127,127,127,.12); }
.pkFindRow.on { background: rgba(154,70,50,.14); font-weight: 600; }
.pkFindRow.inlist { cursor: default; color: var(--ink-dim); }
.pkFindMark { width: 14px; flex-shrink: 0; color: var(--red-ink); }
.pkFindName { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pkFindIn { font-size: var(--fs-100); color: var(--ink-dim); flex-shrink: 0; }

/* 되묻는 상자 — 되돌릴 수 없는 일은 확인 단추를 붉게 */
.pkConfirmDetail { margin-top: var(--s-2); font-size: var(--fs-200); color: var(--ink-dim); white-space: pre-line; }
.btn.pkDanger { background: var(--red-ink); border-color: var(--red-ink); color: #fff; }
/* ==== /patch:common ==== */

/* ==== patch:home ==== */
/* ═══════════════════════════════════════════════════════════════════════════
   홈 — 오늘 밤 하늘 (달·해 시각 / 행성 / 출몰 타임라인)

   앱 홈의 '하늘 상태 바'를 웹으로 옮긴 자리다. 앱은 어두운 헤더 띠 위에 얹혀
   있지만 웹의 본문은 종이(모래)라, 박스로 감싸지 않고 게시판 괘선으로만 나눈다
   (style.css 의 컨셉 — 박스는 최소).

   달만 예외로 어두운 원 하나를 둔다. 위상(초승·보름)은 밝은 부분과 어두운
   부분의 대비로 읽는 그림이라, 종이색 위에 그리면 모양이 드러나지 않는다.

   이름은 전부 sn* / skyNow — style.css 에 없는 이름만 새로 쓴다.
   ═══════════════════════════════════════════════════════════════════════════ */

.skyNow { margin-bottom: var(--s-6); }
/* .wrap 의 첫 덩어리라 위 간격을 게시판과 같게 맞춘다 */
.skyNow h2.sec { margin-top: var(--s-6); }

/* ── 달 + 시각 한 줄 ────────────────────────────────────────────────────── */
.snMain {
  display: flex; align-items: center; gap: clamp(20px, 3vw, 40px);
  flex-wrap: wrap;
  padding: var(--s-4) 2px var(--s-3);
  border-bottom: var(--rule-hair);
}

.snMoon { display: flex; align-items: center; gap: var(--s-3); flex: none; }
/* 달 원 — 빛무리는 밝기에 비례해 스크립트가 opacity 를 넣는다(앱 MoonGlow 와 같은 몫) */
.snDisc {
  position: relative; width: 62px; height: 62px; flex: none;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.snDisc::before {
  content: ''; position: absolute; inset: -13px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 233, 176, .85) 0%, rgba(255, 233, 176, 0) 68%);
  opacity: var(--moon-glow, .25);
  pointer-events: none;
}
.snDisc svg { position: relative; display: block; }
.snMoonTxt { line-height: 1.3; }
.snPct {
  display: block;
  font-size: var(--fs-600); font-weight: 700; color: var(--red-ink);
  font-variant-numeric: tabular-nums; letter-spacing: var(--ls-heading);
}
.snPctLab { display: block; font-size: var(--fs-100); color: var(--ink-dim); }
.snAge { display: block; font-size: var(--fs-200); color: var(--ink-sub); margin-top: 3px; }

.snTimes {
  display: flex; flex: 1 1 460px; flex-wrap: wrap;
  gap: var(--s-3) clamp(14px, 2.6vw, 36px);
}
.snItem { min-width: 66px; }
.snVal {
  display: block;
  font-size: var(--fs-500); font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; line-height: 1.25;
}
/* 달 시각은 해 시각과 성격이 달라 색으로만 살짝 가른다(앱의 보라 칸과 같은 몫) */
.snItem.moon .snVal { color: #46507F; }
.snLab { display: block; font-size: var(--fs-100); color: var(--ink-dim); margin-top: 3px; }

.snNote {
  padding: var(--s-3) 2px 0;
  font-size: var(--fs-200); color: var(--ink-sub);
}
.snNote b { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }

/* ── 접었다 펴는 덩어리(행성 · 내 계획) ───────────────────────────────────── */
.snBlock { margin-top: var(--s-4); }
.snToggle {
  display: flex; align-items: baseline; gap: var(--s-2); width: 100%;
  padding: var(--s-3) 2px; margin: 0;
  background: none; border: 0; border-bottom: var(--rule);
  font: inherit; font-size: var(--fs-400); font-weight: 700; color: var(--ink);
  text-align: left; cursor: pointer;
}
.snToggle:hover { color: var(--red-ink); }
.snToggle .snHint { font-size: var(--fs-100); font-weight: 400; color: var(--ink-dim); }
.snCaret { margin-left: auto; font-size: var(--fs-200); font-weight: 400; color: var(--ink-dim); }
.snBody { padding: var(--s-4) 0 var(--s-2); }

/* ── 출몰 타임라인 — 일몰(0%)에서 다음 일출(100%)까지 ────────────────────── */
.snTl { padding-top: 2px; }
.snTlAxis { display: flex; align-items: center; margin-bottom: var(--s-1); }
.snTlHead {
  flex: 1; display: flex; justify-content: space-between;
  font-size: var(--fs-100); color: var(--ink-sub); font-variant-numeric: tabular-nums;
}
.snTlRow { display: flex; align-items: center; margin: 5px 0; }
.snTlName {
  width: 124px; flex: none; padding-right: var(--s-2);
  font-size: var(--fs-300); font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.snTlTrack {
  position: relative; flex: 1; height: 22px;
  background: var(--sand-deep);
  border: 1px solid var(--line-soft); border-radius: 2px;
  overflow: hidden;
}
.snTlBar { position: absolute; top: 5px; height: 10px; border-radius: 2px; background: var(--red); }
.snTlBar.full { background: #5A5F8F; }          /* 주극성 — 밤새 떠 있다 */
.snTlNow { position: absolute; top: 0; bottom: 0; width: 1.5px; background: var(--ink); }
.snTlTime {
  position: absolute; top: 0; height: 22px; line-height: 22px;
  font-size: var(--fs-100); font-weight: 600; color: var(--ink-sub);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.snTlTime.r { text-align: right; padding-right: 5px; }
.snTlTime.s { padding-left: 5px; }
.snTlNone {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-100); color: var(--ink-dim);
}
/* 오른쪽 꼬리 칸 — 행성은 밝기·지금 고도, 내 계획 천체는 오늘 밤 최고 고도 */
.snTlSide {
  width: 186px; flex: none; padding-left: var(--s-3); text-align: right;
  font-size: var(--fs-100); color: var(--ink-sub);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.snTlHint { margin-top: var(--s-2); text-align: right; font-size: var(--fs-100); color: var(--ink-dim); }
.snTlMore { margin-top: var(--s-2); font-size: var(--fs-200); color: var(--ink-dim); }

/* ── 좁은 화면 ───────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .snTlSide { width: 116px; }                   /* 밝기만 남을 만큼 */
}
@media (max-width: 660px) {
  .snTlName { width: 88px; font-size: var(--fs-200); }
  .snTlSide { display: none; }                  /* 좁으면 막대만 — 출·몰 시각은 막대 옆에 남는다 */
  .snVal { font-size: var(--fs-400); }
  .snDisc { width: 52px; height: 52px; }
}

/* ── 관측 위치 — '오늘 밤 하늘' 제목 오른쪽 끝 ───────────────────────────── */
/*  자리는 h2.sec .tail 이 이미 맡고 있어(margin-left:auto) 그대로 쓰고,
    여기서는 button 이 기본으로 갖고 오는 테·바탕만 벗긴다. */
h2.sec .snWhere {
  appearance: none; background: none; border: 0;
  font: inherit; font-family: var(--sans); font-size: var(--fs-200); font-weight: 600;
  letter-spacing: 0; color: var(--red-ink);
  text-align: right; white-space: nowrap;
}
@media (max-width: 520px) {
  /* 좁으면 제목·밤 날짜와 한 줄에 다 못 들어간다 — 아래 줄로 내려 오른쪽에 붙인다 */
  h2.sec .snWhere { flex-basis: 100%; margin-top: 2px; }
}

/*  관측 위치를 아직 안 정했을 때 — 눌러 볼 것이라고 알아채게 한다(점선 밑줄) */
h2.sec .snWhere.whrUnset { border-bottom: 1px dashed currentColor; padding-bottom: 1px; }

/* 관측 위치를 아직 안 정했을 때 권하는 줄 — 하늘 칸 안에 조용히 눕는다(막지 않는다) */
.snSetWhere {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: var(--s-3); padding: 8px 10px;
  border: 1px dashed var(--rule-color, rgba(0,0,0,.2)); border-radius: 8px;
  font-size: var(--fs-200);
}
.snSetWhere .snSetBtn {
  appearance: none; background: none; cursor: pointer;
  border: 1px solid currentColor; border-radius: 999px; padding: 3px 10px;
  font: inherit; font-weight: 600; color: inherit;
}
.snSetWhere .snSetBtn:hover { background: rgba(255,255,255,.08); }

/* 미니 게시판 — 지금 보여 주는 것이 어느 계획인지 */
.board h2 .bWhich { font-size: var(--fs-100); font-weight: 400; color: var(--ink-dim); margin-left: 6px; }
/* ==== /patch:home ==== */

/* ==== patch:lists ==== */
/* 관측 목록 페이지 — style.css 에 없는 것만.
   다른 페이지로 새지 않게 모두 #listsPage 안에 두고, 이름도 lst- 로 시작한다. */

/* 목록·프리셋 표는 행을 눌러 천체로 가는 표가 아니라서, 표 기본의 손가락 커서·행 물칠을 끈다 */
#listsPage table.list tbody tr.lstNoHover { cursor: default; }
#listsPage table.list tbody tr.lstNoHover:hover td { background: none; }
#listsPage .lstDesc { margin-top: 3px; font-weight: 400; }
#listsPage .lstMv { padding-inline: var(--s-2); font-size: var(--fs-100); }
#listsPage .lstMv[disabled] { opacity: .3; cursor: default; }
#listsPage .lstDone { margin-right: var(--s-2); }
#listsPage .lstNote { padding: var(--s-3) 2px 0; }

/* 프리셋 폴더 여닫기 — ▸ 자리를 늘 잡아 둬야 하위 없는 목록과 글자가 어긋나지 않는다 */
#listsPage .lstCaret {
  display: inline-block; width: 18px; margin-left: -2px;
  color: var(--red-ink); cursor: pointer; font-size: var(--fs-200);
}
#listsPage .lstCaretOff { cursor: default; }
#listsPage .lstFold { font-weight: 400; margin-left: var(--s-2); }
#listsPage tr.lstSubRow td { background: rgba(255, 255, 255, .3); }
#listsPage .lstSub { display: inline-block; padding-left: 30px; font-weight: 400; position: relative; }
#listsPage .lstSub::before { content: '└'; position: absolute; left: 14px; color: var(--ink-dim); }

/* 폴더 하위 탭 — 여러 개를 눌러 묶어 볼 수 있다(앱의 전체보기+하위 고르기와 같은 몫) */
#listsPage .lstTabs {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2);
  padding: var(--s-4) 2px var(--s-2);
}
#listsPage .lstTabLabel { font-size: var(--fs-100); font-weight: 700; letter-spacing: var(--ls-caps); color: var(--ink-dim); margin-right: var(--s-2); }
#listsPage .lstTab {
  display: inline-flex; align-items: baseline; gap: 5px; cursor: pointer;
  font-size: var(--fs-300); color: var(--ink);
  padding: 6px var(--s-3); border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .32);
}
#listsPage .lstTab:hover { background: #fff; border-color: var(--ink-dim); }
#listsPage .lstTab i { font-style: normal; font-size: var(--fs-100); color: var(--ink-dim); }
#listsPage .lstTab.on { background: var(--red); border-color: var(--red); color: var(--paper); font-weight: 700; }
#listsPage .lstTab.on i { color: rgba(255, 255, 255, .8); }
#listsPage .lstTabHint { margin-left: var(--s-2); }

/* 접었다 펴는 칸(필터·담아오기·이름 고치기·가져오기) */
#listsPage .lstPanel {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .45);
  padding: var(--s-4); margin-bottom: var(--s-4);
}
#listsPage .lstRow2, #listsPage .lstField {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3);
  padding: var(--s-2) 0;
}
#listsPage .lstRow2 + .lstRow2 { border-top: var(--rule-hair); }
#listsPage .lstLb {
  flex: none; width: 96px;
  font-size: var(--fs-100); font-weight: 700; letter-spacing: var(--ls-caps); color: var(--ink-dim);
}
#listsPage .lstIn {
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 7px var(--s-3);
  font-size: var(--fs-300); background: rgba(255, 255, 255, .7); color: var(--ink); width: 260px;
}
#listsPage .lstInWide { width: 420px; max-width: 100%; }
#listsPage .lstIn:focus { outline: 2px solid var(--red); outline-offset: 1px; }

/* 액션 줄 — 단추가 여럿이라 요약 글자와 사이를 벌린다 */
#listsPage .lstActs { margin-bottom: var(--s-3); }
#listsPage .lstActs .sum { margin-right: auto; }
#listsPage .lstTools {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3);
  padding-bottom: var(--s-4);
}
#listsPage .lstTools .srch { flex: 1 1 260px; max-width: 420px; }
#listsPage .lstToggle {
  cursor: pointer; font-size: var(--fs-300); color: var(--ink-sub);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 7px var(--s-3);
  background: rgba(255, 255, 255, .32);
}
#listsPage .lstToggle:hover { background: #fff; border-color: var(--ink-dim); }
#listsPage .lstToggle.on { color: var(--red-ink); border-color: var(--red); font-weight: 700; }

/* 조건 칩 — 유형·계절·별자리 */
#listsPage .lstChips { display: flex; flex-wrap: wrap; gap: var(--s-2); flex: 1; min-width: 0; }
#listsPage .lstChip {
  display: inline-flex; align-items: baseline; gap: 5px; cursor: pointer;
  font-size: var(--fs-200); color: var(--ink-sub);
  padding: 4px var(--s-3); border: 1px solid var(--line); border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .3);
}
#listsPage .lstChip:hover { background: #fff; border-color: var(--ink-dim); }
#listsPage .lstChip i { font-style: normal; font-size: var(--fs-100); color: var(--ink-dim); }
#listsPage .lstChip.on { background: rgba(154, 70, 50, .12); border-color: var(--red); color: var(--red-ink); font-weight: 700; }
#listsPage .lstChip.on i { color: var(--red-ink); }

/* 담아올 천체 고르는 상자 — 길어질 수 있어 안에서만 구른다 */
#listsPage .lstBox {
  max-height: 300px; overflow-y: auto;
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .35); padding: var(--s-3);
}
#listsPage .lstErr { font-size: var(--fs-200); line-height: var(--lh-body); color: var(--ink-sub); max-height: 200px; }
#listsPage .lstPickRow {
  display: flex; align-items: center; gap: var(--s-3);
  padding: 5px 2px; border-bottom: var(--rule-hair); cursor: pointer; font-size: var(--fs-300);
}
#listsPage .lstPickRow:last-child { border-bottom: 0; }
#listsPage .lstPickRow:hover { background: rgba(154, 70, 50, .055); }
#listsPage .lstPickRow.dim .lstPickName { color: var(--ink-dim); }
#listsPage .lstPickName { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* .sortSel 은 오른쪽으로 밀리게 만들어져 있어(margin-left:auto) 줄 안에서는 되돌린다 */
#listsPage .lstSrcSel, #listsPage .lstMoveSel { margin-left: 0; }

/* 표 위 고르기 줄 */
#listsPage .lstBar {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3);
  padding: var(--s-3) 2px; border-top: var(--rule-hair);
}
#listsPage .lstSel { font-size: var(--fs-300); color: var(--ink-sub); }
#listsPage .lstSel b { color: var(--red-ink); font-variant-numeric: tabular-nums; }

/* 별자리순일 때 표 사이에 끼는 별자리 머리 */
#listsPage tr.lstGroup { cursor: default; }
#listsPage tr.lstGroup:hover td { background: none; }
#listsPage tr.lstGroup td {
  padding: var(--s-4) var(--s-3) var(--s-2);
  font-family: var(--serif); font-size: var(--fs-500); color: var(--ink);
  border-bottom: var(--rule); background: none;
}
#listsPage tr.lstGroup td span {
  font-family: var(--sans); font-size: var(--fs-100); color: var(--ink-dim);
  margin-left: var(--s-3); letter-spacing: var(--ls-caps);
}

@media (max-width: 720px) {
  #listsPage .lstLb { width: 100%; }
  #listsPage .lstIn, #listsPage .lstInWide { width: 100%; }
  #listsPage .lstTools .srch { flex-basis: 100%; max-width: none; }
}
/* ==== /patch:lists ==== */

/* ==== patch:object ==== */
/* 천체 상세 — style.css 에 없는 것만.
   본문 쪽은 #objPage 안으로, 머리 쪽은 #objHead 안으로 가둔다(다른 페이지로 새지 않게).
   담기 상자·알림은 <body> 에 붙으므로 .ob- 로 시작하는 제 이름을 쓴다. */

/* ── 머리 ── */

/* 그룹 표식 — 제목 옆. 앱은 유형 아이콘 자리에 '그룹' 글자를 넣는데, 웹은 제목 옆이 자연스럽다 */
#objHead .obGroupTag {
  display: inline-block; vertical-align: middle;
  margin-left: var(--s-3);
  font-family: var(--sans); font-size: var(--fs-100); font-weight: 700; letter-spacing: var(--ls-caps);
  color: var(--gold); border: 1px solid rgba(255, 215, 106, .5); border-radius: var(--r-sm);
  padding: 2px 7px;
}

/* 대표 표기 칩 — 여럿 가운데 어느 것이 그 천체의 대표 이름인지 한눈에 */
#objHead .chip2.pri { background: rgba(255, 255, 255, .16); border-color: var(--night-sub); font-weight: 700; }

/* 별명 줄 — 코드형 표기(칩)와 갈라, 진짜 별명만 여기에 */
#objHead .obNick { margin-top: var(--s-3); font-size: var(--fs-200); color: var(--night-sub); }
#objHead .obNick b { color: var(--night-txt); font-weight: 700; }
#objHead .obNick .lb { letter-spacing: var(--ls-caps); color: var(--night-dim); margin-right: var(--s-2); }

/* ── 본문 ── */

/* 관측 포인트 번호 — ①②③ 글리프는 기기마다 크기가 들쭉날쭉해, 원을 직접 그린다 */
#objPage .pt .n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-top: 1px;
  border: 1.5px solid var(--red-ink); border-radius: 50%;
  font-size: var(--fs-100); line-height: 1;
}

/* 제원 표 — 그 천체의 성격을 가르는 값(주성 등급·구성원 수 등)을 굵게 */
#objPage table.spec td .obHi { font-weight: 700; }

/* 성도 밑줄 설명 — 별자리 이름을 또렷하게 */
#objPage #chartNote b { color: var(--ink); font-weight: 700; }

/* 오른쪽 곁단 — 넓은 화면에서는 본문을 내려도 성도·제원이 따라온다.
   좁은 화면(980px 이하)은 style.css 가 단을 세로로 쌓으므로 그대로 둔다. */
@media (min-width: 981px) {
  #objPage .colSide {
    position: sticky; top: var(--s-4);
    max-height: calc(100vh - var(--s-5));
    overflow-y: auto; overscroll-behavior: contain;
    scrollbar-width: thin;
  }
}

/* ── 담기 상자(목록·계획 고르기) ── */
.obDim {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(10, 14, 44, .5);
  display: flex; align-items: center; justify-content: center; padding: var(--s-4);
}
.obPick {
  width: min(420px, 100%); max-height: min(78vh, 640px);
  display: flex; flex-direction: column;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: 0 18px 44px rgba(20, 16, 8, .28);
  padding: var(--s-4);
}
.obPick h3 {
  font-size: var(--fs-500); line-height: var(--lh-snug);
  margin: 0 0 var(--s-3); color: var(--ink);
}
.obPickBody { overflow-y: auto; min-height: 0; margin: 0 calc(var(--s-2) * -1); padding: 0 var(--s-2); }
.obPickItem {
  display: flex; align-items: baseline; gap: var(--s-2); width: 100%;
  text-align: left; cursor: pointer;
  background: none; border: 0; border-bottom: var(--rule-hair);
  padding: var(--s-3) var(--s-2);
  font-size: var(--fs-300); color: var(--ink); font-family: inherit;
}
.obPickItem:hover { background: rgba(255, 255, 255, .6); }
.obPickItem b { font-weight: 700; }
.obPickItem i { font-style: normal; font-size: var(--fs-100); color: var(--ink-dim); }
.obPickItem[disabled] { cursor: default; opacity: .55; }
.obPickItem[disabled]:hover { background: none; }
.obPickEmpty { padding: var(--s-3) var(--s-2); font-size: var(--fs-200); color: var(--ink-dim); }
.obPickNew { display: flex; gap: var(--s-2); padding-top: var(--s-3); border-top: var(--rule); margin-top: var(--s-3); }
.obPickIn {
  flex: 1; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 7px var(--s-3);
  font-size: var(--fs-300); font-family: inherit; background: #fff; color: var(--ink);
}
.obPickFoot { display: flex; justify-content: flex-end; padding-top: var(--s-3); }

/* ── 담은 뒤 알림 ── */
.obToast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 70;
  display: flex; align-items: center; gap: var(--s-3);
  background: var(--ink); color: var(--paper);
  border-radius: var(--r-pill); padding: 10px var(--s-4);
  font-size: var(--fs-300); box-shadow: 0 10px 26px rgba(20, 16, 8, .3);
  max-width: calc(100vw - 32px);
}
.obToast a { color: var(--gold); text-decoration: underline; text-underline-offset: .18em; }
@media (max-width: 640px) {
  .obToast { left: var(--s-4); right: var(--s-4); transform: none; justify-content: space-between; }
}

/* ── 목차 (본문 왼쪽 칸) ────────────────────────────────────────────────────
   보던 목록의 차례를 왼쪽에 편다. 화면을 따라 붙어 다니고(sticky) 자기 안에서만 구른다.
   접으면 얇은 손잡이만 남는다 — 여느 문서 사이트가 옆 목차를 다루는 방식. */
.colToc {
  width: 218px; flex-shrink: 0;
  position: sticky; top: 84px;
  max-height: calc(100vh - 104px);
  display: flex; flex-direction: column;
  border-right: 1px solid var(--rule-color, rgba(0,0,0,.14));
  padding-right: var(--s-4);
}
.colToc[hidden] { display: none; }
.colToc.shut { width: auto; border-right: 0; padding-right: 0; }

.tocHead { display: flex; align-items: baseline; gap: 6px; padding: 0 2px 4px; }
.tocHead b { flex: 1; min-width: 0; font-size: var(--fs-200); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tocCnt { font-size: var(--fs-100); color: var(--ink-dim); }
.tocFold {
  appearance: none; background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 20px; line-height: 1; color: var(--ink-dim);
  padding: 0 4px; align-self: center;
}
.tocFold:hover { color: var(--ink); }

/* 접었을 때 남는 세로 손잡이 */
.tocHandle {
  appearance: none; background: none; cursor: pointer;
  border: 1px solid var(--rule-color, rgba(0,0,0,.18)); border-radius: 8px;
  padding: 10px 4px; color: var(--ink-dim); font: inherit;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.tocHandle:hover { color: var(--ink); }
.tocHandleArrow { font-size: 20px; line-height: 1; }
.tocHandleTxt { writing-mode: vertical-rl; font-size: var(--fs-100); letter-spacing: .08em; }

.tocTools { padding: 0 2px 6px; }
.tocSel {
  width: 100%; font: inherit; font-size: var(--fs-100);
  padding: 3px 6px; border-radius: 6px;
  border: 1px solid var(--rule-color, rgba(0,0,0,.18));
  background: transparent; color: inherit;
}

.tocList { overflow: auto; padding-bottom: 8px; }
.tocGroup {
  position: sticky; top: 0; z-index: 1;
  background: var(--paper, #fff);
  padding: 6px 4px 3px; margin-top: 4px;
  font-size: var(--fs-100); font-weight: 700; color: var(--ink-dim);
  border-bottom: 1px solid var(--rule-color, rgba(0,0,0,.12));
}
.tocItem {
  display: block; padding: 4px 6px; border-radius: 5px;
  font-size: var(--fs-200); line-height: 1.35; color: inherit; text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tocItem:hover { background: rgba(127,127,127,.14); }
.tocItem.on { font-weight: 700; background: rgba(154,70,50,.14); }

@media (max-width: 1100px) { .colToc { display: none; } }

/* 관측 포인트 — 글자가 가이드 본문과 **같은 왼쪽 끝**에서 시작하게.
   번호를 왼쪽 칸으로 세워 두면 그 칸(번호+사이 여백)만큼 글줄이 안으로 밀려,
   바로 위 안시관측 가이드보다 좁아 보인다. 번호를 띄워(float) 첫 줄 옆에만 두고
   이어지는 줄은 가이드와 같은 폭을 쓴다. */
#objPage .pt { display: block; }
#objPage .pt .n { float: left; margin-right: 8px; }
#objPage .pt::after { content: ''; display: block; clear: both; }

/* 제원의 곁말 — ★ 가 무엇을 재는 별인지 괄호로 덧붙일 때 쓴다(값보다 한 단 옅게) */
#objPage .specNote { color: var(--ink-dim); font-size: var(--fs-100); }

/* 천체 상세에서도 '담는 중' 임을 잃지 않는다 */
.objAddBar { margin-bottom: var(--s-4); }
/* ==== /patch:object ==== */

/* ==== patch:plan ==== */
/* 관측 계획 — 시간표·초안 목록에만 쓰는 것. 나머지는 공통 클래스를 그대로 쓴다
   (.rail .fg .fitem .rb .cb .cnt .btn .rmX .magIn .nameIn .sortSel .tag .pickBox .sec …).
   이름 앞에 p 를 붙여 다른 화면과 부딪히지 않게 한다. */

/* ── 왼쪽 단 ─────────────────────────────────────────────────────────── */
.pWide { width: 100%; }
.pWide input { width: 100%; }
.pGap { margin-top: var(--s-4); }
.pHint { margin-top: var(--s-2); }

.pDraft { align-items: flex-start; }
.pDraft.on .pDraftName { color: var(--red-ink); font-weight: 600; }
.pDraftName { display: flex; flex-direction: column; gap: 1px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pDraftDate { font-size: var(--fs-100); color: var(--ink-dim); font-weight: 400; }
.pDraft .rmX { opacity: 0; padding: 0 var(--s-1); }
.pDraft:hover .rmX, .pDraft.on .rmX { opacity: 1; }

.pDateRow { display: flex; align-items: center; gap: var(--s-2); margin-top: var(--s-3); }
.pDateIn {
  flex: 1; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .62); color: var(--ink);
  padding: 7px var(--s-2); font-size: var(--fs-300); font-family: var(--sans);
}
.pStep {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .62); color: var(--ink-sub);
  padding: 6px 9px; font-size: var(--fs-200); cursor: pointer; line-height: 1;
}
.pStep:hover { background: #fff; color: var(--red-ink); border-color: var(--ink-dim); }
.pHourSel { margin-left: 0; }

.pBtns { display: flex; flex-direction: column; gap: var(--s-2); }
.pBtns .btn { justify-content: flex-start; }
.pExp {
  display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center;
  margin-top: var(--s-3); padding: var(--s-3);
  background: rgba(255, 255, 255, .5); border: 1px solid var(--line); border-radius: var(--r-sm);
}
.pExp .sortSel { margin-left: 0; }

/* ── 계획 머리 ───────────────────────────────────────────────────────── */
.pPlanHead { padding: var(--s-2) 2px var(--s-4); border-bottom: var(--rule); margin-bottom: var(--s-5); }
.pTitle { font-family: var(--serif); font-size: var(--fs-700); line-height: var(--lh-heading); color: var(--ink); }
.pSubHead { font-size: var(--fs-200); color: var(--ink-dim); margin-top: var(--s-1); font-variant-numeric: tabular-nums; }

.pTools { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; margin-bottom: var(--s-4); }
.pFill { display: inline-flex; align-items: center; gap: var(--s-2); }
.pFill .magIn { width: 52px; }

/* 골라 빼기 줄 — 아래 고정 바(.pickBar)는 도감 '담기'가 쓰고 있어, 여기서는 자리에 둔다 */
.pSelBar {
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  padding: var(--s-3); margin-bottom: var(--s-4);
  background: rgba(154, 70, 50, .07); border: 1px solid rgba(154, 70, 50, .3); border-radius: var(--r-sm);
}
.pSelN { font-weight: 700; color: var(--red-ink); font-variant-numeric: tabular-nums; margin-right: var(--s-2); }

/* ── 시간표 · 별자리 머리글 ──────────────────────────────────────────── */
.pSlotHead, .pConHead {
  display: flex; align-items: baseline; gap: var(--s-3);
  padding: var(--s-3) var(--s-2);
  background: var(--sand-deep); border-bottom: var(--rule);
  cursor: pointer; font-size: var(--fs-300);
}
.pSlotHead:hover, .pConHead:hover { background: rgba(154, 70, 50, .08); }
.pSlot + .pSlot, .pCon + .pCon { margin-top: var(--s-4); }
.pSlot.empty .pSlotHead { background: none; border-bottom: var(--rule-hair); cursor: default; opacity: .55; }
.pSlot.empty .pSlotHead:hover { background: none; }
.pSlotTime { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.pArrow { color: var(--ink-dim); font-size: var(--fs-100); width: 12px; }
.pConHead b { font-size: var(--fs-400); color: var(--ink); }
.pConTime { font-size: var(--fs-200); color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.pSlotHead .cnt, .pConHead .cnt { margin-left: auto; font-size: var(--fs-100); color: var(--ink-dim); }

/* ── 천체 한 줄 — 두 줄짜리(이름·고도 / 유형·출몰) ───────────────────── */
.pRow {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-2);
  border-bottom: var(--rule-hair);
  font-size: var(--fs-300); line-height: var(--lh-snug);
}
.pRow:hover { background: rgba(154, 70, 50, .05); }
.pRow.sel { background: rgba(154, 70, 50, .1); }
.pMain { flex: 1; min-width: 0; }
.pLine1, .pLine2 { display: flex; align-items: baseline; gap: var(--s-3); min-width: 0; }
.pLine2 { margin-top: 2px; }
.pGrow { flex: 1; }
.pName {
  color: var(--ink); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60%;
}
.pName:hover { color: var(--red-ink); }
.pRow .muted { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.pAlt { font-size: var(--fs-200); color: var(--ink-sub); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pAlt.good { color: var(--red-ink); font-weight: 700; }
.pNow {
  font-size: var(--fs-200); color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap;
  margin-left: var(--s-3); padding-left: var(--s-3); border-left: 1px solid var(--line);
}
.pNow.dim { color: var(--ink-dim); }
.pT { font-size: var(--fs-200); color: var(--ink-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pT.star { color: var(--red-ink); font-weight: 600; }
.pT + .pT { margin-left: var(--s-3); }

.pGrp {
  font-size: var(--fs-100); color: var(--red-ink); cursor: pointer;
  border: 1px solid rgba(154, 70, 50, .45); border-radius: var(--r-pill); padding: 1px var(--s-2);
  white-space: nowrap;
}
.pGrp:hover { background: rgba(154, 70, 50, .1); }
/* 그 시각엔 지평선 아래인 천체 — 시간표에서만 뜬다 */
.pNotUp {
  font-size: var(--fs-100); font-weight: 700; color: var(--paper); background: var(--red);
  padding: 1px var(--s-2); border-radius: var(--r-sm); white-space: nowrap;
}
.pRow.kid { padding-left: var(--s-6); background: rgba(255, 255, 255, .3); }
.pKidNo { font-size: var(--fs-100); color: var(--ink-dim); font-variant-numeric: tabular-nums; width: 16px; }
.pSlotSel {
  border: 1px solid var(--line); border-radius: var(--r-sm); background: rgba(255, 255, 255, .62);
  color: var(--ink-sub); font-size: var(--fs-100); padding: 4px var(--s-2); cursor: pointer;
}
.pEmpty { padding: var(--s-6) 2px; }

@media (max-width: 640px) {
  .pDraft .rmX { opacity: 1; }         /* 손가락에는 hover 가 없다 */
  .pName { max-width: 100%; }
  .pLine1, .pLine2 { flex-wrap: wrap; }
  .pNow { margin-left: 0; padding-left: 0; border-left: 0; }
  .pSlotSel { display: none; }        /* 좁은 화면에서는 시간대 옮기기를 감춘다(줄이 두 겹으로 접힌다) */
}

/* 종이에 뽑아 들고 나가는 사람 — 고르기·시간대 상자는 인쇄하지 않는다.
   (지우기 ✕ 는 다른 화면도 쓰는 클래스라, 내 줄 안의 것만 골라 감춘다) */
@media print {
  .pTools, .pSelBar, .pSlotSel, .pRow .rmX, .pGrp { display: none !important; }
  .pRow, .pSlotHead, .pConHead { break-inside: avoid; }
  .pSlotHead { background: none; border-bottom: 1px solid #000; }
}
/* ==== /patch:plan ==== */

/* ==== patch:solar ==== */
/* 태양계 페이지 — style.css 에 없는 것만. 있는 것(.recTabs·.btn·.spec·.guide·.pt·.sec)은 그대로 쓴다. */

:root { --tl-name-w: 96px; }   /* 타임라인 왼쪽 이름 칸 — 축 눈금도 이 폭만큼 밀린다 */

/* 탭 줄 + 날짜 고르기 — 한 줄에 나란히, 좁으면 접힌다 */
.solBar {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap; margin-top: var(--s-5);
}
.solBar .recTabs { margin-top: 0; flex: 1 1 320px; }
.solDate { display: flex; align-items: center; gap: var(--s-2); padding-bottom: var(--s-2); }
.solDate .btn { padding: 6px 10px; }
.solDateIn {
  border: 1px solid var(--line); border-radius: var(--r-sm); background: rgba(255, 255, 255, .55);
  color: var(--ink); font-family: var(--sans); font-size: var(--fs-300); padding: 6px 8px;
}
.solDateIn:focus { outline: 2px solid var(--red); outline-offset: 1px; }

/* ── 출몰 타임라인 ── */
.tlBox { margin-top: var(--s-4); }
.tlAxis { display: flex; justify-content: space-between; font-size: var(--fs-200); color: var(--ink-sub); margin: 0 0 var(--s-2) var(--tl-name-w); }
.tlRow { display: flex; align-items: center; gap: var(--s-3); margin-bottom: 6px; }
.tlName {
  width: var(--tl-name-w); flex-shrink: 0; font-size: var(--fs-300); color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tlTrack {
  position: relative; flex: 1; height: 26px; border-radius: var(--r-sm);
  background: var(--sand-deep); border: 1px solid var(--line-soft); overflow: hidden;
}
.tlBar { position: absolute; top: 6px; height: 12px; border-radius: 3px; background: var(--red); }
.tlBar.full { background: #3c4670; }          /* 주극(밤새 떠 있음) — 인주와 구분되는 남색 */
.tlNow { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--red-ink); opacity: .75; }
.tlTime {
  position: absolute; top: 0; height: 26px; line-height: 26px;
  font-size: var(--fs-100); font-variant-numeric: tabular-nums; color: var(--ink-sub); white-space: nowrap;
}
.tlTime.rise { text-align: right; padding-right: 5px; }
.tlTime.set { padding-left: 5px; }
.tlNone { display: block; text-align: center; line-height: 26px; font-size: var(--fs-100); color: var(--ink-dim); }
.tlHint { text-align: right; font-size: var(--fs-100); color: var(--ink-dim); margin-top: var(--s-2); }

/* ── 천체 카드 — 넓은 화면에서는 여러 장이 나란히 ── */
.solGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: var(--s-5); margin-top: var(--s-4); }
.solCard {
  background: rgba(255, 255, 255, .55); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--s-4) var(--s-5) var(--s-4);
}
.solHead { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; margin-bottom: var(--s-3); }
.solName { font-family: var(--serif); font-size: var(--fs-600); color: var(--ink); font-weight: 600; }
.solTag {
  font-size: var(--fs-100); color: var(--ink-dim); border: 1px solid var(--line);
  border-radius: 3px; padding: 2px 7px;
}
.solPhase { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-300); color: var(--ink-sub); }
.solPhase svg { display: block; }

/* 정보 표 — 제원표(.spec)와 같은 결이되 값은 오른쪽에 */
.solInfo { width: 100%; border-collapse: collapse; font-size: var(--fs-300); }
.solInfo td { padding: 5px 0; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.solInfo tr:last-child td { border-bottom: 0; }
.solInfo td:first-child { color: var(--ink-dim); white-space: nowrap; width: 8.5em; }
.solInfo td:last-child { color: var(--ink); font-variant-numeric: tabular-nums; }
.solInfo .dim { color: var(--ink-dim); }
.solInfo b { color: var(--red-ink); font-weight: 700; }

/* 접었다 펴는 곳 — 목성 위성·안시 가이드 */
.solFold { border-top: 1px solid var(--line-soft); margin-top: var(--s-3); padding-top: var(--s-3); }
.solFoldBtn {
  display: flex; align-items: center; gap: 6px; width: 100%; background: none; border: 0; padding: 0;
  font-family: var(--sans); font-size: var(--fs-300); font-weight: 600; color: var(--ink); cursor: pointer; text-align: left;
}
.solFoldBtn:hover { color: var(--red-ink); }
.solFoldBtn .cnt { margin-left: auto; font-weight: 400; font-size: var(--fs-100); color: var(--ink-dim); }
.solFoldBody { padding-top: var(--s-3); }
.solFoldBody[hidden] { display: none; }
.solFoldBody .guide { font-size: var(--fs-300); line-height: var(--lh-body); }
.solFoldBody .guide h3 { font-size: var(--fs-400); margin-top: var(--s-4); }
.solFoldBody .guide p { margin-bottom: var(--s-3); }
.solPtHead { font-size: var(--fs-200); font-weight: 700; color: var(--ink-sub); margin: var(--s-4) 0 var(--s-2); }
.solFoldBody .pt { font-size: var(--fs-300); }

/* 목성 위성 현상 표 */
.solJup { width: 100%; border-collapse: collapse; font-size: var(--fs-300); }
.solJup td { padding: 4px 0; border-bottom: 1px solid var(--line-soft); }
.solJup tr:last-child td { border-bottom: 0; }
.solJup .m { color: var(--ink); }
.solJup .k { color: var(--ink-dim); }
.solJup .t { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); white-space: nowrap; }

/* 담기 줄 */
.solActs { display: flex; align-items: center; gap: var(--s-3); margin-top: var(--s-4); }
.solPick { display: inline-flex; align-items: center; gap: 7px; font-size: var(--fs-300); color: var(--ink-sub); cursor: pointer; }
.solPick:hover { color: var(--red-ink); }

.solNote { font-size: var(--fs-200); color: var(--ink-dim); line-height: var(--lh-body); margin-top: var(--s-5); }

@media (max-width: 720px) {
  :root { --tl-name-w: 68px; }
  .solGrid { grid-template-columns: 1fr; }
  .solDate { width: 100%; }
  .solDateIn { flex: 1; min-width: 0; }
}
/* ==== /patch:solar ==== */

/* 홈 출몰표 — 행성 이름을 누르면 태양계 화면으로 */
.snTlLink { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
.snTlLink:hover { color: var(--red); border-bottom-color: currentColor; }
.snMore { display: inline-block; margin-top: 8px; font-size: var(--fs-200); color: var(--red); }
.snMore:hover { text-decoration: underline; }

/* ==== patch:lists2 ==== */
/* 관측 목록 — 표 열 도구(열 머리로 줄 세우기·거르기)에 딸린 것만.
   열 머리 도구 자체의 모양(.ttH·.ttF·.ttPanel …)은 공용이라 여기서 손대지 않는다. */

/* 표 위 고르기 줄 오른쪽 끝에 붙는 한 줄 안내 — 열 머리에 도구가 있다는 것을 알려 준다 */
#listsPage .lstColHint { margin-left: auto; font-size: var(--fs-100); }

/* 열 머리에 도구가 들어가 칸이 좁아 보이지 않게, 이 표만 머리 좌우 여백을 조금 줄인다 */
#listsPage #lvTable table.list thead th { padding-inline: var(--s-2); }

@media (max-width: 720px) {
  /* 좁은 화면에서는 안내가 줄을 하나 더 잡아먹어 표가 밀린다 */
  #listsPage .lstColHint { display: none; }
}
/* ==== /patch:lists2 ==== */

/* ==== patch:plan2 ==== */
/* 관측 계획 — '남중시각순' 보기를 표로 바꾼 것만.
   넓은 화면에서는 줄보다 표가 읽기 쉽고, 열 머리에서 바로 줄 세우고 거를 수 있다.
   (시간표·별자리순 보기는 손대지 않았으므로 plan.css 의 .pRow 그대로다)

   표 머리 도구 자체의 모양(.ttH·.ttArr·.ttF·.ttPanel …)은 도감 쪽에서 한 번만 잡는다.
   여기서는 내 표(.ptTbl)와 그 칸만 손본다. 이름 앞에 pt 를 붙여 다른 화면과 부딪히지 않게 한다. */

/* 도감 표는 줄 아무 데나 눌러 천체를 여는데, 여기는 이름·✕ 만 눌린다.
   줄 전체가 손 모양이 되면 눌러도 아무 일이 없어 고장처럼 보인다. */
.ptTbl tbody tr { cursor: default; }
.ptTbl tbody tr.sel td { background: rgba(154, 70, 50, .1); }

/* 이름 — 줄 보기에서 쓰던 60% 폭 제한은 표에서는 이름을 괜히 자른다.
   칸 안에서는 접혀도 되니 폭 제한을 풀고 줄바꿈을 허락한다. */
.ptTbl .tName { min-width: 160px; }
.ptTbl .pName { max-width: none; white-space: normal; overflow: visible; }
.ptTbl .pGrp { margin-left: var(--s-2); }

/* 출·남중·몰 — 세 시각을 한 칸에 나란히 둔다(접히면 시각을 대조하기 어렵다) */
.ptTbl .ptTimes { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* 최대 고도 — '지금 고도'는 아랫줄로. 줄 보기에서 쓰던 세로 칸막이는 표에서 군더더기다 */
.ptTbl th.ptAltTh { text-align: right; }
.ptTbl .tAlt .pAlt, .ptTbl .tAlt .pNow { display: block; }
.ptTbl .tAlt .pNow { margin-left: 0; padding-left: 0; border-left: 0; }

.ptTbl .ptSlot { width: 92px; }
.ptTbl .ptSlot .pSlotSel { width: 100%; }
.ptTbl .ptX { width: 28px; text-align: right; }

/* 코스(그룹) 구성원 — 안쪽에 든 천체라는 것이 한눈에 보이게 들여 쓴다 */
.ptTbl tr.ptKid td { background: rgba(255, 255, 255, .34); }
.ptTbl tr.ptKid .tName { padding-left: var(--s-6); font-weight: 400; }
.ptTbl tr.ptKid .pKidNo { margin-right: var(--s-2); }

/* 열 조건이 걸려 한 줄도 안 남았을 때 */
.ptEmpty { color: var(--ink-dim); padding: var(--s-5) var(--s-3); }

/* 머리글 안에 접어 둔 조건은 잊기 쉽다 — 몇 칸이 걸렸는지 요약 줄에 붙여 두고 눌러 푼다 */
.ptChip {
  margin-left: var(--s-2); padding: 1px var(--s-2);
  font-size: var(--fs-100); color: var(--red-ink); white-space: nowrap; cursor: pointer;
  border: 1px solid rgba(154, 70, 50, .4); border-radius: var(--r-pill);
}
.ptChip:hover { background: rgba(154, 70, 50, .1); }

@media (max-width: 640px) {
  .ptTbl .tName { min-width: 0; }
}

/* 종이에 뽑아 들고 나가는 사람 — 고르기·시간대·지우기 칸은 인쇄하지 않는다.
   (plan.css 의 인쇄 규칙은 .pRow 안의 ✕ 만 감추므로 표의 것은 여기서 감춘다) */
@media print {
  .ptTbl .pickCell, .ptTbl .ptSlot, .ptTbl .ptX, .ptChip { display: none !important; }
  .ptTbl tbody tr { break-inside: avoid; }
}

/* ── 관측 계획 — 두 단계 ────────────────────────────────────────────────── */
.pWrap { max-width: 1080px; margin: 0 auto; }
.pAppLink { margin-top: var(--s-6); }

/* 계획 카드 — 고르는 화면 */
.pCard {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; margin-bottom: 8px;
  border: 1px solid var(--rule-color, rgba(0,0,0,.16)); border-radius: 10px;
}
.pCard.on { border-color: var(--red-ink); }
.pCardMain { flex: 1; min-width: 0; cursor: pointer; }
.pCardMain b { font-size: var(--fs-400); }
.pCardMain:hover b { text-decoration: underline; }
.pCardSub { margin-top: 2px; font-size: var(--fs-200); color: var(--ink-dim); }

/* 짜는 화면 머리 — 이 계획에 딸린 것을 한 줄에 */
.pBack { display: inline-block; margin-bottom: var(--s-3); color: var(--red-ink); font-weight: 600; cursor: pointer; }
.pHeadRow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pHeadRow .pTitle { font-size: var(--fs-600); cursor: pointer; }
.pHeadRow .pTitle:hover { text-decoration: underline; }
.pSubHead { margin-top: 6px; font-size: var(--fs-200); color: var(--ink-dim); }
.pDot { opacity: .5; }
.pWinPanel, .pExpMenu, .pFilterPanel {
  margin-top: var(--s-3); padding: 10px 12px;
  border: 1px solid var(--rule-color, rgba(0,0,0,.16)); border-radius: 8px;
}
.pWinPanel { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pExpMenu { display: flex; gap: 8px; flex-wrap: wrap; }
.pFilterPanel h3 { margin: 0 0 6px; font-size: var(--fs-200); }
.pFilterPanel .pGap { margin-top: 10px; }
/* ==== /patch:plan2 ==== */

/* ==== patch:recommend ==== */
/* 관측 천체 추천 — style.css 에 없는 것만.
   다른 페이지로 새지 않게 모두 #recPage 안에 두고, 이름도 rc 로 시작한다.
   (열 머리 도구·거르기 상자 자체의 모양은 도감 쪽에 한 벌만 둔다 — 여기서 또 쓰면 두 벌이 된다.) */

/* ── 열 조건 되돌리기 ── */
/* 열 머리로 건 조건은 왼쪽 단에 안 보인다. 표가 갑자기 짧아진 까닭을 짚고 한 번에 되돌릴 자리. */
#recPage .rcClear {
  font-size: var(--fs-200); color: var(--red-ink); cursor: pointer;
  border-bottom: 1px solid transparent; white-space: nowrap;
}
#recPage .rcClear:hover { border-bottom-color: currentColor; }
/* '전체 N개 중' — 결과 수 옆에 붙는 곁말이라 본 숫자보다 물러나 있어야 한다 */
#recPage .rcNote { font-size: var(--fs-200); color: var(--ink-dim); }

/* ── 열 조건에 아무것도 안 걸렸을 때 ── */
/* 표 머리는 남기고 몸만 이 한 줄로 바꾼다 — 머리가 사라지면 방금 건 조건을 되돌릴 데가 없다.
   천체 줄이 아니므로 누르는 손짓(커서·덧칠)은 지운다. */
#recPage table.list tbody tr.rcEmpty { cursor: default; }
#recPage table.list tbody tr.rcEmpty:hover td { background: none; }
#recPage table.list tbody tr.rcEmpty td {
  padding: var(--s-5) var(--s-3); color: var(--ink-dim);
  font-size: var(--fs-200); line-height: var(--lh-snug);
}
/* ==== /patch:recommend ==== */

/* ==== patch:lists3 ==== */
/* 관측 목록 — '＋ 새 목록 만들기' 자리와 2층 폴더에 딸린 것만.
   다른 페이지로 새지 않게 모두 #listsPage 안에 두고, 이름도 lst3- 로 시작한다. */

/* 목록 줄의 단추 묶음 — 폴더가 생기면서 줄마다 단추가 하나씩 늘었다.
   좁은 화면에서 표가 밀리지 않도록 오른쪽에 붙이되 줄바꿈을 허락한다. */
#listsPage .lst3Acts {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  align-items: center; justify-content: flex-end;
}
/* 단추가 다섯이라 기본 여백으로는 세 줄로 접힌다 — 이 칸에서만 좌우 여백을 줄여 한 줄에 앉힌다
   (▲▼ 는 이미 더 좁게 잡혀 있으므로 건드리지 않는다) */
#listsPage .lst3Acts .btn:not(.lstMv) { padding-inline: var(--s-3); }

/* 폴더 줄 — 하위를 거느린 줄이라는 것이 한눈에 보이게 살짝 도드라뜨린다 */
#listsPage tr.lst3FolderRow td { background: rgba(255, 255, 255, .5); }
#listsPage tr.lst3FolderRow td.tName { font-size: var(--fs-400); }

/* 폴더가 비었을 때 하위 자리에 뜨는 한 줄 */
#listsPage .lst3Empty { padding-left: 44px; font-size: var(--fs-200); }

/* 줄 아래에 펼쳐지는 고르는 자리(폴더에 넣기·묶음 해제) — 표 안이라 여백을 따로 준다 */
#listsPage tr.lst3Row td {
  background: rgba(255, 255, 255, .5);
  padding-block: var(--s-3);
}
#listsPage .lst3Pick {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2);
}

/* 갈래 고르기 — 단추 하나에 그 뜻 한 줄. 무엇을 고르는지 읽고 누르게 한다. */
#listsPage .lst3Opts { display: flex; flex-direction: column; gap: var(--s-2); }
#listsPage .lst3Opt {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3);
}
#listsPage .lst3Opt .btn { flex: none; min-width: 168px; }
#listsPage .lst3Hint { font-size: var(--fs-200); }

/* 프리셋 자리 머리줄 — 설명이 남는 자리를 다 쓰고 '뒤로' 가 오른쪽 끝에 붙게 */
#listsPage .lst3Grow { flex: 1; min-width: 0; }

@media (max-width: 720px) {
  #listsPage .lst3Acts { justify-content: flex-start; }
  #listsPage .lst3Opt .btn { min-width: 0; }
  /* 좁은 화면에서는 뜻풀이가 줄을 여럿 잡아먹어 단추가 멀어진다 */
  #listsPage .lst3Hint { display: none; }
  #listsPage .lst3Empty { padding-left: var(--s-3); }
}

/* 목록·폴더 이름을 눌러 연다 — '열기' 단추를 따로 두면 이름이 눌리는 줄 모르고 지나친다.
   글자 자체가 들어가는 문이라는 걸 밑줄로 알린다(누르기 전에는 얌전히). */
.tName .lstLink { cursor: pointer; border-bottom: 1px solid transparent; }
.tName .lstLink:hover { border-bottom-color: currentColor; }

/* 목록 설명 — 제목 아래 한 줄 */
.lvDesc { margin: -2px 2px var(--s-3); font-size: var(--fs-200); color: var(--ink-dim); }
.lvDesc:empty { display: none; }
/* 편집 중에만 뜨는 줄 — 고치는 단추를 한데 모은다 */
.lstEditActs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: -4px; }
/* 표 머리의 고르기 네모 — 반만 골랐으면 반쯤 찬 모양 */
.pickBox.half { background: linear-gradient(to bottom, var(--red-ink) 50%, transparent 50%); }
th.pickCell .pickBox { cursor: pointer; }

/* 천체 그룹 구성원 — 펼치면 칩으로 늘어놓고, 편집 중에만 ✕ 가 붙는다 */
.grpMembers { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 2px 10px; }
.grpChip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px; border: 1px solid var(--rule-color, rgba(0,0,0,.18)); border-radius: 999px;
  font-size: var(--fs-200);
}
.grpChip a { color: inherit; text-decoration: none; }
.grpChip a:hover { text-decoration: underline; }
.grpX { cursor: pointer; color: var(--ink-dim); font-size: var(--fs-200); }
.grpX:hover { color: var(--red-ink); }
/* ==== /patch:lists3 ==== */

/* ==== patch:mdcolor ==== */
/* 안시 가이드·관측 포인트의 강조 — 앱 MarkdownText 와 같은 색 규칙.
   소제목은 푸른색, **굵게** 는 주황, *강조* 는 붉은색. 글쓴이가 색으로 뜻을 나눠 둔 것이라
   웹에서 검은 볼드로만 그리면 그 구분이 사라진다. (야간 팔레트는 웹에 없어 주간 색만 쓴다)
   선택자를 .guide 안까지 적은 것은, 앞서 있는 `.guide b { color: #1f1a12 }` 가
   특이도로 이기기 때문이다. */
.guide h3 { color: #2F6BA3; }
.guide b.mdStrong, .pt b.mdStrong { color: #BF7327; font-weight: 700; }
.guide b.mdEm, .pt b.mdEm { color: #B23B30; font-weight: 700; }
/* ==== /patch:mdcolor ==== */

/* ==== patch:chart ==== */
/* 간략 성도(chart.js) — 캔버스와 확대·축소 단추 */

.skChart { position: relative; line-height: 0; }

/* 캔버스는 그림 크기를 속에 지니고, 겉으로는 자리 폭에 맞춰 늘어난다.
   touch-action: pan-y — 손가락 하나로는 페이지가 그대로 세로로 넘어가고,
   두 손가락일 때만 chart.js 가 확대·이동을 가져간다. */
.skChart .skCanvas {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 9px;
  touch-action: pan-y;
  cursor: grab;
  outline: none;
}
.skChart .skCanvas.isDrag { cursor: grabbing; }
.skChart .skCanvas:focus-visible { box-shadow: 0 0 0 2px rgba(255, 211, 77, 0.7); }

/* 단추는 성도 오른쪽 위에 얹는다 — 별이 가장 덜 가려지는 자리다. */
.skChart .skTools {
  position: absolute;
  top: 7px;
  right: 7px;
  display: flex;
  gap: 4px;
  line-height: 1;
}
.skChart .skBtn {
  min-width: 25px;
  height: 25px;
  padding: 0 7px;
  border: 1px solid rgba(180, 196, 236, 0.28);
  border-radius: 7px;
  background: rgba(12, 18, 38, 0.66);
  color: #dfe6ff;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  transition: background 0.12s, border-color 0.12s;
}
.skChart .skBtn:hover { background: rgba(30, 44, 84, 0.86); border-color: rgba(200, 214, 250, 0.5); }
.skChart .skBtn:active { background: rgba(45, 62, 110, 0.9); }
.skChart .skIn, .skChart .skOut { font-size: 13px; padding: 0 4px; }

@media (max-width: 640px) {
  .skChart .skTools { top: 5px; right: 5px; gap: 3px; }
  .skChart .skBtn { height: 23px; font-size: 11px; padding: 0 6px; }
}

/* 인쇄물에는 단추가 뜻이 없다 */
@media print { .skChart .skTools { display: none; } }
/* ==== /patch:chart ==== */

/* ==== patch:sketch ==== */
/* 관측 스케치 — 천체 상세의 가이드 위에 놓인 도판.
   책의 도판처럼 다루었다. 종이 위에 판을 얹고, 아래에 설명과 관측 자료를 붙인다.
   본문 쪽은 #objPage 안으로 가두고, 크게 보기는 <body> 에 붙으므로 .skLb 제 이름을 쓴다. */

/* 도판 — 그림이 종이 위에 얹힌 한 장으로 보이게. 폭은 읽는 글보다 살짝 넓게 둔다. */
#objPage .skFig { margin: 0; max-width: 640px; }

#objPage .skStage {
  display: block; width: 100%; padding: 0; line-height: 0;
  border: var(--rule); background: var(--paper);
  cursor: zoom-in;
}
/* 검정 바탕 스케치(아이피스에서 본 모습)는 그림 가장자리가 종이와 부딪힌다.
   그 판만 테두리·바탕을 밤하늘 쪽으로 맞춰, 잘린 네모가 아니라 창처럼 보이게 한다. */
#objPage .skStage.dark { background: var(--night-0); border-color: var(--night-0); }
#objPage .skStage img { display: block; width: 100%; height: auto; }
#objPage .skStage:hover { border-color: var(--ink-dim); }
#objPage .skStage.dark:hover { border-color: var(--night-2); }

/* 그림 갈아 끼우기 — 검정 완성본 ↔ 연필 원화 */
#objPage .skFlip { display: flex; gap: var(--s-2); margin-top: var(--s-3); flex-wrap: wrap; }
#objPage .skTab {
  font-family: var(--sans); font-size: var(--fs-100); color: var(--ink-sub);
  background: none; border: var(--rule); border-radius: var(--r-pill);
  padding: 4px var(--s-3); cursor: pointer;
}
#objPage .skTab:hover { border-color: var(--ink-dim); color: var(--ink); }
#objPage .skTab.on { background: var(--red); border-color: var(--red); color: #fff; font-weight: 700; }

/* 관측 노트 — 그린 이가 그날 적은 글. 본문 산문과 같은 결로 읽히게 한다. */
#objPage .skNote {
  margin-top: var(--s-4); font-size: var(--fs-300); line-height: var(--lh-body);
  color: var(--ink); text-wrap: pretty;
}
/* 이름은 .skLb 로 짧게 두면 안 된다 — 아래 '크게 보기' 덮개가 그 이름을 쓰고 있어,
   덮개의 position:fixed·inset:0 이 이 작은 꼬리표에도 걸려 화면을 통째로 가린다(겪었다). */
#objPage .skNote .skNoteLb {
  display: block; margin-bottom: var(--s-1);
  font-size: var(--fs-100); letter-spacing: var(--ls-caps); color: var(--ink-dim);
}

/* 관측 자료 — 곁단 제원표와 같은 표를 쓰되, 본문 폭에서는 이름 칸이 좁아야 읽기 좋다 */
#objPage table.skMeta { margin-top: var(--s-4); }
#objPage table.skMeta td:first-child { width: 96px; }

/* 원본 보기 — 손글씨가 든 전체 스캔. 눌러야 받으므로 여기서 무엇인지 밝혀 둔다 */
#objPage .skOrig {
  display: block; width: 100%; margin-top: var(--s-4);
  font-family: var(--sans); font-size: var(--fs-200); color: var(--ink-sub); text-align: center;
  background: var(--sand-deep); border: var(--rule); border-radius: var(--r-md);
  padding: var(--s-3); cursor: pointer;
}
#objPage .skOrig:hover { border-color: var(--ink-dim); color: var(--ink); }

/* 저작권 한 줄 — 남의 저작물이라 반드시 함께 둔다 */
#objPage .skCr { margin: var(--s-3) 0 0; font-size: var(--fs-100); color: var(--ink-dim); line-height: var(--lh-snug); }

/* ── 크게 보기 ──────────────────────────────────────────────────────────
   그림만 보도록 화면을 어둡게 덮는다. 빈 곳·닫기·Esc 로 닫힌다. */
.skLb {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(6, 8, 20, .93);
  display: flex; align-items: center; justify-content: center;
  padding: var(--s-4);
}
.skLbBox { width: min(960px, 100%); max-height: 100%; display: flex; flex-direction: column; gap: var(--s-3); }
.skLbBar { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.skLbName { font-size: var(--fs-200); color: var(--night-txt); }
.skLbBtn {
  font-family: var(--sans); font-size: var(--fs-200); color: var(--night-txt);
  background: none; border: 1px solid rgba(219, 228, 245, .35); border-radius: var(--r-md);
  padding: 5px var(--s-3); cursor: pointer;
}
.skLbBtn:hover:not(:disabled) { border-color: var(--night-txt); }
.skLbBtn:disabled { opacity: .3; cursor: default; }
/* 그림 자리 — 세로로 긴 원본 스캔도 화면 안에 다 들어오도록 높이로 가둔다 */
.skLbImg { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; cursor: zoom-in; }
/* width·height 를 auto 로 두는 것이 중요하다 — 그림에 적어 둔 크기(자리 미리 잡기용)를
   그대로 쓰면 가로가 900px 로 굳어, 세로만 줄어들고 양옆에 흰 띠가 남는다.
   둘 다 auto 여야 두 max 값에 맞춰 비율대로 함께 줄어든다. */
.skLbImg img { width: auto; height: auto; max-width: 100%; max-height: 74vh; background: #fff; }
.skLbImg.dark img { background: transparent; }
/* 실제 크기로 펴기 — 손글씨가 든 원본은 화면에 맞추면 절반으로 줄어 글씨가 안 읽힌다.
   칸을 스크롤되게 두고 그림은 원래 크기(가로 900px)로 놓는다. */
.skLbImg.zoom { overflow: auto; align-items: flex-start; justify-content: flex-start; cursor: zoom-out; }
.skLbImg.zoom img { max-width: none; max-height: none; }
.skLbNav { display: flex; align-items: center; justify-content: center; gap: var(--s-4); }
.skLbPos { font-size: var(--fs-100); color: var(--night-sub); font-variant-numeric: tabular-nums; }
.skLbHint { margin: 0; text-align: center; font-size: var(--fs-100); color: var(--night-sub); }

/* 좁은 화면 — 도판을 폭 가득, 크게 보기는 여백을 줄여 그림을 키운다 */
@media (max-width: 640px) {
  #objPage .skFig { max-width: 100%; }
  .skLb { padding: var(--s-2); }
  .skLbImg img { max-height: 68vh; }
}

/* 인쇄 — 크게 보기는 종이에 나오지 않는다 */
@media print { .skLb { display: none; } }

/* ── 사이드바로 옮긴 스케치 (성도 위, 같은 폭) ──
   좁은 칸이라 ①그림 위 좌우 화살표로 넘기고 ②노트·기본정보는 접어 둔다. */
.skBox .skFig { margin: 0; }
.skStageWrap { position: relative; }
.skStageWrap .skStage { width: 100%; }
.skArrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 30px; height: 44px; border: 0; cursor: pointer;
  background: rgba(20, 22, 30, .42); color: #fff; font-size: 15px; line-height: 1;
  opacity: 0; transition: opacity .12s;
}
.skArrow.l { left: 0; border-radius: 0 4px 4px 0; }
.skArrow.r { right: 0; border-radius: 4px 0 0 4px; }
.skStageWrap:hover .skArrow, .skArrow:focus-visible { opacity: 1; }
.skArrow:hover { background: rgba(20, 22, 30, .68); }
/* 손가락으로 쓰는 화면은 hover 가 없어, 화살표를 늘 옅게 보인다 */
@media (hover: none) { .skArrow { opacity: .8; } }
.skDots {
  position: absolute; left: 0; right: 0; bottom: 5px; text-align: center;
  font-size: 9px; letter-spacing: 2px; color: rgba(255, 255, 255, .75); pointer-events: none;
}

.skFold {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  margin-top: 8px; padding: 6px 2px; background: none; border: 0; cursor: pointer;
  font-family: inherit; font-size: var(--fs-200); color: var(--ink-sub);
  border-top: 1px solid var(--line);
}
.skFold:hover { color: var(--red); }
.skCaret { font-size: 10px; color: var(--ink-dim); }
.skFoldBody[hidden] { display: none; }
.skFoldBody .skNote { font-size: var(--fs-100); line-height: var(--lh-body); color: var(--ink-sub); padding: 2px 0 6px; }
.skFoldBody .skMeta { width: 100%; }

/* 그림을 배경으로 깐다 — 우클릭 '이미지를 다른 이름으로 저장'이 안 잡힌다.
   (화면 갈무리는 못 막는다 — 그 몫은 그림에 새긴 워터마크가 맡는다) */
.skImg {
  width: 100%; background-size: contain; background-position: center; background-repeat: no-repeat;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
.skImg.big { max-height: 84vh; }

/* 워터마크 — 그림 위에 겹쳐 둔다.
   화면 갈무리는 화면을 그대로 찍으므로 이 글자도 함께 찍힌다. 그림 파일 자체에 굽는 편이
   더 낫지만, 이 저장소의 이미지 도구(jimp-compact)에 글꼴이 빠져 있어 글자를 못 굽는다.
   모서리에 은은하게(사용자 확정) — 감상을 거의 안 방해하면서 출처는 따라간다. */
.skImg.wm { position: relative; }
.skImg.wm::after {
  content: attr(data-wm);
  position: absolute; right: 6px; bottom: 5px;
  font-size: 9px; letter-spacing: .01em; white-space: nowrap;
  color: rgba(255, 255, 255, .62);
  text-shadow: 0 0 3px rgba(0, 0, 0, .85), 0 1px 2px rgba(0, 0, 0, .7);
  pointer-events: none; user-select: none;
}
.skImg.big.wm::after { right: 12px; bottom: 10px; font-size: 12px; }

/* 사이드바 칸 접기 — 성도·스케치 머리글 */
.sFold {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  background: none; border: 0; padding: 0 0 4px; cursor: pointer;
  font-family: var(--serif); font-size: var(--fs-400); font-weight: 600; color: var(--ink);
}
.sFold:hover { color: var(--red); }
.sCaret { font-size: 11px; color: var(--ink-dim); }

/* 천체 상세 사이드바 — 칸 사이 여백을 1/3 로(48px → 16px, 사용자 지정).
   스케치·성도·제원·속한 그룹·오늘 밤이 세로로 이어지는 자리라, 기본 여백으로는
   한 화면에 두 칸밖에 안 들어왔다. 머리글 아래 여백도 함께 좁힌다. */
#objPage .colSide .sbox { margin-bottom: var(--s-4); }
#objPage .colSide .sbox h2,
#objPage .colSide .sFold { margin-bottom: var(--s-2); padding-bottom: 5px; }
/* ==== /patch:sketch ==== */

/* ==== patch:applink ==== */
/* 앱과 주고받기 — 세 화면에 같은 모양. 서버가 붙기 전이라 누르면 안내만 뜬다. */
.alBar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 8px 0 4px; }
.alBtn { white-space: nowrap; }
.alSoon {
  font-size: var(--fs-100); color: var(--ink-dim);
  border: 1px solid var(--line); border-radius: var(--r-pill); padding: 1px 8px;
}
/* ==== /patch:applink ==== */

/* ==== patch:pickways ==== */
/* 무엇으로 담을까 고르는 상자 — 앱의 '천체 추가 방식' 과 같은 얼개 */
.pkWays { display: flex; flex-direction: column; gap: var(--s-2); }
.pkWay {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: var(--s-3) var(--s-4); border: 1px solid var(--line);
  border-radius: 10px; background: var(--paper);
  font: inherit; color: inherit;
}
.pkWay:hover { border-color: var(--ink-3); background: var(--paper-2); }
.pkWay b { display: block; font-size: var(--fs-300); font-weight: 600; }
.pkWay span { display: block; margin-top: 2px; font-size: var(--fs-200); color: var(--ink-3); }
/* ==== /patch:pickways ==== */

/* ==== patch:recbox ==== */
/* 추천 판정 — 제원 표 밖의 제 칸(가장 먼저 묻는 것이라 위에 둔다) */
.recLine { display: flex; gap: var(--s-3); padding: 3px 0; align-items: baseline; }
.recLb { flex: 0 0 auto; min-width: 68px; color: var(--ink-dim); font-size: var(--fs-200); }
.recVal { flex: 1 1 auto; font-size: var(--fs-300); color: var(--ink); }
.recStars { color: var(--red); letter-spacing: 1px; }
.recNeed { color: var(--red-ink); }

.recSel {
  padding: 2px 6px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-300);
}
.recFrom { margin-left: var(--s-2); font-size: var(--fs-100); color: var(--ink-dim); }
/* ==== /patch:recbox ==== */

/* ==== patch:objcard ==== */
/* 천체 이름표 — 밤하늘 머리에서 내려온 이름·표기·별명·요약.
   가이드 바로 위, 곧 '읽기 시작하는 자리' 다. 이름은 이 쪽에서 가장 큰 글자(h1)라
   가이드 소제목(h2, --fs-700)보다 한 단 크게 두고, 제목용 명조로 적는다. */
.headThin { padding-bottom: var(--s-4); }
.headThin .crumb { margin-bottom: 0; }

.objCard {
  margin-bottom: var(--s-5);
  padding-bottom: var(--s-4);
  border-bottom: 2px solid var(--line);
}
.objCardTop { display: flex; align-items: flex-start; gap: var(--s-4); }
.objCard h1 {
  flex: 1 1 auto; margin: 0;
  font-family: var(--serif);
  font-size: var(--fs-800); font-weight: 700;
  line-height: var(--lh-display); letter-spacing: var(--ls-display);
  color: var(--ink);
}
.objCard h1 small {
  display: inline-block; margin-left: var(--s-2);
  font-family: var(--sans);
  font-size: var(--fs-400); font-weight: 500;
  letter-spacing: var(--ls-body); color: var(--ink-sub);
}
.objCard .obGroupTag {
  display: inline-block; margin-left: var(--s-2); vertical-align: middle;
  padding: 1px 8px; border-radius: 999px;
  background: rgba(154, 70, 50, .10); color: var(--red-ink);
  font-family: var(--sans);
  font-size: var(--fs-100); font-weight: 600; letter-spacing: var(--ls-caps);
}
.objAdd { flex: 0 0 auto; margin-top: 6px; }

/* 표기 칩 — 종이 위라 테두리로 가른다(밤하늘에서는 밝은 면이었다) */
.objCard .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s-3); }
.objCard .chip2 {
  padding: 2px 9px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--paper); color: var(--ink-sub);
  font-size: var(--fs-200); line-height: 1.7; cursor: pointer;
  transition: border-color .12s, color .12s;
}
.objCard .chip2:hover { border-color: var(--ink-dim); color: var(--ink); }
.objCard .chip2.pri { border-color: var(--ink-dim); color: var(--ink); font-weight: 600; }
.objCard .chip2.sky { border-color: var(--red); color: var(--red-ink); }

.objCard .obNick { margin-top: var(--s-3); font-size: var(--fs-300); color: var(--ink-sub); }
.objCard .obNick .lb { margin-right: var(--s-2); font-size: var(--fs-200); color: var(--ink-dim); }
.objCard .obNick b { font-weight: 600; color: var(--ink); }

.objCard .quick { margin-top: var(--s-3); font-size: var(--fs-200); color: var(--ink-dim); }
.objCard .quick b { font-weight: 600; color: var(--ink-sub); }

@media (max-width: 640px) {
  .objCardTop { flex-direction: column; gap: var(--s-3); }
  .objAdd { align-self: flex-start; margin-top: 0; }
}

/* 이름 옆 좌우 넘기기 — 보던 목록의 앞·뒤 천체 */
.objStep { display: inline-flex; align-items: center; gap: 2px; margin-top: 8px; flex: 0 0 auto; }
.osBtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--paper);
  color: var(--ink-sub); font-size: 17px; line-height: 1; text-decoration: none;
}
.osBtn:hover { border-color: var(--ink-dim); color: var(--ink); }
.osBtn.off { opacity: .3; }
.osPos {
  min-width: 54px; text-align: center;
  font-size: var(--fs-100); color: var(--ink-dim); font-variant-numeric: tabular-nums;
}

/* 스케치 그린 이 옆 이메일 — 작자 표시(앱과 같은 주소) */
.skMail { color: var(--red-ink); text-decoration: none; border-bottom: 1px solid rgba(154, 70, 50, .35); }
.skMail:hover { border-bottom-color: var(--red); }
/* ==== /patch:objcard ==== */

/* ==== patch:objband ==== */
/* 「오늘 밤 이 천체」 띠 — 밤하늘 머리 위. 종이 위 부품(.snTl*)과 같은 셈법이되
   색은 밤하늘 팔레트로 다시 입힌다(종이 색을 그대로 쓰면 어두운 배경에서 안 보인다). */
.obBand { padding-block: var(--s-6) var(--s-7); }
.obBandName {
  margin: 0 0 var(--s-4);
  font-family: var(--serif);
  font-size: var(--fs-700); font-weight: 700;
  line-height: var(--lh-display); letter-spacing: var(--ls-display);
  color: #fff;
}
.obBandName small {
  font-family: var(--sans); font-size: var(--fs-300); font-weight: 400;
  letter-spacing: 0; color: var(--night-sub); margin-left: var(--s-3);
}

.obTn { max-width: 640px; }
.obTnTop {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap; margin-bottom: var(--s-2);
}
.obNow { display: flex; align-items: baseline; gap: var(--s-2); }
.obNowAlt {
  font-size: var(--fs-600); font-weight: 700; color: var(--gold);
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
.obNowAlt.dim { font-size: var(--fs-400); color: var(--night-dim); font-weight: 600; }
.obNowAz { font-size: var(--fs-400); color: var(--night-txt); }
.obNowState { font-size: var(--fs-200); color: var(--night-dim); }

.obTimes { display: flex; gap: var(--s-4); flex-wrap: wrap; }
.obT {
  font-size: var(--fs-300); color: var(--night-txt);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.obT i { font-style: normal; margin-right: 4px; color: var(--night-dim); }
.obT b { font-weight: 600; color: var(--gold); }

/* 밤 시간 막대 — 일몰 0% ~ 다음 날 일출 100% */
.obTrack {
  position: relative; height: 18px; border-radius: 3px;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .14);
  overflow: hidden;
}
.obBar {
  position: absolute; top: 4px; height: 8px; border-radius: 2px;
  background: linear-gradient(90deg, rgba(255, 215, 106, .75), rgba(255, 215, 106, .95));
}
.obBar.full { background: rgba(140, 160, 230, .8); }   /* 주극성 — 밤새 떠 있다 */
.obNowLine { position: absolute; top: 0; bottom: 0; width: 1.5px; background: #fff; }
.obNone {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-100); color: var(--night-dim);
}
.obAxis {
  display: flex; justify-content: space-between; margin-top: 4px;
  font-size: var(--fs-100); color: var(--night-dim);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
  .obBandName { font-size: var(--fs-600); }
  .obBandName small { display: block; margin: 4px 0 0; }
  .obTnTop { gap: var(--s-2); }
  .obTimes { gap: var(--s-3); font-size: var(--fs-200); }
}
/* ==== /patch:objband ==== */

/* ==== patch:herowhere ==== */
/* 첫 화면 관측 위치 유도 — 히어로 단추 바로 아래. 밤하늘 위라 밝은 글자에 은은한 테두리.
   정하고 나면 사라진다(hidden). */
.heroWhere {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  margin-top: var(--s-4); padding: var(--s-3) var(--s-4);
  border: 1px dashed rgba(255, 215, 106, .38); border-radius: var(--r-md, 10px);
  background: rgba(255, 255, 255, .05);
  font-size: var(--fs-200); color: var(--night-sub); line-height: var(--lh-snug);
}
.heroWhere .snSetBtn {
  flex: 0 0 auto; cursor: pointer;
  padding: 4px 12px; border: 1px solid var(--gold); border-radius: var(--r-pill, 999px);
  background: transparent; color: var(--gold);
  font: inherit; font-weight: 600;
}
.heroWhere .snSetBtn:hover { background: rgba(255, 215, 106, .14); }
/* ==== /patch:herowhere ==== */

/* ==== patch:recset ==== */
/* 추천 설정 — 표 위 접이식. 세로로 늘어놓은 라디오 목록은 1,200px 을 넘겨 화면을 다 먹었다.
   전부 칩 한 줄로 눕히고, 축은 왼쪽 이름표 + 오른쪽 값으로 나란히 둔다. */
.recSet {
  margin-bottom: var(--s-4);
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--sand-deep); overflow: hidden;
}
.recSetHead {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%; padding: var(--s-3) var(--s-4);
  background: none; border: 0; cursor: pointer; font: inherit; color: inherit; text-align: left;
}
.recSetHead b { flex: 0 0 auto; font-size: var(--fs-300); font-weight: 700; }
.recSetSum {
  flex: 1 1 auto; min-width: 0; font-size: var(--fs-200); color: var(--ink-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.recSetCaret { flex: 0 0 auto; font-size: 17px; color: var(--ink-dim); transition: transform .15s; }
.recSet.open .recSetCaret { transform: rotate(180deg); }
.recSetBody { padding: var(--s-2) var(--s-4) var(--s-4); border-top: 1px solid var(--line-soft); }

/* 축 한 줄 = 왼쪽 켬/끔 + 오른쪽 값들 */
.rsRow { display: flex; align-items: flex-start; gap: var(--s-3); padding: var(--s-3) 0; }
.rsRow + .rsRow { border-top: 1px solid var(--line-soft); }
.rsAx {
  flex: 0 0 158px; display: flex; align-items: center; gap: 6px;
  cursor: pointer; font-size: var(--fs-200); padding-top: 2px;
}
.rsAx b { font-weight: 600; }
.rsAxPlain { cursor: default; color: var(--ink-dim); font-weight: 600; }
.rsVal { flex: 1 1 auto; min-width: 0; }

.rsLine { display: flex; align-items: flex-start; gap: var(--s-2); padding: 3px 0; }
.rsLb {
  flex: 0 0 76px; padding-top: 4px;
  font-size: var(--fs-100); color: var(--ink-dim); font-weight: 600;
}
.rsChips { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
/* 도감 목록은 쉰 개가 넘는다 — 두 줄까지만 펴고 그 안에서 구르게 */
.rsChipsScroll { max-height: 84px; overflow-y: auto; align-content: flex-start; }
.rsMm { flex: 0 0 62px; margin-left: 4px; }

/* 칩 */
.rcChip {
  display: inline-block; padding: 2px 9px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--paper); color: var(--ink-sub);
  font-size: var(--fs-200); line-height: 1.6; cursor: pointer; white-space: nowrap;
}
.rcChip:hover { border-color: var(--ink-dim); color: var(--ink); }
.rcChip.on { border-color: var(--red); background: rgba(154, 70, 50, .10); color: var(--red-ink); font-weight: 600; }
.rcChip i { font-style: normal; color: var(--ink-dim); font-size: var(--fs-100); }
.rcChip.on i { color: var(--red-ink); opacity: .75; }
.rcHint { font-size: var(--fs-100); }
.recResetLink { margin-left: var(--s-2); font-size: var(--fs-100); color: var(--red-ink); cursor: pointer; }

@media (max-width: 700px) {
  .rsRow { flex-direction: column; gap: var(--s-2); }
  .rsAx { flex: none; }
  .rsLb { flex: 0 0 64px; }
}
/* ==== /patch:recset ==== */

/* ==== patch:tocfold ==== */
/* 목차 접기 — 제목 옆 작은 '‹' 는 눈에 안 띄었다. 정렬 상자 옆에 글자 있는 단추로 둔다. */
.tocTools { display: flex; align-items: center; gap: 6px; }
.tocTools .tocSel { flex: 1 1 auto; min-width: 0; }
.tocFoldBtn {
  flex: 0 0 auto; cursor: pointer;
  padding: 3px 9px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--paper); color: var(--ink-sub);
  font: inherit; font-size: var(--fs-100); white-space: nowrap;
}
.tocFoldBtn:hover { border-color: var(--ink-dim); color: var(--ink); }

/* 접혀 있을 때 다시 펴는 손잡이도 또렷하게(테두리·바탕을 준다) */
.tocHandle {
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--sand-deep); color: var(--ink-sub);
  padding: 10px 4px;
}
.tocHandle:hover { border-color: var(--ink-dim); background: var(--paper); color: var(--ink); }

/* 목차 묶음 머리글 — 눌러서 접는다(별자리순·폴더 하위 목록) */
.tocGroup {
  /* 붙박이(sticky) 를 끈다 — 접으면 머리글끼리 같은 자리에 눌어붙어 글자가 겹쳐 보였다.
     탐색은 이제 접기가 맡으므로 붙박이가 없어도 불편하지 않다.
     배경도 비워 두면 안 된다(뒤 글자가 비친다) — 종이색으로 채운다. */
  position: static;
  display: flex; align-items: center; gap: 4px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 6px 4px; margin-top: 4px;
  background: var(--sand-deep); border: 0; border-bottom: 1px solid var(--line);
  border-radius: 4px;
  font: inherit; font-size: var(--fs-100); font-weight: 700; color: var(--ink-sub);
}
.tocGroup:hover { color: var(--ink); background: var(--paper); }
.tocGrpArrow { flex: 0 0 auto; font-size: 13px; color: var(--ink-dim); }
.tocGroup .tocCnt { margin-left: auto; font-weight: 400; }
/* ==== /patch:tocfold ==== */

/* ==== patch:homeboard ==== */
/* 첫 화면 관측 위치 — 정하기 전에는 권하고, 정한 뒤에도 '무엇을 기준으로 셈하는지' 를 남긴다 */
.heroWhere.hwDone {
  border-style: solid; border-color: rgba(255, 255, 255, .16);
  background: rgba(255, 255, 255, .04);
}
.heroWhere .hwSet { color: var(--night-sub); }
.heroWhere .hwSet b { color: #fff; font-weight: 600; }

/* 홈 미니 게시판 — 계획 줄(이름·날짜·천체 수, 지난 것은 옅게 + ✕) */
.bPlanRow { display: flex; align-items: center; gap: var(--s-2); }
.bPlanRow .bName { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bPlanMeta { color: var(--ink-dim); font-size: var(--fs-100); font-weight: 400; }
.bPlanRow.past .bName, .bPlanRow.past .bPlanMeta { color: var(--ink-dim); opacity: .65; }
.bPlanX {
  flex: 0 0 auto; cursor: pointer;
  width: 22px; height: 22px; line-height: 1; padding: 0;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--paper); color: var(--ink-dim); font-size: 12px;
}
.bPlanX:hover { border-color: var(--red); color: var(--red-ink); }

/* 목록 줄 — 관측 진도 막대 */
.bListRow { display: block; }
.bListTop { display: flex; align-items: baseline; gap: var(--s-2); }
.bListTop .bName { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bBar {
  display: block; height: 5px; margin-top: 5px; border-radius: 3px;
  background: var(--line-soft); overflow: hidden;
}
.bBar i { display: block; height: 100%; background: var(--red); border-radius: 3px; }
/* ==== /patch:homeboard ==== */
