/* 업무위키 -- site stylesheet. No external fonts/CDNs; system font stack
   only. Namuwiki-inspired layout/visual language (own wordmark, not a copy
   of any third-party logo/trademark). Light theme by default, dark via
   prefers-color-scheme. */

:root {
  /* Two separate accent roles, deliberately not one shared variable:
     --accent is used as TEXT/link/border color on the page's own (light)
     background (toc numbers, heading numbers, callout rules, the logo's
     "업무" half, ...) -- it only ever needs to read against --bg/--bg-alt.
     --accent-fill is used as a SOLID BACKGROUND behind WHITE text (topbar,
     the mobile nav dropdown, filled buttons) -- that pairing needs its own
     independently-verified ≥4.5:1-against-white contrast, which is NOT the
     same requirement and, in dark mode below, is NOT the same color (see
     that block's comment). In light mode both happen to be the same safe
     value. #00796b has a measured contrast ratio of ~5.3:1 against white
     text (WCAG AA normal-text threshold is 4.5:1), unlike the brighter
     #00A495 reference shade, which only reaches ~3.1:1. */
  --accent: #00796b;
  --accent-fill: #00796b;
  --accent-fill-hover: #00564a;  /* hover/active shade of --accent-fill */
  --accent-soft: #e3f2ef;  /* pale teal tint for chips/backgrounds */
  --bg-page: #f5f5f5;      /* page background (Namuwiki-style light gray) */
  --bg: #ffffff;           /* article/card background */
  --bg-alt: #f7f8f9;       /* subtle box background inside a card */
  --fg: #1b1e23;
  --fg-muted: #6b7280;
  --border: #e1e3e6;
  --border-strong: #cfd3d8;
  --link: #00796b;
  --link-visited: #4a6fa5;
  --red-link: #c0392b;
  --code-bg: #f0f2f5;
  --callout-bg: #eef3ff;
  --callout-border: var(--accent);
  --mark-bg: #fff1a8;
  --shadow: 0 2px 10px rgba(20, 24, 33, 0.08);
  --max-width: 1300px;
  --article-width: 1080px;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* --accent stays a brighter teal here -- it's read as TEXT against the
       dark page background (--bg: #202124), where it measures ~5.4:1
       (plenty above the 4.5:1 text threshold). It deliberately is NOT
       reused for --accent-fill: measured against WHITE text (the topbar/
       filled-button case), #26a69a only reaches ~3.0:1 -- below the
       4.5:1 threshold -- which is exactly the advisory this fixes.
       --accent-fill instead stays a dark teal close to the light-mode
       value (independently ≥4.5:1 against white in this mode too), so
       filled buttons/the topbar/the mobile nav dropdown keep readable
       white text in both themes. */
    --accent: #26a69a;
    --accent-fill: #00695c;
    --accent-fill-hover: #00483d;
    --accent-soft: #17322d;
    --bg-page: #17181a;
    --bg: #202124;
    --bg-alt: #26282c;
    --fg: #e7e9ec;
    --fg-muted: #9aa2ad;
    --border: #34363b;
    --border-strong: #45484e;
    --link: #4fd6c6;
    --link-visited: #b7c8ea;
    --red-link: #ff8a75;
    --code-bg: #1e232b;
    --callout-bg: #1c2434;
    --callout-border: var(--accent);
    --mark-bg: #6b5b13;
    --shadow: 0 2px 14px rgba(0, 0, 0, 0.5);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg-page);
  color: var(--fg);
}

