/* ========================== DESIGN TOKENS ==========================
   Adopted verbatim from the `project-website` house template, with three
   measured contrast repairs noted inline. Change values here; do not
   hardcode a colour anywhere below. */
:root{
  --black:#000000; --bg:#000000; --bg-subtle:#0a0a0a;
  --surface:#0e0e0e; --surface-2:#141414; --surface-3:#1a1a1a;
  --border:#1f1f1f; --border-strong:#2e2e2e; --border-hover:#3a3a3a;
  --fg:#ededed; --fg-bright:#ffffff;
  /* REPAIR (dark dim ramp). The template ships --fg-muted:#a1a1a1,
     --fg-dim:#7d7d7d, --fg-faint:#565656 and documents in its own comment
     that --fg-faint fails AA (2.86:1 on --bg). #7d7d7d also lands at 4.23:1
     on --surface-3. The ramp is re-tiered, not re-invented: same three
     steps, each now >= 4.5:1 on --bg, --bg-subtle, --surface, --surface-2
     and --surface-3. Measured: 8.1 / 6.5 / 6.1 on --bg. */
  --fg-muted:#a8a8a8; --fg-dim:#949494; --fg-faint:#8a8a8a;
  --accent:#52a8ff; --accent-strong:#0072f5; --accent-contrast:#ffffff;
  --success:#46d160; --warn:#f5a623; --danger:#ff8080;
  --success-wash:rgba(70,209,96,.12);  --success-line:rgba(70,209,96,.32);
  --warn-wash:rgba(245,166,35,.12);    --warn-line:rgba(245,166,35,.30);
  --danger-wash:rgba(255,128,128,.12); --danger-line:rgba(255,128,128,.30);
  --accent-wash:rgba(82,168,255,.10);  --accent-line:rgba(82,168,255,.28);
  --title-grad:linear-gradient(180deg,#fff 30%,#b9b9b9);
  --title-grad-em:linear-gradient(180deg,#8ec5ff 18%,#4f9bf0);
  --glow:rgba(82,168,255,.14);
  /* The MonoMind mark is inlined with fill:currentColor, so it takes this
     one token. White on dark. (The source file monomind-mark.svg ships its
     own #0000FF — a pure blue that clashes with this palette; to go back to
     the raw brand file, change --brand-mark in the light block below.) */
  --brand-mark:#ffffff;
  /* Fallback ground for the sticky nav, used where color-mix() is not
     supported; the color-mix value on .nav overrides it. */
  --nav-bg:rgba(0,0,0,.70);
  --grid-line:rgba(255,255,255,.03);
  --r-sm:6px; --r-md:10px; --r-lg:14px; --r-xl:20px;
  --font-sans:"Geist","Noto Sans KR","Noto Sans TC",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --font-mono:"Geist Mono",ui-monospace,"SF Mono","Menlo","Consolas",monospace;
  --maxw:1120px; --maxw-prose:760px; --nav-h:60px;
  --ease:cubic-bezier(.22,1,.36,1);
  --shadow-pop:0 12px 32px rgba(0,0,0,.55);
  /* ---- SIGN-OFF BAND -------------------------------------------------
     Scrim numbers live here so the band is tuned in one place and the
     contrast audit can read exactly what is painted. --sc-rx/ry are the
     radial-gradient ellipse RADII as a fraction of the band's w/h.
     The photograph is dark (peak luminance .21 in the text zone), so on
     black it needs only a light touch under near-white type. */
  --sc-c:0,0,0;
  --sc-rx:.43; --sc-ry:.31;
  --sc-r0:.40; --sc-r1:.32; --sc-r2:.16;
  --sc-l0:.78;
  /* The band meets the footer, so its bottom fade lands on the footer's
     own ground rather than on --bg. Both stops carry the seam colour so
     the fade never interpolates through a muddy grey. */
  --seam-0:rgba(10,10,10,0); --seam-1:#0a0a0a;
  --band-ink:#ffffff;
  --band-shadow:0 1px 20px rgba(0,0,0,.55), 0 0 2px rgba(0,0,0,.40);
  color-scheme:dark;
}
/* ---------------------------- LIGHT THEME ---------------------------
   Only the palette changes; every rule below consumes the variables.
   The token values are re-pointed, not re-invented, so the contrast
   relationships of the dark palette survive the flip. */
html[data-theme="light"]{
  --bg:#ffffff; --bg-subtle:#f7f8fa;
  --surface:#f6f7f9; --surface-2:#eef0f4; --surface-3:#e6e9ee;
  --border:#e4e7ec; --border-strong:#d2d7df; --border-hover:#b9c0cb;
  --fg:#1b1f27; --fg-bright:#0b0d12; --fg-muted:#4e5563; --fg-dim:#5c6371;
  /* REPAIR (light --fg-faint). The template's #656c7a measures 4.34:1 on
     --surface-3, which the record panels use. #5f6675 keeps the tier and
     clears AA on every ground here: 5.8 white / 5.4 surface / 4.7 s3. */
  --fg-faint:#5f6675;
  --accent:#0064d2; --accent-strong:#0050a8;
  --success:#12662b; --warn:#8a5200; --danger:#c02626;
  /* REPAIR (light semantic hues). The template's #1a8f3c / #a86500 measure
     4.17 / 4.64 on white and drop below AA once they sit on their own 10%
     tint inside a status pill. Darkened; the hues are unchanged. Measured
     as rendered, on the composited pill ground: accepted 5.7, in-progress
     5.3. #157a33 was tried first and still landed at 4.43 — hence #12662b. */
  --success-wash:rgba(18,102,43,.10);  --success-line:rgba(18,102,43,.30);
  --warn-wash:rgba(138,82,0,.10);      --warn-line:rgba(138,82,0,.28);
  --danger-wash:rgba(192,38,38,.09);   --danger-line:rgba(192,38,38,.26);
  --accent-wash:rgba(0,100,210,.07);   --accent-line:rgba(0,100,210,.26);
  --title-grad:linear-gradient(180deg,#0b0d12 30%,#454b57);
  --title-grad-em:linear-gradient(180deg,#0064d2 18%,#00458f);
  --glow:rgba(0,100,210,.10);
  /* MonoMind mark in light mode: the template's accent-strong blue as it is
     carried in the base :root palette (#0072f5). Measured 4.44:1 on white —
     past the 3:1 that WCAG AA asks of a non-text graphic. The source file's
     own colour is #0000FF; reverting is this one line. */
  --brand-mark:#0072f5;
  --nav-bg:rgba(255,255,255,.82);
  --grid-line:rgba(0,0,0,.04);
  --shadow-pop:0 12px 32px rgba(11,13,18,.12);
  /* ---- SIGN-OFF BAND (light) ----------------------------------------
     On white the plate is lifted with a white wash and the ink flips to
     near-black. Keeping the photograph dark with white type was tried
     first and read as a hole punched in the page.

     The wash is set as light as the measurements allow. A heavier one
     (.62/.56/.44) cleared 8.2:1 but flattened the terracotta and teal into
     a pale haze — the photograph stopped reading as a photograph. These
     values keep the colour and still measure 5.4:1 at the tightest case,
     which is comfortably past the 4.5 target and well past the 3:1 that
     WCAG AA asks of large text. */
  --sc-c:255,255,255;
  --sc-rx:.45; --sc-ry:.33;
  --sc-r0:.48; --sc-r1:.42; --sc-r2:.30;
  --sc-l0:.92;
  --seam-0:rgba(247,248,250,0); --seam-1:#f7f8fa;
  --band-ink:#0b0d12;
  --band-shadow:0 1px 20px rgba(255,255,255,.75), 0 0 2px rgba(255,255,255,.55);
  color-scheme:light;
}
html[data-theme="light"] .btn-primary{background:#0b0d12;border-color:#0b0d12;color:#fff}
html[data-theme="light"] .btn-primary:hover{background:#2a2f3a;border-color:#2a2f3a}
html[data-theme="light"] ::selection{background:rgba(0,100,210,.22);color:#0b0d12}

*,*:before,*:after{box-sizing:border-box}
/* overflow-x:clip (not hidden) — `clip` does not create a scroll container,
   so the sticky nav keeps the viewport as its scrollport. It is here as
   well as on <body> because in RTL Chrome reports a phantom scrollWidth on
   <html> when only <body> is clipped. */
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--nav-h) + 24px);-webkit-text-size-adjust:100%;overflow-x:clip}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,*:before,*:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}}
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--font-sans);font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-feature-settings:"cv11","ss01";text-rendering:optimizeLegibility;overflow-x:hidden}
h1,h2,h3,h4{margin:0;font-weight:600;letter-spacing:-.02em;line-height:1.1;color:var(--fg-bright)}
p{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
img,svg{display:block;max-width:100%}
button{font-family:inherit;cursor:pointer;color:inherit}
input{font-family:inherit}
::selection{background:rgba(82,168,255,.28);color:#fff}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}

/* ---- Google Translate chrome suppression -------------------------------
   element.js injects a banner iframe and then pushes <body> down with an
   inline `top`. Both are killed here so the machine-translated page keeps
   the same layout as the hand-translated one. */
.skiptranslate,iframe.skiptranslate,.goog-te-banner-frame,#goog-gt-tt,.goog-te-balloon-frame{display:none!important}
body{top:0!important;position:static!important}
body>.skiptranslate{display:none!important}
.goog-text-highlight{background:none!important;box-shadow:none!important}
#googleTranslateHost{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}

.container{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:24px}
@media(max-width:420px){.container{padding-inline:16px}}
/* Anchor clearance under the sticky header is owned by ONE declaration:
   scroll-padding-top on <html>, above. Measured: an in-page jump lands the
   target 84px down, clear of the 60px header. A scroll-margin-top of the
   same size on the targets was tried and removed — the two do not override
   each other, they add, and every anchor landed 168px down. */
.section{padding-block:clamp(56px,9vw,112px)}
.eyebrow{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-dim)}
.eyebrow-num{color:var(--fg-faint)}
.section-title{font-size:clamp(1.75rem,3.6vw,2.6rem);letter-spacing:-.03em}
.section-lede{margin-top:16px;max-width:620px;color:var(--fg-muted);font-size:clamp(1rem,1.6vw,1.125rem);line-height:1.6}
.hairline{border:0;height:1px;background:linear-gradient(to right,transparent,var(--border) 20%,var(--border) 80%,transparent);margin:0}
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* Logical inset, not `left`. A machine-translated RTL page flips the
   overflow side: `left:-999px` parks the link on the side RTL treats as
   scrollable, adding 999px of phantom horizontal scroll to the whole page. */
.skip-link{position:absolute;inset-inline-start:-999px;top:8px;z-index:200;background:var(--fg-bright);color:var(--bg);padding:8px 14px;border-radius:var(--r-sm);font-size:.85rem}
.skip-link:focus{inset-inline-start:12px}
code,kbd{font-family:var(--font-mono);font-size:.9em}
.grid-bg{position:absolute;inset:0;background-image:linear-gradient(to right,var(--grid-line) 1px,transparent 1px),linear-gradient(to bottom,var(--grid-line) 1px,transparent 1px);background-size:56px 56px;-webkit-mask-image:radial-gradient(ellipse 80% 60% at 50% 0%,#000 40%,transparent 100%);mask-image:radial-gradient(ellipse 80% 60% at 50% 0%,#000 40%,transparent 100%);pointer-events:none}

@media(prefers-reduced-motion:no-preference){
  .reveal{opacity:0;transform:translateY(14px);transition:opacity .6s var(--ease),transform .6s var(--ease)}
  .reveal.in{opacity:1;transform:none}
}

/* ============================= BUTTONS ============================= */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding-inline:20px;border-radius:var(--r-md);font-size:.94rem;font-weight:500;letter-spacing:-.01em;border:1px solid transparent;transition:transform .15s var(--ease),background .2s var(--ease),border-color .2s var(--ease),color .2s var(--ease);white-space:nowrap;max-width:100%}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--fg-bright);color:#000;border-color:var(--fg-bright)}
.btn-primary:hover{background:#d9d9d9;border-color:#d9d9d9}
.btn-secondary{background:transparent;color:var(--fg);border-color:var(--border-strong)}
.btn-secondary:hover{background:var(--surface-2);border-color:var(--border-hover);color:var(--fg-bright)}
.btn svg{width:16px;height:16px;flex:none}
.btn>span{overflow:hidden;text-overflow:ellipsis}

.card{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);transition:border-color .2s var(--ease),background .2s var(--ease)}
.card:hover{border-color:var(--border-hover)}
.chip{display:inline-flex;align-items:center;gap:6px;height:24px;padding-inline:9px;border-radius:999px;font-family:var(--font-mono);font-size:11.5px;letter-spacing:.01em;color:var(--fg-muted);background:var(--surface-2);border:1px solid var(--border);white-space:nowrap}
.chip-open{color:var(--accent);background:var(--accent-wash);border-color:var(--accent-line)}

/* ============================== NAV ==============================
   THE HEADER OVERLAP FIX. Production shipped a header whose wordmark
   wrapped into the language buttons. Three rules prevent that here and
   they are load-bearing:
     1. .nav-actions is `flex:none` + `margin-inline-start:auto`, so the
        control cluster never shrinks and never gets pushed off-edge.
     2. .brand is `min-width:0` and its name is nowrap + ellipsis, so the
        brand is the thing that gives way — it truncates, never wraps.
     3. Everything secondary (nav links, the brand's suffix tag) is hidden
        by media query well before the row runs out of room.
   Measured at 320px: brand 96 + gap 12 + theme 36 + lang 78 + burger 34
   + padding 32 = 288 of 320. */
/* Sticky header, matching html.monomind.one: a translucent wash of the
   page's own --bg, blurred, on the hairline token. The plain rgba() line
   is the fallback for engines without color-mix(); the line after it wins
   everywhere else, and both flip with the theme. */
.nav{position:sticky;top:0;z-index:50;background:var(--nav-bg);background:color-mix(in srgb,var(--bg) 72%,transparent);backdrop-filter:saturate(160%) blur(14px);-webkit-backdrop-filter:saturate(160%) blur(14px);border-bottom:1px solid var(--border)}
.nav-inner{display:flex;align-items:center;gap:16px;height:var(--nav-h)}
.brand{display:inline-flex;align-items:center;gap:9px;min-width:0;flex:0 1 auto}
/* The mark and the wordmark are one link; the tag beside them is not, so it
   sits outside the anchor. .brand-link keeps min-width:0 so the truncation
   chain from .brand down to .brand-name is unbroken. */
.brand-link{display:inline-flex;align-items:center;gap:9px;min-width:0;font-weight:600;letter-spacing:-.02em;font-size:.98rem;color:var(--fg-bright)}
.brand-link:hover .brand-name{color:var(--fg-bright)}
.brand-mark{color:var(--brand-mark);display:inline-flex;flex:none}
.brand-mark svg{width:26px;height:26px}
.brand-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.brand-tag{flex:none;font-family:var(--font-mono);font-size:11px;font-weight:400;letter-spacing:0;color:var(--fg-dim);padding:2px 7px;border:1px solid var(--border);border-radius:999px;white-space:nowrap}
.nav-links{display:flex;gap:2px;margin-inline-start:6px;min-width:0}
.nav-link{padding:7px 11px;font-size:.9rem;color:var(--fg-muted);border-radius:var(--r-sm);white-space:nowrap;transition:color .15s,background .15s}
.nav-link:hover{color:var(--fg-bright);background:var(--surface-2)}
.nav-actions{display:flex;align-items:center;gap:8px;margin-inline-start:auto;flex:none}
.iconbtn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:var(--r-md);background:transparent;border:1px solid var(--border-strong);color:var(--fg-dim);transition:color .15s,background .15s,border-color .15s}
.iconbtn:hover{color:var(--fg-bright);background:var(--surface-2);border-color:var(--border-hover)}
.iconbtn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.i-moon{display:none}
html[data-theme="light"] .i-sun{display:none}
html[data-theme="light"] .i-moon{display:block}
.nav-toggle{display:none;flex-direction:column;justify-content:center;gap:5px;width:36px;height:36px;background:transparent;border:1px solid var(--border-strong);border-radius:var(--r-md);padding:0;align-items:center}
.nav-toggle span{width:16px;height:1.5px;background:var(--fg);transition:transform .2s,opacity .2s}
.nav-toggle[aria-expanded="true"] span:first-child{transform:translateY(3.25px) rotate(45deg)}
.nav-toggle[aria-expanded="true"] span:last-child{transform:translateY(-3.25px) rotate(-45deg)}
.nav-mobile{display:none;flex-direction:column;padding:6px 24px 14px;border-bottom:1px solid var(--border);background:var(--bg)}
.nav-mobile.open{display:flex}
.nav-mobile a{padding:12px 4px;color:var(--fg-muted);border-bottom:1px solid var(--border);font-size:.98rem}
.nav-mobile a:last-child{border-bottom:0}
.nav-mobile a:hover{color:var(--fg-bright)}
@media(max-width:900px){.nav-links{display:none}.nav-toggle{display:inline-flex}}
@media(max-width:560px){.brand-tag{display:none}}
@media(max-width:400px){.nav-inner{gap:10px}.nav-actions{gap:6px}}

