
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--board-font);
  font-size: var(--board-size-ui);
  line-height: var(--board-leading-ui);
  color: var(--board-text);
  background: var(--board-bg);
  word-break: keep-all;
  overflow-wrap: anywhere;
  -webkit-font-smoothing: antialiased;
  /* The window's height at least, with the shell taking what the header and footer leave: a short page (sign-in, an empty search) keeps its footer on the window's bottom edge instead of stopping mid-window over bare ground. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
/* A flex item with auto side margins sizes to its content, so the shell states its width; .board-shell below caps it and centres it. */
.board-shell { flex: 1 0 auto; width: 100%; }
a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }
.gb-skip-link {
  position: fixed;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 100;
  transform: translateY(-200%);
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--board-line);
  border-radius: var(--board-control-radius);
  background: var(--board-surface);
  color: var(--board-text);
  box-shadow: var(--board-shadow);
  font-weight: var(--board-weight-bold);
}
.gb-skip-link:focus { transform: none; }
#main-content { scroll-margin-top: calc(var(--gb-header-height, 4.0625rem) + var(--board-space-3)); }
#main-content:focus { outline: none; }
/* A link that wraps a block (gallery card, card listing, cover link) underlines every letter inside it; production underlines none. Inline links still do. */
a:has(:is(div, p, h1, h2, h3, h4, h5, h6, img, picture, figure, ul, ol, table, widget, article)):hover { text-decoration: none; }
h1, h2, h3, h4 { line-height: var(--board-leading-tight); margin: 0 0 var(--board-space-2); letter-spacing: -0.02em; font-weight: var(--board-weight-title); }
h1 { font-size: var(--board-size-page); }
h2 { font-size: var(--board-size-head); }
h3 { font-size: var(--board-size-ui); }
p { margin: 0 0 var(--board-space-3); }
img { max-width: 100%; height: auto; }
input, select, textarea, button {
  font: inherit;
  color: inherit;
}
/* The native box in the skin's ink rather than the browser's blue: the one colour on a screen is the black button. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--board-ink); }
input[type="text"], input[type="search"], input[type="email"], input[type="password"], input[type="url"], input[type="date"], input[type="number"], select {
  min-height: var(--board-control-h);
  padding: var(--board-control-pad-y) var(--board-input-pad-x);
  border: 1px solid var(--board-rule);
  border-radius: var(--board-control-radius);
  background: var(--board-surface);
  max-width: 100%;
}
/* A single select draws its own chevron: the native arrow hugs the border, so appearance goes and two gradients make a token-coloured caret whose right edge sits 0.7rem in — the same inset as the text on the left (board-skin.md §9). Multi-line selects keep the native control. */
select:not([multiple]):not([size]) {
  appearance: none;
  padding-right: var(--board-space-6);
  background-image: linear-gradient(45deg, transparent 50%, var(--board-mid) 50%), linear-gradient(135deg, var(--board-mid) 50%, transparent 50%);
  background-position: calc(100% - var(--board-input-pad-x) - 0.3rem) 50%, calc(100% - var(--board-input-pad-x)) 50%;
  background-size: 0.3rem 0.3rem, 0.3rem 0.3rem;
  background-repeat: no-repeat;
}
input[type="search"] { background: var(--board-surface); }
input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
textarea { width: 100%; min-height: 8rem; resize: vertical; border: 1px solid var(--board-rule); border-radius: var(--board-control-radius); background: var(--board-surface); padding: var(--board-input-pad-x); }
input[type="text"]:focus, input[type="search"]:focus, input[type="email"]:focus, input[type="password"]:focus, input[type="url"]:focus, input[type="date"]:focus, input[type="number"]:focus, select:focus, textarea:focus, input:focus-visible {
  outline: 0;
  border-color: var(--board-focus-line, var(--board-ink));
  background-color: var(--board-surface);
  box-shadow: 0 0 0 3px var(--board-focus-ring, color-mix(in srgb, var(--board-ink) 12%, transparent));
}
button:focus-visible, a:focus-visible, summary:focus-visible { outline: 2px solid var(--board-ink); outline-offset: 2px; }
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible { outline: 2px solid var(--board-ink); outline-offset: 2px; }
/* A button is outlined in the field's edge at 13px; the one filled button of a screen is the primary below. */
button, .gb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--board-space-1);
  min-height: var(--board-control-h);
  padding: var(--board-control-pad-y) var(--board-control-pad-x);
  border: 1px solid var(--board-rule);
  border-radius: var(--board-control-radius);
  background: var(--board-surface);
  color: var(--board-text);
  /* `large` takes a button to 15px, a step past the meta it reads beside (noriter-174). */
  font-size: calc(var(--board-size-meta) + var(--board-text-step));
  font-weight: 500;
  line-height: var(--board-control-leading);
  cursor: pointer;
  white-space: nowrap;
}
button:hover, .gb-btn:hover { text-decoration: none; background: var(--board-tint); }
button[disabled] { opacity: 0.5; cursor: default; }
.gb-btn-primary, .btn-write, button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  background: var(--board-primary);
  border-color: var(--board-primary);
  color: var(--board-on-primary);
  font-weight: var(--board-weight-bold);
}
.gb-btn-primary:hover, .btn-write:hover, button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover { background: var(--board-primary-hover); border-color: var(--board-primary-hover); color: var(--board-on-primary); }
/* A submit that should read quiet rather than filled opts out of the primary rule by name; Core's `gb-btn` submits (the write form's 바꾸기, 미리보기, 임시저장) are its secondary buttons, so the screen keeps one black one. */
button:is(.gb-btn-quiet, .gb-btn)[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger) { background: var(--board-surface); border-color: var(--board-rule); color: var(--board-text); font-weight: 500; }
button:is(.gb-btn-quiet, .gb-btn)[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover { background: var(--board-tint); border-color: var(--board-rule); color: var(--board-text); }
.btn-block { display: block; text-align: center; }
button.gb-link, .gb-link { border: 0; background: none; padding: 0; min-height: 0; color: inherit; font-weight: inherit; cursor: pointer; }
button.gb-link:hover { background: none; text-decoration: underline; }
button.gb-danger, .gb-danger { color: var(--board-danger); }
/* The filled danger face — white on the danger tone wherever the class sits, including the delete-account submit. */
.btn-danger, .gb-auth .gb-auth-form button.gb-danger[type="submit"] { background: var(--board-danger-fill); border-color: var(--board-danger-fill); color: #fff; }
.btn-danger:hover, .btn-danger:focus-visible, .gb-auth .gb-auth-form button.gb-danger[type="submit"]:hover, .gb-auth .gb-auth-form button.gb-danger[type="submit"]:focus-visible { background: color-mix(in srgb, var(--board-danger-fill) 88%, black); border-color: color-mix(in srgb, var(--board-danger-fill) 88%, black); color: #fff; }
.gb-inline { display: inline; }
/* In the tree, out of sight: a heading a screen reader reads and the layout does not (skin-api.md §3s, the listing-under-the-post heading), the board search's switch, which a phone toggles by its label (§4), and Core's sr-only — the share button's only visible-to-a-reader word (§4). */
.gb-visually-hidden, .board-search-switch, .gb-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

.board-shell { max-width: var(--board-max); margin: 0 auto; padding: 0 var(--board-gap); }

/* The header: one row — brand, menu, search, the account, the switch — over the page's one rule in the text colour (C). It stays with the reader, on the page's own ground. */
.board-header { position: sticky; top: 0; z-index: 40; background: var(--board-bg); border-bottom: 1px solid var(--board-ink); }
/*
 * headerAutohide on: the layout marks <html> and the runtime flips data-gb-header as the
 * reader scrolls (runtime.ts headerOnScroll, skin-api.md §3t). The slide and the delta thresholds
 * are the legacy bar's own (AppHeader.vue: .header--hidden at 0.22s ease, translateY(-100% - 1px)).
 * :not(:focus-within) is the CSS half of the runtime's guard: a bar the keyboard is inside stays
 * on screen. With the option off — the default — neither attribute is ever written and the bar
 * simply stays, which is also what a scriptless browser gets.
 */
:root[data-gb-header-scroll='hide'] .board-header { transition: transform 0.22s ease; }
:root[data-gb-header='hidden'] .board-header:not(:focus-within) { transform: translateY(calc(-100% - 1px)); }
@media (prefers-reduced-motion: reduce) {
  :root[data-gb-header-scroll='hide'] .board-header { transition: none; }
}
/* The row repeats the shell's column — the same --board-max and --board-gap — so the brand sits on the body's left edge and the last control on its right, while the band runs past both. One centred line: production's brand and menu links share a baseline and do not drift (board-skin.md §9). Its 4rem gives the 65px bar production has, with the hairline above adding the last pixel. */
.board-header-row { display: flex; align-items: center; gap: var(--board-space-2); max-width: var(--board-max); margin: 0 auto; padding: 0 var(--board-gap); height: 3.5rem; }
.board-spacer { flex: 1 1 auto; min-width: 0; }
/* The brand: production's 24px at 900, in the accent. Its right margin adds to the row's own gap, setting the brand and the first menu link --board-space-7 apart so the two do not read as glued (board-skin.md §9). The size sits just above --board-size-display, so it is a literal. */
.gb-brand { line-height: 1; font-size: calc(1.1875rem + var(--board-text-step)); font-weight: var(--board-weight-bold); letter-spacing: -0.02em; color: var(--board-text); margin-right: var(--board-space-6); }
.gb-brand:hover { text-decoration: none; }
/* The icon buttons in the row — search and the theme switch — are one shape: a 40px circle edged with the line's colour (production's icon-button). The phone's hamburger joins them, at its own size. */
.board-search-pop, .gb-theme-toggle { flex: none; }
.board-search-pop { position: relative; }
.board-search-pop > summary, .board-menu-pop > summary, .gb-theme-toggle { display: inline-flex; align-items: center; justify-content: center; width: 2.5rem; height: 2.5rem; min-height: 0; padding: 0; border: 0; border-radius: var(--board-radius); background: none; color: var(--board-ink); cursor: pointer; list-style: none; }
.board-search-pop > summary::-webkit-details-marker, .board-menu-pop > summary::-webkit-details-marker { display: none; }
.board-search-pop > summary:hover, .board-menu-pop > summary:hover, .gb-theme-toggle:hover { background: var(--board-tint); color: var(--board-text); }
.board-search-pop[open] > summary, .board-menu-pop[open] > summary { background: var(--board-tint); color: var(--board-text); }
.board-search-pop .gb-site-search { --board-control-h: 2.25rem; --board-control-pad-y: 0; position: absolute; right: 0; top: calc(100% + var(--board-space-2)); z-index: 30; display: flex; gap: var(--board-space-1); padding: var(--board-space-2); background: var(--board-bg); border: 1px solid var(--board-line); border-radius: var(--board-radius); box-shadow: 0 8px 24px rgb(0 0 0 / 10%); }
.gb-site-search input { width: 15rem; }
/* Matches the primary rule's specificity so the popover's 검색 stays quiet grey, not the page's one black button. */
.gb-site-search button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger) { padding: 0 var(--board-space-3); border-color: var(--board-rule); background: var(--board-surface); color: var(--board-text); font-size: var(--board-size-meta); font-weight: 500; }
.gb-site-search button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover { background: var(--board-tint-2); }
/* The switch: window chrome Core draws and the runtime answers (skin-api.md §3u); CSS picks the icon from the two selectors the tokens use. */
.gb-theme-toggle .gb-theme-icon { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.gb-theme-toggle .gb-theme-icon-sun { display: none; }
.gb-theme-toggle:focus-visible { outline: 2px solid var(--board-ink); outline-offset: 2px; }
@media (prefers-color-scheme: dark) {
  :root:root:not([data-theme="light"]) .gb-theme-toggle .gb-theme-icon-sun { display: block; }
  :root:root:not([data-theme="light"]) .gb-theme-toggle .gb-theme-icon-moon { display: none; }
}
:root:root[data-theme="dark"] .gb-theme-toggle .gb-theme-icon-sun { display: block; }
:root:root[data-theme="dark"] .gb-theme-toggle .gb-theme-icon-moon { display: none; }
.gb-account { position: relative; display: flex; align-items: center; gap: var(--board-space-2); flex: none; }
/* 로그인 is a plain 14px word in the ink; 회원가입 beside it is outlined, so the header carries no filled button and the screen's one stays its own (default-skins.md §1). */
.gb-account .gb-sign-in { font-size: var(--board-size-ui); font-weight: 500; color: var(--board-ink); }
.gb-account .sign-up.sign-up { --board-control-h: 2.125rem; --board-control-pad-x: 0.75rem; background: var(--board-surface); border-color: var(--board-rule); color: var(--board-text); font-weight: 500; }
.gb-account .sign-up.sign-up:hover { background: var(--board-tint); border-color: var(--board-rule); color: var(--board-text); }
.gb-menu { position: relative; }
.gb-menu summary { list-style: none; cursor: pointer; font-weight: var(--board-weight-bold); padding: var(--board-space-1) 0; }
.gb-menu summary::-webkit-details-marker { display: none; }
/* Production's account summary: the 19px person, the name cut at 10rem with an ellipsis, the 15px chevron in the dim ink. The name is a span inside — .gb-viewer-name:empty::before fills it on a shared document, and marks beside it would break :empty on the summary itself. */
.gb-account-menu > summary { display: inline-flex; align-items: center; gap: 0.35rem; }
.gb-account-menu .gb-menu-list .gb-menu-me, .gb-account-menu .gb-menu-list .gb-menu-posts { display: none; }
.gb-account-menu .gb-viewer-name { max-width: 10rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gb-account-menu > summary .gb-icon-chevron { color: var(--board-dim); }
/* Production's dropdown: 14px items with their icon .5rem ahead, a .35rem pad and .4rem radius on the panel, and its own shadow. In dark the same shadow stands — the skin's dark sheet drops --board-shadow only where it names it. */
.gb-menu-list {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 10;
  min-width: 10rem;
  display: flex;
  flex-direction: column;
  padding: 0.35rem;
  background: var(--board-bg);
  border: 1px solid var(--board-line);
  border-radius: var(--board-radius);
  box-shadow: 0 10px 30px rgb(0 0 0 / 10%);
}
.gb-menu-list a, .gb-menu-list button { display: flex; align-items: center; gap: 0.5rem; width: 100%; min-height: 2.25rem; text-align: left; padding: 0.58rem 0.65rem; border: 0; border-radius: 0.35rem; background: none; color: var(--board-text); font-weight: var(--board-weight-normal); font-size: var(--board-size-ui); }
.gb-menu-list a:hover, .gb-menu-list button:hover { background: var(--board-tint); text-decoration: none; }
/* The admin entry leads the menu — production's bold brand word, with the hairline under it. */
.gb-menu-list .gb-menu-admin { font-weight: var(--board-weight-bold); color: var(--board-text); }
.gb-menu-list hr { margin: 0.15rem 0; border: 0; border-top: 1px solid var(--board-line); }
.gb-menu-list form { display: contents; }
/* 로그아웃 is a form's submit, so the shell's primary fill would paint it the page's one filled button; scoped with the same specificity, it stays a row like the links — no ground, the row's ink, the row's tint on hover. */
.gb-menu-list button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger) { justify-content: flex-start; text-align: left; background: none; color: var(--board-text); }
.gb-menu-list button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover { background: var(--board-tint); color: var(--board-text); }
@media (pointer: coarse) {
  /* On touch hardware every control gets the 44px a thumb needs — the same floor .gb-more-menu's summary already gets in styles-inherited. */
  :root { --board-control-h: max(2.75rem, calc(2.75rem * var(--ui-density, 1))); }
  .gb-menu-list a,
  .gb-menu-list button,
  .gb-menu-list .gb-report > summary {
    min-height: 2.75rem;
  }
  .board-menu-pop > summary,
  .board-search-pop > summary,
  .gb-theme-toggle,
  .gb-header-icon,
  .gb-account-menu > summary,
  .board-search-pop .gb-site-search button {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }
}
/* The header's round icon buttons — the notifications bell Core draws and the links a site adds under chrome.header.actions (the messages link is one): the same 40px bordered circle the search summary and theme switch are, so the row reads as one set. */
.gb-header-icon { position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none; width: 2.5rem; height: 2.5rem; padding: 0; border: 0; border-radius: var(--board-radius); background: none; color: var(--board-ink); }
.gb-header-icon:hover { background: var(--board-tint); color: var(--board-text); text-decoration: none; }
/* The unread count: a 16px accent pill on the icon's top-right, ringed in the header's ground so it never touches the glyph under it. */
.gb-header-icon .gb-badge { position: absolute; top: 0.125rem; right: 0.125rem; display: inline-flex; align-items: center; justify-content: center; min-width: 1rem; height: 1rem; padding: 0 0.25rem; border-radius: 999px; border: 0; box-shadow: 0 0 0 2px var(--board-bg); background: var(--board-accent); color: var(--board-on-accent); font-size: max(0.625rem, var(--board-text-floor)); font-weight: 700; line-height: 1; }

/* The menu on a pointer: a plain row of links, the hamburger details' summary hidden and the details itself gone from the row — the nav is a row item in its own right (see the 47.99rem block for the phone). */
.board-menu-pop { display: none; }
.board-menu { display: block; }
.board-band { display: none; }
/* The phone's drawer carries the search and the way in, and the row names the board being read (C-mobile); on a pointer the row has all three of its own. */
.board-here, .board-menu-search, .board-menu-account, .board-menu-me { display: none; }
.board-menu ul { display: flex; flex-wrap: nowrap; gap: 0 var(--board-space-1); list-style: none; margin: 0; padding: 0; }
/* C's menu link: 15px at 600 in the ink, an 8px by 10px pad. Centred flex so a nav-badge pill sits after the title without lifting the box off the line. */
.board-menu a { display: flex; align-items: center; gap: 0.32rem; padding: var(--board-space-2) 0.625rem; font-weight: 600; font-size: var(--board-size-head); color: var(--board-ink); }
.board-menu a:hover { color: var(--board-accent-text); text-decoration: none; }
/* The current board in the accent; with a near-black accent the weight still holds it apart from its neighbours. */
.board-menu a[aria-current] { color: var(--board-accent-text); font-weight: var(--board-weight-bold); }
/* Production's badge (the "NEW" pill by a menu item): literals, so the pill is the same in dark mode. Production's pill is inline, so its box is the 10px face's content area (15px) plus the pad, 17.6px; here it is a flex item, so the line height stands in for that area. */
.nav-badge { flex-shrink: 0; font-size: max(10px, var(--board-text-floor)); font-weight: 800; line-height: max(15px, calc(var(--board-text-floor) + 2px)); letter-spacing: 0.25px; padding: 0.08rem 0.34rem; border-radius: 999px; background: var(--board-accent); color: var(--board-on-accent); }

/*
 * The main column with the rail on its right (default-skins.md §1, C: main 50–958, rail 990–1230).
 * The rail comes first in the markup, so the grid places both by column. No rail (board-skin.md §9),
 * or one with nothing in it — a site that invites nobody in has no member box to draw, and with no
 * menu the rail is empty (overseas-11): the main column takes the whole width.
 */
.board-body { display: grid; grid-template-columns: minmax(0, 1fr) var(--board-rail-w); column-gap: var(--board-space-7); padding: var(--board-space-6) 0 3.5rem; align-items: start; }
.board-body:not(:has(> .board-rail:not(:empty))) { grid-template-columns: minmax(0, 1fr); }
.board-rail:empty { display: none; }
.board-main { min-width: 0; grid-column: 1; grid-row: 1; }
.board-rail { min-width: 0; grid-column: 2; grid-row: 1; display: flex; flex-direction: column; gap: 1.75rem; }
/*
 * A composed page with its own sidebar (the home's): one right column, the rail over the page's
 * sidebar. The main element spans the body on a subgrid, so its title runs the width, its main area
 * takes the left column and its sidebar drops under the rail; the last row grows with the main area.
 * The rail sits over the main element's box, so it is lifted to take its own clicks.
 */
.board-body:has(> .board-rail:not(:empty)):has(> .board-main > aside.gb-sidebar:not(:empty)) { grid-template-rows: auto auto auto 1fr auto; }
.board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) { grid-column: 1 / -1; grid-row: 1 / -1; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; }
.board-body:has(> .board-rail:not(:empty)):has(> .board-main > aside.gb-sidebar:not(:empty)) > .board-rail { grid-row: 2; position: relative; z-index: 1; }
.board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) > .gb-page-title { grid-column: 1 / -1; grid-row: 1; }
.board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) > .gb-area-page-main { grid-column: 1; grid-row: 2 / 5; }
.board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) > aside.gb-sidebar { grid-column: 2; grid-row: 3; margin-top: 1.75rem; }
.board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) > .gb-area-page-bottom { grid-column: 1 / -1; grid-row: 5; }