body {
  font-family: "Pretendard", "Apple SD Gothic Neo", "Malgun Gothic", system-ui,
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  line-height: 1.65;
  font-size: 15px;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
a:visited { color: var(--link-visited); }

/* ---------------------------------------------------------------- topbar */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--accent-fill);
  color: #fff;
  box-shadow: var(--shadow);
}
.topbar a { color: #fff; }
.topbar a:visited { color: #fff; }
.topbar-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 0.55rem 1.25rem;
}

/* Own simple text/CSS wordmark: "업무" in solid white, "위키" a touch
   softer -- a two-tone treatment in the Namuwiki spirit without using
   Namuwiki's name, logo image, or any third-party mark. */
.site-name {
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  white-space: nowrap;
  text-decoration: none !important;
  display: inline-flex;
}
.site-name .logo-a { color: #fff; }
.site-name .logo-b { color: rgba(255, 255, 255, 0.78); font-weight: 700; }

.topnav { display: flex; gap: 0.3rem; align-items: center; }
.topnav a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
  opacity: 0.94;
  padding: 0.35rem 0.55rem;
  border-radius: 6px;
}
.topnav a:hover { opacity: 1; background: rgba(255, 255, 255, 0.14); text-decoration: none; }
.nav-icon { flex: none; }

.mobile-menu-toggle {
  display: none;
  background: none;
  border: none;
  padding: 0.4rem;
  cursor: pointer;
}
.hamburger, .hamburger::before, .hamburger::after {
  display: block;
  width: 20px;
  height: 2px;
  background: #fff;
  position: relative;
}
.hamburger::before, .hamburger::after { content: ""; position: absolute; }
.hamburger::before { top: -6px; }
.hamburger::after { top: 6px; }

.searchbox { position: relative; margin-left: auto; display: flex; align-items: center; }
.searchbox input[type="search"] {
  padding: 0.42rem 0.8rem;
  border-radius: 999px 0 0 999px;
  border: none;
  min-width: 13rem;
  font-size: 0.92rem;
  height: 2.1rem;
}
.search-icon-btn {
  height: 2.1rem;
  width: 2.1rem;
  flex: none;
  border: none;
  background: rgba(0, 0, 0, 0.14);
  color: #fff;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.search-icon-btn:hover { background: rgba(0, 0, 0, 0.24); }
.search-icon-btn:first-of-type { border-radius: 0; }
.search-icon-btn:last-of-type { border-radius: 0 999px 999px 0; }
.search-suggest {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  width: min(24rem, 90vw);
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  max-height: 60vh;
  overflow-y: auto;
  z-index: 50;
}
.suggest-item {
  display: block;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
  color: var(--fg) !important;
}
.suggest-item:last-child { border-bottom: none; }
.suggest-item:hover { background: var(--bg-alt); text-decoration: none; }
.suggest-title { display: block; font-weight: 600; }
.suggest-snippet { display: block; font-size: 0.82rem; color: var(--fg-muted); }

/* ---------------------------------------------------------------- shell */
.page-shell {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 1.25rem 1rem 4rem;
}
.site-footer {
  text-align: center;
  color: var(--fg-muted);
  font-size: 0.85rem;
  padding: 2rem 1rem 3rem;
}

/* Namuwiki-style white "card": every top-level page section (article,
   front page, recent/category/search pages, 404) shares this treatment --
   centered content on a light-gray page background, framed by a thin
   border and a slight corner radius. */
.namu-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  max-width: var(--article-width);
  margin: 0 auto;
  padding: 1.5rem 1.75rem 2rem;
}

/* ---------------------------------------------------------------- article */
.article-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--border-strong);
  padding-bottom: 0.6rem;
}
/* .page-title is a flex item of .article-header (alongside .tool-buttons)
   on article pages, and a plain block heading on the special (front/
   recent/categories/search/404) pages -- min-width:0 only matters in the
   former case (flex items' default min-width:auto refuses to shrink
   below the text's min-content width) and is a harmless no-op in the
   latter (a normal block box already shrinks to fit its container
   regardless of min-width). See .wiki-heading-row's own comment for why
   overflow-wrap+word-break need to be paired with min-width:0, not used
   alone, inside a flex row. */
.page-title {
  font-size: 1.85rem;
  font-weight: 800;
  margin: 0.2rem 0;
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: keep-all;
}
.article-subline { color: var(--fg-muted); font-size: 0.82rem; margin: 0.4rem 0 0.8rem; text-align: right; }

.tool-buttons { display: inline-flex; border: 1px solid var(--border-strong); border-radius: 6px; overflow: hidden; }
.tool-btn {
  padding: 0.3rem 0.7rem;
  font-size: 0.82rem;
  color: var(--fg-muted) !important;
  white-space: nowrap;
  background: var(--bg-alt);
  border-right: 1px solid var(--border-strong);
}
.tool-btn:last-child { border-right: none; }
.tool-btn:hover { background: var(--accent-soft); color: var(--fg) !important; text-decoration: none; }

