/* Additive enhancement layer — loaded after style.css. Nothing here removes
 * or overrides base layout; it only adds new components and new states on
 * top of existing selectors. Motion is controlled only by the in-app pause
 * toggle (`body.motion-paused`, set from assets/graph.js's setPaused()), not
 * automatically by the OS-level prefers-reduced-motion setting — every
 * animation/transition below is paused only when that class is present. */

:root{--gold:#ffc857;--purple:#a463ff;--green:#8fda4a;--magenta:#ff5bc8;--cyan2:#1be7ff;--ease-premium:cubic-bezier(.2,.8,.2,1)}

/* ---------- Three.js ambient depth layer ---------- */
#threeCanvas{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;opacity:1;filter:brightness(1.25) saturate(1.22)}

/* ---------- Sidebar voice-status widget ---------- */
.voice-orb{margin-top:22px;padding:14px 12px;border:1px solid rgba(105,186,255,.22);border-radius:14px;background:linear-gradient(150deg,rgba(12,31,48,.55),rgba(4,14,24,.4));backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);display:flex;flex-direction:column;align-items:center;gap:10px;transition:box-shadow .4s var(--ease-premium),border-color .4s var(--ease-premium)}
.voice-orb-visual{position:relative;width:100%;height:22px;display:flex;align-items:center;justify-content:center}
.voice-orb-ring{position:absolute;inset:-8px 0;border-radius:10px;border:1px solid rgba(105,220,255,.16);pointer-events:none;overflow:hidden}
/* The Knight-Rider-style sweep formerly on this ring (:after, animation:
 * knightSweep) has been removed by request; the ring itself and the wave
 * bars below still carry the idle/listening/processing/speaking states. */
