/* Left rail + Hub panel — #nav-sidebar buttons, the dynamic module rail, the
   Nexus vault picker/switcher, Hub accordion sections and the Nest tree rows
   (indent guides, drag-drop feedback).

   Also holds the .brand-img content:url() logo. url() resolves
   against THIS FILE, not index.html, so every asset path here is
   '../../src/assets/brand/…': up out of electron/css/, up out of electron/, then
   into the shared src/assets/brand/. Any new asset reference anywhere in
   electron/css/ needs the same prefix. */
/* NAV */
#nav-sidebar{
	width:var(--nav); background:var(--surface);
	border-right:1px solid var(--border);
	display:flex; flex-direction:column;
	align-items:center; padding:6px 0; gap:10px;
	flex-shrink:0;
}
.nav-logo{font-size:calc(22px * var(--fsc,1));padding:6px 0 12px}
.nav-logo-btn{
	width:70%;aspect-ratio:1;height:auto;border:none;
	background:transparent;border-radius:var(--r);
	cursor:pointer;color:var(--t2);
	display:flex;align-items:center;justify-content:center;
	padding:0;margin-bottom:2px;
	transition:all var(--ease);-webkit-app-region:no-drag;
}
.nav-logo-btn:hover{color:var(--t1)}
.nav-logo-btn.is-return{color:var(--accent-text,var(--accent))}
.nav-logo-btn .brand-img{width:70%;height:70%}
.nav-logo-btn .icon{width:24px;height:24px}
/* Procress 26: one logo for every theme — the Color mark reads on light and dark alike. */
.brand-img{height:30px;width:30px;object-fit:contain;display:block;content:url('../../src/assets/brand/web/DraconDex_Color.webp')}
.nav-btn{
	position:relative;
	width:70%;aspect-ratio:1;height:auto;border:none;
	background:transparent; border-radius:var(--r);
	cursor:pointer; color:var(--t2);
	display:flex;align-items:center;justify-content:center;
	font-size:calc(17px * var(--fsc,1)); transition:all var(--ease);
	-webkit-app-region:no-drag;
}
.nav-btn:hover{color:var(--t1)}
.nav-btn .icon{width:20px;height:20px}
.nav-btn .kicon-img-icon{width:20px;height:20px;border-radius:50%;object-fit:cover}
.nav-btn:hover .icon{transform:scale(1.08)}
/* process2 part1 #1: finishes an earlier, unfinished pass of this same item
   (the bar existed but the background fill was never removed, and it sat on
   the wrong edge) — active state is now the left-side bar alone, no fill;
   the icon itself is tinted --accent so it still reads as "selected" even
   against a pinned module's own custom icon color. */
.nav-btn.active{color:var(--accent-text,var(--accent))}
.nav-btn.active::after{
	content:'';position:absolute;left:-5px;top:22%;bottom:22%;
	width:3px;border-radius:2px;background:var(--accent);
}
.nav-util{font-size:calc(15px * var(--fsc,1))}
/* Setting window → Workspace → Tool toggle (Plan part1 #Setting): user-
   hidden "quick buttons" (import/export/hashtag/colors). !important because
   these buttons also carry visibility classes like .nexus-only that toggle
   display:flex/none based on app state — this must win regardless. */
.nav-btn.tool-toggle-hidden{display:none!important}
/* Plan part2 #4 — brief highlight so a Tool-toggle flip is unmissable on the
   live nav button/status bar sitting behind the modeless Setting window. */
.tool-toggle-flash{outline:2px solid var(--accent);outline-offset:2px;transition:outline-color .6s ease}

/* NEST TREE FILTER (hub/sections.js, UX-LAYOUT §6.2) — replaces the old
   #search-bar. Label above the field, a visible border at rest, the accent
   at focus (§8). */