.category-box {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.8rem;
  margin: 0.75rem 0;
  font-size: 0.86rem;
}
.category-box-label { color: var(--fg-muted); margin-right: 0.5rem; }
.category-box a { margin: 0 0.5rem; }
.category-box a:first-of-type { margin-left: 0; }
.category-box-sep { color: var(--border-strong); }

.meta-box {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.8rem;
  margin: 0.5rem 0;
  font-size: 0.83rem;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0 1rem;
}
.meta-row { display: flex; gap: 0.3rem; }
.meta-key { color: var(--fg-muted); }
.meta-key::after { content: ":"; }

.toc-box {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-alt);
  padding: 0.75rem 1.1rem;
  margin: 1rem 0;
  max-width: 26rem;
}
.toc-title { font-weight: 700; margin-bottom: 0.5rem; color: var(--accent); }
.toc-list { list-style: none; margin: 0; padding: 0; font-size: 0.9rem; line-height: 1.5; }
.toc-list li { margin: 0.1rem 0; overflow-wrap: anywhere; word-break: keep-all; }
.toc-num { color: var(--accent); margin-right: 0.3rem; font-weight: 600; }
/* Bounded depth classes (see TOC_MAX_DEPTH_CLASS in wiki_site/templates.py)
   instead of a computed inline `style="margin-left:...em"` -- the site's
   own CSP (style-src 'self', no unsafe-inline) makes inline style
   attributes a no-op in the browser, so indentation has to be expressible
   as a fixed, finite set of classes. */
.toc-depth-0 { margin-left: 0; }
.toc-depth-1 { margin-left: 1.1em; }
.toc-depth-2 { margin-left: 2.2em; }
.toc-depth-3 { margin-left: 3.3em; }
.toc-depth-4 { margin-left: 4.4em; }
.toc-depth-5 { margin-left: 5.5em; }
.toc-depth-6 { margin-left: 6.6em; }
.toc-depth-7 { margin-left: 7.7em; }
.toc-depth-8 { margin-left: 8.8em; }

/* ---------------------------------------------------------------- sections */
/* The section spacing lives on `.wiki-heading-row` (the flex row), NOT on
   the heading element itself -- `align-items: center` centers each flex
   child on its own MARGIN box, so an asymmetric top/bottom margin on the
   <h*> (1.5rem top, 0.5rem bottom, for spacing above/below the section)
   would push the heading's actual glyphs off-center within that taller
   margin box, making the fold-toggle caret (a near-zero-margin sibling,
   centered on the row's true midpoint) sit visibly above the heading
   text's baseline. Zeroing the heading's own margin and moving the same
   1.5rem/0.5rem spacing onto the row instead keeps the row's external
   spacing identical while letting flex alignment center the caret against
   the heading's actual (now symmetric-margin) content box -- true at any
   viewport width, no separate mobile-only fix needed. */
/* A flex item's default `min-width` is `auto`, which resolves to its
   content's MIN-CONTENT width, not 0 -- for a heading whose text is one
   long unbreakable run (a URL-like token, a long English identifier with
   no internal spaces), that min-content width can exceed the viewport,
   and the flex item refuses to shrink below it even though
   overflow-wrap would happily break it once given the room. `min-width:
   0` on the row's children (the heading itself; the fold-toggle button
   is already small/fixed-content so doesn't need it) is what actually
   lets the row shrink to the viewport instead of forcing horizontal
   page scroll -- overflow-wrap alone is not sufficient inside a flex
   row, only outside one (see .article-body's own overflow-wrap comment
   below, which covers the NON-flex case: plain paragraphs/lists/table
   cells). `word-break: keep-all` is paired with `overflow-wrap: anywhere`
   (not the gentler `break-word` used for the general article body) so
   normal Korean text still wraps at natural word/phrase boundaries
   first -- `anywhere` is only reached as a last resort for a token that
   has no such boundary at all. */