/* ---------------------------- LANGUAGE ---------------------------- */
.langwrap{position:relative;flex:none}
.langbtn{display:inline-flex;align-items:center;gap:6px;height:36px;padding-inline:10px;border-radius:var(--r-md);background:transparent;border:1px solid var(--border-strong);color:var(--fg-dim);font-family:var(--font-mono);font-size:.76rem;letter-spacing:.02em;white-space:nowrap;transition:color .15s,background .15s,border-color .15s}
.langbtn:hover,.langwrap.open .langbtn{color:var(--fg-bright);background:var(--surface-2);border-color:var(--border-hover)}
.langbtn svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.5;flex:none}
.langbtn .caret{width:5px;height:5px;border-right:1.2px solid currentColor;border-bottom:1.2px solid currentColor;transform:translateY(-2px) rotate(45deg);flex:none}
.langpanel{position:absolute;top:calc(100% + 8px);inset-inline-end:0;z-index:150;width:min(304px,calc(100vw - 24px));display:flex;flex-direction:column;background:var(--surface-2);border:1px solid var(--border-strong);border-radius:var(--r-lg);box-shadow:var(--shadow-pop);overflow:hidden}
.langpanel[hidden]{display:none}
.langsearch{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--border)}
.langsearch svg{width:15px;height:15px;fill:none;stroke:var(--fg-dim);stroke-width:1.6;flex:none}
.langsearch input{flex:1;min-width:0;background:transparent;border:0;outline:none;color:var(--fg-bright);font-size:.88rem;padding:2px 0}
.langsearch input::placeholder{color:var(--fg-faint)}
.langsearch input:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
/* position:relative makes .langlist the offsetParent of every option, so
   the scroll-into-view maths in setActive() measures against the list it
   is scrolling — otherwise the search bar's height is counted in and the
   panel opens already scrolled past its first group header. */