.nest-filter{display:flex;flex-direction:column;gap:3px;padding:6px 8px 4px}
.nest-filter-label{font-size:var(--fs-micro);color:var(--t2)}
.nest-filter input{
	width:100%;box-sizing:border-box;background:var(--raised);border:1px solid var(--border);
	border-radius:var(--r);color:var(--t1);padding:6px 10px;
	font-size:calc(var(--fs-body) * var(--fsc,1));outline:none;transition:border-color var(--ease);
}
.nest-filter input:focus{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.nest-filter-hit .nest-filter-path{margin-left:auto;font-size:var(--fs-micro);color:var(--t3-aa,var(--t2));overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:45%}
/* The Nest's one create button, split (UX-LAYOUT §6.2, E3). */
.split-btn{display:inline-flex;align-items:stretch;border-radius:var(--rs);overflow:hidden;margin-right:2px}
.split-btn .btn{border-radius:0;min-height:26px}
.split-btn .split-main{padding:0 8px;gap:4px}
.split-btn .split-more{padding:0 5px;border-left:1px solid color-mix(in srgb,var(--on-accent) 30%,transparent)}
.split-btn .icon{width:14px;height:14px}

/* NEXUS VAULT PICKER */
.nexus-vault-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.nexus-vault-head h4{display:flex;align-items:center;gap:8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Plan part1 #style2: scoped override — the base .ph rule below is shared
   by 40+ other panel headers app-wide, so the tightened padding/no-margin
   lives here instead of touching .ph itself. #left-panel-foot (the parent)
   also drops its own padding to 0 so the two don't double-stack. */
.ph.nexus-vault-head{padding:2px 12px;margin-bottom:0}
.nexus-vault-name{cursor:pointer;border-radius:var(--rs)}
.nexus-vault-name:hover{color:var(--accent-text,var(--accent))}
.nexus-vault-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;background:var(--accent);display:inline-block}

/* Workspace switcher — dropdown of every Nexus, opened above the vault-head
   name (hub.js's positionPopupNear flips it upward near the panel bottom) */
.nexus-switcher-popup{width:220px;max-height:300px;overflow-y:auto;padding:6px}
/* Last row of the dropdown (v4.6.0): the list stops at 3 recent vaults, and
   this is the way to the full list — the Welcome window. */
.nexus-switcher-popup .nexus-switcher-more{border-top:1px solid var(--border);margin-top:var(--sp-1);border-radius:0}
.nexus-switcher-popup .nexus-switcher-more:first-child{border-top:0;margin-top:0}

/* ═══ V3 MODULE SYSTEM — Nexus nest hub (progress.md Phases 1-3) ═══ */
.hub-toggle{
	width:26px;height:26px;border:none;border-radius:var(--rs);background:transparent;
	color:var(--t2);display:flex;align-items:center;justify-content:center;cursor:pointer;
	margin-left:2px;-webkit-app-region:no-drag;
}
.hub-toggle:hover{color:var(--t1)}
.hub-toggle .icon{width:16px;height:16px}
.hub-toggle.active{color:var(--t1);background:var(--raised)}

.module-rail-tool.rail-sep{width:28px;height:0;border-top:1px solid var(--border);margin:5px 0}
/* mdot anchors to this wrapper (not .nav-btn) so it stays glued to the icon
   itself once .nav-expanded turns the button into a wide icon+label row —
   otherwise the dot would drift to the far right edge of the button. Sized to
   the icon's own footprint (not 100% of the button) so a wide expanded row
   still leaves room for .nav-label to take the rest of the flex line. */
.mdot-anchor{position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.mdot{position:absolute;right:-3px;bottom:-3px;width:7px;height:7px;border-radius:50%;border:1.5px solid var(--surface)}

/* process 2 part1 #2 / process1 part4 #1: dragging #nav-sidebar-resize past
   NAV_LABEL_THRESHOLD (core/ui.js) adds .nav-expanded to #nav-sidebar — every
   .nav-btn (the dynamic v3 rail's .module-rail-item/.module-rail-tool items
   AND the legacy static buttons in index.html) switches from a centered icon
   square to a left-aligned icon+label row. .nav-logo-btn is a different
   class, so the logo itself is unaffected. */
.nav-label{display:none}
/* Process 6 part 1: padding used to be calc(var(--nav) * .07) 10px — the
   first value (top/bottom, the Y axis) scaled with the dragged rail WIDTH,
   so every button's height/margin ballooned as the user widened the rail
   even though only X was being dragged. Vertical padding is fixed now;
   only the button's own width (above, calc(100% - 12px)) still tracks
   --nav, so widening only ever grows buttons on the X axis. */
#nav-sidebar.nav-expanded .nav-btn{
	width:calc(100% - 12px);aspect-ratio:auto;justify-content:flex-start;
	gap:8px;padding:6px 10px;
}
#nav-sidebar.nav-expanded .nav-label{
	display:inline-block;flex:1;min-width:0;text-align:left;
	overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
	font-size:calc(var(--fs-body) * var(--fsc,1));
}