.wiki-heading-row { display: flex; align-items: center; gap: 0.4rem; margin: 1.5rem 0 0.5rem; }
.wiki-section h1, .wiki-section h2, .wiki-section h3,
.wiki-section h4, .wiki-section h5, .wiki-section h6 {
  margin: 0;
  scroll-margin-top: 4.5rem;
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: keep-all;
}
/* Namuwiki style: a thin rule under the more prominent (h1/h2-ish) section
   headings only -- h3+ stay unruled to keep deep nesting from turning into
   a wall of horizontal lines. */
.wiki-section[data-level="1"] > .wiki-heading-row,
.wiki-section[data-level="2"] > .wiki-heading-row {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.3rem;
}
.heading-num { color: var(--accent); font-weight: 700; }

.fold-toggle {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--fg-muted);
  font-size: 0.8rem;
  padding: 0.1rem 0.3rem;
  line-height: 1;
}
.fold-toggle::before { content: "\25be"; display: inline-block; transition: transform 0.15s; }
.fold-toggle[aria-expanded="false"]::before { transform: rotate(-90deg); }

.wiki-section-body.folded { display: none; }

/* ---------------------------------------------------------------- callouts */
.callout {
  border-left: 4px solid var(--callout-border);
  background: var(--callout-bg);
  border-radius: 4px;
  padding: 0.6rem 0.9rem;
  margin: 0.9rem 0;
}
.callout-title { font-weight: 700; margin-bottom: 0.3rem; display: flex; align-items: center; gap: 0.35rem; }
.callout-title::before { content: "\24d8"; font-size: 0.95em; } /* circled "i" -- generic notice icon */
.callout-body > *:first-child { margin-top: 0; }
.callout-body > *:last-child { margin-bottom: 0; }
.callout[data-foldable] .callout-title { cursor: pointer; }
.callout[data-foldable] .callout-title::after { content: "\25be"; margin-left: auto; }
.callout.callout-folded .callout-title::after { transform: rotate(-90deg); display: inline-block; }
.callout.callout-folded .callout-body { display: none; }