.langlist{position:relative;max-height:min(58vh,364px);overflow-y:auto;overscroll-behavior:contain;padding:6px}
.langgroup+.langgroup{margin-top:6px;padding-top:8px;border-top:1px solid var(--border)}
.langgroup[hidden]{display:none}
.langgrouphd{padding:6px 10px 2px;font-family:var(--font-mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--fg-faint)}
.langopt{display:flex;align-items:baseline;gap:8px;padding:8px 10px;border-radius:var(--r-sm);cursor:pointer;color:var(--fg-muted);font-size:.88rem;transition:color .12s,background .12s}
.langopt[hidden]{display:none}
.langopt .lo-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.langopt .lo-native{color:var(--fg-dim);font-size:.8rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.langopt .lo-code{margin-inline-start:auto;font-family:var(--font-mono);font-size:10.5px;color:var(--fg-faint);flex:none}
.langopt.active{background:var(--surface-3);color:var(--fg-bright)}
.langopt[aria-selected="true"]{color:var(--fg-bright)}
.langopt[aria-selected="true"] .lo-name:after{content:"\00a0\2713";color:var(--accent)}
.langempty{padding:14px 10px;text-align:center;color:var(--fg-faint);font-family:var(--font-mono);font-size:.9rem}
.langempty[hidden]{display:none}

/* ============================ COMMAND ============================
   min-width:0 on the flex chain is what lets .cmd-text's own overflow-x
   work. A flex item defaults to min-width:auto, so a long nowrap command
   refuses to shrink and widens its column instead of scrolling inside
   itself — which at 320px pushes the whole page sideways. */
.cmd{display:flex;flex-direction:column;gap:8px;width:100%;max-width:100%;min-width:0}
.cmd-head{display:flex;align-items:center;justify-content:space-between;gap:10px;min-width:0}
.cmd-label{font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--fg-faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmd-hint{flex:none;font-family:var(--font-mono);font-size:10.5px;letter-spacing:.04em;color:var(--fg-dim);border:1px solid var(--border);background:var(--surface-2);border-radius:999px;padding:2px 8px;white-space:nowrap}
.cmd-hint[hidden]{display:none}
.cmd-body{display:flex;align-items:center;gap:10px;min-width:0;background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-md);padding-inline:14px 8px;font-family:var(--font-mono);transition:border-color .2s var(--ease);overflow:hidden}
.cmd-body:hover{border-color:var(--border-hover)}
.cmd-prompt{color:var(--accent);user-select:none;flex:none;font-size:.9rem}
.cmd-text{color:var(--fg);white-space:nowrap;overflow-x:auto;scrollbar-width:thin;flex:1;min-width:0;padding-block:14px;text-align:start;font-size:.84rem}
.cmd-text::-webkit-scrollbar{height:5px}
.cmd-text::-webkit-scrollbar-thumb{background:var(--border-hover);border-radius:99px}
.cmd-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--r-sm);background:transparent;border:1px solid transparent;color:var(--fg-dim);transition:color .15s,background .15s,border-color .15s}
.cmd-btn:hover{color:var(--fg-bright);background:var(--surface-3);border-color:var(--border)}
.cmd-btn svg{width:15px;height:15px;fill:none;stroke:currentColor}
.i-check{display:none;color:var(--success)}
.cmd-btn.copied .i-copy{display:none}
.cmd-btn.copied .i-check{display:block}
.cmd-sm .cmd-body{padding-inline:12px 6px;font-size:.78rem}
.cmd-sm .cmd-text{padding-block:11px;font-size:.78rem}
/* The prompt card holds a comment, not a command: nothing to copy and
   nothing to scroll, so it wraps instead of clipping mid-word. */