.acc-head{
	display:flex;align-items:center;gap:7px;padding:2px 10px;font-size:calc(var(--fs-meta) * var(--fsc,1));font-weight:700;
	letter-spacing:.06em;text-transform:uppercase;color:var(--t2);border-bottom:1px solid var(--border);
	cursor:pointer;
}
.acc-head:hover{color:var(--t1)}
.acc-head .chev{width:9px;height:9px;flex-shrink:0}
.acc-head .act{margin-left:auto;display:flex;gap:4px}
.acc-head .act .btn-i{width:22px;height:22px;padding:2px}
.acc-body{padding:2px 0 8px}
/* Each Hub section (Nest / Sage Hut / Import Dock) gets its own
   independently-scrolling content box instead of sharing one page-length
   scrollbar across all three (#left-panel-inner's own overflow-y:auto
   stays as a harmless fallback — #hub-body's height:100% keeps it from
   ever actually needing to scroll in normal use). Open sections' bodies
   share the remaining vertical space equally (flex:1 each) and scroll on
   their own; a collapsed section's body is display:none (inline style,
   buildAccSection) so it takes no flex space — only its header remains. */
#hub-body{display:flex;flex-direction:column;height:100%}
#hub-body .acc-head{flex-shrink:0}
#hub-body .acc-body{flex:1 1 0;overflow-y:auto;min-height:80px}
.acc-collapsed{border-bottom:1px solid var(--border)}

.li .kicon{display:flex;align-items:center;flex-shrink:0;-webkit-user-drag:none}
.li .kicon .icon{width:15px;height:15px;stroke-width:2.2}
.li .kicon .kicon-img-icon{width:15px;height:15px;border-radius:50%;object-fit:cover}
.module-head .kicon{display:inline-flex;align-items:center}
.module-head .kicon .icon{width:18px;height:18px;stroke-width:2.2}
.module-head .kicon .kicon-img-icon{width:18px;height:18px;border-radius:50%;object-fit:cover}
.li .kind{margin-left:auto;font-size:calc(var(--fs-meta) * var(--fsc,1));color:var(--t3-aa,var(--t2));border:1px solid var(--border);
	border-radius:var(--rs);padding:0 4px;letter-spacing:.03em;flex-shrink:0}
.li .kind-handle{color:var(--accentH);border-color:var(--accent);max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.li .kind-icon{display:inline-flex;align-items:center;justify-content:center;padding:2px}
.li .kind-icon .icon{width:10px;height:10px;stroke-width:2.2}
.li .name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.li.indent1{padding-left:22px}
.li.indent2{padding-left:34px}
.li.indent3{padding-left:46px}
.li.indent4{padding-left:58px}
.li.indent5{padding-left:70px}
/* Nest-tree child guide lines — one thin vertical rule per ancestor depth,
   painted on a ::after overlay (not .li's own background) so it survives
   :hover/.active/.drop-in, which all set the `background` shorthand and
   would otherwise wipe out a background-image drawn directly on .li. Only
   rows from buildNestRow (hub.js) ever carry an indentN class, so this
   never touches Sage Hut/Import Dock/other .li lists elsewhere. Each line
   traces down from its ANCESTOR's chevron center, not the current row's
   own (Plan part1 #hub4 — a v-th-line row's chevron sits one indent step
   past the ancestor it belongs to, so it must never draw a line under
   itself). .tree-chev/.tree-chev-spacer (both 9px) is the row's first flex
   child, flush against .li.indentN's own padding-left, so depth D's
   chevron center is padding-left(D) + 4.5 — base .li's own padding-left is
   10px (depth 0, no indent class), giving 14.5/30.5/46.5/62.5/78.5 for
   depths 0-4, one shallower than this row's own indentN. Every row at a
   given depth reserves that chevron/spacer box (Plan part1 #5), so this
   alignment holds for every row shape, not just ones that happen to show a
   real chevron glyph. */
.li[class*="indent"]::after{content:'';position:absolute;inset:0;pointer-events:none;background-repeat:no-repeat}
.li.indent1::after{background-image:linear-gradient(var(--border),var(--border));background-size:1px 100%;background-position:14.5px 0}
.li.indent2::after{background-image:linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border));background-size:1px 100%,1px 100%;background-position:14.5px 0,26.5px 0}
.li.indent3::after{background-image:linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border));background-size:1px 100%,1px 100%,1px 100%;background-position:14.5px 0,26.5px 0,38.5px 0}
.li.indent4::after{background-image:linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border));background-size:1px 100%,1px 100%,1px 100%,1px 100%;background-position:14.5px 0,26.5px 0,38.5px 0,50.5px 0}
.li.indent5::after{background-image:linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border)),linear-gradient(var(--border),var(--border));background-size:1px 100%,1px 100%,1px 100%,1px 100%,1px 100%;background-position:14.5px 0,26.5px 0,38.5px 0,50.5px 0,62.5px 0}
/* .icon.tree-chev (not bare .tree-chev): the generic .icon{width:1em;
   height:1em} rule further down this file has equal specificity and would
   otherwise win by source order, since every .tree-chev SVG also carries
   the .icon class — silently inflating the chevron past its intended 9px
   and breaking the guide-line/spacer alignment math above. Confirmed live
   (getBoundingClientRect) before this fix: a real chevron rendered ~4.5px
   wider than .tree-chev-spacer despite both being declared 9px. */