.callout-warning, .callout-caution { --callout-border: #d98c00; background: #fff4e0; }
.callout-danger, .callout-error { --callout-border: #c0392b; background: #fdeceb; }
.callout-bug { --callout-border: #c0392b; background: #fdeceb; }
.callout-tip, .callout-hint, .callout-success, .callout-check, .callout-done {
  --callout-border: #1f9d55; background: #e8f8ee;
}
.callout-question, .callout-help, .callout-faq { --callout-border: #8e44ad; background: #f3e9fb; }
.callout-example { --callout-border: #16a3b8; background: #e4f7fa; }
.callout-quote, .callout-cite { --callout-border: #7f8c8d; background: #f1f2f3; }
.callout-todo { --callout-border: var(--accent); background: var(--accent-soft); }
.callout-abstract, .callout-summary, .callout-tldr { --callout-border: #16a3b8; background: #e4f7fa; }

@media (prefers-color-scheme: dark) {
  .callout-warning, .callout-caution { background: #3a2c10; }
  .callout-danger, .callout-error, .callout-bug { background: #3a1c19; }
  .callout-tip, .callout-hint, .callout-success, .callout-check, .callout-done { background: #10301d; }
  .callout-question, .callout-help, .callout-faq { background: #29193a; }
  .callout-example, .callout-abstract, .callout-summary, .callout-tldr { background: #0f2d33; }
  .callout-quote, .callout-cite { background: #24272b; }
  .callout-todo { background: var(--accent-soft); }
}

/* ---------------------------------------------------------------- content */
/* Vault prose routinely chains several inline `code` spans back-to-back
   with a middle-dot separator and no actual space character between them
   (e.g. "코드(a.py·b.py·c.py)") -- since none of those separators is a
   legal line-break opportunity, the whole chain becomes one long
   unbreakable run that silently forces horizontal scroll on the entire
   page at narrow (mobile) widths. `overflow-wrap: break-word` is
   inherited by every descendant (paragraphs, list items, table cells,
   blockquotes, headings), so the browser still prefers a normal
   space-based wrap first and only breaks mid-token as a last resort. */
.article-body { overflow-wrap: break-word; }
.article-body img { max-width: 100%; height: auto; border-radius: 6px; }
.article-body { line-height: 1.8; word-break: keep-all; }
.visual-view { margin: 1rem 0; min-width: 0; }
.visual-size-toggle {
  color: var(--link); background: var(--bg-alt); border: 1px solid var(--border);
  border-radius: 6px; padding: 0.5rem 0.75rem; cursor: pointer; font: inherit;
}
.visual-viewport { max-width: 100%; overflow: auto; margin-top: 0.4rem; }
.article-body .visual-viewport .mermaid { background: #fff; color: #1b1e23; border-radius: 6px; padding: 1rem; }
.visual-expanded .visual-viewport img { max-width: none; }
.visual-expanded .visual-viewport svg { max-width: none !important; width: auto; min-width: 100%; }
.visual-expanded .visual-viewport .mermaid { width: max-content; min-width: 100%; }
:focus-visible { outline: 2px solid var(--link); outline-offset: 3px; }
#backlinks-body { scroll-margin-top: 8rem; }
.article-body table {
  border-collapse: collapse;
  width: 100%;
  margin: 1rem 0;
  font-size: 0.9rem;
  display: block;
  overflow-x: auto;
}
.article-body th, .article-body td {
  border: 1px solid var(--border);
  padding: 0.45rem 0.65rem;
  text-align: left;
}
.article-body th { background: var(--bg-alt); font-weight: 700; }

.article-body pre {
  background: var(--code-bg);
  border-radius: 6px;
  padding: 0.8rem 1rem;
  overflow-x: auto;
  font-size: 0.86rem;
}
.article-body code {
  background: var(--code-bg);
  border-radius: 4px;
  padding: 0.1rem 0.3rem;
  font-family: ui-monospace, SFMono-Regular, "Cascadia Code", Consolas, monospace;
  /* A single long unbroken inline-code token (a long path, an arrow-joined
     pipeline name with no spaces) has nowhere to wrap by default and
     silently forces horizontal scroll on the whole page at narrow
     (mobile) widths -- overflow-wrap lets it break mid-token instead,
     inside `pre code` it's a no-op since `pre` already scrolls its own
     overflow-x. */
  overflow-wrap: anywhere;
}
.article-body pre code { background: none; padding: 0; }
.article-body pre.mermaid { background: var(--bg-alt); text-align: center; }
.mermaid-fallback-note { color: var(--fg-muted); font-size: 0.85rem; margin: 0.4rem 0; }

/* Namuwiki "인용" look: a colored left rule + a light tinted background,
   instead of the plainer gray-only blockquote treatment. */
.article-body blockquote {
  border-left: 4px solid var(--accent);
  background: var(--accent-soft);
  border-radius: 0 4px 4px 0;
  margin: 1rem 0;
  padding: 0.5rem 1rem;
  color: var(--fg);
}

.wikilink-red, a.wikilink-red:visited { color: var(--red-link) !important; }
.wikilink-red { cursor: default; }

.ext-icon { font-size: 0.75em; margin-left: 0.15em; }

/* KaTeX renders directly INTO this element (app.js: `katex.render(text,
   el, ...)` -- `.katex`/`.katex-html`/`.katex-mathml` all end up as
   CHILDREN of `.math-tex` itself), so this is the right place to bound a
   too-wide formula, same treatment as `.article-body pre` already gets
   for wide code: `overflow-x: auto` makes `.math-tex` its own scroll
   container so an overlong expression scrolls horizontally within its
   own box instead of pushing the whole page wider (found during a
   390px-viewport sweep of the real vault: a handful of pages had a
   `$..$` span whose rendered KaTeX output was visibly wider than the
   viewport -- unlike `.article-body pre`/`code`, inline math text isn't
   `overflow-wrap`-able at all, it has to be either re-flowed by KaTeX
   itself or, as here, made scrollable). `max-width: 100%` keeps it from
   ever being wider than its container even before that scroll kicks in. */
.math-tex { display: inline-block; max-width: 100%; overflow-x: auto; vertical-align: middle; }
span.math-tex[data-display="true"] { display: block; text-align: center; margin: 0.8rem 0; }

/* Footnotes: superscript ref in link color; the python-markdown 'footnotes'
   extension's own generated list (div.footnote > ol > li) gets a top
   separator, Namuwiki-tooltip-style. */
sup.footnote-ref { cursor: pointer; }
sup.footnote-ref a { color: var(--link); font-weight: 700; }
.footnote-popover {
  position: absolute;
  max-width: 22rem;
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 0.6rem 0.8rem;
  font-size: 0.86rem;
}
.footnote-popover[hidden] { display: none; }
.article-body div.footnote {
  margin-top: 1.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border-strong);
  font-size: 0.86rem;
  color: var(--fg-muted);
}

/* ---------------------------------------------------------------- lists */
.plain-list { list-style: none; margin: 0; padding: 0; }
.plain-list li {
  padding: 0.4rem 0.1rem;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}
.plain-list li:hover { background: var(--bg-alt); }
.recent-date { color: var(--fg-muted); font-size: 0.82rem; white-space: nowrap; }

/* Namuwiki-like 문서/수정 시각 table look for the 최근 변경 page -- the DOM
   stays a plain <ul>/<li> (app.js already renders list items with the
   title on the left and the date right-aligned; see
   wiki_site.pages.recent_static_html / app.js's listItemHtml), a static
   two-column header row above it plus bordered/shaded rows makes it read
   as a table without changing how the payload is rendered. */
.namu-table-head {
  display: flex;
  justify-content: space-between;
  background: var(--bg-alt);
  border: 1px solid var(--border-strong);
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  padding: 0.5rem 0.7rem;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--fg-muted);
}
.namu-table-body { border: 1px solid var(--border-strong); border-radius: 0 0 6px 6px; overflow: hidden; }
.namu-table-body li { margin: 0; border-radius: 0; padding: 0.5rem 0.7rem; }
.namu-table-body li:last-child { border-bottom: none; }

/* ---------------------------------------------------------------- front page */
.front-banner {
  background: var(--accent-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1.1rem 1.3rem;
  margin-bottom: 1.25rem;
  text-align: center;
}
.front-banner-logo { font-size: 1.15rem; font-weight: 700; margin: 0 0 0.35rem; }
.front-banner-logo .logo-a { color: var(--accent); }
.front-banner-logo .logo-b { color: var(--fg); }
.front-intro { color: var(--fg-muted); margin: 0 0 0.7rem; }
.front-random-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  background: var(--accent-fill);
  color: #fff !important;
  font-size: 0.88rem;
  font-weight: 600;
}
.front-random-btn:hover { background: var(--accent-fill-hover); text-decoration: none; }

.front-columns { display: flex; gap: 1.25rem; flex-wrap: wrap; }
.front-col {
  flex: 1 1 18rem;
  min-width: 0;
  margin: 0;
  padding: 1rem 1.1rem 1.1rem;
}
.front-col h2 { margin-top: 0; font-size: 1.05rem; }

/* ---------------------------------------------------------------- category page */
.category-chip-list { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.category-chip-list li {
  display: inline-flex;
  border: none;
  padding: 0;
  width: auto;
}
.category-chip-list li a {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.3rem 0.8rem;
  font-size: 0.85rem;
  color: var(--fg) !important;
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: keep-all;
}
.category-chip-list li a:hover { background: var(--accent-soft); border-color: var(--accent); text-decoration: none; }
.category-detail { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--border); }
#category-detail-title { font-size: 1.1rem; }

/* ---------------------------------------------------------------- search page */
.search-count { color: var(--fg-muted); font-size: 0.86rem; margin: 0 0 0.75rem; }
.search-hit-snippet { color: var(--fg-muted); font-size: 0.86rem; margin-top: 0.15rem; flex-basis: 100%; }
.search-hit-list li { display: block; overflow-wrap: anywhere; word-break: keep-all; }
.search-hit-list li > a:first-child { font-weight: 700; font-size: 1rem; }
mark { background: var(--mark-bg); color: inherit; border-radius: 2px; }

/* ---------------------------------------------------------------- lock screen */
body.locked .page-shell > main#app-root { display: none; }
.lock-screen {
  max-width: 22rem;
  margin: 3rem auto;
  padding: 1.75rem 1.5rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  box-shadow: var(--shadow);
  text-align: center;
}
.unlock-form .lock-logo { font-size: 1.4rem; font-weight: 800; margin: 0 0 0.3rem; }
.unlock-form .lock-logo .logo-a { color: var(--accent); }
.unlock-form .lock-logo .logo-b { color: var(--fg); }
.unlock-form .lock-note { color: var(--fg-muted); font-size: 0.85rem; margin: 0 0 0.9rem; }
.unlock-form p { color: var(--fg-muted); margin: 0 0 0.8rem; }
.unlock-form input[type="password"] {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 1rem;
  margin-bottom: 0.6rem;
  background: var(--bg);
  color: var(--fg);
}
.unlock-form button[type="submit"] {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: none;
  border-radius: 8px;
  background: var(--accent-fill);
  color: #fff;
  font-size: 1rem;
  cursor: pointer;
}
.unlock-form button[type="submit"]:hover { background: var(--accent-fill-hover); }
.unlock-error { color: var(--red-link); font-size: 0.85rem; margin-top: 0.6rem; }
.unlock-progress { color: var(--fg-muted); font-size: 0.85rem; margin-top: 0.6rem; }

/* ---------------------------------------------------------------- notice toast */
.notice-toast {
  position: fixed;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  max-width: min(28rem, 90vw);
  background: var(--fg);
  color: var(--bg);
  padding: 0.6rem 1rem;
  border-radius: 8px;
  font-size: 0.88rem;
  box-shadow: var(--shadow);
  z-index: 70;
}
.notice-toast-error { background: var(--red-link); color: #fff; }

/* ---------------------------------------------------------------- backlinks */
.backlinks-box { margin: 1.5rem 0 0.5rem; padding-top: 0.75rem; border-top: 1px solid var(--border); }
.backlinks-title { font-weight: 700; }

/* ------------------------------------------------------------- view banner */
/* 업무위키/나무위키 view toggle (see assets/app.js's showCrossViewBannerIfNeeded)
   -- shown at the top of an article that belongs to the OTHER view than
   the one currently selected (e.g. a direct/bookmarked link). Uses the
   same --accent-soft/--accent/--accent-fill tokens as the rest of the
   page chrome, so it already has a correct dark-mode variant with no
   extra @media block needed here (see the :root / prefers-color-scheme
   block near the top of this file). */
.view-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0 0 1rem;
  padding: 0.65rem 0.9rem;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 8px;
  color: var(--fg);
  font-size: 0.9rem;
}
.view-banner-switch {
  flex: none;
  border: none;
  border-radius: 6px;
  padding: 0.35rem 0.7rem;
  background: var(--accent-fill);
  color: #fff;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}
.view-banner-switch:hover { background: var(--accent-fill-hover); }

/* ---------------------------------------------------------------- responsive */
@media (max-width: 768px) {
  .wiki-section :is(h1, h2, h3, h4, h5, h6) { scroll-margin-top: 8rem; }
  .mobile-menu-toggle { display: inline-flex; align-items: center; justify-content: center; }
  .topnav {
    display: none;
    position: absolute;
    left: 0; right: 0; top: 100%;
    background: var(--accent-fill-hover);
    flex-direction: column;
    align-items: stretch;
    padding: 0.5rem 1rem;
    gap: 0;
  }
  .topnav.open { display: flex; }
  .topnav a { padding: 0.6rem 0.4rem; }
  .searchbox { order: 3; flex-basis: 100%; margin-left: 0; }
  .searchbox input[type="search"] { width: 100%; }
  .topbar-inner { flex-wrap: wrap; position: relative; }
  .view-banner { flex-wrap: wrap; }
  .page-shell { padding: 0 0 3rem; }
  .namu-card { border-radius: 0; border-left: none; border-right: none; padding: 1.1rem 1rem 1.5rem; max-width: 100%; }
  .page-title { font-size: 1.4rem; }
  .toc-box { max-width: 100%; }
  .front-columns { flex-direction: column; }
  .front-col { padding: 0.9rem 1rem; }
}
