
/* The two pills' glyphs: the mask carries currentColor, so a pressed pill and a dim one draw the same shape. */
:root {
  --board-icon-up: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 10v12'/%3E%3Cpath d='M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z'/%3E%3C/svg%3E");
  --board-icon-down: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17 14V2'/%3E%3Cpath d='M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z'/%3E%3C/svg%3E");
  --board-icon-reply: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 18v-2a4 4 0 0 0-4-4H4'/%3E%3Cpath d='m9 17-5-5 5-5'/%3E%3C/svg%3E");
  --board-icon-bookmark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 3H7c-1.1 0-2 .9-2 2v16l7-3 7 3V5c0-1.1-.9-2-2-2z'/%3E%3C/svg%3E");
}
/* Standalone parts retain their surfaces when a custom arrangement uses them separately. */
.post-head, .post-body { background: var(--board-surface); border: 1px solid var(--board-line); border-radius: var(--board-radius-l); box-shadow: var(--board-shadow); }
.post-head { padding: var(--board-card-pad); }
.post-body { margin-top: var(--board-space-3); padding: var(--board-card-pad); }
/* One document surface contains the heading, prose and its actions. Standalone parts above
 * keep their frame for custom arrangements; the standard arrangement groups them here. */
.post-document, .post-discussion { background: var(--board-surface); border: 1px solid var(--board-line); border-radius: var(--board-radius-l); box-shadow: var(--board-shadow); }
.post-document .post-head, .post-document .post-body { background: none; border: 0; border-radius: 0; box-shadow: none; }
.post-document .post-head { border-bottom: 1px solid var(--board-line); }
.post-document .post-body { margin-top: 0; }
/* 말머리 and the board as chips, so the title stands alone in the h1. */
.post-chips { display: flex; flex-wrap: wrap; gap: var(--board-space-2); margin: 0 0 var(--board-space-3); }
.chip { display: inline-block; padding: 2px var(--board-space-2); border-radius: var(--board-radius-s); background: var(--board-tint); color: var(--board-mid); font-size: var(--board-size-meta); }
.chip:hover { text-decoration: none; background: var(--board-tint-2); color: var(--board-text); }
.post-title { font-size: var(--board-size-title); font-weight: var(--board-weight-title); margin: 0; letter-spacing: -0.03em; line-height: var(--board-leading-tight); }
/* In the head the badges lead the chip row; the row's own gap is the spacing, so the badge's inline margin comes off (board-skin.md §2). */
.post-chips .gb-badge { margin-right: 0; }
/* The head's chip row draws chip and badge as one box (the legacy PostDetailView .gb-badge); no hover tint. */
.post-chips .chip, .post-chips .gb-badge { padding: 0.22rem 0.48rem; border: 1px solid var(--board-line); border-radius: 0.35rem; background: var(--board-tint); color: var(--board-dim); font-size: var(--board-size-caption); font-weight: var(--board-weight-bold); line-height: 1.6; }
.post-chips .chip:hover { background: var(--board-tint); color: var(--board-dim); }
.post-chips .gb-badge.gb-badge-notice { border-color: var(--board-accent); background: var(--board-accent); color: var(--board-on-accent); }
.post-chips .gb-badge.gb-badge-locked, .post-chips .gb-badge.gb-badge-secret { border-color: var(--board-danger); background: var(--board-danger); color: var(--board-on-accent); }
.post-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--board-space-2) var(--board-space-4); overflow: hidden; margin: var(--board-space-3) 0 0; color: var(--board-dim); font-size: var(--board-size-meta); }
.post-meta .gb-author { display: inline-flex; align-items: center; gap: var(--board-space-2); color: var(--board-text); font-weight: var(--board-weight-bold); }
.post-meta .gb-avatar { flex: none; width: 1.5rem; height: 1.5rem; border-radius: 50%; object-fit: cover; }
.post-meta .gb-avatar-initial { display: inline-flex; align-items: center; justify-content: center; background: var(--board-accent); color: var(--board-on-accent); font-size: var(--board-size-caption); }
.post-meta time, .post-meta .gb-views { display: inline-flex; align-items: center; gap: var(--board-space-1); font-variant-numeric: tabular-nums; }
.post-meta .gb-icon { flex: none; opacity: 0.65; }
/* A standalone page's body (.gb-static-page, /about) reads like a post's: a code line wider than a phone scrolls in its box instead of widening the page. The body runs the card's whole inner width, as production's does: prose, pre, table and embed all take the column, and no measure caps the text. */
:is(.post, .gb-static-page) .gb-body { font-size: var(--board-size-read); line-height: var(--board-leading-read); }
/* Prose gets a reading measure; tables, code and media retain the document's full width. */
:is(.post, .gb-static-page) .gb-body > :is(p, ul, ol, blockquote) { max-width: 70ch; }
:is(.post, .gb-static-page) .gb-body > :first-child { margin-top: 0; }
:is(.post, .gb-static-page) .gb-body h1, :is(.post, .gb-static-page) .gb-body h2, :is(.post, .gb-static-page) .gb-body h3 { margin: 1.6em 0 0.5em; }
:is(.post, .gb-static-page) .gb-body h1, :is(.post, .gb-static-page) .gb-body h2 { font-size: var(--board-size-display); }
:is(.post, .gb-static-page) .gb-body h3 { font-size: var(--board-size-head); }
:is(.post, .gb-static-page) .gb-body p, :is(.post, .gb-static-page) .gb-body ul, :is(.post, .gb-static-page) .gb-body ol, :is(.post, .gb-static-page) .gb-body pre, :is(.post, .gb-static-page) .gb-body blockquote, :is(.post, .gb-static-page) .gb-body table { margin: 0 0 1em; }
:is(.post, .gb-static-page) .gb-body a { color: var(--board-text); text-decoration: underline; text-underline-offset: 0.15em; }
:is(.post, .gb-static-page) .gb-body pre { padding: var(--board-space-4) var(--board-space-5); background: var(--board-tint); border-radius: var(--board-radius); overflow: auto; font-family: var(--board-mono); font-size: 0.85em; line-height: var(--board-leading-ui); }
:is(.post, .gb-static-page) .gb-body code { font-family: var(--board-mono); font-size: 0.9em; background: var(--board-tint); padding: 0.1em 0.35em; border-radius: var(--board-radius-s); }
:is(.post, .gb-static-page) .gb-body pre code { padding: 0; background: none; }
:is(.post, .gb-static-page) .gb-body blockquote { margin-left: 0; padding: var(--board-space-1) var(--board-space-4); border-left: 2px solid var(--board-ink); color: var(--board-mid); }
:is(.post, .gb-static-page) .gb-body table { border-collapse: collapse; }
:is(.post, .gb-static-page) .gb-body th, :is(.post, .gb-static-page) .gb-body td { padding: var(--board-space-2) var(--board-space-3); border-bottom: 1px solid var(--board-line); text-align: left; }
:is(.post, .gb-static-page) .gb-body th { border-bottom-color: var(--board-ink); }
/*
 * A table wider than the card on a phone scrolls inside it instead of squeezing every column into a
 * letter-wide strip (a post's spec table came out 1,462px tall at 390). Block-level keeps the table
 * layout and lets it overflow the card's inner width; the cell floor keeps a column readable while
 * long text still wraps — nowrap would run a long cell out to one line.
 */