/* The one reusable region: C draws no card, so it is a plain block on the page; its first heading carries the rule. */
.board-card {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}
/* The phone layout stops just under 48rem, so a 768px tablet (iPad portrait, the `md` of the usual grids) keeps the wide one. The boundary is not one line but production's own per part (_breakpoints.scss, below() = max-width): the list table and the pager drop at 43.75rem (its tablet-narrow, 700px), the list's search and head at 37.5rem (mobile, 600px), the gallery and card grids at 47.5rem (tablet, 760px), and everything else — this card pad, the header, the tiles — stays at 47.99rem. max-width rather than a range query so older iOS Safari still reads it. */
/* A phone's gutter is C's 14px. */
@media (max-width: 47.99rem) {
  :root:root { --board-card-pad: calc(var(--board-space-4) * var(--ui-density, 1)); --board-gap: 0.875rem; }
}

/* A box is a titled group: a heading over a list. No border, no band. */
.box { position: relative; margin: 0; }
.box-title { font-size: var(--board-size-head); font-weight: var(--board-weight-title); color: var(--board-text); margin: 0; }
/*
 * The rail is a step below the main column (default-skins.md §1, the owner's review): its headings
 * are 14px over a 1px hairline, never the main column's 2px rule, and its rows part by the faintest
 * divider.
 */