.cmd-note .cmd-body{align-items:flex-start}
.cmd-note .cmd-text{white-space:normal;overflow-x:visible;line-height:1.55}
.cmd-note .cmd-prompt{padding-block:11px}
.t-cmd{color:var(--fg-bright)}
.t-sub{color:var(--fg-bright)}
.t-flag{color:var(--accent)}
.t-url{color:var(--fg-muted)}
.t-arg{color:var(--fg)}
.t-comment{color:var(--fg-faint)}

/* ============================== DOCTOR ============================== */
.checks{counter-reset:chk;display:flex;flex-direction:column;gap:14px;max-width:var(--maxw-prose)}
.check{counter-increment:chk;position:relative;padding:18px 20px 18px 62px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);transition:border-color .2s var(--ease)}
.check:hover{border-color:var(--border-hover)}
.check:before{content:counter(chk,decimal-leading-zero);position:absolute;inset-inline-start:20px;top:19px;font-family:var(--font-mono);font-size:.8rem;color:var(--accent)}
.check h3,.check h4{font-size:1rem;letter-spacing:-.01em}
.check p{margin-top:7px;color:var(--fg-muted);font-size:.92rem;line-height:1.65}
.check code{border-radius:5px;padding:1px 7px;border:1px solid var(--border);background:var(--surface-2);color:var(--accent);white-space:nowrap}
.check p code.warn{color:var(--warn);background:var(--warn-wash);border-color:var(--warn-line)}
.check p code.err{color:var(--danger);background:var(--danger-wash);border-color:var(--danger-line)}
@media(max-width:420px){.check{padding:16px}.check:before{position:static;display:block;margin-bottom:8px}}