@media (max-width: 47.99rem) {
  :is(.post, .gb-static-page) .gb-body table { display: block; max-width: 100%; overflow-x: auto; }
  :is(.post, .gb-static-page) .gb-body th, :is(.post, .gb-static-page) .gb-body td { min-width: 4.5rem; }
}
:is(.post, .gb-static-page) .gb-body hr { border: 0; border-top: 1px solid var(--board-line); margin: var(--board-space-7) 0; }
:is(.post, .gb-static-page) .gb-body img { display: block; margin: var(--board-space-3) 0; border-radius: var(--board-radius-s); }
/* An embed keeps its width attribute (a YouTube iframe says 560), which on a phone runs past the card. It never grows past the text column, and a video keeps 16:9 as it narrows instead of the attribute's height banded in black. */
:is(.post, .gb-static-page) .gb-body iframe, :is(.post, .gb-static-page) .gb-body video, :is(.post, .gb-static-page) .gb-body embed { display: block; max-width: 100%; margin: var(--board-space-3) 0; }
:is(.post, .gb-static-page) .gb-body iframe[src*="youtube"], :is(.post, .gb-static-page) .gb-body iframe[src*="youtu.be"] { height: auto; aspect-ratio: 16 / 9; border: 0; }
/* A provider frame's wrapper holds the margin, and the link to the original sits right under the frame. */
:is(.post, .gb-static-page) .gb-body .gb-embed-frame iframe { margin: 0; border: 0; }
/* A paragraph with nothing in it is the author's blank line, as it was on the old board: it holds a line's height instead of collapsing to nothing. */
:is(.post, .gb-static-page) .gb-body p:empty::before { content: "\00a0"; }
/* The og-card plugin ships its own sheet for these cards, and that sheet already carries the geometry the card needs: the thumbnail is flush with the frame it fills, and the text keeps its own inset. The skin hands it the board's colours and type scale and nothing else — a second opinion on the padding here is what pushed the thumbnail off its own frame (board-skin.md §2). One extra class step is all the weight these need. */
.gb-plugin-og-card .gb-link-card, :is(.post, .gb-static-page) .gb-body .gb-link-card { background: var(--board-tint); border-color: var(--board-line); }
.gb-plugin-og-card .gb-link-card-thumb, :is(.post, .gb-static-page) .gb-body .gb-link-card-thumb { background: var(--board-line); }
/* Every other picture in a post stands on its own with room around it and keeps its own height; this one is the frame's own fill, so it takes neither the margin nor the corner, and it fills the frame instead of running past the bottom of it (noriter.com's own card answers the same reset the same way). */
.gb-plugin-og-card .gb-link-card-thumb img, :is(.post, .gb-static-page) .gb-body .gb-link-card-thumb img { max-width: none; height: 100%; margin: 0; border-radius: 0; }
.gb-plugin-og-card .gb-link-card-title, :is(.post, .gb-static-page) .gb-body .gb-link-card-title { font-size: var(--board-size-ui); font-weight: var(--board-weight-bold); }
/* The plugin dims the second line by fading it, which fades a link's own colour with it; the board has a colour for a quiet line and says it outright. */
.gb-plugin-og-card .gb-link-card-description, :is(.post, .gb-static-page) .gb-body .gb-link-card-description { font-size: var(--board-size-caption); color: var(--board-dim); opacity: 1; }
.gb-plugin-og-card .gb-link-card-site, .gb-plugin-og-card .gb-link-card-caption-site, :is(.post, .gb-static-page) .gb-body .gb-link-card-site, :is(.post, .gb-static-page) .gb-body .gb-link-card-caption-site { font-size: var(--board-size-caption); color: var(--board-dim); opacity: 1; }
.gb-plugin-og-card .gb-link-card-caption-title, :is(.post, .gb-static-page) .gb-body .gb-link-card-caption-title { font-size: var(--board-size-caption); font-weight: var(--board-weight-bold); }
.gb-plugin-og-card .gb-link-card-caption, :is(.post, .gb-static-page) .gb-body .gb-link-card-caption { background: var(--board-tint); border-top-color: var(--board-line); }
/* It is a link, so it answers the pointer the way the board's other cards do. */
.gb-plugin-og-card a.gb-link-card:hover, :is(.post, .gb-static-page) .gb-body a.gb-link-card:hover { border-color: var(--board-accent); box-shadow: var(--board-shadow); }
/* The hero is a picture with a strip of text under it, not a framed box: nothing behind it, and the board's own lift to sit it off the page. */
.gb-plugin-og-card .link-card--image, :is(.post, .gb-static-page) .gb-body .link-card--image { background: none; box-shadow: var(--board-shadow); }
.gb-plugin-og-card .link-card--image img, :is(.post, .gb-static-page) .gb-body .link-card--image img { margin: 0; border-radius: 0; }
.post .gb-notice { margin: var(--board-space-3) 0; }
.post .gb-tags { padding: 0; margin: var(--board-space-3) 0 0; }
/* The site's own last word in the card, after the chips (the content.body.after slot, skin-api.md §8): the translation note is a caption in the dim, set off from the tags above it. A plugin that contributes nothing leaves the frame empty, so the margin rides :not(:empty) rather than opening a gap with nothing under it. */
.post-foot-note:not(:empty) { margin-top: var(--board-space-4); font-size: var(--board-size-caption); color: var(--board-dim); }
.post-foot-note p { margin: 0; }
/* One centred row of pills under the card, not inside it: the card ends and the row stands below it, so there is no hairline to part them (the gap does that). Each reaction is a glyph and its count, the bookmark and the share beside them. */
.post-vote { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0.4rem; margin-top: 0.625rem; }
.post-vote .gb-reactions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
/* 저장 and 공유 are pills, not the page's call to action: the selector carries the shell's primary rule's specificity so that it wins by order. Production's 41x38 at 13px/700 in the dim, its pad a literal off the spacing scale. */
.post-vote .gb-reaction, .post-vote .gb-bookmark.gb-hint, .post-vote .gb-bookmark button[type="submit"]:not(.gb-link), .post-vote .gb-share { display: inline-flex; align-items: center; justify-content: center; gap: var(--board-space-1); min-height: 2.375rem; padding: 0.45rem 0.7rem; border: 1px solid var(--board-line); border-radius: 999px; background: var(--board-surface); color: var(--board-dim); font-size: var(--board-size-caption); font-weight: var(--board-weight-bold); }
.post-vote .gb-reaction:hover, .post-vote .gb-bookmark.gb-hint:hover, .post-vote .gb-bookmark button[type="submit"]:not(.gb-link):hover, .post-vote .gb-share:hover { background: var(--board-tint); opacity: 1; }
.post-vote .gb-reaction[aria-pressed="true"], .post-vote .gb-bookmark button[aria-pressed="true"] { background: var(--board-accent); border-color: var(--board-accent); color: var(--board-on-accent); }
.post-vote .gb-bookmark.gb-hint, .post-vote .gb-bookmark button[type="submit"]:not(.gb-link) { font-size: 0; }
.post-vote .gb-bookmark.gb-hint::before, .post-vote .gb-bookmark button::before { content: ""; flex: none; width: 1rem; height: 1rem; background: currentColor; mask: var(--board-icon-bookmark) center / contain no-repeat; }
/* The share button is Core's markup, so its own icon comes in as an SVG rather than a mask; it is sized to the bookmark's glyph beside it. */
.post-vote .gb-share svg { flex: none; width: 1rem; height: 1rem; }
/* 주소를 복사했음 — the one line the button has to say, set beside it in the dim and gone again on the next post. */
.post-vote .gb-share-notice { font-size: var(--board-size-meta); color: var(--board-dim); }
/* The guest's sign-in line is no longer a visible sentence; it stays in the row for a reader who tabs to it. */
.post-vote .gb-reactions .gb-hint { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
/* 수정·신고 stay a small text row, right-aligned, and only when there is one. */
/* The space around the row is the row's own margin, not this box's padding: on a shared document the row is in the member branch, and a visitor's empty box must be no height at all. */
.post-tools { display: flex; justify-content: flex-end; align-items: center; gap: var(--board-space-2); font-size: var(--board-size-meta); color: var(--board-mid); }
.post-tools .gb-actions { display: flex; gap: var(--board-space-2); align-items: center; margin: var(--board-space-2) 0 0; }
/* 삭제 is a submit dressed as the link beside it: the base button's 36px floor would stretch this text-height row. */
.post-tools .gb-actions button.gb-link { min-height: 0; display: inline; }

/* The author card (`settings.authorCard`, board-skin.md §9): the writer's signature block between the body card and the reactions — the post's own surface, face first, the bio under a bold Signature. */
.author-card { display: flex; align-items: flex-start; gap: var(--board-space-4); margin-top: var(--board-space-3); padding: var(--board-card-pad); background: var(--board-surface); border: 1px solid var(--board-line); border-radius: var(--board-radius-l); box-shadow: var(--board-shadow); }
.author-card-avatar { flex: 0 0 4.5rem; width: 4.5rem; height: 4.5rem; object-fit: cover; border-radius: var(--board-radius); }
.author-card-text { min-width: 0; }
.author-card-text p { margin: 0.4rem 0; white-space: pre-line; color: var(--board-dim); }
.author-card-text a { margin-right: 0.8rem; color: var(--board-accent-text); font-size: var(--board-size-meta); }
.post-document .author-card { margin: 0 var(--board-card-pad); padding: var(--board-space-5) 0; background: none; border: 0; border-top: 1px solid var(--board-line); border-radius: 0; box-shadow: none; }
.post-document .post-vote { margin: 0; padding: var(--board-space-5) var(--board-card-pad); border-top: 1px solid var(--board-line); }
.post-document .post-tools { padding: 0 var(--board-card-pad); }
.post-document .post-tools .gb-actions { margin: 0 0 var(--board-space-4); }
@media (max-width: 35rem) {
  .author-card-avatar { flex-basis: 3.5rem; width: 3.5rem; height: 3.5rem; }
}

/* The nav row after the comments: the neighbours as buttons on the right, the one primary 목록 last. It keeps the card gap above it, the 이전 글 / 다음 글 row standing where 관련글 does. The bottom margin is the measured gap to the listing card below (26.4px), off the spacing scale. */
.post-nav { display: flex; flex-direction: column; gap: var(--board-space-2); margin: var(--board-space-3) 0 1.65rem; font-size: var(--board-size-meta); color: var(--board-mid); }
.post-nav .gb-series-place { margin: 0; color: var(--board-dim); }
.post-nav-links { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: var(--board-space-2); }
/* A bordered control that is not the filled one sits on the skin's surface, never on the page ground: 43.6px tall, bold ui-size, the glyph at the edge each neighbour points to. */
.post-nav .gb-newer, .post-nav .gb-older { --board-control-h: 2.725rem; --board-control-pad-y: 0.5rem; --board-control-pad-x: 0.8rem; gap: var(--board-space-1); font-size: var(--board-size-ui); }
.post-nav .gb-icon { flex: none; }
.post-nav .label { color: inherit; }
/* A missing neighbour keeps its seat as a dimmed placeholder, the same fade the disabled step of a pager wears. */
.post-nav .gb-newer[aria-disabled], .post-nav .gb-older[aria-disabled] { opacity: 0.38; cursor: default; }
/* 목록으로 is the row's one filled button; it takes the same height so the three stand on one line. */
.post-nav .gb-list { --board-control-h: 2.725rem; --board-control-pad-y: 0.5rem; --board-control-pad-x: 0.8rem; gap: var(--board-space-1); font-size: var(--board-size-ui); }

/* The board the post sits on, once the space asked for it (skin-api.md §3s): the listing card between the nav row and the comments. It borrows the board list's own sheet (.board-card.board-list), so the phone row layout comes with it. Where the board keeps no 말머리 the top pad stands in for the tabs row a board page puts above the table; where it draws them, the tabs are that row and the pad is dropped, so the card starts where the board's own does. It is the last block of the post page, so it carries no bottom margin: the page padding below it is the whole distance to the footer. */
.post-listing { margin: 0; padding-top: var(--board-space-3); }
.post-listing:has(.gb-categories) { padding-top: 0; }

/* The comments are one surface card: heading, list (or its empty line) and the pager inside one frame, the form a soft panel under them (skin-api.md §3s). */
.gb-comments { margin: var(--board-space-3) 0 0; padding: 0 var(--board-card-pad) var(--board-space-4); background: var(--board-surface); border: 1px solid var(--board-line); border-radius: var(--board-radius-l); box-shadow: var(--board-shadow); }
/* A #comments or #comment-N jump lands under the bar, not behind it — production's 77px (CommentItem.vue: scroll-margin-top: var(--app-header-offset) + .75rem). The margin reads --gb-header-height, the bar's drawn height the runtime writes on every page, rather than the offset: a fragment jump is the browser's own scroll, the autohiding bar steps aside on it, and an offset-following margin would land the comment under a bar that is no longer there — 12px instead of 77. The height keeps 77 in both states, which is also the number a scriptless browser gets from the fallback. */
#comments, [id^='comment-'] { scroll-margin-top: calc(var(--gb-header-height, 4.0625rem) + 0.75rem); }
/* 댓글 N carries the comment glyph the core view draws: an outline path, so it sits in the line as an element and takes the accent (production's own heading has no rule under it). */
.gb-comments h2 { display: flex; align-items: center; gap: var(--board-space-2); font-size: 1.0625rem; font-weight: var(--board-weight-title); padding: var(--board-space-2) 0; margin: 0; }
.gb-comments h2 .gb-icon-comment { flex: none; color: var(--board-accent-text); }
/* 채택된 답변: the same answer repeated above the list, in a box the reader can pick out of the thread. Its heading is the section's own, not another 댓글 — no icon (board-skin.md §2). */
.gb-accepted-answer { margin: 0 0 var(--board-space-4); padding: var(--board-space-3) var(--board-space-4); border: 1px solid var(--board-count); border-radius: var(--board-radius-l); background: var(--board-tint); }
.gb-accepted-answer h2 { padding: 0; margin: 0 0 var(--board-space-2); font-size: var(--board-size-ui); color: var(--board-count); }
.gb-accepted-answer h2::before { content: none; }
.gb-accepted-answer .gb-comment-list > li:last-child { border-bottom: 0; padding-bottom: 0; }
/* The box already says which answer this is; the in-place bar would say it twice. */
.gb-accepted-answer .gb-comment.gb-is-accepted { border-left: 0; padding-left: 0; }
/* 댓글 정렬: the same text tabs 말머리 uses, a size down and without a rule of their own — the heading above already drew one. */
.gb-comment-sorts { display: flex; gap: 0 var(--board-space-4); padding: var(--board-space-2) 0 0; font-size: var(--board-size-meta); }
.gb-comment-sorts a { color: var(--board-dim); font-weight: var(--board-weight-normal); }
.gb-comment-sorts a:hover { text-decoration: none; color: var(--board-text); }
.gb-comment-sorts a[aria-current] { color: var(--board-text); font-weight: var(--board-weight-bold); text-decoration: underline; text-underline-offset: 3px; }
/* 다른 곳의 댓글(plugin-api.md §7b): 스레드 위에 자기 제목으로 서고, 나머지는 접혀 있다. */
.gb-comment-section { margin-bottom: var(--board-space-6); }
/* Core draws the 다른 곳의 댓글 heading inside .gb-comments, so it is the thread's own 댓글 N row already - icon, title and count inline on the small gap .gb-comments h2 sets. Two parts the thread's heading does not carry: the icon takes the accent where only the thread's own glyph did, and the count rides it bold where it stood dim. No rule under it, as under 댓글 (plugin-api.md §7b). */
.gb-comment-section-title { border-bottom: 0; }
.gb-comment-section-icon { flex: none; color: var(--board-accent-text); }
.gb-comment-section-count { color: var(--board-accent-text); font-weight: var(--board-weight-bold); }
/* The caption the site set (수집된 해외 반응) sits at the far end of the row, a size down in the dim line. */
.gb-comment-section-caption { margin-left: auto; color: var(--board-dim); font-size: var(--board-size-caption); font-weight: var(--board-weight-normal); }
.gb-comment-section-list > li { padding: var(--board-space-3) 0; }
.gb-comment-section-more > summary { padding: var(--board-space-2) 0; font-size: var(--board-size-meta); color: var(--board-dim); cursor: pointer; }
.gb-comment-section-more > summary:hover { color: var(--board-text); }
.gb-comment-list { list-style: none; margin: 0; padding: 0; }
.gb-comment-list > li { padding: var(--board-space-4) 0; border-bottom: 1px solid var(--board-line); }
.gb-comment-list .gb-comment-list { margin: var(--board-space-3) 0 0 var(--board-space-1); padding: 0 0 0 var(--board-space-4); border-left: 2px solid var(--board-tint-2); }
.gb-comment-list .gb-comment-list > li { padding: var(--board-space-2) 0; }
.gb-comment-list .gb-comment-list > li:last-child { border-bottom: 0; padding-bottom: 0; }
.gb-comment .gb-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--board-space-2); margin: 0 0 var(--board-space-1); font-size: var(--board-size-meta); color: var(--board-dim); }
.gb-comment .gb-meta .gb-author { color: var(--board-text); font-weight: var(--board-weight-bold); font-size: var(--board-size-ui); }
.gb-comment .gb-avatar { width: 1.75rem; height: 1.75rem; border-radius: 50%; object-fit: cover; }
.gb-comment .gb-parent { color: var(--board-mid); }
/* Nested replies already sit under their parent inside a left-bordered list, so the target name is hidden there; only top-level replies whose parent lives elsewhere keep the core arrow and name. */
.gb-comment-list .gb-comment-list > li.gb-comment > .gb-meta > .gb-parent { display: none; }
.gb-comment .gb-body { line-height: var(--board-leading-read); font-size: var(--board-size-read); }
.gb-comment .gb-body p:last-child { margin-bottom: 0; }
/* 채택된 답변 in place: a quiet bar on the accepted comment's left edge and the label beside its author, both the informational blue the 해결 mark carries. */
.gb-comment.gb-is-accepted { border-left: 2px solid var(--board-count); padding-left: var(--board-space-3); }
.gb-accepted-mark { display: inline-block; padding: 0 var(--board-space-2); border: 1px solid var(--board-count); border-radius: var(--board-radius-s); color: var(--board-count); font-size: var(--board-size-caption); font-weight: var(--board-weight-bold); line-height: var(--board-leading-ui); }
/*
 * The row under a comment, production's measure: 좋아요 · 싫어요 · 답글 on one line, each a 13px word or
 * count beside a 15px outline glyph, 0.8rem apart and 0.45rem under the body. Core draws the reactions
 * and the actions as two siblings, so both go inline-flex and share the comment's line.
 * On shared documents the actions sit inside a viewer-branch wrapper, which the margin rule below also covers.
 */