.board-rail .box-title, .board-main > aside.gb-sidebar .box-title, .board-main > aside.gb-sidebar .gb-widget h2 { font-size: var(--board-size-ui); font-weight: var(--board-weight-bold); padding: 0 0 var(--board-space-2); margin: 0; border-bottom: 1px solid var(--board-line); }
.box-nav ul { list-style: none; margin: 0; padding: 0; }
.box-nav ul ul { padding: 0; }
.box-nav li a { display: flex; align-items: center; gap: var(--board-space-2); padding: 0.5625rem 0; border-bottom: 1px solid var(--board-hair); font-size: var(--board-size-ui); color: var(--board-text); }
.box-nav li a:hover { color: var(--board-accent-text); text-decoration: none; }
.box-nav li li a { padding-left: var(--board-space-3); font-size: var(--board-size-meta); color: var(--board-mid); }
.box-nav a[aria-current] { color: var(--board-accent-text); font-weight: var(--board-weight-bold); }
/* The member box is no card: a hairline under it, like every other rail block. */
.phone-write { display: none; }
.box-member { padding: 0 0 var(--board-space-4); border-bottom: 1px solid var(--board-line); }
.member-name { font-size: var(--board-size-head); font-weight: var(--board-weight-bold); margin: 0 0 var(--board-space-2); }
.member-links { list-style: none; margin: 0 0 var(--board-space-2); padding: 0; font-size: var(--board-size-meta); color: var(--board-mid); }
.member-links li { padding: 2px 0; }
.box-member form { font-size: var(--board-size-meta); color: var(--board-dim); }
.box-member .btn-block { display: flex; --board-control-h: 2.5rem; }
/* C-home's 글쓰기: the box's one filled button, 40px across the box with the pencil before the word. */
.box-member .member-write { align-items: center; justify-content: center; gap: 0.375rem; margin-top: var(--board-space-3); border-radius: var(--board-radius); font-size: var(--board-size-ui); font-weight: var(--board-weight-bold); }
/* A page that places Core's `me` widget already draws the name, the links and the doors there: the box keeps its 글쓰기 alone. */
.board-shell:has(.gb-widget-me) .box-member { padding: 0; border-bottom: 0; }
.board-shell:has(.gb-widget-me) .box-member > :not(.member-write, [data-viewer-branch="member"]),
.board-shell:has(.gb-widget-me) .box-member [data-viewer-branch="member"] > :not(.member-write) { display: none; }
.board-shell:has(.gb-widget-me) .box-member .member-write { margin-top: 0; }

