
/* 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");
}
/* The post is no card: the article opens on the region's 2px rule, the head is ruled off by a hairline, and the prose runs on the page (C). */
.post-head, .post-body { background: none; border: 0; border-radius: 0; box-shadow: none; }
.post-head { padding: var(--board-space-4) 0 var(--board-space-3); border-bottom: 1px solid var(--board-line); }
.post-body { margin-top: 0; padding: var(--board-space-6) 0 var(--board-space-2); }
.post-document { border-top: 2px solid var(--board-ink); }
.post-document, .post-discussion { background: none; border-radius: 0; box-shadow: none; }
/* 말머리 and the board as quiet words over the title, so the title stands alone in the h1. */
.post-chips { display: flex; flex-wrap: wrap; gap: var(--board-space-1) var(--board-space-3); margin: 0 0 var(--board-space-1); font-size: var(--board-size-meta); }
.chip { display: inline-block; padding: 0; background: none; color: var(--board-mid); font-size: var(--board-size-meta); }
.chip:hover { color: var(--board-text); }
.post-title { font-size: var(--board-size-display); font-weight: var(--board-weight-title); margin: 0; letter-spacing: -0.03em; line-height: 1.45; }
.post-chips .gb-badge { margin-right: 0; }
.post-chips .chip, .post-chips .gb-badge { padding: 0; border: 0; border-radius: 0; background: none; color: var(--board-dim); font-size: var(--board-size-meta); font-weight: 500; line-height: 1.6; }
.post-chips .chip:hover { background: none; color: var(--board-text); }
.post-chips .gb-badge.gb-badge-notice { background: none; color: var(--board-accent-text); font-weight: var(--board-weight-bold); }
.post-chips .gb-badge.gb-badge-locked, .post-chips .gb-badge.gb-badge-secret { background: none; color: var(--board-danger); font-weight: var(--board-weight-bold); }
.post-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--board-space-1) 0.875rem; overflow: hidden; margin: var(--board-space-2) 0 0; color: var(--board-dim); font-size: var(--board-size-meta); font-variant-numeric: tabular-nums; }
.post-meta .gb-author { display: inline-flex; align-items: center; gap: var(--board-space-2); color: var(--board-text); font-weight: 600; }
.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 { display: none; }
/* 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: 47.5rem; }
: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"; }
/* Link cards (the og-card plugin's markup and the importer's): Core's theme draws them and this skin draws without it, so the whole card is here — C's hairline frame on the page ground, the thumbnail flush with its side, no lift. */
.gb-plugin-og-card a.gb-link-card, :is(.post, .gb-static-page) .gb-body a.gb-link-card { color: inherit; text-decoration: none; }
.gb-plugin-og-card .gb-link-card, :is(.post, .gb-static-page) .gb-body .gb-link-card { display: flex; gap: 0.875rem; align-items: stretch; max-width: 47.5rem; margin: 1.1rem 0; overflow: hidden; border: 1px solid var(--board-line); border-radius: var(--board-radius); background: var(--board-bg); }
.gb-plugin-og-card .gb-link-card-thumb, :is(.post, .gb-static-page) .gb-body .gb-link-card-thumb { position: relative; flex: 0 0 7.5rem; overflow: hidden; background: var(--board-tint); }
.gb-plugin-og-card .gb-link-card-thumb img, :is(.post, .gb-static-page) .gb-body .gb-link-card-thumb img { position: absolute; inset: 0; display: block; width: 100%; max-width: none; height: 100%; margin: 0; object-fit: cover; border-radius: 0; }
.gb-plugin-og-card .gb-link-card-body, :is(.post, .gb-static-page) .gb-body .gb-link-card-body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; min-height: 5.25rem; padding: 0.75rem 0.875rem 0.75rem 0; }
.gb-plugin-og-card .gb-link-card-title, :is(.post, .gb-static-page) .gb-body .gb-link-card-title, .gb-plugin-og-card .gb-link-card-description, :is(.post, .gb-static-page) .gb-body .gb-link-card-description { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.gb-plugin-og-card .gb-link-card-title, :is(.post, .gb-static-page) .gb-body .gb-link-card-title { color: var(--board-text); font-size: var(--board-size-ui); font-weight: var(--board-weight-bold); line-height: 1.4; }
.gb-plugin-og-card .gb-link-card-description, :is(.post, .gb-static-page) .gb-body .gb-link-card-description { color: var(--board-mid); font-size: var(--board-size-meta); line-height: 1.5; opacity: 1; }
.gb-plugin-og-card .gb-link-card-site, :is(.post, .gb-static-page) .gb-body .gb-link-card-site, .gb-plugin-og-card .gb-link-card-caption-site, :is(.post, .gb-static-page) .gb-body .gb-link-card-caption-site, .gb-plugin-og-card .gb-link-card-caption-title, :is(.post, .gb-static-page) .gb-body .gb-link-card-caption-title { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--board-size-caption); line-height: 1.4; }
.gb-plugin-og-card .gb-link-card-site, :is(.post, .gb-static-page) .gb-body .gb-link-card-site, .gb-plugin-og-card .gb-link-card-caption-site, :is(.post, .gb-static-page) .gb-body .gb-link-card-caption-site { color: var(--board-dim); opacity: 1; }
.gb-plugin-og-card .gb-link-card-site, :is(.post, .gb-static-page) .gb-body .gb-link-card-site { margin-top: auto; padding-top: 0.2rem; }
.gb-plugin-og-card .gb-link-card-caption-title, :is(.post, .gb-static-page) .gb-body .gb-link-card-caption-title { margin-top: 0.15rem; color: var(--board-text); 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 { display: block; padding: 0.6rem 0.75rem; background: none; border-top: 1px solid var(--board-line); }
.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-rule); }
/* The image card: the picture is the face, the caption under it on the same ground. */
.gb-plugin-og-card .gb-link-card--image, :is(.post, .gb-static-page) .gb-body .gb-link-card--image, .gb-plugin-og-card .link-card--image, :is(.post, .gb-static-page) .gb-body .link-card--image { display: block; margin: 1.1rem 0 1.5rem; background: none; }
.gb-plugin-og-card .gb-link-card--image img, :is(.post, .gb-static-page) .gb-body .gb-link-card--image img, .gb-plugin-og-card .link-card--image img, :is(.post, .gb-static-page) .gb-body .link-card--image img { display: block; width: 100%; height: auto; margin: 0; object-fit: cover; border-radius: 0; }
@media (max-width: 47.99rem) {
  .gb-plugin-og-card .gb-link-card-thumb, :is(.post, .gb-static-page) .gb-body .gb-link-card-thumb { flex-basis: 5.5rem; }
  .gb-plugin-og-card .gb-link-card-body, :is(.post, .gb-static-page) .gb-body .gb-link-card-body { min-height: 4.5rem; padding: 0.65rem 0.7rem 0.65rem 0; }
  .gb-plugin-og-card .gb-link-card-description, :is(.post, .gb-static-page) .gb-body .gb-link-card-description { -webkit-line-clamp: 1; }
}
.post .gb-notice { margin: var(--board-space-3) 0; }
/* The phone's post (C-mobile): an 18px title, 15px prose and the vote boxes a size down. */
@media (max-width: 47.99rem) {
  .post-title { font-size: calc(1.125rem + var(--board-text-step)); }
  /* `large` brings the phone's prose to the pointer's 17px (noriter-174), hence twice the step. */
  :is(.post, .gb-static-page) .gb-body { font-size: calc(0.9375rem + 2 * var(--board-text-step)); line-height: 1.7; }
  .post-vote .gb-reaction { width: 5.25rem; height: 3.25rem; }
}
.post .gb-tags { gap: var(--board-space-1) 0.625rem; padding: var(--board-space-2) 0 0; margin: 0; }
.post .gb-tags .gb-tag { min-height: 0; padding: 0; background: none; border-radius: 0; color: var(--board-mid); font-size: var(--board-size-meta); }
.post .gb-tags .gb-tag:hover { background: none; color: var(--board-text); text-decoration: underline; }
/* 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; }
/*
 * The vote: C's two 96×60 boxes centred under the prose, the glyph over the count, outlined in the
 * field's edge; a pressed one takes the accent's edge and words. 저장 and 공유 beside them are quiet
 * text controls. The selectors carry the shell's primary rule's specificity so they win by order.
 */