.gb-comment .gb-reactions, .gb-comment .gb-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.8rem; margin: 0.45rem 0 0; vertical-align: top; font-size: var(--board-size-caption); line-height: 1.6; }
.gb-comment .gb-reactions + .gb-actions, .gb-comment .gb-reactions + [data-viewer-branch="member"] > .gb-actions { margin-left: 0.8rem; }
.gb-comment .gb-actions a, .gb-comment .gb-actions button { color: var(--board-dim); }
.gb-comment .gb-actions button { border: 0; background: none; padding: 0; font-weight: var(--board-weight-normal); }
.gb-comment .gb-actions button:hover { background: none; text-decoration: underline; }
.gb-comment .gb-reaction, .gb-comment .gb-actions > a, .gb-comment .gb-actions > [data-viewer-branch="member"] > a { display: inline-flex; align-items: center; gap: 0.2rem; min-height: 0; padding: 0.15rem; border: 0; border-radius: 0; background: none; color: var(--board-dim); font-size: var(--board-size-caption); font-weight: var(--board-weight-normal); line-height: 1.6; }
.gb-comment .gb-actions > a:hover, .gb-comment .gb-actions > [data-viewer-branch="member"] > a:hover { color: var(--board-text); text-decoration: none; }
/* 답글 gets the answer glyph in front of it, drawn like the reaction glyphs beside it. */
.gb-comment .gb-actions > a::before, .gb-comment .gb-actions > [data-viewer-branch="member"] > a::before { content: ""; flex: none; width: 0.9375rem; height: 0.9375rem; background: currentColor; mask: var(--board-icon-reply) center / contain no-repeat; }
.gb-comment .gb-reaction[aria-pressed="true"] { color: var(--board-text); }
/* Both rows draw the same two shapes: the word stays for a screen reader, the glyph takes its place. A custom kind names no shape here and keeps its label. */
:is(.post-vote, .gb-comment) :is(.gb-reaction-like, .gb-reaction-value-1, .gb-reaction-value-neg1) { font-size: 0; }
:is(.post-vote, .gb-comment) :is(.gb-reaction-like, .gb-reaction-value-1, .gb-reaction-value-neg1)::before { content: ""; flex: none; width: 1rem; height: 1rem; background: currentColor; mask-repeat: no-repeat; mask-position: center; mask-size: contain; }
:is(.post-vote, .gb-comment) :is(.gb-reaction-like, .gb-reaction-value-1)::before { mask-image: var(--board-icon-up); }
:is(.post-vote, .gb-comment) .gb-reaction-value-neg1::before { mask-image: var(--board-icon-down); }
:is(.post-vote, .gb-comment) .gb-reaction .gb-count { font-size: var(--board-size-meta); font-variant-numeric: tabular-nums; }
/* The spacing rides the glyph, not the flex gap: the hidden word is a flex item of its own and would take a second gap. */
.gb-comment .gb-reactions .gb-reaction { gap: 0; }
.gb-comment :is(.gb-reaction-like, .gb-reaction-value-1, .gb-reaction-value-neg1)::before { width: 0.9375rem; height: 0.9375rem; margin-right: 0.2rem; }
.gb-comment .gb-reaction .gb-count { font-size: var(--board-size-caption); }
.comment-secret .gb-body, .gb-tombstone { color: var(--board-dim); font-style: italic; }
/* 댓글이 없을 때 (board-skin.md §2): the outline mark, the sentence and the nudge under it, one centred column 48px tall. */
.gb-comments .gb-empty, .gb-profile-comments .gb-empty { display: grid; justify-items: center; gap: var(--board-space-2); padding: var(--board-empty-pad); text-align: center; }
.gb-comments .gb-empty .gb-icon-comment { color: var(--board-mid); }
.gb-comments .gb-empty strong { font-size: var(--board-size-ui); font-weight: var(--board-weight-bold); color: var(--board-text); }
.gb-comments .gb-empty span { font-size: var(--board-size-ui); color: var(--board-mid); }
/* 댓글 작성 is its own card after the thread's, so a reader who has read the comments meets the form as a section (board-skin.md §2). */
.gb-comment-write { margin: var(--board-space-3) 0 var(--board-space-3); padding: var(--board-card-pad); background: var(--board-surface); border: 1px solid var(--board-line); border-radius: var(--board-radius-l); box-shadow: var(--board-shadow); }
.gb-comment-write h2 { margin: 0 0 var(--board-space-3); font-size: var(--board-size-head); font-weight: var(--board-weight-title); }
/* The guest's box: the sentence on the left, the one thing they can do about it (a 로그인 button) on the right. */
.gb-comment-write .gb-notice { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--board-space-3); margin: 0; padding: var(--board-space-4); background: var(--board-tint); border: 1px solid var(--board-line); border-radius: var(--board-radius); font-size: var(--board-size-ui); color: var(--board-mid); }
/* Reading and writing comments are one discussion. Only their internal boundary is ruled. */
.post-discussion { margin-top: var(--board-space-6); }
.post-discussion:empty { display: none; }
.post-discussion > .gb-comments { margin: 0; padding: var(--board-card-pad); background: none; border: 0; border-radius: 0; box-shadow: none; }
.post-discussion > .gb-comments h2 { padding-top: 0; }
.post-discussion .gb-comment-list > li:last-child { border-bottom: 0; padding-bottom: 0; }
.post-discussion > .gb-comment-write { margin: 0 var(--board-card-pad); padding: var(--board-space-5) 0; background: none; border: 0; border-top: 1px solid var(--board-line); border-radius: 0; box-shadow: none; }
.post-discussion > .gb-comment-write h2 { font-size: var(--board-size-ui); }
.post-discussion > .gb-comment-write .gb-notice { padding: 0; background: none; border: 0; border-radius: 0; }
/*
 * The card is already the panel; the form inside it draws no second one. Its last row is
 * production's .form-bottom — 등록 at the right end, and a 답글's 취소 on the same line to its
 * left. The markup writes the button first, so the wrap puts each field on a line of its own and
 * the order property re-seats the link left of the button in the right-aligned last line.
 */