@media (pointer: coarse) {
  .box-nav li a { min-height: 2.75rem; }
  .member-links a,
  .box-member .btn-block {
    min-height: 2.75rem;
  }

  .member-links a {
    display: inline-flex;
    align-items: center;
  }
}

/* The footer runs the full window like the header band: a surface strip with the hairline on top only, its row repeating the shell's column so the links and the copyright line up with the body. It stands outside .board-shell for that width (index.tsx, board-skin.md §9). Its pad is production's 23.2px, a literal off the spacing scale, and its line height is the 1.6 that fills the band's 73px. */
.board-footer { background: var(--board-bg); border-top: 1px solid var(--board-line); padding: var(--board-space-6) 0; color: var(--board-dim); font-size: var(--board-size-meta); line-height: 1.6; }
.footer-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--board-space-2) var(--board-space-4); max-width: var(--board-max); margin: 0 auto; padding: 0 var(--board-gap); }
.gb-footer-links { display: flex; flex-wrap: wrap; align-items: center; gap: var(--board-space-4); }
.board-footer p { margin: 0; }
.footer-copy { font-size: var(--board-size-caption); }
/* Any nav in the row — the chrome.footer slot's and the site's footer menu — reads as one run of inline links at the row's size, with no rule or pad of its own, since the band draws the only hairline. */
.gb-footer-links nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--board-space-4); border-top: 0; padding-top: 0; color: var(--board-dim); font-size: var(--board-size-meta); }
.gb-footer-links nav a { color: inherit; }
.gb-footer-links .gb-lang-switch ul { display: flex; flex-wrap: wrap; gap: var(--board-space-2) var(--board-space-4); margin: 0; padding: 0; list-style: none; }
.gb-footer-links .gb-lang-switch a, .gb-footer-links .gb-lang-switch span { display: inline-flex; align-items: center; min-block-size: 44px; color: inherit; }