/* Comparison table. Same reflow contract as the record panels' .mdtable:
   the header row is taken out of the flow below 760px and each cell grows
   its own label from data-label, so a row becomes a small stacked card. */
.cmp-wrap{margin-top:26px;border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);overflow:hidden}
.cmp{width:100%;border-collapse:collapse;font-size:.92rem}
.cmp th{text-align:start;font-family:var(--font-mono);font-size:10.5px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--fg-faint);background:var(--bg-subtle);padding:13px 16px;border-bottom:1px solid var(--border);white-space:nowrap}
.cmp td{padding:16px;border-bottom:1px solid var(--border);vertical-align:top;color:var(--fg-muted);line-height:1.6}
.cmp tr:last-child td{border-bottom:0}
.cmp-name{font-family:var(--font-mono);font-size:.9rem;color:var(--fg-bright);white-space:nowrap}
@media(max-width:760px){
  .cmp,.cmp tbody,.cmp tr,.cmp td{display:block;width:100%}
  .cmp thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}
  .cmp tr{padding:14px 16px;border-bottom:1px solid var(--border)}
  .cmp tr:last-child{border-bottom:0}
  .cmp td{border-bottom:0;padding:7px 0}
  .cmp td:first-child{padding-top:0}
  .cmp td:before{content:attr(data-label);display:block;font-family:var(--font-mono);font-size:10px;letter-spacing:.07em;text-transform:uppercase;color:var(--fg-faint);margin-bottom:3px}
  .cmp td:first-child:before{display:none}
}
/* ============================== FOOTER ============================== */
.footer{border-top:1px solid var(--border);background:var(--bg-subtle);padding-block:52px 28px;margin-top:clamp(48px,8vw,96px)}
/* One column since the Links list was folded back into the brand block. */
.footer-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:40px;margin-bottom:36px}
.foot-brand{display:inline-flex;align-items:center;gap:10px;min-width:0;color:var(--fg-bright)}
.foot-brand .brand-mark svg{width:24px;height:24px}
.foot-name{font-size:1.02rem;font-weight:600;letter-spacing:-.02em;color:var(--fg-bright)}
.foot-desc{margin-top:10px;max-width:var(--maxw-prose);color:var(--fg-muted);font-size:.92rem;line-height:1.6}
.foot-desc b{font-weight:500;color:var(--fg)}
.foot-inline{margin-top:18px;display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 12px;font-size:.9rem;color:var(--fg-muted)}
.foot-inline a{color:var(--fg-muted);transition:color .15s;overflow-wrap:anywhere;min-width:0}
.foot-inline a:hover{color:var(--fg-bright)}
.foot-inline .sep{color:var(--fg-faint)}
/* The GitHub link is an icon, not text: centre it on the same baseline
   row as the adjacent text link. */