.gb-comment-form { display: flex; flex-wrap: wrap; justify-content: flex-end; column-gap: var(--board-space-3); margin: var(--board-space-3) 0 0; padding: 0; border-radius: 0; background: none; }
.gb-comment-form > * { flex: 1 0 100%; }
/* The native picker stays script-free and uses the profile form's button face. */
.gb-comment-form input[type='file']::file-selector-button { margin-right: 0.6rem; padding: 0.45rem 0.8rem; border: 1px solid var(--board-line); border-radius: 0.4rem; background: var(--board-surface); color: var(--board-ink); font: inherit; }
.gb-comment-form input[type='file']::file-selector-button:hover { background: var(--board-tint); }
.gb-comment-form > a, .gb-comment-form > button[type='submit'] { flex: 0 0 auto; }
.gb-comment-form > a { order: 1; align-self: center; }
.gb-comment-form > button[type='submit'] { order: 2; }
.gb-comment-form h3 { margin: 0 0 var(--board-space-2); font-size: var(--board-size-ui); }
.gb-comment-form textarea { min-height: 5.5rem; }
.gb-comment-form label { display: inline-block; margin: var(--board-space-2) var(--board-space-4) var(--board-space-2) 0; font-size: var(--board-size-meta); color: var(--board-mid); }
.gb-comment-form > label { margin-right: 0; }
.gb-comments .gb-pagination { margin: var(--board-space-3) 0; }