/*
 * Core's composed page: the reading area beside a supporting sidebar, then the bottom band under
 * both (pages-and-layouts.md §4). Independent groups share the same gap in both directions.
 */
/* With no rail beside it, a composed page draws its own two columns, the sidebar at the rail's width. */
.board-body:not(:has(> .board-rail:not(:empty))) > .board-main:has(> aside.gb-sidebar:not(:empty)) { display: grid; grid-template-columns: minmax(0, 1fr) var(--board-compose-w); column-gap: var(--board-space-7); align-items: start; }
.board-main > .gb-page-title { grid-column: 1 / -1; }
/* The bottom band takes the shell's whole width, under both columns (pages-and-layouts.md §5). */
.board-main > .gb-area-page-bottom { grid-column: 1 / -1; }
/* Zero-min columns and items: one unbreakable line inside a widget must not widen the page on a phone (board-skin.md §9). */
.board-main > .gb-area-page-main, .board-main > aside.gb-sidebar { min-width: 0; }
/*
 * The main area is two columns and each slot takes the width its layout asked for: span 1 is one
 * column, and anything else - span 2 up, full, or no span at all - runs the whole width. The site's
 * home is a market card a column over a full-width feed (site-composition.md §2).
 */
.gb-area-page-main { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--board-space-7) 1.75rem; align-content: start; }
.gb-area-page-main > * { min-width: 0; }
.gb-area-page-main > .gb-widget-slot:not([data-span="1"]) { grid-column: 1 / -1; }
/*
 * The bottom band is three columns on the same reading: span 1 and span 2 keep their columns, and
 * span 3 up, full or none run the whole width (site-composition.md §2).
 */
.gb-area-page-bottom { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--board-space-7) 1.75rem; margin-top: var(--board-space-7); }
.gb-area-page-bottom > * { min-width: 0; }
.gb-area-page-bottom > .gb-widget-slot[data-span="2"] { grid-column: span 2; }
.gb-area-page-bottom > .gb-widget-slot:not([data-span="1"]):not([data-span="2"]) { grid-column: 1 / -1; }
/*
 * The space side area stacks its widgets with the main grid's vertical gap, so two boxes never run
 * together (site-composition.md §2). A composed page's sidebar is one card instead: its widgets share
 * a single surface, each heading in its own band and a hairline between one widget and the next, so
 * the whole side reads as one box (board-skin.md §2).
 */
.gb-area-space-sidebar { display: flex; flex-direction: column; gap: var(--board-gap); }
/* The widgets above the board's head stack with production's 10px, so two of them never run together (site-composition.md §2, board-skin.md §9). */
.gb-area-space-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.625rem; }
/* A composed page's sidebar is the rail's register: its widgets stack 28px apart, each under its own 14px heading and hairline. */
.gb-area-page-sidebar { display: flex; flex-direction: column; gap: 1.75rem; }
.gb-area-page-sidebar .gb-widget, .gb-area-page-sidebar .gb-slot > section { background: none; border: 0; border-radius: 0; box-shadow: none; padding: 0; }
/* The last row of a widget draws no line of its own: the widget's end is the one line below, and two rows of hairlines 20px apart read as a double rule (board-skin.md §2). */
.gb-area-page-sidebar .box-rows > li:last-child, .gb-area-page-sidebar .recent-comments > li:last-child { border-bottom: 0; }
/*
 * A widget that rendered nothing keeps its wrapper but takes no cell, taken out by Core's Area
 * setting the hidden attribute. The guard is here because an author rule that sets a value other
 * than none on the slot would outrank the browser's own rule for the attribute, exactly as the
 * pager's does below (skin-api.md §3a).
 */
.gb-widget-slot[hidden] { display: none; }
/*
 * C draws no card: a widget is a region on the page, led by its heading over the 2px rule. A
 * plugin's bare section in a content slot is the same region.
 */
.gb-widget:not(.gb-widget-hero), .gb-slot > section { background: none; border: 0; border-radius: 0; box-shadow: none; padding: 0; }
.gb-widget > h2, .gb-slot > section > h2 { font-size: var(--board-size-head); font-weight: var(--board-weight-bold); margin: 0 0 var(--board-space-1); padding: 0 0 var(--board-space-2); border-bottom: 2px solid var(--board-ink); }
/* A site's introduction: the page's lead type over a hairline, no frame and no band. */
.gb-widget-hero { padding: var(--board-space-2) 0 var(--board-space-6); border-bottom: 1px solid var(--board-line); }
.gb-widget.gb-widget-hero h2 { font-size: var(--board-size-title); line-height: var(--board-leading-tight); margin: 0 0 var(--board-space-3); padding: 0; border: 0; letter-spacing: -0.03em; max-width: 24ch; }
.gb-widget-hero p { margin: 0 0 var(--board-space-4); color: var(--board-mid); font-size: var(--board-size-read); line-height: 1.7; max-width: 40rem; }
/* Its way in is outlined: the screen's one filled button belongs to the page's own action. */
.gb-widget-hero a.gb-cta, .gb-widget-hero p > a:only-child { display: inline-flex; align-items: center; min-height: var(--board-control-h); padding: 0 var(--board-space-4); border: 1px solid var(--board-rule); border-radius: var(--board-radius); color: var(--board-text); font-size: var(--board-size-meta); font-weight: var(--board-weight-bold); }
.gb-widget-hero a.gb-cta:hover, .gb-widget-hero p > a:only-child:hover { background: var(--board-tint); text-decoration: none; }
.gb-widget-markdown { line-height: var(--board-leading-read); font-size: var(--board-size-ui); color: var(--board-mid); max-width: 44rem; }
/* Introductory prose continues the page introduction; it is not another independently framed item. */
.gb-area-page-main > .gb-widget-slot > .gb-widget-markdown { background: none; border: 0; border-radius: 0; box-shadow: none; padding: 0; }
.gb-widget-hero > :last-child, .gb-widget-markdown > :last-child { margin-bottom: 0; }
.gb-widget-markdown > :first-child { margin-top: 0; }
.gb-widget-tags ul, .gb-widget-menu ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--board-space-1); }
/* A tag and its count form one readable unit rather than a run of unrelated words and digits. */
.gb-widget-tags ul { padding-top: var(--board-space-3); gap: var(--board-space-1) var(--board-space-3); }
.gb-widget-tags li, .gb-widget-tags .gb-tag-list > li { display: inline-flex; align-items: baseline; gap: 0.1875rem; padding: 0; border: 0; }
.gb-widget-tags li a { display: inline-flex; align-items: center; min-height: 1.75rem; font-size: var(--board-size-meta); color: var(--board-mid); }
.gb-widget-tags li a::before { content: "#"; }
.gb-widget-tags li small { color: var(--board-dim); font-size: var(--board-size-caption); font-variant-numeric: tabular-nums; }
.gb-widget-stats { display: flex; gap: var(--board-space-6); color: var(--board-dim); }
/* A widget on the home: a bold name, 더 보기 at the far end, rows under a hairline. */
.box-list, .box-cards, .box-compact, .box-digest { margin: 0; }
/* In a composed grid a widget fills its cell, so two cards side by side end on one line (a bottom band's 읽을거리 beside a short tile). */
.gb-area > .gb-widget-slot > .gb-widget { height: 100%; }
/* A section's head: its 15px name and 더보기 at the far end, over the region's 2px rule in the text colour (C). */
.box-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--board-space-2) var(--board-space-3); padding-bottom: var(--board-space-2); border-bottom: 2px solid var(--board-ink); }
.box .box-head .box-title { flex: 1 1 10ch; min-width: 0; padding: 0; margin: 0; border: 0; font-size: var(--board-size-head); }
/* In the rail the head steps down: a 14px name over the 1px hairline. */
:is(.board-rail, .board-main > aside.gb-sidebar) .box-head { border-bottom: 1px solid var(--board-line); }
/* The head already draws the rail's hairline, so its title draws none: the rail heading rule above outranks .box .box-head .box-title and would put a second line under the name. */
:is(.board-rail, .board-main > aside.gb-sidebar) .box .box-head .box-title { font-size: var(--board-size-ui); padding: 0; border: 0; }

