@font-face { font-family: "Pretendard Variable"; font-style: normal; font-weight: 300 800; font-display: swap; src: url("assets/fonts/PretendardVariable.subset.woff2") format("woff2-variations"); } /* self-hosted subset: KS X 1001 + every character the app and data use (OFL, assets/fonts/Pretendard-OFL.txt); anything else falls to IBM Plex Sans KR */
/* ---- tokens (palette B: moss green, wine, amber) ---- */
:root {
  --icon-sm: 20px; /* 작은 아이콘 한 변(칸 안의 svg: 줄 앞 그림, 버튼 안 아이콘) */
  --icon-row: 48px; /* card: how far the camera / share row stands off the foot of the photo or the placeholder (see .ph-hero) */
  --paper: #f2f2f7; /* grouped-list grey (애플 결); the logo paper stays --logo-paper */
  --logo-paper: #f4f2ec; /* the logo's paper: manifest background_color, the app icons and the loading screen share it, so the OS start screen hands over without a seam */
  --sheet: #fff;
  --panel: #e5e5ea;
  --open-past: #cddacd;
  --soon: #d70015;
  --sun: #ff9f0a;
  --off: #d0d4cb;
  --gone: #c7c7cc; /* the part of a bar that has passed: a mid grey (3:1 on the page), apart from the open colour; dark below */
  --hair: #e9e7e0;
  --bg: var(--paper);
  --surface: var(--sheet);
  --sunken: rgba(118, 118, 128, .16);
  --fg: #111114;
  --muted: #5c5c63;
  --line: rgba(60, 60, 67, .14);
  --line-strong: #bcb8ac;
  --wall: #2a2d32; /* the logo's wall: the slider's passed stretch (dark: the paper) */
  --sun-ui: #a35000; /* the sun as a mark that must read on the page (3:1): the slider's thumb, the lit 내 위치 pin; dark below */
  --open: #1e7e34;        /* text on surface */
  --open-bar: #34c759; /* day bar fill */
  --warn: var(--soon);    /* text on surface */
  --rain-tint: color-mix(in srgb, var(--warn) 8%, var(--surface)); /* 비 예보 알약의 연분홍 면(2026-11-07 승인): 글자는 --warn, 어두운 테마도 같이 따라감 */
  --sun-bar: var(--sun);
  --point: #3f6c9e; /* 포인트(2026-11-05): 지금 고른 시각만 — 시각 태그·시각선·슬라이더 손잡이 테두리·현재 탭·답의 시각과 개수. 컨셉의 애(파랑), 응달 파랑(--shade-bar)보다 어둡고 낮은 채도 */
  --chip: 40px; --glyph: 30px; --badge: 22px; /* 목록 줄 날씨 칩 규격: 칩 · 그림 · 모서리 배지 */
  --sun-chip: #a85f0a; --sun-glyph: #96550a; /* 양달 칩의 옅은 면과 글리프(밝은 모드; 어두운 모드는 --sun-bar) */
  --shade-glyph: #36649d; /* 응달 칩(옅은 면) 위의 해 글리프: --shade-bar는 2.8:1이라 3:1 미달이어서 한 단계 진하게 (4.9:1) */
  --chev-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23111114' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* ⌄ 12px: 정렬 알약·조건 버튼 */
  --shade-bar: #4d8fe0; /* the 응달 stretch of a day bar (the pick) */
  --closed: var(--off);
  /* 올리브·모래(2026-11-08 홈 시안 B, Komoot 결): 홈의 주 행동 하나와 보조 면에만. --accent(먹색)는 그대로 */
  --olive: #4f6814; --on-olive: #f5f3ec; --olive-soft: #e7e8d1; --sand: #ede9de; --sand-ink: #4a4636;
  --accent: #111114; /* 먹색: 주 행동·현재 시각 (초록은 상태 표시만) */
  --accent-soft: rgba(118, 118, 128, .16);
  --scrim: rgb(0 0 0 / .45);
  --on-accent: #fff; /* text on an --accent fill (dark: the accent is light, so the text is dark) */
  --plate: #f4f2ec; /* the 클라이머 유형 테스트 plate (도감 card): the logo's paper, apart from the page */
  --sun-disc: #f4b942; /* the logo's sun on the plate's wall */
  --hold-a: #f4b942; /* the question's two holds: the first statement is the sun's yellow, */
  --hold-b: #7cc47f; /* the second a green of the characters' holds */
  --hold-edge: #17191c; /* what a hold's outline is mixed with (white on the dark page) */
  --shade-ink: rgba(42, 45, 50, .22); /* the logo's slab as shade */
  --sticker: #fff; /* the sticker edge round the character */
  --on-photo: #fff; /* text and marks laid over a photo, in both themes */
  --open-on-white: #1e7e34; --soon-on-white: #d70015; --muted-on-white: #5c5c63; --sun-on-white: #a35000; --fg-on-white: #111114; /* the light theme's text colours, for white pills that stay white in dark (--fg-on-white: a crag's condition) */
  --shadow-seg: 0 1px 2px rgb(0 0 0 / .12); /* the raised segment of a segmented control */
  --shadow-tab: 0 3px 8px rgb(0 0 0 / .12), 0 3px 1px rgb(0 0 0 / .04); /* the chosen white pill of the 세그먼트 (.segs, .tabs): a softer lift than --shadow-seg (2026-11-05 새 디자인 체계) */
  --shadow-thumb: 0 0 0 1.5px var(--point), 0 .5px 4px rgb(0 0 0 / .14), 0 6px 13px rgb(0 0 0 / .14); /* the time slider's handle */
  --track-rest: #7e7e84; /* the slider's stretch still ahead (3:1 on the page) */
  --mat: rgb(246 246 249 / .74); /* 재질: header, time box, tab bar, menu (blur 20px; opaque --surface under reduced-transparency / more-contrast) */
  --mat-hair: rgb(60 60 67 / .2); /* the 0.5px hairline of a 재질 bar */
  --rope: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='10'%3E%3Cpath d='M0,5.0L2,5.7L4,6.3L6,6.8L8,7.3L10,7.5L12,7.6L14,7.5L16,7.3L18,6.8L20,6.3L22,5.7L24,5.0L26,4.3L28,3.7L30,3.2L32,2.7L34,2.5L36,2.4L38,2.5L40,2.7L42,3.2L44,3.7L46,4.3L48,5.0' fill='none' stroke='%23f2f2f7' stroke-width='4.4'/%3E%3Cpath d='M0,5.0L2,5.7L4,6.3L6,6.8L8,7.3L10,7.5L12,7.6L14,7.5L16,7.3L18,6.8L20,6.3L22,5.7L24,5.0L26,4.3L28,3.7L30,3.2L32,2.7L34,2.5L36,2.4L38,2.5L40,2.7L42,3.2L44,3.7L46,4.3L48,5.0' fill='none' stroke='%238a8a90' stroke-width='2.4'/%3E%3Cpath d='M0,7.3L2,6.8L4,6.3L6,5.7L8,5.0L10,4.3L12,3.7L14,3.2L16,2.7L18,2.5L20,2.4L22,2.5L24,2.7L26,3.2L28,3.7L30,4.3L32,5.0L34,5.7L36,6.3L38,6.8L40,7.3L42,7.5L44,7.6L46,7.5L48,7.3' fill='none' stroke='%23f2f2f7' stroke-width='4.4'/%3E%3Cpath d='M0,7.3L2,6.8L4,6.3L6,5.7L8,5.0L10,4.3L12,3.7L14,3.2L16,2.7L18,2.5L20,2.4L22,2.5L24,2.7L26,3.2L28,3.7L30,4.3L32,5.0L34,5.7L36,6.3L38,6.8L40,7.3L42,7.5L44,7.6L46,7.5L48,7.3' fill='none' stroke='%23a9a9af' stroke-width='2.4'/%3E%3Cpath d='M0,2.7L2,2.5L4,2.4L6,2.5L8,2.7L10,3.2L12,3.7L14,4.3L16,5.0L18,5.7L20,6.3L22,6.8L24,7.3L26,7.5L28,7.6L30,7.5L32,7.3L34,6.8L36,6.3L38,5.7L40,5.0L42,4.3L44,3.7L46,3.2L48,2.7' fill='none' stroke='%23f2f2f7' stroke-width='4.4'/%3E%3Cpath d='M0,2.7L2,2.5L4,2.4L6,2.5L8,2.7L10,3.2L12,3.7L14,4.3L16,5.0L18,5.7L20,6.3L22,6.8L24,7.3L26,7.5L28,7.6L30,7.5L32,7.3L34,6.8L36,6.3L38,5.7L40,5.0L42,4.3L44,3.7L46,3.2L48,2.7' fill='none' stroke='%23c7c7cc' stroke-width='2.4'/%3E%3C/svg%3E"); /* 슬라이더 밧줄: 회색 세 톤, 가닥 둘레는 바탕색(--paper)으로 끊김 (2026-11-05 사용자 결정: 색은 일러스트에만) */
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M12.5 11.5 8.5 16l4 4.5M19.5 11.5l4 4.5-4 4.5' fill='none' stroke='%233f6c9e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); /* ‹ › on the slider handle (--point) */
  --shadow-float: 0 4px 16px rgb(0 0 0 / .25); /* floating card, toast */
  --shadow-pop: 0 2px 12px rgb(0 0 0 / .25); /* a smaller floating piece (the share previews' picture) */
  --shadow-hair: 0 1px 0 var(--line); /* the hairline under a sticky bar */
  /* page-level layers, low to high: list bands < sticky controls < the search dropdown < the tab bar < toast < boot screen.
     Inside one component the numbers are local (0-3) and stay as they are. */
  --z-band: 2; --z-axis: 3; --z-tabbar-flow: 4; --z-controls: 5; --z-picks: 6; --z-to-top: 6; --z-tabbar: 7; --z-boot: 100; --z-toast: 1000;
  --now: var(--accent);
  --pin-open: #26282d; /* 열린 핀은 목록 막대와 같은 먹색(초록 폐기) */
  --pin-soon: #a8325a;
  --pin-closed: #9aa29c;
  --pin-unknown: #55585b;
  --pin-edge: #17191c;
  --pin-me: #2563eb;
  --pin-sun: #e08a1e; /* 양달 ring; pins sit on light tiles in both themes */
  --fav: #f5c21b; /* the ♥ of a favorite: yellow fill with a darker edge, so it reads on the light page too */
  --fav-edge: #a87400;
  --hatch: color-mix(in srgb, var(--fg) 40%, transparent); /* 빗금 = not usable (휴게·휴무·휴장) */
  --r-xs: 2px; /* bars, tracks, ticks */
  --r-sm: 4px;
  --r-8: 8px; /* thumbnails, the day bar, previews */
  --r-md: 8px;
  --r-base: 12px; /* the default corner: cards, buttons */
  --r-lg: 12px;
  --r-16: 16px; /* the top corners of a sheet */
  --r-pill: 999px;
  --fs-xs: .8125rem;
  --fs-sm: .875rem;
  --fs-md: 1rem;
  --fs-base: 1rem;
  --fs-lg: 1.25rem;
  --fs-xl: 1.5rem;
  --gap: 12px;
  --tap: 44px;
  --h-s: 22px; /* 부품 높이 세 단계(2026-11-05): 태그 22 · 알약·스텝 32 · 입력·주 버튼 44 */
  --h-m: 32px;
  --h-l: 44px;
  /* spacing scale (docs/system/design-tokens.md): the values the layout already used; spacing declarations take these */
  --sp-2: 2px;
  --sp-4: 4px;
  --sp-8: 8px;
  --sp-12: 12px;
  --sp-16: 16px;
  --sp-24: 24px;
  --sp-32: 32px;
  --sp-48: 48px;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --dur-press: 140ms;
  --dur-ui: 200ms;
  --dur-exit: 140ms;
  --font: "Pretendard Variable", "IBM Plex Sans KR", system-ui, "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  --font-serif: "Gowun Batang", "IBM Plex Sans KR", "Batang", serif; /* the words under the sun picture; the hours above it stay in --font */
}
/* dark: the phone's setting (자동), unless 내 정보 › 화면 picked 라이트; html[data-theme="dark"] below repeats the same values */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #17191c;
    --sheet: #1e2125;
    --panel: #262a2f;
    --wall: #f4f2ec;
    --sun-ui: #f2b25c;
    --open-past: #2b4231;
    --soon: #f08aa8;
    --sun: #f2b25c;
    --fav: #ffd34d;
    --fav-edge: #ffd34d;
    --off: #343a37;
    --gone: #666d72;
    --hair: #24282c;
    --fg: #f4f2ec;
    --muted: #a9aaa7;
    --line: #33373c;
    --line-strong: #4a4e54;
    --open: #86c993;
    --open-bar: #86c993;
    --rope: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='10'%3E%3Cpath d='M0,5.0L2,5.7L4,6.3L6,6.8L8,7.3L10,7.5L12,7.6L14,7.5L16,7.3L18,6.8L20,6.3L22,5.7L24,5.0L26,4.3L28,3.7L30,3.2L32,2.7L34,2.5L36,2.4L38,2.5L40,2.7L42,3.2L44,3.7L46,4.3L48,5.0' fill='none' stroke='%2317191c' stroke-width='4.4'/%3E%3Cpath d='M0,5.0L2,5.7L4,6.3L6,6.8L8,7.3L10,7.5L12,7.6L14,7.5L16,7.3L18,6.8L20,6.3L22,5.7L24,5.0L26,4.3L28,3.7L30,3.2L32,2.7L34,2.5L36,2.4L38,2.5L40,2.7L42,3.2L44,3.7L46,4.3L48,5.0' fill='none' stroke='%23a9aaa7' stroke-width='2.4'/%3E%3Cpath d='M0,7.3L2,6.8L4,6.3L6,5.7L8,5.0L10,4.3L12,3.7L14,3.2L16,2.7L18,2.5L20,2.4L22,2.5L24,2.7L26,3.2L28,3.7L30,4.3L32,5.0L34,5.7L36,6.3L38,6.8L40,7.3L42,7.5L44,7.6L46,7.5L48,7.3' fill='none' stroke='%2317191c' stroke-width='4.4'/%3E%3Cpath d='M0,7.3L2,6.8L4,6.3L6,5.7L8,5.0L10,4.3L12,3.7L14,3.2L16,2.7L18,2.5L20,2.4L22,2.5L24,2.7L26,3.2L28,3.7L30,4.3L32,5.0L34,5.7L36,6.3L38,6.8L40,7.3L42,7.5L44,7.6L46,7.5L48,7.3' fill='none' stroke='%238a8c90' stroke-width='2.4'/%3E%3Cpath d='M0,2.7L2,2.5L4,2.4L6,2.5L8,2.7L10,3.2L12,3.7L14,4.3L16,5.0L18,5.7L20,6.3L22,6.8L24,7.3L26,7.5L28,7.6L30,7.5L32,7.3L34,6.8L36,6.3L38,5.7L40,5.0L42,4.3L44,3.7L46,3.2L48,2.7' fill='none' stroke='%2317191c' stroke-width='4.4'/%3E%3Cpath d='M0,2.7L2,2.5L4,2.4L6,2.5L8,2.7L10,3.2L12,3.7L14,4.3L16,5.0L18,5.7L20,6.3L22,6.8L24,7.3L26,7.5L28,7.6L30,7.5L32,7.3L34,6.8L36,6.3L38,5.7L40,5.0L42,4.3L44,3.7L46,3.2L48,2.7' fill='none' stroke='%236b6f74' stroke-width='2.4'/%3E%3C/svg%3E");
    --mat: rgb(30 33 37 / .74);
    --mat-hair: rgb(255 255 255 / .16);
    --point: #8fb4e3;
    --olive: #b4c765; --on-olive: #1c2206; --olive-soft: #2b3318; --sand: #2b2d27; --sand-ink: #d9d4c4;
    --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M12.5 11.5 8.5 16l4 4.5M19.5 11.5l4 4.5-4 4.5' fill='none' stroke='%238fb4e3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --shade-glyph: #86a3c9;
    --chev-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23f4f2ec' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --accent: #f4f2ec;
    --accent-soft: #2b4231;
    --sunken: #262a2f;
    --line: #33373c;
    --scrim: rgb(0 0 0 / .6);
    --on-accent: #17191c;
    --plate: #1e2125;
    --sun-disc: #f4b942;
    --shade-ink: rgba(0, 0, 0, .32);
    --hold-edge: #fff;
    --sticker: #f4f2ec;
    --shade-bar: #86a3c9;
    /* pins sit on light OSM tiles in both themes; the legend sits on the dark page */
    --pin-open: #26282d;
    --pin-soon: #d0587f;
    --pin-closed: #8d958f;
    --pin-unknown: #a9aaa7;
    --pin-edge: #0d100f;
    --pin-me: #3b82f6;
  }
}
:root[data-theme="dark"] {
  --paper: #17191c; --sheet: #1e2125; --panel: #262a2f; --wall: #f4f2ec; --sun-ui: #f2b25c; --open-past: #2b4231; --soon: #f08aa8; --sun: #f2b25c;
  --fav: #ffd34d; --fav-edge: #ffd34d; --off: #343a37; --gone: #666d72; --hair: #24282c; --fg: #f4f2ec; --muted: #a9aaa7;
  --line: #33373c; --line-strong: #4a4e54; --open: #86c993; --open-bar: #86c993; --rope: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='10'%3E%3Cpath d='M0,5.0L2,5.7L4,6.3L6,6.8L8,7.3L10,7.5L12,7.6L14,7.5L16,7.3L18,6.8L20,6.3L22,5.7L24,5.0L26,4.3L28,3.7L30,3.2L32,2.7L34,2.5L36,2.4L38,2.5L40,2.7L42,3.2L44,3.7L46,4.3L48,5.0' fill='none' stroke='%2317191c' stroke-width='4.4'/%3E%3Cpath d='M0,5.0L2,5.7L4,6.3L6,6.8L8,7.3L10,7.5L12,7.6L14,7.5L16,7.3L18,6.8L20,6.3L22,5.7L24,5.0L26,4.3L28,3.7L30,3.2L32,2.7L34,2.5L36,2.4L38,2.5L40,2.7L42,3.2L44,3.7L46,4.3L48,5.0' fill='none' stroke='%23a9aaa7' stroke-width='2.4'/%3E%3Cpath d='M0,7.3L2,6.8L4,6.3L6,5.7L8,5.0L10,4.3L12,3.7L14,3.2L16,2.7L18,2.5L20,2.4L22,2.5L24,2.7L26,3.2L28,3.7L30,4.3L32,5.0L34,5.7L36,6.3L38,6.8L40,7.3L42,7.5L44,7.6L46,7.5L48,7.3' fill='none' stroke='%2317191c' stroke-width='4.4'/%3E%3Cpath d='M0,7.3L2,6.8L4,6.3L6,5.7L8,5.0L10,4.3L12,3.7L14,3.2L16,2.7L18,2.5L20,2.4L22,2.5L24,2.7L26,3.2L28,3.7L30,4.3L32,5.0L34,5.7L36,6.3L38,6.8L40,7.3L42,7.5L44,7.6L46,7.5L48,7.3' fill='none' stroke='%238a8c90' stroke-width='2.4'/%3E%3Cpath d='M0,2.7L2,2.5L4,2.4L6,2.5L8,2.7L10,3.2L12,3.7L14,4.3L16,5.0L18,5.7L20,6.3L22,6.8L24,7.3L26,7.5L28,7.6L30,7.5L32,7.3L34,6.8L36,6.3L38,5.7L40,5.0L42,4.3L44,3.7L46,3.2L48,2.7' fill='none' stroke='%2317191c' stroke-width='4.4'/%3E%3Cpath d='M0,2.7L2,2.5L4,2.4L6,2.5L8,2.7L10,3.2L12,3.7L14,4.3L16,5.0L18,5.7L20,6.3L22,6.8L24,7.3L26,7.5L28,7.6L30,7.5L32,7.3L34,6.8L36,6.3L38,5.7L40,5.0L42,4.3L44,3.7L46,3.2L48,2.7' fill='none' stroke='%236b6f74' stroke-width='2.4'/%3E%3C/svg%3E"); --mat: rgb(30 33 37 / .74); --mat-hair: rgb(255 255 255 / .16); --point: #8fb4e3; --olive: #b4c765; --on-olive: #1c2206; --olive-soft: #2b3318; --sand: #2b2d27; --sand-ink: #d9d4c4; --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M12.5 11.5 8.5 16l4 4.5M19.5 11.5l4 4.5-4 4.5' fill='none' stroke='%238fb4e3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); --shade-glyph: #86a3c9; --chev-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23f4f2ec' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); --accent: #f4f2ec; --accent-soft: #2b4231; --sunken: #262a2f; --scrim: rgb(0 0 0 / .6); --on-accent: #17191c;
    --plate: #1e2125;
    --sun-disc: #f4b942;
    --shade-ink: rgba(0, 0, 0, .32);
    --hold-edge: #fff;
    --sticker: #f4f2ec;
    --shade-bar: #86a3c9;
  --pin-open: #26282d; --pin-soon: #d0587f; --pin-closed: #8d958f; --pin-unknown: #a9aaa7; --pin-edge: #0d100f; --pin-me: #3b82f6;
  color-scheme: dark;
}
:root[data-theme="light"] { color-scheme: light; } /* form controls and scrollbars follow the picked theme */

/* ---- base ---- */
* { box-sizing: border-box; }
html[data-text="large"] { font-size: 125%; --tap: 52px; } /* 글자 크기 (내 정보): rem scales, on top of the phone's own setting */
html[data-text="xlarge"] { font-size: 150%; --tap: 60px; }
/* 아주 크게: 늘 화면에 붙어 있는 상단(제목·필터·시간)만 '크게' 수준으로 두어 목록이 첫 화면에 보이게 한다(토큰 값 = 기본 × 1.25 ÷ 1.5) */
html[data-text="xlarge"] .filters .pill { padding: 0 var(--sp-8); }
html[data-text="xlarge"] .filters { flex-wrap: wrap; row-gap: var(--sp-4); } /* 가장 큰 글씨: 검색창이 첫 줄 전폭, 양달·응달 칸과 조건은 그 아래 줄(한 줄이면 검색창 문구가 한 글자만 보인다) */
html[data-text="xlarge"] .filters .find { order: -1; flex: 1 1 100%; }
html[data-text="xlarge"] .scrub-sum .dow { display: none; } /* 가장 큰 글씨: 요일을 빼야 날짜·지금으로·도착이 한 줄에 든다 */
html[data-text="xlarge"] .top, html[data-text="xlarge"] .controls, html[data-text="xlarge"] .tabbar { --tap: 52px; --fs-xs: .6771rem; --fs-sm: .7292rem; --fs-md: .7813rem; --fs-base: .8333rem; --fs-lg: 1.0417rem; --fs-xl: 1.25rem; }
html { -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--stick-h, 0px) + 8px); } /* focus/anchor scrolls land below the sticky controls */
body { margin: 0; background: var(--bg); color: var(--fg); font: 1rem/1.5 var(--font); font-variant-numeric: tabular-nums; overflow-x: hidden; word-break: keep-all; overflow-wrap: break-word; }
.wrap { max-width: 680px; margin: 0 auto; padding: 0 max(var(--sp-16), env(safe-area-inset-left)) 0 max(var(--sp-16), env(safe-area-inset-right)); } /* viewport-fit=cover: keep landscape content out from under the notch */
h1, h2, h3, p { margin: 0; }
h1, h2, h3, h4 { text-wrap: balance; }
p, li, dd { text-wrap: pretty; }
input, select, button { font: inherit; color: var(--fg); }
button, select, summary, .btn, .file-btn { cursor: pointer; }
button, a, summary, label, .btn, .file-btn { touch-action: manipulation; }
button, summary, .btn, .file-btn { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; } /* controls, not content */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.muted, .meta { color: var(--muted); font-size: var(--fs-sm); }
[hidden] { display: none !important; }

/* ---- header ---- */
.top { background: var(--bg); padding: var(--sp-8) 0 var(--sp-2); }
h1 { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); letter-spacing: .02em; }
h1 { display: flex; align-items: center; gap: var(--sp-8); }
h1 strong { color: var(--fg); font-weight: 700; font-size: 1.125rem; }
.top h1 { min-height: 32px; font-size: var(--fs-xl); font-weight: 700; color: var(--fg); letter-spacing: 0; } /* the name as text until the new logo; as tall as the old logo image so the sticky offsets stay */
.top h1 .logo { display: block; height: 44px; margin-block: -6px; aspect-ratio: 367 / 167; color: transparent; overflow: hidden; background: var(--fg); -webkit-mask: url(assets/hinoae-wordmark.svg) left center / contain no-repeat; mask: url(assets/hinoae-wordmark.svg) left center / contain no-repeat; } /* the script wordmark as a mask so it takes --fg in both themes; 44px tall with -6px margins keeps the 32px header row; the name stays as (transparent) text for readers */
@supports not ((mask-image: url(x)) or (-webkit-mask-image: url(x))) { .top h1 .logo { color: var(--fg); background: none; height: auto; margin: 0; aspect-ratio: auto; overflow: visible; } } /* no mask support: show the name as text again */
.logo { flex: none; display: block; }
#summary { font-size: min(var(--fs-xl), calc((100vw - 32px) / 16.5)); /* the headline fits one row whatever the system font size; a long lead may still wrap */
   font-weight: 500; text-wrap: balance; line-height: 1.15; letter-spacing: -.025em; margin-top: 0; } /* plain weight: only the time and the count are strong */
#summary b { color: var(--open); font-weight: 700; }
#summary small { display: block; font-size: var(--fs-sm); font-weight: 500; color: var(--muted); } /* the forecast line of another day (planWxLine): a quiet second row */
@media (max-width: 520px) { #summary { line-height: 1.05; } } /* two rows (a long day lead on a narrow phone): tighter lines, the header does not grow by a full line */
#summary b.zero, #summary.none { color: var(--muted); }
/* 내 지역 on: a small line under the summary; pressing it goes back to 전국 (the 44px tap area is padding pulled back by the margin) */
.region-line { display: inline-flex; align-items: center; gap: var(--sp-4); min-height: var(--tap); margin: -6px 0 0; padding: 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-sm); white-space: nowrap; }
.region-line > span:first-child { color: var(--fg); font-weight: 600; }
.region-line .x { text-decoration: underline; text-underline-offset: 2px; }
.region-line:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sub { color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; }
/* date + slider stay sticky while the list scrolls; app.js sets a negative top so the filter row scrolls away,
   and --stick-h (0 when .unstuck) to the part that stays */
.controls { position: sticky; top: 0; z-index: var(--z-controls); padding: var(--sp-8) 0 var(--sp-2); background: var(--bg); box-shadow: var(--shadow-hair); }
.controls.unstuck { position: static; box-shadow: none; }
.controls[hidden] { display: none; }
.controls > .wrap { display: grid; gap: var(--sp-4); }
.field { display: block; min-width: 0; }
#nowBtn {
  width: 100%; min-height: var(--tap); padding: 0 var(--sp-8); font-size: var(--fs-md);
  border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface);
}
#nowBtn { width: auto; padding: 0 var(--sp-12); font-weight: 600; color: var(--fg); border-color: transparent; border-radius: var(--r-pill); background: var(--sunken); } /* a small chip, not a second outlined box: the search field is the one outlined control */
#findQ { border-radius: var(--r-base); }
/* arrival time: the slider follows the thumb 1:1, nothing animates */
/* date · weekday · arrival wrap as a unit under large text; "지금으로" sits at the slider's end, so it never widens the header */
.scrub-hd { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-8); }
@media (max-width: 340px) { .scrub-hd { column-gap: var(--sp-4); } } /* 320px: 질문 + 지금으로 + 11/6(금) ▾ need the 8px the wider gap costs, or the date pill drops to a second line and the box stops pinning */
/* the 시간 박스: the question, the day, the slider and ±1시간 on one full-width band (the slider keeps the page's 16px sides, so its thumb stays above the same time on the axis below) */
.scrub { --thumb-w: 32px; --thumb-h: 32px; --bar-h: 10px; --bar-inset: 8px; --unreach: calc(1 / 18); /* 23:00–24:00 cannot be picked: the bar ends under the last pickable hour */ /* thumb-w / 2 must equal the axis --pad (16px): the thumb centre then travels the axis 06–24 */ margin: 0 calc(-1 * var(--sp-16)); padding: var(--sp-4) var(--sp-16) 0; background: var(--surface); border-block: 1px solid var(--line); }
.scrub #summary { font-size: clamp(var(--fs-md), calc((100vw - 32px) / 22), var(--fs-lg)); /* grows with the screen: one line at 390px, also at night (0곳) */ line-height: 1.3; padding: var(--sp-2) 0 var(--sp-12); text-align: center; }
.scrub #summary b:first-of-type { white-space: nowrap; } /* 11/6(금) 15:00 stays whole: the line breaks after 에, not inside the day and time */
.scrub #summary b:last-of-type { font-size: 1.45em; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -.03em; } /* the count is the answer: bigger, and its width does not jump while the slider moves */ /* the answer, in the band that stays in view while the slider is dragged (it was the page's headline) */
#countOpen { display: none; } /* the headline in the band already counts them */
.scrub-q { font-size: var(--fs-md); font-weight: 700; color: var(--fg); white-space: nowrap; }
.scrub-date { position: relative; flex: 0 1 auto; margin-left: auto; min-width: 0; }
.scrub-sum { display: flex; align-items: center; gap: var(--sp-8); min-height: 32px; padding: 0 var(--sp-12); border-radius: var(--r-pill); background: var(--sunken); list-style: none; } /* the picked day as a tag (no ▾: 홈 has no calendar, the days are the chips under the question) */
.scrub-days.segs { margin-top: var(--sp-8); grid-auto-columns: max-content; overflow-x: auto; scrollbar-width: none; } /* 오늘·내일·모레 + 일정 날(●) + + 일정 잡기: the .segs control (app.js drawDays), above the time box so the pinned part does not grow; it scrolls sideways when the trips are many */
.scrub-days.segs button { display: inline-flex; align-items: center; justify-content: center; min-width: var(--tap); padding: 0 var(--sp-12); } /* .segs :is(button)보다 명시도를 높여 칩 폭·점 위치를 지킨다 */
html[data-text] .scrub-days.segs { flex-wrap: nowrap; } /* 큰 글씨에서 .segs가 flex+wrap이 돼도 칩 줄은 가로 스크롤(줄바꿈·눌림 없음) */
.scrub-days.segs > button { flex: none; }
.scrub-days .day-dot { display: inline-block; width: 6px; height: 6px; margin-left: var(--sp-4); border-radius: 50%; background: currentColor; vertical-align: middle; } /* 일정이 있는 날: 글자 뒤 점(같은 말이 aria-label에도 있다) */
/* 시안 new-home2: 날짜 칩은 따로 테두리가 있는 알약, 고른 칩은 굵은 테두리(세그먼트 바가 아님). 새 토큰 없음 */
.scrub-days.segs { display: flex; gap: var(--sp-8); padding: var(--sp-8) var(--sp-4); background: none; border-radius: 0; }
.scrub-days.segs > button { min-height: var(--tap); border-radius: var(--r-pill); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); font-weight: 700; }
.scrub-days.segs > button[aria-pressed="true"] { background: var(--surface); color: var(--fg); box-shadow: inset 0 0 0 2px var(--fg); }
.scrub-days .day-add { color: var(--muted); } /* 두 톤: 일정 칩·오늘 등은 --fg(.segs), 칩을 더하는 + 일정 잡기만 --muted. (0,2,0)이라 .segs :is(button)(0,1,1)을 이긴다 */
@media (max-width: 340px) { .scrub-days.segs > button { padding: 0 var(--sp-8); } } /* 320px: 오늘·내일·모레 + 일정 잡기가 288px 안에 끝까지 들어간다(12px면 6px 잘림) */
.scrub-sum .sub { min-width: 0; white-space: normal; font-size: var(--fs-sm); font-weight: 600; } /* wraps at spaces (keep-all) instead of being cut off */
.scrub-row { position: relative; display: flex; align-items: center; gap: var(--sp-8); min-height: calc(var(--tap) - 4px); } /* same height with or without the button */
#time { position: relative; z-index: 1; flex: 1 1 0; min-width: 0; height: var(--tap); margin: 0 calc(var(--thumb-w) / -2); /* half the thumb width: the thumb's half width, so its centre travels exactly the axis' 06–24 plot */ -webkit-appearance: none; appearance: none; background: transparent; }
/* the passed stretch is grey and the time to come is green, like every row's gauge (app.js sets --fill); the thumb is the same sun as the current tab's dot */
#time::-webkit-slider-runnable-track { height: var(--bar-h); background: transparent; } /* the bar itself is .scrub-bar behind the input: its ends sit 8px inside the screen (a track border would square the corners) */
#time::-moz-range-track { height: var(--bar-h); background: transparent; }
#time::-moz-range-progress { height: var(--bar-h); background: transparent; }
.scrub-bar { position: absolute; left: calc(var(--bar-inset) - var(--sp-16)); right: calc(100% * var(--unreach) - var(--bar-inset)); top: 50%; height: var(--bar-h); transform: translateY(-50%); border-radius: var(--r-pill); background: linear-gradient(to right, var(--gone) calc(var(--thumb-w) / 2 - var(--bar-inset) + (100% - var(--thumb-w) / 2) * var(--fill, 0) / (1 - var(--unreach))), var(--track-rest) 0); pointer-events: none; } /* the split sits under the thumb's centre: 16px (half the thumb) in from the screen edge, 8px in from the bar's own end */
#time::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: var(--thumb-w); height: var(--thumb-h); margin-top: calc((var(--bar-h) - var(--thumb-h)) / 2); border: 0; border-radius: var(--r-md); background: var(--glass); box-shadow: 0 0 0 1px var(--line-strong), 0 0 0 4px var(--surface), 0 2px 6px rgb(0 0 0 / .28); } /* a handle you take hold of: the ◂ ▸ says it slides */
#time::-moz-range-thumb { width: var(--thumb-w); height: var(--thumb-h); border: 0; border-radius: var(--r-md); background: var(--glass); box-shadow: 0 0 0 1px var(--line-strong), 0 0 0 4px var(--surface), 0 2px 6px rgb(0 0 0 / .28); }
#nowBtn { flex: none; }
.scrub-grip { display: none; /* 화살표는 손잡이 배경(--chev)으로 옮겼다 */ position: absolute; z-index: 2; left: calc(100% * var(--fill, 0)); top: 50%; width: 0; height: 0; color: var(--fg-on-white); pointer-events: none; } /* ◂ ▸ on the handle: its centre is the thumb centre (--fill is the thumb's travel); border triangles take --fg-on-white, the ink that pairs with the white --glass handle in light and dark */
.scrub-grip::before, .scrub-grip::after { content: ""; position: absolute; top: -6px; border: solid transparent; }
.scrub-grip::before { right: 3px; border-width: 6px 7px 6px 0; border-right-color: currentColor; }
.scrub-grip::after { left: 3px; border-width: 6px 0 6px 7px; border-left-color: currentColor; }
.scrub-ans { display: flex; align-items: center; gap: var(--sp-4); } /* ‹ the answer › : the arrows change the number beside them */
.scrub-ans #summary { flex: 1 1 0; min-width: 0; }
.scrub-ans .step-btn { position: relative; flex: none; width: 40px; min-height: 32px; padding: 0; display: grid; place-items: center; margin-bottom: var(--sp-12); font-size: var(--fs-sm); } /* an arrow, not a word: the slider is the control, these are its two ends; margin-bottom puts them on the sentence middle (it has 12px of room below) */
.scrub-ans .step-btn::after { content: ""; position: absolute; inset: -2px -4px -6px; } /* the tap area stays 44px; its top edge stops at the slider (it sits over the slider's last pixels and would lose them anyway) */
#nowBtn { position: relative; min-height: 32px; font-size: var(--fs-sm); white-space: nowrap; }
#nowBtn::after { content: ""; position: absolute; inset: -6px -4px; } /* the tap area stays 44px */
.scrub-hint { margin: 0; text-align: center; padding-bottom: var(--sp-4); font-size: var(--fs-xs); font-weight: 600; color: var(--muted); pointer-events: none; } /* first visit only (scrub-hint.js), between the slider and the answer; it stays with 지금으로 too: a weekday visit starts on the planned Saturday, so 지금으로 shows from the first look */
html[data-text="xlarge"] .scrub-hint { display: none; }
@keyframes scrub-nudge { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(28px); } }
#time.nudge::-webkit-slider-thumb { animation: scrub-nudge 1.2s ease-in-out 2; }
#time.nudge::-moz-range-thumb, #time.nudge ~ .scrub-grip { animation: scrub-nudge 1.2s ease-in-out 2; }
@media (prefers-reduced-motion: reduce) { #time.nudge::-webkit-slider-thumb, #time.nudge::-moz-range-thumb, #time.nudge ~ .scrub-grip { animation: none; } }
.axis .t { cursor: pointer; }
.axis .t::after { content: ""; position: absolute; inset: -12px -14px; } /* the tap area for jumping to that hour stays 44px */
.step-btn { border: 0; border-radius: var(--r-pill); background: var(--sunken); color: var(--fg); }
.step-btn[aria-disabled="true"] { color: var(--muted); opacity: .7; }
.step-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.scrub-sum.is-today .sub { color: var(--muted); }

/* filter row: five buttons on one line at 390px; wraps under large text so "조건" stays reachable */
.filters { position: relative; display: flex; flex-wrap: nowrap; align-items: center; gap: var(--sp-8); } /* one row: a wrapped 조건 button breaks the layout (large system font) */
.filters .pill { flex: 0 1 auto; min-width: 0; padding: 0 var(--sp-8); font-size: var(--fs-xs); white-space: nowrap; }
/* 양달/응달 · 3시간+ · 가까운 순 switch something on and off: outlined pills. 조건 opens a sheet: a text button at the right edge, bold with an underline while a condition is on */
.filters .quiet { margin-left: auto; padding: 0 var(--sp-8); border-color: transparent; background: transparent; color: var(--muted); font-size: var(--fs-sm); } /* 조건 ▾ and the date ▾ (.scrub-sum) are the same kind of control: muted words, --fs-sm, 600, a ▾ */
.filters .quiet#moreFilters { min-width: 5em; text-align: right; } /* 조건 ▾ → 조건 1 ▾ (가까운 순을 켜면 1이 붙는다)에도 검색창 폭·핀 위치가 그대로 */
.filters .quiet.on { color: var(--fg); font-weight: 700; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
button.pill.quiet:hover { border-color: transparent; }
.pill {
  flex: none; display: inline-flex; align-items: center; gap: var(--sp-2); min-height: var(--tap);
  padding: 0 var(--sp-2) 0 var(--sp-12); border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  background: var(--surface); font-size: var(--fs-sm); white-space: nowrap;
}
.pill > span { color: var(--muted); font-size: var(--fs-xs); }
.pill select { border: 0; background: transparent; padding: var(--sp-8) var(--sp-4); min-height: calc(var(--tap) - 2px); font-weight: 600; }
.pill select:focus-visible { outline: none; }
.pill:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
button.pill { padding: 0 var(--sp-12); font-weight: 600; }
.toggle[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.filters .toggle[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); } /* the filter row: on = filled (green; 양달·응달 take their own colour) */
/* on = a check mark too, not only the fill (aria-pressed already tells screen readers, so the mark is silent) */
.toggle[aria-pressed="true"]::before, .sh-toggle[aria-pressed="true"]::before { content: "✓"; content: "✓" / ""; margin-right: var(--sp-2); }
button.pill, #nowBtn, .btn {
  transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-press) var(--ease-out),
    color var(--dur-press) var(--ease-out), border-color var(--dur-press) var(--ease-out);
}
button.pill:active, #nowBtn:active, .btn:active { transform: scale(.97); }
#locateMsg { font-size: var(--fs-sm); color: var(--muted); }

/* ---- tabs ---- */
main { padding-bottom: calc(var(--sp-48) + var(--tabbar-h, 0px)); } /* the fixed tab bar must not cover the list's end */
html { scroll-padding-bottom: calc(var(--tabbar-h, 0px) + 8px); }
/* 목록/지도 stay in view under the date + slider, so the map is never a place you can't leave (app.js sets --ctl-h, and
   --stick-h = controls + this bar; .unstuck when even that would take over a short screen) */
/* phones and tablets: the bar is fixed at the bottom (thumb reach; the same grammar as the wall sheet's tabs). It carries the home-bar inset
   itself; app.js sets --tabbar-h (its height) for the page's end padding, the toast, the map and the 맨 위로 button. */
.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-tabbar); margin: 0; padding: var(--sp-4) max(var(--sp-16), env(safe-area-inset-right)) calc(var(--sp-4) + env(safe-area-inset-bottom)) max(var(--sp-16), env(safe-area-inset-left)); background: var(--bg); box-shadow: 0 -1px 0 var(--line); }
.tabbar > .tabs { max-width: 680px; margin: 0 auto; }
.tabs { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--sp-4); padding: var(--sp-4); background: var(--sunken); border-radius: var(--r-base); }
.tabs [role="tab"] {
  min-height: var(--tap); border: 0; border-radius: var(--r-md); background: transparent;
  font-weight: 600; color: var(--muted); white-space: nowrap;
}
.tabs [aria-selected="true"] { background: var(--surface); color: var(--accent); box-shadow: var(--shadow-seg); }
.tb-ic { display: none; }
/* phones and tablets: icon over label; the current tab is told by the app's sun, a small dot at the icon's right (no pill) */
@media (max-width: 1023.98px) {
  .tabbar > .tabs { grid-template-columns: repeat(3, 1fr); gap: 0; padding: 0; background: none; border-radius: 0; }
  .tabs [role="tab"] { display: grid; justify-items: center; align-content: center; gap: var(--sp-2); min-height: 52px; padding: var(--sp-4) 0 var(--sp-2); border-radius: var(--r-md); font-size: var(--fs-xs); }
  .tabs [aria-selected="true"] { background: none; box-shadow: none; color: var(--fg); }
  .tb-ic { position: relative; display: block; }
  .tb-ic svg { display: block; width: 24px; height: 24px; }
  .tabs [aria-selected="true"] .tb-ic svg { color: var(--olive); }
  .tabs [aria-selected="true"] .tb-ic::after { content: ""; position: absolute; top: 0; right: -9px; width: 8px; height: 8px; border-radius: 50%; background: var(--sun); box-shadow: 0 0 0 3px color-mix(in srgb, var(--sun) 25%, transparent); }
}

/* ---- map ---- */
#panel-map { margin-top: var(--sp-16); display: grid; gap: var(--sp-12); }
/* the map fills what is left under the sticky controls (minus a strip of page below it, so a finger can still scroll the
   page); opening the tab scrolls it into exactly that place (app.js), so it is never half off screen while it pans */
#map { height: calc(100vh - var(--stick-h, 0px) - var(--tabbar-h, 0px) - 40px); height: calc(100dvh - var(--stick-h, 0px) - var(--tabbar-h, 0px) - 40px); min-height: 320px; border-radius: var(--r-base); border: 1px solid var(--line); background: var(--sunken); z-index: 0; }
#map .leaflet-bar a { width: var(--tap); height: var(--tap); line-height: var(--tap); font-size: var(--fs-lg); }
#map.leaflet-container, #map .leaflet-control-attribution { font-size: var(--fs-xs); }
html[data-text="xlarge"] #map .leaflet-control-attribution { font-size: .5rem; } /* the credit is small print: 12px, not 19px over the pins */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) #map .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) saturate(.5) brightness(.85) contrast(.9); } }
:root[data-theme="dark"] #map .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) saturate(.5) brightness(.85) contrast(.9); } /* a dark map at night: the tiles inverted and desaturated; the pins are drawn on top, so they stay as drawn */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) #map .leaflet-bar a { background: var(--surface); color: var(--fg); border-color: var(--line); } :root:not([data-theme="light"]) #map .leaflet-bar { border: 1px solid var(--line); box-shadow: none; border-radius: var(--r-base); overflow: hidden; } :root:not([data-theme="light"]) #map .leaflet-control-attribution { background: color-mix(in srgb, var(--bg) 70%, transparent); color: var(--muted); } :root:not([data-theme="light"]) #map .leaflet-control-attribution a { color: var(--muted); } }
:root[data-theme="dark"] #map .leaflet-bar a { background: var(--surface); color: var(--fg); border-color: var(--line); }
:root[data-theme="dark"] #map .leaflet-bar { border: 1px solid var(--line); box-shadow: none; border-radius: var(--r-base); overflow: hidden; }
:root[data-theme="dark"] #map .leaflet-control-attribution { background: color-mix(in srgb, var(--bg) 70%, transparent); color: var(--muted); }
:root[data-theme="dark"] #map .leaflet-control-attribution a { color: var(--muted); }
/* wide screens: the list and the map side by side. app.js (`wide`) shows the map panel with 홈 and the 목록 ⇄ 지도
   toggle goes away; 일정·기록 sit under the tab bar on the same left edge. The tab bar stops sticking (--stick-h = the controls only). */
@media (min-width: 1024px) {
  html { scrollbar-gutter: stable; } /* no 7px sideways shift when a tab is short enough to lose the scrollbar */
  .wrap { max-width: 1200px; }
  main.wrap { display: grid; grid-template-columns: minmax(0, 460px) minmax(0, 1fr); grid-template-rows: auto auto 1fr; column-gap: var(--sp-24); align-items: start; } /* 1fr: the map spans all three rows, so the extra height goes to the list row, not the search's or the tab bar's */
  main.wrap > * { grid-column: 1 / -1; }
  main.wrap > .tabbar, main.wrap > #panel-list { grid-column: 1; }
  main.wrap > #panel-map { grid-column: 2; grid-row: 1 / span 3; position: sticky; top: calc(var(--ctl-h, 0px) + var(--sp-12)); }
  .controls > .wrap > * { max-width: 460px; } /* the filters and the slider are as wide as the list column under them, not the whole page */
  .controls > .wrap > .scrub { max-width: 492px; } /* the time box bleeds 16px each side (margin -16px) like the axis and the rows under it: 460 + 32, so its slider lines up with the axis */
  main.wrap > :is(#panel-log, #panel-sched) { max-width: 680px; } /* 일정·기록: wider than the list column but on the same left edge, so the tab bar never moves sideways */
  .tabbar { position: static; padding: var(--sp-4) var(--sp-16); box-shadow: none; z-index: var(--z-tabbar-flow); margin: 0 -16px; }
  .tabbar > .tabs { max-width: none; margin: 0; }
  .tabs { grid-template-columns: 1fr 1fr 1fr; }
  #homeView { display: none; } /* the list and the map are side by side: no 목록 ⇄ 지도 to choose */
  #map { height: calc(100dvh - var(--stick-h, 0px) - 275px); } /* room for the strip under the controls and the legend below */
}
/* pin names (src/map.js) at street zoom; map.js hides the ones that would overlap */
#map .pin-label { padding: 1px var(--sp-8); font: 600 .8125rem/1.3 var(--font); color: #17191c; background: #fff; border-color: #bcb8ac; white-space: nowrap; }
/* a crowd of walls: a hold with the count on it, soft halo in the same hue (size set per count in src/map.js); grey when none is open */
#map .pin-cluster { --hue: var(--pin-open); position: relative; display: block; width: var(--size, 42px); height: var(--size, 42px); font-variant-numeric: tabular-nums; cursor: pointer; filter: drop-shadow(0 2px 3px rgb(0 0 0 / .4)); transition: transform .15s; }
#map .pin-cluster svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
#map .pin-cluster path { fill: var(--hue); stroke: #fff; stroke-width: 3.5; stroke-linejoin: round; }
#map .pin-cluster path.halo { fill: none; stroke: color-mix(in srgb, var(--hue) 30%, transparent); stroke-width: 11; }
#map .pin-cluster text { fill: #fff; stroke: none; font: 700 17px/1 var(--font); text-anchor: middle; dominant-baseline: central; }
#map .pin-cluster:hover { transform: scale(1.08); }
#map .pin-cluster.idle { --hue: var(--pin-closed); }
@media (prefers-reduced-motion: reduce) { #map .pin-cluster { transition: none; } #map .pin-cluster:hover { transform: none; } }
/* a wall's pin: a hold on the map (src/map.js holdIcon); the same states as the legend below */
#map .pin-mk { display: grid; place-items: center; }
#map .pin-mk svg { width: 34px; height: 34px; overflow: visible; filter: drop-shadow(0 1px 1.5px rgb(0 0 0 / .45)); transition: transform .12s; }
#map .pin-mk .body { fill: var(--pin-open); stroke: var(--pin-edge); stroke-width: 2.5; stroke-linejoin: round; }
#map .pin-mk .bolt { fill: #fff; opacity: .85; }
#map .pin-mk .ring { fill: none; stroke: var(--pin-sun); stroke-width: 3.5; }
#map .pin-mk.soon .body { fill: var(--pin-soon); stroke-width: 5; }
#map .pin-mk.closed .body { fill: var(--pin-closed); transform-box: fill-box; transform-origin: center; transform: scale(.8); }
#map .pin-mk.unknown .body { fill: none; stroke: var(--pin-unknown); stroke-width: 4; }
#map .pin-mk.unknown .bolt { display: none; }
#map .pin-mk.approx .body { stroke-dasharray: 4 3; }
#map .pin-mk.sel svg { transform: scale(1.3); }
#map .pin-mk.sel .body { stroke-width: 4; }
#map .pin-mk.soon.sel .body { stroke-width: 6.5; }
@media (prefers-reduced-motion: reduce) { #map .pin-mk svg { transition: none; } }
/* 핀 설명: a gym wall (dark in both themes) with one hold per pin state; the tape under it carries the exact map pin */
.legend { list-style: none; margin: var(--sp-8) 0 0; padding: var(--sp-16) var(--sp-12) var(--sp-12); display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: var(--sp-16) var(--sp-4); border-radius: var(--r-base); background-color: #2a2d32; background-image: radial-gradient(circle, #4a4f56 1.6px, transparent 2px); background-size: 22px 22px; }
.legend li { display: flex; flex-direction: column; align-items: center; gap: var(--sp-8); }
.legend .pin-hold { width: 58px; height: 58px; overflow: visible; filter: drop-shadow(0 2px 2px rgb(0 0 0 / .45)); }
.legend .pin-hold path { stroke: #f4f2ec; stroke-width: 3; }
.legend .pin-hold .bolt { fill: #2a2d32; opacity: .75; }
.legend .pin-hold .h-open { fill: #3fa592; }
.legend .pin-hold .h-soon { fill: #d0587f; stroke-width: 6; stroke-linejoin: round; }
.legend .pin-hold .h-closed { fill: #b3bab4; stroke-width: 2.5; }
.legend .pin-hold .h-unknown { fill: none; stroke: #fff; stroke-width: 5.5; }
.legend .pin-hold .h-approx { fill: none; stroke: #fff; stroke-width: 4; stroke-dasharray: 6 4.5; }
.legend .pin-hold .h-sun { fill: none; stroke: #f4b942; stroke-width: 5; }
.legend .tape { display: inline-flex; align-items: center; gap: var(--sp-8); padding: 3px var(--sp-12) 3px var(--sp-8); background: #f4f2ec; color: #17191c; font: 700 var(--fs-xs)/1.4 var(--font); box-shadow: 0 1px 2px rgb(0 0 0 / .4); border-radius: 1px; transform: rotate(-1.5deg); white-space: nowrap; }
.legend li:nth-child(even) .tape { transform: rotate(1.2deg); }
/* the dots mirror the pin styles in src/map.js; the tape is paper in both themes, like the map tiles */
.dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid #17191c; flex: none; transform: scale(.85); }
.dot.open { background: var(--pin-open); }
.dot.soon { background: var(--pin-soon); border-width: 3px; }
.dot.closed { background: var(--pin-closed); width: 11px; height: 11px; }
.dot.unknown { border-color: #55585b; border-width: 2.5px; }
.dot.approx { border: 2px dashed #55585b; }
.dot.sunring { outline: 3px solid var(--pin-sun); outline-offset: 2px; margin: 0 5px; }
/* the selected card floats over the map's lower part, so the map and its pins stay in view */
.mapbox { position: relative; }
#pin-card:empty { display: none; }
/* the map card is the list row's own header (rowHead) opened: chips and the line into the sheet under it */
#pin-card { --pad: 16px; background: var(--surface); width: min(440px, calc(100% - 16px)); margin-inline: auto; } /* a phone's width at most: on a wide map the wide 길찾기 would stretch across 600px */
#pin-card .pin-row { border-bottom: 0; }
#pin-card :is(.pin-row, .expand), #pin-card .row-btn:not(:active) { background: var(--surface); } /* one surface: the list's header/body tones only hide the hour grid, which the map has none of */
#pin-card .row-btn { padding-right: calc(var(--pad) + 36px); } /* room for the close button */
#pin-card .row-go { display: none; }
#pin-card :is(.pin-row, .row-btn, .l1, .expand, .expand-in, .dock, .chip-bar, .sheet-row) { min-width: 0; max-width: 100%; } /* a narrow card (320px, big text) shrinks its rows instead of scrolling sideways */
/* the map card's variation of the wall card: three groups (state · actions · info), 16px between them and 8px inside; the dock is the wall card's (길찾기·전화·공유 quiet squares, 다녀왔어요 the one filled button); the line into the sheet is a full-width row under a hairline */
#pin-card .dock { margin-top: var(--sp-2); padding: 0; } /* no side inset: the buttons start on the same line as the ♥, the chips and 암장 정보 자세히 */
#pin-card .dock > .dock-ic, #pin-card .dock-share > .icon-btn { box-shadow: inset 0 0 0 1px var(--line-strong); }
#pin-card .chip-bar { margin: var(--sp-16) 0 0; }
#pin-card .sheet-row { margin-top: var(--sp-8); border-top: 1px solid var(--hair); }
#pin-card .sheet-line { flex: 1 1 auto; width: 100%; min-height: 44px; }
#pin-card .sheet-line i { margin-left: auto; }
#pin-card {
  position: absolute; left: 8px; right: 8px; bottom: 8px; z-index: 1; max-height: 85%; overflow: auto; overscroll-behavior: contain; /* the card is short now; the scroll only guards huge text sizes */
  border-radius: var(--r-base); box-shadow: var(--shadow-float);
}
@media (max-width: 360px) { #pin-card { --pad: 12px; width: auto; left: 0; right: 0; bottom: 0; border-radius: var(--r-base) var(--r-base) 0 0; } } /* 320px: the card spans the map edge to edge and 12px padding give the dock 24px more, so 다녀왔어요 is not clipped (big type at 320px still is: four buttons do not fit) */
@media (max-width: 360px) { #pin-card .been-btn > :not(small) { display: none; } } /* 320px: the stamp goes so the word fits the narrow button */
/* 자세히 보기: the one way on from the map card to the list card */
.pin-more {
  min-height: var(--tap); padding: 0 var(--sp-16); margin-top: var(--sp-2); border: 1px solid var(--line-strong); border-radius: var(--r-base);
  background: transparent; color: var(--fg); font: inherit; font-size: var(--fs-md); font-weight: 600; white-space: nowrap;
}
.pin-more:active { background: var(--sunken); }
/* 이번 주말, 여기: a curated pick, set apart from the timetable below (a tinted band, where the list is
   flat rows with bars). Folded: thumbnail, wall, reason. Opened: day pills + basis, then compact rows. Every control is at least --tap high. */
/* 이번 주 변경: one line on the home for the followed walls, a sheet behind it */
.changes-strip { margin-top: var(--sp-12); }
.changes-list { list-style: none; margin: 0; padding: 0; }
.cs-item { position: relative; display: flex; align-items: center; margin-top: var(--sp-8); border: 1px solid var(--line-strong); border-radius: var(--r-base); background: var(--surface); touch-action: pan-y; transition: transform 240ms var(--ease-out), opacity 240ms var(--ease-out); }
.cs-item:first-child { margin-top: 0; }
.cs-item.dragging { transition: none; }
.cs-main { flex: 1; min-width: 0; min-height: var(--tap); display: grid; gap: var(--sp-2); margin: 0; padding: var(--sp-8) var(--sp-12); border: 0; border-radius: var(--r-base); background: none; color: var(--fg); font: inherit; font-size: var(--fs-sm); text-align: left; cursor: pointer; }
.cs-main b { font-weight: 700; }
.cs-main small { color: var(--muted); font-size: var(--fs-sm); }
.cs-x { flex: none; display: grid; place-items: center; width: var(--tap); min-height: var(--tap); margin: 0; padding: 0; border: 0; background: none; color: var(--muted); cursor: pointer; }
.cs-x svg { width: 18px; height: 18px; }
.cs-main:focus-visible, .cs-x:focus-visible, .ch-all:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ch-all { display: block; white-space: nowrap; margin: var(--sp-4) 0 0 auto; min-height: var(--tap); padding: 0 var(--sp-8); border: 0; background: none; color: var(--accent); font: inherit; font-weight: 600; cursor: pointer; }
@media (prefers-reduced-motion: reduce) { .cs-item { transition: none; } }
.pick { --pad: 16px; margin: var(--sp-12) -16px 0; background: color-mix(in srgb, var(--accent) 7%, var(--bg)); border-block: 1px solid var(--line); }
.pick-sum { display: flex; align-items: center; gap: var(--sp-12); min-height: 56px; padding: 8px var(--pad); list-style: none; cursor: pointer; }
.pick-sum::-webkit-details-marker { display: none; }
.pick-sum::after { content: ""; flex: none; width: 9px; height: 9px; margin: -4px var(--sp-4) 0 0; border: solid var(--muted); border-width: 0 2px 2px 0; transform: rotate(45deg); transition: transform var(--dur-ui) var(--ease-out); }
.pick[open] > .pick-sum::after { transform: translateY(5px) rotate(-135deg); }
.pick-sum:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pick-chip { flex: none; display: flex; }
.pick-chip:empty { display: none; }
.pick-sumtext { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pick-eyebrow { font-size: var(--fs-xs); font-weight: 700; color: var(--accent); }
.pick[open] :is(.pick-chip, .pick-hint) { display: none; } /* opened: the list below says it */
.pick[open] > .pick-sum { min-height: 44px; }
.pick-hint { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-body { padding: 0 var(--pad); }
.pick-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--sp-8); padding-bottom: var(--sp-8); }
.pick-set { flex: none; display: flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); padding: 0 var(--sp-2); border: 0; background: none; color: var(--accent); font: inherit; font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; }
.pick-set svg { flex: none; width: 18px; height: 18px; }
.pick-segs { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--sp-4); margin-bottom: var(--sp-8); padding: 3px; background: var(--sunken); border-radius: var(--r-base); }
.pick-seg { min-height: var(--tap); border: 0; border-radius: var(--r-md); background: transparent; color: var(--muted); font: inherit; font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; }
.pick-seg[aria-pressed="true"] { background: var(--surface); color: var(--accent); box-shadow: var(--shadow-seg); }
.pick-basis { margin: 0 0 var(--sp-8); color: var(--muted); font-size: var(--fs-xs); }
.pick-name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--sp-8); font-size: var(--fs-base); font-weight: 600; line-height: 1.3; overflow-wrap: break-word; }
/* the first pick leads: a larger name and picture; 2nd and 3rd stay compact */
.pick-empty { margin: 0; padding: var(--sp-12) 0; color: var(--muted); font-size: var(--fs-sm); }
/* two days side by side; each column: day, the first pick large with its 09–21 day bar, the others as two short lines */
.pick-bar { justify-content: flex-start; margin-top: calc(var(--sp-8) * -1); } /* the day pills are gone: sit under the title line */
/* one box per day, stacked: 1위 on its own line with the bar, 2·3위 side by side under it at one height */
.pick-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); margin-bottom: var(--sp-8); }
.pick-col { display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface); overflow: hidden; }
.pick-dh { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-8); padding: var(--sp-4) var(--sp-12); border-bottom: 1px solid var(--line); font-size: var(--fs-xs); font-weight: 700; color: var(--accent); }
.pick-dh em { font-style: normal; font-weight: 700; color: var(--soon); white-space: nowrap; }
.pick-dh.wet { background: color-mix(in srgb, var(--soon) 14%, var(--surface)); } /* a wet day: the head says so, in the same pink as 곧 마감 */
.pick-ax { display: flex; justify-content: space-between; margin-top: var(--sp-2); color: var(--muted); font-size: var(--fs-xs); line-height: 1.2; }
.pick-lead, .pick-next { display: flex; flex-direction: column; gap: var(--sp-2); width: 100%; border: 0; background: transparent; color: var(--fg); font: inherit; text-align: left; }
.pick-lead { min-height: var(--tap); padding: var(--sp-12) var(--sp-12); }
.pick-next { min-height: var(--tap); padding: var(--sp-8) var(--sp-12); }
.pick-next + .pick-next { border-left: 1px solid var(--line); }
.pick-lead:active, .pick-next:active { background: var(--sunken); }
.pick-lead .pick-name { font-size: var(--fs-md); font-weight: 700; }
.pick-rest { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-top: 1px solid var(--line); }
.pick-rest > .pick-next:only-child { grid-column: 1 / -1; }
.pick-next .pick-name { font-size: var(--fs-sm); }
.pick-why { font-size: var(--fs-sm); color: var(--muted); }
.pick-next .pick-why { font-size: var(--fs-xs); }
.pick-tl { position: relative; display: block; height: 16px; margin-top: var(--sp-8); border-radius: var(--r-8); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); overflow: hidden; }
.pick-tl > span { position: absolute; top: 0; bottom: 0; }
.pick-tl .sun { background: var(--sun-bar); }
.pick-tl .shade { background: var(--shade-bar); }
.pick-tl::after { content: ""; position: absolute; inset: 0 auto 0 50%; width: 1px; background: rgb(255 255 255 / .55); } /* 15:00 */
.pick-key { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-8); margin: 0 0 var(--sp-8); color: var(--muted); font-size: var(--fs-xs); }
.pick-key .sunnow { margin-right: 0; }
.pick-name .fee { margin-left: 0; }
:is(.pick-why, .pick-key) .sunnow.pic { padding: 1px var(--sp-4); } /* (.sunnow.pic alone is as specific as a bare descendant rule: spell it out) */
.pick-why .sunnow { margin-right: var(--sp-4); vertical-align: -3px; }
:is(.pick-why, .pick-key) .sunnow.pic svg { width: 14px; height: 14px; }
.pick-key .sunnow.shade { background: var(--shade-bar); } /* the key and the bar share the shade tone */
.pick-lead:focus-visible, .pick-next:focus-visible { outline-offset: -2px; } /* inside the day box (overflow hidden) */
.pick-col .pick-empty { padding: var(--sp-12); }
.pick-name .rfav { margin-right: 0; font-size: var(--fs-sm); } /* a 내 암장 leads: the heart sits before the name */
.pick-skip { margin: 0; padding: var(--sp-8) var(--sp-12); border-top: 1px solid var(--line); color: var(--muted); font-size: var(--fs-xs); }
.pick-alt { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-8); border-top: 1px solid var(--line); background: var(--sunken); } /* the 대안: a row of its own, a step quieter */
.pick-altk { color: var(--accent); font-size: var(--fs-xs); font-weight: 700; }
.pick-note { margin: 0; padding: var(--sp-4) 0 var(--sp-12); color: var(--muted); font-size: var(--fs-xs); }
/* 운동 스케줄 비 알림 (src/schedule-view.js): the home card reuses .pick; its week is seven tappable days, and the 내 정보 sheet's weekdays are the same cells as toggles */
.sd-rain { display: inline-flex; padding: var(--sp-2) var(--sp-8); color: var(--soon); }
.sd-rain svg, .sd-ok svg { width: 24px; height: 24px; }
.sd-ok { display: inline-flex; padding: var(--sp-2) var(--sp-8); color: var(--accent); } /* a folded card with nothing wrong: the same chip, without the pink */
.sd-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--sp-2); margin: 0 0 var(--sp-8); padding: 0; list-style: none; }
.sd-day { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); width: 100%; min-height: var(--tap); padding: 0; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface); color: var(--muted); font: inherit; font-size: var(--fs-xs); }
.sd-day b { font-weight: 600; }
.sd-day svg { width: 16px; height: 16px; }
.sd-day.wet { background: color-mix(in srgb, var(--soon) 14%, var(--surface)); } /* a rainy day: the pink of 곧 마감 and the card's wet head; the letter stays dark (the pink on its own tint is 3.3:1), the umbrella carries the colour */
.sd-day.wet b { color: var(--fg); }
.sd-day.wet svg { color: var(--soon); }
.sd-day.mine { outline: 2px solid var(--accent); outline-offset: -2px; } /* a 운동 요일: the frame */
.sd-day.mine[aria-pressed="true"] { outline-color: var(--on-accent); outline-offset: -4px; } /* on the accent fill the frame turns light, inside the edge */
.sd-day.mine b { color: var(--fg); }
.sd-day[aria-pressed="true"], .sd-tog:has(:checked) { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.sd-day[aria-pressed="true"] b, .sd-day[aria-pressed="true"] svg, .sd-tog:has(:checked) b { color: var(--on-accent); }
.sd-tog:has(:checked) b { font-weight: 700; }
.sd-day:focus-visible, .sd-tog:has(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.sd-day:disabled { opacity: .45; } /* a day with no 운동: same dimming as a closing weekday */
.sd-day .pick-altk { line-height: 1; font-weight: 400; } /* 옮김: a wall left this day (a small label in the cell) */
.sd-day[aria-pressed="true"] .pick-altk { color: var(--on-accent); }
.sd-line { flex-direction: row; justify-content: space-between; align-items: baseline; gap: var(--sp-8); border-top: 1px solid var(--line); } /* a wall of the picked day: a row, the picked one a step sunken */
.pick-dh + .sd-line { border-top: 0; }
.sd-line[aria-expanded="true"] { background: var(--sunken); }
.sd-line .pick-why { flex: none; font-size: var(--fs-xs); }
.sd-move { padding: var(--sp-8) var(--sp-12) var(--sp-12); background: var(--sunken); } /* under the picked wall: move it a day; continues the sunken line */
.sd-moveb { display: flex; flex-wrap: wrap; gap: var(--sp-8); }
.sd-move .sh-toggle, .sd-out .sh-toggle { white-space: nowrap; }
.sd-move .sh-toggle:disabled { opacity: .45; cursor: default; } /* the same dimming as a closing weekday */
.sd-move .pick-altk { margin-left: var(--sp-4); } /* 맑음 inside the button */
.sd-move .sh-hint { margin-top: var(--sp-8); }
.sd-out { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-8); }
.sd-tog { cursor: pointer; }
.sd-tog:has(:disabled) { opacity: .45; cursor: default; } /* a closing weekday of the wall: same dimming as the other disabled buttons */
.sd-tog b { color: var(--fg); font-size: var(--fs-sm); }
.sd-tog.sat:not(:has(:checked)) b { color: var(--shade-bar); } /* 토 blue and 일 red (the 응달 blue and the --warn rose) until picked */
.sd-tog.sun:not(:has(:checked)) b { color: var(--warn); }
.sd-key { margin-bottom: var(--sp-8); }
.pick-dh:not(.wet) em { color: var(--muted); } /* a dry day's head: no warning pink */
.sched-note { display: block; width: 100%; min-height: 44px; margin: var(--sp-8) 0 0; padding: var(--sp-8) 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-sm); text-align: left; cursor: pointer; } /* the 기록 tab's 운동 스케줄, as one line of bad news on the list */
.sched-note::after { content: " ›"; }
#sched .pick-hint { white-space: normal; } /* the wall and the day are both worth reading: two lines, not an ellipsis */
.sd-ask { display: flex; flex-direction: column; gap: var(--sp-8); padding: var(--sp-12) var(--pad); } /* 어제 다녀왔어요?: a row under the rain card's slot, one question at a time */
.sd-asktext { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0; font-size: var(--fs-base); font-weight: 600; }
.sd-askbtns { display: flex; gap: var(--sp-8); }
.sh-toggle.sd-yes { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.sh-toggle.sd-yes:focus-visible { outline-color: var(--fg); } /* the filled button's own ring would be the same green */
.sd-wall { clear: both; margin-bottom: var(--sp-12); }
.sd-wallh.end { justify-content: flex-end; } /* 암장 시트: 이름은 머리에 이미 있어 삭제만 */
.sd-wallh { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); margin-bottom: var(--sp-4); }
.sd-adder { clear: both; display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-8); } /* 암장 추가: ♥ 칩 · 검색 · 결과 · 닫기 (기록 추가 시트의 부품) */
.sd-adder .la-chips { margin-bottom: 0; }
.sd-adder .la-field, .sd-adder .la-picks { align-self: stretch; margin-top: 0; }
.card.no-photo { grid-template-columns: minmax(0, 1fr); }
@media (prefers-reduced-motion: no-preference) {
  #pin-card.enter .card { animation: pin-in var(--dur-ui) var(--ease-out); }
  @keyframes pin-in { from { opacity: 0; transform: translateY(12px); } }
}
/* the map credit sits top right (map.js), clear of the card */
#map .leaflet-top.leaflet-right .leaflet-control-attribution { border-radius: 0 var(--r-base) 0 6px; max-width: calc(100% - var(--tap) - var(--sp-24)); } /* wraps in the room right of the zoom buttons (big text made it two lines over +) */
.pin-close {
  position: absolute; top: 4px; right: 4px; z-index: 4; width: 44px; height: 44px; border: 0; border-radius: var(--r-md);
  background: transparent; color: var(--muted); font-size: var(--fs-lg); line-height: 1;
}

/* ---- timetable ---- */
.board { --pad: 16px; position: relative; margin: var(--sp-12) -16px 0; background: var(--surface); border-block: 1px solid var(--line); }
@media (max-width: 559px) { .board { margin-top: 0; border-top: 0; } } /* the time box already ends in a hairline: a second one 10px below read as a glitch */
.axis {
  position: sticky; top: var(--stick-h, 0px); z-index: var(--z-axis); height: 1.625rem; box-shadow: 0 1px 0 var(--line-strong);
  background: color-mix(in srgb, var(--panel) 92%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .axis { background: var(--panel); } }
@media (prefers-reduced-transparency: reduce) { .axis { background: var(--panel); backdrop-filter: none; -webkit-backdrop-filter: none; } }
/* frosted chip over a photo (the time left, the sun mark): translucent white + blur where supported, the old opaque white elsewhere; only on a photo card */
:root { --glass: rgb(255 255 255 / .95); --glass-blur: none; --glass-edge: none; }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { :root { --glass: rgb(255 255 255 / .84); --glass-blur: blur(8px) saturate(140%); --glass-edge: inset 0 0 0 1px rgb(255 255 255 / .3), 0 1px 4px rgb(0 0 0 / .12); } }
@media (prefers-reduced-transparency: reduce) { :root { --glass: rgb(255 255 255 / .95); --glass-blur: none; --glass-edge: none; } }
.axis .t, .axis .nowtag { position: absolute; transform: translateX(-50%); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.axis .t { top: 3px; color: var(--fg); font-weight: 600; left: calc(var(--pad) + (100% - 2 * var(--pad)) * var(--x)); }
.axis .t.under, .axis .dp.under { visibility: hidden; } /* under the time tag (app.js) */
.axis .dp { position: absolute; top: 3px; transform: translateX(-50%); font-size: var(--fs-sm); font-weight: 500; color: var(--muted); white-space: nowrap; left: calc(var(--pad) + (100% - 2 * var(--pad)) * var(--x)); } /* 오전 · 오후 · 저녁 between the numbers */
.axis .m { position: absolute; bottom: 0; width: 1px; height: 5px; background: var(--line-strong); transform: translateX(-50%); left: calc(var(--pad) + (100% - 2 * var(--pad)) * var(--x)); } /* an hour without a number */
.axis .nowtag {
  top: calc(.25em - 1px); white-space: nowrap; z-index: 1; left: clamp(calc(1.5em + 6px), calc(var(--pad) + (100% - 2 * var(--pad)) * var(--x)), calc(100% - 1.5em - 6px)); /* half the tag, so big text keeps it on screen */
  font-weight: 700; line-height: 1; padding: var(--sp-4) var(--sp-8); border-radius: var(--r-sm); background: var(--accent); color: var(--on-accent);
}
.plot { position: absolute; left: var(--pad); right: var(--pad); top: 1.625rem; bottom: 0; pointer-events: none; display: none; } /* the hour grid behind the rows is off: the axis labels and each row's own bar say the time */
.grid { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--hair); }
.tgroup { position: relative; }
/* 연결 세로선: the picked time (the axis chip, app.js sets --x on .board) carried down to every row's pin; drawn as the list's own background, so it runs behind the row words */
#rows-open { background: linear-gradient(color-mix(in srgb, var(--point) 45%, transparent), color-mix(in srgb, var(--point) 45%, transparent)) no-repeat; background-size: 1px 100%; background-position: calc(var(--pad) + (100% - 2 * var(--pad)) * var(--x, -1)) 0; }
.band {
  display: flex; justify-content: space-between; align-items: center; gap: var(--sp-8); min-height: 32px; padding: 4px var(--pad);
  background: var(--sunken); border-bottom: 1px solid var(--line); font-size: var(--fs-xs); font-weight: 600; color: var(--muted);
}
#group-open > .band { min-height: 28px; padding-block: var(--sp-2); background: linear-gradient(color-mix(in srgb, var(--point) 45%, transparent), color-mix(in srgb, var(--point) 45%, transparent)) no-repeat var(--surface); background-size: 1px 100%, auto; background-position: calc(var(--pad) + (100% - 2 * var(--pad)) * var(--x, -1)) 0, 0 0; /* the picked-time line runs through the header too, so the chip and the row pins read as one line */ border-bottom: 0; /* opaque (it is sticky) but the board's own colour: one hairline under the axis, not a third band */ position: sticky; top: calc(var(--stick-h, 0px) + 1.625rem); z-index: var(--z-band); } /* "양달 N · 응달 M · 정렬" stays under the time axis */
summary.band { list-style: none; min-height: var(--tap); }
summary.band::-webkit-details-marker { display: none; }
summary.band > span:first-child::before { content: "▸"; display: inline-block; width: 1.1em; }
details[open] > summary.band > span:first-child::before { content: "▾"; }
#countOpen { color: var(--open); }
.band-note { flex: 1 1 auto; min-width: 0; color: var(--muted); font-size: var(--fs-xs); font-weight: 600; } /* 비 오는 곳 아래로: the only words in the band (its title is for screen readers; the summary above says it) */
#group-open > .band.bare { min-height: 0; padding-block: 0; } /* 0곳: no sort, no sun count, no note: the band folds to the line */
#group-open > .band { font-size: var(--fs-sm); font-weight: 700; color: var(--fg); min-height: 36px; } /* what the list is sorted by must read at a glance, not sink into the axis ticks above */
.sort-btn { position: relative; flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: var(--sp-4); min-height: 32px; padding: 0 var(--sp-8); border: 0; border-radius: var(--r-pill); background: var(--sunken); color: var(--fg); font-size: var(--fs-xs); font-weight: 500; white-space: nowrap; } /* the order of the list as a button: the ⇅ says it can be changed */
.sun-sum { position: relative; flex: none; margin: 0 auto 0 calc(-1 * var(--sp-4)); padding: 0 var(--sp-4); border: 0; background: var(--surface); color: var(--muted); font-size: var(--fs-xs); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; } /* 양달 20 · 응달 12: what makes this app different, the band's only words (its title is sr-only). A --surface plate: the picked-time line passes behind the words, not through them */
.sun-sum[hidden] { display: none; }
.sun-sum::after { content: ""; position: absolute; inset: -12px -6px; } /* the tap area stays 44px */
html[data-text="xlarge"] #group-open > .band { flex-wrap: wrap; row-gap: var(--sp-4); } /* the title keeps its line; 양달 · 응달 goes under it (a four-line title in a pinned band ate a seventh of the screen) */
.sort-btn svg { width: 14px; height: 14px; flex: none; }
.sort-menu { position: absolute; top: calc(100% - var(--sp-2)); right: var(--pad); z-index: 1; display: grid; min-width: 9em; padding: var(--sp-4); border-radius: var(--r-md); background: var(--surface); box-shadow: var(--shadow-float); } /* two choices under the button; the pressed one is bold with a ✓ */
.sort-menu[hidden] { display: none; }
.sort-menu button { min-height: var(--tap); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-sm); background: none; color: var(--fg); font-size: var(--fs-sm); font-weight: 600; text-align: left; white-space: nowrap; }
.sort-menu button[aria-checked="true"] { color: var(--accent); font-weight: 700; }
.sort-menu button[aria-checked="true"]::after { content: " ✓"; content: " ✓" / ""; }
.sort-btn::after { content: ""; position: absolute; inset: -6px -4px; } /* the tap area stays 44px */
:is(.tgroup, .crag-board) .empty { position: relative; margin: 10px var(--pad); background: var(--sheet); } /* covers the grid lines */
.rows { list-style: none; margin: 0; padding: 0; }
:is(.row, .crag-row) { position: relative; isolation: isolate; border-bottom: 1px solid var(--hair); } /* isolate: the ♥, the dock and the photo's tools stack inside the row, never over the sticky time axis and group band */
:is(.row-btn, .crag-head) {
  display: block; width: 100%; min-height: 56px; padding: 13px var(--pad) 14px; text-align: left; line-height: 1.35; --rowbg: var(--surface);
  border: 0; background: none; scroll-margin-top: calc(2.125rem + 2rem); /* html's scroll-padding-top already clears the sticky bars; the margin only leaves room for the axis below them */ transition: background-color var(--dur-press) var(--ease-out);
}
:is(.row-btn, .crag-head):active { background: color-mix(in srgb, var(--fg) 6%, transparent); }
:is(.row-btn, .crag-head):focus-visible { outline-offset: -2px; }
.expand-in :is(a, button, summary), .sheet-open { scroll-margin: calc(var(--stick-h, 0px) + 2.5rem) 0 16px; }
/* name never truncates (wraps instead); region keeps at least 5em or moves down; time left wraps to its own line, right-aligned */
.l1 { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--sp-2) var(--sp-8); }
.rname { min-width: 0; font-size: var(--fs-base); font-weight: 600; letter-spacing: -.01em; }
#rows-open .rname { text-shadow: 0 0 3px var(--surface); } /* the picked-time line runs behind the names */
.sunnow {
  flex: none; padding: 0 var(--sp-8); border-radius: var(--r-8); font-size: var(--fs-xs); font-weight: 600; white-space: nowrap;
  background: color-mix(in srgb, var(--sun) 22%, transparent); color: var(--fg);
}
/* 응달 / 방향 모름: same size, told apart by the word; unknown gets a dashed edge */
.sunnow.shade { background: var(--sunken); }
/* the picture form of 양달 / 응달 on a row (the word is its aria-label and title) and on the filter chips */
.sunnow.pic { display: inline-flex; align-items: center; padding: var(--sp-2) var(--sp-8); }
/* 방향 모름: no chip and a dashed ring, so it weighs less than a known state; 실내: an outlined chip, the sun does not apply */
.sunnow.unknown.pic { padding: var(--sp-2) var(--sp-8); border: 0; background: transparent; color: var(--muted); } /* same height as the other chips */
.sunnow.unknown.pic svg path:first-child { stroke-dasharray: 2.4 3; }
.sunnow.indoor.pic { padding: 1px 5px; color: var(--muted); }
.key li svg { width: 16px; height: 16px; margin-right: var(--sp-4); vertical-align: -3px; }
.sunnow.pic svg { width: 24px; height: 24px; } /* beta feedback: 18px read as too small */
/* the sun icon: ink on the amber chip in light (the amber itself is 2.4:1 there), the amber in dark (6:1) */
.sunnow.sun.pic { background: #a85f0a; color: #fff; } /* a solid chip in the pressed filter's colours: white on a darker amber (4.9:1), white on steel blue */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .sunnow.sun.pic { background: var(--sun-bar); color: var(--on-accent); } }
:root[data-theme="dark"] .sunnow.sun.pic { background: var(--sun-bar); color: var(--on-accent); }
.sunnow.shade.pic { background: var(--shade-bar); color: var(--on-accent); }
/* 양달 | 응달: one capsule with two segments, the icons in the row bars' colours; the pressed segment is filled with its colour (no ✓: the colour says it). Pressing it again clears it. */
.sunnow.unknown { background: transparent; border: 1px dashed var(--line-strong); padding: 0 5px; color: var(--muted); font-weight: 500; }
/* the row extras (다녀옴, region, 요금…) share the room between the name and the time. One line high: an extra that does not fit wraps below and is clipped whole, so there is never half a word or a wrapped closing time */
.rsub { container-type: inline-size; flex: 1 1 0; min-width: 0; display: flex; flex-wrap: wrap; align-content: flex-start; align-items: center; column-gap: var(--sp-8); height: 1.5rem; line-height: 1.5rem; overflow: hidden; }
.rsub > * { flex: none; max-width: 100%; }
/* a hard rule for a stray letter: when the extras are squeezed to almost nothing, none of them shows */
@container (max-width: 4.5em) { .rsub > :not(.newspill) { visibility: hidden; } }
@container (max-width: 9.5em) { .rsub:has(.newspill) .rmeta { display: none; } } /* a pill takes the line before the region is cut to a stub ("서…") */
:is(.row, .crag-row):is(.cold, .wet):not(.is-open) .rname { opacity: .85; }
:is(.row, .crag-row):is(.cold, .wet):not(.is-open) .bar { opacity: .65; } /* a wall below the chosen 기온, or under rain without a roof, recedes (name and bar only: the hours and the temperature stay at full contrast) */
/* 날씨 세트 (card-parts wxSet): 날씨가 먼저다. 해에 영향을 주는 날씨(비·눈·뇌우·강풍·한파·폭염, 해가 든 곳의 흐림)면 칩 그림이 그 날씨가 되고(칩 채움은 양달 주황·응달 파랑 그대로),
   양달/응달 그림은 칩 오른쪽 위의 20px 원 배지(.wx-dir)로 올라간다. 칩 아래 기온 한 줄, 영향 날씨면 --warn. 새 색 없음: 배지 글자는 칩 채움과 같은 양달·응달 색,
   링은 줄 배경(--rowbg)이라 눌린 줄도 깨끗하다. 기온 글자는 흐름에서 빼 두어(absolute) 줄 높이를 늘리지 않고, 막대를 글자 높이만큼 내려 겹침을 막는다(보통 글씨에서 모든 줄 87px). */
:is(.row, .crag-row).is-open :is(.row-btn, .crag-head) { --rowbg: rgb(255 255 255 / .9); }
.wxset { position: relative; flex: none; display: inline-block; margin-right: var(--sp-4); line-height: 0; }
.wxset > .sunnow.pic { margin-right: 0; }
.wx-dir { position: absolute; top: -6px; right: -4px; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; background: #a85f0a; color: #fff; box-shadow: 0 0 0 2px var(--rowbg, var(--surface)); } /* 양달: the chip's own amber, white mark */
.wx-dir svg { width: 14px; height: 14px; stroke-width: 2.4; }
.wxset:has(.sunnow.shade) .wx-dir { background: var(--shade-bar); color: var(--on-accent); }
.wxset:has(.sunnow.unknown) .wx-dir { background: var(--surface); color: var(--muted); box-shadow: inset 0 0 0 1.5px var(--muted), 0 0 0 2px var(--rowbg, var(--surface)); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .wxset:has(.sunnow.sun) .wx-dir { background: var(--sun-bar); color: var(--on-accent); } }
:root[data-theme="dark"] .wxset:has(.sunnow.sun) .wx-dir { background: var(--sun-bar); color: var(--on-accent); }
/* 흐림: the sun is hidden, so the chip is neutral (no 양달 colour, no badge) */
.wxset > .sunnow.pic.scw-veil, .wxset > .sunnow.sun.pic.scw-veil { background: var(--sunken); color: var(--muted); } /* (.sun spelled out: the dark 양달 fill rules are as specific) */
/* the weather picture sits on a soft tint of the chip's colour (the solid dot in the corner is the verdict) */
.wxset > .sunnow.pic.scw-on { background: color-mix(in srgb, var(--sun-chip) 16%, var(--surface)); color: var(--sun-glyph); }
.wxset > .sunnow.shade.pic.scw-on { background: color-mix(in srgb, var(--shade-bar) 16%, var(--surface)); color: var(--shade-glyph); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .wxset > .sunnow.sun.pic.scw-on { background: color-mix(in srgb, var(--sun-bar) 22%, var(--surface)); color: var(--sun-bar); } }
:root[data-theme="dark"] .wxset > .sunnow.sun.pic.scw-on { background: color-mix(in srgb, var(--sun-bar) 22%, var(--surface)); color: var(--sun-bar); }
.wx-temp { position: absolute; top: 100%; left: 50%; transform: translateX(-50%); margin-top: var(--sp-2); font-size: var(--fs-xs); font-weight: 600; line-height: 1; color: var(--muted); white-space: nowrap; }
:is(.row, .crag-row).has-photo.is-open :is(.row-btn, .crag-head) .wx-temp { color: var(--on-photo); }
:is(.row-btn, .crag-head) > .bar { margin-top: calc(var(--fs-xs) + 3px); } /* the temperature hangs under the chip: the bar starts below it even on a 06~07시 row, whose bar begins under the chip */
:is(.row-btn, .crag-head):has(.wx-temp) > .bar { margin-top: calc(var(--fs-xs) + 8px); } /* 320px: 온도 글자 아래로 막대가 4px 겹치던 줄(6~7시 시작 막대) */
/* the list row's chip is a 34px square (the icon centred), so the badge and the name have room */
:is(.row, .crag-row) .sunnow.pic { position: relative; width: 34px; height: 34px; padding: 0; justify-content: center; margin-right: var(--sp-4); }
:is(.row, .crag-row) .sunnow.pic svg { width: 24px; height: 24px; }
/* the sun chip weakens with the sky: 구름 조금 a little lighter, 흐림 lighter (rain keeps the fill: its badge says it) */
:is(.row, .crag-row).part:not(.is-open) .sunnow.sun.pic:not(.scw-on, .scw-veil) { background: #bd7a2a; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) :is(.row, .crag-row).part:not(.is-open) .sunnow.sun.pic:not(.scw-on, .scw-veil) { background: color-mix(in srgb, var(--sun-bar) 70%, transparent); } }
:root[data-theme="dark"] :is(.row, .crag-row).part:not(.is-open) .sunnow.sun.pic:not(.scw-on, .scw-veil) { background: color-mix(in srgb, var(--sun-bar) 70%, transparent); }
/* the open card's row line: the same levels, inverted (a light chip, no ring; the sun mark weakens with the sky) so it still reads on the tinted block or a photo */
:is(.row, .crag-row).is-open.part :is(.row-btn, .crag-head) .sunnow.sun.pic:not(.scw-on, .scw-veil) { position: relative; background: rgb(255 255 255 / .9); color: #a85f0a; box-shadow: none; }
.wx-credit { padding: var(--sp-8) var(--sp-16) 0; font-size: var(--fs-xs); color: var(--muted); }
.wx-credit a { color: inherit; display: inline-block; padding: var(--sp-8) 0; margin: calc(var(--sp-8) * -1) 0; } /* 44px tap area, same line height */
.row-go.pv-arrow { flex: none; width: .75em; margin-left: calc(-1 * var(--sp-4)); font-size: var(--fs-base); line-height: 1; color: var(--muted); text-align: center; } /* the row is a button: › says so */
:is(.row, .crag-row).is-open .row-go { display: none; } /* the open card needs no hint: the › is for the list row only */
.l1 .left { min-width: 3.4em; text-align: right; }
.left .lf-pre { display: none; } /* 가능: only on the open card's pill */
.row.is-open .left .lf-pre { display: inline; } /* "4시간 가능" / "12시간 가능" fill it: the weather before it lines up row to row */
.l1 .rname { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 400px) { .l1 .rname { min-width: 4em; flex: 1 1 4em; } .l1 { flex-wrap: wrap; } .l1 .left { margin-left: auto; } html[data-text="xlarge"] .l1 .rname { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; white-space: normal; } html[data-text="xlarge"] .row.unknown .l1 .left { display: none; } } /* a narrow phone: the name keeps four characters and the time-left pill drops to the next line before it squeezes the name; xlarge may also wrap the name to two lines */ /* 운영시간을 아직 몰라요 is the group's own title above: the row gives the width to the name */ /* the biggest text on a narrow phone: the name may take two lines before it is cut */
@media (max-width: 400px) { html[data-text="xlarge"] .crag-row .l1 .rname { -webkit-line-clamp: 1; line-clamp: 1; } } /* 싱글피치 카드: 가장 큰 글씨의 좁은 폰에서는 이름을 한 줄로 말줄임(전체 이름은 title과 시트 머리에) */
.rmeta { font-size: var(--fs-xs); color: var(--muted); height: 1.5rem; overflow: hidden; } /* wraps at spaces inside its one-line box: "서울 광진구" shows "서울" before it would show half a word */
.left { flex: none; margin-left: auto; font-size: var(--fs-sm); font-weight: 500; white-space: nowrap; color: var(--open); } /* the value is the same on most rows: light; .few (3 hours or less) is bold */
.left.few, :is(.row, .crag-row).is-open .left { font-weight: 700; }
.row.has-photo.is-open .row-btn .left:not(.few) { font-weight: 600; } /* on the photo's pill only the few-hours value is bold: 8시간 and 2시간 must not look the same */
:is(.row, .crag-row).is-open:not(.has-photo) :is(.row-btn, .crag-head) .left { padding: 2px var(--sp-12); border-radius: var(--r-pill); background: color-mix(in srgb, currentColor 12%, transparent); } /* the open card's time left is a pill with or without a photo */
.row.soon .left { color: var(--soon); }
.row.closed .rname, .row.unknown .rname { color: var(--muted); font-weight: 500; }
.row.closed .left, .row.unknown .left { color: var(--muted); font-weight: 400; }
.bar { position: relative; display: block; height: 15px; margin-top: var(--sp-8); }
.row:not(.is-open) > .row-btn:has(.bar) { padding-bottom: var(--sp-8); } /* the bar's own 7px below it plus this: the gap under the bar matches the one above it */
.bar .seg { position: absolute; top: 0; height: 8px; border-radius: var(--r-sm); background: var(--open); }
.bar .seg.past { background: var(--gone); }
/* the two halves of a split interval meet square (no rounded notch where the tone changes) */
.bar .seg.j-end { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.bar .seg.j-start { border-top-left-radius: 0; border-bottom-left-radius: 0; }
/* light bars (closed, the legend's past swatch) get an edge with 3:1 against the sheet, so their length stays readable */
.row.closed .bar .seg { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 70%, transparent); }
.row.soon .bar .seg { background: var(--soon); }
/* 닫힘·단축 제보(closure-warning): the green "열림" fill gives way to a --warn outline, so the bar does not say 열림 over a warning; the passed grey stays */
.row.warned .bar .seg:not(.past), .card.warned .bar .seg:not(.past) { background: transparent; box-shadow: inset 0 0 0 1.5px var(--warn); }
.row.soon .bar .seg.past, .card.soon .bar .seg.past { background: var(--gone); } /* gone is grey on a closing-soon bar too: only the time left is pink */
.row.closed .bar .seg, .row.unknown .bar .seg { background: var(--off); }
.sunband.cap-l, .g-sunon.cap-l { border-top-left-radius: var(--r-sm); border-bottom-left-radius: var(--r-sm); } /* the orange that starts at the bar's start keeps its round end */
.sunband.cap-r, .g-sunon.cap-r { border-top-right-radius: var(--r-sm); border-bottom-right-radius: var(--r-sm); }
.sunband { position: absolute; top: 0; height: 8px; border-radius: 0; background: var(--sun); } /* the open bar itself turns orange where the wall is sunny (only inside the open hours); square ends, so no rounded orange shows inside the green */
.sunband.past { opacity: .45; }
:is(.row, .card) .bar .sunband.past { display: none; } /* gone is one grey, never a paler orange (a crag row keeps its split sun) */
.row.closed .sunband { opacity: .25; } /* a closed wall's sun is reference only */
.tick { position: absolute; top: -3px; height: 14px; width: 2px; margin-left: -1px; background: var(--fg); border-radius: 1px; }
.row.broken { padding: 10px var(--pad); }

/* expanded row: opens and closes in --dur-ui (the same time as the slider's crossfade, src/dom.js crossfadeRows); hidden content leaves the a11y tree */
.expand {
  display: grid; grid-template-rows: 0fr; opacity: 0; visibility: hidden; background: var(--sheet); /* opaque: hides the grid lines */
  transition: grid-template-rows var(--dur-ui) var(--ease-out), opacity var(--dur-ui) var(--ease-out), visibility 0s linear var(--dur-ui);
}
:is(.row, .crag-row).is-open > .expand {
  grid-template-rows: 1fr; opacity: 1; visibility: visible;
  transition: grid-template-rows var(--dur-ui) var(--ease-out), opacity var(--dur-ui) var(--ease-out), visibility 0s;
}
.row.snap > .expand { transition: none; } /* closes at once (toggleRow): the row that was tapped must not move while the page scrolls to it */
.expand-in { min-height: 0; overflow: hidden; padding: 0 var(--pad); }
.row.is-open .expand-in { padding-bottom: var(--sp-16); }
.crag-row.enter > .expand { animation: expand-open var(--dur-ui) var(--ease-out); } /* a crag card is drawn open (renderCragBoard): the row the user just opened plays the wall's opening once */
@keyframes expand-open { from { grid-template-rows: 0fr; opacity: 0; } }
.herowrap { position: relative; margin-top: var(--sp-2); }
/* an open row with a photo: the photo fills the row's head cell and the row's own line, bar and the hours sit on it */
.rhero { display: none; margin: 0; }
:is(.row, .crag-row).has-photo.is-open { display: grid; grid-template-columns: minmax(0, 1fr); }
:is(.row, .crag-row).has-photo.is-open > :is(.rhero, .row-btn, .crag-head) { grid-area: 1 / 1; }
:is(.row, .crag-row).has-photo.is-open > :is(.expand, .crag-body) { grid-area: 2 / 1; }
:is(.row, .crag-row).has-photo.is-open > .rhero { display: block; min-height: 280px; background: var(--off); }
.rhero-track { position: absolute; inset: 0; display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.rhero-track::-webkit-scrollbar { display: none; }
.rhero-slide { flex: none; width: 100%; height: 100%; scroll-snap-align: center; }
.rhero img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rhero.has-tools .rhero-track { cursor: pointer; }
.rhero-foot, .rhero-foot * { pointer-events: none; } .rhero-foot a { pointer-events: auto; } /* the swipe goes through the text to the photos */
.rhero.has-tools .rhero-foot:not(:has(.rhero-wx)) .credit { margin-bottom: var(--sp-32); } /* the dots and the camera take the foot's last line */
/* right-bottom: faint dots (the current one stretches out with a springy pop) and the camera that sends one more; the tap area is 44px, the chip stays small */
.rhero-tools { position: absolute; z-index: 2; right: calc(var(--pad) - 6px); bottom: var(--sp-8); display: inline-flex; align-items: center; gap: var(--sp-2); height: 28px; color: var(--on-photo); filter: drop-shadow(0 1px 2px rgb(0 0 0 / .65)); }
.rhero-dots { display: inline-flex; align-items: center; gap: var(--sp-4); margin-right: var(--sp-8); }
.rhero-dots i { width: 4px; height: 4px; border-radius: 3px; background: rgb(255 255 255 / .55); box-shadow: 0 0 0 1px rgb(0 0 0 / .28); transition: width 260ms cubic-bezier(.34, 1.56, .64, 1), height 260ms cubic-bezier(.34, 1.56, .64, 1), background-color 160ms, transform 160ms; }
.rhero-dots i.on { width: 11px; height: 6px; background: rgb(255 255 255 / .95); }
.rhero-dots i.edge { transform: scale(.6); }
@media (prefers-reduced-motion: reduce) { .rhero-dots i { transition: none; } }
.rhero-add { position: relative; width: 32px; height: 32px; display: grid; place-items: center; padding: 0; border: 0; background: none; color: inherit; opacity: .92; cursor: pointer; }
.rhero-add::after { content: ""; position: absolute; inset: -9px -6px; }
.rhero-add svg { width: 21px; height: 21px; }
/* the full-screen gallery (src/gallery-view.js) */
dialog.gal { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: #0b0d0c; color: #fff; flex-direction: column; animation: gal-in var(--dur-ui) var(--ease-out); }
dialog.gal[open] { display: flex; }
@keyframes gal-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { dialog.gal { animation: none; } }
.gal-bar { display: flex; align-items: center; justify-content: space-between; min-height: 56px; padding: var(--sp-8) var(--sp-8) var(--sp-8) var(--sp-16); }
.gal-count { font-size: var(--fs-base); font-weight: 600; font-variant-numeric: tabular-nums; }
.gal-btn { width: var(--tap); height: var(--tap); display: grid; place-items: center; border: 0; border-radius: 50%; background: none; color: #fff; font-size: 22px; cursor: pointer; }
.gal-btn:active { background: rgb(255 255 255 / .12); }
.gal-track { flex: 1; min-height: 0; display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.gal-track::-webkit-scrollbar { display: none; }
.gal-slide { flex: none; width: 100%; scroll-snap-align: center; display: flex; align-items: center; }
.gal-slide img { width: 100%; max-height: 100%; object-fit: contain; display: block; }
.gal-zoom { display: block; width: 100%; max-height: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.gal-slide.zoomed { display: block; overflow: auto; overscroll-behavior: contain; touch-action: pan-x pan-y; scrollbar-width: none; }
.gal-slide.zoomed::-webkit-scrollbar { display: none; }
.gal-slide.zoomed .gal-zoom { width: 300%; max-height: none; cursor: zoom-out; }
.gal-slide.zoomed img { width: 100%; max-height: none; }
dialog.gal.is-zoomed .gal-track { overflow-x: hidden; scroll-snap-type: none; }
dialog.gal.is-zoomed .gal-navs, dialog.gal.is-zoomed .gal-hint { display: none; }
.gal-hint { margin: 0; padding: var(--sp-4) var(--sp-16) 0; text-align: center; font-size: var(--fs-sm); color: rgb(255 255 255 / .65); }
.gal-navs { position: absolute; top: 50%; left: 0; right: 0; display: flex; justify-content: space-between; padding: 0 var(--sp-8); pointer-events: none; }
.gal-navs .gal-btn { pointer-events: auto; background: rgb(0 0 0 / .45); } .gal-navs .gal-btn:disabled { opacity: 0; pointer-events: none; }
@media (hover: none) { .gal-navs { display: none; } }
.gal-meta { margin: 0; padding: var(--sp-12) var(--sp-16) var(--sp-2); min-height: 30px; font-size: var(--fs-sm); color: rgb(255 255 255 / .8); } .gal-meta b { color: #fff; font-weight: 600; }
.gal-thumbs { display: flex; gap: var(--sp-8); padding: var(--sp-8) var(--sp-16) var(--sp-12); overflow-x: auto; scrollbar-width: none; }
.gal-thumbs::-webkit-scrollbar { display: none; }
.gal-thumbs button { flex: none; width: 44px; height: 44px; padding: 0; border: 2px solid transparent; border-radius: var(--r-8); overflow: hidden; background: #222; opacity: .6; cursor: pointer; }
.gal-thumbs button.on { border-color: #fff; opacity: 1; }
.gal-thumbs img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gal-foot { padding: var(--sp-8) var(--sp-16) var(--sp-16); } .gal-foot[hidden] { display: none; }
.gal-send { width: 100%; min-height: 48px; border: 1px solid rgb(255 255 255 / .55); border-radius: var(--r-pill); background: none; color: #fff; font: inherit; font-size: var(--fs-base); font-weight: 600; white-space: nowrap; cursor: pointer; }
.rhero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, rgb(0 0 0 / .6) 0%, rgb(0 0 0 / .4) 42%, rgb(0 0 0 / .1) 58%, rgb(0 0 0 / .1) 64%, rgb(0 0 0 / .8) 100%); pointer-events: none; }
.row.is-open > .expand .linkbar { margin: 0 calc(var(--pad) * -1); border-top: 0; } /* as wide as the photo and right under it: the photo's own toolbar */
/* the wide two-column card: a photo card has no head line, so the info starts in the first row (the strip above spans both columns) */
@media (min-width: 560px) and (max-width: 1023px) { .row.has-photo .m-cols { margin-top: 0; } .row.has-photo .m-cols:not(:has(> .m-head :is(.x-sub, .addr-btn))) > .m-info { grid-row: 1; } } /* the info rises beside the sun box only when the (otherwise empty) head holds nothing: a 휴게 line or note in it keeps its own row above */
.rhero-foot { position: absolute; z-index: 1; left: var(--pad); right: var(--pad); bottom: var(--sp-12); display: flex; flex-direction: column; gap: var(--sp-12); }
.rhero-line { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-8); }
.rhero-wx { min-height: 1.5rem; line-height: 1.5rem; margin: 0; color: var(--on-photo); text-shadow: 0 1px 3px rgb(0 0 0 / .5); font-size: var(--fs-sm); font-weight: 500; } 
.rhero-wx .strong { font-weight: 700; }
.wx-pill { display: inline-block; margin-left: var(--sp-8); padding: 0 var(--sp-8); border-radius: var(--r-pill); background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); font-weight: 700; line-height: 1.25rem; white-space: nowrap; text-shadow: none; } /* a judgement ("바람 셈") reads as a pill, not as another number */
.rhero-wx .wx-pill { background: rgb(255 255 255 / .95); color: var(--soon-on-white); }
.rhero-cap { min-width: 0; color: var(--on-photo); text-shadow: 0 1px 3px rgb(0 0 0 / .5); }
.rhero-cap small { display: block; font-size: var(--fs-sm); font-weight: 500; }
.rhero-cap b { display: block; font-size: 2rem; line-height: 1.15; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.rhero .credit { position: static; flex: 0 1 auto; min-width: 0; max-width: 55%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-xs); opacity: .85; padding: 0; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; color: rgb(255 255 255 / .8); text-shadow: 0 1px 3px rgb(0 0 0 / .6); } /* a licensed photo: its credit as quiet text */
:is(.row, .crag-row).has-photo.is-open > :is(.row-btn, .crag-head) { position: relative; z-index: 1; align-self: start; color: var(--on-photo); text-shadow: 0 1px 3px rgb(0 0 0 / .5); }
:is(.row, .crag-row).has-photo.is-open :is(.row-btn, .crag-head) :is(.rname, .rmeta, .basis, .fee, .been, .setnew, .newspill) { color: var(--on-photo); }
:is(.row, .crag-row).has-photo.is-open :is(.row-btn, .crag-head) :is(.setnew, .newspill) { background: transparent; border-color: currentColor; } /* over a photo there is no paper to fill: the outline keeps it legible */
:is(.row, .crag-row).has-photo.is-open :is(.row-btn, .crag-head):focus-visible { outline-color: var(--on-photo); box-shadow: inset 0 0 0 4px rgb(0 0 0 / .45); } /* a ring that shows on a photo: white inside a dark edge */
.row.has-photo.is-open .row-btn .left { padding: 2px var(--sp-12); border-radius: var(--r-pill); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--glass-edge); color: var(--open-on-white); text-shadow: none; } /* a white pill in both themes: its text keeps the light theme's dark colours */
.row.susp .rname { min-width: 4em; } /* the name never gives way to the reason */
.row.susp .left { flex: 0 1 auto; min-width: 0; max-width: 9em; overflow: hidden; text-overflow: ellipsis; } /* a shut wall's reason can be long: it gives way instead of pushing the row wider */
.row.is-open:is(.susp, .unknown) .row-btn .left { display: none; } /* an open card says the reason itself; a photo says 임시 휴관 중 in its pill */
.row.has-photo.is-open.soon .row-btn .left { color: var(--soon-on-white); }
.row.has-photo.is-open:is(.closed, .unknown) .row-btn .left { color: var(--muted-on-white); }
:is(.row, .crag-row).has-photo.is-open :is(.row-btn, .crag-head) .sunnow { text-shadow: none; } /* on the photo the sun mark is a white pill like the time left: a tinted chip washes out over a picture */
:is(.row, .crag-row).has-photo.is-open :is(.row-btn, .crag-head) .sunnow.pic { background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); box-shadow: var(--glass-edge); backdrop-filter: var(--glass-blur); color: var(--sun-on-white); }
:is(.row, .crag-row).has-photo.is-open :is(.row-btn, .crag-head) :is(.sunnow.shade, .sunnow.unknown, .sunnow.indoor).pic { color: var(--muted-on-white); }
.row.has-photo.is-open .bar .seg { background: var(--on-photo); box-shadow: none; }
.row.has-photo.is-open.soon .bar .seg { background: var(--soon-on-white); box-shadow: 0 0 0 1px #fff; } /* closing soon over a photo: pink with a white edge */
.row.has-photo.is-open.warned .bar .seg:not(.past) { background: transparent; box-shadow: inset 0 0 0 1.5px var(--on-photo); } /* the warning's outline over a photo */
.row.has-photo.is-open .bar .seg.past, .row.has-photo.is-open.soon .bar .seg.past { background: rgb(255 255 255 / .55); box-shadow: 0 0 0 1px rgb(0 0 0 / .3); } /* gone: still visible over a bright sky, edged like the sun band */
/* the pin (thicker on an open card) and the time-left chip say where now is: the grey/colour split is not the only cue */
.row.is-open .tick, .card .tick { width: 3px; margin-left: -1.5px; }
/* open and close time under the bar's ends, on every row: pulled up into the bar box's empty lower half, so a row grows by little more than the text */
.gauge-ends { display: none; } /* a folded row and the map card keep the bar clean: the times show once a list card is open */
:is(.row, .crag-row).is-open .gauge-ends { display: flex; justify-content: space-between; gap: var(--sp-8); margin-top: calc(var(--sp-4) * -1); font-size: var(--fs-xs); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--muted); }
:is(.row, .crag-row).has-photo.is-open .gauge-ends { color: var(--on-photo); text-shadow: 0 0 3px rgb(0 0 0 / .75), 0 1px 3px rgb(0 0 0 / .8); } /* the same edge as the photo credit: the end times stay readable on a bright sky, where the scrim has faded */
/* time-left chip on every open row, folded or open: "10h" on a narrow phone, "10시간 가능" with room (a shut row keeps its rowLeft words) */
.lf-card .lf-l { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } /* narrow: clipped, not display:none, so a screen reader still hears the long wording */
@media (min-width: 421px) { .lf-card .lf-s { display: none; } .lf-card .lf-l { position: static; width: auto; height: auto; overflow: visible; clip: auto; } }
:is(.row, .crag-row).has-photo.is-open .tick { background: var(--on-photo); box-shadow: 0 0 0 1px rgb(0 0 0 / .4); }
:is(.row, .crag-row).has-photo.is-open .sunband { box-shadow: 0 0 0 1px rgb(0 0 0 / .35); }
.x-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.x-top { display: flex; align-items: flex-start; justify-content: flex-end; gap: var(--sp-8); }
.x-top .x-name { flex: 1; min-width: 0; }
:is(.row, .crag-row).is-open { position: relative; z-index: 1; background: var(--bg); } /* above the board's hour grid: an open card hides the grid lines behind it */
:is(.row, .crag-row).is-open:not(.has-photo) { --ph-tint: color-mix(in srgb, var(--off) 70%, var(--sun) 12%); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) :is(.row, .crag-row).is-open:not(.has-photo) { --ph-tint: var(--panel); } } /* dark: a plain panel, not olive/brown */
:root[data-theme="dark"] :is(.row, .crag-row).is-open:not(.has-photo) { --ph-tint: var(--panel); }
:is(.row, .crag-row).is-open:not(.has-photo) > :is(.row-btn, .crag-head) { background: var(--ph-tint); box-shadow: 0 1px 0 var(--ph-tint); } /* the shadow closes the sub-pixel seam above the hours block */ /* no photo: the row's own line is part of the same grey block as the hours below it */
.ph-hero { position: relative; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-8); min-height: 96px; padding: var(--sp-12) var(--pad); margin: 0 calc(var(--pad) * -1); background: var(--off); }
/* no photo yet: the 해벽 mark, very faint, stands where the picture would be */
.ph-hero { overflow: hidden; background: var(--ph-tint); }
.ph-hero::before { content: ""; position: absolute; inset: 0; background: url("assets/ph-hero-light.svg") center / cover no-repeat; pointer-events: none; } /* raking light on wall panels (docs/design/ph-hero-philosophy.md): only lines, laid over the condition tint */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .ph-hero::before { background-image: url("assets/ph-hero-dark.svg"); } }
:root[data-theme="dark"] .ph-hero::before { background-image: url("assets/ph-hero-dark.svg"); }
.ph-hero > * { position: relative; }
.ph-hero .rhero-cap { color: var(--fg); text-shadow: none; }
.ph-hero .rhero-add { color: var(--accent); width: 44px; height: 44px; margin: 0 0 0 -10px; }
.ph-hero .rhero-add svg { width: 24px; height: 24px; }
.photo-ask { flex: none; display: inline-flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); margin: calc(var(--sp-4) * -1) 0 calc(var(--sp-12) * -1); padding: 0; border: 0; background: none; color: var(--accent); font: inherit; font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; cursor: pointer; } /* no photo yet: a quiet link at the right end of the name row */
.photo-ask svg { width: 16px; height: 16px; }
.x-name { margin: var(--sp-12) 0 var(--sp-2); font-size: var(--fs-lg); line-height: 1.25; font-weight: 700; letter-spacing: -.02em; min-width: 0; overflow-wrap: break-word; }
.x-sub { font-size: var(--fs-sm); color: var(--muted); }
.today { margin-top: var(--sp-12); font-size: var(--fs-base); }
/* 오늘 운영 … with 다녀왔어요 at the right end; a long line pushes the pill to the right of the next line */
.today-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-8) var(--sp-12); margin-top: var(--sp-12); }
.today-row .today { margin-top: 0; min-width: 0; }
.today span { color: var(--muted); font-size: var(--fs-sm); margin-right: var(--sp-8); }
/* the decision line: today's hours one step larger */
.susp-pill { display: inline-block; padding: 0 var(--sp-12); border-radius: var(--r-pill); background: var(--warn); color: var(--on-accent); font-size: var(--fs-sm); line-height: 1.8; white-space: nowrap; }
.today-row .today b.susp-pill, .rhero-cap b.susp-pill { display: inline-block; width: fit-content; margin-top: var(--sp-4); font-size: var(--fs-sm); line-height: 1.8; letter-spacing: 0; text-shadow: none; } /* a small pill, not the 2rem hours of an open day */
/* 닫힘·단축 제보: a --warn pill in the place of the remaining-time pill, the phone beside it (44px target); the words carry it, colour only helps */
.warn-wrap { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); vertical-align: middle; }
.warn-pill { display: inline-block; padding: 0 var(--sp-12); border-radius: var(--r-pill); background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); font-weight: 700; font-size: var(--fs-sm); line-height: 1.8; max-width: 100%; }
.warn-pill .wp-t, .warn-pill .wp-s { white-space: nowrap; } /* the pill folds to two lines at a word edge (큰 글자·320px), each half stays whole; the short .warn-left label keeps its nowrap */
.warn-left { color: var(--warn); font-weight: 700; white-space: nowrap; }
.has-photo.is-open .warn-left { color: var(--soon-on-white); } /* it sits on the white glass pill in both themes */
.warn-line { margin-top: var(--sp-8); }
.warn-note { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); color: var(--warn); }
.row.is-open.warned .row-btn .left { display: none; } /* the open card says it in its own pill */
.row.has-photo.is-open.warned .row-btn .left { display: inline-block; color: var(--soon-on-white); } /* a photo card: the glass pill on the photo says 확인 전 (the one place the eye starts) */
.g-lead.susp { color: var(--warn); font-weight: 600; }
.today-row .today b { font-size: var(--fs-lg); letter-spacing: -.02em; }
/* 혼잡도: the level is in the words; the 3-bar meter (1 여유 · 2 보통 · 3 혼잡 filled) repeats it without colour */
.crowd-chip { display: inline-flex; align-items: center; gap: var(--sp-8); margin-top: var(--sp-8); padding: var(--sp-2) var(--sp-12); border: 1px solid var(--line); border-radius: var(--r-pill); font-size: var(--fs-sm); }
.crowd-chip.muted { color: var(--muted); border-style: dashed; font-size: var(--fs-xs); }
/* 날씨·바람: one quiet line under the 혼잡도 chip; 바람 셈 is a neutral outlined pill (--warn already means 곧 닫힘 / 오래됨) */
/* the 날씨 상자 on the open card, above the sun box */
.wx-box { margin: var(--sp-12) 0 0; padding: var(--sp-8) var(--sp-12); border: 1px solid var(--line); border-radius: var(--r-base); background: var(--surface); display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-12); } /* one slim row: now · the next hours (the hours wrap under at a narrow width) */
/* in the sun box the 날씨 is the sky's first line: no card of its own, a hairline under it, the sky's own text colour */
.sunbox.sc .wx-box { margin: 0; padding: var(--sp-8) 0; border: 0; border-radius: 0; background: none; color: inherit; border-bottom: 1px solid color-mix(in srgb, currentColor 16%, transparent); }
.sunbox.sc .wx-box :is(.wxb-d, .wxb-obs, .wxb-hrs li, .wxb-hrs small, .wxb-rain) { color: inherit; }
.sunbox.sc .wx-box :is(.wxb-d, .wxb-obs, .wxb-hrs li) { opacity: .85; }
.sunbox.sc .wx-box .wxb-hrs b { color: inherit; }
.sunbox.sc .wx-box .wxb-hrs li { border-left-color: color-mix(in srgb, currentColor 18%, transparent); }
.wxb-top { flex: 1 1 0; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-8); }
.wxb-t { font-size: var(--fs-xl); font-weight: 700; line-height: 1.2; }
.wxb-d { font-size: var(--fs-xs); color: var(--muted); }
.wxb-obs { flex: none; margin-left: auto; font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.wxb-top .wx-pill { margin-left: 0; align-self: center; }
.wxb-top .wxb-d { flex: 0 1 auto; min-width: 0; }
.sunbox.sc .wx-box .wx-pill { background: var(--soon-on-white); color: #fff; } /* readable on every sky, light or dark */
.wx-pill.cold { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; color: var(--muted); } /* 기온 낮음 is a condition, not a harm: muted like the row badge (--warn stays for rain and wind) */
.sunbox.sc .wx-box .wx-pill.cold { background: rgb(0 0 0 / .62); color: #fff; } /* .62 (the photo credit's dark): 4.5:1+ for white even on the palest sky; was .4 = ~3:1 */
.wxb-hrs { flex: 0 1 auto; list-style: none; display: flex; margin: 0; padding: 0; }
.wxb-hrs li { flex: none; min-width: 2.6rem; display: grid; justify-items: center; font-size: var(--fs-xs); color: var(--muted); border-left: 1px solid var(--hair); }
.wxb-hrs li:first-child { border-left: 0; }
.wxb-hrs b { font-size: var(--fs-md); color: var(--fg); }
.wxb-hrs small { font-size: var(--fs-xs); color: #2f62b0; }
.wxb-rain { flex: 1 0 100%; margin: 0; font-size: var(--fs-sm); font-weight: 600; color: #2f62b0; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) :is(.wxb-hrs small, .wxb-rain) { color: #8db4ee; } }
:root[data-theme="dark"] :is(.wxb-hrs small, .wxb-rain) { color: #8db4ee; }
.wx-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-8); margin-top: var(--sp-8); font-size: var(--fs-sm); color: var(--muted); }
.wx-k { font-size: var(--fs-xs); font-weight: 600; color: var(--muted); }
.wx-chip { color: var(--fg); white-space: nowrap; }
.wx-chip + .wx-chip::before { content: "·"; margin-right: var(--sp-8); color: var(--muted); font-weight: 400; }
.wx-chip.wx-t { font-weight: 700; }
.wx-chip.strong { color: var(--warn); font-weight: 700; }

.crowd-meter { flex: none; display: inline-flex; align-items: flex-end; gap: var(--sp-2); height: 12px; }
.crowd-meter i { width: 4px; border: 1px solid currentColor; border-radius: 1px; }
.crowd-meter i:nth-child(1) { height: 6px; }
.crowd-meter i:nth-child(2) { height: 9px; }
.crowd-meter i:nth-child(3) { height: 12px; }
.crowd-chip[data-level="여유"] i:nth-child(-n+1),
.crowd-chip[data-level="보통"] i:nth-child(-n+2),
.crowd-chip[data-level="혼잡"] i:nth-child(-n+3),
.crowdnow[data-level="여유"] i:nth-child(-n+1),
.crowdnow[data-level="보통"] i:nth-child(-n+2),
.crowdnow[data-level="혼잡"] i:nth-child(-n+3) { background: currentColor; }
/* list-row pill: same size as .sunnow, outlined so it doesn't read as sun */
.crowdnow { flex: none; display: inline-flex; align-items: center; gap: var(--sp-4); padding: 0 var(--sp-8); border: 1px solid var(--line-strong); border-radius: var(--r-8); font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; color: var(--fg); }
/* 혼잡 stands out in the list: --soon (the warning colour) on the text and edge; the three filled bars still say it without colour */
.crowdnow[data-level="혼잡"] { color: var(--soon); border-color: var(--soon); font-weight: 700; }
/* 여유 · 보통 · 혼잡 in the 기록 추가 sheet: pressed shows ✓ and fills, so not by colour alone */
.crowd-pills { display: flex; gap: var(--sp-8); }
.crowd-pill, .la-chip {
  min-height: var(--tap); min-width: 64px; padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  background: var(--surface); font-size: var(--fs-sm); font-weight: 600; white-space: nowrap;
  transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out);
}
/* 지금 어때요?: the one-tap report in the open card, under the 혼잡도 chip */
.crowd-pill:disabled { opacity: .45; cursor: default; }
.crowd-pill:active, .la-chip:active { transform: scale(.97); }
.crowd-pill[aria-pressed="true"], .la-chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.crowd-pill[aria-pressed="true"]::before, .la-chip[aria-pressed="true"]::before { content: "✓"; content: "✓" / ""; margin-right: var(--sp-2); }
.stale-note { margin-top: var(--sp-4); font-size: var(--fs-sm); font-weight: 600; color: var(--muted); } /* muted note: --fs-sm, 600 */
.tags { margin-top: var(--sp-8); display: flex; flex-wrap: wrap; gap: var(--sp-8); }
.tags-line { margin: 0; font-size: var(--fs-sm); color: var(--muted); }
.meta-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-8); margin: var(--sp-12) 0 0; } /* the rope chip and the wall's facts share a row */
.meta-row .chip { white-space: nowrap; }
.expand-in .meta-go { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-8); box-sizing: border-box; width: 100%; margin: var(--sp-8) 0 0; min-height: var(--tap); }
.meta-part { display: flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.chip.fact { white-space: nowrap; } /* an informing chip (스피드월, 지붕): the plain grey .chip, no border, nothing to press */
.chip.rental { border: 1px solid currentColor; background: transparent; color: var(--open); font: inherit; font-size: var(--fs-xs); font-weight: 600; line-height: 1.5; white-space: nowrap; cursor: pointer; padding: var(--sp-2) var(--sp-8); border-radius: var(--r-8); }
.chip.rental:focus-visible, .meta-part:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pv-sub { display: block; font-size: var(--fs-xs); font-weight: 400; color: var(--muted); } /* the wall's own lot, under the cost */
/* 로프 pills under the facts: what the wall asks, and (with 내 로프 picked) whether mine is enough, in the parking chips' outlined look */
.rope-line { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin: var(--sp-8) 0 0; }
.chip.rope { border: 1px solid var(--line-strong); background: transparent; font-weight: 600; white-space: nowrap; }
.chip.rope.ok { color: var(--open); border-color: currentColor; }
.chip.rope.short { color: var(--soon); border-color: currentColor; }
.chip.rope svg { width: 12px; height: 12px; vertical-align: -2px; margin-right: var(--sp-4); } /* the ! of a rope too short */
/* 길찾기 · 공지사항 · 전화 …: a flat strip like the list rows (hairlines, icon over word); 44px+ tall, a cell is the tap area */
.linkbar { display: flex; flex-wrap: wrap; margin-top: var(--sp-12); border-block: 1px solid var(--hair); }
.lb-item { flex: 1 1 0; min-width: 44px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); min-height: 48px; padding: var(--sp-8) var(--sp-4); color: var(--fg); font-size: var(--fs-xs); font-weight: 600; text-decoration: none; text-align: center; transition: background-color var(--dur-press) var(--ease-out); }
.lb-item svg { width: 22px; height: 22px; color: var(--fg); } /* icon only: a bit larger and as dark as the text it replaces */
.lb-item:active { background: color-mix(in srgb, var(--fg) 6%, transparent); }
.lb-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.linkbar > * + * { border-left: 1px solid var(--hair); }
button.lb-item { border: 0; background: none; font: inherit; font-size: var(--fs-xs); font-weight: 600; cursor: pointer; }
.linkbar > .share-wrap { flex: 1 1 0; min-width: 44px; display: flex; margin: 0; }
.linkbar > .share-wrap > .lb-item { flex: 1; }
.nav-dlg { width: min(340px, calc(100% - 48px)); padding: var(--sp-24) var(--sp-24) var(--sp-8); border: 0; border-radius: 20px; background: var(--surface); color: var(--fg); box-shadow: var(--shadow-float); }
.nav-dlg::backdrop { background: rgb(0 0 0 / .45); }
.nd-title { margin: 0 0 var(--sp-12); font-size: var(--fs-lg); font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.nd-opt, .nd-more { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); width: 100%; min-height: 52px; padding: 0; border: 0; border-top: 1px solid var(--hair); background: none; color: inherit; font: inherit; font-size: var(--fs-base); text-align: left; cursor: pointer; }
.nd-more { color: var(--accent); font-size: var(--fs-md); }
.nd-def { font-style: normal; font-size: var(--fs-xs); color: var(--accent); background: var(--accent-soft); padding: 0 var(--sp-8); border-radius: var(--r-pill); }
.nd-opt:focus-visible, .nd-more:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.nav-pick { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin-top: var(--sp-8); }
.nav-pick button { flex: 1 1 0; min-height: 44px; padding: 0 var(--sp-8); border: 1px solid var(--hair); border-radius: 10px; background: var(--bg); color: var(--fg); font: inherit; font-weight: 600; white-space: nowrap; cursor: pointer; }
.nav-pick button.plain { flex: 0 0 auto; color: var(--muted); font-weight: 500; }
.nav-pick button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tag { display: inline-block; border: 1px solid var(--line); border-radius: var(--r-md); padding: 0 var(--sp-12); font-size: var(--fs-xs); line-height: 2; }
.tag.brk { background: var(--sunken); border-color: transparent; }
.hol-note { margin-top: var(--sp-4); font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
/* sun box: compass column (Task 4 draws into .sundial-slot) + words */
.sunbox {
  display: flex; flex-direction: column; gap: var(--sp-12); margin-top: var(--sp-12);
  padding: var(--sp-16); border-radius: var(--r-lg); background: color-mix(in srgb, var(--panel) 55%, transparent);
}
.sunbox.solo .sb-txt { display: flex; flex-direction: column; gap: var(--sp-12); }
/* top line: state chip + the key value (big). several windows each stay in one piece */
.sb-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-12); }
.sb-chip { display: inline-flex; align-items: center; gap: var(--sp-8); min-height: 32px; padding: 0 var(--sp-12); border-radius: 999px; background: var(--sunken); color: var(--fg); font-size: var(--fs-md); font-weight: 700; white-space: nowrap; }
.sb-chip.lit { background: color-mix(in srgb, var(--sun) 28%, var(--paper)); }
.sb-chip.lit::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--sun); }
.sb-chip.na { color: var(--muted); }
.sb-fig { width: 100%; max-width: 360px; margin: 0 auto; }
.sundial-slot { aspect-ratio: 360 / 166; border-radius: var(--r); overflow: hidden; line-height: 0; }
/* the picture sits above the words in every layout */
.sunbox:not(.solo) {
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "head" "verd" "fig" "sent" "note" "why"; /* one column: the picture is wide enough to read its own labels */
}
.sunbox:not(.solo) > .sb-head { grid-area: head; }
.sunbox:not(.solo) > .sun-verdict { grid-area: verd; }
.sunbox:not(.solo) > .sb-fig { grid-area: fig; max-width: 360px; margin: var(--sp-8) auto var(--sp-4); }
.sunbox:not(.solo) > .dsent { grid-area: sent; }
.sunbox:not(.solo) > .sun-why { grid-area: why; }
.sunbox:not(.solo) > .sun-extra { grid-area: note; }
.sun-extra { display: grid; gap: var(--sp-8); }
/* the sky hides the sun (cloud, rain …): a quiet line, the verdict above is about where the sun falls */
.sun-veil { margin: 0; display: flex; align-items: center; gap: var(--sp-8); font-size: var(--fs-sm); line-height: 1.5; color: var(--muted); }
.sun-veil svg { width: 16px; height: 16px; flex: none; }
/* 등반 어려움 (rain / snow / thunder / strong wind): the weather line leads the sun box, the picture and the words under it step back (no new colour: the same sky, quieter) */
.sunbox.wx-hard :is(.sb-fig, .sb-ground) { opacity: .55; filter: saturate(.4); }
/* a wall that faces different ways: the verdict is for the main wall. A quiet callout, not a warning: small, full-contrast text on a thin rule */
.sun-note { margin: 0; padding: var(--sp-8) var(--sp-12); border-radius: var(--r-md); background: var(--sunken); font-size: var(--fs-sm); line-height: 1.5; color: var(--fg); }
.sun-verdict { margin: 0; font-size: var(--fs-md); font-weight: 600; } /* is it sunny while the wall is open? */
/* sun scene (src/sun-scene.js): three scenes, 양달 / 응달 / 밤; only the sun moves. The sun box is the sky (k-* tokens by the sun's state, "low" = evening sun),
   the picture stands in it with no frame, the words below ride on the ground colour. --sc-text on the sky, --sc-gtext on the ground. The admin preview has no box: .sun-scene paints its own sky */
.sun-scene { display: block; width: 100%; height: auto; background: linear-gradient(180deg, var(--sc-sky0), var(--sc-sky1)); }
.k-lit { --sc-sky0: #fbeccb; --sc-sky1: #f4cf94; --sc-sun: #e8731a; --sc-halo: #f6a542; --sc-ground: #a0561a; --sc-wall: #3b2f27; --sc-face: #f4b04a; --sc-body: #1c140f; --sc-helmet: #e8731a; --sc-ink: #5a3508; --sc-acc: #8a4d08; --sc-hill: #8d5a2c; --sc-text: #4a2c08; --sc-gtext: #fff; }
.k-lit.low { --sc-sky0: #ffd9b8; --sc-sky1: #f08a6a; --sc-sun: #e8531a; --sc-halo: #ff9a5a; --sc-ground: #8a3f1c; --sc-wall: #3b2218; --sc-face: #ffb070; --sc-body: #1c0f0a; --sc-helmet: #e8531a; --sc-ink: #6a2810; --sc-text: #5a2410; }
.k-shade { --sc-sky0: #c9d6e8; --sc-sky1: #8ea5c5; --sc-sun: #e9892a; --sc-halo: #f2b66a; --sc-ground: #3d5373; --sc-wall: #1b2432; --sc-face: #6f87a9; --sc-body: #0f151f; --sc-helmet: #e9892a; --sc-ink: #1f3550; --sc-acc: #1f3550; --sc-hill: #2b3f5c; --sc-text: #10202f; --sc-gtext: #fff; }
.k-night { --sc-sky0: #0c1226; --sc-sky1: #26305a; --sc-sun: #f1e4ae; --sc-halo: #9aa6d6; --sc-ground: #0d1326; --sc-wall: #05080f; --sc-face: #2c3760; --sc-body: #dfe5f5; --sc-helmet: #f1e4ae; --sc-ink: #9aa6d6; --sc-acc: #e0a850; --sc-hill: #05080f; --sc-text: #e6ebf5; --sc-gtext: #e6ebf5; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .k-lit { --sc-sky0: #4a3a26; --sc-sky1: #6b4a24; --sc-ground: #7a4a1e; --sc-wall: #1a1410; --sc-body: #efe3cf; --sc-ink: #f2c98a; --sc-acc: #f2b25c; --sc-text: #f5ecdc; --sc-gtext: #fbf3e6; }
  :root:not([data-theme="light"]) .k-lit.low { --sc-sky0: #5a3326; --sc-sky1: #7a3b26; --sc-ground: #6a3118; --sc-ink: #ffd2b8; --sc-text: #ffe6d6; }
  :root:not([data-theme="light"]) .k-shade { --sc-sky0: #1a2434; --sc-sky1: #2a3d5c; --sc-ground: #223149; --sc-wall: #0b1019; --sc-body: #e6ebf5; --sc-ink: #a9bfdc; --sc-acc: #a9bfdc; --sc-text: #dbe6f5; --sc-gtext: #e6ebf5; }
}
:root[data-theme="dark"] .k-lit { --sc-sky0: #4a3a26; --sc-sky1: #6b4a24; --sc-ground: #7a4a1e; --sc-wall: #1a1410; --sc-body: #efe3cf; --sc-ink: #f2c98a; --sc-acc: #f2b25c; --sc-text: #f5ecdc; --sc-gtext: #fbf3e6; }
:root[data-theme="dark"] .k-lit.low { --sc-sky0: #5a3326; --sc-sky1: #7a3b26; --sc-ground: #6a3118; --sc-ink: #ffd2b8; --sc-text: #ffe6d6; }
:root[data-theme="dark"] .k-shade { --sc-sky0: #1a2434; --sc-sky1: #2a3d5c; --sc-ground: #223149; --sc-wall: #0b1019; --sc-body: #e6ebf5; --sc-ink: #a9bfdc; --sc-acc: #a9bfdc; --sc-text: #dbe6f5; --sc-gtext: #e6ebf5; }
/* 날씨 층(sun-scene.js wxLayout): 흐림·비·눈이면 하늘이 가라앉고 구름이 해를 덮고, 비·눈은 구름 밑에서 땅까지 내린다. 새 토큰 --wx-*(2026-11-03 사용자 승인, 라이트·다크 각각) */
.sunbox.sc { --wx-cloud-top: #ffffff; --wx-cloud-bot: #cfd8e4; --wx-rcloud-top: #a7b2c4; --wx-rcloud-bot: #6f7b8f; --wx-rain: #eaf1fb; --wx-snow: #ffffff; --wx-tint-cloud: rgb(150 160 175 / .24); --wx-tint-rain: rgb(95 110 135 / .4); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sunbox.sc { --wx-cloud-top: #98a3b5; --wx-cloud-bot: #6c778a; --wx-rcloud-top: #6b7689; --wx-rcloud-bot: #3c4556; --wx-rain: #b8cae6; --wx-snow: #dfe8f6; --wx-tint-cloud: rgb(52 58 70 / .24); --wx-tint-rain: rgb(28 34 46 / .42); }
  :root:not([data-theme="light"]) .sunbox.sc:is(.scx-rain, .scx-snow) { --sc-text: #f2f5fa; } /* 어두워진 하늘 위 글씨는 밝게 */
}
:root[data-theme="dark"] .sunbox.sc { --wx-cloud-top: #98a3b5; --wx-cloud-bot: #6c778a; --wx-rcloud-top: #6b7689; --wx-rcloud-bot: #3c4556; --wx-rain: #b8cae6; --wx-snow: #dfe8f6; --wx-tint-cloud: rgb(52 58 70 / .24); --wx-tint-rain: rgb(28 34 46 / .42); }
:root[data-theme="dark"] .sunbox.sc:is(.scx-rain, .scx-snow) { --sc-text: #f2f5fa; }
.sunbox.sc.scx-cloud .sb-sky { background: linear-gradient(var(--wx-tint-cloud), var(--wx-tint-cloud)), linear-gradient(180deg, var(--sc-sky0), var(--sc-sky1)); }
.sunbox.sc:is(.scx-rain, .scx-snow) .sb-sky { background: linear-gradient(var(--wx-tint-rain), var(--wx-tint-rain)), linear-gradient(180deg, var(--sc-sky0), var(--sc-sky1)); }
.sc-c0 { stop-color: var(--wx-cloud-top); } .sc-c1 { stop-color: var(--wx-cloud-bot); }
:is(.scx-rain, .scx-snow) .sc-c0 { stop-color: var(--wx-rcloud-top); } :is(.scx-rain, .scx-snow) .sc-c1 { stop-color: var(--wx-rcloud-bot); }
.sc-r0 { stop-color: var(--wx-rain); }
.sc-drop { stroke-width: 1.9; stroke-linecap: round; }
.sc-flake { stroke: var(--wx-snow); stroke-width: 3.2; filter: drop-shadow(0 0 1px rgb(40 52 74 / .55)); } /* 옅은 윤곽: 라이트의 회색·베이지 하늘에서도 점이 보인다 */
.scx-cloud :is(.sc-sun, .sc-hal) { opacity: .5; } .scx-cloud .sc-ray { opacity: .3; } /* 흐림: 해가 구름 뒤로 비친다 */
:is(.scx-rain, .scx-snow) :is(.sc-sun, .sc-hal) { opacity: 0; } :is(.scx-rain, .scx-snow) .sc-ray { opacity: 0; } /* 비·눈: 구름이 해를 덮는다 */
@keyframes sc-drift { from { transform: translateX(-6px); } to { transform: translateX(8px); } }
@keyframes sc-snow { from { transform: translate(0, -14px); opacity: 0; } 15% { opacity: 1; } to { transform: translate(-2px, 30px); opacity: 0; } } /* 눈은 거의 곧게 내린다 */
@keyframes sc-fall { from { transform: translate(0, -14px); opacity: 0; } 15% { opacity: 1; } to { transform: translate(-6px, 30px); opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  .sc-drift { animation: sc-drift 9s ease-in-out infinite alternate; }
  .sc-drop { animation: sc-fall 1.1s linear infinite; }
  .sc-flake { animation-name: sc-snow; animation-duration: 1.8s; }
}
/* the box: sky on top (chip, hours, picture bled to the edges), ground colour below (the sentence and notes) */
.sunbox.sc { display: block; padding: 0; overflow: hidden; background: none; }
.row .sunbox.sc { margin-top: var(--sp-24); } /* the info rows end, then the sun card begins */
.sunbox.sc .sb-sky { padding: var(--sp-16) var(--sp-16) 0; background: linear-gradient(180deg, var(--sc-sky0), var(--sc-sky1)); color: var(--sc-text); }
.sunbox.sc .sb-sky :is(.dwhen, .dw-k, .dw-r) { color: var(--sc-text); }
/* the chip and the sun's window sit in a row of their own above the picture (rows 2 and 3): the numerals never cover the sun */
.sunbox.sc .sb-sky { display: grid; }
.sunbox.sc .sb-sky > .wx-box { grid-row: 1; }
.sunbox.sc .sb-sky > :is(.sb-head, .sb-fig) { grid-column: 1; min-width: 0; }
.sunbox.sc .sb-sky > .sb-head { grid-row: 2; margin-top: var(--sp-12); }
.sunbox.sc .sb-sky > .sb-fig { grid-row: 3; align-self: end; }
.sunbox.sc .sb-head { flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-12); } /* the state chip, the sun's window beside it (under it on a narrow phone): above the picture, never on it */
.sunbox.sc .sb-head .dwhen { flex: 0 1 auto; display: grid; justify-items: start; gap: 0; text-align: left; }
.sunbox.sc .sb-fig { width: calc(100% + 2 * var(--sp-16)); max-width: none; margin: var(--sp-8) calc(-1 * var(--sp-16)) 0; }
.sunbox.sc .sun-scene { background: none; }
/* the words above the picture (the weather row, the state chip, the sun's window): no box, the sky itself is slightly veiled behind them and the veil fades out into the picture, so the text reads and nothing has an edge. Light skies get a white veil, deep skies a dark one */
.sunbox.sc { --sc-panel: rgb(255 255 255 / .55); }
.sunbox.sc.k-night { --sc-panel: rgb(0 0 0 / .32); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .sunbox.sc { --sc-panel: rgb(0 0 0 / .32); } }
:root[data-theme="dark"] .sunbox.sc { --sc-panel: rgb(0 0 0 / .32); }
.sunbox.sc .sb-sky { position: relative; isolation: isolate; }
.sunbox.sc .sb-sky::before { content: ""; position: absolute; inset: 0 0 auto 0; height: calc(100% - 150px); min-height: 150px; z-index: -1; pointer-events: none; background: linear-gradient(to bottom, var(--sc-panel) 0, var(--sc-panel) 62%, transparent 100%); }
.sunbox.sc .wx-box :is(.wxb-d, .wxb-obs, .wxb-hrs li) { opacity: 1; }
.sunbox.sc .sb-ground { font-family: var(--font-serif); display: grid; gap: var(--sp-8); padding: var(--sp-8) var(--sp-16) var(--sp-12); background: var(--sc-ground); color: var(--sc-gtext); }
.sunbox.sc .sb-ground :is(.dsent, .sun-veil, .sun-note, .sun-limit, summary) { color: inherit; }
.sunbox.sc .sb-ground .sun-note { border-left-color: currentColor; }
/* 계산 기준: a small ! beside the conclusion line instead of a row of its own (the words stay for screen readers; the body opens under the line) */
.sunbox.sc .sb-ground { position: relative; }
.sunbox.sc .sb-ground .dsent { padding-right: var(--sp-24); font-size: var(--fs-sm); line-height: 1.55; }
.sunbox.sc .sun-why > summary { position: absolute; top: -4px; right: var(--sp-2); width: var(--tap); min-height: var(--tap); height: var(--tap); justify-content: center; gap: 0; font-size: 0; }
.sunbox.sc .sun-why > summary::after, .sunbox.sc .sun-why[open] > summary::after { content: "!"; display: grid; place-items: center; width: 13px; height: 13px; border: 1.25px solid currentColor; border-radius: 50%; font: 700 .6875rem/1 var(--font); opacity: .85; }
.sunbox.sc .sun-why[open] > summary::after { background: color-mix(in srgb, currentColor 22%, transparent); }
/* 계산 기준 is a bubble over the picture, not a row: the card keeps its height and the rows below do not move */
.sunbox.sc .sun-why .sun-limit { position: absolute; right: var(--sp-8); bottom: calc(100% + var(--sp-8)); z-index: 3; width: min(17rem, calc(100% - var(--sp-16))); padding: var(--sp-8) var(--sp-12); border-radius: var(--r-base); background: var(--surface); color: var(--fg); box-shadow: var(--shadow-float); font-size: var(--fs-xs); line-height: 1.55; }
.sunbox.sc .sun-why .sun-limit::after { content: ""; position: absolute; right: var(--sp-16); bottom: -5px; width: 10px; height: 10px; background: var(--surface); transform: rotate(45deg); } /* the bubble's tip points down at the ! */
.sc-h0 { stop-color: var(--sc-halo); stop-opacity: .55; } .sc-h1 { stop-color: var(--sc-halo); stop-opacity: 0; }
.sc-sun, .sc-moon { fill: var(--sc-sun); }
.sc-ground { fill: var(--sc-ground); } .sc-band.a { fill: #000; opacity: .18; } .sc-band.b { fill: #fff; opacity: .14; }
.sc-wall { fill: var(--sc-wall); } .sc-face { fill: var(--sc-face); } .sc-hill { fill: var(--sc-hill); }
.sc-shadow { fill: #08101c; opacity: .38; } .sc-ray { fill: #fff1c2; } .sc-star { fill: #eef1fb; opacity: .85; }
.sc-tick { fill: var(--sc-acc); } .sc-now { fill: var(--sc-sun); stroke: #fff; stroke-width: 1.2; }
.sc-body { stroke: var(--sc-body); } .sc-fill-body { fill: var(--sc-body); } .sc-helmet { fill: var(--sc-helmet); } .sc-lamp { fill: #fff3c4; }
.sc-lab { font-family: var(--font); font-size: 13px; font-weight: 600; fill: var(--sc-ink); text-anchor: middle; }
.sc-lab.acc { fill: var(--sc-acc); } .sc-lab.on-ground { fill: #cfe0f5; }
.dsent { margin: 0; font-size: var(--fs-md); line-height: 1.5; }
.dsent b { font-weight: 700; }
.dsent.off, .sunbox.solo:has(.sb-chip.na) .dsent { color: var(--muted); font-size: var(--fs-sm); font-weight: 600; } /* a quiet one-line reason (no direction → no sun math) */
.sun-limit { margin: 0; font-size: var(--fs-xs); line-height: 1.5; color: var(--muted); }
.dwhen { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--sp-8); font-size: var(--fs-lg); font-weight: 700; font-variant-numeric: tabular-nums; }
.dwhen .dw-k { flex: 1 0 100%; font-size: var(--fs-xs); font-weight: 500; color: var(--muted); }
.dwhen .dw-r { white-space: nowrap; }
.dwhen.ref { font-size: var(--fs-md); font-weight: 500; }
/* 계산 기준: one folded line, 44px tap */
.sun-why > summary { display: flex; align-items: center; gap: var(--sp-4); min-height: var(--tap); color: var(--muted); font-size: var(--fs-sm); list-style: none; }
.sun-why > summary::-webkit-details-marker { display: none; }
.sun-why > summary::after { content: "▾"; font-size: .8em; }
.sun-why[open] > summary::after { content: "▴"; }
.sun-why > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-md); }
.acts { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin-top: var(--sp-12); }
/* icon-only actions (공유 beside the name, 길찾기 beside the address): a 44px tap area, the glyph in the text colour */
.icon-btn { display: inline-flex; align-items: center; justify-content: center; flex: none; width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: 50%; background: none; color: var(--muted); text-decoration: none; cursor: pointer; }
.icon-btn svg { width: 22px; height: 22px; transition: transform var(--dur-press) var(--ease-out), fill var(--dur-press) var(--ease-out), stroke var(--dur-press) var(--ease-out); }
.icon-btn:active svg { transform: scale(.9); }
.icon-btn.done { color: var(--accent); }
@media (hover: hover) and (pointer: fine) { .icon-btn:hover { color: var(--accent); } }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.x-head { display: flex; align-items: flex-start; gap: var(--sp-4); margin: var(--sp-12) 0 var(--sp-2); }
.x-head .x-name { flex: 1; min-width: 0; margin: 0; }
.share-wrap { position: relative; flex: none; margin: -10px -10px -10px 0; } /* the pad is tap area only */
.x-head > .fav-btn, .name-row > .fav-btn { margin: -10px -8px -10px -10px; } /* ♥ stands before the name */
.name-row { display: flex; align-items: flex-start; }
.name-row .name { min-width: 0; }
.fav-btn.on svg { fill: var(--fav); stroke: var(--fav-edge); }
.rfav { margin-right: -4px; color: var(--fav); text-shadow: 0 0 1px var(--fav-edge), 0 0 1px var(--fav-edge); font-size: var(--fs-xs); } /* the mark after a favorite's name in the list; [hidden] hides it */
.m-info, .m-head { min-width: 0; }
@media (min-width: 560px) and (max-width: 1023px) { /* wide: name/hours left, sun box right (compass above words), the rest under the name. Stops at 1023px: from 1024px the open card sits in the 460px list column and stacks like on a phone */
  .m-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 var(--sp-24); align-items: start; margin-top: var(--sp-24); }
  .m-cols .x-head { margin-top: 0; } /* top of the name = top of the sun box */
  .m-cols > .m-head { grid-column: 1; grid-row: 1; }
  .m-cols > .m-info { grid-column: 1; grid-row: 2; }
  .m-cols .sunbox { grid-column: 2; grid-row: 1 / span 3; margin-top: 0; padding: var(--sp-16); }
  .m-cols:not(:has(> .m-head :is(.x-sub, .addr-btn), > .m-info > *)) > .sunbox { grid-column: 1 / -1; max-width: 480px; justify-self: center; width: 100%; } /* nothing in the left column: the sun box takes the full width, not the right half beside a blank */
  .m-cols .sunbox:not(.solo) { display: flex; }
  .m-cols .sunbox:not(.solo) > .sb-fig { max-width: 300px; }
  .m-cols .sunbox.sc { padding: 0; display: block; }
  .m-cols .sunbox.sc .sb-fig { max-width: none; }
  .m-cols > .m-foot { grid-column: 1; grid-row: 3; }
  .m-cols > .go-row { grid-column: 1 / -1; grid-row: 4; margin-top: 0; }
}
.expand-in .acts .btn, .expand-in .actions .btn {
  flex: 1 1 auto; white-space: nowrap; justify-content: center; height: 46px; padding: 0 var(--sp-16); border-radius: var(--r-base);
  border: 1px solid var(--fg); background: var(--fg); color: var(--bg); font-size: var(--fs-md); font-weight: 600;
}
.expand-in .acts .btn.sub, .expand-in .actions .btn { background: transparent; color: var(--fg); border-color: var(--line-strong); font-weight: 500; }
/* 내 후기 */
.blog { margin-top: var(--sp-12); }
.blog-row { display: flex; flex-wrap: wrap; gap: var(--sp-8); }
.blog .btn { min-height: var(--tap); padding: 0 var(--sp-16); justify-content: center; font-size: var(--fs-md); font-weight: 500; white-space: nowrap; color: var(--fg); border: 1px solid var(--line-strong); background: transparent; border-radius: var(--r-base); }
.blog-h { font-size: var(--fs-xs); color: var(--muted); }
.blog-h b { display: block; color: var(--fg); font-weight: 600; } /* the title, and under it the one-line note */
.blog-list { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.blog-list[hidden] { display: none; }
.blog-list a { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); min-height: var(--tap); padding: 0 var(--sp-2); color: var(--fg); text-decoration: none; border-top: 1px solid var(--hair); font-size: var(--fs-sm); }
.blog-list .bt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.blog-wrap .blog-list .bt { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow-wrap: anywhere; padding: var(--sp-8) 0; } /* a long title takes two lines, then an ellipsis */
html[data-text="xlarge"] .blog-wrap .blog-list a { flex-wrap: wrap; row-gap: 0; } /* the date drops under the title */
html[data-text="xlarge"] .blog-wrap .blog-list .bt { flex-basis: 100%; -webkit-line-clamp: 3; line-clamp: 3; }
html[data-text="xlarge"] .blog-wrap .blog-list .bd { padding-bottom: var(--sp-8); }
.blog-list .bd { flex: none; font-size: var(--fs-xs); color: var(--muted); }
.pf-go { position: relative; display: flex; align-items: center; gap: var(--sp-4); margin-top: var(--sp-4); color: var(--accent); font-size: var(--fs-xs); font-weight: 400; white-space: nowrap; }
.pf-go::after { content: ""; position: absolute; inset: -12px -4px; } /* taps like 44px */
.pf-go svg { flex: none; width: 14px; height: 14px; }
.blog-list a svg { flex: none; width: 14px; height: 14px; margin-left: calc(var(--sp-4) * -1); color: var(--muted); } /* ↗: the link leaves the app */
.blog-more { display: flex; align-items: center; min-height: var(--tap); width: 100%; padding: 0 var(--sp-2); border: 0; border-top: 1px solid var(--hair); background: none; color: var(--accent); font: inherit; font-size: var(--fs-sm); font-weight: 600; text-align: left; }
/* every "더 보기" fold ends in the same chevron: down when folded, up when open */
.blog-more { justify-content: space-between; gap: var(--sp-8); }
.blog-more::after {
  content: ""; flex: none; width: 9px; height: 9px; margin: -4px var(--sp-8) 0 var(--sp-2); border: solid var(--accent); border-width: 0 2px 2px 0;
  transform: rotate(45deg); transition: transform var(--dur-ui) var(--ease-out);
}
.blog-more[aria-expanded="true"]::after { transform: translateY(5px) rotate(-135deg); }
/* the way into the wall sheet: everything that does not decide the visit lives there (structure only; the look is settled with the mockup) */
.sheet-open {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); flex: 1; min-width: 0; min-height: 56px; padding: var(--sp-8) var(--sp-16);
  border: 0; border-radius: var(--r-base); background: var(--accent); color: var(--on-accent); cursor: pointer;
  font: inherit; text-align: left; white-space: nowrap;
}
.sheet-open .so-t { min-width: 0; display: grid; }
.sheet-open b { font-size: var(--fs-md); font-weight: 700; }
.sheet-open small { font-size: var(--fs-xs); opacity: .85; overflow: hidden; text-overflow: ellipsis; }
.sheet-open i { flex: none; font-style: normal; font-size: 1.375rem; line-height: 1; }
.sheet-open:active { transform: scale(.985); }
.sheet-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- '더 보기' pictures: hours grid, seasonal sun ----
   Hatching only ever means "not usable" (휴게, 휴무, 동절기 휴장). */
.hgrid, .ssun { --lab: 3.6rem; } /* one label column for both, so the two time axes are the same width */
.fees { overflow-x: auto; } /* fallback: a table that still cannot fit scrolls inside its card, never past it */
.fees table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.fees th, .fees td { padding: var(--sp-8) var(--sp-4); border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.fees thead th { color: var(--muted); font-weight: 500; font-size: var(--fs-xs); }
.fees thead th:first-child { width: 25%; }
.fees thead th:nth-child(2) { width: 30%; } /* 대상 + 관외/관내 stay on one line, level with the prices */
.fees tbody th { font-weight: 700; width: 25%; } /* wide enough that "일일이용권" and "(볼더링 +리드)" take two lines, not three */
.fees .f-who { color: var(--muted); white-space: nowrap; }
.fees .f-pg { position: relative; display: flex; flex-wrap: nowrap; justify-content: space-between; gap: var(--sp-4); } /* 대상 left, 거주지 (관외 / 관내) right-aligned */
.fees .f-dup { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } /* screen-reader only */
.fees .f-pg > :last-child { margin-left: auto; } /* 거주지 stays right even when the repeated 대상 (.f-dup, on the 2nd… row) is not drawn */
.fees .f-won, .fees .f-all { text-align: center; white-space: nowrap; }
@media (max-width: 360px) { .fees .f-won { font-size: var(--fs-xs); } .fees th, .fees td { padding-left: 3px; padding-right: 3px; } } /* 320px: a price column is narrow (관외 | 관내 beside 대상): one step down so 52,500원 fits without scrolling */
.fees .f-all { text-align: center; }
.fees thead th:nth-child(n+3) { text-align: center; }
.fees .f-times { white-space: normal; font-size: var(--fs-xs); line-height: 1.5; }
.fees .f-times span { display: block; }
.fees tbody .f-gh { width: auto; font-weight: 500; font-size: var(--fs-xs); color: var(--muted); text-align: center; } /* the group names (관외 | 관내) over their price columns */
.fees .f-note { color: var(--muted); font-size: var(--fs-xs); }
.f-disc { margin: var(--sp-8) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.g-segrow { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-12); margin-bottom: var(--sp-8); }
.g-segrow .g-seg { margin-bottom: 0; flex: 1 1 100%; }
.g-seg { display: flex; gap: var(--sp-8); margin: 0 0 var(--sp-8) calc(var(--sp-12) * -1); border-bottom: 1px solid var(--line); } /* the app's underline tabs, as .hd-tabs (내 정보: 나 | 설정): muted words, the chosen one bold with a 3px accent line */
.g-seg button {
  display: inline-flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); padding: 0 var(--sp-12); border: 0; border-bottom: 3px solid transparent; margin-bottom: -1px; background: none; color: var(--muted);
  font: inherit; font-size: var(--fs-md); font-weight: 600; line-height: 1.25; white-space: nowrap; cursor: pointer;
}
.g-seg button[aria-pressed="true"] { color: var(--fg); font-weight: 700; border-bottom-color: var(--accent); }
.g-seg .sw-m { font-size: var(--fs-xs); font-weight: 500; opacity: .8; }
.g-seg button.shut:not([aria-pressed="true"]) { color: var(--warn); }
.g-seg button.shut:not([aria-pressed="true"]) .sw-m { font-weight: 700; opacity: 1; }
.g-seg button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.g-lead { font-size: var(--fs-sm); margin-bottom: var(--sp-4); }
.g-lead b { color: var(--warn); } /* only drawn for a closed day: the closure reads in the closed colour, not the open one */
.g-lead.preview { color: var(--warn); font-weight: 600; }
.g-axis { position: relative; height: 22px; margin-left: var(--lab); font-size: var(--fs-xs); color: var(--muted); }
.g-axis span { position: absolute; top: 0; line-height: 22px; transform: translateX(-50%); white-space: nowrap; }
.g-axis .first { transform: none; }
.g-axis .last { transform: translateX(-100%); }
.g-axis .nowtag { line-height: 1; top: 2px; padding: 3px 5px; border-radius: var(--r-sm); background: var(--accent); color: var(--on-accent); font-weight: 700; z-index: 4; }
.g-body { position: relative; isolation: isolate; border-bottom: 1px solid var(--hair); }
.g-plot { position: absolute; top: 0; bottom: 0; left: var(--lab); right: 0; pointer-events: none; }
.g-plot .gl { position: absolute; top: 0; bottom: 0; width: 1px; background: color-mix(in srgb, var(--hair) 55%, transparent); z-index: 1; } /* the hour lines stay in the back */
.g-plot .nowl { position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--now); box-shadow: 0 0 0 1px var(--surface); z-index: 3; }
.g-row { display: flex; min-height: 44px; border-top: 1px solid var(--hair); }
.g-lab { width: var(--lab); flex: none; display: flex; flex-direction: column; justify-content: center; font-size: var(--fs-sm); line-height: 1.2; }
.g-lab small { font-size: var(--fs-xs); font-weight: 700; color: var(--open); }
.g-wrap { display: contents; }
.g-trk { position: relative; display: block; flex: 1; min-width: 0; }
.g-row.g-today { background: color-mix(in srgb, var(--open-past) 45%, transparent); } /* today: a 2px edge, a bold label and the same pale tint as the current season row under it */
.g-row.g-today .g-lab { font-weight: 700; padding-left: var(--sp-8); }
/* the week's bars are the list's bar (.bar .seg): 8px, the same radius and tones, the part before the time line paler with a 1px edge */
.g-bar { position: absolute; bottom: 10px; height: 8px; border-radius: var(--r-sm); background: var(--open); z-index: 2; }
.g-bar.past { background: var(--open-past); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--open) 70%, transparent); }
.g-bar.j-end { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.g-bar.j-start { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.g-brk, .g-off, .k-hatch {
  background-image: repeating-linear-gradient(135deg, var(--hatch) 0 2px, transparent 2px 6px);
}
.g-brk { position: absolute; bottom: 8px; height: 12px; border: 1px solid var(--line-strong); border-radius: var(--r-xs); z-index: 2; }
.g-off { position: absolute; left: 0; right: 0; bottom: 6px; height: 16px; border: 1px solid var(--line); border-radius: var(--r-sm); }
.g-row:not(.g-today) .g-txt { color: var(--muted); } /* only today's hours are in full colour; the other days' hours are quiet */
.g-closed { position: absolute; left: 6px; bottom: 6px; line-height: 16px; padding: 0 var(--sp-4); border-radius: 3px; background: var(--surface); font-size: var(--fs-xs); font-weight: 600; z-index: 4; white-space: nowrap; }
.g-closed.none { left: 0; font-weight: 400; color: var(--muted); background: none; }
.g-txt { position: absolute; bottom: 20px; padding: 0 3px; border-radius: var(--r-xs); background: var(--surface); font-size: var(--fs-xs); line-height: 1.25; white-space: nowrap; font-variant-numeric: tabular-nums; z-index: 4; } /* one line over its bar */
.g-note { position: absolute; left: 0; max-width: 100%; bottom: 20px; padding: 0 3px; border-radius: var(--r-xs); background: var(--surface); color: var(--muted); font-size: var(--fs-xs); line-height: 1.25; font-variant-numeric: tabular-nums; z-index: 4; } /* a quiet word or a short line over the bar, above the time line; it may wrap on large text */
.s-row.cur .g-txt, .s-row.cur .g-note, .g-row.g-today .g-txt, .g-row.g-today .g-note { background: color-mix(in srgb, var(--open-past) 45%, var(--surface)); }
.g-row.shut .g-bar, .g-row.shut .g-txt, .g-row.shut .g-sunon { opacity: .35; }
/* 운영 중 양달: the open bar itself is orange there (the same as the list row: same place and height as .g-bar, square ends) */
.g-sunon { position: absolute; bottom: 10px; height: 8px; border-radius: 0; background: var(--sun-bar); z-index: 3; }
.g-sunon.past { opacity: .45; }
.g-key { list-style: none; margin: var(--sp-8) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-12); font-size: var(--fs-xs); color: var(--muted); }
.g-key li { display: inline-flex; align-items: center; gap: var(--sp-8); }
.g-key i { flex: none; display: inline-block; width: 20px; height: 10px; border-radius: var(--r-xs); }
.k-bar { background: var(--open-bar); }
.k-hatch { border: 1px solid var(--line-strong); }
.k-sunon { background: var(--sun-bar); }
.g-key i.k-now { width: 2px; height: 14px; background: var(--now); }
.k-open { border: 1px solid var(--open); background: color-mix(in srgb, var(--open-past) 50%, transparent); }
.g-notes { list-style: none; margin: var(--sp-8) 0 0; padding: 0; font-size: var(--fs-xs); color: var(--muted); }
/* seasonal sun: the season on the left (like a weekday in the hours grid), "6/21 · 예상 12:40–19:40" over the track on the right */
.s-row { display: flex; align-items: center; padding: 0; border-top: 1px solid var(--hair); }
.s-main { flex: 1; min-width: 0; }
.ws-legend { margin: var(--sp-8) 0 var(--sp-12); }
.g-lab small { white-space: nowrap; }
.s-ref { margin: var(--sp-8) 0 0; color: var(--muted); font-size: var(--fs-xs); }
.s-row .g-trk { height: 44px; }
.s-row.cur { background: color-mix(in srgb, var(--open-past) 45%, transparent); }
.s-row[hidden] { display: none; }
/* the hours time line is dragged along the axis and the bars; pan-y leaves the page's up-and-down scroll and keeps the sheet's sideways tab swipe out */
.g-zone { position: relative; display: flex; align-items: center; min-height: var(--tap); touch-action: pan-y; cursor: ew-resize; user-select: none; -webkit-user-select: none; }
.g-zone .g-axis { flex: 1; }
.g-zone:has(.g-range:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.g-verdict { margin: 0 0 var(--sp-8); font-size: var(--fs-base); font-weight: 700; }
.g-verdict.open { color: var(--open); }
.g-verdict.closed { color: var(--warn); }
/* the ! of the sun card (13px ring + bubble) inside a line of text: the 44px tap box hangs out around the ring, the bubble opens under the line across the card */
.sun-why.inl { display: inline; }
.sun-why.inl > summary { display: inline-grid; place-items: center; vertical-align: middle; width: var(--tap); min-height: var(--tap); height: var(--tap); margin: -16px -16px -16px -10px; padding: 0; font-size: 0; color: var(--muted); cursor: pointer; } /* the 44px box hangs out around the 13px ring without making the line taller */
.sun-why.inl > summary::after, .sun-why.inl[open] > summary::after { content: "!"; display: grid; place-items: center; width: 13px; height: 13px; border: 1.25px solid currentColor; border-radius: 50%; font: 700 .6875rem/1 var(--font); }
.sun-why.inl[open] > summary::after { background: color-mix(in srgb, currentColor 22%, transparent); }
.sun-why.inl .sun-limit { position: absolute; left: var(--sp-12); right: var(--sp-12); z-index: 5; margin-top: var(--sp-8); padding: var(--sp-8) var(--sp-12); border-radius: var(--r-base); background: var(--surface); color: var(--fg); box-shadow: var(--shadow-float); font-size: var(--fs-xs); font-weight: 400; line-height: 1.55; text-align: left; }
.ws-chk .sun-why.inl .sun-limit { bottom: calc(var(--sp-16) + var(--sp-24)); margin: 0; } /* the foot's bubble opens upward: below it is the tab bar */
.ssun-h { display: flex; align-items: center; margin: var(--sp-16) 0 var(--sp-4); padding-top: var(--sp-16); border-top: 1px solid var(--hair); font-size: var(--fs-base); font-weight: 700; }
.ws-hours .ssun { margin-top: 0; }
/* first view: 안내 lines, parking (label column shared with the memo list) */
.memo-list.info { margin-top: var(--sp-8); border-top: 1px solid var(--hair); }
.memo-list.info li { padding: 3px 0; } /* tight: the open panel stays near one screen */
.irow { display: grid; grid-template-columns: 4.5em minmax(0, 1fr) auto; gap: var(--sp-8); align-items: center; padding: 3px 0; border-top: 1px solid var(--hair); font-size: var(--fs-sm); line-height: 1.45; }
.irow .mk { color: var(--muted); align-self: center; } /* the row is a 44px tap target: the label sits on the value's middle, not at the top */
.irow-s { grid-template-columns: 3em minmax(0, 1fr) auto; }
.irow-s .mk { text-align-last: justify; text-justify: inter-character; } /* 운영·이용·게시판: 두 글자도 세 글자 칸 양끝에 맞춘다 */
.memo-list li:has(> .pv-go) { align-items: center; }
.pv { grid-column: 2 / -1; min-width: 0; margin: 0; overflow-wrap: break-word; }
.pk-word { font-weight: 600; }
.pnear { display: block; margin: var(--sp-4) 0 0; } /* a labelled row: the label is the quiet one (as in the memo list), the words are the text */
.pn-k { margin-right: var(--sp-8); color: var(--muted); font-weight: 600; }
.pk-word.good { color: var(--open); }
.pk-word.warn { color: var(--warn); }
.pk-word.muted { color: var(--muted); font-weight: 400; }
.pv-go { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); min-height: var(--tap); width: 100%; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.pv-t { min-width: 0; }
.pv-t:has(.tr) { color: var(--muted); } /* 운영: today's hours lead, the rest (휴무 요일) is quiet */
.pv-t .tr { color: var(--fg); font-weight: 600; }
.pv-t:not(:has(.tr, .pv-none)) { font-weight: 600; } /* 이용·게시판: one value, so it carries the weight */
.pv-t.is-new { color: var(--accent); }
.pv-arrow { flex: none; color: var(--muted); font-size: var(--fs-md); } /* full opacity: 3:1+ on both themes (a faded › was 2.4:1) */
.pv-go:active { background: color-mix(in srgb, var(--fg) 6%, transparent); border-radius: var(--r-sm); }
.pv-go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm); }
.pv-none { color: var(--muted); font-weight: 600; }
.pv-go:has(.pv-none) .pv-arrow { font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; } /* 아직 몰라요 · 알려 주기 › */
/* 휴무안내: a quiet line (a weather condition) or a red one (an admin-entered closing); the report button sits at the right, under the words when the line is narrow */
.irow.notice { padding: var(--sp-8) 0; }
.irow.notice .nt-t { min-width: 0; grid-column: 2; color: var(--muted); }
.irow.notice.sure :is(.mk, .nt-t) { color: var(--warn); font-weight: 600; }
.irow.notice.rain .nt-t { color: #2f62b0; font-weight: 600; } /* rain is coming: the weather box's rain blue */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .irow.notice.rain .nt-t { color: #8db4ee; } }
:root[data-theme="dark"] .irow.notice.rain .nt-t { color: #8db4ee; }
.tr { white-space: nowrap; }
.nt-go { grid-column: 3; display: inline-flex; align-items: center; gap: var(--sp-4); position: relative; isolation: isolate; min-height: var(--tap); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-pill); background: none; color: var(--fg); font: inherit; font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; cursor: pointer; }
.nt-go::before { content: ""; position: absolute; inset: calc((100% - 30px) / 2) 0; z-index: -1; border-radius: var(--r-pill); box-shadow: inset 0 0 0 1px var(--line-strong); } /* visible face = chip height; the 44px hit area stays */
.nt-go svg { width: 16px; height: 16px; flex: none; }
.nt-go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nt-go:active { transform: scale(.97); }
@media (max-width: 340px) { .irow.notice:has(.nt-go) .nt-go { grid-column: 2; grid-row: 2; justify-self: start; } }
html[data-text="large"] .irow.notice:has(.nt-go) .nt-go, html[data-text="xlarge"] .irow.notice:has(.nt-go) .nt-go { grid-column: 2; grid-row: 2; justify-self: start; }
/* big type: the name sits over the words, so the words get the whole width */
html:is([data-text="large"], [data-text="xlarge"]) .irow.notice { grid-template-columns: minmax(0, 1fr) auto; }
html:is([data-text="large"], [data-text="xlarge"]) .irow.notice .mk { grid-column: 1 / -1; grid-row: 1; text-align-last: start; }
html:is([data-text="large"], [data-text="xlarge"]) .irow.notice .nt-t { grid-column: 1 / -1; grid-row: 2; }
html:is([data-text="large"], [data-text="xlarge"]) .irow.notice:has(.nt-go) .nt-go { grid-column: 1 / -1; grid-row: 3; justify-self: start; }
/* 주차 요금표: 행 = 주차장, 열 = 1시간·하루·비고. The name column stays while the rest scrolls sideways. */
.pfee-wrap { margin-top: var(--sp-8); overflow-x: auto; }
.pfee { border-collapse: separate; border-spacing: 0; font-size: var(--fs-sm); white-space: nowrap; }
.pfee caption { padding-bottom: var(--sp-4); color: var(--muted); font-weight: 600; text-align: left; caption-side: top; }
.pfee th, .pfee td { padding: var(--sp-8); border-top: 1px solid var(--hair); font-weight: 400; text-align: center; font-variant-numeric: tabular-nums; }
.pfee thead th, .pfee thead th.pf-note { color: var(--muted); font-size: var(--fs-xs); text-align: center; }
.pfee thead th.pf-note { text-align: left; } /* the head sits over its left-aligned notes */
.pfee tbody th { position: sticky; left: 0; z-index: 1; background: var(--surface); text-align: left; font-weight: 600; white-space: normal; min-width: 5.5em; max-width: 8.5em; }
.pfee .pf-note { text-align: left; white-space: normal; min-width: 6em; color: var(--muted); font-size: var(--fs-xs); }
.pfee .pf-flat { font-weight: 600; }
.pfee .pf-cond { color: var(--muted); font-weight: 400; font-size: var(--fs-xs); }
@media (max-width: 360px) { .pfee th, .pfee td { padding-left: 3px; padding-right: 3px; } .pfee tbody th { min-width: 4.5em; max-width: 5.5em; } .pfee .pf-note { min-width: 3.5em; } } /* 320px: the lot name wraps tighter so a table with four columns (은평·고양) fits the sheet instead of scrolling */
.pfee tr.pf-has-more > * { padding-bottom: var(--sp-2, 2px); }
.pfee tr.pf-more td { border-top: 0; padding-top: 0; text-align: left; white-space: normal; color: var(--muted); font-size: var(--fs-xs); } /* a long 비고 under its lot's row, across every column */
/* 근처 장비점 sheet (src/gear-view.js): the line from the wall to the shop is the one picture; the rest is quiet. The paid zone, when there is one, is set apart and always carries 광고·제휴. */
.gear-body { display: grid; grid-template-columns: minmax(0, 1fr); padding-bottom: var(--sp-8); }
/* the 근처 sheets (src/gear-view.js nearSheetBody): one place per slide, swiped sideways like the card's photos (.rhero-track); the dots sit at the sheet's
   bottom (sticky), the current one accent, the look of .tour-dots but their own class: they stay at 아주 크게 (.tour-dots hide there) */
.gsw-track { display: flex; align-items: start; min-width: 0; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.gsw-track::-webkit-scrollbar { display: none; }
.gsw-track:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-md); }
.gsw-slide { flex: none; width: 100%; scroll-snap-align: center; scroll-snap-stop: always; }
.gsw-dots { position: sticky; bottom: 0; display: flex; justify-content: center; gap: 5px; padding: var(--sp-12) 0 var(--sp-4); background: var(--surface); }
.gsw-dots i { width: 6px; height: 6px; border-radius: 99px; background: var(--line-strong); transition: background .3s; }
.gsw-dots i.on { background: var(--accent); }
@media (prefers-reduced-motion: reduce) { .gsw-dots i { transition: none; } }
.gear-item { display: grid; gap: var(--sp-8); --gear-edge: color-mix(in srgb, var(--fg) 50%, var(--paper)); }
.gsk-wrap { display: grid; gap: var(--sp-8); padding-top: var(--sp-8); }
.gsk { color: var(--fg); position: relative; width: 100%; aspect-ratio: 343 / 168; overflow: hidden; border-radius: var(--r-md); background-color: var(--panel); box-shadow: inset 0 0 0 1px var(--line); }
.gsk-decor { position: absolute; inset: 0; width: 100%; height: 100%; } /* a faint river and streets: decoration, not the real ones (the caption says 약도) */
.gsk-water { fill: color-mix(in srgb, #6f9fbd 22%, var(--panel)); }
.gsk-road { fill: none; stroke: var(--surface); stroke-linecap: round; } .gsk-road.a { stroke-width: 9; } .gsk-road.b { stroke-width: 6; }
.gsk-line { position: absolute; inset: 0; width: 100%; height: 100%; }
.gsk-line line { stroke: var(--gear-edge); stroke-width: 2.5; stroke-dasharray: 6 6; stroke-linecap: round; }
.gsk-pt { position: absolute; transform: translate(-50%, -50%); display: grid; place-items: center; }
.gsk-pt > svg { width: 36px; height: 36px; display: block; }
.gsk-pt.shop > svg { width: 28px; height: 28px; color: var(--sun-ui); fill: color-mix(in srgb, var(--sun-ui) 22%, transparent); stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.gsk-pt .gsk-tag { position: absolute; top: calc(100% + var(--sp-2)); left: 50%; transform: translateX(-50%); padding: 0 var(--sp-8); border-radius: var(--r-pill); background: var(--surface); box-shadow: var(--shadow-pop); font-size: var(--fs-xs); font-weight: 600; line-height: 1.6; white-space: nowrap; max-width: 150px; overflow: hidden; text-overflow: ellipsis; }
.gsk-pt.above .gsk-tag { top: auto; bottom: calc(100% + var(--sp-2)); }
.gsk-sun { fill: var(--sun-disc); } .gsk-slab { fill: var(--wall); }
.gsk-km { position: absolute; transform: translate(-50%, -50%); padding: 0 var(--sp-8); border-radius: var(--r-sm); background: var(--panel); font-size: var(--fs-md); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.gsk-north { position: absolute; top: var(--sp-8); right: var(--sp-8); width: 18px; height: 22px; }
.gsk-n-arrow { fill: var(--muted); } .gsk-n-txt { fill: var(--muted); font: 700 10px var(--font); font-variant-numeric: tabular-nums; }
.gsk-cap { color: var(--muted); font-size: var(--fs-xs); }
.gear-ic { display: inline-flex; vertical-align: -4px; margin-right: var(--sp-4); color: var(--muted); } /* the kind's carabiner, before a shop's name (the card's line and the sheet) */
.gear-ic svg { width: var(--icon-sm); height: var(--icon-sm); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.gear-name { margin: var(--sp-8) 0 0; font-size: var(--fs-lg); font-weight: 700; line-height: 1.25; letter-spacing: -.02em; }
.gear-note { margin: 0; color: var(--muted); font-size: var(--fs-md); }
.gear-links { display: grid; grid-template-columns: 1fr 1fr; margin-top: var(--sp-8); overflow: hidden; border-radius: var(--r-base); box-shadow: inset 0 0 0 1.5px var(--gear-edge); }
.gear-links.n1 { grid-template-columns: 1fr; }
.gear-link { display: flex; align-items: center; justify-content: center; gap: var(--sp-8); min-height: 52px; color: var(--fg); font-weight: 600; text-decoration: none; }
.gear-link svg { width: var(--icon-sm); height: var(--icon-sm); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.gear-link + .gear-link { border-left: 1.5px solid var(--gear-edge); }
.gear-link .gl-out { color: var(--muted); font-weight: 400; }
.gear-link:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
.gear-link:active { background: var(--sunken); }
button.gear-link { width: 100%; border: 0; background: none; font: inherit; cursor: pointer; } /* 외벽 탭에서 보기 (근처 외벽): a cell of the same frame */
.gear-zone-h { display: flex; gap: var(--sp-8); align-items: center; padding-top: var(--sp-8); color: var(--muted); font-size: var(--fs-sm); }
.gear-mark { border: 1px solid var(--line-strong); border-radius: var(--r-xs); padding: 0 var(--sp-8); white-space: nowrap; }
.ws-sec.flash { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (prefers-reduced-motion: no-preference) { .ws-sec.flash { transition: outline-color .4s; } }
.addr-line { display: flex; align-items: center; gap: var(--sp-2); margin: var(--sp-2) 0 0; }
.addr-line .icon-btn { margin: -10px 0; }
/* the whole line is the button: no copy chip; a dotted underline says it can be tapped */
.addr-btn { display: inline-flex; max-width: 100%; min-height: var(--tap); margin: -10px 0; padding: 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-sm); text-align: left; cursor: pointer; }
.addr-t { min-width: 0; overflow-wrap: break-word; align-self: center; }
.addr-ic { display: inline-flex; flex: none; align-self: center; margin-left: var(--sp-8); } /* the copy icon says the line can be tapped */
.addr-ic svg { width: 18px; height: 18px; }
.addr-line .icon-btn svg { width: 18px; height: 18px; } /* the copy and the route icon are one size */
.addr-nav { margin: var(--sp-8) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.addr-btn.done .addr-t { color: var(--accent); font-weight: 600; }
.addr-btn.done svg { color: var(--accent); }
.addr-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.memo-list { list-style: none; margin: 0; padding: 0; font-size: var(--fs-sm); line-height: 1.45; }
.memo-list li { display: grid; grid-template-columns: 5.5em minmax(0, 1fr); gap: var(--sp-8); margin: 0; padding: 5px 0; border-bottom: 1px solid var(--hair); font-size: inherit; } /* li.key: not the legend .key */
.memo-list li:last-child { border-bottom: 0; }
.memo-list .mk { color: var(--muted); }
.memo-list .mv { min-width: 0; overflow-wrap: break-word; }
.memo-list .mv.free { grid-column: 1 / -1; }
.memo-list .sp-note { display: block; margin-top: 1px; color: var(--muted); font-size: var(--fs-xs); } /* 시설's spec rows: where the number comes from, under it */
.memo-list li.key .mk, .memo-list li.key .mv { color: var(--warn); font-weight: 600; }
.memo-list li.key.quiet .mk, .memo-list li.key.quiet .mv { color: var(--muted); } /* 우천·동절기 안내: a rule to know, not something wrong today (--warn is for what affects now) */
.expand-in .row-actions { margin: var(--sp-8) 0 0; }
.expand-in .row-actions button { font-size: var(--fs-sm); }

.key { list-style: none; margin: var(--sp-12) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-16); color: var(--muted); font-size: var(--fs-xs); }
.key li { display: inline-flex; align-items: center; gap: 5px; }
.key i, .ab-sec p > i[class^="k-"] { display: inline-block; width: 16px; height: 5px; border-radius: var(--r-xs); }
.ab-sec p > i[class^="k-"] { margin-right: var(--sp-8); vertical-align: middle; } /* the swatch that starts a how-to line */
.k-open { background: color-mix(in srgb, var(--fg) 85%, transparent); } /* 도움말 범례: 목록 막대와 같은 먹색 */
.k-sun { background: var(--sun); }
.k-soon { background: var(--soon); }

/* conditions: bottom sheet. No padding on the dialog itself, so a click on it is a click on the backdrop. */
.sheet {
  margin: auto auto 0; width: 100%; max-width: 560px; max-height: 88dvh; padding: 0;
  border-radius: var(--r-16) var(--r-16) 0 0; border-bottom: 0;
}
/* enter and exit are one transition, so the sheet leaves the way it came (closes faster, like .expand); the backdrop fades with it.
   Browsers without allow-discrete / @starting-style keep the old enter-only keyframe and close instantly. */
.sheet { transform: translateY(24px); opacity: 0; transition: transform var(--dur-exit) var(--ease-out), opacity var(--dur-exit) var(--ease-out), display var(--dur-exit) allow-discrete, overlay var(--dur-exit) allow-discrete; }
.sheet[open] { transform: none; opacity: 1; transition-duration: var(--dur-ui); }
.sheet:not([open]) { pointer-events: none; } /* leaving (display is held for --dur-exit): no clicks or second submit */
.sheet::backdrop { opacity: 0; transition: opacity var(--dur-exit) var(--ease-out), display var(--dur-exit) allow-discrete, overlay var(--dur-exit) allow-discrete; }
.sheet[open]::backdrop { opacity: 1; transition-duration: var(--dur-ui); }
@starting-style { .sheet[open] { transform: translateY(24px); opacity: 0; } .sheet[open]::backdrop { opacity: 0; } }
@supports not (transition-behavior: allow-discrete) {
  .sheet, .sheet[open], .sheet::backdrop { transition: none; transform: none; opacity: 1; }
  .sheet[open] { animation: sheet-in var(--dur-ui) var(--ease-out); }
}
@keyframes sheet-in { from { transform: translateY(24px); opacity: 0; } }
.sheet form { display: grid; padding: 8px 16px calc(16px + env(safe-area-inset-bottom)); }
.sheet form::before { content: ""; justify-self: center; width: 36px; height: 4px; border-radius: var(--r-xs); background: var(--line-strong); }
.sheet-grab { margin: calc(var(--sp-8) * -1) calc(var(--sp-16) * -1) 0; height: 32px; padding-top: var(--sp-8); display: grid; justify-items: center; align-content: start; touch-action: none; cursor: grab; } /* src/sheet-gestures.js: the bar is a pull-down handle, and a bigger target than its 4px */
.sheet-grab::before { content: ""; width: 36px; height: 4px; border-radius: var(--r-xs); background: var(--line-strong); }
.sheet form:has(> .sheet-grab)::before { display: none; }
.sh-head { display: flex; align-items: center; justify-content: space-between; min-height: 52px; }
/* the title row stays at the top while the sheet scrolls, with a 완료 ✓ at its right end (app.js adds it): no scrolling to the bottom to be done */
.sheet:not(.board-page) .sh-head { position: sticky; top: 0; z-index: 2; background: var(--surface); box-shadow: var(--shadow-hair); }
.sh-okw { display: flex; align-items: center; gap: var(--sp-8); margin-right: -8px; }
.sh-count { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.sh-ok { flex: none; width: var(--tap); height: var(--tap); display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--fg); cursor: pointer; } /* a plain ink line like the tab bar's icons: the sheet's own buttons (닉네임 저장 …) are the only saves */
.sh-ok svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.sh-ok:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sh-ok:active { background: var(--sunken); }
.sh-ok:disabled { opacity: .35; cursor: default; }
.sh-head h2 { font-size: 1.125rem; }
.sh-done { min-height: 44px; margin-right: -8px; padding: 0 var(--sp-12); border: 0; border-radius: var(--r-md); background: none; color: var(--accent); font-weight: 600; white-space: nowrap; }
/* the sheets that have their own save / send / quiz (기록 추가, 같이 가요, 클라이머 유형 테스트) end with a quiet 닫기; the others close with the title row's ✓ (app.js adds it) and have no button here */
.sh-close { min-height: var(--tap); margin-top: var(--sp-8); padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-base); background: none; color: var(--fg); font: inherit; font-weight: 600; white-space: nowrap; cursor: pointer; }
.sh-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sh-row { margin: 0; padding: var(--sp-16) 0; border: 0; border-top: 1px solid var(--hair); min-width: 0; }
div.sh-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); }
.sh-row legend { float: left; width: 100%; margin-bottom: var(--sp-8); padding: 0; }
.sh-row legend, .sh-label { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.segs { clear: both; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--sp-4); padding: var(--sp-4); border-radius: var(--r-base); background: var(--sunken); }
.segs :is(label, button) {
  position: relative; display: grid; place-items: center; min-height: 44px; padding: 0 var(--sp-4); border-radius: var(--r-md);
  font-size: var(--fs-md); font-weight: 600; color: var(--muted); white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out);
}
.segs button { border: 0; background: none; font-family: inherit; }
.segs input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.segs button[aria-pressed="true"], .segs label:has(:checked) { background: var(--surface); color: var(--accent); box-shadow: var(--shadow-seg); }
.segs button:focus-visible, .segs label:has(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
html[data-text] .segs { display: flex; flex-wrap: wrap; } /* 큰 글씨: 칸이 많으면 줄을 바꿔 쌓는다 */
html[data-text] .segs :is(label, button) { flex: 1 1 auto; padding: 0 var(--sp-8); }
.sh-toggle {
  min-height: 44px; padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-base); background: var(--surface);
  font-weight: 600; white-space: nowrap;
  transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-press) var(--ease-out),
    color var(--dur-press) var(--ease-out), border-color var(--dur-press) var(--ease-out);
}
.sh-toggle[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.sh-toggle:active { transform: scale(.97); }

@media (hover: hover) and (pointer: fine) {
  :is(.row-btn, .crag-head):hover { background: color-mix(in srgb, var(--fg) 4%, transparent); }
  button.pill:hover, .sh-toggle:hover { border-color: var(--fg); }
  .segs label:hover { color: var(--fg); }
}

.empty { padding: var(--sp-16); border: 1px dashed var(--line-strong); border-radius: var(--r-base); color: var(--muted); font-size: var(--fs-sm); }
.clear-filters, .soonest-go {
  display: block; min-height: var(--tap); margin-top: var(--sp-12); padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  background: var(--surface); font-weight: 600; white-space: nowrap;
  transition: transform var(--dur-press) var(--ease-out), border-color var(--dur-press) var(--ease-out);
}
.clear-filters:active, .soonest-go:active { transform: scale(.97); }
.soonest-go { white-space: normal; text-align: left; color: var(--accent); } /* nothing is open: the earliest wall, one tap to its opening time */
.cards { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--gap); }

/* ---- card ---- */
.card {
  display: grid; grid-template-columns: 72px minmax(0, 1fr); column-gap: var(--sp-12); row-gap: var(--sp-12);
  background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--closed);
  border-radius: var(--r-base); padding: var(--sp-12) var(--sp-16) var(--sp-12) var(--sp-12);
}
.card > :not(.thumb):not(.head) { grid-column: 1 / -1; }
.card.open { border-left-color: var(--open); }
.card.open.short, .card.open.warned { border-left-color: var(--warn); }
.card.unknown { border-left-color: var(--line-strong); color: var(--muted); }

.thumb { width: 72px; height: 72px; border-radius: var(--r-md); object-fit: cover; background: var(--sunken); display: block; }
.placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); color: var(--muted); text-align: center; }
.ph-primary { font-size: 1.15rem; font-weight: 700; line-height: 1.1; }
.ph-secondary { font-size: var(--fs-xs); line-height: 1.2; }

.head { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.name { font-size: var(--fs-base); font-weight: 700; line-height: 1.3; letter-spacing: -.01em; min-width: 0; overflow-wrap: break-word; }
.where { display: flex; flex-wrap: wrap; gap: 0 var(--sp-8); color: var(--muted); font-size: var(--fs-xs); }
.where small { font-size: inherit; }
.status { font-weight: 700; font-size: var(--fs-md); margin-top: var(--sp-2); color: var(--muted); }
.card.open .status { color: var(--open); }
.card .status.soon, .card.open.short .status { color: var(--warn); }
.card.unknown .status { font-weight: 500; color: var(--muted); }
.card.unknown .name { font-weight: 600; font-size: var(--fs-base); }
.card.unknown { background: transparent; }
.card.unknown .btn { background: transparent; color: var(--muted); border-color: var(--line-strong); }

/* the card's day bar is the list's bar (.bar, listBar in app.js): 06–24h, green = open, orange where it is sunny, tick = chosen time */
.daybar-wrap { padding-top: var(--sp-2); }
.daybar-wrap .bar { margin-top: 0; }
.card.soon .bar .seg { background: var(--soon); }
.card.closed .bar .seg, .card.unknown .bar .seg { background: var(--off); }
.card.closed .bar .seg { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 70%, transparent); }
.card.closed .sunband { opacity: .25; } /* a closed wall's sun is reference only, as in the list */
.ticks { position: relative; height: 1.1em; margin-top: 3px; font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.ticks span { position: absolute; transform: translateX(-50%); line-height: 1.1; }
.ticks span:first-child { transform: none; }
.ticks span:last-child { transform: translateX(-100%); }
.nosun { font-size: var(--fs-xs); color: var(--muted); text-align: right; margin-top: 1px; }

.chips { display: flex; flex-wrap: wrap; gap: var(--sp-8); }
.chip { font-size: var(--fs-xs); padding: var(--sp-2) var(--sp-8); border-radius: var(--r-8); background: var(--sunken); color: var(--fg); line-height: 1.5; }
.chip.parking { border: 1px solid var(--line-strong); background: transparent; }
.chip.parking.good { color: var(--open); border-color: currentColor; }
.chip.parking.warn { color: var(--warn); border-color: currentColor; }
.chip.parking.neutral { color: var(--fg); }
.chip.parking.muted { color: var(--muted); }
.chip[title] { text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }
.card.unknown .chip { color: var(--muted); }

.note { font-size: var(--fs-sm); color: var(--muted); line-height: 1.45; margin-top: -4px; }

.actions { display: flex; flex-wrap: wrap; gap: var(--sp-8); }
.btn {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 var(--sp-16);
  border: 1px solid var(--line-strong); border-radius: var(--r-pill); text-decoration: none;
  color: var(--fg); font-size: var(--fs-sm); font-weight: 600; background: var(--surface);
}
.btn.primary { border-color: var(--accent); color: var(--accent); }

.memo { font-size: var(--fs-sm); color: var(--fg); min-width: 0; overflow-wrap: break-word; white-space: pre-line; }
.card.unknown .memo { color: var(--muted); }
.photo { display: block; max-width: 100%; height: auto; border-radius: var(--r-md); margin: var(--sp-4) 0 var(--sp-8); }
.card.broken { grid-template-columns: 1fr; }

/* ---- data management, editor (behaviour unchanged) ---- */
#manage { margin-top: var(--sp-32); padding-top: var(--sp-12); border-top: 1px solid var(--line); }
#manage > summary { min-height: var(--tap); display: flex; align-items: center; font-weight: 600; color: var(--muted); }
.manage-buttons, .row-actions { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin: var(--sp-8) 0; }
.manage-buttons button, .row-actions button, .file-btn {
  min-height: var(--tap); padding: 0 var(--sp-16); font-size: var(--fs-sm);
  border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface); color: var(--fg);
}
.file-btn { display: inline-flex; align-items: center; }
dialog {
  max-width: 560px; width: calc(100% - 32px); padding: var(--sp-16);
  border: 1px solid var(--line-strong); border-radius: var(--r-base); background: var(--surface); color: var(--fg);
}
dialog::backdrop { background: var(--scrim); }
#editFields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-8); max-height: 60vh; overflow: auto; }
#editFields label { display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--muted); }
#editFields input {
  min-width: 0; width: 100%; min-height: var(--tap); padding: 0 var(--sp-12);
  border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--bg); color: var(--fg);
}
@media (max-width: 480px) { #editFields { grid-template-columns: 1fr; } }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; scroll-behavior: auto !important; }
  .expand, :is(.row, .crag-row).is-open > .expand { transition: none; } /* folds and opens at once */
  button:active, .btn:active { transform: none !important; } /* press scale off; color transitions stay */
  .sheet, .sheet[open] { transform: none; } /* sheets fade, no slide */
  .icon-btn:active svg { transform: none; } /* press scale off for icons too (svg is not a button) */
  .blog-more::after { transition: none; } /* chevron flips instantly */
}

/* Korean labels never wrap mid-label */
.btn, .manage-buttons button, .row-actions button, .file-btn, #nowBtn, button.pill { white-space: nowrap; }

.card.stale .status { color: var(--muted); }
.card .stale-note { color: var(--muted); }

.credit {
  position: absolute; right: 10px; bottom: 10px; max-width: 55%; padding: 3px var(--sp-8); border-radius: var(--r-pill);
  font-size: var(--fs-xs); line-height: 18px; color: var(--on-photo); background: rgb(0 0 0 / .62);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); text-decoration: none; min-width: 0; overflow-wrap: break-word;
}
.foot { display: grid; gap: var(--sp-8); padding-top: var(--sp-8); padding-bottom: var(--sp-48); color: var(--muted); font-size: var(--fs-xs); line-height: 1.5; }
.foot p { text-wrap: pretty; }
.foot a { color: var(--accent); display: inline-block; padding-block: 13px; margin-block: -13px; } /* 44px tap area, same line layout */
.foot .brand { margin-top: 0; }
.foot-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); margin: 0; }
.foot-link { min-height: var(--tap); padding: 0 var(--sp-4); border: 0; background: none; color: var(--accent); font: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.foot-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ab-sec { display: grid; gap: var(--sp-4); padding: var(--sp-12) 0; border-top: 1px solid var(--line); }
.ab-sec[hidden] { display: none; }
.ab-sec h3 { margin: 0; font-size: var(--fs-base); }
.ab-sec p { margin: 0; font-size: var(--fs-sm); line-height: 1.6; color: var(--muted); text-wrap: pretty; }
.ab-sec a { color: var(--accent); padding-block: 13px; }
.ab-sec ul { margin: 0; padding-left: 1.1em; display: grid; gap: var(--sp-8); font-size: var(--fs-sm); line-height: 1.6; text-wrap: pretty; }
/* 안전수칙 sheet */
.sf-mark { width: var(--chip); height: var(--chip); color: var(--fg); flex: none; }
.sf-mark rect { fill: var(--accent); stroke: none; }
.sf-lead { margin: 0 0 var(--sp-8); font-size: var(--fs-base); line-height: 1.6; font-weight: 600; text-wrap: pretty; }
.sf-pledge-box { display: grid; gap: var(--sp-8); padding: var(--sp-12) 0; border-top: 1px solid var(--line); }
.sf-pledge { min-height: var(--tap); padding: var(--sp-8) var(--sp-16); border: 0; border-radius: var(--r-base); background: var(--fg); color: var(--bg); font: inherit; font-weight: 700; cursor: pointer; }
.sf-pledge:active { transform: scale(.98); }
.sf-pledge:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sf-pledged { display: flex; align-items: center; gap: var(--sp-8); margin: 0; min-height: var(--tap); font-weight: 700; }
.sf-pledged:focus { outline: none; }
.sf-stamp { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 2px solid var(--accent); border-radius: 50%; color: var(--accent); font-size: var(--fs-sm); }
.sf-note { margin: 0; font-size: var(--fs-sm); line-height: 1.6; color: var(--muted); text-wrap: pretty; }
.foot .brand strong { color: var(--fg); font-weight: 700; }
/* 문의 메일 (앱 정보 sheet): text + a copy button (no mailto: link, an in-app browser may not open a mail app) */
.ab-mail .mail-addr { color: var(--fg); font-weight: 600; white-space: nowrap; user-select: all; }
.ab-mail .foot-link { min-height: 36px; }
.load-error { margin: var(--sp-12) 0; padding: var(--sp-16) var(--sp-16); border: 2px solid var(--warn); border-radius: var(--r-base); background: var(--surface); color: var(--fg); font-weight: 600; }
.load-error p { margin: 0 0 var(--sp-12); text-wrap: pretty; }
.load-error button { min-height: 44px; padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface); color: var(--fg); font-weight: 600; white-space: nowrap; }
.load-error button:disabled { opacity: .6; }
.load-failed .tabbar, .load-failed #panel-list, .load-failed #panel-map, .load-failed #panel-log, .load-failed #panel-sched { display: none; }

#breakRow, #favRow { flex-wrap: wrap; }
.sent { display: inline-block; } /* a sentence moves to the next line whole instead of breaking in the middle (hints, notices) */
.nb { white-space: nowrap; }
.sh-hint { flex-basis: 100%; margin: 0; font-size: var(--fs-xs); color: var(--muted); }
.home-open > .sh-hint { margin: var(--sp-8) var(--sp-4) 0; } /* 시안 ⑦-c: 위치 없을 때 목록 아래 한 줄 */
.home-open-h .sort-btn { display: inline-flex; align-items: center; gap: var(--sp-4); } .home-open-h .sort-btn svg { width: var(--icon-sm); height: var(--icon-sm); } /* 정렬 알약 앞 ⇅ */
#arriveRow.go { cursor: pointer; } /* 줄 어디를 눌러도 도착 시각 시트 */
.chip.break { color: var(--muted); }

.checked { margin-top: var(--sp-8); font-size: var(--fs-xs); color: var(--muted); }

.fee { display: inline-flex; align-items: center; gap: 3px; margin-left: var(--sp-8); vertical-align: middle; font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0; color: var(--muted); white-space: nowrap; }
.fee svg { width: 13px; height: 13px; flex: none; }
.fee.free { padding: 0 var(--sp-8); border-radius: var(--r-pill); background: var(--accent); color: var(--on-accent); font-weight: 700; } /* 무료 a filled pill, 유료 plain grey: apart at a glance */
.l1 .fee { margin-left: 0; }
.l1 .fee svg { display: none; } /* a list row says 유료/무료 in grey words only: it is not what decides a visit (it stays on the card) */
.l1 .fee.free { padding: 0; background: none; color: var(--muted); font-weight: 600; }

/* 내 지역 (sheet checkboxes by 권역, ≤5, in 조건 and 내 정보) and 구분 */
#regionClear { margin: 0 0 var(--sp-8); }
.sh-row :is(.segs, #regionOptsC) + .sh-hint { margin: var(--sp-8) 0 0; }
.rg-list { clear: both; display: flex; flex-wrap: wrap; gap: var(--sp-8); } /* the legend floats in a .sh-row: start below it */
.rg-n { margin-left: var(--sp-8); font-size: var(--fs-xs); font-weight: 500; color: var(--muted); }
.rg-list label:has(:checked) .rg-n { color: inherit; opacity: .75; }
.rg-list label {
  position: relative; display: inline-flex; align-items: center; min-height: var(--h-m); padding: 0 var(--sp-12);
  border: 1px solid transparent; border-radius: var(--r-pill); background: var(--sunken); font-size: var(--fs-xs); font-weight: 500; /* 면 칩: 정렬·구분 세그먼트와 같은 --sunken 면, 선택만 색으로 채운다 */
  white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out), border-color var(--dur-press) var(--ease-out);
}
.rg-list input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.rg-list label::after { content: ""; position: absolute; inset: -6px 0; } /* 32px chip, 44px touch target */
/* on = fill + a check mark, not only the colour */
.rg-list label:has(:checked) { background: var(--surface); border-color: var(--fg); color: var(--fg); font-weight: 700; } /* 선택 칩 = 흰 알약 + 1px 먹색 윤곽 + 굵은 글자 (채움 아님) */
.rg-list label:has(:checked)::before { content: "✓"; content: "✓" / ""; margin-right: var(--sp-4); }
.rg-list label:has(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
/* indoor-only: the word 실내 in place of 양달/응달, a solid edge (방향 모름 is dashed) */
.sunnow.indoor { background: transparent; border: 1px solid var(--line-strong); padding: 0 5px; }
.basis { font-size: var(--fs-xs); font-weight: 600; color: var(--fg); white-space: nowrap; } /* darker than the region beside it: which hours these are matters */
@media (hover: hover) and (pointer: fine) { .rg-list label:not(:has(:checked)):hover { background: var(--line); } }

/* report sheet (reuses .sheet / .segs) */
.rp-field { display: flex; flex-direction: column; gap: var(--sp-4); padding: var(--sp-12) 0; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.rp-field input, .rp-field textarea {
  width: 100%; min-height: var(--tap); padding: var(--sp-12); font: inherit; font-weight: 400;
  border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--bg); color: var(--fg);
}
.rp-field textarea { resize: vertical; white-space: pre-wrap; }
/* 7 kinds do not fit one row: swipe sideways inside the strip (a grid column would stretch the sheet and push 닫기 off screen) */
#report .segs { display: flex; flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none; }
#report .segs::-webkit-scrollbar { display: none; }
#report .segs label { flex: 1 0 auto; padding: 0 var(--sp-12); scroll-snap-align: start; }
.rp-extra[hidden], .rp-nick[hidden], .rp-note[hidden] { display: none; }
.rp-photo-preview { display: block; max-height: 64px; width: auto; max-width: 100%; margin: var(--sp-4) 0; border-radius: var(--r-md); object-fit: contain; background: var(--sunken); }
/* 암장 사진 tab: picked pictures as a grid; each has a 44px tap area in its corner to take it out */
.rp-drop { cursor: pointer; }
.rp-box { display: flex; align-items: center; justify-content: center; gap: var(--sp-8); min-height: 96px; border: 1px dashed var(--line-strong); border-radius: var(--r-base); color: var(--muted); font-weight: 600; } /* the same dotted box as the 루트 tab's empty state */
.rp-drop:focus-within .rp-box { outline: 2px solid var(--accent); outline-offset: 2px; }
.rp-pick-sum { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.rp-thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr)); gap: var(--sp-8); margin: var(--sp-8) 0; padding: 0; list-style: none; }
.rp-thumbs li { position: relative; aspect-ratio: 1; overflow: hidden; border-radius: var(--r-md); background: var(--sunken); }
.rp-thumbs img { display: block; width: 100%; height: 100%; object-fit: cover; }
.rp-thumb-x { position: absolute; top: 0; right: 0; display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; border: 0; color: #fff; font: inherit; font-size: var(--fs-lg); line-height: 1; cursor: pointer; background: radial-gradient(circle 13px at 50% 50%, rgb(0 0 0 / .65) 96%, transparent 100%); }
.rp-thumb-x:disabled { opacity: .5; cursor: default; }
.rp-thumbs[hidden], .rp-pick-sum[hidden] { display: none; }
.pf-rank[hidden] { display: none; }
.pf-rank-list { margin: var(--sp-8) 0 0; padding: 0; list-style: none; display: grid; gap: var(--sp-4); font-size: var(--fs-sm); }
.pf-rank-list b { display: inline-block; min-width: 2.2em; color: var(--accent); }
.rp-chat-name { user-select: all; -webkit-user-select: all; color: var(--fg); min-width: 0; overflow-wrap: break-word; } /* one tap selects the whole name, to copy */
/* the foot of a card: 정보가 달라요 · 오픈채팅방 알려주기, quiet text links (the 44px height is the tap area) */
.help-row { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0 var(--sp-16); margin-top: var(--sp-16); } /* right-aligned and apart from the sun card above: the card's last, quiet line */
.help-link { min-height: var(--tap); padding: 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-sm); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
/* the two 제보 links under the card's buttons stay quiet: small, a pale underline (the tap area stays 44px) */
.help-row .help-link { display: inline-flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-xs); text-decoration: none; } /* a small icon and the words, no underline: quiet, not a web link */
.help-row .help-link svg { width: 14px; height: 14px; flex: none; }
/* 날씨 구역: 등록한 구역의 비 예보 띠(홈 맨 위, 휴무안내 줄과 같은 마크업)와 카드의 종류·봉우리 줄, 등록 버튼 (docs/superpowers/specs/2026-11-06-positioning-natural-rock-design.md) */
.zone-banner { margin: 0 0 var(--sp-12); }
.zone-banner[hidden] { display: none; }
.zone-meta { margin: var(--sp-4) 0; color: var(--muted); font-size: var(--fs-sm); overflow-wrap: break-word; }
.zone-toggle { white-space: nowrap; min-width: var(--tap); }
.zone-banner .irow.notice.rain .nt-t { color: var(--fg); font-weight: 600; } /* 알리기만 하는 줄: 눌러지는 파란 링크처럼 보이지 않게 본문색 */
.zone-toggle[aria-pressed="true"] { color: var(--fg); font-weight: 600; text-decoration: none; }
.rp-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.rp-status { min-height: 1.4em; margin: var(--sp-8) 0; font-size: var(--fs-sm); white-space: pre-line; }
.rp-alt { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--accent); font-weight: 600; white-space: nowrap; }
.rp-send { min-height: var(--tap); border: 0; border-radius: var(--r-md); background: var(--accent); color: var(--on-accent); font-weight: 600; white-space: nowrap; }
.rp-send:disabled { opacity: .5; }
.rp-name { color: var(--fg); font-size: var(--fs-base); font-weight: 600; min-width: 0; overflow-wrap: break-word; }

/* ---- 내 정보 (header button + sheet) ---- */
.top .wrap { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto auto; align-items: center; } /* title | 종류 스위치 | 도움말 | 안전수칙 | 내 정보 */
.top .wrap > :not(h1):not(.mode-switch):not(.me-btn):not(.safety-btn):not(.help-btn) { grid-column: 1 / -1; }
.top .wrap > h1 { grid-column: 1; } .top .wrap > .help-btn { grid-column: 3; } .top .wrap > .safety-btn { grid-column: 4; } .top .wrap > .me-btn { grid-column: 5; }
.help-btn { color: var(--fg); }
.me-btn { margin-right: -10px; color: var(--fg); }
.me-btn svg { width: 24px; height: 24px; }
.safety-btn { color: var(--fg); }
.safety-btn svg { width: 24px; height: 24px; }
.pf-backup { flex-wrap: wrap; }
.pf-btns { display: flex; flex-wrap: wrap; gap: var(--sp-8); flex-basis: 100%; }
.pf-btns .sh-toggle { flex: 1 1 8rem; }
.pf-status { flex-basis: 100%; min-height: 1.5em; font-size: var(--fs-sm); color: var(--muted); }
.pf-link { display: flex; flex: 1; align-items: center; justify-content: space-between; gap: var(--sp-8); min-height: var(--tap); color: var(--fg); font-weight: 600; text-decoration: none; }
button.pf-link { width: 100%; padding: 0; border: 0; background: none; font: inherit; font-weight: 600; text-align: left; cursor: pointer; }
.pf-ios { margin: 0; font-size: var(--fs-sm); color: var(--muted); }
.pf-link span { font-size: var(--fs-xs); font-weight: 400; color: var(--muted); text-align: right; }
.pf-link span:not(.pv-arrow) { margin-left: auto; } /* 설명은 오른쪽으로 붙이고 › 가 맨 끝에 온다 */
.pf-link .pv-arrow { font-size: var(--fs-md); } /* .pf-link span의 xs를 이겨 다른 › 와 같은 크기 */
.pf-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 시트 머리의 글자 탭(나 | 설정): 본문의 면 세그먼트와 달리 밑줄 탭, 화면 전체가 바뀐다 */
.sh-head:has(> .hd-tabs) { flex-wrap: wrap; align-content: flex-start; padding-bottom: 0; }
.hd-tabs { order: 9; flex: 1 0 100%; display: flex; gap: var(--sp-8); margin: var(--sp-4) calc(var(--sp-12) * -1) 0; } /* 눌림 영역을 글자 밖으로 넓히고 첫 글자는 본문 왼쪽 줄에 맞춘다 */
.hd-tabs [role="tab"] { min-height: var(--tap); min-width: var(--tap); padding: 0 var(--sp-12); border: 0; border-bottom: 3px solid transparent; background: none; color: var(--muted); font: inherit; font-size: var(--fs-md); font-weight: 600; white-space: nowrap; cursor: pointer; }
.hd-tabs [aria-selected="true"] { color: var(--fg); font-weight: 700; border-bottom-color: var(--accent); }
.hd-tabs [role="tab"]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pf-stack { display: grid; }
.pf-pane { display: grid; grid-area: 1 / 1; align-content: start; overflow-x: clip; } /* 두 패널이 한 칸을 겹쳐 쓴다: 시트 높이가 탭마다 바뀌어 탭 막대가 튀지 않는다 */
.pf-pane.off { visibility: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .pf-pane.from-r { animation: pane-from-r var(--dur-ui) var(--ease-out); }
  .pf-pane.from-l { animation: pane-from-l var(--dur-ui) var(--ease-out); }
}
@keyframes pane-from-r { from { transform: translateX(24px); opacity: 0; } }
@keyframes pane-from-l { from { transform: translateX(-24px); opacity: 0; } }
.pf-region { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8); }
.sh-note { display: flex; align-items: center; gap: var(--sp-8); margin: var(--sp-8) 0 0; } /* a status line + its retry, under a control */
.sh-note[hidden] { display: none; }
.sh-note .sh-hint { flex: 1; }
.pf-region .sh-label { white-space: nowrap; }
.pf-region #regionSum { flex: 1; font-weight: 600; }
.pf-region .pf-link, .sh-note .pf-link { flex: none; width: auto; padding: 0 var(--sp-8); font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; text-decoration: underline; }
html[data-text="xlarge"] .sh-note { flex-wrap: wrap; align-items: flex-start; } /* 가장 큰 글씨: 문구는 전폭, 다시 찾기는 그 아래 */
html[data-text="xlarge"] .sh-note .sh-hint { flex: 1 1 100%; }

/* ---- 기록 추가 sheet ---- */
.la-pick legend { margin-bottom: var(--sp-8); }
.la-row { flex-wrap: wrap; }
.la-field { display: grid; gap: var(--sp-8); flex-basis: 100%; clear: both; }
.la-field input, .la-field textarea, .la-field select {
  width: 100%; min-height: var(--tap); padding: var(--sp-8) var(--sp-12); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  background: var(--bg); color: var(--fg); font: inherit;
}
.la-field textarea { resize: vertical; white-space: pre-wrap; }
.la-chips { display: flex; flex-wrap: wrap; gap: var(--sp-8); clear: both; margin-bottom: var(--sp-12); }
.la-chips[hidden] { display: none; }
div.la-when { row-gap: 0; }
.la-when .sh-label { flex-basis: 100%; margin: 0 0 var(--sp-8); }
.la-when .la-chips { flex-basis: 100%; margin-bottom: 0; }
.la-datewrap { position: relative; display: inline-flex; max-width: 100%; }
.la-datewrap:focus-within .la-chip { outline: 2px solid var(--accent); outline-offset: 2px; }
.la-date { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; } /* 칩 위에 투명하게: 탭이 네이티브 달력을 직접 연다 */
.la-chip { display: inline-flex; align-items: center; justify-content: center; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.la-chip.fixed { pointer-events: none; background: var(--sunken); border-color: var(--line); color: var(--fg); } /* 암장이 정해진 채 열림: 눌리는 칩(검정 ✓)과 달리 회색 이름표, 바꿀 수 없음 */
.la-field input::placeholder { color: var(--muted); opacity: 1; } /* 기본 placeholder 는 대비 4.1:1 */
.la-search { clear: both; }
.map-find-btn, .map-legend-btn { position: absolute; top: 34px; right: 10px; z-index: 1; display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; border: 2px solid rgba(0,0,0,.2); border-radius: var(--r-md); background: var(--surface); color: var(--fg); box-shadow: var(--shadow-float); cursor: pointer; }
.map-find-btn svg, .map-legend-btn svg { width: 22px; height: 22px; }
.map-legend-btn { top: calc(34px + var(--tap) + var(--sp-8)); } /* under the search button */
html[data-text="xlarge"] .map-legend-btn { top: calc(var(--tap) * 2 + var(--sp-16)); }
/* 핀 설명: a popover over the map (the ⓘ button opens it), not a block under it, so it is on screen with the pins it explains */
.map-legend { position: absolute; left: var(--sp-8); right: var(--sp-8); top: var(--sp-8); z-index: 3; max-height: calc(100% - var(--sp-16)); overflow-y: auto; border-radius: var(--r-base); background: #2a2d32; box-shadow: var(--shadow-float); }
.map-legend-head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-4) var(--sp-4) 0 var(--sp-16); color: #f4f2ec; }
.map-legend-head b { font-size: var(--fs-md); }
.map-legend-close { flex: none; width: var(--tap); height: var(--tap); border: 0; background: none; color: #f4f2ec; font-size: var(--fs-lg); line-height: 1; cursor: pointer; }
.map-legend .legend { margin: 0; border-radius: 0 0 var(--r-base) var(--r-base); }
.map-legend-btn:focus-visible, .map-legend-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
html[data-text="xlarge"] .map-find-btn { top: calc(var(--tap) + var(--sp-8)); } /* the map credit wraps to 3 lines in big text: below it, not over "contributors" */
.map-find-btn:focus-visible, .map-find-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.map-find { position: absolute; top: 8px; left: 8px; right: 8px; z-index: 2; }
.map-find-bar { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-8); border-radius: var(--r-base); background: var(--surface); box-shadow: var(--shadow-float); }
.map-find-bar .la-field { flex: 1; }
.map-find-bar input { min-height: 36px; padding-block: var(--sp-4); }
.map-find-close { flex: none; width: var(--tap); height: var(--tap); border: 0; background: none; color: var(--muted); font-size: var(--fs-lg); line-height: 1; cursor: pointer; }
.map-find .la-picks { margin-top: var(--sp-4); background: var(--surface); box-shadow: var(--shadow-float); }
/* the search shares the filter row: it takes what the 양달·응달 and 조건 buttons leave; its results open under the whole row */
.find { position: relative; flex: 1 1 0; min-width: 0; margin: 0; }
/* the search field's 내 위치: a pin at its right end while the field is empty (typing brings the browser's own ✕ there); filled in the sun's colour while 가까운 순 runs on a known position */
.find-loc { position: absolute; top: 0; right: 0; width: var(--tap); height: var(--tap); display: grid; place-items: center; padding: 0; border: 0; border-radius: var(--r-base); background: none; color: var(--muted); cursor: pointer; }
.find-loc svg { width: var(--icon-sm); height: var(--icon-sm); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.find-loc[aria-pressed="true"] { color: var(--sun-ui); }
.find-loc[aria-pressed="true"] svg { fill: color-mix(in srgb, var(--sun-ui) 28%, transparent); }
.find-loc.busy { opacity: .5; }
.find-loc:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.find:has(#findQ:not(:placeholder-shown)) .find-loc { display: none; }
.find[hidden] { display: none; }
.find .la-field { flex-basis: auto; }
.find .la-picks { position: absolute; left: 0; right: 0; top: calc(100% + var(--sp-4)); z-index: var(--z-picks); margin: 0; background: var(--surface); box-shadow: var(--shadow-float); }
.find .la-field input { border-color: transparent; background: var(--sunken); /* no outline: the time band below is the hero, not the search box */ min-height: var(--tap); padding-block: var(--sp-4); padding-right: calc(var(--tap) - var(--sp-4)); text-overflow: ellipsis; } /* 글자 크기는 그대로(작으면 iOS 가 확대함) */
.la-picks { list-style: none; margin: var(--sp-8) 0 0; padding: 0; max-height: calc(var(--tap) * 5); overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--line); border-radius: var(--r-md); }
.la-picks li + li { border-top: 1px solid var(--hair); }
.la-hit { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-8); width: 100%; min-height: var(--tap); padding: var(--sp-12) var(--sp-12); border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.la-hit:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.la-picks .pn { font-weight: 500; }
.la-picks .pr { margin-left: auto; font-size: var(--fs-xs); color: var(--muted); }
.la-picks .none { padding: var(--sp-12); font-size: var(--fs-sm); color: var(--muted); }
.la-err { flex-basis: 100%; margin-top: var(--sp-8); font-size: var(--fs-sm); font-weight: 600; color: var(--warn); }
.la-err::before { content: "! "; }
/* 저장 바: 시트가 스크롤돼도 항상 보인다(dialog 가 스크롤 상자). 음수 아래 마진 = 폼의 아래 안쪽 여백까지 덮는다. */
.la-share[hidden], .la-share-body[hidden] { display: none; }
.la-share-on { display: flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); font-weight: 600; }
.la-share-on input { flex: none; width: 20px; height: 20px; accent-color: var(--accent); }
.la-share-body { display: grid; gap: var(--sp-8); margin-top: var(--sp-8); }
.la-foot { position: sticky; bottom: 0; z-index: 1; display: grid; gap: var(--sp-8); margin: 0 -16px calc(-16px - env(safe-area-inset-bottom)); padding: 10px 16px calc(16px + env(safe-area-inset-bottom)); border-top: 1px solid var(--hair); background: var(--surface); box-shadow: 0 -6px 8px -8px rgb(0 0 0 / .25); }
.la-need { margin: 0; text-align: center; }
.la-need[hidden] { display: none; }
.la-save { min-height: var(--tap); border: 0; border-radius: var(--r-base); background: var(--accent); color: var(--on-accent); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 var(--sp-16); }
.la-save:disabled { background: var(--sunken); color: var(--muted); }
/* 방문 시각: the wall's hours of that day on the 06–24 axis (휴게 hatched). The bar (44px tall, full width) takes taps
   and sideways drags itself (log-view.js pointer handlers; pan-y keeps vertical swipes scrolling the sheet); an invisible
   range input over it, deaf to pointers, serves arrow keys and screen readers. .vt-mark draws the pick. */
div.la-time { display: block; }
.la-time { border-top: 0; padding-top: 0; } /* 언제 칩 바로 아래 한 줄로 이어진다 */
.la-time-toggle { margin: 0 -8px 0 auto; }
#la-time-body[hidden] { display: none; }
.la-time-hd { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-12); }
.la-time-say { font-size: var(--fs-base); font-variant-numeric: tabular-nums; }
.la-time-say.unset { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); }
.vt { position: relative; height: var(--tap); margin-top: var(--sp-8); border-radius: var(--r-sm); cursor: pointer; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.vt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.vt-trk { position: absolute; left: 0; right: 0; top: 14px; height: 16px; border-radius: 4px; background: var(--sunken); }
.vt-bar { position: absolute; top: 2px; bottom: 2px; border-radius: 3px; background: var(--open-bar); }
.vt-future { position: absolute; top: 0; bottom: 0; right: 0; border-radius: 0 4px 4px 0; background: var(--surface); opacity: .7; pointer-events: none; }
.vt-brk { position: absolute; top: 0; bottom: 0; border: 1px solid var(--line-strong); border-radius: var(--r-xs);
  background-image: repeating-linear-gradient(135deg, var(--hatch) 0 2px, transparent 2px 6px); }
.vt-trk.off { border: 1px solid var(--line); background-image: repeating-linear-gradient(135deg, var(--hatch) 0 2px, transparent 2px 6px); }
.vt-mark { position: absolute; top: 4px; bottom: 4px; width: 3px; margin-left: -1.5px; border-radius: var(--r-xs); background: var(--fg); box-shadow: 0 0 0 2px var(--surface); pointer-events: none; }
.vt-mark::before { content: ""; position: absolute; left: 50%; top: -3px; width: 11px; height: 11px; margin-left: -5.5px; border-radius: 50%; background: var(--fg); box-shadow: 0 0 0 2px var(--surface); }
.vt input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; pointer-events: none; -webkit-appearance: none; appearance: none; }
/* a 1px thumb keeps the input's value ↔ position mapping the same as the bar's axis */
.vt input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 1px; height: var(--tap); }
.vt input::-moz-range-thumb { width: 1px; height: var(--tap); border: 0; }
.vt-axis { position: relative; height: 1.4em; font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.vt-axis span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.vt-axis span:first-child { transform: none; }
.vt-axis span:last-child { transform: translateX(-100%); }
.la-time-ft { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-8) var(--sp-12); margin-top: var(--sp-4); }
.la-time-ft .sh-hint { flex: 1 1 12rem; }
.la-time-clear { margin-left: auto; }
div.la-crowd { flex-wrap: wrap; justify-content: flex-start; gap: var(--sp-8); }
.la-crowd-q { flex-basis: 100%; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.la-crowd-q span { font-weight: 400; }
.la-crowd .crowd-pills { flex-wrap: wrap; }
.la-more { display: block; }
.la-more > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); min-height: var(--tap); font-weight: 600; cursor: pointer; list-style: none; }
.la-more > summary::-webkit-details-marker { display: none; }
.la-more > summary::after { content: "▾"; content: "▾" / ""; margin-left: var(--sp-8); color: var(--muted); }
.la-more[open] > summary::after { content: "▴"; content: "▴" / ""; }
.la-more > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.la-more-note { margin-left: auto; font-size: var(--fs-xs); font-weight: 400; color: var(--muted); }
/* 그레이드 기록 (the 기록 추가 sheet): a wall of holds, easy grades on top; a tap adds one (완등: a filled hold, 시도: an amber ring) */
.la-gmode, .la-disc, .la-multi .segs { width: 100%; margin-bottom: var(--sp-12); }
.gw, .la-wall, .gwall { width: 100%; }
.gr { display: grid; grid-template-columns: 44px repeat(4, minmax(0, 1fr)); align-items: center; min-height: 52px; border-top: 1px solid var(--hair); }
.gr:first-child { border-top: 0; }
.gr-l { font-weight: 700; }
.hold { position: relative; width: var(--tap); height: var(--tap); margin: 0 auto; padding: 0; border: 1.5px dashed var(--line-strong); border-radius: 50%; background: none; color: var(--muted); font: inherit; font-size: var(--fs-xs); cursor: pointer; }
.hold.s { border: 1.5px solid var(--accent); background: var(--accent); color: var(--on-accent); font-size: var(--fs-md); font-weight: 700; }
.hold.t { border: 2.5px solid var(--sun); color: var(--fg); font-size: var(--fs-md); font-weight: 700; }
.hold .tb { position: absolute; top: -3px; right: -3px; min-width: 20px; height: 20px; border: 2px solid var(--sun); border-radius: var(--r-pill); background: var(--surface); color: var(--fg); font-size: .6875rem; font-weight: 700; line-height: 16px; }
.hold:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.la-gsum { width: 100%; margin-top: var(--sp-12); }
.gs { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8); margin: 0 0 var(--sp-8); font-size: var(--fs-sm); }
.gs b { margin-right: var(--sp-4); }
.gs.sends b { color: var(--accent); }
.gs.tries b { color: var(--muted); }
.gs.routes b { color: var(--accent); }
.gc { display: inline-flex; align-items: center; min-height: 32px; padding-left: var(--sp-12); border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--surface); }
.gm { min-width: var(--tap); min-height: var(--tap); margin-block: calc(var(--sp-8) * -1); border: 0; background: none; color: var(--accent); font: inherit; font-size: var(--fs-lg); }
.gm:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-pill); }
.la-more > summary + .sh-row { border-top: 0; }

/* ---- 다녀왔어요 / 내 기록 (open card) and "✓ 다녀옴 N번" (list row) ---- */
.been { flex: none; font-size: var(--fs-xs); font-weight: 600; color: var(--muted); white-space: nowrap; }
/* 세팅일이 바뀌었어요 (♥ walls, setting.js): words + ✦ in an outlined pill, not colour alone */
.setnew, .newspill { flex: none; display: inline-block; width: fit-content; padding: 0 var(--sp-8); border: 1px solid transparent; border-radius: var(--r-pill); background: var(--sunken); font-size: var(--fs-xs); font-weight: 600; color: var(--accent); white-space: nowrap; } /* information is a filled chip like 무료/주차 (outline = tappable); on a photo the outline stays, see below */
.rsub:has(.newspill) { flex-wrap: nowrap; min-width: 6em; } /* the pill and the region on one line: the region is the one that gives way */
.rsub:has(.newspill) .rmeta { flex: 0 1 auto; min-width: 0; text-overflow: ellipsis; white-space: nowrap; }
.rsub > .newspill { line-height: calc(1.5rem - 2px); } /* inside the 1.5rem line with its border */
p.setnew, p.newspill { margin-top: var(--sp-8); }
.newspill.warn { color: var(--warn); } /* 닫힘 소식만 --warn (the other news stay accent) */
.row.is-open:is(:has(.irow.notice.sure), :has(p.newspill)) .row-btn .newspill { display: none; } /* an open card says a closing twice at most: the 휴무 line or the news sentence replaces the head's pill */
p.newspill { white-space: normal; border-radius: var(--r-base); padding: 0 var(--sp-12); } /* the card's pill tells the whole thing, so it may wrap */
/* 다녀왔어요: a 64px stamp square left of 자세히 (outlined; filled with the count once there is a record) */
.go-row { display: flex; align-items: stretch; margin-top: var(--sp-12); overflow: hidden; border-radius: var(--r-base); box-shadow: inset 0 0 0 1.5px var(--go-edge); --go-edge: color-mix(in srgb, var(--fg) 50%, var(--paper)); } /* the edge keeps 3:1 against the page in both themes */
/* a card with no sun picture (indoor, a closed day): the two actions share one outlined frame, no fill (the card above is already a grey panel); only the stamp carries the sun */
:is(.expand-in, .crag-body) .go-row .been-btn { border: 0; border-radius: 0; border-right: 1.5px solid var(--go-edge); background: none; color: var(--fg); }
:is(.expand-in, .crag-body) .go-row .been-btn :is(svg, .been-stamp) { color: currentColor; }
:is(.expand-in, .crag-body) .go-row .been-btn.done { background: var(--sunken); }
.go-row .sheet-open { border-radius: 0; background: none; color: var(--fg); }
.go-row .sheet-open:focus-visible, :is(.expand-in, .crag-body) .go-row .been-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
/* a frame holding only 다녀왔어요 (a crag card with no sun picture, until 암장 정보 자세히 joins it) hugs the button: no empty frame, no divider */
.go-row:has(> .been-btn:only-child) { width: fit-content; }
.go-row > .been-btn:only-child { border-right: 0; }
/* share (card-parts.js photoTools): an icon on the photo's foot, bottom-right, no circle; the camera is its twin at bottom-left: both 24px icons with a 44px tap, one row above the dock */
.photo-tools { position: absolute; z-index: 2; right: calc(var(--pad) - 10px); bottom: var(--icon-row); display: flex; align-items: center; color: var(--on-photo); filter: drop-shadow(0 1px 2px rgb(0 0 0 / .65)); }
.ph-hero > .photo-tools { bottom: var(--icon-row); color: var(--accent); filter: none; } /* on the placeholder block: the camera's colour */
.photo-tools .share-wrap { display: flex; margin: 0; }
.photo-tools .icon-btn { width: 44px; height: 44px; background: none; color: inherit; }
.photo-tools .icon-btn svg { width: 24px; height: 24px; }
.photo-tools .icon-btn:is(:hover, .done) { color: inherit; }
.photo-tools .icon-btn:focus-visible { outline: 2px solid currentColor; outline-offset: -6px; }
/* the two actions under the photo (card-parts.js dock): 길찾기 outlined, 다녀왔어요 in the panel tone, 48px, no outline */
.dock { display: flex; gap: var(--sp-8); margin-top: var(--sp-12); padding: 0; } /* no pill around the two buttons (it was a card inside the card): they stand on their own, each with its own seg-level shadow */
:is(.expand-in, .crag-body) .dock > :is(.dock-go, .been-btn) { flex: 1 1 0; min-width: 0; } /* halves (beats the stamp's flex:none) */
.dock-go, :is(.expand-in, .crag-body) .dock .been-btn { display: flex; align-items: center; justify-content: center; gap: var(--sp-8); min-height: var(--h-l); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-pill); font: inherit; font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; text-decoration: none; cursor: pointer; }
.dock-go { background: var(--sunken); color: var(--fg); box-shadow: var(--shadow-seg), inset 0 0 0 1px var(--line); } /* the way there: a soft sunken fill, below 다녀왔어요 in the order of the two */
:is(.expand-in, .crag-body) .dock .been-btn { background: var(--accent); box-shadow: var(--shadow-seg); color: var(--on-accent); font-weight: 800; } /* the app's own action, the card's first: accent fill (the one coloured fill in the dock) */
:is(.expand-in, .crag-body) .dock .been-btn.done { background: var(--sunken); box-shadow: var(--shadow-seg), inset 0 0 0 1px var(--line); color: var(--fg); font-weight: 700; } /* done: quiet again, the card has what it asked for */
:is(.expand-in, .crag-body) .dock .been-btn :is(svg, .been-stamp) { color: currentColor; }
.dock :is(svg, .been-stamp) { width: var(--icon-sm); height: var(--icon-sm); flex: none; }
.dock .been-btn small { font-size: inherit; }
.dock > :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 길찾기 · 전화: icons only (aria-label + title say it), one square each; 다녀왔어요 takes the rest of the line */
:is(.expand-in, .crag-body) .dock > .dock-ic { flex: 0 0 var(--h-l); padding: 0; }.dock > .dock-share { flex: 0 0 var(--h-l); display: flex; margin: 0; } /* the map card's 공유: the same outlined square as 길찾기 and 전화 */
.dock-share > .icon-btn { width: 100%; height: auto; min-height: var(--h-l); border-radius: var(--r-pill); background: var(--sunken); color: var(--fg); box-shadow: var(--shadow-seg), inset 0 0 0 1px var(--line); }
.dock-share svg { width: 22px; height: 22px; }
.dock-share > .icon-btn:focus-visible { outline-offset: 2px; } /* the ring stands outside the square like the other dock buttons' (.dock > :focus-visible) */
@media (max-width: 360px) { :is(.expand-in, .crag-body) .dock > .dock-ic, .dock > .dock-share { flex-basis: var(--h-l); } } /* four buttons (길찾기 · 전화 · 공유 · 다녀왔어요) on a narrow screen: the squares give 12px back so 다녀왔어요 is not clipped in big type */
.dock > .dock-ic svg { width: 22px; height: 22px; }
.dock > :active { transform: scale(.98); }
/* the one line of chips (card-parts.js chipBar): pale pills, 30px to look at and 44px to tap; each opens the sheet where its detail is */
.chip-bar { position: relative; display: flex; flex-wrap: wrap; gap: var(--sp-8); margin: var(--sp-8) 0 var(--sp-4); padding-bottom: var(--sp-12); } /* the chips belong to the dock above; the air under them splits them from the rows */
.cchip-cell { display: inline-flex; max-width: 100%; }
.chip-bar .cchip { margin-left: 0; } /* a 유료/무료 chip (.fee) carries a 6px left margin of its own: the row starts on the card's line */
.cchip { display: inline-flex; align-items: center; gap: var(--sp-4); min-height: var(--h-m); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-pill); background: var(--sunken); color: var(--fg); font: inherit; font-size: var(--fs-sm); font-weight: 500; white-space: nowrap; max-width: 100%; min-width: 0; }
.cchip > span:not(.sr-only) { overflow: hidden; text-overflow: ellipsis; }
.cchip svg { width: 16px; height: 16px; flex: none; }
@media (max-width: 400px) { .cchip { font-size: var(--fs-xs); padding: 0 var(--sp-8); } } /* three chips stay on one line on a phone */
button.cchip { position: relative; cursor: pointer; }
:is(button, a).cchip::after { content: ""; position: absolute; inset: -9px -2px; } /* looks 30px, taps like 48px */
:is(button, a).cchip:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
:is(button, a).cchip:active { transform: scale(.97); }
.cchip svg { color: var(--muted); } /* every chip reads the same; only a warning (정기휴무, short rope) takes a colour */
.cchip.warn, .cchip.warn svg { color: var(--warn); }
.cchip.sched { box-shadow: inset 0 0 0 1px var(--accent); background: transparent; color: var(--accent); font-weight: 700; } /* 매주 가요 leads the line: an outline asks for a tap, */
.sched-pop { scroll-margin-bottom: 88px; position: absolute; left: 0; right: 0; top: calc(100% + var(--sp-8)); z-index: 5; padding: var(--sp-12) var(--sp-12); border-radius: var(--r-base); background: var(--surface); box-shadow: 0 4px 18px rgb(0 0 0 / .18), 0 0 0 1px var(--line); }
.sched-pop .sd-week { margin-bottom: 0; }
.sched-pop .sd-tog:not(:has(:checked)) { border-color: transparent; background: transparent; } /* the weekdays are plain letters until picked (the 내 정보 rows keep their boxes) */
.sched-pop-h { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); }
.sched-pop-h .pick-basis { margin: 0; }
.cchip.sched[aria-expanded="true"] { box-shadow: inset 0 0 0 2px var(--accent); } /* open: a thicker outline */
@media (max-width: 340px) { .sched-pop { padding-inline: var(--sp-8); } } /* seven weekdays at 41px instead of 36 */
.cchip.sched.on { background: var(--accent); color: var(--on-accent); } /* filled once the weekdays are set */
/* the line into the sheet (card-parts.js sheetLine): a hairline above, 48px */
.sheet-line { display: flex; align-items: center; gap: var(--sp-8); width: 100%; min-height: 48px; margin-top: var(--sp-4); padding: 0; border: 0; background: none; color: var(--fg); font: inherit; text-align: left; cursor: pointer; }
.sheet-line b { flex: none; font-size: var(--fs-md); font-weight: 700; white-space: nowrap; }
/* the line into the sheet is a row of two: the words with their › beside them, and the 한 줄 타임라인 pill at the right end (card-parts.js sheetLine / setBoardPill) */
.sheet-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-8); margin-top: var(--sp-4); }
.sheet-row .sheet-line { flex: 0 1 auto; width: auto; margin-top: 0; }
.sheet-row .sheet-line i { margin-left: 0; }
.board-pill { position: relative; flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: var(--sp-8); min-height: 36px; padding: 0 var(--sp-12); border: 0; border-radius: var(--r-pill); background: var(--sunken); color: var(--fg); font: inherit; font-size: var(--fs-sm); font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer; }
.board-pill::after { content: ""; position: absolute; inset: -4px 0; } /* looks 36px, taps like 44px */
.board-pill svg { width: 16px; height: 16px; flex: none; }
.board-pill i { font-style: normal; color: var(--muted); }
.board-pill.new { color: var(--open); }
.board-pill.new b { font-weight: 700; }
.board-pill.none { background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--muted); }
.board-pill:active { transform: scale(.97); }
.board-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sheet-line i { margin-left: auto; flex: none; font-style: normal; font-size: 1.375rem; line-height: 1; }
.sheet-line:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 8px; } /* the line has no side padding: the ring stands off the words */
/* under a sun picture the two buttons are the card's foot, the wall's base: only the card's own colours (--sc-*), so every sky (lit, low, shade, night, dark) carries them */
.sunbox.sc .sc-actions { padding: var(--sp-12) var(--sp-16) var(--sp-16); background: var(--sc-wall); }
.sunbox.sc .sc-frame { --sc-edge: color-mix(in srgb, var(--sc-gtext) 45%, transparent); display: flex; align-items: stretch; overflow: hidden; border-radius: var(--r-base); box-shadow: inset 0 0 0 1.5px var(--sc-edge); } /* one frame, the stamp and 자세히 split by a hairline */
.sunbox.sc .sc-frame .been-btn { min-width: 76px; border: 0; border-radius: 0; border-right: 1.5px solid var(--sc-edge); color: var(--sc-halo); background: none; }
.sunbox.sc .sc-frame .been-btn.done { background: color-mix(in srgb, var(--sc-halo) 20%, transparent); }
.sunbox.sc .sc-frame .sheet-open { border-radius: 0; background: none; color: var(--sc-gtext); }
.sunbox.sc .sc-frame .sheet-open i { color: var(--sc-halo); }
.sunbox.sc .sc-frame :is(.been-btn, .sheet-open):focus-visible { outline: 2px solid var(--sc-halo); outline-offset: -4px; }
/* a frame holding only 다녀왔어요 (the crag card, until 암장 정보 자세히 joins it) hugs the button like the lone .go-row: no divider */
.sunbox.sc .sc-frame:has(> .been-btn:only-child) { width: fit-content; }
.sunbox.sc .sc-frame > .been-btn:only-child { border-right: 0; }
:is(.expand-in, .crag-body) .been-btn {
  flex: none; min-width: 68px; min-height: 56px; padding: 0 var(--sp-8); display: grid; place-items: center; align-content: center; gap: var(--sp-2);
  border: 2px solid var(--accent); border-radius: var(--r-base); background: none; color: var(--accent); font-family: inherit; cursor: pointer;
}
:is(.expand-in, .crag-body) .been-btn.done { background: var(--accent); color: var(--on-accent); }
:is(.expand-in, .crag-body) .been-btn svg { width: 22px; height: 22px; }
:is(.expand-in, .crag-body) .been-btn small { font-size: var(--fs-xs); font-weight: 700; white-space: nowrap; } /* the app's smallest text, 13px */
:is(.expand-in, .crag-body) .been-btn:active { transform: scale(.97); }
.been-stamp { flex: none; width: 22px; height: 22px; background: currentColor; }
.been-stamp.stamp-in { animation: stamp-in 120ms var(--ease-out) both; }
@media (prefers-reduced-motion: reduce) { .been-stamp.stamp-in { animation: none; } }
.mylog { margin-top: var(--sp-12); }
.mylog-note { margin-top: var(--sp-4); font-size: var(--fs-xs); color: var(--muted); }
.mylog-list { list-style: none; margin: var(--sp-4) 0 0; padding: 0; font-size: var(--fs-sm); }
.mylog-list li { display: flex; gap: var(--sp-12); padding: var(--sp-8) 0; border-top: 1px solid var(--hair); }
.ml-d { flex: none; color: var(--muted); white-space: nowrap; }
.ml-m { min-width: 0; overflow-wrap: break-word; }

/* ---- 기록 tab ---- */
#panel-log { margin-top: var(--sp-16); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-16); } /* minmax(0,…): a wide child (the year map) scrolls inside its card instead of widening the page */
/* 내 활동: the 등급 seal + name, the bar to the next tier, the numbers */
.lg-act { padding: var(--sp-16) var(--sp-16); border-radius: var(--r-lg); background: var(--surface); border: 1px solid var(--line); }
.lg-act-hd { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-8); }
.lg-act-rank { flex: 1 1 5.5rem; min-width: 0; }
.lg-act-rank b { font-size: var(--fs-lg); color: var(--open); }
.lg-act-rank p:first-child { font-weight: 600; }
.lg-act-next { font-size: var(--fs-sm); color: var(--muted); }
.lg-track { height: 10px; margin-top: var(--sp-12); border-radius: var(--r-pill); background: var(--sunken); box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; }
.lg-fill { height: 100%; border-radius: inherit; background: var(--open); }
.lg-bar-end { display: flex; justify-content: space-between; margin: var(--sp-4) var(--sp-2) 0; font-size: var(--fs-xs); font-weight: 600; color: var(--muted); }
.lg-act-meta { margin: var(--sp-8) var(--sp-2) 0; font-size: var(--fs-sm); color: var(--muted); }
.lg-info { position: relative; display: inline-grid; place-items: center; width: 24px; height: 24px; margin-left: var(--sp-8); padding: 0; vertical-align: -5px; border: 0; background: none; color: var(--muted); }
.lg-info::after { content: ""; position: absolute; inset: -10px; }
.lg-info svg { width: var(--icon-sm); height: var(--icon-sm); }
.ri-list { display: grid; margin: var(--sp-4) 0 0; padding: 0; list-style: none; }
.ri-list li { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: var(--sp-4) var(--sp-12); min-height: 52px; padding: var(--sp-8) 0; border-top: 1px solid var(--hair); }
.ri-name { display: grid; gap: 1px; min-width: 0; }
.ri-list b { font-size: var(--fs-base); }
.ri-name small { font-size: var(--fs-xs); font-weight: 400; color: var(--muted); }
.ri-list span, .ri-list em { font-size: var(--fs-sm); font-style: normal; color: var(--muted); white-space: nowrap; }
.ri-list em { min-width: 3.5rem; text-align: right; font-weight: 600; }
.ri-now b, .ri-now em { color: var(--open); }
.ri-done em { color: var(--open); }
.ri-todo b { color: var(--muted); font-weight: 600; }
.ri-dots { display: inline-flex; gap: 3px; }
.ri-dots i { width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--line-strong); }
.ri-dots i.on { border-color: var(--open); background: var(--open); }
.lg-act small { display: block; margin-top: var(--sp-8); font-size: var(--fs-xs); color: var(--muted); }
.lg-clm { padding: var(--sp-16) var(--sp-16); border-radius: var(--r-lg); background: var(--surface); border: 1px solid var(--line); }
.lg-clm-hd { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-8) var(--sp-8); }
.lg-clm-lv { font-size: var(--fs-lg); color: var(--open); }
.lg-clm-say { font-size: var(--fs-sm); color: var(--muted); }
.lg-clm-list { list-style: none; margin: var(--sp-12) 0 0; padding: 0; display: grid; gap: var(--sp-12); }
.lg-clm-row.zero p { color: var(--muted); }
.lg-clm-row p { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--sp-8) var(--sp-8); margin: 0; font-size: var(--fs-sm); }
.lg-clm-row .lg-track { height: 6px; margin-top: var(--sp-8); }
.lg-act-none { display: flex; align-items: center; gap: var(--sp-12); padding: 0 var(--sp-4); font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.lg-act-none .rk-seal { width: 44px; height: 44px; margin: var(--sp-8) 20px var(--sp-8) 22px; }
/* the 등급 seal: the 해벽 mark in a round rim, ringed by the sun's path — a thin tilted orbit (upper half behind the face, lower
   half in front) with 5 sun stops on the front arc (in front of the face), one more filled per tier, 전국 완주 draws the whole orbit solid;
   -1 (none yet) a dashed face with the empty orbit. The orbit box is 174% x 61% of the seal, tilted -24deg; margins reserve its reach. */
.rk-seal { --rk-line: color-mix(in srgb, var(--muted) 60%, transparent); position: relative; flex: none; width: 56px; height: 56px; margin: var(--sp-12) 22px var(--sp-12) 20px; }
.rk-face { position: absolute; inset: 0; z-index: 1; border-radius: 50%; background: var(--surface); color: var(--open); box-shadow: 0 0 0 3px var(--surface); } /* page-colour stroke: the orbit behind stops short of the rim */
.rk-face .stamp { position: absolute; inset: 0; } /* the emblem's own ring is the rim */
.rk-orb { position: absolute; left: -37%; top: 19.5%; width: 174%; height: 61%; border: 1px solid var(--rk-line); border-radius: 50%; transform: rotate(-24deg); pointer-events: none; }
.rk-back { z-index: 0; clip-path: inset(-3px -3px 50% -3px); }
.rk-front { z-index: 2; clip-path: inset(50% -3px -3px -3px); box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 2px var(--surface); } /* page-colour halo both sides: the line weaves over the rim */
.rk-seal.complete .rk-orb:not(.rk-dots) { border: 1.5px solid var(--open); }
.rk-dots { z-index: 3; border: 0; }
.rk-dot { position: absolute; width: calc(6px * var(--s, 1)); height: calc(6px * var(--s, 1)); margin: calc(-3px * var(--s, 1)) 0 0 calc(-3px * var(--s, 1)); border-radius: 50%; border: 1px solid var(--rk-line); background: var(--surface); box-shadow: 0 0 0 2px var(--surface); } /* the page-colour halo cuts the orbit line behind the dot */
.rk-dot.on { width: calc(9px * var(--s, 1)); height: calc(9px * var(--s, 1)); margin: calc(-4.5px * var(--s, 1)) 0 0 calc(-4.5px * var(--s, 1)); border: 0; background: var(--open); }
.rk-seal[data-level="-1"] .stamp { background: var(--muted); opacity: .5; }
.rk-seal.stamp-in { animation: stamp-in 120ms var(--ease-out) both; }
@media (prefers-reduced-motion: reduce) { .rk-seal.stamp-in { animation: none; } }
.lg-add {
  min-height: var(--tap); padding: 0 var(--sp-16); border: 1px solid var(--accent); border-radius: var(--r-pill); background: var(--accent);
  color: var(--on-accent); font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; /* the tab's one main action is filled */
}
.lg-backup { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; margin: 0; font-size: var(--fs-xs); color: var(--muted); }
.lg-backup button { min-height: var(--tap); padding: 0 var(--sp-8); border: 0; background: none; color: var(--accent); font: inherit; font-weight: 600; text-decoration: underline; }
.lg-empty { padding: 24px var(--sp-16); text-align: center; border: 1px dashed var(--line-strong); border-radius: var(--r-lg); }
.lg-empty h3 { font-size: var(--fs-lg); }
.lg-ghost { margin: 0 0 var(--sp-16); opacity: .45; pointer-events: none; user-select: none; } /* the empty 기록 shows its own month, dimmed: what it will look like once a visit is saved */
.lg-ghost-t { margin: 0 0 var(--sp-4); font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.lg-ghost-day { position: relative; display: grid; place-items: center; min-height: 36px; border-radius: var(--r-md); font-size: var(--fs-sm); color: var(--muted); }
.lg-ghost-day.now { box-shadow: inset 0 0 0 1px var(--fg); color: var(--fg); }
.lg-empty p { margin: var(--sp-8) 0 var(--sp-16); color: var(--muted); font-size: var(--fs-sm); }
.lg-empty-say span { display: block; text-wrap: balance; } /* one phrase per line: no break inside "보여드려요" */
.lg-empty-btns { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-8); }
/* 올해 도장 fold: a details card; the seal itself is .ys-* below */
.hm { padding: 0 var(--sp-8) var(--sp-4); border-radius: var(--r-lg); background: var(--surface); border: 1px solid var(--line); }
.hm > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); min-height: var(--tap); padding: 0 var(--sp-8); list-style: none; cursor: pointer; font-size: var(--fs-base); font-weight: 600; }
.hm > summary::-webkit-details-marker { display: none; }
.hm > summary::after { content: ""; flex: none; width: 9px; height: 9px; margin: -4px var(--sp-4) 0 var(--sp-2); border: solid var(--accent); border-width: 0 2px 2px 0; transform: rotate(45deg); transition: transform var(--dur-ui) var(--ease-out); }
.hm[open] > summary::after { transform: translateY(5px) rotate(-135deg); }
.hm > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.hm-sum { margin-left: auto; font-size: var(--fs-sm); font-weight: 500; color: var(--muted); }
/* month calendar: 일~토, cells at least 44px; a record day carries the 해벽 mark as an ink stamp (+N when 2+), today a --fg border, the picked day an accent ring + tint */
.cal { padding: var(--sp-8) var(--sp-8) var(--sp-12); border-radius: var(--r-lg); background: var(--surface); border: 1px solid var(--line); }
.cal-head { display: flex; align-items: center; gap: var(--sp-4); }
.cal-head h3 { flex: 1; text-align: center; font-size: var(--fs-base); }
.cal-nav, .cal-today { min-width: var(--tap); min-height: var(--tap); border: 0; border-radius: var(--r-md); background: none; color: var(--fg); font-size: var(--fs-lg); line-height: 1; }
.cal-today { padding: 0 var(--sp-12); font-size: var(--fs-sm); font-weight: 600; color: var(--accent); white-space: nowrap; }
.cal-legend { margin: var(--sp-8) var(--sp-4) 0; text-align: right; font-size: var(--fs-xs); color: var(--muted); }
.cal-share { display: block; margin: var(--sp-8) auto 0; min-height: var(--tap); padding: 0 var(--sp-16); border: 0; background: none; color: var(--accent); font: inherit; font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; cursor: pointer; }
.ms-prev { display: grid; place-items: center; margin: var(--sp-4) 0 var(--sp-12); }
.ms-hint { text-align: center; }
.ms-prev canvas { width: auto; height: auto; max-width: min(72vw, 300px); max-height: 40vh; border-radius: var(--r-8); background: #17191c; box-shadow: var(--shadow-pop); } /* the picture keeps its own shape (4:5 or 9:16) */
.ms-say:empty { display: none; }
.ms-say { margin-top: var(--sp-4); text-align: center; }
.ps-tools { display: flex; align-items: center; gap: var(--sp-8); margin-top: var(--sp-8); }
.ps-dome-why[hidden], .ps-tools[hidden], .ps-again[hidden], .ps-zoom[hidden], .ps-pick[hidden], .ps-line[hidden] { display: none; }
.ps-ratio { flex: 1 1 0; min-width: 0; }
html[data-text] .ps-tools { flex-wrap: wrap; }
html[data-text] .ps-ratio { flex-basis: 100%; } /* 큰 글씨: 세그먼트가 두 줄로 쌓이면 `해의 길`은 아래 줄로 */
.ps-tools .sh-toggle, .ps-actions .sh-toggle, .ps-zoom .sh-toggle { padding: 0 var(--sp-12); font-size: var(--fs-sm); white-space: nowrap; }
.ps-tools .sh-toggle::before { content: "✓"; content: "✓" / ""; margin-right: var(--sp-2); visibility: hidden; } /* the check's room is kept while it is off, so the toggle does not grow when it is turned on */
.ps-tools .sh-toggle[aria-pressed="true"]::before { visibility: visible; }
.ps-tools .sh-toggle:disabled, .ps-actions .sh-toggle:disabled, .ps-zoom .sh-toggle:disabled { opacity: .45; cursor: default; }
.ps-line { display: block; width: 100%; box-sizing: border-box; min-height: var(--tap); margin: 0 0 var(--sp-8); padding: 0 var(--sp-12); border: 1px solid var(--line); border-radius: var(--r-8); background: var(--surface); color: var(--fg); font: inherit; }
.ps-line:focus-visible, #ps-canvas:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* the camera floats on the card: choosing the photo is about the card, so it sits on it, in a white pill like the list's photo chips */
.ps-prev { position: relative; width: fit-content; margin-inline: auto; }
.ps-pick { position: absolute; right: var(--sp-8); bottom: var(--sp-8); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--glass-edge); color: var(--fg-on-white); }
.ps-pick:focus-visible { outline-offset: 2px; }
.ps-actions .sh-toggle { flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-8); font-size: var(--fs-md); }
.ps-actions .sh-toggle svg { width: var(--icon-sm); height: var(--icon-sm); flex: none; }
.ps-share:not(:disabled) { background: var(--accent); border-color: var(--accent); color: var(--on-accent); } /* sharing is what the sheet is for; saving is the same button in outline */
/* the card keeps its own shape (4:5 or 9:16): size it by what fits, never by a fixed ratio */
#ps-canvas, #ps-img { width: auto; height: auto; aspect-ratio: auto; max-width: min(72vw, 300px); max-height: 40vh; border-radius: var(--r-8); background: #17191c; box-shadow: var(--shadow-pop); }
#ps-canvas.can-drag { touch-action: none; cursor: grab; } /* only with a photo: without one the sheet may scroll over the card */
#ps-canvas.dragging { cursor: grabbing; }
.ps-zoom { display: flex; align-items: center; gap: var(--sp-8); margin-bottom: var(--sp-8); }
.ps-zoom label { font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; }
.ps-zoom input[type="range"] { flex: 1 1 auto; min-width: 0; min-height: var(--tap); accent-color: var(--accent); }
.ps-actions { display: flex; align-items: center; gap: var(--sp-8); margin-bottom: var(--sp-4); }
/* 오늘의 해벽 in the 기록 rows: a thumbnail when the card is made, a quiet link like 삭제 when not, and for today's newest row without a card a
   full-width line under it. No pill: every other button of a row is plain text. */
.lg-card, .lg-card-link { flex: none; min-width: var(--tap); min-height: var(--tap); border: 0; background: none; font: inherit; }
.lg-card { display: grid; place-items: center; padding: 0 var(--sp-4); }
.lg-card-img { display: block; height: 53px; width: auto; border-radius: 4px; box-shadow: 0 0 0 1px var(--line); }
.lg-card-link { padding: 0 var(--sp-8); color: var(--accent); font-size: var(--fs-sm); font-weight: 500; white-space: nowrap; }
.lg-has-cta { flex-wrap: wrap; }
.lg-cta { flex: 1 1 100%; white-space: nowrap; display: flex; align-items: center; gap: var(--sp-8); min-height: var(--tap); margin: 0 var(--sp-12) var(--sp-12); padding: 0 var(--sp-12); border: 1px dashed var(--accent); border-radius: var(--r-8); background: var(--accent-soft); color: var(--accent); font: inherit; font-size: var(--fs-base); font-weight: 600; text-align: left; }
.lg-cta-go { margin-left: auto; font-weight: 400; }
.lg-card:active, .lg-card-link:active, .lg-cta:active { background: var(--sunken); }
.lg-card:focus-visible, .lg-card-link:focus-visible, .lg-cta:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* the strip: the cards made so far, newest first, one row you swipe */
.pstrip { margin-top: var(--sp-16); }
.pstrip h3 { margin: 0 0 var(--sp-8); font-size: var(--fs-base); }
.pstrip h3 span { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); }
.pstrip-list { list-style: none; display: flex; gap: var(--sp-8); margin: 0; padding: var(--sp-4); overflow-x: auto; overscroll-behavior-x: contain; }
.pstrip-item { display: grid; gap: var(--sp-4); justify-items: start; width: min-content; min-width: var(--tap); padding: 0; border: 0; background: none; color: var(--fg); font: inherit; text-align: left; }
.pstrip-img { display: block; height: 96px; width: auto; border-radius: 6px; box-shadow: 0 0 0 1px var(--line); }
.pstrip-cap { width: 0; min-width: 100%; font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pstrip-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cal-sum { margin: var(--sp-2) 0 var(--sp-8); text-align: center; font-size: var(--fs-sm); color: var(--muted); }
.cal-grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
.cal-grid th { padding: var(--sp-4) 0; font-size: var(--fs-xs); font-weight: 600; color: var(--muted); }
.cal-grid td { padding: var(--sp-2); text-align: center; }
.cal-day {
  position: relative; display: grid; place-items: center; align-content: center; gap: 1px; width: 100%; min-height: max(44px, 2.9rem); padding: var(--sp-2) 0;
  border: 1px solid transparent; border-radius: var(--r-md); background: none; color: var(--fg); font-size: var(--fs-sm); line-height: 1.1;
}
.cal-day.future { color: var(--muted); }
.cal-n { font-weight: 600; }
.cal-plan { position: absolute; left: 50%; bottom: 3px; width: 6px; height: 6px; margin-left: -3px; border-radius: 50%; background: var(--accent); } /* 운동 예정: information, not decoration; the accent, never the sun colour */
.lg-plan { margin: 0 0 var(--sp-8); color: var(--accent); font-size: var(--fs-sm); font-weight: 600; }
.lg-plan-n { white-space: nowrap; } /* a wall's name is not broken across lines */
.cal-badge { position: absolute; bottom: 1px; right: 1px; z-index: 2; min-width: 15px; padding: 0 3px; border-radius: var(--r-pill); background: var(--fg); color: var(--bg); font-size: 13px; font-weight: 700; line-height: 15px; }
.cal-day[aria-current="date"] { border: 1.5px solid var(--muted); }
.cal-day:has(.cal-stamp) .cal-n { visibility: hidden; } /* a stamped day shows the stamp only, whatever the artwork lets through */
td[aria-selected="true"] > .cal-day { background: color-mix(in srgb, var(--open) 14%, transparent); outline: 2px solid var(--fg); outline-offset: 2px; }
/* the stamp: the logo file (or the wall's own, via --stamp-src from src/stamp.js) as a one-colour mask in the --open ink; the calendar's stamp is pressed over the day number and covers it (the button's aria-label carries the date) */
.stamp { display: block; background: var(--open); -webkit-mask: var(--stamp-src, url(assets/hinoae-mark.svg)) center / contain no-repeat; mask: var(--stamp-src, url(assets/hinoae-mark.svg)) center / contain no-repeat; }
.cal-stamp { position: absolute; z-index: 2; pointer-events: none; left: 50%; top: 50%; width: 68%; max-width: 42px; aspect-ratio: 1; margin: calc(max(-21px, -34%)) 0 0 calc(max(-21px, -34%)); }
.cal-stamp.stamp-in { animation: stamp-in 120ms var(--ease-out) both; }
@keyframes stamp-in { from { transform: scale(1.15); } to { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .cal-stamp.stamp-in { animation: none; } }
.cal-day .cal-n { position: relative; z-index: 1; }
.rec-stamp { position: relative; flex: none; align-self: center; width: 32px; height: 32px; margin: 0 0 0 var(--sp-12); }
/* the record's seal: mark in a rim; a 2nd rim = first visit to the wall; the sun dot rides the rim (filled sunny, hollow shade) */
.seal { box-sizing: border-box; border-radius: 50%; } /* the emblem's own ring is the rim */
.seal.first { box-shadow: 0 0 0 1.5px var(--bg), 0 0 0 3px var(--open); } /* a second rim outside the emblem's */
.seal > .stamp { position: absolute; inset: 0; }
.seal > .sun { position: absolute; width: 22%; height: 22%; min-width: 7px; min-height: 7px; transform: translate(-50%, -50%); border-radius: 50%; border: 1.5px solid var(--open); }
.seal > .sun.lit { background: var(--open); box-shadow: 0 0 0 2px var(--bg); }
.seal > .sun.shade { background: var(--bg); }
.cal-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.lg-band { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-4) var(--sp-16); margin: 0; padding: var(--sp-4) 0; } /* 기록 요약: 큰 숫자 칸 셋(지표 카드)이 아니라 한 줄의 사실. 숫자가 먼저, 이름이 뒤 */
.lg-band > div { display: flex; align-items: baseline; gap: var(--sp-4); min-width: 0; }
.lg-band dd { order: -1; margin: 0; font-size: var(--fs-md); font-weight: 700; font-variant-numeric: tabular-nums; }
.lg-band dt { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); white-space: nowrap; }
.lg-day + .lg-walls { margin-top: var(--sp-16); }
.lg-walls h3 { font-size: var(--fs-base); }
.lg-walls ul { list-style: none; margin: var(--sp-4) 0 0; padding: 0; border-top: 1px solid var(--hair); }
.lg-walls li { border-bottom: 1px solid var(--hair); }
.lg-wrow { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-8); width: 100%; padding: var(--sp-12) 0; background: none; border: 0; font: inherit; color: inherit; text-align: left; }
.lg-wsub { flex: none; font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; }
.cal-hint { margin: var(--sp-4) var(--sp-4) 0; text-align: center; }
.lg-day h3 { font-size: var(--fs-base); outline-offset: 2px; }
.lg-day h3 span { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); }
.lg-recs { list-style: none; margin: var(--sp-8) 0 0; padding: 0; border-block: 1px solid var(--line); background: var(--surface); }
.lg-recs li { display: flex; align-items: stretch; border-top: 1px solid var(--hair); }
.lg-recs li:first-child { border-top: 0; }
.lg-open { flex: 1; min-width: 0; display: grid; gap: 1px; min-height: var(--tap); padding: var(--sp-12) var(--sp-12); border: 0; background: none; color: var(--fg); font: inherit; text-align: left; }
.lg-name { font-weight: 600; min-width: 0; overflow-wrap: break-word; }
.lg-region { font-size: var(--fs-xs); color: var(--muted); }
.lg-memo { font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* a record's 완등 / 시도 lines under its wall, and the year's 완등 per grade */
.lg-gr { font-size: var(--fs-sm); }
.lg-gr.send { font-weight: 600; }
.lg-gr.try { color: var(--muted); }
.lg-gy { margin-top: var(--sp-16); }
.lg-gy h3 { margin: 0 0 var(--sp-8); font-size: var(--fs-md); }
.gy-list { list-style: none; margin: 0; padding: 0; }
.gy-list li { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) 2.25rem; align-items: center; gap: var(--sp-8); min-height: 28px; font-size: var(--fs-sm); }
.gy-g { color: var(--muted); }
.gy-trk { display: block; height: 10px; }
.gy-bar { display: block; height: 10px; border-radius: var(--r-xs); background: var(--line-strong); }
.gy-n { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.lg-del { flex: none; min-width: var(--tap); min-height: var(--tap); padding: 0 var(--sp-12); border: 0; background: none; color: var(--muted); font-size: var(--fs-sm); font-weight: 500; white-space: nowrap; } /* quiet: not as loud as the wall's name beside it */
.lg-open:active, .lg-del:active, .cal-nav:active, .cal-today:active, .cal-day:active { background: var(--sunken); }
.lg-open:focus-visible, .lg-del:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.lg-day .sh-hint { margin-top: var(--sp-8); }

/* ---- toast: a line at the foot, above the home indicator; 실행 취소 inside ---- */
.toast {
  position: fixed; left: 16px; right: 16px; bottom: calc(16px + max(var(--tabbar-h, 0px), env(safe-area-inset-bottom))); z-index: var(--z-toast); max-width: 560px; margin: 0 auto;
  display: flex; align-items: center; gap: var(--sp-8); padding: var(--sp-8) var(--sp-8) var(--sp-8) var(--sp-16); border-radius: var(--r-base); background: var(--fg); color: var(--bg);
  font-size: var(--fs-sm); font-weight: 600; box-shadow: var(--shadow-float);
  top: auto; width: auto; height: auto; border: 0; overflow: visible; /* it is a popover (log-view.js): drop the UA box */
  opacity: 0; transform: translateY(8px); pointer-events: none;
  transition: opacity var(--dur-ui) var(--ease-out), transform var(--dur-ui) var(--ease-out);
}
.toast.on { opacity: 1; transform: none; pointer-events: auto; }
.toast p { flex: 1; min-height: var(--tap); display: flex; align-items: center; }
#toast-act { flex: none; min-height: var(--tap); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-md); background: none; color: var(--bg); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
/* two actions do not fit beside the words on a phone: the words take the first row, the two buttons the second, at the right */
.toast:has(#toast-act2:not([hidden])) { flex-wrap: wrap; }
.toast:has(#toast-act2:not([hidden])) p { flex: 1 1 100%; min-height: 0; padding: var(--sp-8) var(--sp-12) 0 0; }
.toast:has(#toast-act2:not([hidden])) #toast-act { margin-left: auto; }
#toast-act2 { flex: none; min-height: var(--tap); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-md); background: none; color: var(--bg); font-weight: 600; white-space: nowrap; }
#toast-act:focus-visible, #toast-act2:focus-visible { outline: 2px solid var(--bg); outline-offset: -2px; }
@media (prefers-reduced-motion: reduce) { .toast { transition: none; transform: none; } }
@media (hover: hover) and (pointer: fine) { .lg-open:hover, .cal-day:hover, .cal-nav:hover { background: color-mix(in srgb, var(--fg) 5%, transparent); } }

/* 같이 가요: the share menu, the invite sheet, and the banner an invite link opens with. Every control is --tap high. */
.sm-wall { margin: 0; padding: 0 0 var(--sp-8); color: var(--muted); font-size: var(--fs-sm); min-width: 0; overflow-wrap: break-word; }
.inv-when { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-12); }
.inv-field { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; margin-top: var(--sp-12); }
.inv-when .inv-field { margin-top: 0; }
.inv-count { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-8); }
.inv-kind { display: flex; border: 1px solid var(--line-strong); border-radius: var(--r-md); overflow: hidden; }
.inv-kind button { min-height: var(--tap); padding: 0 var(--sp-16); border: 0; background: var(--surface); color: var(--fg); font: inherit; font-weight: 600; white-space: nowrap; }
.inv-kind button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.inv-field input, .inv-field select { width: 100%; min-height: var(--tap); padding: 0 var(--sp-12); border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface); color: var(--fg); font: inherit; }
.inv-check { min-height: 1.4em; margin: 0; padding: var(--sp-8) 0; font-size: var(--fs-sm); }
.inv-alt { min-height: var(--tap); padding: 0 var(--sp-4); border: 0; background: none; color: var(--accent); font: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.inv-tags { clear: both; display: flex; flex-wrap: wrap; gap: var(--sp-8); } /* the legend floats in a .sh-row: start below it */
.inv-pic-box { position: relative; width: min(540px, 100%); }
.inv-pic-box img { transition: opacity 0.15s; }
.inv-pic.stale img { opacity: 0.4; }
.inv-pic-save { position: absolute; right: 10px; bottom: 10px; display: grid; place-items: center; width: var(--tap); height: var(--tap); border: 0; border-radius: 50%; background: rgba(0, 0, 0, 0.6); color: var(--on-photo); }
.inv-preview { margin: var(--sp-8) 0 0; padding: var(--sp-12) var(--sp-12); border-radius: var(--r-md); background: var(--sunken); font: inherit; font-size: var(--fs-sm); white-space: pre-wrap; min-width: 0; overflow-wrap: break-word; }
.inv-say { min-height: 1.4em; margin: 0; padding-top: var(--sp-8); color: var(--accent); font-size: var(--fs-sm); font-weight: 600; }
.inv-actions { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--sp-8); }
.inv-send, .inv-copy, .inv-image { min-height: var(--tap); border-radius: var(--r-base); font: inherit; font-weight: 700; }
.inv-send { display: block; width: 100%; border: 0; background: var(--accent); color: var(--on-accent); }
.inv-copy, .inv-image { border: 1px solid var(--line-strong); background: transparent; color: var(--fg); white-space: nowrap; }
.inv-why { margin: var(--sp-8) 0 0; }
.inv-why[hidden] { display: none; }
.inv-why + .inv-actions { margin-top: var(--sp-8); }
.inv-kakao[aria-disabled="true"] { opacity: 0.5; }
.inv-kakao { display: block; width: 100%; margin-top: var(--sp-8); }
.inv-kakao-note { margin: var(--sp-8) 0 0; font-size: var(--fs-sm); }
.inv-link-hint { margin-top: var(--sp-8); font-size: var(--fs-sm); }
.inv-pic { margin: var(--sp-12) 0 0; }
.inv-pic[hidden] { display: none; }
.inv-pic img { display: block; width: min(540px, 100%); height: auto; border: 1px solid var(--line); border-radius: var(--r-md); }
.inv-pic figcaption { margin-top: var(--sp-8); font-size: var(--fs-sm); color: var(--muted); text-wrap: pretty; }
:is(.inv-kind button, .inv-alt, .inv-send, .inv-copy, .inv-image, .ib-close, .ib-again, .inv-field input, .inv-field select):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.invite-banner { margin: var(--sp-12) 0 0; padding: var(--sp-12) var(--sp-16) var(--sp-4); border: 1px solid var(--accent); border-radius: var(--r-base); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.invite-banner[hidden] { display: none; }
.ib-title { margin: 0; font-weight: 700; color: var(--accent); }
.ib-meta { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); }
.k-past { background: var(--gone); box-shadow: none; }
/* 맨 위로: shows after a screen of scrolling, so the filters are one tap away from the bottom of a long list */
.to-top { position: fixed; right: var(--sp-16); bottom: calc(var(--sp-16) + max(var(--tabbar-h, 0px), env(safe-area-inset-bottom))); z-index: var(--z-to-top); display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; border: 1px solid var(--line-strong); border-radius: 50%; background: var(--surface); color: var(--fg); box-shadow: var(--shadow-float); cursor: pointer; } /* right edge, just above the tab bar: clear of the browser's own centred scroll arrows */
.to-top[hidden] { display: none; }
.to-top svg { width: 22px; height: 22px; }
.to-top:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.howto-more > summary { display: flex; align-items: center; min-height: var(--tap); color: var(--accent); font-weight: 600; cursor: pointer; } /* the rest of the guide: folded for a first visit, open when asked with ? */
.howto-more > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
#howto .ab-sec ul.key { display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-16); padding-left: 0; list-style: none; } /* the icon and bar keys run along a line, not down the sheet */
.howto-more h3 { margin-top: var(--sp-8); }
.ib-demo { margin: var(--sp-8) 0 var(--sp-4); } /* a real 가로 막대, drawn with the list rows' own classes */
.ib-demo .bar { margin-top: var(--sp-4); }
.ib-cap { display: flex; font-size: var(--fs-xs); color: var(--muted); } .ib-cap > span { flex: 1 1 50%; text-align: center; }
.ib-note { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); min-width: 0; overflow-wrap: break-word; }
.ib-from { color: var(--muted); font-size: var(--fs-xs); }
.ib-again { min-height: var(--tap); margin: var(--sp-4) var(--sp-12) 0 0; padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-base); background: var(--surface); color: var(--fg); font: inherit; font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; }
.ib-again[hidden] { display: none; }
.ib-close { min-height: var(--tap); margin-left: -2px; padding: 0 var(--sp-2); border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-sm); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
div.sh-row.inv-prev { display: block; } /* (a div.sh-row is a flex row elsewhere; this one stacks the label, the text and the hint) */
.inv-spin { display: inline-block; width: 1.1em; height: 1.1em; vertical-align: -0.2em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; }
@media (prefers-reduced-motion: no-preference) { .inv-spin { animation: inv-spin 800ms linear infinite; } }
@keyframes inv-spin { to { transform: rotate(360deg); } }

/* loading screen: the vertical lockup (light or dark) on the app background until the first list is drawn */
#boot { position: fixed; inset: 0; z-index: var(--z-boot); display: grid; place-items: center; background: var(--logo-paper); transition: opacity var(--dur-ui) var(--ease-out); animation: boot-out 0s 8s forwards; }
#boot img { width: min(58vw, 290px); height: auto; transform: translateY(14.7%); animation: boot-in 200ms var(--ease-out) both; } /* smaller and centred, like the OS start screen's mark, and shifted so the mark (not the whole lockup) sits at screen centre where the OS splash draws it; it fades in rather than appearing */
#boot .dk { display: none; }
:root[data-theme="dark"] #boot { background: var(--bg); }
:root[data-theme="dark"] #boot .lt { display: none; }
:root[data-theme="dark"] #boot .dk { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #boot { background: var(--bg); }
  :root:not([data-theme="light"]) #boot .lt { display: none; }
  :root:not([data-theme="light"]) #boot .dk { display: block; }
}
#boot.done { opacity: 0; pointer-events: none; }
@keyframes boot-in { from { opacity: 0; } }
@keyframes boot-out { to { opacity: 0; visibility: hidden; pointer-events: none; } } /* never trap the page if the script fails */
@media (prefers-reduced-motion: reduce) { #boot { transition: none; } #boot img { animation: none; } }

/* 한 줄 타임라인 (src/board-view.js): a feed of avatar + name + time + text, a pill composer, ghost action chips */
.bd-box { margin-top: var(--sp-12); padding-top: var(--sp-12); border-top: 1px solid var(--line); }
.bd-title { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.bd-list { list-style: none; margin: var(--sp-8) 0 0; padding: 0; }
/* editorial: no boxes, the type and the space do the work; a name carries one small hold-coloured dot */
.bd-post { display: grid; grid-template-columns: calc(var(--fs-xs) * 4.2) minmax(0, 1fr); column-gap: var(--sp-12); padding: var(--sp-12) 0; }
.bd-time { white-space: nowrap; padding-top: 3px; text-align: right; font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.bd-reply { display: block; }
.bd-full .bd-old { background: linear-gradient(90deg, color-mix(in srgb, var(--fg) 22%, transparent) 0 3px, transparent 3px); margin-left: calc(var(--sp-16) * -1); padding-left: var(--sp-16); } /* 응달: the slab's shade runs down the older posts */
.bd-day { display: flex; align-items: center; gap: var(--sp-12); margin: var(--sp-24) 0 var(--sp-4); font-size: var(--fs-sm); font-weight: 800; letter-spacing: .02em; }
.bd-day::before { content: ""; width: 14px; height: 14px; border-radius: 50%; background: var(--sun-disc); }
.bd-day.bd-shade::before { border-radius: 0; background: color-mix(in srgb, var(--fg) 30%, transparent); clip-path: polygon(0 0, 100% 0, 100% 100%, 40% 100%); }
.bd-day::after { content: ""; flex: 1; height: 1px; background: var(--line); }
/* the full view's header: the logo's sun and slab */
.bd-hero { position: relative; order: -2; overflow: hidden; margin: 0 calc(var(--sp-16) * -1); padding: var(--sp-24) var(--sp-16) var(--sp-16); background: color-mix(in srgb, var(--sun-disc) 22%, var(--bg)); }
:root[data-theme="dark"] .bd-hero { background: color-mix(in srgb, var(--sun-disc) 9%, var(--bg)); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .bd-hero { background: color-mix(in srgb, var(--sun-disc) 9%, var(--bg)); } }
:root[data-theme="dark"] .bd-sun { opacity: .9; }
.bd-sun { position: absolute; top: -52px; right: 36px; width: 132px; height: 132px; border-radius: 50%; background: var(--sun-disc); }
.bd-slab { position: absolute; top: 0; bottom: 0; right: 0; width: 28%; background: var(--shade-ink); clip-path: polygon(0 0, 100% 0, 100% 100%, 46% 100%); }
.bd-hero h3 { position: relative; margin: 0; font-size: var(--fs-xl); letter-spacing: -.02em; }
.bd-hero p { position: relative; margin: var(--sp-4) 0 0; color: var(--muted); font-size: var(--fs-sm); }
.bd-new { animation: bd-in var(--dur-ui) var(--ease-out); } /* a post that just arrived (board-view.js); the first load and redraws stay still */
@keyframes bd-in { from { opacity: 0; transform: translateY(6px); } }
.bd-main { min-width: 0; }
.bd-reply .bd-head { gap: var(--sp-8); }
.bd-dot { --h: 160; flex: none; width: 8px; height: 8px; border-radius: 50%; background: hsl(var(--h) 62% 50%); }
.bd-head { display: flex; align-items: center; gap: var(--sp-8); margin: 0; }
.bd-by { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); font-weight: 700; letter-spacing: -.01em; }
.bd-text { margin: var(--sp-8) 0 0; font-size: var(--fs-base); line-height: 1.6; min-width: 0; overflow-wrap: break-word; }
.bd-meta, .bd-status, .bd-count, .bd-hint { font-size: var(--fs-xs); color: var(--muted); }
.bd-meta { flex: none; margin-left: auto; font-variant-numeric: tabular-nums; }
.bd-acts { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-8) 0 0 calc(var(--sp-8) * -1); }
.bd-acts:empty { display: none; }
.bd-status:empty { display: none; }
.bd-status { margin-top: var(--sp-8); }
.bd-rep, .bd-more { padding: 0 var(--sp-8); border: 0; border-radius: var(--r-pill); background: none; color: var(--muted); font: inherit; font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; cursor: pointer; }
.bd-rep { min-height: var(--tap); }
.bd-rep:hover:not(:disabled), .bd-more:hover { background: var(--hair); color: var(--fg); }
.bd-rep:active:not(:disabled) { opacity: .6; }
.bd-rep:disabled { cursor: default; opacity: .7; }
.bd-rp { color: var(--accent); }
.bd-more { display: block; width: 100%; margin-top: var(--sp-8); min-height: var(--tap); border: 1px solid var(--line); font-size: var(--fs-sm); }
.bd-more[hidden], .bd-retry[hidden] { display: none; }
/* composer: the name above (small), then one rounded bar holding the text, its counter and a round send button */
.bd-form { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); margin-top: var(--sp-12); }
.bd-row { display: flex; gap: var(--sp-8); align-items: center; }
.bd-compose { gap: var(--sp-8); padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-8); border: 1.5px solid var(--fg); border-radius: var(--r-pill); background: var(--surface); transition: border-color var(--dur-ui, .15s), box-shadow var(--dur-ui, .15s); }
.bd-compose:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.bd-nick { flex: 0 1 5.5em; width: 5.5em; min-width: 0; min-height: var(--tap); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-pill); background: var(--hair); color: var(--fg); font: inherit; font-size: var(--fs-xs); font-weight: 600; text-overflow: ellipsis; }
.bd-nick[readonly] { color: var(--muted); }
.bd-body { flex: 1; min-width: 0; min-height: var(--tap); padding: 0; border: 0; background: none; color: var(--fg); font: inherit; }
.bd-body::placeholder, .bd-nick::placeholder { color: var(--muted); }
.bd-body:focus, .bd-nick:focus { outline: none; }
.bd-nick:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* count + the note: closed until the form is in use, so the bar is one line */
.bd-hint { display: none; margin: 0 var(--sp-12); }
.bd-form:focus-within .bd-hint { display: block; }
.bd-count { font-variant-numeric: tabular-nums; }
.bd-hp[hidden] { display: none; }
.bd-send { flex: none; display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: 50%; background: var(--accent); color: var(--on-accent); cursor: pointer; transition: opacity var(--dur-ui, .15s), transform var(--dur-ui, .15s); }
.bd-send svg { width: var(--icon-sm); height: var(--icon-sm); margin-left: var(--sp-2); }
.bd-send:active:not(:disabled) { transform: scale(.92); }
.bd-send:disabled { opacity: .35; cursor: default; }
.bd-box:focus { outline: none; }
.bd-off > :not(.bd-status) { display: none; } /* the Worker refused this wall: only the one line saying so stays */
.bd-all { color: var(--accent); font-size: var(--fs-sm); font-weight: 600; }
/* the board page: a full-height sheet; the form comes first so a long list never hides it */
.board-page { height: 100dvh; max-height: 100dvh; border-radius: 0; border: 0; }
.bp-back { margin-left: -8px; margin-right: 0; }
.bp-title { flex: 1; min-width: 0; margin-left: var(--sp-4); overflow-wrap: break-word; }
.bp-title:focus { outline: none; }
.sh-head:has(.bp-back) { justify-content: flex-start; }
/* the wall sheet: the board page's full-height dialog with a tab bar at the foot (structure only; the look is settled with the mockup) */
.wall-sheet[open] { display: flex; flex-direction: column; overflow: hidden; }
.ws-top { flex: none; padding: max(var(--sp-8), env(safe-area-inset-top)) max(var(--sp-16), env(safe-area-inset-right)) 0 max(var(--sp-16), env(safe-area-inset-left)); } /* landscape iPhone: the notch never covers ← 닫기 */
/* the panes sit in one row; a swipe snaps from pane to pane, and each pane scrolls up and down by itself */
.ws-body { flex: 1; min-height: 0; display: flex; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior: contain; }
.ws-body::-webkit-scrollbar { display: none; }
.ws-panel { position: relative; /* the sr-only lists inside anchor here, not on the overflow:hidden dialog (they stretched its scroll area) */ flex: 0 0 100%; min-width: 0; overflow-y: auto; overscroll-behavior-y: contain; /* y only: "contain" on both axes stops a sideways swipe from passing to .ws-body, so no tab ever changed by swiping */ scroll-snap-align: start; scroll-snap-stop: always; padding: 0 max(var(--sp-16), env(safe-area-inset-right)) calc(var(--sp-16) + env(safe-area-inset-bottom)) max(var(--sp-16), env(safe-area-inset-left)); }
html:has(.wall-sheet[open]) { overflow: hidden; } /* the page behind the sheet stands still (and the browser's own scroll buttons have nothing to offer over it) */
.wall-sheet:has(.ws-tabs:not([hidden])) .ws-panel { padding-bottom: var(--sp-16); } /* the tab bar carries the safe-area inset, so it is not added twice */
.ws-tabs { order: 1; display: flex; flex: none; border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); background: var(--surface); }
.ws-tabs[hidden] { display: none; }
/* icon over label; the tab in view gets a pill behind its icon, and the pill follows a swipe (--on: 0 to 1, set from the scroll) */
@property --on { syntax: "<number>"; inherits: true; initial-value: 0; }
.ws-tabs [role="tab"] { flex: 1; min-height: 62px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); padding: var(--sp-4) 0 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; }
.ws-tabs [aria-selected="true"] { color: var(--fg); font-weight: 700; }
.ws-ic { display: grid; place-items: center; width: 58px; height: 30px; border-radius: var(--r-pill); background: color-mix(in srgb, var(--accent-soft) calc(var(--on) * 100%), transparent); }
.ws-ic svg { width: 22px; height: 22px; }
.ws-tabs [aria-selected="true"] .ws-ic { color: var(--accent); }
.ws-tabs [role="tab"]:active { opacity: .7; }
/* a section is a lighter panel on the sheet's backdrop: title (with 수정 요청 at its right), the check date under it, then the facts */
.wall-sheet { background: var(--bg); }
.ws-sec { position: relative; margin: 0 0 var(--sp-12); padding: var(--sp-16) var(--sp-16) var(--sp-16); border-radius: var(--r-base); background: var(--surface); }
.ws-sec.empty { border: 0; color: inherit; font-size: inherit; } /* not the page-wide .empty box: the section holds its own dotted .ws-empty */
.ws-sec-h { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-8); min-height: var(--tap); }
.ws-sec-h h3 { margin: 0; font-size: var(--fs-lg); font-weight: 700; }
.ws-chk { margin: calc(var(--sp-8) * -1) 0 var(--sp-12); color: var(--muted); font-size: var(--fs-xs); }
.ws-chk-ask { position: relative; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; } /* a word in the check-date line, not a button of its own */
.ws-chk-ask::after { content: ""; position: absolute; inset: -14px -8px; } /* taps like 44px */
.ws-chk.end { margin: var(--sp-12) 0 0; text-align: right; } /* a section's check date: bottom right of its card */
.ws-stale { margin: var(--sp-8) 0 0; color: var(--warn); font-size: var(--fs-xs); }
.ws-empty { margin-top: var(--sp-8); padding: var(--sp-12); border: 1px dashed var(--line-strong); border-radius: var(--r-base); text-align: center; color: var(--muted); }
.ws-empty p { margin: 0; }
.ws-ask.pri { background: var(--accent); color: var(--on-accent); }
.ws-ask.sub { border-color: transparent; text-decoration: underline; text-underline-offset: 3px; }
/* 시간 tab: 맞아요 / 달라요 (src/tap-view.js). Quiet neutral pills: one answer is not a guarantee, so no green. */
.ws-tap { margin-top: var(--sp-8); min-height: 7rem; }
.tap-msg { margin: 0; color: var(--muted); font-size: var(--fs-sm); }
.tap-btns { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin-top: var(--sp-8); }
.tap-btn { min-height: var(--tap); padding: 0 var(--sp-16); min-width: calc(var(--tap) * 1.4); border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: none; color: var(--fg); font: inherit; font-weight: 600; white-space: nowrap; }
.tap-btn.sub { border-color: transparent; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.tap-msg.err { color: var(--warn); font-weight: 600; }
.tap-btns:empty { display: none; }
.ws-ask { min-height: var(--tap); margin-top: var(--sp-4); padding: 0 var(--sp-16); border: 1px solid var(--accent); border-radius: var(--r-pill); background: none; color: var(--accent); font: inherit; font-weight: 600; white-space: nowrap; }
.ws-info { display: grid; gap: var(--sp-8); } /* 외벽 제원 · 시설: its lists in one card */
.ws-empty-sub { color: var(--muted); font-size: var(--fs-sm); }
/* 빈칸 채우기 (src/fill-view.js): the rows of the 이용 tab's last section; the inputs take the report sheet's field look */
.fill-sec .ws-empty-sub { margin: var(--sp-4) 0 0; }
.fill-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); padding: var(--sp-12) 0 0; margin-top: var(--sp-12); border-top: 1px solid var(--line); }
.fill-k { font-weight: 600; }
.fill-row p { margin: 0; }
.fill-form { display: flex; gap: var(--sp-8); align-items: center; }
.fill-form .ws-ask { margin-top: 0; }
.fill-in { flex: 1; min-width: 0; min-height: var(--tap); padding: 0 var(--sp-12); font: inherit; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--bg); color: var(--fg); }
.fill-msg { color: var(--warn); font-size: var(--fs-sm); }
.fill-msg:empty { display: none; }
.fill-note { color: var(--muted); font-size: var(--fs-sm); }
.fill-note:empty { display: none; }
.fill-pick { justify-self: start; margin-top: 0; }
/* 지도에서 고르기 (src/pin-picker.js): the map under a fixed cross; the sheet is the usual bottom sheet */
.pp-stage { position: relative; margin: var(--sp-8) 0; }
.pp-map { height: min(46vh, 420px); border-radius: var(--r-base); overflow: hidden; }
.pp-cross { position: absolute; inset: 0; pointer-events: none; z-index: 500; }
.pp-cross::before, .pp-cross::after { content: ""; position: absolute; background: var(--accent); box-shadow: 0 0 0 1.5px var(--bg); }
.pp-cross::before { left: 50%; top: calc(50% - 18px); width: 2px; height: 36px; transform: translateX(-1px); }
.pp-cross::after { top: 50%; left: calc(50% - 18px); height: 2px; width: 36px; transform: translateY(-1px); }
.pp-actions { display: flex; flex-wrap: wrap; gap: var(--sp-8); align-items: center; }
.pp-actions .ws-ask, .pp-actions .btn, .pp-actions .sh-close { margin-top: 0; }
.fill-state, .fill-done { color: var(--muted); font-size: var(--fs-sm); }
/* ===== wall sheet head (외벽 시트 머리; from docs/superpowers/mockups/2026-10-22-sheet-system-v2.html). Scoped to .wall-sheet.is-wall. ===== */
@property --sun-t { syntax: "<number>"; inherits: true; initial-value: .5; }
/* the head: the sun card's sky (--sc-*, from .k-lit/.k-shade/.k-night; .k-none = no sun math: the sunken paper), the name, one line, the ✓, and on its ground the logo's slab and the sun */
.k-none { --sc-sky0: var(--sunken); --sc-sky1: var(--sunken); --sc-ground: var(--line-strong); --sc-wall: var(--muted); --sc-text: var(--fg); --sc-halo: var(--sun-ui); --sc-sun: var(--sun-ui); }
.is-wall .sh-sky { --arc: 40px; --ground: 10px; --slab-h: 52px; --d-max: 24px; position: relative; isolation: isolate; flex: none; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; column-gap: var(--sp-8); min-height: 140px;
  padding: calc(var(--sp-24) + env(safe-area-inset-top)) var(--sp-8) calc(var(--ground) + var(--arc) + var(--d-max) / 2 + var(--sp-8)) var(--sp-16); /* the words stop above the sun's highest point, so the band grows with 큰 글씨 instead of colliding */
  background: linear-gradient(180deg, var(--sc-sky0), var(--sc-sky1)); color: var(--sc-text); }
.is-wall .sk-txt { min-width: 0; max-width: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-8); }
.is-wall .sk-txt > .sk-title { flex: 0 0 100%; } /* leaves the slab its corner of the ground */
.is-wall .sk-title { margin: 0; font-size: var(--fs-lg); font-weight: 700; line-height: 1.25; letter-spacing: -.02em; overflow-wrap: break-word; }
.is-wall .sk-title:focus { outline: none; }
.is-wall .sk-contact { display: flex; flex-wrap: wrap; gap: var(--sp-8); flex: 0 0 100%; margin: calc(var(--sp-2) * -1) 0 0 -2px; } /* its own line under name and region, left-aligned (the disc's 2px inset is cancelled so it lines up with the text) */
.is-wall .sk-ct { position: relative; isolation: isolate; display: inline-grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; color: #fff; text-decoration: none; font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; }
.is-wall .sk-ct::before { content: ""; position: absolute; inset: 2px; z-index: -1; border-radius: 50%; background: rgb(20 22 24 / .32); border: 1px solid rgb(255 255 255 / .28); box-shadow: 0 2px 8px rgb(0 0 0 / .2), inset 0 1px 0 rgb(255 255 255 / .25); -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%); } /* the dark glass disc of the card's 카메라·공유 (40px inside the 44px target) */
@media (prefers-reduced-transparency: reduce) { .is-wall .sk-ct::before { background: rgb(20 22 24 / .72); -webkit-backdrop-filter: none; backdrop-filter: none; } }
.is-wall .sk-ct.txt { width: auto; padding: 0 var(--sp-12); }
.is-wall .sk-ct.txt::before { border-radius: var(--r-pill); }
.is-wall .sk-ct svg { width: 22px; height: 22px; }
.is-wall .sk-ct:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; border-radius: 50%; }
.is-wall .sk-contact[hidden] { display: none; }
.is-wall .sk-sub { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-8); margin: 0; font-size: var(--fs-sm); font-weight: 500; }
.is-wall .sk-chip { display: inline-block; padding: 0 var(--sp-8); border-radius: var(--r-pill); background: color-mix(in srgb, currentColor 14%, transparent); font-size: var(--fs-xs); font-weight: 700; line-height: 1.7; white-space: nowrap; }
.is-wall .bd-hero { display: none; } /* the board's banner is the sky: the head is the same on every tab */
.is-wall .sk-act { display: flex; align-items: center; gap: var(--sp-4); margin-top: calc(-1 * var(--sp-12)); }
.is-wall .sk-rep::after { content: ""; position: absolute; inset: 0 min(0px, calc((100% - 44px) / 2)); } /* a label under 44px wide (제보) is padded out to a 44px target without moving it; one rule for the wall sheet and the 싱글피치 sheet (wall-sheet.js builds both) */
.is-wall .sk-rep { position: relative; min-height: var(--tap); margin-block: -6px; /* 44px tall target; the 12px extra is pulled back so the name line keeps its height */ padding: 0 var(--sp-8); border: 0; border-radius: var(--r-pill); background: none; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); color: inherit; font: inherit; font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; cursor: pointer; }
.is-wall .sk-ok { width: var(--tap); height: var(--tap); display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: none; color: inherit; cursor: pointer; }
.is-wall .sk-ok svg { width: 22px; height: 22px; }
.is-wall .sk-ok:active { background: color-mix(in srgb, currentColor 12%, transparent); }
.is-wall .sh-sky :focus-visible { outline-color: currentColor; } /* the page's green ring would vanish on the sky: the band's own ink */
.is-wall .sk-scene { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.is-wall .sk-ground { position: absolute; left: 0; right: 0; bottom: 0; height: var(--ground); background: var(--sc-ground); z-index: 2; }
.is-wall .sk-slab { position: absolute; right: 18%; bottom: calc(var(--ground) - 1px); height: var(--slab-h); aspect-ratio: 80 / 224; background: var(--sc-wall); clip-path: polygon(0 0, 100% 0, 100% 100%, 57.5% 100%); z-index: 1; } /* the logo's slab */
/* the sun: on a shallow arc by the viewed time (--sun-t: 0 = sunrise at the left, 1 = sunset at the right; past either end it sinks under the ground) */
.is-wall .sk-disc { --d: var(--d-max); position: absolute; z-index: 0; width: var(--d); height: var(--d); border-radius: 50%; background: var(--sc-sun); box-shadow: 0 0 0 4px color-mix(in srgb, var(--sc-halo) 40%, transparent);
  left: calc(6% + clamp(0, var(--sun-t), 1) * 88% - var(--d) / 2); bottom: calc(var(--ground) - var(--d) / 2 + sin(var(--sun-t) * 180deg) * var(--arc)); }
@supports not (bottom: calc(sin(90deg) * 1px)) { .is-wall .sk-disc { bottom: calc(var(--ground) + var(--arc) * .8 - var(--d) / 2); } }
.is-wall .k-night .sk-disc, .is-wall .k-night.sh-sky .sk-disc { --sun-t: .64; --d: calc(var(--d-max) * .75); box-shadow: 0 0 0 5px color-mix(in srgb, var(--sc-halo) 22%, transparent); } /* the moon stays put */
.is-wall .k-none .sk-disc { display: none; }
/* one moment: on open the sun rises from the horizon to where it is (once; the whole thing is off for 모션 줄이기) */
@property --sc-sky0 { syntax: "<color>"; inherits: true; initial-value: #ffffff; }
@property --sc-sky1 { syntax: "<color>"; inherits: true; initial-value: #ffffff; }
@property --sc-text { syntax: "<color>"; inherits: true; initial-value: #000000; }
@property --sc-wall { syntax: "<color>"; inherits: true; initial-value: #000000; }
@property --sc-sun { syntax: "<color>"; inherits: true; initial-value: #ff0000; }
@property --sc-halo { syntax: "<color>"; inherits: true; initial-value: #ff0000; }
@keyframes sk-rise { from { --sun-t: 0; } }
@media (prefers-reduced-motion: no-preference) { .is-wall .sh-sky.is-opening .sk-disc { animation: sk-rise 600ms var(--ease-out) both; }
  .is-wall .sk-disc { transition: --sun-t var(--dur-ui) var(--ease-out); } /* dragging the hours axis: the sun glides to the picked time */
  .is-wall .sh-sky { transition: --sc-sky0 var(--dur-ui) var(--ease-out), --sc-sky1 var(--dur-ui) var(--ease-out), --sc-text var(--dur-ui) var(--ease-out), --sc-wall var(--dur-ui) var(--ease-out), --sc-sun var(--dur-ui) var(--ease-out), --sc-halo var(--dur-ui) var(--ease-out); } /* and the sky changes colour with it */
}
/* 루트 tab: the count as bars (the .gy-* rows of the 올해 완등 block), a chip per wall section when counted by section */
.rt-chips { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin: var(--sp-8) 0; }
/* 제보 시트의 벽 고르기: 한 줄로 가로 스크롤 */
.ov-photo { position: relative; display: block; width: 100%; padding: 0; border: 0; border-radius: var(--r-base); overflow: hidden; background: var(--surface); cursor: zoom-in; }
.ov-photo img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.ov-n { position: absolute; right: var(--sp-8); bottom: var(--sp-8); padding: var(--sp-2) var(--sp-12); border-radius: var(--r-pill); background: rgb(0 0 0 / .6); color: #fff; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.rt-chips.rt-scroll { flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity; padding-bottom: var(--sp-4); }
.rt-scroll .rt-chip { flex: none; scroll-snap-align: start; }
.rt-chip.dashed { border-style: dashed; }
.rt-n { font-weight: 700; }
.rt-add { display: flex; gap: var(--sp-8); margin: var(--sp-8) 0; }
.rt-add input { flex: 1; min-width: 0; }
.rp-extra { min-width: 0; } /* a grid item: without this the chip row widens the whole form instead of scrolling */
.rt-chip { min-height: var(--tap); padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--surface); color: var(--fg); font: inherit; font-size: var(--fs-sm); white-space: nowrap; }
.rt-chip[aria-pressed="true"] { border-color: var(--accent); background: var(--accent); color: var(--on-accent); font-weight: 700; }
.rt-bars.stale .gy-bar { opacity: .55; } /* only the bars fade: the labels and numbers keep their contrast */
.rt-total { margin: var(--sp-8) 0 0; color: var(--muted); font-size: var(--fs-sm); }
.gy-list li.mine .gy-g { color: var(--fg); font-weight: 700; } /* the rows inside 내 그레이드 */
.gy-list li.mine .gy-bar { background: var(--accent); }
.pf-grade { clear: both; display: flex; align-items: center; gap: var(--sp-8); }
.pf-grade select { min-height: var(--tap); padding: 0 var(--sp-12); border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface); color: var(--fg); font: inherit; }
.pf-grade select:disabled { color: var(--muted); }
/* 내 정보·조건 시트: 외곽선 대신 --sunken 면(정렬·지역 칩과 같은 말). 켜진 토글만 색으로 채운다 */
#profile .sh-toggle:not([aria-pressed="true"]), #conditions .sh-toggle:not([aria-pressed="true"]) { background: var(--sunken); border-color: transparent; }
#profile .rp-field input, #profile .pf-grade select { background: var(--sunken); border-color: transparent; }
#profile-title:focus-visible { outline: none; } /* 시트가 제목에 포커스를 두고 열린다: 키보드로 고른 것이 아니라 링을 그리지 않는다 */
@media (hover: hover) and (pointer: fine) { #profile .sh-toggle:not([aria-pressed="true"]):hover, #conditions .sh-toggle:not([aria-pressed="true"]):hover { background: var(--line); border-color: transparent; } }
.bd-thread { margin: var(--sp-8) 0 0 3px; padding: var(--sp-2) 0 var(--sp-4) var(--sp-16); border-left: 2px solid var(--line); }
.bd-replies { list-style: none; margin: 0; padding: 0; }
.bd-reply { padding: var(--sp-12) 0 var(--sp-8); }
.bd-reply + .bd-reply { border-top: 0; }
.bd-thread .bd-compose { background: var(--surface); }
html[data-text] .bd-compose { flex-wrap: wrap; border-radius: var(--r-lg); } /* 큰 글씨: 닉네임 한 줄, 입력칸 한 줄 */
html[data-text] .bd-nick { flex: 1 1 100%; width: auto; min-height: 36px; }
html[data-text] .bd-body { flex: 1; }
.bd-rp[aria-expanded="true"] { background: var(--accent-soft); color: var(--fg); }
.bd-full { display: flex; flex-direction: column; margin-top: 0; padding-top: 0; border-top: 0; }
.bd-full .bd-form { order: -1; margin: var(--sp-12) 0 var(--sp-4); padding: 0; }
.bd-full .bd-form::before { content: none; }

/* 클라이머 유형 테스트 (src/climber-view.js): the intro / friend card, the sheet's question and result (the result is one 도감 plate) */
.climber-card[hidden] { display: none; }
.climber-card { overflow: hidden; margin: var(--sp-12) 0 0; border: 2px solid var(--fg); border-radius: var(--r-base); background: var(--plate); }
/* the entry card: one wall (bolt holes, the sun, the slab's shade) with the characters standing on it, the words and one button; × sits in the top corner */
.cc-wall { position: relative; isolation: isolate; height: 132px; overflow: hidden; background-color: color-mix(in srgb, var(--tint, #dfe7bf) var(--tint-mix, 55%), var(--plate)); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .cc-wall { --tint-mix: 30%; } }
:root[data-theme="dark"] .cc-wall { --tint-mix: 30%; }
.cc-wall::before { content: ""; position: absolute; inset: 0; z-index: 0; background-image: radial-gradient(circle, color-mix(in srgb, var(--fg) 14%, transparent) 2px, transparent 2.6px); background-size: 26px 26px; background-position: 13px 13px; }
.cc-sun { position: absolute; z-index: 1; top: -46px; right: 58px; width: 120px; height: 120px; border-radius: 50%; background: var(--sun-disc); }
.cc-shade { position: absolute; z-index: 2; top: 0; bottom: 0; right: 0; width: 38%; background: var(--shade-ink); clip-path: polygon(0 0, 100% 0, 100% 100%, 42% 100%); }
.cc-cast { position: absolute; z-index: 3; left: 0; right: 0; bottom: -6px; display: flex; justify-content: center; }
.cc-cast img { width: 92px; height: 92px; margin: 0 -9px; filter: drop-shadow(2px 0 0 var(--sticker)) drop-shadow(-2px 0 0 var(--sticker)) drop-shadow(0 2px 0 var(--sticker)) drop-shadow(0 -2px 0 var(--sticker)) drop-shadow(2px 3px 0 color-mix(in srgb, var(--fg) 26%, transparent)); }
.cc-cast img:nth-child(1) { transform: translateY(6px) rotate(-5deg); }
.cc-cast img:nth-child(2) { z-index: 1; transform: translateY(-4px) rotate(3deg); }
.cc-cast img:nth-child(3) { transform: translateY(2px) rotate(-3deg); }
.cc-cast img:nth-child(4) { transform: translateY(8px) rotate(5deg); }
.climber-card.friend .cc-cast { justify-content: flex-start; padding-left: var(--sp-24); }
.climber-card.friend .cc-cast img { width: 124px; height: 124px; margin: 0; transform: none; }
.climber-card.friend .cc-sun { right: auto; left: 38px; top: -40px; }
.climber-card.friend .cc-shade { width: 44%; }
.cc-x { position: absolute; z-index: 5; top: var(--sp-2); right: var(--sp-2); display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; border: 0; background: none; color: var(--fg); cursor: pointer; }
.cc-x::before, .cc-x::after { content: ""; grid-area: 1 / 1; }
.cc-x::before { width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--plate) 88%, transparent); }
.cc-x::after { width: 14px; height: 14px; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M5 5l14 14M19 5L5 19'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M5 5l14 14M19 5L5 19'/%3E%3C/svg%3E") center / contain no-repeat; }
.cc-body { padding: var(--sp-16) var(--sp-16) var(--sp-16); }
.cc-title { margin: 0; font-size: var(--fs-lg); font-weight: 700; line-height: 1.25; letter-spacing: -.03em; text-wrap: balance; }
.cc-sub { margin: var(--sp-4) 0 var(--sp-12); font-size: var(--fs-sm); color: var(--muted); text-wrap: balance; }
.cc-go { display: block; width: 100%; min-height: var(--tap); padding: 0 var(--sp-16); border: 0; border-radius: var(--r-pill); background: var(--sun-disc); color: #17191c; font: inherit; font-size: var(--fs-base); font-weight: 700; white-space: nowrap; cursor: pointer; box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .16); }
:is(.cc-go, .cc-x):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cr-btns button { min-height: var(--tap); padding: 0 var(--sp-16); border: 1px solid var(--line-strong); border-radius: var(--r-base); background: var(--surface); color: var(--fg); font: inherit; font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; cursor: pointer; }
:is(.cc-go, .cc-x, .cr-btns button, .cq-hold) { transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out), border-color var(--dur-press) var(--ease-out); }
:is(.cc-go, .cc-x, .cr-btns button, .cq-hold):active { transform: scale(.97); }
.cr-btns .cr-list { border-color: var(--fg); background: var(--fg); color: var(--bg); }
.cr-share .cr-kakao { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
.cr-btns button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.climber-q { min-width: 0; margin: 0; padding: 0; border: 0; }
.climber-q:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; } /* the question takes focus when it appears: keep it visible for keyboard users */
/* the question sheet: ← and × at the ends, the logo and the title between, a row of bolts (done / here / to come) with the count at its end, then two holds */
#climber-sheet:has(#climberQuiz:not([hidden])) :is(.sh-head, .sh-close) { display: none; }
.cq-head { display: grid; grid-template-columns: var(--tap) minmax(0, 1fr) var(--tap); align-items: center; margin: calc(var(--sp-4) * -1) calc(var(--sp-8) * -1) var(--sp-4); }
.cq-ic { display: grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: 50%; background: none; color: var(--fg); cursor: pointer; }
.cq-ic.gone { visibility: hidden; }
.cq-ic::before { content: ""; width: 22px; height: 22px; background: currentColor; -webkit-mask: var(--ic) center / contain no-repeat; mask: var(--ic) center / contain no-repeat; }
.cq-ic.back { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 5l-7 7 7 7'/%3E%3C/svg%3E"); }
.cq-ic.x { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E"); }
.cq-ic:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cq-brand { display: flex; align-items: center; justify-content: center; gap: var(--sp-8); font-weight: 700; letter-spacing: -.02em; }
.cq-brand::before { content: ""; flex: none; width: 34px; height: 34px; background: currentColor; -webkit-mask: url(assets/hinoae-mark.svg) center / contain no-repeat; mask: url(assets/hinoae-mark.svg) center / contain no-repeat; }
.cq-prog { display: flex; align-items: center; gap: var(--sp-12); margin: 0 0 var(--sp-16); }
.cq-bolts { display: flex; flex: 1 1 auto; justify-content: space-between; min-width: 0; }
.cq-bolts i, .cq-hold::before { position: relative; border-radius: 50%; }
.cq-bolts i { width: 17px; height: 17px; box-shadow: inset 0 0 0 1.5px var(--muted); }
.cq-bolts i::after { content: ""; position: absolute; inset: 27%; clip-path: polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%); background: color-mix(in srgb, var(--muted) 55%, transparent); }
.cq-bolts i.on { background: var(--accent); box-shadow: none; }
.cq-bolts i.on::after { background: var(--on-accent); }
.cq-bolts i.here { background: var(--sun-disc); box-shadow: none; transform: scale(1.25); }
.cq-bolts i.here::after { background: #2a2d32; }
.cq-count { flex: none; font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
.cq-count b { color: var(--fg); }
.cq-opts { display: grid; grid-auto-rows: 1fr; gap: var(--sp-16); margin: 0 0 var(--sp-8); }
/* a hold: an uneven outline, a darker lip along the bottom, the bolt in it; the first statement is the sun's yellow, the second green */
.cq-hold { position: relative; display: flex; align-items: center; gap: var(--sp-12); width: 100%; min-height: calc(var(--tap) * 2); padding: var(--sp-16) var(--sp-24) var(--sp-16) var(--sp-16); border: 0; background: color-mix(in srgb, var(--hold) 30%, var(--surface)); box-shadow: inset 0 -5px 0 color-mix(in srgb, var(--hold) 45%, transparent), inset 0 0 0 1.5px color-mix(in srgb, var(--hold) 60%, var(--hold-edge)); color: var(--fg); font: inherit; font-size: var(--fs-base); line-height: 1.45; text-align: left; cursor: pointer; }
.cq-hold.a { --hold: var(--hold-a); border-radius: 62px 26px 54px 30px / 48px 30px 50px 36px; }
.cq-hold.b { --hold: var(--hold-b); border-radius: 28px 60px 32px 56px / 32px 50px 36px 48px; }
.cq-hold::before { content: ""; flex: none; width: 28px; height: 28px; background: #d8dbd4; box-shadow: inset 0 0 0 1.5px #43484a; }
.cq-hold::after { content: ""; position: absolute; left: calc(var(--sp-16) + 7px); top: 50%; width: 14px; height: 14px; transform: translateY(-50%); clip-path: polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%); background: #43484a; } /* the hexagon socket in the bolt's head */
.cq-hold[aria-pressed="true"] { background: var(--hold); box-shadow: inset 0 -5px 0 rgba(0, 0, 0, .18), inset 0 0 0 1.5px color-mix(in srgb, var(--hold) 60%, var(--hold-edge)); color: #17191c; font-weight: 700; }
.cq-hold:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.cq-title { margin: 0 0 var(--sp-16); font-size: var(--fs-xl); font-weight: 700; line-height: 1.3; letter-spacing: -.02em; text-wrap: balance; }
.climber-res { display: grid; gap: var(--sp-16); padding: var(--sp-8) 0; }
/* the plate: a double frame, FIG. n / 08, the stage, the name, the bars. The shared picture (climber-image.js) is drawn the same way. */
.cr-plate { position: relative; padding: var(--sp-16) var(--sp-16) var(--sp-12); border: 2px solid var(--fg); background: var(--plate); }
.cr-plate::before { content: ""; position: absolute; inset: 5px; border: 1px solid var(--fg); pointer-events: none; }
.cr-head { display: flex; align-items: baseline; justify-content: space-between; margin: 0 var(--sp-4) var(--sp-8); }
.cr-fig { margin: 0; font-size: var(--fs-xs); letter-spacing: .1em; font-variant-numeric: tabular-nums; }
.cr-animal { font-size: var(--fs-sm); font-weight: 700; color: var(--accent); }
/* the stage is one face of an outdoor wall: bolt holes, the logo's sun behind the character, the logo's leaning slab as the shade */
.cr-wall { position: relative; isolation: isolate; border-radius: var(--r-base); overflow: hidden; background-color: color-mix(in srgb, var(--tint) var(--tint-mix, 55%), var(--plate)); }
.cr-wall::before { content: ""; position: absolute; inset: 0; z-index: 0; background-image: radial-gradient(circle, color-mix(in srgb, var(--fg) 14%, transparent) 2px, transparent 2.6px); background-size: 26px 26px; background-position: 13px 13px; }
.cr-sun { position: absolute; z-index: 1; top: 0; left: var(--sun-x); width: 40%; aspect-ratio: 1; border-radius: 50%; background: var(--sun-disc); transform: translateY(calc(var(--lift) * -100%)); }
.cr-shade { position: absolute; z-index: 2; top: 0; bottom: 0; width: 38%; background: var(--shade-ink); clip-path: polygon(0 0, 100% 0, 100% 100%, 42% 100%); }
.cr-shade.r { right: 0; }
.cr-shade.l { left: 0; transform: scaleX(-1); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .cr-wall { --tint-mix: 30%; } }
:root[data-theme="dark"] .cr-wall { --tint-mix: 30%; }
.cr-pic { position: relative; z-index: 3; display: block; width: 100%; max-width: 260px; height: auto; margin: 0 auto; padding: var(--sp-8) 0; filter: drop-shadow(2px 0 0 var(--sticker)) drop-shadow(-2px 0 0 var(--sticker)) drop-shadow(0 2px 0 var(--sticker)) drop-shadow(0 -2px 0 var(--sticker)) drop-shadow(2px 4px 0 color-mix(in srgb, var(--fg) 26%, transparent)); } /* a sticker edge */
.cr-name { margin: var(--sp-16) 0 var(--sp-8); text-align: center; font-size: 28px; line-height: 1.15; letter-spacing: -.04em; text-wrap: balance; } /* 28px: the one name on the plate, larger than the three words (--fs-lg); no token yet */
.cr-name:focus { outline: none; }
.cr-nick { max-width: 18em; margin: 0 auto var(--sp-16); text-align: center; font-size: var(--fs-md); font-weight: 600; color: var(--accent); text-wrap: balance; }
.cr-tri { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0 0 var(--sp-12); border-top: 1px solid var(--fg); border-bottom: 1px solid var(--hair); }
.cr-tri > div { padding: var(--sp-12) var(--sp-4) var(--sp-12); text-align: center; }
.cr-tri > div + div { border-left: 1px solid var(--hair); }
.cr-tri b { display: block; font-size: var(--fs-lg); line-height: 1.2; letter-spacing: -.02em; }
.cr-dots { display: flex; justify-content: center; gap: var(--sp-8); margin-top: var(--sp-8); } /* 3 filled: all three answers leaned this way, 2: two of three */
.cr-dots i { width: 14px; height: 14px; border-radius: 50%; background: var(--accent); }
.cr-dots i.off { background: none; box-shadow: inset 0 0 0 2px var(--muted); }
.cr-route { display: table; max-width: 100%; margin: 0 auto var(--sp-12); padding: var(--sp-4) var(--sp-12); border: 1px solid var(--fg); border-radius: var(--r-pill); font-size: var(--fs-sm); line-height: 1.4; text-align: center; text-wrap: balance; }
.cr-plate-foot { display: flex; align-items: center; justify-content: center; gap: var(--sp-8); margin: 0; padding-top: var(--sp-8); border-top: 1px solid var(--fg); font-size: var(--fs-xs); color: var(--muted); }
.cr-plate-foot::before { content: ""; width: 18px; height: 18px; background: currentColor; -webkit-mask: url(assets/hinoae-mark.svg) center / contain no-repeat; mask: url(assets/hinoae-mark.svg) center / contain no-repeat; }
.cr-safe { margin: 0; padding: var(--sp-12) var(--sp-16); border: 1px solid color-mix(in srgb, var(--soon) 30%, transparent); border-radius: var(--r-base); background: color-mix(in srgb, var(--soon) 8%, var(--surface)); font-size: var(--fs-sm); font-weight: 600; }
.cr-read { display: grid; gap: var(--sp-8); font-size: var(--fs-md); }
.cr-read p, .cr-read ul { margin: 0; }
.cr-read ul { padding-left: var(--sp-24); }
.cr-read b { margin-right: var(--sp-4); }
.cr-btns { display: flex; flex-wrap: wrap; gap: var(--sp-8); }
.cr-share { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cr-share-note { margin: calc(var(--sp-8) * -1) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.cr-status { margin: 0; min-height: 1.2em; font-size: var(--fs-xs); color: var(--soon); }
.cr-more { border-top: 1px solid var(--hair); }
.cr-more summary { display: flex; align-items: center; justify-content: space-between; min-height: var(--tap); font-weight: 600; list-style: none; cursor: pointer; }
.cr-more summary::-webkit-details-marker { display: none; }
.cr-more summary::after { content: ""; width: 9px; height: 9px; border: solid var(--muted); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.cr-more[open] summary::after { transform: rotate(-135deg); }
.cr-more summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cr-more-body { display: grid; gap: var(--sp-12); padding-bottom: var(--sp-8); font-size: var(--fs-md); }
.cr-more-body p { margin: 0; }
.cr-tip { padding: var(--sp-8) var(--sp-12); border: 1px dashed var(--line-strong); border-radius: var(--r-base); font-size: var(--fs-sm); }
.cr-note { margin: 0; font-size: var(--fs-xs); color: var(--muted); }
/* the reveal after the 12th answer, once, about 1.1 s: the sun rises, the character pops in, the name and the three words arrive, the dots light one by one.
   Uses the individual `translate`/`scale` properties so it composes with the sun's own transform. */
@keyframes cr-sunrise { from { translate: 0 230%; } }
@keyframes cr-fade { from { opacity: 0; } }
@keyframes cr-pop { from { opacity: 0; translate: 0 18px; scale: .9; } }
@keyframes cr-rise { from { opacity: 0; translate: 0 10px; } }
@keyframes cr-dot { from { scale: 0; } }
@media (prefers-reduced-motion: no-preference) {
  .cr-plate.reveal .cr-sun { animation: cr-sunrise 720ms var(--ease-out) both; }
  .cr-plate.reveal .cr-shade { animation: cr-fade 500ms ease-out 200ms both; }
  .cr-plate.reveal .cr-pic { animation: cr-pop 520ms cubic-bezier(.34, 1.56, .64, 1) 240ms both; }
  .cr-plate.reveal .cr-name { animation: cr-rise 380ms var(--ease-out) 460ms both; }
  .cr-plate.reveal .cr-nick { animation: cr-rise 380ms var(--ease-out) 520ms both; }
  .cr-plate.reveal .cr-tri > div { animation: cr-rise 360ms var(--ease-out) both; }
  .cr-plate.reveal .cr-tri > div:nth-child(1) { animation-delay: 600ms; }
  .cr-plate.reveal .cr-tri > div:nth-child(2) { animation-delay: 660ms; }
  .cr-plate.reveal .cr-tri > div:nth-child(3) { animation-delay: 720ms; }
  .cr-plate.reveal .cr-dots i { animation: cr-dot 280ms cubic-bezier(.34, 1.56, .64, 1) both; }
  .cr-plate.reveal .cr-dots i:nth-child(1) { animation-delay: 700ms; }
  .cr-plate.reveal .cr-dots i:nth-child(2) { animation-delay: 770ms; }
  .cr-plate.reveal .cr-dots i:nth-child(3) { animation-delay: 840ms; }
  .cr-plate.reveal .cr-route { animation: cr-rise 360ms var(--ease-out) 900ms both; }
}

/* 올해 도장 (src/year-seal-view.js): angle = the day, ring = the hour, the daylight band behind, one short arc per visit */
.ys { display: block; width: 100%; max-width: 340px; margin: 0 auto; touch-action: manipulation; }
.ys-rim { fill: none; stroke: var(--fg); stroke-opacity: .85; stroke-width: 1.4; }
.ys-rim.thin { stroke-opacity: .5; stroke-width: .7; }
.ys-tick { stroke: var(--fg); stroke-width: 1; }
.ys-month { font: 11px var(--font); fill: var(--muted); }
html[data-text="large"] .ys-month { font-size: 12px; }
html[data-text="xlarge"] .ys-month { font-size: 13px; }
.ys-day { fill-opacity: var(--ys-band); }
.ys-day.edge { fill-opacity: var(--ys-band-edge); }
.ys-night { fill: var(--shade-bar); fill-opacity: var(--ys-band-night); }
.ys-day.dim, .ys-night.dim { opacity: .42; }
.ys-orbit { fill: none; stroke: var(--fg); stroke-width: 1; stroke-dasharray: 1.2 5; stroke-linecap: round; }
.ys-orbit.past { stroke-opacity: .38; }
.ys-orbit.future { stroke-opacity: .14; }
.ys-today-line { stroke: var(--fg); stroke-opacity: .3; stroke-width: 1; }
.ys-sun-halo { fill: none; stroke: var(--pin-sun); stroke-opacity: .8; stroke-width: 1; }
.ys-sun { fill: var(--pin-sun); stroke: var(--surface); stroke-width: 1.6; }
.ys-num { font: 300 34px var(--font); font-variant-numeric: tabular-nums; fill: var(--fg); }
.ys-unit { font: 12px var(--font); fill: var(--muted); }
.ys-title { display: flex; flex: 1; align-items: center; justify-content: center; }
.ys-title h3 { flex: 0 1 auto; }
.ys-mark { cursor: pointer; outline: none; }
.ys-mark .under { fill: none; stroke: var(--surface); stroke-width: 5.2; stroke-linecap: round; }
.ys-mark .over { fill: none; stroke-width: 3; stroke-linecap: round; }
.ys-mark.sun .over { stroke: var(--ys-sun); }
.ys-mark.shade .over { stroke: var(--ys-shade); }
.ys-mark.night .over { stroke: var(--ys-night); }
.ys-mark.unknown .over { stroke: var(--ys-unknown); }
.ys-mark .core { display: none; }
.ys-mark.unknown .core { display: inline; fill: none; stroke: var(--surface); stroke-width: 1.3; stroke-linecap: round; } /* a hollow capsule: where it was, and that the sun is not known */
.ys-ring { display: none; fill: none; stroke: var(--accent); stroke-width: 1.6; pointer-events: none; }
.ys-ring.on { display: inline; }
:root { --ys-band: .18; --ys-band-edge: .32; --ys-band-night: .1; --ys-sun: #d9840f; --ys-shade: #4d82b0; --ys-night: #252a2e; --ys-unknown: #6a706c; } /* what an arc says about the sun: lit, shade, after sunset, not known */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --ys-band: .26; --ys-band-edge: .45; --ys-band-night: .14; --ys-sun: #f0a040; --ys-shade: #6aa3d2; --ys-night: #cfd5d0; --ys-unknown: #a8afaa; } }
:root[data-theme="dark"] { --ys-band: .26; --ys-band-edge: .45; --ys-band-night: .14; --ys-sun: #f0a040; --ys-shade: #6aa3d2; --ys-night: #cfd5d0; --ys-unknown: #a8afaa; }
.ys-key { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-4) var(--sp-12); margin: var(--sp-4) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.ys-key span { display: inline-flex; align-items: center; gap: var(--sp-4); white-space: nowrap; }
.ys-key i { display: inline-block; width: 14px; height: 5px; border-radius: 3px; background: var(--ys-sun); }
.ys-key i.shade { background: var(--ys-shade); }
.ys-key i.night { background: var(--ys-night); }
.ys-key i.unknown { background: none; box-shadow: inset 0 0 0 1.3px var(--ys-unknown); }
.yi-list { display: grid; gap: var(--sp-12); margin: var(--sp-4) 0 var(--sp-12); padding: 0; list-style: none; }
.yi-list li { display: grid; gap: var(--sp-2); }
.yi-list b { font-size: var(--fs-base); }
.yi-list span { font-size: var(--fs-sm); color: var(--muted); }
.ys-plot { padding: var(--sp-4) 0 0; }
.ys-cap { min-height: 1.5rem; margin: var(--sp-4) 0 0; text-align: center; font-size: var(--fs-sm); color: var(--muted); }

/* 첫 방문 투어 (src/tour.js): 화면 전체를 덮는 dialog, 구멍은 box-shadow 로 뚫는다. 구멍과 말풍선이 같은 곡선으로 미끄러져 옮겨 간다 */
.tour { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: transparent; overflow: hidden; }
.tour::backdrop { background: transparent; }
.tour-sample { position: fixed; top: max(96px, 22vh); left: max(16px, calc((100vw - 560px) / 2)); width: min(560px, calc(100vw - 32px)); margin: 0; padding: 0; list-style: none; border-radius: var(--r-base); background: var(--surface); }
.tour-hole { position: fixed; border-radius: var(--r-base); pointer-events: none;
  box-shadow: 0 0 0 2px var(--accent), 0 0 28px 4px color-mix(in srgb, var(--accent) 50%, transparent), 0 0 0 100vmax rgb(4 8 7 / .66);
  transition: left .42s var(--ease-out), top .42s var(--ease-out), width .42s var(--ease-out), height .42s var(--ease-out); animation: tour-in .5s var(--ease-out) both; }
.tour-tip { position: fixed; display: grid; gap: var(--sp-8); width: min(316px, calc(100vw - 32px)); padding: var(--sp-16) var(--sp-16) var(--sp-12); border-radius: var(--r-16); background: var(--surface); color: var(--fg);
  box-shadow: 0 18px 48px rgb(0 0 0 / .38), 0 0 0 1px color-mix(in srgb, var(--fg) 8%, transparent);
  transition: left .42s var(--ease-out), top .42s var(--ease-out); animation: tour-in .5s .08s var(--ease-out) both; }
.tour-arrow { position: absolute; left: var(--ax, 50%); width: 14px; height: 14px; margin-left: -7px; border-radius: 3px; background: var(--surface); transform: rotate(45deg); box-shadow: -1px -1px 0 color-mix(in srgb, var(--fg) 8%, transparent); transition: left .42s var(--ease-out); }
.tour-tip[data-side="below"] .tour-arrow { top: -7px; }
.tour-tip[data-side="above"] .tour-arrow { bottom: -7px; box-shadow: 1px 1px 0 color-mix(in srgb, var(--fg) 8%, transparent); }
.tour-top { display: flex; align-items: center; justify-content: flex-end; }
.tour-skip { min-height: var(--tap); margin: calc(var(--sp-12) * -1) calc(var(--sp-8) * -1) calc(var(--sp-12) * -1) 0; padding: 0 var(--sp-8); border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-sm); white-space: nowrap; cursor: pointer; }
.tour-txt { display: grid; gap: var(--sp-4); }
.tour-txt.swap { animation: tour-txt .38s var(--ease-out) both; }
.tour-tip h2 { margin: 0; font-size: var(--fs-lg); line-height: 1.25; letter-spacing: -.02em; }
.tour-tip p { margin: 0; font-size: var(--fs-base); line-height: 1.55; color: var(--muted); }
.tour-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-8); margin-top: var(--sp-4); }
html[data-text="xlarge"] .tour-dots { display: none; } /* 글자를 가장 크게 하면 점·버튼이 한 줄에 안 들어간다 */
.tour-dots { display: flex; gap: 5px; }
.tour-dots i { width: 6px; height: 6px; border-radius: 99px; background: var(--line-strong); transition: width .3s var(--ease-out), background .3s; }
.tour-dots i.on { background: var(--accent); }
.tour-nav { display: flex; gap: var(--sp-4); }
.tour-btn { min-height: var(--tap); padding: 0 var(--sp-12); border: 0; border-radius: 999px; background: none; color: var(--muted); font: inherit; font-weight: 600; white-space: nowrap; cursor: pointer; }
.tour-btn.primary { padding: 0 var(--sp-24); background: var(--accent); color: var(--on-accent); }
.tour-btn:focus-visible, .tour-skip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tour.follow .tour-hole, .tour.follow .tour-tip, .tour.follow .tour-arrow { transition: none; }
@media (max-height: 500px) { .tour-sample { top: 48px; } .tour-arrow { display: none; } .tour-tip { max-height: calc(100dvh - 32px); overflow: auto; } } /* 가로로 눕힌 폰: 카드와 말풍선이 겹치지 않게 위로 올리고, 화살표는 접는다 */
@keyframes tour-in { from { opacity: 0; } }
@keyframes tour-txt { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .tour-hole, .tour-tip, .tour-arrow, .tour-dots i { transition: none; animation: none; } .tour-txt.swap { animation: none; } }

/* ---- 새 디자인 체계 2단계 (docs/system/design-harness.md 2-2절): 슬라이더·알약·세그먼트·칩. 재질·포커스 링·터치 영역은 3단계 ---- */
.scrub .scrub-bar { background: var(--rope) repeat-x center / 48px 10px; border-radius: 0; } /* 남은 구간 = 회색 세 가닥 밧줄 */
.scrub .scrub-bar::after { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--thumb-w) / 2 - var(--bar-inset) + (100% - var(--thumb-w) / 2) * var(--fill, 0) / (1 - var(--unreach))); background: var(--gone); } /* 지나간 구간은 밧줄을 회색 한 톤으로 덮는다 */
#time::-webkit-slider-thumb { border-radius: 50%; background: var(--chev) center / 32px 32px no-repeat #fff; box-shadow: var(--shadow-thumb); } /* 32px 흰 원 + 얇은 ‹ › */
#time::-moz-range-thumb { border-radius: 50%; background: var(--chev) center / 32px 32px no-repeat #fff; box-shadow: var(--shadow-thumb); }
.pill, #nowBtn, .sort-btn, .step-btn { border: 0; box-shadow: none; background: var(--sunken); }
.pill:active, #nowBtn:active, .sort-btn:active, .step-btn:active { transform: scale(.97); transition: transform 100ms ease-out; }
.segs, .tabs { padding: var(--sp-2); gap: 0; border-radius: var(--r-base); background: var(--sunken); }
.segs :is(label, button), .tabs [role="tab"] { border-radius: var(--r-md); font-weight: 500; color: var(--fg); }
.segs button[aria-pressed="true"], .segs label:has(:checked), .tabs [aria-selected="true"] { background: var(--surface); color: var(--fg); font-weight: 600; box-shadow: var(--shadow-tab); }
#sortBtn, .arrive-pill { padding: 0 var(--sp-24) 0 var(--sp-12); background: var(--sunken) var(--chev-down) no-repeat right var(--sp-8) center / 12px 12px; }
#sortBtn svg { display: none; } /* 정렬은 `남은 시간 순 ⌄` 메뉴 알약 */
/* ---- 새 디자인 체계 3단계 (design-harness.md 2-2절): 재질·포커스 링·터치 영역·행 구분선 ---- */
body .top, body .controls, body .tabbar, #sortMenu { background: var(--mat); -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); }
body .top { box-shadow: 0 .5px 0 var(--mat-hair); }
body .controls { box-shadow: none; }
body .tabbar { box-shadow: 0 -.5px 0 var(--mat-hair); } /* 탭바 윗선은 0.5px 헤어라인만 */
#sortMenu { box-shadow: var(--shadow-float); }
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  body .top, body .controls, body .tabbar, #sortMenu { background: var(--surface); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (max-width: 1023px) {
  body .tabbar .tabs { background: transparent; padding: 0; }
  body .tabbar .tabs [role="tab"] { color: var(--muted); font-weight: 500; }
  body .tabbar .tabs [aria-selected="true"] { background: transparent; box-shadow: none; color: var(--olive); font-weight: 600; } /* 탭바의 현재 탭은 칸이 아니라 글자 무게와 색 */
}
:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.segs button { position: relative; }
.segs button::before { content: ""; position: absolute; inset: -8px 0; } /* 보이는 크기 28px는 그대로, 터치 영역만 44px */
:is(.row, .crag-row) { border-bottom-color: transparent; } /* 행 사이는 선 대신 간격과 글자 무게 */
/* ---- 암장 목록 줄 (사용자 결정 2026-11-05: 구분은 가장자리 선, 카드 아님): 날씨 칩 열(칩 + 아래 기온) 옆에 이름 줄·막대 줄을 둔다.
   막대는 8시 이후(축 x ≥ 칩 열 오른쪽)에 시작하므로 칩 열과 겹치지 않는다 ---- */
.rows :is(.row, .crag-row)::after { content: ""; position: absolute; left: var(--pad); right: var(--pad); bottom: 0; height: 1px; background: var(--line); z-index: -1; pointer-events: none; } /* 줄 사이 선 */
.rows :is(.row, .crag-row):last-child::after { display: none; }
.rows .row-btn { position: relative; padding-block: var(--sp-8); min-height: 72px; }
.rows .row-btn .wxset { position: absolute; left: var(--pad); top: var(--sp-8); margin: 0; }
.rows .l1:has(> .wxset) { padding-left: calc(var(--sp-48) + var(--sp-16) + var(--sp-2)); } /* 칩 열(40) + ♥ 자리 */
.rows .l1:has(> .wxset) > .rfav-gap { width: 0; margin: 0; }
.rows .row-btn:has(.wxset) ~ .row-fav { left: calc(var(--pad) + 37px); top: -1px; } /* ♥는 칩과 이름 사이 */
.rows .row-btn .wx-temp { font-size: var(--fs-md); font-weight: 700; color: var(--fg); margin-top: var(--sp-2); }
.rows .row-btn .bar { margin-top: var(--sp-8); height: 13px; }
#rows-open .bar .seg:not(.past) { background: color-mix(in srgb, var(--fg) 85%, transparent); } /* 모두 열린 목록: 막대는 먹색, 색은 양달(주황)·곧 마감(빨강)처럼 가를 때만 */
#rows-open .left { color: var(--fg); font-size: var(--fs-md); font-weight: 700; }
#rows-open .left.few { color: var(--soon); }
#rows-open .rname { font-size: var(--fs-md); font-weight: 700; letter-spacing: -.01em; }
#rows-open .rsub { font-size: var(--fs-xs); color: var(--muted); }
.wx-dir svg :is(path, circle, line, polyline) { stroke-width: 2.8; } /* 14px 배지의 선: 2.4면 1.4px로 얇다 */
.scrub #summary b:not(.zero) { color: var(--point); } /* 답의 시각과 개수: 지금 고른 시각 = 포인트 */
.scrub #summary b:last-of-type { font-size: 1.15em; }
#group-open > .band { font-size: var(--fs-xs); font-weight: 500; color: var(--muted); } /* 정렬 줄: 알약과 같은 13px */
#moreFilters::after { content: ""; display: inline-block; width: 12px; height: 12px; margin-left: var(--sp-4); vertical-align: -2px; background: var(--chev-down) center / 12px no-repeat; } /* 조건 ⌄: 글자 ▾ 대신 같은 쉐브론 */
/* ---- 부품 규격 (사용자 결정 2026-11-05): 높이 22/32/44 · 컨트롤은 알약, 면은 12 · 알약 글자 13/500 · 채움은 회색 ---- */
#nowBtn, .scrub-sum, .sort-btn, #moreFilters { min-height: var(--h-m); font-size: var(--fs-xs); font-weight: 500; }
.scrub-sum .sub { font-size: var(--fs-xs); font-weight: 500; }
#moreFilters { position: relative; padding: 0 var(--sp-12); border: 0; border-radius: var(--r-pill); background: var(--sunken); color: var(--fg); }
#moreFilters::before { content: ""; position: absolute; inset: -6px -4px; } /* 보이는 높이는 32, 터치 영역은 44 */
.filters .quiet#moreFilters { text-align: center; }
.axis .nowtag { background: var(--point); color: var(--on-accent); display: flex; align-items: center; height: var(--h-s); border-radius: var(--r-pill); padding: 0 var(--sp-8); font-size: var(--fs-xs); font-weight: 600; } /* 지금 고른 시각 태그: 4px 상자가 아니라 알약 */
.mtn-band { height: 56px; color: color-mix(in srgb, var(--fg) 30%, transparent); pointer-events: none; overflow: hidden; } /* 컨셉 일러스트: 시간 박스 위(스크롤하면 검색 줄과 함께 사라진다) */
.mtn-band svg { display: block; width: 100%; height: 100%; }
/* 날씨 칩(2026-11-05 확정): 날씨가 먼저(칩 그림 = 날씨, 해 배지는 날씨가 칩을 차지했을 때만), 면은 항상 옅게(양달 갈색·응달 파랑·흐림 회색), 글리프는 크게 */
.rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset > .sunnow.pic { width: var(--chip); height: var(--chip); border-radius: var(--r-md); }
.rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset > .sunnow.pic svg { width: var(--glyph); height: var(--glyph); }
.rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset > .sunnow.sun.pic:not(.scw-veil) { background: color-mix(in srgb, var(--sun-chip) 16%, var(--surface)); color: var(--sun-glyph); }
.rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset > .sunnow.shade.pic:not(.scw-veil) { background: color-mix(in srgb, var(--shade-bar) 16%, var(--surface)); color: var(--shade-glyph); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset > .sunnow.sun.pic:not(.scw-veil) { background: color-mix(in srgb, var(--sun-bar) 22%, var(--surface)); color: var(--sun-bar); } }
:root[data-theme="dark"] .rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset > .sunnow.sun.pic:not(.scw-veil) { background: color-mix(in srgb, var(--sun-bar) 22%, var(--surface)); color: var(--sun-bar); }
.rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset .wx-dir { width: var(--badge); height: var(--badge); top: auto; right: auto; left: calc(var(--badge) / -3); bottom: 0; } /* 배지는 칩 왼쪽 아래: 오른쪽 위에 두면 ♥와 붙는다 */
.rows :is(.row, .crag-row):not(.has-photo.is-open) .wxset .wx-dir svg { width: 14px; height: 14px; }
/* 가장 큰 글씨의 좁은 폰: 지역명을 먼저 숨기고, 그래도 넘치면 이름이 두 줄까지(사용자 결정 2026-11-05) */
@media (max-width: 400px) { html[data-text="xlarge"] .rows .row-btn .l1 .rsub { display: none; } }
.rows .row-btn:has(.wxset) ~ .row-fav { top: 3px; } /* ♥ 중심을 이름 글자 중심에 맞춘다 */
.rows .row-btn .wx-temp { left: 20px; transform: translateX(-50%); } /* 칩 폭 40 / 칸 폭 44: 기온을 칩 중심 아래로 */ /* 칩 폭 40 / 칸 폭 44: 기온을 칩 중심 아래로 */
/* 실내·방향 모름 줄: 날씨 칩이 없어도 같은 칩 열(40, 옅은 회색 면)에 둬서 이름 줄이 외벽 줄과 맞는다 */
.rows :is(.row, .crag-row):not(.has-photo.is-open) .l1 > .sunnow.pic { position: absolute; left: var(--pad); top: var(--sp-8); box-sizing: border-box; width: var(--chip); height: var(--chip); padding: 0; border: 0; border-radius: var(--r-md); background: var(--sunken); }
.rows :is(.row, .crag-row):not(.has-photo.is-open) .l1 > .sunnow.pic svg { width: var(--glyph); height: var(--glyph); }
.rows .row-btn .l1:has(> .sunnow.pic) { padding-left: calc(var(--sp-48) + var(--sp-16) + var(--sp-2)); }
.rows .row-btn .l1:has(> .sunnow.pic) > .rfav-gap { width: 0; margin: 0; }
.rows .row-btn:has(.l1 > .sunnow.pic) ~ .row-fav { left: calc(var(--pad) + 37px); top: 3px; }
@media (max-width: 400px) { .rows .row-btn .l1 .rname { flex: 0 1 auto; } } /* 좁은 폰: 이름이 제 글자 폭을 먼저 쓰고, 남는 칸을 지역(.rsub)이 가져간다 */
.rows .row-btn .l1 .rsub { justify-content: flex-end; } /* 지역은 남은 시간 옆 오른쪽 끝에 모아 줄마다 같은 열에 놓는다(이름 길이에 따라 흔들리지 않게) */
.lg-peaks { margin: calc(var(--sp-8) * -1) calc(var(--sp-8) * -1) var(--sp-12); height: 48px; } /* 기록 빈 화면의 머리: 홈의 봉우리 띠를 그대로 */
/* 기록 밧줄(src/rope-meter.js): 가닥이 하나, 둘, 셋으로 늘고 매듭에서 색이 켜진다. 세 색은 컨셉의 세 가닥이라 여기서만 쓴다 */
.rope-meter { --rope-gold: #d9a21b; --rope-verm: #c24a2e; --rope-blue: #3f6c9e; display: block; width: 100%; height: 32px; margin: var(--sp-8) 0; color: var(--fg); fill: none; stroke-linecap: round; stroke-linejoin: round; }
.rope-meter .rope-halo { stroke: var(--paper); stroke-width: 6.8; }
.rope-meter .knot-halo { stroke-width: 6.4; }
.rope-meter .rope-strand { stroke-width: 3.2; }
.rope-meter .rope-strand.soft { opacity: .5; }
.rope-meter .s0 { stroke: var(--rope-gold); }
.rope-meter .s1 { stroke: var(--rope-verm); }
.rope-meter .s2 { stroke: var(--rope-blue); }
.rope-meter .rope-unlit { stroke: var(--gone); stroke-width: 1.6; stroke-dasharray: 1 5; }
.rope-meter .rope-ink { stroke: currentColor; stroke-width: 2.4; }
.lg-sum { display: grid; } .lg-sum small { margin-top: var(--sp-8); font-size: var(--fs-xs); color: var(--muted); }
/* ---- 싱글피치 (config.singlePitch): 토글, 목록 줄, 펼친 카드 ----
   목록 줄은 외벽 줄의 규칙을 같이 쓴다(위쪽 외벽 규칙을 :is(.row, .crag-row) / :is(.row-btn, .crag-head)로 넓힘): 여기에는 크랙에만 있는 것만 둔다. 컨디션 글자는 운영 상태 색(초록·앰버)과 뜻이 겹치지 않게 중립 톤이고 비 예보만 와인(조심할 것)이다. */
/* 조건 시트: 싱글피치 목록(cragList)이 쓰지 않는 줄은 싱글피치 모드에서 숨긴다(구분·최소 이용 시간·휴게시간·주차·장비 대여; 기온 ○°↑는 싱글피치도 쓴다; 내 지역 칩의 개수는 외벽 수라 숨김). 정렬의 첫 칸은 모드마다 말이 다르다 */
body[data-mode="crag"] :is(#venueRow, #minRow, #breakRow, #parkRow, #rentRow, #regionOptsC .rg-n), body[data-mode="crag"] .for-wall, body:not([data-mode="crag"]) .for-crag { display: none; }
.mode-switch { grid-column: 2; justify-self: start; display: inline-flex; padding: var(--sp-2); margin-left: var(--sp-12); background: var(--sunken); border-radius: var(--r-pill); } /* 로고 줄의 빈자리: 헤더 높이를 늘리지 않는다 */
.mode-switch[hidden] { display: none; }
.mode-switch button { position: relative; display: grid; place-items: center; width: 46px; height: 40px; padding: 0; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--muted); cursor: pointer; }
.mode-switch button::after { content: ""; position: absolute; inset: -2px -1px; } /* 눌리는 칸은 세로 44px */
.mode-switch button svg { width: var(--glyph); height: var(--glyph); }
.mode-switch button[aria-pressed="true"] { background: var(--surface); color: var(--fg); box-shadow: var(--shadow-seg); }
.mode-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.crag-board { --pad: 16px; position: relative; margin: var(--sp-12) -16px 0; background: var(--surface); border-block: 1px solid var(--line); } /* .board와 같은 면: --pad는 .board처럼 여기서 정의한다(루트 토큰이 아니다) */
.crag-board[hidden] { display: none; }
.crag-rows { list-style: none; margin: 0; padding: 0; }
/* 줄: .l1 > 양달 칩 · .rname · .rsub(지역) · .left(컨디션 글자) · ›, 둘째 줄은 .bar(일출~일몰 위 양달 .sunband / 응달 .sunband.shade + .tick) */
.crag-row .l1 { flex-wrap: wrap; } /* 긴 컨디션 글자는 375px에서 다음 줄 오른쪽으로 (외벽의 남은 시간은 짧아 줄바꿈하지 않는다) */
.crag-row .left { color: var(--fg); } /* 오른쪽 값은 컨디션 글자: 운영 초록이 아니다 */
.crag-row .left.is-rain, .crag-cond-text.is-rain { color: var(--soon); }
.crag-row .left:is(.is-wet, .is-frozen), .crag-cond-text:is(.is-wet, .is-frozen) { color: var(--soon); } /* 젖음 계산의 젖음·얼음도 비 예보처럼 조심 색 */
.crag-row .left:is(.is-unknown, .is-out) { color: var(--muted); font-weight: 400; }
.sunband.shade { background: var(--shade-bar); } /* 크랙 막대만: 일출~일몰 전체를 양달/응달로 칠하므로 응달 조각이 있다 */
.crag-head > .crag-nodir { display: block; margin-top: var(--sp-8); } /* 막대 자리: 방향 정보 없음 */
/* 사진을 입은 열린 줄(외벽 .row.has-photo 규칙을 넓혀 같이 씀): 컨디션은 외벽 남은 시간처럼 흰 알약, 글자는 라이트 값 고정(초록 없음, 비는 와인, 모름은 회색) */
.crag-row.has-photo.is-open .crag-head .left { padding: 2px var(--sp-12); border-radius: var(--r-pill); background: rgb(255 255 255 / .95); color: var(--fg-on-white); text-shadow: none; }
.crag-row.has-photo.is-open .crag-head .left.is-rain { color: var(--soon-on-white); }
.crag-row.has-photo.is-open .crag-head .left:is(.is-wet, .is-frozen) { color: var(--soon-on-white); }
.crag-row.has-photo.is-open .crag-head .left:is(.is-unknown, .is-out) { color: var(--muted-on-white); }
.crag-row.has-photo.is-open .crag-head .crag-nodir { color: var(--on-photo); }
.crag-row .rhero-line { flex-wrap: wrap; } /* 해 시각(일출–일몰, 외벽 운영시간보다 길 수 있음)이 한 줄에 안 들어가면 사진 출처가 그 아래 줄로(시각이 두 줄로 꺾이지 않게) */
.crag-row.is-open .l1 { flex-wrap: nowrap; } /* 열린 카드의 머리는 외벽 열린 줄처럼 한 줄: 좁으면 지역(.rsub)이 숨고 알약은 내려가지 않는다(사진 위 머리가 아래 '오늘 해'와 겹치지 않게) */
.crag-nodir { font-size: var(--fs-xs); color: var(--muted); }
.crag-body { padding: 0 var(--pad) var(--sp-16); }
.crag-cond-text { margin: 0; font-weight: 700; }
/* 컨디션 탭(src/crag-cond-pane.js, 시안 docs/superpowers/mockups/2026-10-22-crag-cond-tab.html). 색은 기존 토큰 + 이미 쓰는 파랑(.crag-rain의 비)·청록(.row.windy의 돌풍 배지)뿐: 새 토큰 없이 이 탭 안에서만 이름을 붙인다. icon()의 svg는 크기가 없어 em으로 맞춘다. */
.crag-cond-pane svg { width: 1em; height: 1em; flex: none; }
.crag-cond { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: var(--sp-12); align-items: center; }
.crag-cond .badge { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; font-size: 28px; }
.crag-cond .state { margin: 0; font-size: var(--fs-lg); font-weight: 700; line-height: 1.25; }
/* the head's colour says the state: good = sun, wet (마르는 중·비·최근 비) = wine (조심), unknown = quiet. Never --open: green means 운영 중 only */
.crag-cond.is-good .badge { background: var(--panel); color: var(--fg); } /* 해 색은 양달 뜻에만 */
.crag-cond.is-good .state { color: var(--fg); }
.crag-cond.is-wet .badge { background: color-mix(in srgb, var(--soon) 14%, transparent); color: var(--soon); }
.crag-cond.is-wet .state { color: var(--soon); }
.crag-cond.is-unknown .badge { background: var(--panel); color: var(--muted); }
.crag-cond.is-unknown .state { color: var(--fg); }
.crag-cond .when { margin: 0; font-size: var(--fs-md); font-weight: 600; }
.crag-dry { grid-column: 1 / -1; display: flex; align-items: center; gap: var(--sp-8); margin: var(--sp-4) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.crag-dry .segs { flex: 1; display: flex; gap: var(--sp-4); }
.crag-dry .seg { flex: 1; height: 8px; border-radius: var(--r-pill); box-shadow: inset 0 0 0 1.5px var(--open); }
.crag-dry .seg.on { background: var(--open); }
.crag-dry b { color: var(--fg); white-space: nowrap; }
.ws-sec-h:has(.end) { flex-wrap: wrap; row-gap: var(--sp-4); } /* 큰 글씨: 제목과 알약이 한 줄에 안 들면 알약이 아래 줄로 내려간다(잘리거나 제목이 두 줄로 꺾이지 않게) */
.crag-cond-pane .ws-sec-h h3 { white-space: nowrap; }
.ws-sec-h h3 > svg { font-size: 20px; color: var(--muted); vertical-align: -3px; margin-right: var(--sp-8); }
.ws-sec-h .end { margin-left: auto; font-size: var(--fs-xs); font-weight: 600; color: var(--fg); background: var(--panel); padding: var(--sp-2) var(--sp-8); border-radius: var(--r-pill); white-space: nowrap; }
.ws-sec-h .end.wind { background: color-mix(in srgb, var(--wind) 16%, transparent); color: var(--fg); } .ws-sec-h .end.wind svg { color: var(--wind); } /* text in --fg: the teal tint alone, 4.5:1 */
.ws-sec-h .end svg { vertical-align: -2px; }
.crag-rain2 { display: flex; gap: var(--sp-4); align-items: stretch; color: var(--rain); }
.crag-rain2 .col { flex: 1; min-width: 0; display: grid; grid-template-rows: auto 56px auto auto; justify-items: center; align-items: end; font-size: var(--fs-xs); }
.crag-rain2 .mm { font-weight: 700; line-height: 1.6; min-height: 1.6em; }
.crag-rain2 .rbar { display: block; width: 100%; height: var(--h); background: currentColor; border-radius: var(--r-xs); min-height: 2px; }
.crag-rain2 .is-fc .rbar { background: color-mix(in srgb, currentColor 28%, transparent); box-shadow: inset 0 0 0 1.5px currentColor; } /* 예보: 옅은 채움 + 윤곽 (다가올 비가 지난 비보다 약해 보이지 않게) */
.crag-rain2 .rbar.is-none { background: var(--hair); box-shadow: none; } /* 비 없음(1mm 미만): 파랑이 아니다 */
.crag-rain2 .d { font-size: min(var(--fs-xs), 4.2vw); margin-top: var(--sp-4); color: var(--muted); line-height: 1.4; }
.crag-rain2 .is-today .d { color: var(--fg); font-weight: 700; box-shadow: 0 2px 0 var(--fg); }
/* 시간별 하늘 아이콘(td.sky) 색: 맑음·구름 조금 = 해, 비 = 파랑, 나머지 = 흐린 회색 */
.crag-hours td.sky.rain { color: var(--rain); }
.crag-rain2 .split { flex: none; width: 1px; background: var(--hair); } /* 지난 날과 오늘·예보 사이 */
.crag-rain-cap { display: flex; margin: var(--sp-4) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.crag-rain-cap span { flex: 1 1 0; }
.crag-rain-cap span:last-child { padding-left: var(--sp-4); }
.crag-hours { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 0; text-align: center; }
.crag-hours th, .crag-hours td { padding: var(--sp-8) 0; font-weight: 400; white-space: nowrap; } /* 한 값은 쪼개지 않는다: 칸이 좁으면 글자를 줄인다(아래 vw 상한) */
.crag-hours thead th { font-size: min(var(--fs-xs), 4.6vw); color: var(--muted); padding-bottom: var(--sp-2); }
.crag-hours tbody th { width: 1.9em; text-align: left; color: var(--muted); font-size: 18px; }
.crag-hours tbody th .unit { display: block; font-size: var(--fs-xs); line-height: 1; color: var(--muted); } /* 돌풍 줄의 단위 */
.crag-hours td.sky { font-size: 28px; line-height: 1; color: var(--muted); }
.crag-hours td.sky.has-dir { padding-bottom: var(--sp-8); } /* room for the badge that hangs 5px below the picture */
.crag-hours td.sky .sky-in { position: relative; display: inline-block; line-height: 0; }
.crag-hours td.sky .sky-dir { position: absolute; right: -5px; bottom: -5px; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; background: #a85f0a; color: #fff; box-shadow: 0 0 0 2px var(--surface); } /* 목록 칩의 모서리 배지(.scw-dir)와 같은 점: 양달 앰버, 응달 스틸블루 */
.crag-hours td.sky .sky-dir svg { width: 12px; height: 12px; }
.crag-hours td.sky .sky-dir.shade { background: var(--shade-bar); color: var(--on-accent); }
.crag-hours td.sky .sky-dir.shade svg { width: 13px; height: 13px; stroke-width: 2.4; } /* 목록 칩 배지와 같은 응달 점(칸이 좁아 원만 18px) */
.crag-hours td.sky.rain .sky-dir { box-shadow: 0 0 0 3px var(--surface); } /* 비 파랑과 응달 파랑이 붙어 읽히지 않게 링을 한 겹 더 */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .crag-hours td.sky .sky-dir.sun { background: var(--sun-bar); color: var(--on-accent); } }
:root[data-theme="dark"] .crag-hours td.sky .sky-dir.sun { background: var(--sun-bar); color: var(--on-accent); }
.crag-hours td.t { font-size: min(var(--fs-xl), 5.5vw); font-weight: 700; line-height: 1.2; }
.crag-hours td.g { font-size: var(--fs-md); border-top: 1px solid var(--hair); }
.crag-hours td.g.strong { background: color-mix(in srgb, var(--wind) 18%, transparent); color: var(--fg); font-weight: 700; }
.crag-hours th.at, .crag-hours td.at { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.crag-hours thead th.at { font-weight: 700; color: var(--fg); border-radius: var(--r-xs) var(--r-xs) 0 0; }
.crag-note { display: flex; align-items: center; gap: var(--sp-8); margin: var(--sp-16) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.crag-note svg { font-size: 16px; }
.crag-cond-pane { --rain: #2f62b0; --wind: #1f7a70; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .crag-cond-pane { --rain: #8db4ee; --wind: #2f9a8c; } }
:root[data-theme="dark"] .crag-cond-pane { --rain: #8db4ee; --wind: #2f9a8c; }
/* 비 막대: 컨디션 줄의 값 칸 안(.pv, 외벽 .irow). 색은 외벽 날씨 상자의 비 글자(.wxb-rain의 파랑, 다크 규칙도 같이 넓힘)라 응달 막대(--shade-bar)와 겹치지 않는다.
   지난 날은 채움, 오늘과 예보 날은 윤곽, 오늘은 아래 점(비가 0이라 막대가 거의 없어도 보인다) */
/* 해 박스는 외벽 .sunbox(app.js cragSunBox) 그대로: 안에 하루 막대는 없다(막대는 줄 머리에). 하늘 첫 줄 날씨의 비는 외벽 .sunbox.sc .wx-pill(와인 = 곧 끝남·조심할 것) */
.crag-body > .sunbox { margin-bottom: var(--sp-12); } /* 아래 후기·다녀왔어요와 붙지 않게(위 간격은 .sunbox의 margin-top) */
.crag-text { margin: var(--sp-8) 0 0; white-space: pre-line; }
.crag-way { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-8); } /* 가는 길 row's value: the 주차 word · footprints + minutes on one line (wraps only when narrow) */
.crag-walk { display: inline-flex; align-items: center; gap: var(--sp-4); font-weight: 600; }
.crag-walk svg { width: 16px; height: 16px; color: var(--muted); }
.crag-quiet { color: var(--muted); font-weight: 400; } /* 모르는 값(도보 시간 미상): 줄의 '마르는 시간 모름'처럼 조용히 */
/* 카드는 외벽 카드 부품(.dock, .meta-row/.chip.rope, .irow/.pv-go, .blog)을 그대로 쓴다. 여기는 크랙 것만:
   모르는 값(.crag-quiet) · 주의(와인 윤곽, 접지 않음). 주차 값은 외벽 주차 줄의 .pk-word(good/warn/muted) */
/* 싱글피치 어프로치 탭(src/approach-sheet.js, 암장 시트 .ws-panel 안): 저장 칩 · 길 띠(누르면 그 단계로) · 사진 또는 큰 글 · 방향 · 와인 줄 · 이전/다음.
   진행(갈 길·걸어 온 길·지금 정지점·방향 화살표·저장됨) = --accent(외벽 시트의 눌린 칩·다음 버튼과 같은 색), 와인(--soon) = 가면 안 되는 쪽. 초록(--open)은 '운영 중'에만 쓴다. 새 색은 없다. */
.approach-pane { display: grid; padding-top: var(--sp-8); }
.approach-pane > .ws-sec { display: grid; gap: var(--sp-12); } /* the steps, photo and text sit in one sheetCard */ /* 어프로치 탭: the side padding, height and scrolling are .ws-panel's */
.ap-chipbox { flex: none; }
.ap-chip { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 var(--sp-12); border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--surface); color: var(--muted); font: inherit; font-size: var(--fs-xs); font-weight: 700; white-space: nowrap; }
button.ap-chip { cursor: pointer; color: var(--accent); }
.ap-chip.is-saved { border-color: var(--accent); color: var(--accent); }
.ap-chip.is-fail { border-color: var(--soon); color: var(--soon); }
.ap-strip { position: relative; height: 60px; margin: 0 var(--sp-16); }
.ap-line, .ap-fill { position: absolute; left: 0; top: 15px; height: 4px; border-radius: var(--r-xs); }
.ap-line { right: 0; background: var(--line); }
.ap-fill { width: var(--x); background: var(--accent); }
.ap-stop { position: absolute; top: 0; left: var(--x); transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: var(--sp-4); min-width: var(--tap); min-height: 52px; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
.ap-dot { width: 32px; height: 32px; box-sizing: border-box; display: grid; place-items: center; border: 2px solid var(--line-strong); border-radius: 50%; background: var(--surface); color: var(--muted); font-size: var(--fs-sm); font-weight: 700; }
.ap-dot svg { width: 16px; height: 16px; }
.ap-stop.is-done .ap-dot { border-color: var(--accent); color: var(--accent); }
.ap-stop.is-cur .ap-dot { border-color: var(--accent); background: var(--accent); color: var(--on-accent); transform: scale(1.15); }
.ap-min { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.ap-stop:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-md); }
.ap-where { margin: 0; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.ap-view { position: relative; overflow: hidden; border-radius: var(--r-base); background: var(--sunken); touch-action: pan-y; } /* a sideways drag here steps the photo, not the sheet's tabs */
.ap-view[hidden] { display: none; }
.ap-view.is-photo { cursor: pointer; user-select: none; -webkit-user-select: none; }
.ap-view img { display: block; width: 100%; aspect-ratio: 4 / 3; max-height: 48dvh; object-fit: cover; }
.ap-view.is-text, .ap-view.is-fail { display: grid; align-content: center; gap: var(--sp-8); min-height: 160px; padding: var(--sp-16); }
.ap-fail { display: grid; gap: var(--sp-4); color: var(--muted); font-size: var(--fs-sm); }
.ap-fail b { color: var(--fg); font-size: var(--fs-md); }
.ap-big { margin: 0; font-size: var(--fs-lg); font-weight: 700; }
.ap-sub { margin: 0; color: var(--muted); }
.ap-text { white-space: pre-line; } /* crag.approach: the card's old free text, its line breaks kept */
.ap-dir { display: flex; align-items: center; gap: var(--sp-12); }
.ap-dir[hidden] { display: none; }
.ap-dir b { font-size: var(--fs-md); }
.ap-dir .pk-word { flex: none; white-space: nowrap; } /* 노지 · 무료 stays on one line next to the parking text */
.ap-dir.is-big b { font-size: var(--fs-xl); }
.ap-arrow { flex: none; width: 48px; height: 48px; display: grid; place-items: center; border-radius: var(--r-base); background: color-mix(in srgb, var(--accent) 12%, var(--surface)); color: var(--accent); }
.ap-arrow svg { width: 28px; height: 28px; }
.ap-wrong { margin: 0; padding: var(--sp-8) var(--sp-12); border: 1px solid color-mix(in srgb, var(--soon) 30%, var(--line)); border-radius: var(--r-base); background: color-mix(in srgb, var(--soon) 9%, var(--surface)); font-size: var(--fs-sm); }
.ap-wrong[hidden] { display: none; }
.ap-wrong b { color: var(--soon); }
.ap-nav { display: flex; gap: var(--sp-8); }
.ap-nav button { flex: 1; min-height: var(--tap); border: 1px solid var(--line-strong); border-radius: var(--r-base); background: none; color: var(--fg); font: inherit; font-weight: 600; white-space: nowrap; cursor: pointer; }
.ap-nav .ap-next { border: 0; background: var(--accent); color: var(--on-accent); }
.ap-nav button:disabled { opacity: .4; cursor: default; }
.ap-clear { justify-self: center; min-height: var(--tap); padding: 0 var(--sp-12); border: 0; background: none; color: var(--muted); font: inherit; font-size: var(--fs-xs); text-decoration: underline; white-space: nowrap; cursor: pointer; }
.ap-clear[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .ap-stop.is-cur .ap-dot { transform: none; } }
/* 싱글피치 루트 탭(src/routes-sheet.js, 암장 시트 .ws-panel 안): 개념도 칩(외벽 시트의 .rt-chips/.rt-chip 그대로) · 개념도(누르면 크게, 스크롤) · 출처 · 루트 표. 새 색은 없다. */
.routes-pane { display: grid; gap: var(--sp-12); padding-top: var(--sp-8); } /* 루트 탭: padding and scrolling are .ws-panel's */
.rs-topo { overflow: auto; border-radius: var(--r-base); background: var(--sunken); }
.rs-topo[hidden], .rs-credit[hidden] { display: none; }
.rs-zoom { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.rs-zoom img { display: block; width: 100%; max-height: 48dvh; object-fit: contain; }
.rs-topo.is-zoom { max-height: 70dvh; overscroll-behavior-x: contain; } /* a pan at its edge does not switch the sheet tab */
.rs-topo.is-zoom .rs-zoom { width: 200%; cursor: zoom-out; }
.rs-topo.is-zoom .rs-zoom img { max-height: none; }
.rs-topo.is-fail { display: grid; place-items: center; min-height: 120px; padding: var(--sp-16); }
.rs-fail { margin: 0; color: var(--muted); font-size: var(--fs-sm); font-weight: 600; }
.rs-credit { margin: 0; color: var(--muted); font-size: var(--fs-xs); }
.rs-tablebox { overflow-x: auto; overscroll-behavior-x: contain; }
.rs-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.rs-table th, .rs-table td { padding: var(--sp-8) var(--sp-8); border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.rs-table thead th { color: var(--muted); font-size: var(--fs-xs); font-weight: 700; white-space: nowrap; vertical-align: middle; }
.rs-table tbody th { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rs-table td:not(:nth-child(2)) { white-space: nowrap; }
.rs-tablewrap { position: relative; } /* the ! bubble opens over the table */
.rs-pioneer-why { text-align: right; } /* 초등자 정보: one ! at the top right of the table */
.rs-pl { display: block; }
.rs-pl + .rs-pl { margin-top: var(--sp-8); padding-top: var(--sp-8); border-top: 1px solid var(--line); }
.rs-prs { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-12); margin-top: var(--sp-4); color: var(--muted); } /* each route stays whole, groups wrap between them */
.rs-pr { white-space: nowrap; }
.rs-pl b { display: block; font-weight: 700; }
.rs-pioneer-why .sun-limit { max-height: 40dvh; overflow-y: auto; overscroll-behavior: contain; } /* 50 routes: the bubble scrolls */
/* 큰 글씨: 표가 옆으로 밀리지 않게 숫자 칸 여백을 줄이고, 장비·길이는 줄바꿈, 이름은 필요하면 글자 사이에서 끊는다 */
html[data-text="xlarge"] :is(.rs-table th, .rs-table td) { padding-inline: var(--sp-4); }
html[data-text="xlarge"] .rs-table :is(thead th, td:not(:nth-child(2), :nth-child(3))) { white-space: normal; }
html[data-text="xlarge"] .rs-table td:nth-child(2) { overflow-wrap: anywhere; }
html[data-text="xlarge"] .rs-table th:not([aria-sort="ascending"], [aria-sort="descending"]) .rs-th::after { display: none; } /* 320px: 안 쓰는 정렬 삼각형 자리(12px)가 이름 칸 폭을 먹어 이름이 음절 중간에서 끊겼다 */
.rs-name { display: block; font-weight: 600; }
.ws-sec-n { margin-left: var(--sp-8); color: var(--muted); font-size: var(--fs-md); font-weight: 600; white-space: nowrap; } /* 루트 24개 ⓘ: the count beside a card's title */
.rs-th { display: inline-flex; align-items: center; gap: var(--sp-4); min-height: var(--tap); margin: calc(var(--sp-8) * -1) 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; white-space: nowrap; }
button.rs-th { cursor: pointer; } /* every header is this 44px box (a sortable one is a button), so they share a line; a small triangle shows the order in use */
.rs-table th[aria-sort] .rs-th::after { content: ''; border: 4px solid transparent; border-top-color: transparent; opacity: 0; }
.rs-table th[aria-sort="ascending"] .rs-th::after { border-bottom-color: currentColor; border-top-width: 0; opacity: 1; }
.rs-table th[aria-sort="descending"] .rs-th::after { border-top-color: currentColor; border-bottom-width: 0; opacity: 1; }
.rs-table th[aria-sort="ascending"], .rs-table th[aria-sort="descending"] { color: var(--fg); }
.rs-bars-h { display: block; margin: 0 0 var(--sp-8); font-size: var(--fs-sm); }
.rs-mine { margin: 0; color: var(--fg); font-size: var(--fs-sm); font-weight: 700; }
.rs-table tr.is-mine { background: color-mix(in srgb, var(--accent) 10%, transparent); } /* the colour alone marks 내 그레이드 (user 2026-11-03: the ●/icon marks are kept for 완등·코멘트·베타 영상 later); same meaning as .gy-list li.mine: tokens only, so all three themes follow */
.rs-table tr.is-mine .rs-name { font-weight: 700; }
/* end routes sheet */

/* 눌림: 외벽 버튼과 같은 scale(.97) + --dur-press */
:is(.mode-switch button, button.ap-chip, .ap-clear, .ap-nav button) { transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out), border-color var(--dur-press) var(--ease-out); }
:is(.mode-switch button, button.ap-chip, .ap-clear, .ap-nav button):active { transform: scale(.97); }
/* ♥ in the list row, left of the name (app.js timeRow): a button beside the row's own button, over the room .rfav-gap leaves; 44 × 44 to tap */
.rfav-gap { flex: none; width: 22px; margin-right: -4px; }
.row-fav { position: absolute; z-index: 3; left: calc(var(--pad) + 35px); top: 8px; width: 44px; height: 44px; color: var(--muted); opacity: .8; } /* 44px, not --tap (that grows with the text size and would push the icon off the name's line); the icon stays where the 32px box put it */
.row-fav svg { width: var(--icon-sm); height: var(--icon-sm); }
.row-fav.on { opacity: 1; }
:is(.row, .crag-row):not(:has(.l1 .sunnow)) .row-fav { left: calc(var(--pad) - 11px); top: 6px; } /* a row with no sun chip starts its name at the edge */
:is(.row, .crag-row).has-photo.is-open .row-fav { color: var(--on-photo); opacity: 1; filter: drop-shadow(0 1px 2px rgb(0 0 0 / .55)); }
:is(.row, .crag-row).has-photo.is-open .row-fav.on { color: var(--fav); }
/* the dock floats over the photo's foot: the card's opening part rises 30px over the photo (its top 30px is clear, so the photo shows through), and the photo's own foot lifts to stay above it */
:is(.row, .crag-row).has-photo.is-open > .expand { position: relative; z-index: 2; margin-top: -30px; background: linear-gradient(to bottom, transparent 30px, var(--sheet) 30px); }
:is(.row, .crag-row).has-photo.is-open .expand-in > .dock:first-child { margin-top: 0; }
:is(.row, .crag-row).has-photo:not(.is-open) > .expand { transition-duration: 0s; transition-delay: 0s; } /* closing: the photo leaves first, so the dock and chips must not linger for the exit time */
:is(.row, .crag-row).has-photo > .expand { opacity: 1; } /* the dock lies over the photo: a fading card would show the photo through it. The card opens by its height alone (the closed one is hidden by visibility) */
:is(.row, .crag-row).has-photo.is-open .rhero-foot { bottom: calc(var(--icon-row) + 48px + var(--sp-4)); } /* the hours cap sits above the camera / share row */
:is(.row, .crag-row).has-photo.is-open .rhero-tools { left: calc(var(--pad) - 2px); right: calc(var(--pad) - 2px); bottom: calc(var(--icon-row) + var(--sp-4)); height: 44px; display: grid; grid-template-columns: 1fr auto 1fr; pointer-events: none; }
:is(.row, .crag-row).has-photo.is-open .rhero-tools > * { pointer-events: auto; }
:is(.row, .crag-row).has-photo.is-open .rhero-tools .rhero-add { grid-column: 1; grid-row: 1; justify-self: start; width: 44px; height: 44px; }
:is(.row, .crag-row).has-photo.is-open .rhero-tools .rhero-add svg { width: 24px; height: 24px; }
:is(.row, .crag-row).has-photo.is-open .rhero-tools .rhero-dots { grid-column: 2; grid-row: 1; }
.ph-hero { padding-bottom: calc(var(--icon-row) + 44px + var(--sp-4)); }
.ph-hero + .dock { position: relative; z-index: 2; margin-top: -30px; }
/* focus over a photo: a white ring (the photo tokens), the group's dark drop-shadow lifts it off a bright sky */
:is(.row, .crag-row).has-photo.is-open :is(.row-fav, .rhero-add, .photo-tools .icon-btn):focus-visible { outline: 2px solid var(--on-photo); outline-offset: -4px; border-radius: 50%; }
/* camera / share over a photo: a dark glass disc (40px) inside the 44px target, so a bright photo does not swallow the white icon. The group's drop-shadow is dropped: a filter on the parent would blank the backdrop blur */
:is(.row, .crag-row).has-photo.is-open .photo-tools { filter: none; right: calc(var(--pad) - 2px); } /* the glass disc is inset 2px: its outer edge lands on the gutter */
:is(.row, .crag-row).has-photo.is-open :is(.rhero-tools .rhero-add, .photo-tools .icon-btn) { position: relative; isolation: isolate; color: var(--on-photo); opacity: 1; }
:is(.row, .crag-row).has-photo.is-open :is(.rhero-tools .rhero-add, .photo-tools .icon-btn)::before { content: ""; position: absolute; inset: 2px; z-index: -1; border-radius: 50%; background: rgb(20 22 24 / .32); border: 1px solid rgb(255 255 255 / .28); box-shadow: 0 2px 8px rgb(0 0 0 / .2), inset 0 1px 0 rgb(255 255 255 / .25); -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%); }
@media (prefers-reduced-transparency: reduce) { :is(.row, .crag-row).has-photo.is-open :is(.rhero-tools .rhero-add, .photo-tools .icon-btn)::before { background: rgb(20 22 24 / .72); -webkit-backdrop-filter: none; backdrop-filter: none; } }
/* the 예약하기 band under the dock (card-parts.js reserveBand): 44px, a sun tint; a must-reserve wall (.required) gets a yellow ! badge and a deeper tint */
.reserve-band { display: flex; align-items: center; gap: var(--sp-8); min-height: 44px; margin-top: var(--sp-8); padding: 0 var(--sp-12); border-radius: var(--r-base); background: var(--sunken); color: var(--fg); text-decoration: none; font-size: var(--fs-sm); }
.reserve-band.required { background: var(--sunken); box-shadow: inset 3px 0 0 var(--warn); } /* 예약 필수: a --warn bar, no black fill (black fill is 길찾기's) */
.reserve-band svg { width: 18px; height: 18px; flex: none; }
.rb-badge { flex: none; display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid var(--warn); color: var(--warn); font-style: normal; font-size: var(--fs-xs); font-weight: 800; line-height: 1; }
.reserve-band b { flex: none; font-weight: 700; white-space: nowrap; }
.reserve-band span { margin-left: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reserve-band:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.reserve-band:active { transform: scale(.99); }
/* a wall with no hours: the hero says it once, quietly (not 2rem like an hours range), and the placeholder block is tall enough for the dock that floats over its foot */
.rhero-cap b.hero-note { display: inline; font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0; line-height: 1.3; } /* closed day / no hours: one small line ("오늘 휴무"), the hours of an open or coming day are under the bar */
.rhero-cap:has(.hero-note) small { display: inline; margin-right: var(--sp-8); }
.ph-hero { min-height: 112px; padding-top: var(--sp-8); } /* a thin block: the camera / share row and the dock's overlap are all it holds; about the same height with a note (closed, no hours) or only the icons */
.row.has-photo.is-open .rmeta { font-weight: 600; } /* the region line over a bright sky */
/* one frame for the camera / share row, with or without a photo (--icon-row: how far the icons' tap boxes stand off the foot of the photo or the block; the dock covers the lowest 30px,
   the photo's credit takes the strip under the camera). The camera is always at the left, share at the right, on one horizontal line. */
.row.has-photo.is-open .rhero > .credit { position: absolute; z-index: 2; left: var(--pad); bottom: 34px; padding: var(--sp-16) var(--sp-8); margin: calc(var(--sp-16) * -1) calc(var(--sp-8) * -1); width: max-content; opacity: 1; color: #fff; text-shadow: 0 0 3px rgb(0 0 0 / .75), 0 1px 3px rgb(0 0 0 / .8); max-width: calc(100% - var(--pad) * 2 - 56px); font-size: var(--fs-xs); line-height: 1.2; pointer-events: auto; }
.ph-hero { flex-direction: column; align-items: flex-start; justify-content: flex-end; }
.ph-hero :is(.rhero-add, .photo-tools) { color: color-mix(in srgb, var(--accent) 70%, var(--fg)); }
.ph-hero > .rhero-add { position: absolute; left: calc(var(--pad) - 2px); bottom: var(--icon-row); margin: 0; } /* the same box as the photo's: its disc edge lands on the gutter */
.ph-hero > .photo-tools { right: calc(var(--pad) - 2px); }
.ph-hero :is(.rhero-add, .photo-tools .icon-btn) { isolation: isolate; }
.ph-hero .photo-tools .icon-btn { position: relative; }
.ph-hero :is(.rhero-add, .photo-tools .icon-btn)::before { content: ""; position: absolute; inset: 2px; z-index: -1; border-radius: 50%; background: color-mix(in srgb, var(--fg) 8%, transparent); border: 1px solid var(--line); } /* the photo card's round buttons, in the block's own quiet colours (no glass: nothing to blur) */
.rhero:not(.ph-hero) .rhero-cap b.hero-unk { color: inherit; text-shadow: 0 0 3px rgb(0 0 0 / .75), 0 1px 3px rgb(0 0 0 / .8); } /* on a photo: the photo's white, not --muted grey */
.rhero-cap b.hero-unk { font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0; color: var(--muted); margin-right: var(--sp-16); } /* "운영시간을 아직 몰라요": a plain line, not the big hero number */
input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; background: var(--muted); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center / contain no-repeat; cursor: pointer; } /* the browser's blue clear ✕ → a muted one */
.fees .f-free { margin: 0; padding: var(--sp-8) 0; font-size: var(--fs-sm); }
.fees .f-nb { white-space: nowrap; } /* a session's label and its hours each stay whole; the line breaks between them */
html[data-text="xlarge"] .fees .f-all { white-space: normal; overflow-wrap: anywhere; } /* big type: a text cell wraps instead of overflowing the fixed table; an amount never breaks inside its digits */
html[data-text="xlarge"] .fees thead th:nth-child(2) { width: 23%; }
html[data-text="xlarge"] .fees td, html[data-text="xlarge"] .fees th { padding-left: var(--sp-2); padding-right: var(--sp-2); }
html[data-text="xlarge"] .fees .f-won { font-size: var(--fs-xs); } /* the prices are the widest cells: one step down so 4,000원 fits two columns at 320px */
html[data-text="xlarge"] .fees .f-pg { flex-direction: column; gap: 0; align-items: flex-start; } /* 대상 over 거주지 */
html[data-text="xlarge"] .fees .f-pg > :last-child { margin-left: 0; }
html[data-text="xlarge"] .fees tbody th, html[data-text="xlarge"] .fees thead th:first-child { width: 20%; }
.cal-share-sub { margin: 0 0 var(--sp-8); text-align: center; }
.ms-nav { display: flex; align-items: center; justify-content: center; gap: var(--sp-8); font-weight: 600; }
.ms-nav .cal-nav:disabled { opacity: .3; }
.ps-dome-why { margin: var(--sp-4) 0 0; text-align: right; }

/* 새 암장 제보 (src/crag-submit-view.js): existing tokens only */
.csub-nowrap, .csub-entry { white-space: nowrap; }
.csub-body { display: grid; gap: var(--sp-8); padding-top: var(--sp-8); }
.csub-near, .csub-mine-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); }
.csub-mine { list-style: none; margin: 0; padding: 0 var(--sp-8); display: grid; gap: var(--sp-4); font-size: var(--fs-sm); }
.csub-mine[hidden] { display: none; }
.csub-mine-row > :first-child { min-width: 0; overflow-wrap: anywhere; }
.csub-mine-row > .chip { white-space: nowrap; flex: none; }
.csub-near { flex-wrap: wrap; }
.csub-near > :first-child { flex: 1 1 auto; min-width: 0; }
.csub-near .csub-dist { white-space: nowrap; }
.csub-near > .sh-hint { flex-basis: 100%; }
.csub-body .btn.primary:disabled { opacity: .45; cursor: default; }

/* 외출(일정) 카드 (src/trip-view.js): 외벽 줄의 날씨 칩(--chip·--glyph) · 이름 · 날짜 · 배지, 아래 .irow 줄과 dock 모양 버튼. 새 토큰·새 색 없음. */
.trip-card { background: var(--surface); border-radius: var(--r-base); box-shadow: inset 0 0 0 1px var(--line); padding: var(--sp-12); margin-bottom: var(--sp-8); }
.ln:focus-visible, .trip-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.trip-head { display: grid; grid-template-columns: var(--chip) minmax(0, 1fr) auto; gap: 0 var(--sp-12); align-items: start; }
.trip-wx { display: flex; flex-direction: column; align-items: center; margin: 0; line-height: 1; }
.trip-chip { display: grid; place-items: center; width: var(--chip); height: var(--chip); border-radius: var(--r-md); background: var(--sunken); color: var(--fg); }
.trip-chip svg { width: var(--glyph); height: var(--glyph); }
.trip-wx.no-fc .trip-chip { color: var(--muted); } /* 예보 없음: 달력 그림, 날씨처럼 보이지 않게 옅게 */
.trip-wx .wx-temp { position: static; transform: none; margin-top: var(--sp-4); color: var(--fg); font-weight: 700; } /* D-day 또는 기온: 칩 아래 흐름 안에 */
.trip-t { min-width: 0; align-self: center; }
.trip-name { margin: 0; font-size: var(--fs-md); font-weight: 800; line-height: 1.3; }
.trip-date { margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.trip-badge { padding: var(--sp-2) var(--sp-8); border-radius: var(--r-pill); box-shadow: inset 0 0 0 1px var(--line); font-size: var(--fs-xs); font-weight: 700; color: var(--muted); white-space: nowrap; }
.trip-badge.rain { color: var(--warn); box-shadow: inset 0 0 0 1px var(--warn); } /* 글자가 상태를 말한다: 색만으로 표시하지 않는다 */
.trip-badge.today { color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.trip-top .trip-badge.today { background: var(--accent); color: var(--on-accent); box-shadow: none; } /* 시안 ③: 당일 카드의 오늘 알약은 채움 */
.trip-badge.mine { background: var(--sunken); box-shadow: none; color: var(--fg); }
.trip-blk { margin-top: var(--sp-12); }
.trip-blk-t { margin: 0 0 var(--sp-2); font-size: var(--fs-xs); font-weight: 600; color: var(--muted); }
.trip-blk .irow:first-of-type { border-top: 0; }
.trip-card > .irow { margin-top: var(--sp-8); }
.trip-card .chip-bar { margin: var(--sp-12) 0 0; padding-bottom: 0; }
.trip-acts { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin-top: var(--sp-12); }
.trip-btn { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; min-height: var(--h-l); padding: 0 var(--sp-12); border: 0; border-radius: var(--r-pill); background: var(--sunken); box-shadow: var(--shadow-seg), inset 0 0 0 1px var(--line); color: var(--fg); font: inherit; font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; cursor: pointer; } /* dock-go 모양 */
.trip-btn.main { background: var(--accent); box-shadow: var(--shadow-seg); color: var(--on-accent); font-weight: 800; } /* 이 카드의 일: 다녀왔어요와 같은 채움 */
.trip-card > .trip-btn { width: 100%; margin-top: var(--sp-12); }
/* 일정 카드의 날씨 머리(.pc, 시안 home-v3 2026-11-07): 장소 · 날짜 줄 → 날씨 제목 → 날씨 칸 둘(비 오는 칸은 --rain-tint) → 안내. 새 토큰 없음 */
.pc .pc-eye { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-8); min-width: 0; font-size: var(--fs-sm); font-weight: 700; color: var(--muted); }
.pc .pc-place { flex: 1; min-width: 0; }
.pc .pc-head { margin: var(--sp-8) 0 var(--sp-12); font-size: var(--fs-lg); font-weight: 800; line-height: 1.3; }
.pc .pc-wx { display: flex; gap: var(--sp-8); }
.pc .pc-cell { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--sp-8); padding: var(--sp-12); border-radius: var(--r-base); background: var(--sunken); }
.pc .pc-cell.wet { background: var(--rain-tint); color: var(--warn); }
.pc button.pc-cell { width: 100%; border: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; } .pc button.pc-cell .pv-arrow { margin-left: auto; color: var(--muted); } .pc button.pc-cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } /* 누르면 날씨 자세히: 읽기만 하던 칸에 ›를 붙인다 */
.pc .pc-g svg { width: var(--icon-sm); height: var(--icon-sm); display: block; }
.pc .pc-t b { display: block; font-size: var(--fs-sm); }
.pc .pc-t small { font-size: var(--fs-xs); color: var(--muted); }
.pc .pc-cell.wet small { color: var(--warn); }
.pc .pc-note { margin: var(--sp-12) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.pc .trip-blk .trip-opt { min-height: 48px; }
html[data-text="large"] .pc .pc-wx, html[data-text="xlarge"] .pc .pc-wx { flex-direction: column; }
@media (max-width: 360px) { .pc .pc-wx { flex-direction: column; } }
.trip-ask { margin: var(--sp-12) 0 0; font-size: var(--fs-md); font-weight: 700; }
/* 누르는 줄 한 부품(card-parts lineRow): 칩/그림 · 제목 위 보조 · 끝 값 또는 ›. 날짜 줄·일정 후보·암장 추천 줄이 같이 쓴다 */
.ln { display: flex; align-items: center; gap: var(--sp-8); width: 100%; min-height: calc(var(--tap) + var(--sp-12)); margin-bottom: var(--sp-8); padding: var(--sp-8) var(--sp-12); border: 0; border-radius: var(--r-base); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.trip-dday { display: flex; align-items: baseline; gap: var(--sp-8); margin: 0 var(--sp-4) var(--sp-8); font-size: var(--fs-xs); font-weight: 700; color: var(--muted); } /* 칩 줄과 카드 사이: D-n은 중립색(비 예보는 카드 안 알약이 말한다) */
.trip-dday b { font-size: var(--fs-md); font-weight: 700; color: var(--fg); } /* 800 → 700(시안 home-v3 검수): 카드 제목(800)과 겨루지 않게 */
.home-top { padding-top: var(--sp-8); } /* 칩 줄과 맨 위 카드·일정 잡기 줄 사이 */
.home-top .trip-card, .home-top .ln { margin-bottom: var(--sp-12); } /* 맨 위 카드와 접힌 줄 사이(카드 안 간격 12와 같게) */
.ln-tile { flex: none; display: grid; place-items: center; width: var(--chip); height: var(--chip); border-radius: var(--r-md); background: var(--sunken); color: var(--muted); } /* 추천 줄의 앞 그림 칸: 날씨 칩과 같은 40px */
.ln-tile + .ln-t .ln-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* 추천 줄 이름은 한 줄(shortName) */
.ln-tile svg { width: var(--icon-sm); height: var(--icon-sm); }
.ln-end { flex: none; display: inline-flex; align-items: center; gap: var(--sp-4); }
.ln-v { font-size: var(--fs-xs); font-weight: 700; color: var(--muted); white-space: nowrap; } /* 줄 끝 값: 열림 · 22시까지 / 19시에 열어요 */
.ln-v.open { color: var(--open); }
.home-note { margin: var(--sp-8) var(--sp-4) var(--sp-12); } /* 누를 곳 없는 안내: 카드 면 없이 회색 한 줄 */
.ln:last-child { margin-bottom: 0; } /* 줄 사이 간격은 줄이, 마지막 아래는 부모가 */
.ln-t { flex: 1; min-width: 0; }
.ln-n { display: block; font-size: var(--fs-sm); font-weight: 700; }
.ln-m { display: block; margin: 0; font-size: var(--fs-xs); color: var(--muted); }
.ln.sel { background: var(--sunken); } /* 근거 있는 첫 선택지(추천) */
.tg { flex: none; display: inline-flex; align-items: center; min-height: var(--h-s); margin-left: var(--sp-4); padding: 0 var(--sp-8); border-radius: var(--r-pill); background: var(--sunken); font-size: var(--fs-xs); font-weight: 700; color: var(--muted); white-space: nowrap; } /* 작은 알약 한 모양: 이름 옆 · 줄 끝 */
.tg.ok { color: var(--open); background: color-mix(in srgb, var(--open) 8%, var(--surface)); } /* 추천: 글자가 말한다, 색은 거들 뿐 */
.tg.rain { color: var(--warn); background: var(--rain-tint); } /* 비 예보: 연분홍 면(2026-11-07 승인) */
.trip-line { margin: 0; padding: var(--sp-4) 0; font-size: var(--fs-sm); font-weight: 600; line-height: 1.45; } /* 누르지 않는 줄(지금 · 플랜B 후보): 이름 칸 없이 */
.trip-line + .trip-line { border-top: 1px solid var(--hair); }
/* 시안 ⑤: 내 암장 줄들과 맨 아래 외벽 더 찾기 줄은 한 장의 면, 줄 사이는 가는 선(낱장 카드 아님) */
.ln-box { background: var(--surface); border-radius: var(--r-base); box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; }
.home-top .ln-box { margin-bottom: var(--sp-12); }
.ln-box .ln { margin: 0; border-radius: 0; background: transparent; box-shadow: none; }
.ln-box .ln + .ln { border-top: 1px solid var(--hair); }
/* 시안 ④: 일정 없는 홈의 열린 외벽 3곳(제목줄 + 정렬 알약 + 한 면 상자). 전체 시간표는 외벽 더 찾기 시트에 */
.home-open { margin: var(--sp-4) 0 var(--sp-12); }
.home-open-h { display: flex; align-items: center; justify-content: space-between; margin: var(--sp-12) var(--sp-4) var(--sp-8); }
.home-open-h b { font-size: var(--fs-md); font-weight: 800; }
.home-open-h .sort-btn { white-space: nowrap; }
.home-open .ln-box { margin-bottom: 0; }

/* 일정 탭 (src/sched-tab-view.js): 헤더 + 달력(.cal-* 그대로, 일정 있는 날 = .cal-plan 점) 또는 목록(.trip-card), 맨 아래 매주 운동(.sched-week). 새 토큰·새 색 없음. */
#panel-sched { margin-top: var(--sp-16); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-16); }
.sched-hd { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); }
.sched-title { margin: 0; font-size: var(--fs-lg); font-weight: 800; }
.sched-tg { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-4); flex: none; min-width: var(--tap); min-height: var(--tap); padding: 0 var(--sp-8); border: 0; border-radius: var(--r-md); background: none; color: var(--fg); font: inherit; font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; cursor: pointer; } /* 44px: 목록 ⇄ 달력 (그림 + 글자) */
.sched-tg svg { width: 22px; height: 22px; }
.sched-tg:active { background: var(--sunken); }
.sched-tg:focus-visible, .sched-add:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sched-h { margin: 0 0 var(--sp-8); font-size: var(--fs-base); font-weight: 700; }
.sched-h.sched-q { font-size: var(--fs-lg); font-weight: 800; } /* 일정 0개: 주말 질문과 평일 질문은 같은 무게 */
.sched-n { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); }
.sched-sec > .sh-hint { margin-bottom: var(--sp-8); }
.sched-first .trip-acts { margin: 0 0 var(--sp-12); }
.sched-day .trip-card { margin-bottom: 0; }
.sched-day { display: grid; gap: var(--sp-8); }
.sched-day > .irow { border-top: 0; }
.sched-add { width: 100%; }
.sched-week { display: grid; gap: var(--sp-8); }
.sched-week > .sched-h { margin: 0; }
@media (hover: hover) and (pointer: fine) { .sched-tg:hover { background: color-mix(in srgb, var(--fg) 5%, transparent); } }

/* 일정 추가 시트 (src/trip-sheet.js, #tripAdd): 기록 추가 시트의 .la-field 검색 · .la-chip 날짜 칩 · .la-foot 저장 줄, 후보는 .trip-fold 줄. 새 토큰·새 색 없음. */
.tripadd-cands { display: grid; margin-top: var(--sp-12); }
.tripadd-cand { margin-bottom: var(--sp-8); }
.tripadd-cand[aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--accent); } /* 고른 곳: 테두리 + '선택' 글자(색만으로 말하지 않는다) */
.tripadd-cand .trip-badge[hidden] { display: none; }
.tripadd-none { padding: var(--sp-8) 0; }
div.sh-row.tripadd-when { display: block; } /* 날짜 label above the chips, like 장소 (a div.sh-row is a flex row elsewhere) */
.tripadd-days { margin-bottom: 0; }
.tripadd-custom { display: grid; gap: var(--sp-12); margin-top: var(--sp-12); }
.tripadd-custom[hidden] { display: none; }
.tripadd-full { font-size: var(--fs-base); font-weight: 600; }
/* 기록 추가 시트의 완등 칸 + 프로젝트 했어요 (src/route-field.js): la-* 칩·칸·체크 줄을 그대로 쓰고 배치만 더한다. 새 색 없음. */
.la-route { row-gap: var(--sp-8); }
.la-route > .sh-label { flex-basis: 100%; margin: 0; }
.la-route .la-chips { flex-basis: 100%; margin-bottom: 0; }
.la-route .la-chips[hidden], .la-route-body[hidden], .la-route .la-err[hidden] { display: none; }
.la-route-past { align-items: center; }
.la-route-past-q { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.la-route-on { flex-basis: 100%; }
.la-route-body { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: var(--sp-8) var(--sp-12); flex-basis: 100%; }

/* 외벽 더 찾기 시트(일정이 있는 날): 화면 80%, 검색·조건·시간·시간표가 이 안에서 스크롤 (시안 ⑥) */
.sheet.is-find { height: 80dvh; overflow-x: clip; --stick-h: 52px; } /* 시트 머리(.sh-head 52px) 아래에 axis·band가 붙는다: 머리를 가리지 않게 */ .sheet.is-find .board { overflow-x: clip; } .sheet.is-find form { padding-bottom: calc(var(--sp-16) + env(safe-area-inset-bottom)); } .sheet.is-find .filters { margin-top: var(--sp-8); } .sheet.is-find .board { margin-top: var(--sp-12); }
#arriveRow { cursor: default; margin-top: var(--sp-12); } #arriveRow[hidden] { display: none; } #arriveRow .arrive-pill { position: relative; } #arriveRow .arrive-pill::before { content: ""; position: absolute; inset: -6px -4px; } /* 알약은 32px 그대로, 눌리는 면만 44px */ /* 시안 ④ 박스 줄: 키보드는 알약 하나, 줄 어디를 눌러도 같은 시트(›는 없음) */ html[data-text="xlarge"] #arriveRow { flex-wrap: wrap; } html[data-text="xlarge"] #arriveRow .ln-t { flex-basis: 100%; } html[data-text="xlarge"] #arriveRow .arrive-pill { margin-left: 0; } /* 큰 글씨: 질문이 한 줄을 다 쓰고 알약은 그 아래 */
.arrive-pill { margin-left: auto; white-space: nowrap; } /* 도착 시각 알약: 시간표 머리 오른쪽, 정렬 알약과 같은 모양(3a) */
#sortBtn { margin-left: var(--sp-8); }
.ws-wx .wx-box { margin: 0; } /* 시간 탭 날씨 칸: 제목 아래 카드의 날씨 상자가 그대로, 위 여백은 제목 줄이 맡는다 */
.ws-wx-hrs { margin-top: var(--sp-12); flex-wrap: wrap; row-gap: var(--sp-8); } /* 큰 글씨: 6칸이 한 줄에 안 들어가면 줄바꿈(가로 넘침 없음) */
.ws-wx-hrs li { flex: 1 1 0; }
.ws-wx-none { margin: 0; }

/* 홈 시안 B (2026-11-08): 올리브 = 주 행동 하나(+ 일정 잡기 칩·빈 홈 줄), 모래 = 보조 알약·앞 칸. 도착 줄의 설명은 읽는 사람에게만 남기고, 알약과 목록이 위계를 잡는다 */
.ln[data-home="ask"] { background: var(--olive); box-shadow: none; color: var(--on-olive); }
.ln[data-home="ask"] .ln-m, .ln[data-home="ask"] .pv-arrow { color: var(--on-olive); }
#arriveRow { display: none; } /* 도착 시각 알약은 열린 외벽 섹션 안(.home-open-ctl)으로 옮겼다: 목록을 바꾸는 조작이라 목록 위에 따로 두지 않는다 */
.home-open-card { background: var(--surface); border-radius: var(--r-16); box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; } /* 열린 외벽: 제목은 카드 위, 알약(도착 시각·정렬)과 목록은 한 카드 안 */
.home-open-h .arrive-pill { margin-left: var(--sp-8); }
.home-open-ctl { display: flex; justify-content: flex-end; margin: var(--sp-8) var(--sp-8) 0; } /* 8px: 카드의 overflow:hidden이 알약 눌림 영역(위 6px)을 자르지 않게 */
/* 정렬은 눌러서 바꾸는 조작이라 알약 모양을 지키되, 도착 시각(조건)보다 작게 카드 안 위쪽에 둔다 */
.home-open .sort-btn.sort-quiet { background-color: var(--sand); color: var(--sand-ink); font-weight: 600; }
.home-open .ln-box { box-shadow: none; border-radius: 0; background: transparent; border-top: 1px solid var(--hair); }
.home-open-card > .home-note { margin: 0 var(--sp-16) var(--sp-12); }
.home-open-ctl .sort-btn, .home-open-ctl .arrive-pill { margin-left: 0; }
.home-open .sort-btn, .home-open .arrive-pill { background-color: var(--sand); color: var(--sand-ink); }
.home-open .ln-tile { background: none; color: var(--muted); }
.home-open .ln-tile.ln-sun { color: var(--sun-ui); }
.home-open-h b { font-size: var(--fs-xl); }
/* 일정이 없는 홈은 올리브 줄이 일정 잡기 입구: 맨 위 칩의 같은 이름 입구는 숨긴다(일정이 있으면 줄이 없으니 칩이 남는다) */
body:has(#homeTop .ln[data-home="ask"]) .scrub-days .day-add { display: none; }

/* 홈 시안 B 확정(2026-11-08): 도착 알약 = 올리브 외곽선(조건), 정렬 알약 = 모래 면(순서). 다크는 일정 잡기 줄을 --olive-soft 면 + 올리브 글자로 낮춘다 */
.home-open-h .arrive-pill { background-color: transparent; box-shadow: inset 0 0 0 1.5px var(--olive); color: var(--olive); font-weight: 600; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ln[data-home="ask"] { background: var(--olive-soft); color: var(--olive); box-shadow: inset 0 0 0 1px rgb(180 199 101 / .28); }
  :root:not([data-theme="light"]) .ln[data-home="ask"] .ln-m, :root:not([data-theme="light"]) .ln[data-home="ask"] .pv-arrow { color: var(--olive); }
}