.post-vote { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: var(--board-space-2) var(--board-space-4); margin: 1.75rem 0 0; padding-bottom: var(--board-space-6); }
.post-vote .gb-reactions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--board-space-2); }
.post-vote .gb-reaction { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; width: 6rem; height: 3.75rem; padding: 0; border: 1px solid var(--board-rule); border-radius: var(--board-radius-l); background: var(--board-bg); color: var(--board-mid); font-size: var(--board-size-caption); font-weight: var(--board-weight-bold); }
.post-vote .gb-bookmark.gb-hint, .post-vote .gb-bookmark button[type="submit"]:not(.gb-link), .post-vote .gb-share, .post-vote .gb-copy-link { display: inline-flex; align-items: center; justify-content: center; gap: 0.3125rem; min-height: 2rem; padding: 0.375rem 0; border: 0; border-radius: 0; background: none; color: var(--board-mid); font-size: var(--board-size-meta); font-weight: var(--board-weight-normal); }
.post-vote .gb-reaction:hover { background: var(--board-tint); opacity: 1; }
.post-vote .gb-bookmark.gb-hint:hover, .post-vote .gb-bookmark button[type="submit"]:not(.gb-link):hover, .post-vote .gb-share:hover, .post-vote .gb-copy-link:hover { background: none; color: var(--board-text); opacity: 1; }
.post-vote .gb-reaction[aria-pressed="true"] { background: var(--board-bg); border-color: var(--board-accent); color: var(--board-accent-text); }
.post-vote .gb-bookmark button[aria-pressed="true"] { color: var(--board-accent-text); }
.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: 0.875rem; height: 0.875rem; 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, .post-vote .gb-copy-link svg { flex: none; width: 0.875rem; height: 0.875rem; }
/* 주소를 복사했음 — 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, .post-vote .gb-copy-link-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; flex-wrap: wrap; justify-content: flex-end; 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-space-4) 0; border-top: 1px solid var(--board-line); }
.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-mid); font-size: var(--board-size-meta); text-decoration: underline; }
.post-document .author-card { margin: var(--board-space-4) 0 0; }
.post-document .post-tools .gb-actions { margin: var(--board-space-3) 0 0; }
@media (max-width: 35rem) {
  .author-card-avatar { flex-basis: 3.5rem; width: 3.5rem; height: 3.5rem; }
}

/* The nav row: 이전 글, 다음 글 and 목록 as C's 34px outlined buttons over a hairline, the screen's filled button left to the comment form. */
.post-nav { display: flex; flex-direction: column; gap: var(--board-space-2); margin: var(--board-space-6) 0 2.5rem; padding-top: var(--board-space-3); border-top: 1px solid var(--board-line); 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.125rem; --board-control-pad-y: 0; --board-control-pad-x: 0.875rem; gap: var(--board-space-1); font-size: var(--board-size-ui); font-weight: var(--board-weight-normal); }
.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 outlined like its neighbours in C; the same height so the three stand on one line. */
.post-nav .gb-list.gb-list { --board-control-h: 2.125rem; --board-control-pad-y: 0; --board-control-pad-x: 0.875rem; gap: var(--board-space-1); background: var(--board-surface); border-color: var(--board-rule); color: var(--board-text); font-size: var(--board-size-ui); font-weight: var(--board-weight-normal); }
.post-nav .gb-list.gb-list:hover { background: var(--board-tint); border-color: var(--board-rule); color: var(--board-text); }