/*
 * A feed the layout arranged as a compact box (site-composition.md §2): one line per post with the
 * date and the marks taken off it, for a box a reader scans rather than reads. The rank the layout
 * asked for stands in its own column before the title, and the count is the bare number at the
 * row's end (board-skin.md §8).
 */
.box-compact .box-rows li { display: flex; align-items: center; gap: var(--board-space-2); min-height: 2.4375rem; padding: 0.5625rem 0; border-bottom: 1px solid var(--board-hair); font-size: var(--board-size-ui); }
/* C closes a section with its last row's divider, so the list ends on a line like a table. */
.box-compact .box-row { align-items: center; }
.box-compact .box-row-title { flex: 1; }
/* The rank's column: 19px and tabular, so 1..9 line up whether the box holds nine rows or twenty. */
.box-rank { flex: none; width: 1.1875rem; color: var(--board-dim); font-weight: var(--board-weight-bold); font-variant-numeric: tabular-nums; text-align: left; }
/* The first three ranks in the accent, the rest muted (C's 실시간 인기). */
.box-rows > li:nth-child(-n + 3) .box-rank { color: var(--board-accent-text); }
/* A comment count rides the title as [n] in the accent, 12px at 600 (C). */
.box-count { flex: none; color: var(--board-count); font-size: var(--board-size-caption); font-weight: 600; font-variant-numeric: tabular-nums; }
.box-count::before { content: "["; }
.box-count::after { content: "]"; }
/* A sidebar box keeps the count right after the title rather than at the row's end, so it stays when the title runs out of room (board-skin.md §2). */
.gb-area-page-sidebar .box-compact .box-row-title { flex: 0 1 auto; }

/*
 * A feed the layout arranged as a digest (site-composition.md §2): a 72x54 thumbnail, the board's
 * name, the title and the post's excerpt — the shape a feed of mixed boards wants, where naming the
 * board is what a card's caption could not do (board-skin.md §8).
 */
.box-digest .box-rows li { display: flex; align-items: center; gap: var(--board-space-4); height: 4.6875rem; padding: 0; border-bottom: 1px solid var(--board-hair); }
/* The picture is always a box, cover or none, so a column of rows keeps one left edge; a post without one gets the page icon in the same frame. */
.digest-cover { flex: none; display: flex; align-items: center; justify-content: center; width: 4.5rem; height: 3.375rem; background: var(--board-tint); border: 0; border-radius: var(--board-radius-s); overflow: hidden; color: var(--board-dim); }
.digest-cover img { display: block; width: 100%; height: 100%; object-fit: cover; }
.digest-body { flex: 1; min-width: 0; }
.digest-line { display: flex; align-items: baseline; gap: var(--board-space-2); margin: 0; }
.digest-space { flex: none; color: var(--board-accent-text); font-size: var(--board-size-caption); font-weight: var(--board-weight-bold); }
.digest-title { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--board-text); font-size: var(--board-size-ui); font-weight: 500; }
.digest-summary { margin: 0; color: var(--board-dim); font-size: var(--board-size-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/*
 * The board directory Core renders as its own boards widget (site-composition.md §2, board-skin.md
 * §8): a grid of four tiles, one per board, each the board's name over its newest post over the word
 * to go in, and the whole tile one link to the board. The hairlines are drawn by the tile that has a
 * neighbour — a column's own edge ends the row and draws nothing. 286x112 in production, and the
 * name underlines on hover rather than the whole tile.
 */
.box-boards .board-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); list-style: none; margin: 0; padding: 0; border-bottom: 1px solid var(--board-hair); }
.box-boards .board-tiles > li { min-width: 0; }
/* The vertical hairline sits before every tile but a row's first; the horizontal one above every tile from the second row on. */
.box-boards .board-tiles > li:not(:nth-child(4n + 1)) { border-left: 1px solid var(--board-line); }
.box-boards .board-tiles > li:nth-child(n + 5) { border-top: 1px solid var(--board-line); }
.board-tile { display: flex; flex-direction: column; gap: var(--board-space-2); min-height: 7rem; padding: 0.9rem 0.75rem; }
/* The name's row carries the layout's own word for the board (the notes prop) at its far end. */
.board-tile-top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--board-space-2); min-width: 0; }
.board-tile-name { color: var(--board-ink); font-size: var(--board-size-head); font-weight: var(--board-weight-bold); }
.board-tile-note { flex: none; color: var(--board-dim); font-size: var(--board-size-caption); }
/* The newest post's title on one line: a long title ends in an ellipsis rather than pushing the tile wider. */
.board-tile-latest { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--board-dim); font-size: var(--board-size-meta); }
.board-tile-go { color: var(--board-dim); font-size: var(--board-size-caption); }
.board-tile:hover .board-tile-name { text-decoration: underline; }
/* Two columns on a phone: the same hairlines, one shorter row apiece, and the four-column rules undone. */
@media (max-width: 47.99rem) {
  .box-boards .board-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .box-boards .board-tiles > li:not(:nth-child(4n + 1)) { border-left: 0; }
  .box-boards .board-tiles > li:nth-child(n + 5) { border-top: 0; }
  .box-boards .board-tiles > li:not(:nth-child(odd)) { border-left: 1px solid var(--board-line); }
  .box-boards .board-tiles > li:nth-child(n + 3) { border-top: 1px solid var(--board-line); }
}