.voice-orb-wave{display:flex;align-items:center;gap:3px;height:20px}
.voice-orb-wave span{width:3px;border-radius:2px;background:linear-gradient(#8fe9ff,#4aa9ff);height:6px;animation:voiceIdle 2.6s ease-in-out infinite}
.voice-orb-wave span:nth-child(2){animation-delay:.15s}
.voice-orb-wave span:nth-child(3){animation-delay:.3s}
.voice-orb-wave span:nth-child(4){animation-delay:.45s}
.voice-orb-wave span:nth-child(5){animation-delay:.6s}
.voice-orb-label{font-size:8px;letter-spacing:2.4px;color:#8fc3de;transition:color .3s ease}
@keyframes voiceIdle{0%,100%{height:5px;opacity:.55}50%{height:11px;opacity:.9}}
@keyframes voiceListen{0%,100%{height:6px}50%{height:22px}}
@keyframes voiceSpeak{0%,100%{height:8px}25%{height:19px}50%{height:9px}75%{height:24px}}
@keyframes voiceThink{0%,100%{transform:translateY(0);opacity:.5}50%{transform:translateY(-6px);opacity:1}}
.voice-orb[data-state=listening]{border-color:rgba(85,247,214,.4);box-shadow:0 0 22px rgba(57,239,216,.16)}
.voice-orb[data-state=listening] .voice-orb-wave span{background:linear-gradient(#7bffe6,#22c9a8);animation:voiceListen 1s ease-in-out infinite}
.voice-orb[data-state=listening] .voice-orb-label{color:#7ff2df}
.voice-orb[data-state=processing]{border-color:rgba(180,140,255,.4);box-shadow:0 0 22px rgba(150,110,255,.14)}
.voice-orb[data-state=processing] .voice-orb-wave span{background:linear-gradient(#c9a8ff,#7a6bff);animation:voiceThink .9s ease-in-out infinite}
.voice-orb[data-state=processing] .voice-orb-label{color:#c6b3ff}
.voice-orb[data-state=speaking]{border-color:rgba(105,220,255,.5);box-shadow:0 0 26px rgba(90,200,255,.2)}
.voice-orb[data-state=speaking] .voice-orb-wave span{background:linear-gradient(#a9ecff,#5aa8ff);animation:voiceSpeak .7s ease-in-out infinite}
.voice-orb[data-state=speaking] .voice-orb-label{color:#bfeaff}
@media(max-width:1000px){.voice-orb{display:none}}

/* Voice state also reflects onto the always-visible mobile mic button */
body.ai-processing #micButton{border-color:#b48cff;box-shadow:0 0 20px rgba(150,110,255,.5);animation:micThink .9s ease-in-out infinite}
@keyframes micThink{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}

/* ---------- Optional context bar ---------- */
/* composer-area's own box is taller than its visible content (context bar +
   status + input + chips stack with gaps), and at common laptop viewport
   heights that empty box-space overlaps the graph-tools cluster above it.
   Make the section itself click-through and re-enable it on the actual
   interactive children, rather than fighting pixel-perfect positioning. */
.composer-area{pointer-events:none}
.composer-area>*{pointer-events:auto}
.context-bar{display:flex;align-items:center;gap:8px;margin:0 13px 10px;padding:6px 12px;border:1px solid rgba(120,210,255,.18);border-radius:20px;background:rgba(6,18,30,.55);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);font-size:8px;letter-spacing:1.6px;color:#8fb7cf;white-space:nowrap;overflow:hidden;max-width:100%;pointer-events:none}
.context-bar svg{width:11px;height:11px;flex-shrink:0;color:#69baff}
.context-bar>span{color:#5f88a0}
.context-bar strong{font-weight:600;color:#cdeeff;letter-spacing:.4px;overflow:hidden;text-overflow:ellipsis}
@media(max-width:720px){.context-bar{display:none}}

/* ---------- First-time hint ---------- */
.first-hint{position:absolute;left:50%;bottom:4%;transform:translateX(-50%);z-index:5;max-width:280px;padding:12px 16px;border:1px solid rgba(120,210,255,.25);border-radius:14px;background:linear-gradient(145deg,rgba(12,31,48,.85),rgba(4,14,24,.72));backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);text-align:center;box-shadow:0 18px 40px rgba(0,0,0,.35);animation:hintIn .6s var(--ease-premium);pointer-events:none}
.first-hint strong{display:block;font-size:11px;color:#e7f6ff;margin-bottom:4px}
.first-hint span{font-size:10px;color:#9fc0d4;line-height:1.5}
@keyframes hintIn{from{opacity:0;transform:translate(-50%,10px)}to{opacity:1;transform:translate(-50%,0)}}
@media(max-width:1000px){.first-hint{display:none}}

/* ---------- Node tooltip (colour-accented per constellation group) ---------- */
.node-tooltip{--accent:105,210,255;position:fixed;transform:translate(-50%,-100%);z-index:60;max-width:240px;padding:11px 14px;border:1px solid rgba(120,210,255,.22);border-top:2px solid rgba(var(--accent),.85);border-radius:10px;background:linear-gradient(145deg,rgba(10,26,40,.92),rgba(4,12,20,.88));backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 14px 34px rgba(0,0,0,.4),0 0 22px rgba(var(--accent),.16);pointer-events:none;transition:opacity .15s ease}
.node-tooltip strong{display:block;font-size:9px;letter-spacing:1.6px;color:rgb(var(--accent));margin-bottom:4px}
.node-tooltip span{font-size:11px;line-height:1.5;color:#d3e6f2}
.node-tooltip[hidden]{display:none}

/* ---------- Explorer side panel: futuristic slide/fade open + close ---------- */
dialog{transition:transform .58s cubic-bezier(.16,.84,.22,1),opacity .42s ease,filter .58s ease}
dialog.opening{transform:translateX(100%) perspective(900px) rotateY(-5deg) scale(.96);opacity:0;filter:blur(10px)}
@starting-style{ dialog[open]{transform:translateX(120px) perspective(900px) rotateY(-3deg) scale(.965);opacity:0;filter:blur(8px)} }
dialog.closing{transform:translateX(100%) perspective(900px) rotateY(-5deg) scale(.96);opacity:0;filter:blur(10px)}
dialog::backdrop{transition:background-color .32s ease,backdrop-filter .32s ease}
@starting-style{ dialog[open]::backdrop{background-color:transparent;backdrop-filter:blur(0px)} }
dialog{--panel-accent:105,220,255;overflow-x:hidden;overscroll-behavior:contain;contain:paint;border-left-color:rgba(var(--panel-accent),.8);background:linear-gradient(145deg,rgba(9,29,46,.67),rgba(2,10,19,.58));backdrop-filter:blur(24px) saturate(155%);-webkit-backdrop-filter:blur(24px) saturate(155%);box-shadow:-28px 0 90px #0008,-2px 0 34px rgba(var(--panel-accent),.34),inset 1px 0 rgba(255,255,255,.12)}
dialog[data-section=companies]{--panel-accent:78,164,255}dialog[data-section=skills]{--panel-accent:255,199,98}dialog[data-section=projects]{--panel-accent:57,235,227}dialog[data-section=achievements]{--panel-accent:190,111,255}dialog[data-section=connect]{--panel-accent:255,126,190}dialog[data-section=knowledge]{--panel-accent:46,217,255}dialog[data-section=evidence]{--panel-accent:186,234,107}dialog[data-section=flagship]{--panel-accent:58,221,239}dialog[data-section=briefing]{--panel-accent:222,198,136}
dialog:before{content:'';position:fixed;inset:0 auto 0 0;width:2px;background:linear-gradient(transparent,rgb(var(--panel-accent)),transparent);box-shadow:0 0 20px rgba(var(--panel-accent),.7);animation:panelEdge 3.2s ease-in-out infinite;pointer-events:none}
dialog:after{content:'';position:fixed;left:0;right:0;top:0;height:18%;background:linear-gradient(transparent,rgba(var(--panel-accent),.045),transparent);transform:translateY(-120%) skewY(-5deg);animation:panelScan 5s linear infinite;pointer-events:none}
dialog[open] #panelBody>*{animation:panelContentIn .42s var(--ease-premium) both}
dialog[open] #panelBody>*:nth-child(2){animation-delay:.04s}dialog[open] #panelBody>*:nth-child(3){animation-delay:.08s}dialog[open] #panelBody>*:nth-child(4){animation-delay:.12s}dialog[open] #panelBody>*:nth-child(5){animation-delay:.16s}
@keyframes panelContentIn{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}
@keyframes panelEdge{50%{filter:brightness(1.8);opacity:.7}}
@keyframes panelScan{to{transform:translateY(680%) skewY(-5deg)}}
.motion-paused dialog,.motion-paused dialog::backdrop{transition:none!important}

/* ---------- Career-twin core: listening breathing + per-word speaking pulse ---------- */
body.listening .core{opacity:1;animation:coreListen 1.6s ease-in-out infinite}
@keyframes coreListen{0%,100%{box-shadow:inset 0 0 21px #45beff9c,0 0 25px #29baff99,0 0 70px #764aef66}50%{box-shadow:inset 0 0 30px #55f7d6cc,0 0 40px #39efd8cc,0 0 85px #29baffaa}}
.core-pulse{animation:corePulseWord .3s var(--ease-premium)}
@keyframes corePulseWord{0%{filter:brightness(1)}35%{filter:brightness(1.35) saturate(1.15)}100%{filter:brightness(1)}}
.core-ripple{position:absolute;inset:-6px;border-radius:50%;border:1px solid rgba(120,220,255,.55);pointer-events:none;animation:coreRipple .75s ease-out forwards}
@keyframes coreRipple{from{transform:scale(.85);opacity:.8}to{transform:scale(1.4);opacity:0}}
.motion-paused .core-pulse,.motion-paused .core-ripple,body.motion-paused.listening .core{animation:none!important}
.avatar-hud{position:absolute;inset:0;pointer-events:none;z-index:4}
/* Moved 8 Sep 2026 to sit above the outer ring rather than inside it, overlapping the avatar
 * photo — now a direct child of .core (avatar-voice.js), not .core-inner, since .core-inner
 * clips to a circle and would have hidden anything positioned outside its own bounds. -40px
 * clears .core-ring.second's own -25px outward extension plus this pill's height and a gap. */
.avatar-state{position:absolute;top:auto;bottom:17%;left:50%;transform:translateX(-50%);z-index:6;pointer-events:none;display:flex;align-items:center;gap:7px;padding:5px 10px;border:1px solid #69dcff77;border-radius:20px;background:#03121df2;box-shadow:0 0 16px #31baff33;white-space:nowrap}
.avatar-state i{width:5px;height:5px;border-radius:50%;background:#73f6dc;box-shadow:0 0 8px #73f6dc}
.avatar-state b{font-size:8px;letter-spacing:1.35px;color:#d9f7ff;font-weight:700}
.avatar-mouth{position:absolute;left:50%;top:47.5%;transform:translate(-50%,-50%);display:flex;align-items:center;gap:2px;height:18px;padding:3px 5px;border-radius:10px;background:#03111bbb;box-shadow:0 0 10px #69dcff33}
.avatar-mouth i{display:block;width:2px;height:4px;border-radius:2px;background:#9ceaff;box-shadow:0 0 5px #59d9ff}
.avatar-scan{position:absolute;left:24%;right:24%;top:22%;height:1px;background:linear-gradient(90deg,transparent,#80edff,transparent);opacity:0}
.avatar-caption{position:absolute;left:50%;bottom:-41px;transform:translate(-50%,5px);width:max-content;max-width:220px;padding:5px 10px;border:1px solid #5acfff4d;border-radius:20px;background:#04131ee6;color:#c9f3ff;font-size:8px;letter-spacing:.8px;opacity:0;transition:opacity .2s,transform .2s;pointer-events:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.avatar-caption.visible{opacity:1;transform:translate(-50%,0)}

/* ---------- "Ask My Career Twin" sidebar button hover ---------- */
/* Bug found and fixed 8 Sep 2026: this button (unlike every .nav-item right above it, which
 * already has its own :hover state) had no hover feedback at all, despite already carrying a
 * glowing "important action" style at rest - clicking it felt like a dead spot until you did. */
.ask-twin{transition:box-shadow .25s var(--ease-premium),border-color .25s var(--ease-premium),transform .15s var(--ease-premium)}
.ask-twin:hover,.ask-twin:focus-visible{border-color:#a6b8ff;box-shadow:0 0 22px #5a8bff99,inset 0 -4px 16px #7a6bffb0;transform:translateY(-1px)}
.core[data-presence=listening] .avatar-mouth i{animation:avatarListen .72s ease-in-out infinite alternate}.core[data-presence=listening] .avatar-mouth i:nth-child(2n){animation-delay:-.31s}.core[data-presence=listening] .avatar-state{border-color:#73f6dc99;box-shadow:0 0 18px #39efd844}
.core[data-presence=processing] .avatar-scan{opacity:.9;animation:avatarScan 1.2s ease-in-out infinite}.core[data-presence=processing] .avatar-state i{background:#c7a7ff;box-shadow:0 0 8px #a579ff}
.core[data-presence=speaking] .avatar-mouth i{animation:avatarSpeak .25s ease-in-out infinite alternate}.core[data-presence=speaking] .avatar-mouth i:nth-child(2){animation-delay:-.08s}.core[data-presence=speaking] .avatar-mouth i:nth-child(4){animation-delay:-.16s}
.core.core-pulse .avatar-mouth{transform:translate(-50%,-50%) scaleY(calc(.75 + var(--speech-energy,.5)));filter:brightness(1.4)}
@keyframes avatarListen{to{height:13px}}@keyframes avatarSpeak{to{height:14px}}@keyframes avatarScan{50%{top:72%}}

/* ---------- Selected / hovered career node treatment ---------- */
.graph-node.is-selected .bubble{transform:scale(1.08);box-shadow:inset 0 0 24px rgba(var(--color),.85),0 0 16px rgba(var(--color),1),0 0 55px rgba(var(--color),.55)}
.graph-node.is-selected .bubble:before{border-color:rgba(var(--color),.55)}
.graph-node.is-selected strong{font-weight:750;text-shadow:0 2px 7px #000,0 0 20px rgba(var(--color),.65)}
.graph-stage[data-hover-group]:not([data-hover-group=""]) .graph-node{transition:opacity .25s ease}
.graph-stage[data-hover-group="experience"] .graph-node:not(.experience):not(.is-selected),
.graph-stage[data-hover-group="skills"] .graph-node:not(.skills):not(.is-selected),
.graph-stage[data-hover-group="projects"] .graph-node:not(.projects):not(.is-selected),
.graph-stage[data-hover-group="achievements"] .graph-node:not(.achievements):not(.is-selected),
.graph-stage[data-hover-group="connections"] .graph-node:not(.connections):not(.is-selected),
.graph-stage[data-hover-group="knowledge"] .graph-node:not(.knowledge):not(.is-selected),
.graph-stage[data-hover-group="evidence"] .graph-node:not(.evidence):not(.is-selected){opacity:.55}

/* ---------- Hover spotlight + subtle parallax inside the graph stage (desktop only) ---------- */
.graph-stage{--mx:50%;--my:50%;--px:0px;--py:0px}
.graph-stage:before{content:'';position:absolute;inset:0;pointer-events:none;z-index:1;background:radial-gradient(circle at var(--mx) var(--my),rgba(0,180,255,.07),transparent 38%);opacity:0;transition:opacity .3s ease}
.graph-stage:hover:before{opacity:1}
.graph-stage>canvas{transform:translate(var(--px),var(--py));transition:transform .1s linear}
.graph-node{transform:translate(calc(-50% + (var(--px,0px) * .5)),calc(-50% + (var(--py,0px) * .5)))}
/* Already covered by the .motion-paused rule further down (same selectors),
 * which is the only thing that pauses this now — see file header. */

/* ---------- Composer: focus glow + cosmetic processing ring ---------- */
.composer:focus-within{box-shadow:0 0 10px #56baff,0 0 34px rgba(35,131,251,.6),inset 0 0 16px rgba(39,131,202,.47)}
.composer{position:relative}
.composer:after{content:'';position:absolute;inset:-2px;border-radius:52px;padding:2px;background:conic-gradient(from 0deg,rgba(105,220,255,0) 0%,rgba(105,220,255,.95) 10%,rgba(160,120,255,.7) 16%,rgba(105,220,255,0) 26%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:0;pointer-events:none}
body.ai-processing .composer:after{opacity:1;animation:composerSpin 1s linear infinite}
@keyframes composerSpin{0%,100%{opacity:.35}50%{opacity:1}}

/* ---------- Quick-prompt chip active state ---------- */
.suggestions button.is-active{color:#e8faff;border-color:#8bdcff;background:linear-gradient(#16324a,#0a1a28);box-shadow:0 0 14px rgba(105,220,255,.25)}

/* ---------- Sidebar nav active indicator + shine ---------- */
.nav-item{--nav-accent:#69baff;position:relative;overflow:hidden;transition:color .18s ease,background-color .18s ease,box-shadow .18s ease}
/* Base hidden state for the collapsed-tablet-rail tooltip (a real element, not ::after
 * content:attr(), so unlike a pseudo-element it always exists and needs hiding outside that
 * one breakpoint - see the tablet media query below for why. */
.nav-tip{position:absolute;left:calc(100% + 10px);top:50%;transform:translate(5px,-50%);opacity:0;visibility:hidden;pointer-events:none}
.nav-item[data-view=home]{--nav-accent:#8fcfff}
.nav-item[data-view=profile]{--nav-accent:#8b7dff}
.nav-item[data-view=companies]{--nav-accent:#4ea4ff}
.nav-item[data-view=projects]{--nav-accent:#39ebe3}
.nav-item[data-view=skills]{--nav-accent:#ffc762}
.nav-item[data-view=achievements]{--nav-accent:#be6fff}
.nav-item[data-view=evidence]{--nav-accent:#baea6b}
.nav-item[data-view=knowledge]{--nav-accent:#2ed9ff}
.nav-item[data-view=connect]{--nav-accent:#ff7ebe}
.nav-item.active:before{content:'';position:absolute;left:0;top:8px;bottom:8px;width:3px;border-radius:3px;background:var(--nav-accent);box-shadow:0 0 5px var(--nav-accent),0 0 13px var(--nav-accent)}
.nav-item:hover{color:#fff;background:color-mix(in srgb,var(--nav-accent),transparent 88%);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--nav-accent),transparent 72%)}
.nav-item:hover svg,.nav-item:focus-visible svg,.nav-item.active svg{color:var(--nav-accent);filter:drop-shadow(0 0 5px var(--nav-accent))}
.nav-item.active:after{content:'';position:absolute;top:0;left:-60%;width:40%;height:100%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.08),transparent);animation:navShine 3.4s ease-in-out infinite}
@keyframes navShine{0%{left:-60%}60%,100%{left:120%}}

/* ---------- Draggable career nodes ---------- */
.graph-node{cursor:grab;touch-action:none}
.graph-node:after{content:'DRAG';position:absolute;top:-17px;left:50%;transform:translateX(-50%) translateY(4px);font-size:6px;letter-spacing:1.4px;color:rgba(var(--color),.9);opacity:0;transition:opacity .2s,transform .2s;pointer-events:none}
.graph-node:hover:after,.graph-node:focus-visible:after{opacity:.75;transform:translateX(-50%) translateY(0)}
.graph-node.is-dragging{cursor:grabbing;z-index:5}
.graph-node.is-dragging .bubble{transform:scale(1.16);box-shadow:inset 0 0 26px rgba(var(--color),.9),0 0 20px rgba(var(--color),1),0 0 60px rgba(var(--color),.65);transition:none}
.graph-node.is-dragging strong{text-shadow:0 2px 8px #000,0 0 22px rgba(var(--color),.8)}
@media(max-width:720px){.graph-node{cursor:pointer;touch-action:auto}}
@media(max-width:720px){.graph-node:after{display:none}.avatar-caption{bottom:-30px;max-width:145px}.avatar-state{top:auto;bottom:17%;padding:4px 8px}.avatar-mouth{top:47.5%;transform:translate(-50%,-50%) scale(.8)}}
#resetLayout:hover{color:#8ddfff}

/* Each draggable category gently drifts at its own cadence. CSS translate is
   independent of the positioning transform, so saved layouts remain exact. */
.node-float{position:relative;display:flex;align-items:center;flex-direction:column;animation:nodeFloatA 6.8s ease-in-out infinite alternate}
.graph-node:nth-of-type(2n) .node-float{animation-name:nodeFloatB;animation-duration:7.7s;animation-delay:-2.8s}
.graph-node:nth-of-type(3n) .node-float{animation-name:nodeFloatC;animation-duration:8.4s;animation-delay:-4.1s}
.graph-node.is-dragging .node-float{animation-play-state:paused}
@keyframes nodeFloatA{50%{translate:3px -5px}100%{translate:-2px 2px}}
@keyframes nodeFloatB{50%{translate:-4px -2px}100%{translate:2px 4px}}
@keyframes nodeFloatC{50%{translate:2px 4px}100%{translate:-3px -3px}}

/* ---------- Right feature card hover polish ---------- */
.right-rail{perspective:1000px}
.feature{position:relative;overflow:hidden;background:linear-gradient(120deg,rgba(15,35,49,.55),rgba(4,15,25,.35));border-color:rgba(130,207,246,.23);backdrop-filter:blur(18px) saturate(130%);-webkit-backdrop-filter:blur(18px) saturate(130%);box-shadow:inset 0 1px rgba(255,255,255,.055),0 14px 36px rgba(0,0,0,.16);animation:railCardIn .58s var(--ease-premium) both}
.feature:nth-of-type(2){animation-delay:.06s}.feature:nth-of-type(3){animation-delay:.12s}.feature:nth-of-type(4){animation-delay:.18s}.feature:nth-of-type(5){animation-delay:.24s}.feature:nth-of-type(6){animation-delay:.3s}
.feature>svg{transition:transform .2s ease,color .2s ease}
.feature:hover .feature-icon{box-shadow:inset 0 0 15px color-mix(in srgb,var(--accent),transparent 70%),0 0 14px color-mix(in srgb,var(--accent),transparent 60%);color:#fff}
.feature:hover>svg{transform:translateX(3px);color:var(--accent)}
.feature:hover,.feature:focus-visible{transform:scale(1.008)!important;border-color:var(--accent);background:linear-gradient(120deg,color-mix(in srgb,var(--accent),#10202b 88%),rgba(5,18,29,.94));box-shadow:inset 3px 0 var(--accent),inset 0 1px rgba(255,255,255,.1),0 0 26px color-mix(in srgb,var(--accent),transparent 78%),0 18px 42px rgba(0,0,0,.28)}
.feature:active{transform:translateX(-2px) scale(.995)}
@keyframes railCardIn{from{opacity:0;transform:translateX(42px) rotateY(-4deg)}to{opacity:1;transform:none}}

/* Keep the permanent shortcut rail stable; hover must never restart its entrance sequence. */
.right-rail .feature{animation:none}

/* Every slide-panel record uses one semantic hover language, whether it is an article or button. */
dialog #panelBody .record{position:relative;transition:transform .2s ease,border-color .2s ease,background-color .2s ease,box-shadow .2s ease}
dialog #panelBody .record:hover,dialog #panelBody .record:focus-within{transform:translateY(-2px);border-color:rgba(var(--panel-accent),.82);background:linear-gradient(125deg,rgba(var(--panel-accent),.13),rgba(9,20,29,.86));box-shadow:inset 3px 0 rgba(var(--panel-accent),.9),0 12px 28px #0005,0 0 18px rgba(var(--panel-accent),.12)}
dialog #panelBody .action-link,dialog #panelBody .tag,dialog #panelBody .exploration-steps button{transition:transform .16s ease,border-color .16s ease,background-color .16s ease,box-shadow .16s ease,color .16s ease}
dialog #panelBody .action-link:hover,dialog #panelBody .action-link:focus-visible,dialog #panelBody .tag:hover,dialog #panelBody .tag:focus-visible,dialog #panelBody .exploration-steps button:hover,dialog #panelBody .exploration-steps button:focus-visible{transform:translateY(-1px);border-color:rgb(var(--panel-accent));color:#fff;background:rgba(var(--panel-accent),.18);box-shadow:0 0 16px rgba(var(--panel-accent),.2)}

/* Knight Rider / JARVIS display inside the right Voice AI card. */
/* The Knight-Rider-style scanning bar (formerly .jarvis-display/.jarvis-track)
 * has been removed by request — it overlapped the card's own description
 * text. The card's border/glow-by-voice-state treatment is kept. */
#voiceFeature[data-voice-state=speaking]{border-color:#71e9ff;box-shadow:inset 0 0 24px #31d2ff29,0 0 24px #31d2ff2e}
.motion-paused dialog:before,.motion-paused dialog:after,.motion-paused .avatar-mouth i,.motion-paused .avatar-scan,.motion-paused #panelBody>*,.motion-paused .node-float,.motion-paused .feature{animation:none!important}.motion-paused .avatar-caption{transition:none!important}

/* Completion: shared glass, relationship states and accessible controls. */
:root{--glass-border:rgba(120,210,255,.18);--glass-highlight:rgba(255,255,255,.045);--text-secondary:#afc3d4;--radius-md:14px}
.feature,.composer,dialog,.context-bar{backdrop-filter:blur(16px) saturate(120%);-webkit-backdrop-filter:blur(16px) saturate(120%)}
.feature.is-selected{border-color:var(--accent);box-shadow:inset 3px 0 var(--accent),0 0 20px color-mix(in srgb,var(--accent),transparent 88%)}
.feature.is-selected .feature-icon{color:#fff;box-shadow:inset 0 0 18px color-mix(in srgb,var(--accent),transparent 65%),0 0 18px color-mix(in srgb,var(--accent),transparent 50%);animation:featureSelectedPulse 1.8s ease-in-out infinite alternate}.feature.is-selected>svg{color:var(--accent);transform:translateX(3px)}@keyframes featureSelectedPulse{to{filter:brightness(1.25);transform:scale(1.035)}}
.nav-item.active{font-weight:700;color:#fff;background:linear-gradient(100deg,color-mix(in srgb,var(--nav-accent),transparent 84%),rgba(19,31,42,.82));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--nav-accent),transparent 68%),0 0 18px color-mix(in srgb,var(--nav-accent),transparent 88%)}
.graph-node.is-related .bubble{border-color:#d1f4ff;filter:brightness(1.08)}
.core.has-context{box-shadow:inset 0 0 25px #45beff99,0 0 35px #29baffa0,0 0 72px #764aef55}
body[data-voice-state=processing] .core{opacity:1;animation:coreThink 1.5s ease-in-out infinite}
body[data-voice-state=speaking] .core{box-shadow:0 0 35px #6febff,0 0 90px #855cff77}
@keyframes coreThink{50%{filter:brightness(1.15)}}
body[data-voice-state=processing] #sendButton svg{animation:sendThink 1s ease-in-out infinite}
@keyframes sendThink{50%{opacity:.35}}
.voice-orb[data-state=processing] .voice-orb-wave span{height:5px;width:5px;border-radius:50%}
.voice-orb-wave span:nth-child(2){animation-delay:.12s}.voice-orb-wave span:nth-child(3){animation-delay:.24s}.voice-orb-wave span:nth-child(4){animation-delay:.36s}.voice-orb-wave span:nth-child(5){animation-delay:.48s}
.mobile-voice-status{display:none}
.exploration-steps{display:flex;gap:5px;margin:20px 0;flex-wrap:wrap}
.exploration-steps button{display:flex;align-items:center;gap:6px;padding:8px;border:1px solid #335570;border-radius:10px;color:#badcef;font-size:11px;min-height:44px}
.exploration-steps small{display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:#15354b}
.exploration-steps [aria-current=step],.tag.active{background:#174262;border-color:#85dfff;color:#fff;font-weight:700}
.career-timeline{list-style:none;padding:0 0 0 19px;border-left:1px solid #38729b;margin:20px 0 25px 7px}
.career-timeline>li{position:relative;padding-bottom:25px}.career-timeline>li:before{content:'';position:absolute;left:-24px;top:4px;width:8px;height:8px;border-radius:50%;background:#72d9ff;box-shadow:0 0 10px #56baff88}
.career-timeline>li>span{display:block;font-size:11px;color:#9bd9f1;margin-bottom:10px}
.evidence-meta{display:grid;grid-template-columns:110px 1fr;gap:12px;font-size:12px;line-height:1.7}.evidence-meta dt{color:#84cdeb}.evidence-meta dd{margin:0;color:#c5d5e2}
.ambient-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.12;mix-blend-mode:screen;filter:saturate(.8) brightness(.7);pointer-events:none;mask-image:radial-gradient(ellipse,#000 20%,transparent 72%)}
.motion-paused .graph-stage>canvas{transform:none!important}.motion-paused .graph-node{transform:translate(-50%,-50%)!important}
.motion-paused *:before,.motion-paused *:after{animation-play-state:paused!important}
#closeExplorer,.side-controls>*,.graph-tools button,.composer>button{min-width:44px;min-height:44px}
.graph-tools{border-radius:23px}.node-tooltip{max-width:min(240px,calc(100vw - 24px));font-size:12px}
/* Bug fixed 8 Sep 2026: this was previously gated to short viewports only
   (max-height:860px), on the assumption the sidebar's normal-flow content (nav + ask-twin +
   control-row + voice-orb) would always end well above the absolutely-positioned
   sidebar-bottom's fixed 27px offset (its base rule, style.css). Several elements were added
   to the sidebar's normal flow this project (control-row, voice-orb, cv-menu, cert-badges)
   without revisiting that assumption, so at plenty of ordinary desktop heights the cert
   badges/CV menu now visually collide with the voice-ready badge above them. Applying this
   unconditionally (at this width tier) makes sidebar-bottom a normal-flow element and the
   sidebar itself scrollable if its content ever exceeds the viewport, instead of overlapping. */
@media(min-width:1001px){.sidebar{overflow-y:auto}.sidebar-bottom{position:static;margin:20px 10px 0}.sidebar-bottom p{margin:12px 0}.voice-orb{margin-top:12px;padding:10px}.ask-twin{margin-top:14px}.sidebar-bottom>.cert-badges{display:grid;grid-template-columns:repeat(3,46px);gap:6px}.sidebar-bottom #certBadges .certifications-label{display:flex;align-items:center;grid-column:span 2;order:0;margin:0;color:#d7effa;font-size:9px;letter-spacing:0;text-transform:none}.sidebar-bottom #certBadges img{order:1}}
/* A normal desktop-height sidebar fits cleanly; scrolling is reserved for genuinely short windows. */
@media(min-width:1001px) and (min-height:900px){.sidebar{overflow-y:hidden;padding-top:16px;padding-bottom:14px}.brand{padding-bottom:18px}.sidebar nav{gap:2px}.nav-item{min-height:35px;padding-top:7px;padding-bottom:7px}.ask-twin{margin-top:13px}.control-row{margin-top:10px}.voice-orb{margin-top:10px}.sidebar-bottom{margin-top:18px}}
.conversation{background:linear-gradient(145deg,rgba(7,29,45,.56),rgba(3,14,25,.42));backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%)}
@media(max-width:1000px){.mobile-voice-status{display:inline;color:#bcecff;font-size:8px;white-space:nowrap;letter-spacing:.6px;margin-right:8px}.composer-status #status{overflow:hidden;text-overflow:ellipsis}.context-bar{display:flex}.context-bar[hidden]{display:none}}
@media(max-width:1000px){.voice-advanced-choice{display:none!important}}
@media(max-width:1000px){.avatar-state{box-sizing:border-box;max-width:calc(100% - 14px);gap:4px;padding:4px 7px}.avatar-state b{min-width:0;overflow:hidden;text-overflow:clip;font-size:clamp(5.5px,1.35vw,7px);letter-spacing:clamp(.55px,.16vw,1px)}.conversation{background:linear-gradient(145deg,rgba(7,29,45,.5),rgba(3,14,25,.36));backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%)}.prompt-library{background:linear-gradient(145deg,rgba(7,29,45,.48),rgba(3,14,25,.32))!important;backdrop-filter:blur(24px) saturate(140%);-webkit-backdrop-filter:blur(24px) saturate(140%)}.prompt-library::backdrop{background:rgba(0,8,15,.34)!important;backdrop-filter:blur(5px)}}
@media(max-width:720px){.tag,.filter-row button,.action-link,.back-button,.suggestions button,.read-answer{min-height:44px;display:inline-flex;align-items:center}.composer-status{flex-wrap:wrap;white-space:normal;row-gap:5px}.composer-status #status{max-width:100%;white-space:nowrap}.context-bar{font-size:8px;margin-bottom:10px}.context-bar strong{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.composer input{height:44px}.universe{padding-bottom:265px}.conversation{bottom:265px;max-height:calc(100dvh - 290px)}.feature{min-height:106px}.nav-item{min-width:44px}.evidence-meta{grid-template-columns:90px 1fr}}
@media(max-width:720px){.conversation .message .tag{min-height:38px;padding:7px 10px;line-height:1.25}.conversation #messages{scroll-behavior:auto!important;overflow-anchor:none}}

/* Also noticed while moving this: this rule has no @media wrapper (it sits right after two
 * media-query blocks, which is likely why), so it has always applied unconditionally at every
 * width rather than a specific breakpoint - flagging that rather than guessing at a fix for
 * it too, since it renders fine as-is and wasn't part of what was asked. */
.first-hint{top:0;bottom:auto;left:auto;right:6%;transform:none;width:max-content;max-width:320px;padding:5px 12px;border-radius:20px}.first-hint strong{display:none}.first-hint span{font-size:9px}
#mobileMotionToggle{display:none}
@media(max-width:720px){#mobileMotionToggle{display:grid}.graph-tools{left:50%;transform:translateX(-50%) scale(calc(1 / var(--zoom)))}.composer-status{padding:5px 8px;margin-left:0;margin-right:0;background:#061321e8;border:1px solid #294154;border-radius:9px}.mobile-voice-status{padding-right:8px;border-right:1px solid #426780}.composer-status #status{flex:1;min-width:0}}

/* Canonical bio copy in the profile teaser, matching the wording used on the
 * main portal (public_html/index.php, profile.php) — kept compact so the
 * card's existing height/position budget still holds. */
.profile-teaser .role-line{font-size:12px;line-height:1.6;margin:0 0 6px}
.profile-teaser .positioning-line{font-size:10.5px;line-height:1.55;color:#7fa0b8;margin:0 0 10px}

/* Photo avatar in place of the placeholder SVG bust. Sits inside .core-inner,
 * so it inherits the existing .core-ring / .core:before/:after rotating-ring
 * animation for free — no separate "circling" animation needed. */
/* The avatar now fills most of the circle (absolutely positioned) instead of
 * being one item in a centered flex stack, so it can be sized generously,
 * without competing for space with the caption text below, which becomes a
 * bottom-anchored overlay instead. object-fit:contain (not cover) so the
 * portrait's own full ring/glass rim is always shown uncropped and centered
 * - cover was symmetrically cropping ~20px off each side, into the rim
 * itself. The symmetric 2% inset keeps the PNG optically centered, while
 * .avatar-mouth's 47.5% position tracks the portrait's actual mouth. */
.core-inner{display:block}
.core-inner>.core-avatar{position:absolute;inset:2%;width:96%;height:96%;object-fit:contain;object-position:50% 50%;border-radius:50%;filter:drop-shadow(0 0 10px #558fff)}
/* Bug fixed 8 Sep 2026: text-shadow alone wasn't reliably readable over the avatar photo (a
 * bright/busy region can still wash out a dark drop-shadow) - each line is now its own small
 * frosted-glass pill instead, matching the same glass-badge language already used for
 * .avatar-state and .avatar-caption elsewhere on this same component, so the text has a
 * genuine solid-enough backing regardless of what's behind it in the photo. .core-inner clips
 * to a circle (overflow:hidden) but these stay well within that circle, so nothing is cut off. */
.core-inner>strong,.core-inner>small{position:absolute;left:8%;right:8%;text-align:center;margin:0!important;border:1px solid rgba(105,220,255,.3)!important;padding:4px 6px!important;border-radius:12px;background:rgba(3,14,23,.78);backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px);box-shadow:0 4px 14px rgba(0,0,0,.4);text-shadow:0 1px 3px #000a}
.core-inner>strong{bottom:calc(15% + 22px)}
.core-inner>small{bottom:23%;color:#bdd8f1}
.core-inner>strong{border:0!important;background:transparent!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;box-shadow:none!important;background-image:linear-gradient(90deg,#d7ff91 0%,#72efb7 48%,#75dcff 100%)!important;background-clip:text!important;-webkit-background-clip:text!important;color:transparent!important;-webkit-text-fill-color:transparent!important;filter:drop-shadow(0 1px 2px #00120c) drop-shadow(0 0 8px #77eea044)}
.feedback-open{position:static;width:100%;margin:7px 0 0;z-index:18;display:flex;align-items:center;justify-content:center;gap:6px;padding:6px 8px;border:1px solid #b9ed6b66;border-radius:8px;background:#061a21cc;color:#d9ff9c;font-size:7px;letter-spacing:.07em;text-transform:uppercase;box-shadow:0 0 12px #78d98b18}.feedback-open-mobile{display:none}.feedback-open span{font-size:11px;color:#d9ff77}.feedback-open:hover{border-color:#d9ff8f;box-shadow:0 0 18px #78e5a733}.mobile-resource-bar{display:none}
.composer-prompts{display:none}
.tablet-sidebar-tools{display:none}
.feedback-dialog{inset:50% auto auto 50%;margin:0;width:min(540px,calc(100vw - 28px));height:auto;max-height:min(760px,90dvh);padding:0;border:1px solid #6edfb966;border-radius:18px;transform:translate(-50%,-50%);background:linear-gradient(145deg,#081e2bf8,#030d16fc);box-shadow:0 30px 90px #000d,0 0 35px #68e9ac22;overflow:auto}.feedback-dialog::backdrop{background:#000a;backdrop-filter:blur(7px)}.feedback-dialog form{padding:22px}.feedback-head{display:flex;justify-content:space-between;gap:18px;margin-bottom:14px}.feedback-head small{color:#85eebc;font-size:7px;letter-spacing:.18em}.feedback-head h2{margin:4px 0;font-size:25px}.feedback-head p{margin:0;color:#91aaba;font-size:10px}.feedback-head button{width:30px;height:30px;border:1px solid #385566;border-radius:50%;font-size:19px}.feedback-question{display:grid;grid-template-columns:26px minmax(0,1fr) auto;align-items:center;gap:10px;padding:11px 0;border-top:1px solid #29404f}.feedback-question>span{display:grid;place-items:center;width:23px;height:23px;border:1px solid #67cba955;border-radius:50%;color:#8ce8bd;font-size:8px}.feedback-question>strong{font-size:11px;font-weight:550}.feedback-stars{display:flex;gap:2px}.feedback-stars button{padding:2px;color:#45606b;font-size:21px;line-height:1;transition:.15s}.feedback-stars button:hover,.feedback-stars button.selected{color:#e5c66a;text-shadow:0 0 9px #f2c65c77;transform:scale(1.08)}.feedback-stars button:focus-visible{outline:1px solid #e9cf74;outline-offset:1px}.feedback-actions{display:flex;align-items:center;justify-content:space-between;gap:15px;margin-top:14px;padding-top:14px;border-top:1px solid #29404f}.feedback-actions span{color:#8fa9b8;font-size:9px}.feedback-actions button{padding:9px 13px;border:1px solid #72d9b466;border-radius:9px;background:#124a3e;color:#dffff2;font-size:10px}.feedback-actions button:disabled{opacity:.4;cursor:not-allowed}
@media(max-width:1000px){#feedbackOpen{display:none}}
@media(max-width:1000px){.composer-prompts{display:flex;flex-wrap:nowrap;gap:6px;overflow-x:auto;scrollbar-width:none;margin:8px 0 0;padding:0 0 2px;width:auto;border:0;background:none;box-shadow:none}.composer-prompts::-webkit-scrollbar{display:none}.composer-prompts button{display:block;flex:0 0 auto;white-space:nowrap;text-align:left;font-size:8px;color:#90cff5;border:1px solid #304959;border-radius:16px;background:linear-gradient(#111e2b,#080e16);padding:6px 10px}.composer-prompts button:hover{color:#8ddfff;border-color:#80d6ff}}
@media(max-width:720px){.mobile-resource-bar{position:relative;z-index:8;display:block;margin:10px 19px 215px;padding:14px;border:1px solid #294557;border-radius:14px;background:linear-gradient(145deg,rgba(8,30,45,.94),rgba(3,15,25,.96));box-shadow:0 12px 30px #0005}.mobile-resource-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:11px}.mobile-resource-head span{color:#77cfea;font-size:7px;letter-spacing:.16em}.mobile-resource-head strong{color:#8da6b6;font-size:8px;font-weight:500}.mobile-cert-badges{display:flex!important;gap:7px;max-width:100%;padding:0 0 11px;overflow-x:auto}.mobile-cert-badges img{flex:0 0 42px;width:42px;height:42px;object-fit:contain;padding:4px;border:1px solid #315166;border-radius:8px;background:#fff}.mobile-resource-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}.mobile-cv-menu{position:relative}.mobile-cv-menu summary,.mobile-resource-actions .feedback-open-mobile{display:flex;align-items:center;justify-content:center;gap:6px;min-height:38px;margin:0;padding:7px 9px;border:1px solid #35566b;border-radius:9px;background:#081a27;color:#c6e3f3;font-size:8px;letter-spacing:.04em;list-style:none;cursor:pointer}.mobile-cv-menu summary::-webkit-details-marker{display:none}.mobile-cv-menu summary svg{width:13px}.mobile-cv-menu>div{position:absolute;left:0;right:0;bottom:calc(100% + 6px);z-index:20;overflow:hidden;border:1px solid #35566b;border-radius:9px;background:#06131f;box-shadow:0 10px 28px #000a}.mobile-cv-menu a{display:block;padding:10px;color:#cde7f6;font-size:9px}.mobile-cv-menu a+a{border-top:1px solid #274052}.mobile-resource-actions .feedback-open-mobile{color:#d9ff9c;border-color:#88ca6688}.mobile-resource-actions .feedback-open-mobile span{font-size:11px}}
@media(max-width:600px){.feedback-dialog form{padding:17px}.feedback-question{grid-template-columns:24px minmax(0,1fr)}.feedback-stars{grid-column:2}.feedback-actions{align-items:stretch;flex-direction:column}}
@media(max-width:720px){.core-inner>strong{bottom:calc(15% + 21px);padding:3px 5px!important}.core-inner>small{bottom:19%;padding:3px 5px!important}}

/* Sidebar: no-longer-a-card voice entry point, visible animation/voice
 * toggles, certification badges and the resume menu (replacing the removed
 * top brand block and the old single motion/sound icon row). */
.control-row{display:flex;gap:8px;margin-top:14px}
.control-toggle{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:9px 6px;border:1px solid #263c4a;border-radius:9px;background:#0c1720;color:#a4c9da;font-size:9px;letter-spacing:.4px;transition:border-color .2s ease,color .2s ease,background .2s ease}
.control-toggle:hover{border-color:#3d5c72;color:#d3e8f5}
.control-toggle svg{width:13px;height:13px;flex-shrink:0}
.control-toggle[aria-pressed=true]{border-color:#5386ff55;background:#101c30;color:#8fb3ff}
.responsive-voice-toggle{display:none}
@media(max-width:1000px){.responsive-voice-toggle{display:inline-flex;align-items:center;gap:5px;margin-left:auto;padding:5px 8px;border:1px solid #49768d;border-radius:999px;background:#071b28;color:#bfeaff;font-size:8px;line-height:1;white-space:nowrap}.responsive-voice-toggle svg{width:12px;height:12px}.responsive-voice-toggle[aria-pressed=true]{border-color:#55dcb088;background:#0a302c;color:#a8ffe2}.responsive-voice-toggle[aria-pressed=false]{border-color:#63717b;background:#111a21;color:#9baab4}}
.voice-settings-toggle{padding:5px}
.voice-volume-range{width:100%;display:block;margin:2px 0 10px;accent-color:#4aa9ff;height:20px}
.cert-badges{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
.cert-badges img{width:46px;height:46px;object-fit:contain;padding:6px;border-radius:10px;background:linear-gradient(145deg,rgba(15,35,49,.6),rgba(4,15,25,.4));border:1px solid rgba(130,207,246,.22);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);transition:transform .2s ease,border-color .2s ease,box-shadow .2s ease;cursor:default}
.cert-badges img:hover{transform:translateY(-3px) scale(1.1);border-color:#6febff;box-shadow:0 8px 20px rgba(72,201,255,.35)}
.cv-menu-wrap{position:relative;margin-bottom:12px}
.cv-menu-toggle{display:flex;align-items:center;gap:6px;width:100%;padding:9px 10px;border:1px solid #263c4a;border-radius:9px;background:#0c1720;color:#a4c9da;font-size:9px;letter-spacing:.4px}
.cv-menu-toggle:hover{border-color:#3d5c72;color:#d3e8f5}
.cv-menu-toggle svg{width:13px;height:13px;flex-shrink:0}
.cv-menu-toggle svg:last-child{margin-left:auto}
.cv-menu{position:absolute;bottom:calc(100% + 6px);left:0;right:0;border:1px solid #345269;border-radius:10px;background:linear-gradient(135deg,#101c2bf5,#030910f2);box-shadow:0 10px 30px #0008;overflow:hidden;z-index:5}
.cv-menu[hidden]{display:none}
.cv-menu a{display:block;padding:9px 11px;color:#cfe6f5;text-decoration:none}
.cv-menu a:hover{background:#152738}
.cv-menu a strong{display:block;font-size:10px;font-weight:560}
.cv-menu a span{display:block;font-size:8px;color:#7fa0b8;margin-top:2px}
/* Real, pre-existing bug found while fixing this 8 Sep 2026: this rule's font-size/line-height/
 * letter-spacing/color/margin were NEVER actually taking effect. style.css's ".sidebar-bottom p"
 * (a class + element selector, specificity 0,1,1) has always outranked plain ".copyright"
 * (0,1,0) regardless of which stylesheet loads later — CSS specificity, not source order,
 * decides ties. So this line was actually rendering at 12px with a 3px letter-spacing and a
 * 20px top/bottom margin the whole time, which is why "Powered by" broke into three ragged
 * lines instead of the two intended below. Selector strengthened to ".sidebar-bottom p.copyright"
 * (0,2,1) so it now reliably wins. Was white-space:nowrap, which cut text off mid-word instead
 * of ever wrapping — replaced with a normal line-height so a manual <br> in the markup controls
 * exactly where it breaks, and it wraps further rather than clipping if it still doesn't fit. */
.sidebar-bottom p.copyright{font-size:10px;letter-spacing:0;color:#5c7385;text-align:center;margin:8px 0 0;line-height:1.5}
.copyright a{color:#7fa8c9;text-decoration:none;font-weight:600}
.copyright a:hover{color:#9be8ff;text-decoration:underline}
.clear-device-data{display:block;width:100%;text-align:center;margin-top:6px;font-size:6.5px;letter-spacing:.2px;color:#4a6070;background:none;border:0;text-decoration:underline;cursor:pointer}
.clear-device-data:hover{color:#7fa8c9}
.evidence-badge{display:inline-block;padding:2px 7px;border-radius:9px;font-size:8px;font-weight:600;letter-spacing:.3px;color:#7fe8b8;background:rgba(84,232,178,.12);border:1px solid rgba(84,232,178,.3);margin-right:4px}
.evidence-badge-none{color:#e8b87f;background:rgba(232,184,127,.12);border-color:rgba(232,184,127,.3)}
.live-counter{display:block;font-size:8px;letter-spacing:.6px;color:#7fe8b8;margin-top:4px}
.live-counter .live-dot{margin-right:5px}
.year-scrub{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 18px;padding:12px 14px;border:1px solid #294256;border-radius:12px;background:linear-gradient(125deg,#172636aa,#09141daa)}
.year-scrub label{font-size:11px;color:#b1c3d3;display:flex;align-items:center;gap:6px}
.year-scrub strong{color:#8bd6fb;font-size:14px}
.year-scrub input[type=range]{flex:1;min-width:120px;accent-color:#48c9ff}
.career-timeline>li{transition:opacity .25s ease,filter .25s ease}
.career-timeline>li.is-outside-year{opacity:.28;filter:grayscale(.6)}
#printBriefing{margin:0 0 16px}
.tone-toggle{display:flex;align-items:center;gap:4px;margin-left:auto;margin-right:10px}
/* Short, plain-language cue added 8 Sep 2026 so a first-time visitor understands these are
 * clickable and what they're for, without needing anything explained elsewhere — "Reading
 * as" plus the buttons reads as one instruction: pick who you are, before you leave. */
.tone-toggle-label{font-size:7px;letter-spacing:1.4px;text-transform:uppercase;color:#6f93ab;margin-right:2px;white-space:nowrap}
@media(max-width:1000px){.tone-toggle-label{display:none}}
/* Bug fixed 8 Sep 2026: style.css's ".conversation header button" (0,1,2 - a class plus two
 * element selectors) has always outranked plain ".tone-toggle button" (0,1,1) here, forcing
 * every tone chip into the round 25x25px circle meant for the icon-only close button next to
 * it - "Neutral" and "Recruiter" were being squeezed into a shape with no room for their own
 * text, which is exactly what read as "Nest" / "Recr". Selector strengthened to
 * ".conversation header .tone-toggle button" (0,2,2) so this reliably wins, and every
 * property the circular-button rule sets is explicitly reset back to a normal text pill. */
.conversation header .tone-toggle button{width:auto;height:auto;border-radius:10px;flex-shrink:1;font-size:8px;padding:4px 8px;border:1px solid #294256;color:#8bb0c8;background:#0c1720;white-space:nowrap}
.conversation header .tone-toggle button.is-active{border-color:#48c9ff;color:#9be8ff;background:#0c2430}
.tone-frame{display:block;font-size:9px;letter-spacing:.3px;color:#8bd6fb;margin-bottom:5px;font-style:italic}
@media(max-width:720px){.tone-toggle{display:none}}
.visitor-ripple{position:fixed;top:70px;right:24px;z-index:40;max-width:260px;padding:9px 14px;border-radius:20px;border:1px solid rgba(105,220,255,.25);background:linear-gradient(135deg,rgba(9,29,46,.85),rgba(2,10,19,.8));backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);font-size:10px;color:#bcdcec;box-shadow:0 10px 30px rgba(0,0,0,.35);opacity:0;transform:translateY(-8px);transition:opacity .5s ease,transform .5s ease;pointer-events:none}
.visitor-ripple.is-visible{opacity:1;transform:translateY(0)}
.visitor-ripple .live-dot{margin-right:6px}
@media(max-width:1000px){.visitor-ripple{display:none}}
@media print{
 body *{visibility:hidden}
 dialog#explorer,dialog#explorer *{visibility:visible}
 dialog#explorer{position:absolute;top:0;left:0;right:0;bottom:auto;width:100%;height:auto;max-height:none;overflow:visible;background:#fff;color:#000;box-shadow:none;border:0;padding:24px}
 dialog#explorer::backdrop{display:none}
 .panel-search,#printBriefing,.panel-top>button,.first-hint{display:none!important}
 .record,article.record{border:1px solid #ccc;background:#fff;color:#000;break-inside:avoid}
 .record h3,.record p,.view-intro,.view-meta,.section-title{color:#000}
 .tag,.tag-list button{border:1px solid #999;color:#000;background:#fff}
 a[href]:after{content:" (" attr(href) ")";font-size:9px;color:#555;word-break:break-all}
 /* v9.2 (MD 103-111, 120): with the explorer open, print / Save-as-PDF prints the WHOLE open view (e.g. the recruiter
    briefing), not the scrolled viewport - the app shell behind the modal is taken out of the flow, the page and the
    dialog lose their viewport-height limits and every scroll container flows across as many pages as needed. */
 html.explorer-open,html.explorer-open body{height:auto!important;min-height:0!important;max-height:none!important;overflow:visible!important;display:block!important;background:#fff!important}
 html.explorer-open body>*:not(dialog#explorer){display:none!important}
 html.explorer-open dialog#explorer{position:absolute!important;inset:0 auto auto 0!important;width:100%!important;max-width:none!important;height:auto!important;max-height:none!important;min-height:0!important;overflow:visible!important;transform:none!important;filter:none!important;opacity:1!important;margin:0!important;padding:0 4mm!important}
 html.explorer-open dialog#explorer *{animation:none!important;transition:none!important}
 dialog#explorer #panelBody,dialog#explorer .panel-top,dialog#explorer section,dialog#explorer article,dialog#explorer div{max-height:none!important;overflow:visible!important}
 dialog#explorer .panel-top{position:static!important;background:#fff!important}
 dialog#explorer #copyDeepLink,dialog#explorer #closeExplorer,dialog#explorer #jdText,dialog#explorer #jdMatchBtn,dialog#explorer .year-scrub{display:none!important}
 dialog#explorer .print-only{display:block!important}
 dialog#explorer h2,dialog#explorer h3,dialog#explorer small,dialog#explorer strong,dialog#explorer li,dialog#explorer span{color:#000!important}
 dialog#explorer h3.section-title{break-after:avoid;page-break-after:avoid;margin-top:14px}
 dialog#explorer .record h3,dialog#explorer .record p{overflow-wrap:anywhere}
 dialog#explorer .jd-requirement{break-inside:avoid;page-break-inside:avoid}
}
.print-only{display:none}

/* Company logos: the base white background made white/light-colored logos
 * (TDRA, MoE, etc.) invisible. Match the main portal's own treatment
 * (public_html/assets/css/styles.css .company-logo-mark) — dark glass
 * background with a drop-shadow on the image itself, not a white plate. */
.record-logo{background:linear-gradient(145deg,rgba(9,52,78,.78),rgba(2,20,35,.9));border:1px solid rgba(79,181,222,.35);filter:drop-shadow(0 2px 5px rgba(0,0,0,.5))}

/* Keep the hero paragraph clear of the constellation nodes on wide screens —
 * it had no max-width and could stretch under the Experience node. */
.hero-copy{max-width:min(56vw,600px)}
/* More breathing room between the hero identity line and the profile-teaser
 * card below it — they sit close together at common viewport heights. */
.profile-teaser{bottom:158px}
/* At ≤720px the card is back in normal document flow, right after the graph
 * (see style.css). This unconditional `bottom` offset above predates that and
 * was still shifting the in-flow card upward by 158px — pulling it into the
 * bottom-most graph nodes while leaving a matching gap below it before the
 * feature cards. Cancelled here, later in the cascade, so it wins over the
 * rule above at this width without touching the desktop/tablet positioning. */
@media(max-width:720px){.profile-teaser{bottom:auto}}

/* Responsive reliability: detail panels always open at their heading, while the
 * question composer remains visible above browser UI and the bottom navigation. */
@media(max-width:1000px){
 dialog#explorer{inset:0!important;width:100vw!important;max-width:100vw!important;height:100dvh!important;max-height:100dvh!important;margin:0!important;padding:max(18px,env(safe-area-inset-top)) max(18px,env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(18px,env(safe-area-inset-left));overscroll-behavior:contain;scroll-padding-top:max(18px,env(safe-area-inset-top))}
 dialog#explorer .panel-top{position:sticky;top:calc(-1 * max(18px,env(safe-area-inset-top)));z-index:4;margin-left:-2px;margin-right:-2px;padding:8px 2px 12px;background:linear-gradient(180deg,#0b1928 72%,transparent)}
}
@media(max-width:720px){
 .composer-area{display:block!important;visibility:visible!important;bottom:calc(70px + env(safe-area-inset-bottom))!important;left:max(12px,env(safe-area-inset-left))!important;right:max(12px,env(safe-area-inset-right))!important;z-index:30!important}
 .composer{min-height:58px}.composer input{display:block!important;visibility:visible!important;opacity:1!important;min-width:0!important;font-size:16px!important}
 .sidebar{height:calc(62px + env(safe-area-inset-bottom))!important;padding-bottom:env(safe-area-inset-bottom)!important}
}

/* "Enterprise Architect" heading: fit on one line with an accent gradient
 * instead of the previous plain white text that wrapped to two lines. */
.profile-teaser h2{font-size:20px;letter-spacing:-.3px;white-space:nowrap;background:linear-gradient(100deg,#8ff2ff,#79b8ff 55%,#c893ff);color:transparent;background-clip:text;-webkit-background-clip:text}

/* Positioning-line: two sentences in the graph's own accent colors. */
.positioning-line .pos-a{display:block;color:#6fe3ff;font-weight:600}
.positioning-line .pos-b{display:block;color:#c893ff;font-weight:600;margin-top:4px}
@media(max-width:1000px){.control-row,.cert-badges,.cv-menu-wrap,.copyright{display:none}}

/* Six metric tiles instead of four (added Federal Govt. Experience and a
 * broader Projects count) — three columns keeps two even rows. */
.metrics>div{grid-template-columns:repeat(3,1fr)!important}
.metrics>div>div{border-bottom:1px solid #19303c;padding-bottom:10px;margin-bottom:10px}
.metrics>div>div:nth-child(3n+1){padding-left:0!important}
.metrics>div>div:nth-child(3n){border-right:0!important}
.metrics>div>div:nth-last-child(-n+3){border-bottom:0;margin-bottom:0}

/* Bigger eyebrow labels, by request. */
.eyebrow{font-size:10px!important}
.metrics>small{font-size:8px!important}

/* Compact graph controls live at the right edge, clear of the Knowledge node. */
@media(min-width:721px){.graph-tools{left:auto!important;right:34px;bottom:5%;border-radius:14px;transform:scale(calc(1 / var(--zoom)))}.graph-tools button{min-width:28px!important;min-height:28px!important;width:28px;height:28px;padding:3px!important;font-size:7px}.graph-tools #resetGraph{width:38px}.graph-tools svg{width:10px;height:10px}}
@media(min-width:1251px){.graph-tools{right:28px}}
@media(min-width:1600px){.graph-tools{right:72px}}

/* Mobile flow correction: one composer-clearance area, never resource margin + page padding. */
.version-link{appearance:none;border:0;background:none;color:#8fdfff;font:inherit;padding:0;cursor:pointer;text-decoration:underline;text-decoration-color:#3abed766;text-underline-offset:3px}
.version-link:hover,.version-link:focus-visible{color:#fff;text-shadow:0 0 12px #4fdfff}
.visitor-totals{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;margin:8px 0 2px;border:1px solid #65cfff24;border-radius:8px;overflow:hidden;background:#07172599}
.visitor-totals span{display:flex;flex-direction:column;align-items:center;padding:5px 2px;color:#7895aa;font-size:6.5px;letter-spacing:.8px;text-transform:uppercase;border-left:1px solid #65cfff20}.visitor-totals span:first-child{border-left:0}.visitor-totals strong{color:#dff7ff;font-size:10px;line-height:1.1;margin-bottom:2px}
.sidebar-bottom{display:flex;flex-direction:column}.certifications-label{order:1;color:#ccecff;font-size:8px;letter-spacing:.8px;margin-bottom:5px}.sidebar-bottom>.cert-badges{order:2}.sidebar-bottom>.cv-menu-wrap{order:3}.sidebar-bottom>.visitor-totals{order:4}.sidebar-bottom>.feedback-open{order:5}.sidebar-bottom>.copyright{order:6;margin-top:9px}
/* Same rounded-corner scrollbar overhang as .prompt-library (see the comment above that rule):
   this dialog has no overflow of its own, so it silently inherited overflow-y:auto from the
   base dialog{} rule in style.css - the native scrollbar then sat right on this dialog's own
   border-radius:18px corner instead of being clipped to it. Splitting header/body the same way
   (fixed header, only .version-dialog-body scrolls, overflow:hidden on the outer dialog clips
   the scrollbar to the rounded corner) fixes it here too. */
.version-dialog{position:fixed;inset:50% auto auto 50%;transform:translate(-50%,-50%);width:min(620px,calc(100vw - 32px));height:auto;max-height:calc(100dvh - 32px);margin:0;padding:0;border:1px solid #52d9ff66;border-radius:18px;background:linear-gradient(145deg,#081c2b,#040c14);color:#dff7ff;box-shadow:0 30px 90px #000c,0 0 45px #1bc8ff1f;overflow:hidden}
/* display must stay scoped to [open] - see the identical note above .prompt-library - otherwise
   this dialog renders on every page load instead of only when showModal() is called. */
.version-dialog[open]{display:flex;flex-direction:column}
.version-dialog::backdrop{background:#01060bcc;backdrop-filter:blur(8px)}.version-dialog-head{flex:0 0 auto;padding:28px 28px 0;display:flex;justify-content:space-between;gap:20px;align-items:flex-start}
.version-dialog-head small{font-size:8px;letter-spacing:2.6px;color:#55dcff}.version-dialog h2{margin:7px 0 5px;font-size:28px}.version-dialog-head span{font-size:10px;color:#b8ffdc;border:1px solid #59e6ac55;border-radius:999px;padding:4px 9px}.version-dialog-head button{border:1px solid #6daac955;background:#0b2231;color:#dff7ff;width:38px;height:38px;border-radius:50%;font-size:20px;cursor:pointer}.version-dialog-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:0 28px 28px}.version-dialog-body>p{font-size:15px;line-height:1.65;color:#c5dcea;margin:24px 0 12px}.version-dialog-body>div#versionDetails{white-space:pre-line;font-size:12px;line-height:1.75;color:#92adbf}
.version-capabilities{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:24px}.version-capabilities span{padding:10px;border:1px solid #55dfff2e;border-radius:9px;background:#0a2030;color:#a9dff0;font-size:9px;text-align:center}
@media(max-width:720px){
 .universe{padding-bottom:275px!important}
 .mobile-resource-bar{margin-bottom:0!important}
 .eyebrow{position:relative!important;left:0!important;right:auto!important;display:block!important;width:calc(100% - 40px)!important;max-width:360px;margin:24px 20px 0!important;transform:none!important;white-space:nowrap;overflow:visible;font-size:7px!important;letter-spacing:2px!important}
 .version-dialog-head{padding:21px 21px 0}.version-dialog-body{padding:0 21px 21px}.version-dialog h2{font-size:22px}.version-capabilities{grid-template-columns:1fr}.visitor-totals-mobile{margin:10px 0 5px}.visitor-totals-mobile span{font-size:7px;padding:7px 2px}.visitor-totals-mobile strong{font-size:12px}
 .mobile-copyright{display:block!important;margin:6px 0 0!important;color:#6f8798!important;font-size:9px!important;line-height:1.5!important;letter-spacing:0!important;text-align:center}
 .hero-copy{width:calc(100% - 40px)}.hero-copy p{width:100%;max-width:none;line-height:1.65}.hero-copy p br{display:none}
}

/* Phone composition: compact, single-line identity; equal prompt chips; and a
 * conversation card whose lower edge is measured against the real composer. */
@media(max-width:720px){
 .hero-copy{margin:16px 14px 0!important;width:calc(100% - 28px)!important;max-width:none!important}
 .hero-copy h1{margin-bottom:9px!important;font-size:27px!important;line-height:1.08!important;letter-spacing:-1px!important;white-space:nowrap}
 .hero-copy h1>span{font-size:1em!important;letter-spacing:-1.2px!important}
 .hero-copy p{max-width:none!important;font-size:10px!important;line-height:1.45!important;text-align:left}
 .hero-copy .identity{margin-top:8px!important}
 .composer-area{left:10px!important;right:10px!important}
 .composer{min-height:50px!important;padding:5px 7px!important;gap:7px!important}
 .composer input{height:38px!important;font-size:14px!important}
 .composer>button{width:38px!important;height:38px!important;min-width:38px!important;min-height:38px!important}
 .suggestions,.composer-prompts{align-items:stretch}
 .suggestions button,.composer-prompts button{box-sizing:border-box;height:40px!important;min-height:40px!important;padding:0 11px!important;line-height:1.15!important}
 .conversation{bottom:var(--mobile-composer-clearance,250px)!important;max-height:min(310px,calc(100dvh - var(--mobile-composer-clearance,250px) - 10px))!important;border-radius:15px!important}
 .conversation header{padding:9px 12px!important}
 .conversation #messages{padding:10px 12px!important}
 .conversation .message{margin-bottom:12px!important}
 .conversation .message p{font-size:11px!important;line-height:1.55!important}
 .conversation .message .tag{min-height:34px!important;padding:6px 9px!important;font-size:8px!important}
 .conversation .message .source-note{margin-top:7px!important;padding-top:5px!important}
}

/* Collapsed tablet rail: icon actions retain discoverable names on hover and keyboard focus. */
@media(min-width:721px) and (max-width:1000px){
 .nav-item,.ask-twin,.tablet-tool{overflow:visible!important;position:relative}
 /* .ask-twin/.tablet-tool never open the explorer dialog, so their attr()-based tooltip is
  * unaffected by the bug below and stays as-is. */
 .ask-twin:after,.tablet-tool:after{content:attr(data-label);position:absolute;left:calc(100% + 10px);top:50%;z-index:80;transform:translate(5px,-50%);padding:7px 10px;border:1px solid #4d7893;border-radius:7px;background:#071722f2;color:#e2f6ff;font-size:10px;font-weight:500;letter-spacing:0;line-height:1.2;white-space:nowrap;box-shadow:0 8px 24px #0009;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .16s,transform .16s,visibility .16s}
 .ask-twin:hover:after,.ask-twin:focus-visible:after,.tablet-tool:hover:after,.tablet-tool:focus-visible:after{opacity:1;visibility:visible;transform:translate(0,-50%)}
 /* .nav-item tooltips use a real .nav-tip child element instead of ::after content:attr() -
  * opening the explorer dialog puts it in the browser's top layer, which makes the sidebar
  * behind it inert, and confirmed on every nav icon (not one in particular): once that
  * happens, Chromium can permanently stop resolving content:attr()/var() for that icon's
  * tooltip afterwards, rendering an empty box instead of the label. Neither rewriting the
  * attribute nor replacing the element with an identical clone was enough to clear it once
  * triggered, so plain DOM text (immune to that class of pseudo-element bug) replaces it here. */
 .nav-item .nav-tip{z-index:80;padding:7px 10px;border:1px solid #4d7893;border-radius:7px;background:#071722f2;color:#e2f6ff;font-size:10px;font-weight:500;letter-spacing:0;line-height:1.2;white-space:nowrap;box-shadow:0 8px 24px #0009;transition:opacity .16s,transform .16s,visibility .16s}
 .nav-item:hover .nav-tip,.nav-item:focus-visible .nav-tip{opacity:1;visibility:visible;transform:translate(0,-50%)}
 /* While the explorer panel is open, the sidebar behind it is inert - hide tooltips outright
  * rather than show one rendering over an inert background icon. */
 html.explorer-open .nav-item .nav-tip,html.explorer-open .ask-twin:after,html.explorer-open .tablet-tool:after{opacity:0!important;visibility:hidden!important}
 .sidebar-bottom{display:block!important;left:12px;right:12px;bottom:14px}
 .sidebar-bottom>.visitor-totals,.sidebar-bottom>.feedback-open,.sidebar-bottom>.copyright{display:none!important}
 .tablet-sidebar-tools{display:grid;grid-template-columns:1fr;justify-items:center;gap:7px}
 .tablet-tool,.tablet-sidebar-tools .feedback-open{display:grid!important;place-items:center;width:42px;height:36px;margin:0;padding:0;border:1px solid #29495d;border-radius:9px;background:#071925;color:#9bcde1;box-shadow:none}
 .tablet-tool:hover,.tablet-tool:focus-visible{border-color:#68d9ff;color:#effcff;background:#102a3b}
 .tablet-tool svg{width:16px;height:16px}.tablet-visitor{height:42px;grid-template-rows:17px 12px}.tablet-visitor strong{font-size:8px;letter-spacing:0;color:#dff8ff}
}
/* Curated suggested-prompt library and controlled graph emphasis. */
.graph-node.prompt-focus .bubble{filter:brightness(1.3);box-shadow:0 0 0 2px rgba(var(--color),.72),0 0 34px rgba(var(--color),.65);animation:promptNodePulse 1.7s ease-in-out 2}
@keyframes promptNodePulse{50%{transform:scale(1.07)}}
/* A single scrolling dialog (overflow:auto on .prompt-library itself, covering the header, search
   box and card grid together) caused two problems: the native scrollbar sat right on the dialog's
   rounded corner and visibly poked outside it (browsers don't clip a scrollbar to border-radius),
   and scrolling the list also scrolled the search box and close button out of reach. Making the
   dialog a fixed-height flex column with only .prompt-library-list scrolling (min-height:0 is
   required here - without it a flex child won't shrink enough to actually scroll) keeps the
   search/close row permanently visible while overflow:hidden on the outer dialog clips the
   scrollbar to the rounded corner instead of letting it overhang.
   IMPORTANT: display:flex must stay scoped to the [open] attribute. A <dialog> is normally kept
   hidden by the browser's own built-in stylesheet (dialog:not([open]){display:none}), which only
   applies while there is no author rule for `display` on that element at all. Setting display
   unconditionally on .prompt-library (as an earlier version of this fix did) overrides that
   built-in rule for the element permanently, regardless of [open] - the popup then renders
   immediately on page load and calling .close() (which only removes the open attribute) can no
   longer hide it either, since this rule keeps forcing it visible either way. */
.prompt-library{position:fixed;inset:0;margin:auto;width:min(920px,calc(100vw - 32px));max-height:min(84vh,820px);padding:0;border:1px solid rgba(69,202,244,.45);border-radius:18px;background:linear-gradient(145deg,rgba(7,27,42,.54),rgba(3,17,29,.38));color:#eaf8ff;box-shadow:0 30px 100px #000b;overflow:hidden;backdrop-filter:blur(24px) saturate(140%);-webkit-backdrop-filter:blur(24px) saturate(140%)}
.prompt-library[open]{display:flex;flex-direction:column}
.prompt-library::backdrop{background:rgba(0,8,15,.38);backdrop-filter:blur(7px)}
.prompt-library-head{flex:0 0 auto;padding:24px 24px 0;display:flex;align-items:flex-start;justify-content:space-between;gap:18px}.prompt-library-head h2{margin:5px 0 7px;font-size:25px}.prompt-library-head p{max-width:680px;margin:0 0 16px;color:#9db8c7;font-size:11px;line-height:1.55}.prompt-library-head small{letter-spacing:.18em;color:#55dff4}.prompt-library-head button{flex:0 0 40px;width:40px;height:40px;border:1px solid #31566c;border-radius:50%;color:#dff7ff;background:#061725;font-size:22px}
.prompt-library>input{flex:0 0 auto;margin:0 24px 16px;min-height:46px;padding:0 15px;border:1px solid #31566c;border-radius:12px;background:#03121f;color:#eaf8ff;font:inherit}
.prompt-library-list{flex:1 1 auto;min-height:0;overflow-y:auto;padding:0 24px 24px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-content:start}.prompt-library-list button{display:block;min-height:auto;padding:14px 16px;text-align:left;border:1px solid #294d62;border-radius:13px;background:linear-gradient(145deg,#082235,#061825);color:#eaf8ff;transition:.18s transform,.18s border-color,.18s box-shadow}.prompt-library-list button:hover,.prompt-library-list button:focus-visible{transform:translateY(-2px);border-color:#50dfee;box-shadow:0 10px 28px rgba(23,195,231,.14)}.prompt-library-list small,.prompt-library-list strong{display:block}.prompt-library-list small{color:#75bed4;font-size:9px;letter-spacing:.11em;text-transform:uppercase}.prompt-library-list strong{margin-top:6px;font-size:14px;font-weight:500;line-height:1.4}.prompt-card-foot b{color:#7fb8cc;font-weight:500}.prompt-card-foot i{color:#5ce7ef;font-style:normal;font-weight:700}
@media(max-width:620px){.prompt-library-list{grid-template-columns:1fr;padding:0 16px 16px}.prompt-library-head{padding:16px 16px 0}.prompt-library>input{margin:0 16px 16px}}

/* ---------- Verified-evidence tag distinction (Zero-Gap v5 section 41A) ----------
 * app.js's mapEvidenceToLinks() adds this class only to a 'verified_evidence' item that
 * carries a real opaque evidence_id (EvidenceService-issued, never a raw DB id). It stays a
 * plain, non-navigable tag when the evidence drawer isn't available, but is visually marked as
 * the stronger tier rather than rendered identically to a source-backed/documented-context tag.
 * ZERO-GAP Final Closure Patch Gap A: when the drawer IS available, mapEvidenceToLinks() adds
 * role="button" - styled here as a real, obviously-clickable affordance (pointer cursor, focus
 * ring, hover state) so the distinction between "just a strength indicator" and "opens more
 * detail" is visible, not just present in the markup. */
.tag-verified{border-color:#55dff4;background:#0f3a49aa;color:#eaffff}
.tag-verified::before{content:'✓ ';color:#55dff4}
.tag-verified[role="button"]{cursor:pointer;transition:background .15s ease,transform .1s ease}
.tag-verified[role="button"]:hover{background:#0f3a49dd;transform:translateY(-1px)}
.tag-verified[role="button"]:focus-visible{outline:2px solid #55dff4;outline-offset:2px}

.evidence-drawer{position:fixed;inset:50% auto auto 50%;transform:translate(-50%,-50%);width:min(520px,calc(100vw - 32px));height:auto;max-height:calc(100dvh - 32px);margin:0;padding:0;border:1px solid #55dff466;border-radius:18px;background:linear-gradient(145deg,#081c2b,#040c14);color:#dff7ff;box-shadow:0 30px 90px #000c,0 0 45px #1bc8ff1f;overflow:hidden}
.evidence-drawer[open]{display:flex;flex-direction:column}
.evidence-drawer::backdrop{background:#01060bcc;backdrop-filter:blur(8px)}
.evidence-drawer-head{flex:0 0 auto;padding:22px 22px 0;display:flex;justify-content:space-between;gap:16px;align-items:flex-start}
.evidence-drawer-head small{font-size:8px;letter-spacing:2.6px;color:#55dff4}
.evidence-drawer-head h2{margin:6px 0 0;font-size:20px}
.evidence-drawer-head button{border:1px solid #6daac955;background:#0b2231;color:#dff7ff;width:34px;height:34px;border-radius:50%;font-size:18px;cursor:pointer;flex-shrink:0}
.evidence-drawer-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:16px 22px 22px}
.evidence-drawer-title{font-size:16px;margin:0 0 8px;color:#eaffff}
.evidence-drawer-detail{font-size:13.5px;line-height:1.6;color:#c5dcea;margin:0 0 14px}
.evidence-drawer-row{display:flex;justify-content:space-between;gap:12px;font-size:12px;padding:8px 0;border-top:1px solid #1c3a4a}
.evidence-drawer-row strong{color:#92adbf;font-weight:500;text-transform:capitalize}
.evidence-drawer-row span{color:#dff7ff;text-align:right}
.evidence-drawer-error{color:#ff9d9d;font-size:13px}