/* 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: 0; }
.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). */
/* The comments: a 14px 댓글 N over a hairline, rows parted by the faintest divider (C). */
.gb-comments { margin: 1.75rem 0 0; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
/* 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-1); font-size: var(--board-size-ui); font-weight: var(--board-weight-title); padding: 0 0 var(--board-space-2); margin: 0; border-bottom: 1px solid var(--board-line); }
.gb-comments h2 .gb-icon-comment { display: none; }
/* 채택된 답변: 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: var(--board-space-3) 0 var(--board-space-4); padding: var(--board-space-3) var(--board-space-4); border: 1px solid var(--board-accent); border-radius: var(--board-radius); background: var(--board-bg); }
.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 0.625rem; 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); }
/* 다른 곳의 댓글(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: 0.625rem 0; border-bottom: 1px solid var(--board-hair); }
/* A reply sits on the panel fill, stepped in (C). */
.gb-comment-list .gb-comment-list { margin: 0.625rem 0 -0.625rem; padding: 0; border: 0; }
.gb-comment-list .gb-comment-list > li { padding: 0.625rem 0 0.625rem 1.75rem; background: var(--board-tint); border-top: 1px solid var(--board-hair); border-bottom: 0; }
.gb-comment-list .gb-comment-list > li:last-child { border-bottom: 0; }
.gb-comment .gb-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--board-space-1) var(--board-space-2); margin: 0 0 3px; font-size: var(--board-size-byline); color: var(--board-dim); }
.gb-comment .gb-meta .gb-author { color: var(--board-text); font-weight: 600; font-size: var(--board-size-byline); }
.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: 1.55; font-size: calc(var(--board-size-ui) + var(--board-text-step)); }
.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-accent); padding-left: var(--board-space-3); }
.gb-accepted-mark { display: inline-block; padding: 0 var(--board-space-1); border: 1px solid var(--board-accent); border-radius: 3px; color: var(--board-accent-text); 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.875rem; margin: var(--board-space-1) 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; }
/* Under the post the row ends at the right edge, so the report form opens leftward from there. */
.post-tools .gb-actions .gb-report-form { left: auto; right: 0; }
/* Under a comment the row starts after the votes, so the form is placed from the comment's own left edge, just below 신고. */
.gb-comment { position: relative; }
.gb-comment .gb-actions { position: static; }
.gb-comment .gb-actions .gb-report-form { top: auto; left: 0; width: min(20rem, 100%); }
/* The report form's own submit is a button again, not one more word in the row. */
.gb-comment .gb-actions .gb-report-form button { padding: var(--board-space-1) var(--board-space-3); border: 1px solid var(--board-rule); border-radius: var(--board-radius); color: var(--board-text); }
/* A comment's ••• sits in the same row as 답글 and 추천, so it reads as one more text control, not a boxed button (noriter-130). */
.gb-comment .gb-more-menu summary { display: inline-flex; align-items: center; border: 0; background: none; padding: 0.15rem; color: var(--board-dim); font-weight: var(--board-weight-normal); }
.gb-comment .gb-more-menu summary svg { display: block; }
/* Every control in the row is drawn as one word of one height — the delete and accept buttons and 신고 too, or the tallest sets the line and the rest sink below the votes (noriter-158). */
.gb-comment .gb-reaction, .gb-comment .gb-actions > a, .gb-comment .gb-actions > [data-viewer-branch="member"] > a, .gb-comment .gb-actions > .gb-inline > button, .gb-comment .gb-actions .gb-report > summary { 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:not(.gb-edit)::before, .gb-comment .gb-actions > [data-viewer-branch="member"] > a:not(.gb-edit)::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; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
.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-3) var(--board-space-4); background: none; border: 1px solid var(--board-rule); 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: 0; }
.post-discussion:empty { display: none; }
.post-discussion > .gb-comments { margin: 1.75rem 0 0; }
.post-discussion > .gb-comment-write { margin: var(--board-space-3) 0 0; }
/* The thread's heading already named the section; the form's own heading stays for a screen reader. */
.post-discussion > .gb-comment-write > h2 { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 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.35rem 0.75rem; border: 1px solid var(--board-rule); border-radius: var(--board-radius); 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: 4.5rem; padding: 0.625rem 0.75rem; font-size: var(--board-size-ui); }
.gb-comment-form > button[type='submit'] { min-width: 5rem; --board-control-h: 2.5rem; font-size: var(--board-size-ui); }
.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; }