.icon.tree-chev{width:9px;height:9px;stroke-width:3;color:var(--t3-aa,var(--t2));flex-shrink:0}
.tree-chev-spacer{width:9px;height:9px;flex-shrink:0}
.li.sel{background:var(--raised);color:var(--t1)}
/* Nest-tree drag-drop feedback (Plan part1 #4) — top/bottom quarter of a
   row previews a sibling reorder there, the middle half previews nesting
   the dragged module as that row's child. */
.li.drop-before{box-shadow:inset 0 2px 0 0 var(--accent)}
.li.drop-after{box-shadow:inset 0 -2px 0 0 var(--accent)}
.li.drop-in{outline:1px dashed var(--accent);outline-offset:-2px;background:var(--hover)}
/* Plan part1 #hub5 — square corners for Hub list rows specifically. .li is a
   shared row primitive used in 30+ other files app-wide; scoping to
   #hub-body (the Nest tree/Sage Hut/Import Dock accordion container) keeps
   every other .li list elsewhere untouched. */
#hub-body .li{border-radius:0}


/* ── Activity Bar destinations (v5 Part 7, V5.md §11.9) ── */
.left-dest-head{display:flex;align-items:center;justify-content:space-between;gap:6px}
.left-dest-head .acts{display:inline-flex;gap:2px}
.left-dest-body{flex:1;min-height:0;overflow-y:auto;padding:6px 8px;display:flex;flex-direction:column;gap:4px}
.left-search-input{width:100%}
.left-search-res{display:flex;flex-direction:column;gap:2px}
.left-search-row b{color:var(--accent-text,var(--accent))}
.setting-db-io{display:flex;gap:8px;margin-bottom:14px}
.csv-preview{max-height:320px;overflow:auto;border:1px solid var(--border);border-radius:var(--rs,6px)}
.csv-preview table{border-collapse:collapse;font-size:calc(12px * var(--fsc,1));width:max-content;min-width:100%}
.csv-preview th,.csv-preview td{padding:4px 8px;border-bottom:1px solid var(--border);text-align:left;vertical-align:top;white-space:nowrap}
.csv-preview th select{margin-top:4px;font-size:calc(var(--fs-meta) * var(--fsc,1))}

/* ═══ Procress 18 part 1 + 16 B8 — the Nest sidebar head ═══════════════════
   ① Nexus switcher ② [+ New ▾] ③ filter ④ tree. Replaces the accordion head
   and the vault-name bar that sat at the bottom (#left-panel-foot). */
#hub-body > .nest-head{display:flex;align-items:center;gap:4px;padding:8px 8px 4px;flex-shrink:0}
.btn.nexus-switch{flex:1;min-width:0;display:flex;align-items:center;gap:8px;height:32px;padding:0 8px;
	border:1px solid transparent;border-radius:var(--r);background:transparent;color:var(--t1);cursor:pointer;
	font:600 calc(13.5px * var(--fsc,1)) inherit;text-align:left}