/* Account settings: provider rows grow a password field only for a sensitive unlink. */
.gb-account-providers ul { display: grid; gap: var(--board-space-2); margin: 0; padding: 0; list-style: none; }
.gb-account-providers li { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--board-space-3); padding: var(--board-space-3) 0; border-bottom: 1px solid var(--board-line); }
.gb-account-providers form.gb-inline { display: flex; align-items: flex-end; justify-content: flex-end; gap: var(--board-space-2); flex-wrap: wrap; }
.gb-account-providers .gb-provider-password { display: grid; gap: var(--board-space-1); margin: 0; color: var(--board-dim); font-size: var(--board-size-caption); font-weight: var(--board-weight-normal); }
.gb-account-providers .gb-provider-password input { width: min(14rem, 100%); }
@media (max-width: 47.99rem) {
  .gb-account-providers li { align-items: stretch; flex-direction: column; }
  .gb-account-providers form.gb-inline { justify-content: flex-start; }
  .gb-account-providers .gb-provider-password { flex: 1 1 100%; }
  .gb-account-providers .gb-provider-password input { width: 100%; }
}

/*
 * Search narrowing/recovery: the reader should see what changed the answer before the results, and
 * the recovery link sits with the empty result rather than looking like another search mode.
 */
.gb-search-scope {
  margin: calc(-1 * var(--board-space-2)) 0 var(--board-space-4);
  color: var(--board-dim);
  font-size: var(--board-size-meta);
}
.gb-search-scope a { color: var(--board-accent-text); font-weight: var(--board-weight-bold); }
.gb-search-empty-action { margin: var(--board-space-4) 0 0; text-align: center; }

@media (max-width: 60rem) {
  /* One column: the main column, then the rail under it. The subgrid of a composed page lets go, so its sidebar follows its main area. */
  .board-body, .board-body:has(> .board-rail:not(:empty)):has(> .board-main > aside.gb-sidebar:not(:empty)) { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; gap: var(--board-space-7); padding-top: var(--board-space-5); }
  .board-body > .board-main, .board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) { grid-column: 1; grid-row: auto; display: block; }
  .board-body > .board-rail, .board-body:has(> .board-rail:not(:empty)):has(> .board-main > aside.gb-sidebar:not(:empty)) > .board-rail { grid-column: 1; grid-row: auto; order: 2; }
  .board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) > aside.gb-sidebar { margin-top: var(--board-space-7); }
  .board-body:has(> .board-rail:not(:empty)) > .board-main:has(> aside.gb-sidebar:not(:empty)) > .gb-area-page-bottom { margin-top: var(--board-space-7); }
  .box-member { display: none; }
  /* C-mobile-list's floating 글쓰기 (`PhoneWrite`): the login box's write button for a phone, gone where the page draws a board's own. */
  .phone-write { position: fixed; z-index: 35; right: max(1rem, env(safe-area-inset-right)); bottom: calc(1.5rem + env(safe-area-inset-bottom)); display: flex; align-items: center; gap: 0.375rem; height: 3rem; padding: 0 1.125rem 0 1rem; border-radius: 1.5rem; background: var(--board-ink); color: var(--board-bg); font-size: var(--board-size-ui); font-weight: var(--board-weight-bold); box-shadow: 0 2px 10px rgb(0 0 0 / 0.22); text-decoration: none; }
  .phone-write svg { width: 1.125rem; height: 1.125rem; }
  .board-shell:has(.btn-write, .write-fab) .phone-write { display: none; }
  .board-body:not(:has(> .board-rail:not(:empty))) > .board-main:has(> aside.gb-sidebar:not(:empty)) { grid-template-columns: minmax(0, 1fr); }
}

/*
 * Collapse the header before its menu and account controls run out of room. The brand may shorten,
 * but actions stay together on one row. Only the expanded navigation takes a second row.
 */