/*
 * The write form as C draws it (C-write): one row per field, the label in a 112px column and the
 * field beside it, 10px above and below and a hairline under each. Core's labels wrap their fields,
 * so the label is the row and its text the first column; the body's label and editor are siblings,
 * held in one row by this skin's arrangement (`board-compose-body`). The doubled class outranks the
 * inherited sheet's column of stacked labels, which loads after this one.
 */
.gb-content-form.gb-content-form { gap: 0; padding-top: 0; max-width: none; }
.gb-content-form.gb-content-form > :is(label, .board-compose-body, .board-compose-row),
.gb-content-form.gb-content-form > .gb-slot-compose-fields > label { display: grid; grid-template-columns: 112px minmax(0, 1fr); align-items: center; gap: 0.75rem; padding: 0.625rem 0; border-bottom: 1px solid var(--board-hair); font-size: var(--board-size-ui); font-weight: 600; color: var(--board-ink); }
.gb-content-form.gb-content-form > .gb-slot-compose-fields { gap: 0; }
.gb-content-form.gb-content-form > :is(label, .board-compose-row) :is(input, select),
.gb-content-form.gb-content-form > .gb-slot-compose-fields > label :is(input, select) { font-weight: var(--board-weight-normal); }
.gb-content-form.gb-content-form > .board-compose-body { align-items: start; }
.gb-content-form.gb-content-form > .board-compose-body > label { padding-top: 0.625rem; font: inherit; color: inherit; }
/* A checkbox row (공지로 고정) keeps its box before its words, in the field column. */
.gb-content-form.gb-content-form > label:has(> input[type="checkbox"]:is(:first-child, [type="hidden"]:first-child + *)) { display: flex; gap: var(--board-space-2); padding-left: calc(112px + 0.75rem); font-weight: var(--board-weight-normal); }
/* The attachments have no label of their own once the picker mounts; they stand in the field column too. */
.gb-content-form.gb-content-form > .gb-attach { margin: 0; padding: 0.625rem 0 0.625rem calc(112px + 0.75rem); border-bottom: 1px solid var(--board-hair); }
.gb-content-form.gb-content-form > .gb-submit { border-top: 0; }
/* Which board (C-write): Core's select keeps its word in the 112px column like every other row; the label lets go of its box so the word, the select and 바꾸기 stand in the grid. */
.gb-content-form.gb-content-form > .gb-compose-space { display: grid; grid-template-columns: 112px auto minmax(0, 1fr); align-items: center; gap: 0.75rem; margin: 0; padding: 0.625rem 0; border-bottom: 1px solid var(--board-hair); font-size: var(--board-size-ui); font-weight: 600; color: var(--board-ink); }
.gb-content-form.gb-content-form > .gb-compose-space > label { display: contents; }
.gb-content-form.gb-content-form > .gb-compose-space select { min-width: 12.5rem; font-weight: var(--board-weight-normal); }
.gb-content-form.gb-content-form > .gb-compose-space > .gb-btn { justify-self: start; }