.foot-inline a svg{display:block}
.foot-inline a:has(svg){display:inline-flex;align-items:center;align-self:center}
/* align-self, not just align-items: .foot-inline aligns its children on the
   text baseline, and an icon-only inline-flex box has no text to derive one
   from, so it is aligned by its bottom edge and rides ~3px high. Centring it
   against the flex line instead puts it on the text's optical centre. */
.foot-caps{margin-top:16px;display:flex;flex-wrap:wrap;gap:7px}
.foot-caps li{font-family:var(--font-mono);font-size:11px;color:var(--fg-dim);border:1px solid var(--border);border-radius:999px;padding:4px 10px}
.license{margin-top:28px;padding-top:24px;border-top:1px solid var(--border);color:var(--fg-dim);font-size:.85rem;line-height:1.6}
.license b{color:var(--fg);font-weight:500}
.foot-bottom{margin-top:20px;color:var(--fg-faint);font-size:.8rem;font-family:var(--font-mono)}

@media print{
  .nav,.nav-mobile,.skip-link,.hero-glow,.grid-bg{display:none!important}
  .reveal{opacity:1!important;transform:none!important}
  .tabpanel[hidden]{display:block!important}
  body{background:#fff;color:#111}
  .hero-title{background:none;-webkit-text-fill-color:#111;color:#111}
}

/* Korean line-breaking. Latin text breaks at spaces, but the default
   `word-break:normal` lets Korean break between any two syllables, so a
   headline splits mid-word (철 지 / 난). `keep-all` forces breaks at the
   space-delimited eojeol boundary, which is how Korean is actually set.
   Not applied to Chinese: breaking between Han characters is correct there.
   overflow-wrap is the escape hatch for a single unbreakable token. */
html[lang="ko"]{word-break:keep-all;overflow-wrap:break-word}
/* ========================= SIGN-OFF BAND =========================
   Full-bleed closing band: the brand photograph, a theme-tuned scrim, and
   the tagline settling out of wide, blurred tracking.

   The photograph is the brand's own artwork, where a blurred field stands
   for work without context. The animation enacts the line rather than
   decorating it: the words start uncohered and draw together as the blur
   clears. Only transform, opacity and filter are animated. */
.sign-off{position:relative;height:60vh;min-height:400px;max-height:720px;
  overflow:hidden;isolation:isolate;display:grid;place-items:center}
/* inset:-6% keeps the image's own edges outside the band. One URL, one
   rule — the same cached file backs the band on every page. */
.sign-bg{position:absolute;inset:-6%;z-index:0;background-image:url(/clarity-bg.jpg);
  background-position:center;background-size:cover;transform:translateZ(0)}
.sign-scrim{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(180deg,
      rgba(var(--sc-c),var(--sc-l0)) 0%,
      var(--seam-0) 16%,
      var(--seam-0) 74%,
      var(--seam-1) 100%),
    radial-gradient(ellipse calc(var(--sc-rx) * 100%) calc(var(--sc-ry) * 100%) at 50% 50%,
      rgba(var(--sc-c),var(--sc-r0)) 0%,
      rgba(var(--sc-c),var(--sc-r1)) 60%,
      rgba(var(--sc-c),var(--sc-r2)) 100%)}
.sign-inner{position:relative;z-index:2;width:100%;max-width:var(--maxw);
  margin:0 auto;padding-inline:24px;text-align:center}
.sign-line{font-size:clamp(1.65rem,5.2vw,3.25rem);line-height:1.16;letter-spacing:-.028em;
  font-weight:600;color:var(--band-ink);text-shadow:var(--band-shadow);
  text-wrap:balance;margin:0}
/* Each word is a nowrap box, so the line breaks only where the script
   allows: at spaces for Latin and Korean, and between glyphs for Han,
   where the splitter emits one box per character. This is also what keeps
   html[lang="ko"]{word-break:keep-all} intact — the same guarantee, made
   structurally rather than by property. */
.sign-line .sw{display:inline-block;white-space:nowrap}
.sign-line .sg{display:inline-block;will-change:transform}
/* The resolved state is the DEFAULT state. Animation is additive and only
   ever runs under .run, so no-JS and reduced-motion both land on the
   finished frame with nothing to undo. */
@keyframes signoff-line{
  from{opacity:.14;filter:blur(12px)}
  70% {opacity:1}
  to  {opacity:1;filter:blur(0)}
}
@keyframes signoff-glyph{from{transform:translateX(var(--tx,0px))} to{transform:translateX(0)}}
.sign-off.run .sign-line{animation:signoff-line 1600ms var(--ease) both}
.sign-off.run .sg{animation:signoff-glyph 1600ms var(--ease) both}
/* Belt and braces over the global reduced-motion clamp above, which only
   compresses every animation to .001ms. This band's opening frame is a big
   one — faint, blurred, glyphs pushed wide — so it is removed outright
   rather than compressed to a sub-millisecond flash. */
@media(prefers-reduced-motion:reduce){
  .sign-off,.sign-off *,.sign-off.run,.sign-off.run *{animation:none!important}
}
/* The footer follows the band directly; its own top margin would open a
   gap in the middle of the seam. */
.sign-off + .footer{margin-top:0}
@media(max-width:360px){.sign-inner{padding-inline:18px}}