@media (max-width: 70rem) {
  /* The row wraps so the menu can take a line of its own; auto height lets it grow with that line, the min keeps the closed row production's 64px. No wrap gap: production puts the menu straight against the row, its hairline the only separation. */
  .board-header-row { position: relative; flex-wrap: wrap; height: auto; min-height: 3.5rem; row-gap: 0; }
  .board-spacer { display: none; }
  /* The phone shrinks the row: a 20px brand and 38px icon circles (production's own values at 390), the brand's right margin gone since the hamburger now leads it. */
  .gb-brand { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: calc(1.0625rem + var(--board-text-step)); margin-right: 0; }
  /* C's phone header (C-mobile): 「사이트 / 게시판」 on the left, the board in the accent at 14px/600, and the brand gives the board the room the row has left. */
  .board-header-row:has(> .board-here) > .gb-brand { flex: 0 1 auto; max-width: 55%; }
  .board-here { display: flex; align-items: baseline; gap: 0.375rem; flex: 1 1 0; min-width: 0; }
  .board-here-sep { color: var(--board-dim); }
  .board-here a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--board-size-ui); font-weight: 600; color: var(--board-accent-text); }
  /* Right of the board: the theme switch, a plugin's icons and the bell, then the hamburger last (C-mobile). The search and the sign-in move into the menu, so the row drops its own while there is a menu to hold them. */
  .gb-theme-toggle { order: 2; }
  .gb-account { order: 3; }
  .board-header-row:has(> .board-menu-pop) > .board-search-pop,
  .board-header-row:has(> .board-menu-pop) > .gb-account :is(.gb-sign-in, .sign-up) { display: none; }
  .board-menu-pop > summary, .board-search-pop > summary, .gb-theme-toggle { width: 2.375rem; height: 2.375rem; }
  /* The account is the person icon alone at this width — the name would push the row past 360px. */
  .gb-account-menu > summary .gb-viewer-name { display: none; }
  /* The account menu is a sheet from the bottom, the phone convention: the button is the avatar alone, the dim behind it is the summary's own and a tap on it closes the sheet. */
  .gb-account-menu > summary .gb-icon-chevron { display: none; }
  .gb-account-menu .gb-menu-list .gb-menu-me, .gb-account-menu .gb-menu-list .gb-menu-posts { display: flex; }
  .gb-account-menu .gb-menu-list .gb-menu-profile { display: none; }
  .gb-menu-me { gap: var(--board-space-2); font-weight: var(--board-weight-bold); }
  .gb-menu-me .gb-avatar-initial { display: inline-flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; border: 1px solid var(--board-line); }
  .gb-account-menu[open] > summary::after { content: ""; position: fixed; inset: 0; z-index: 40; background: rgb(0 0 0 / 40%); }
  .gb-account-menu[open] > .gb-menu-list { position: fixed; inset: auto 0 0 0; z-index: 41; min-width: 0; max-height: 80vh; overflow-y: auto; padding: var(--board-space-2) var(--board-space-2) calc(var(--board-space-2) + env(safe-area-inset-bottom)); border-width: 1px 0 0; border-radius: 1rem 1rem 0 0; box-shadow: 0 -10px 30px rgb(0 0 0 / 15%); }
  .gb-header-icon { width: 2.375rem; height: 2.375rem; }
  /* The hamburger ends the row: the base sheet hides the details on a pointer, here it comes back. */
  .board-menu-pop { display: block; order: 4; position: static; flex: none; align-self: center; }
  /* Block-level, not inline-flex: an inline summary inside a block details leaves a line box whose descender space pushes the hamburger off centre. */
  .board-menu-pop > summary { display: flex; }
  /* Production leaves the open hamburger as it is — no tint — so the base sheet's open ground stops here. */
  .board-menu-pop[open] > summary { background: none; color: var(--board-ink); }
  /* The menu is a line of the wrapped row, so it is in flow: opening it grows the header and shifts main, rather than overlaying the page. It shows only while its trigger's details is open — the open flag is the whole state, no script. */
  .board-menu { order: 5; flex-basis: 100%; display: none; }
  /* min-width 0: a flex item's floor is otherwise its content's one-line width, which pushed the page sideways instead of scrolling the list (noriter-171). */
  .board-band { order: 6; flex-basis: 100%; min-width: 0; display: block; border-top: 1px solid var(--board-line); }
  .board-band ul { display: flex; overflow-x: auto; scrollbar-width: none; white-space: nowrap; margin: 0; padding: 0 0.375rem; list-style: none; }
  .board-band ul::-webkit-scrollbar { display: none; }
  /* The row's ends fade while there is more past them (scroll shadows: the "local" layers cover the "scroll" ones once the end is reached), so a half-seen last tab reads as a row that goes on. */
  .board-band ul { background: linear-gradient(to right, var(--board-bg) 30%, transparent) left / 2rem 100% no-repeat local, linear-gradient(to left, var(--board-bg) 30%, transparent) right / 2rem 100% no-repeat local, linear-gradient(to right, var(--board-line), transparent) left / 0.75rem 100% no-repeat scroll, linear-gradient(to left, var(--board-line), transparent) right / 0.75rem 100% no-repeat scroll; }
  .board-band a { display: flex; align-items: center; min-height: 2.75rem; padding: 0 0.625rem; font-size: var(--board-size-head); font-weight: 600; color: var(--board-ink); }
  .board-band a[aria-current] { color: var(--board-accent-text); }
  .board-header-row:has(> .board-menu-pop[open]) > .board-band { display: none; }
  .board-header-row:has(> .board-menu-pop[open]) > .board-menu { display: block; border-top: 1px solid var(--board-line); padding: 0.35rem 0 var(--board-space-3); }
  /* One full-width column, rows touching — production's single column with no gap between links. */
  .board-menu ul { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
  /* Production's drawer link: 44px tall, 8.8/9.6 padding, 16px/600 ink on a 6.4px radius. Off the skin's scale, so literals. */
  .board-menu a { min-height: 2.75rem; padding: 0.55rem 0; border-radius: 0; border-bottom: 1px solid var(--board-hair); line-height: 1.6; font-size: var(--board-size-head); }
  .board-menu a[aria-current] { color: var(--board-accent-text); font-weight: var(--board-weight-bold); }
  /* The drawer's search heads it and the way in closes it: the same field and button as the row's panel, laid in the menu's column. */
  .board-menu-search { display: flex; gap: var(--board-space-1); padding: var(--board-space-2) 0 var(--board-space-3); border-bottom: 1px solid var(--board-hair); }
  .board-menu-search input { flex: 1 1 0; min-width: 0; }
  .board-menu-search button { flex: none; }
  /* The signed-in block heads the drawer: the name, the account's links as rows, 로그아웃 last. */
  .board-menu-me { display: block; padding-bottom: var(--board-space-2); border-bottom: 1px solid var(--board-hair); }
  .board-menu .board-menu-who { display: flex; align-items: center; gap: var(--board-space-2); font-weight: var(--board-weight-bold); }
  .board-menu-who .gb-avatar-initial { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; border: 1px solid var(--board-line); font-size: var(--board-size-ui); }
  .board-menu-me ul { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--board-space-4); }
  .board-menu-me .nav-badge { margin-left: var(--board-space-1); }
  .board-menu .board-menu-me form button.gb-link { min-height: 2.75rem; color: var(--board-dim); font-size: var(--board-size-ui); font-weight: 600; }
  .board-menu-account { display: flex; gap: var(--board-space-5); margin: 0; padding-top: var(--board-space-1); }
  .board-menu .board-menu-account a { display: inline-flex; padding: 0; border-bottom: 0; font-size: var(--board-size-ui); }
  /* The search panel takes the same full-width placement; the row is now its containing block too. */
  .board-search-pop { position: static; }
  .board-search-pop .gb-site-search { left: 0; right: 0; top: 100%; width: auto; border-radius: 0 0 var(--board-radius) var(--board-radius); }
  /* The field takes what the button leaves: without min-width 0 it keeps its intrinsic width and pushes the button past a 390px screen. */
  .board-search-pop .gb-site-search input { width: auto; flex: 1 1 0; min-width: 0; }
  .board-search-pop .gb-site-search button { flex: none; }
  .gb-account .sign-up { --board-control-pad-x: 0.6rem; }
}

@media (max-width: 37.5rem) {
  .board-header-row { column-gap: var(--board-space-1); padding-inline: var(--board-space-3); }
  /* Sign-up remains on the sign-in screen; the header keeps one readable account entry on phones. */
  .gb-account .sign-up { display: none; }
  .gb-account .gb-sign-in { display: inline-flex; align-items: center; justify-content: center; min-height: 2.75rem; padding-inline: var(--board-space-1); }
}

@media (max-width: 47.99rem) {
  /*
   * One column on a phone: the two market cards and both bottom rows follow main then sidebar then
   * bottom, with nothing beside them and nothing to scroll sideways (board-skin.md §9). The span
   * rules are repeated at their own weight so an implicit column cannot widen the page.
   */
  .gb-area-page-main, .gb-area-page-bottom { grid-template-columns: minmax(0, 1fr); }
  .gb-area-page-main > .gb-widget-slot, .gb-area-page-main > .gb-widget-slot:not([data-span="1"]),
  .gb-area-page-bottom > .gb-widget-slot, .gb-area-page-bottom > .gb-widget-slot[data-span="2"],
  .gb-area-page-bottom > .gb-widget-slot:not([data-span="1"]):not([data-span="2"]) { grid-column: 1 / -1; }
}
