/* app.css — KB Curation SPA styling.
 *
 * Translated from the Claude Design "KB Curation" mock (template.html): the mock's global
 * <style> block verbatim + the self-hosted IBM Plex @font-face declarations (woff2 baked
 * into static/fonts/, NO CDN — in-VPC/no-egress posture) + the style-hover="..." attributes
 * from the DSL turned into real CSS :hover rules (class-based). Inline element styles from
 * the mock are preserved in the JS render (app.js), so this file carries only the font faces,
 * the shared global rules, and the hover states.
 */

/* ===== IBM Plex Sans (self-hosted; latin + latin-ext + vietnamese subsets) ============= */
/* Weights 400/500/600/700 share one file per subset (as in the source mock). */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/plex-sans-vietnamese.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/plex-sans-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/plex-sans-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===== IBM Plex Mono (self-hosted; per-weight files) =================================== */
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/plex-mono-400-vietnamese.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/plex-mono-400-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/plex-mono-400-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/plex-mono-500-vietnamese.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/plex-mono-500-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/plex-mono-500-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/plex-mono-600-vietnamese.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/plex-mono-600-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/plex-mono-600-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===== global (verbatim from the mock's <style>) ====================================== */
*{box-sizing:border-box}
html,body{margin:0}
body{background:#eef1f6;font-family:Arial,'Helvetica Neue',Helvetica,system-ui,-apple-system,sans-serif;color:#14171f;font-size:13.5px;line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:#2f6bed;text-decoration:none}
a:hover{color:#1f52c9}
::selection{background:#ffe27a;color:#3a2d00}
button{font-family:inherit}
kbd{font-family:'IBM Plex Mono',ui-monospace,Menlo,monospace}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-thumb{background:#cdd5e0;border-radius:9px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:#b4bfcd;background-clip:content-box}
.navwrap ::-webkit-scrollbar{height:0}
.navrow{display:flex;align-items:center;gap:10px;padding:0 18px;overflow-x:auto;scrollbar-width:none}
.navrow::-webkit-scrollbar{display:none}
.appbody{display:grid;grid-template-columns:308px minmax(0,1fr);min-height:0;min-width:0;overflow:hidden}
.review{display:grid;grid-template-columns:minmax(0,1.04fr) minmax(0,0.96fr);min-height:0;min-width:0;overflow:hidden}
.review>.pane{overflow:auto;min-height:0;min-width:0;overflow-wrap:anywhere}
details>summary{list-style:none}
details>summary::-webkit-details-marker{display:none}
details>summary::marker{content:""}
@media (max-width:1300px){.appbody{grid-template-columns:286px minmax(0,1fr)}}
@media (max-width:880px){.pipeline{display:none!important}}
@media (max-width:1120px){.review{grid-template-columns:1fr;overflow:auto}.review>.pane{overflow:visible;min-height:auto}}
@media (max-width:760px){.appbody{grid-template-columns:1fr}.appbody>.qcol{display:none}}

/* ===== hover states (the mock's style-hover="..." attributes, made real) ============== */
.hoverable-help:hover{background:rgba(255,255,255,.12) !important}
.hoverable-activity:hover{background:#f7f9fc !important}
.hoverable-cite:hover{background:#dfe9ff !important}
.hoverable-expand:hover{color:#1f52c9 !important}

/* app root fills the viewport (the mock's outer wrapper div) */
#app{height:100vh;display:grid;grid-template-rows:auto 1fr;overflow:hidden;min-width:0}

/* ===== micro-animations + hover polish (subtle, GPU-only, reduced-motion aware) — 2026-07-16 ===
   Entry animations are GATED in app.js (state.anim) so each plays ONCE on the render caused by the
   change, not on every full rebuild. Only opacity/transform (no layout thrash); ~120-240ms ease-out. */
@keyframes kb-reveal{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes kb-fade{from{opacity:0}to{opacity:1}}
@keyframes kb-pop{from{opacity:0;transform:scale(.98) translateY(-5px)}to{opacity:1;transform:none}}
@keyframes kb-row{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
.a-reveal{animation:kb-reveal .18s cubic-bezier(.2,.7,.3,1) both}
.a-fade{animation:kb-fade .18s ease-out both}
.a-pop{animation:kb-pop .14s cubic-bezier(.2,.7,.3,1) both;transform-origin:top left}
.a-row{animation:kb-row .24s ease-out both}
/* smooth hover/press feedback (#4/#5) — intra-element, safe with the rebuild render. Inline styles
   set the base background, so hover overrides need !important (same pattern as .hoverable-*). */
.qrow{transition:background .13s ease,box-shadow .13s ease}
.qrow:hover{background:#f6f9fe !important}
.seg-btn{transition:background .12s ease,color .12s ease,box-shadow .12s ease}
.seg-btn:hover{background:rgba(16,24,40,.045) !important}
.conn-btn{transition:background .13s ease,border-color .13s ease,color .13s ease}
.conn-btn:hover{background:rgba(255,255,255,.08) !important}
.hoverable-help,.hoverable-activity,.hoverable-cite,.hoverable-expand,.hoverable-copyicon,.hoverable-openlink{transition:background .13s ease,color .13s ease}
/* thread-header controls (icon-only Copy + subtle Open-in-<connector> link) */
.hoverable-copyicon:hover{background:rgba(16,24,40,.07) !important;color:#2b3240 !important}
.hoverable-openlink:hover{color:#173fa0 !important;text-decoration:underline}
.act-btn{transition:filter .12s ease,transform .07s ease}
.act-btn:hover{filter:brightness(1.04)}
.act-btn:active{transform:translateY(1px)}
/* keyboard focus — visible ring on every control. This tool is keyboard-driven (J/K/A/E/R) and
   had NO focus indicator; :focus-visible shows it for keyboard nav but not on mouse click. */
:focus-visible{outline:2px solid #2f6bed;outline-offset:2px}
.navwrap :focus-visible{outline-color:#8fb4ff}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:1ms !important;animation-delay:0ms !important;transition-duration:1ms !important;scroll-behavior:auto !important}
}