.btn.nexus-switch:hover{background:var(--hover)}
.btn.nexus-switch:focus-visible{outline:2px solid var(--accentH,var(--accent));outline-offset:1px}
.btn.nexus-switch .name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.btn.nexus-switch .icon{width:12px;height:12px;flex-shrink:0;color:var(--t3-aa,var(--t2))}
#hub-body > .nest-create{padding:0 8px 6px;flex-shrink:0}
#hub-body > .nest-create .split-btn{display:flex}
#hub-body > .nest-create .split-main{flex:1;justify-content:center}
/* Procress 20: the Nexus's folder is on a drive that is not connected */
#hub-body > .nest-locate-warn{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 8px 6px;padding:6px 8px;border:1px solid var(--border);border-left:3px solid var(--warn);border-radius:var(--rs);background:var(--raised);color:var(--t2);font-size:calc(var(--fs-meta) * var(--fsc,1));line-height:1.4;flex-shrink:0}
#hub-body > .nest-locate-warn span{flex:1;min-width:120px}
#hub-body > .nest-filter{flex-shrink:0}
.nest-filter-box{position:relative;display:flex;align-items:center}
.nest-filter-box input{flex:1;padding-right:28px}
.nest-filter-box input::-webkit-search-cancel-button{display:none}
.nest-filter-clear,.nest-filter-kbd{position:absolute;right:4px}
.nest-filter-kbd{font:calc(11px * var(--fsc,1)) var(--mono,ui-monospace,monospace);color:var(--t3-aa,var(--t2));
	border:1px solid var(--border);border-radius:var(--rs);padding:0 5px;pointer-events:none}
/* Procress 18 part 1: rail buttons — ≥ 36 px to hit, and the open one shows a
   fill AND the side bar, not colour alone. */
#nav-sidebar .nav-btn{min-width:36px;min-height:36px}
.nav-btn.active{background:var(--raised)}
.nav-btn:focus-visible{outline:2px solid var(--accentH,var(--accent));outline-offset:1px}
/* Procress 16 B7: where dropped files will land */
#left-panel-inner .file-drop-target{outline:2px dashed var(--accent);outline-offset:-2px;border-radius:var(--r)}
/* Procress 16 part 2: picture thumbnails in the Nest */
.nest-thumb{width:16px;height:16px;object-fit:cover;border-radius:var(--rs);display:block}
/* Procress 18 part 2 — Nest rows: 12 px per level (was 16, guides moved with
   it), ⋯ at the end on hover / keyboard focus, a count badge, a grab cursor */
/* Procress 21 (UX-LAYOUT §12.2): the tree is a compact list — every row,
   module, element or file, is --row-compact tall, at any UI Size. */
#nest-tree-body .li{cursor:grab;min-height:var(--row-compact);padding-top:0;padding-bottom:0}
#nest-tree-body .li:active{cursor:grabbing}
#nest-tree-body .li:focus-visible{outline:2px solid var(--accentH,var(--accent));outline-offset:-2px}
.li .nest-row-more{visibility:hidden;width:22px;height:22px;margin-left:2px;flex-shrink:0}
.li:hover .nest-row-more,.li:focus-within .nest-row-more,.li:focus .nest-row-more{visibility:visible}
.li .nest-count{margin-left:auto;font-size:calc(var(--fs-meta) * var(--fsc,1));color:var(--t3-aa,var(--t2))}
.li .nest-count + .kind{margin-left:6px}
#nav-sidebar .qa-btn .icon{opacity:.85} /* Procress 16 part 7: a Quick Access button (one of yours) */
/* Setting hover preview (core/settings.js): a ring at the cursor fills over
   SETTING_PREVIEW_DELAY_MS, then the hovered theme/language previews. Lives
   on <html>, outside body's theme vars — color is set inline from --accent. */
#preview-ring{position:fixed;left:0;top:0;width:20px;height:20px;margin:14px 0 0 10px;pointer-events:none;z-index:var(--z-max);opacity:0;transition:opacity .12s}
#preview-ring.on{opacity:1}
#preview-ring svg{display:block;width:100%;height:100%;transform:rotate(-90deg)}
#preview-ring circle{fill:none;stroke:currentColor;stroke-width:3}
#preview-ring circle:first-child{opacity:.25}
#preview-ring .pr-fill{stroke-dasharray:100;stroke-dashoffset:100;stroke-linecap:round}
#preview-ring.on .pr-fill{animation:pr-fill var(--pr-dur,3s) linear forwards}
@keyframes pr-fill{to{stroke-dashoffset:0}}