/* The category as chips (C-write): a hairline box each, the chosen one edged in the rule and set bold, as the pager marks its page. The radio itself is kept for the keyboard and hidden from sight. */
.board-category-chips { display: flex; flex-wrap: wrap; gap: var(--board-space-2); }
.board-chip { position: relative; display: inline-flex; }
.board-chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.board-chip span { display: inline-flex; align-items: center; min-height: 2rem; padding: 0 0.75rem; border: 1px solid var(--board-line); border-radius: var(--board-radius); font-size: var(--board-size-meta); font-weight: var(--board-weight-normal); color: var(--board-mid); }
.board-chip:hover span { border-color: var(--board-rule); color: var(--board-ink); }
.board-chip input:checked + span { border-color: var(--board-ink); color: var(--board-ink); font-weight: var(--board-weight-bold); }
.board-chip input:focus-visible + span { outline: 2px solid var(--board-ink); outline-offset: 2px; }

@media (max-width: 47.99rem) {
  /* One column on a phone: the label over its field. */
  .gb-content-form.gb-content-form > :is(label, .board-compose-body, .board-compose-row),
  .gb-content-form.gb-content-form > .gb-slot-compose-fields > label { grid-template-columns: minmax(0, 1fr); gap: 0.375rem; }
  .gb-content-form.gb-content-form > .board-compose-body > label { padding-top: 0; }
  .gb-content-form.gb-content-form > .gb-compose-space { grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.5rem; }
  .gb-content-form.gb-content-form > .gb-compose-space select { min-width: 0; }
  .gb-content-form.gb-content-form > label:has(> input[type="checkbox"]:is(:first-child, [type="hidden"]:first-child + *)),
  .gb-content-form.gb-content-form > .gb-attach { padding-left: 0; }
}
@media (pointer: coarse) {
  .board-chip span { min-height: 2.75rem; }
}
