/* felipe.wurch.dev — an interrogated résumé, not a browsed one.
   The chat-specific layer on top of the shared world in styles.css (fonts,
   tokens, reset, .link-btn) — link that first, this second. */

:root{
  --dock-radius:18px;
  --bubble-radius:18px;
  --shell:min(100% - 32px,720px);

  /* Theme/spacing — tunable at runtime by /felipe-dev.js in dev builds.
     --accent itself is defined in styles.css (with a dark-mode override);
     the panel overrides it inline rather than redeclaring it here. */
  --msg-gap:clamp(28px,4.2vh,46px);
  --bubble-pad-y:15px;
  --bubble-pad-x:18px;

  /* Terminal — tunable at runtime by /felipe-dev.js in dev builds. */
  --term-rows:5;
  --term-log-size:.74rem;
  --term-line-gap:7px;
  --term-mask-pct:30%;
  --term-face-size:.86rem;
  --term-face-left:18px;
  --term-face-bottom:18px;
  --term-bob-amp:-2px;
  --term-bob-dur:1.15s;
}

html{height:100%}

body{
  height:100%;
  height:100dvh;
  display:flex;
  flex-direction:column;
  overflow:hidden;
}

/* ── Header ─────────────────────────────────────────────── */
.bar{
  flex:none;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  padding:14px clamp(16px,4vw,32px);
  border-bottom:1px solid var(--border);
  background:color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
}
.bar-home{
  position:relative;
  font-family:var(--font-mono);
  font-size:.72rem;
  letter-spacing:.06em;
  color:var(--ink-soft);
  text-decoration:none;
  display:flex;
  align-items:center;
  gap:6px;
  min-height:32px;
}
.bar-home::after{
  content:"";position:absolute;left:0;right:0;bottom:2px;height:1.5px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform .32s cubic-bezier(.22,1,.36,1);
}
.bar-home:hover{color:var(--ink)}
.bar-home:hover::after{transform:scaleX(1)}
.agent-id{display:flex;align-items:center;gap:12px;min-width:0;padding-left:14px;border-left:1px solid var(--border)}
.agent-avatar{
  width:44px;height:44px;flex:none;border-radius:50%;position:relative;
  overflow:hidden;background:var(--surface);
  box-shadow:0 6px 16px -10px var(--shadow),0 0 0 2px var(--bg),0 0 0 3px var(--border);
  transition:box-shadow .4s cubic-bezier(.16,1,.3,1);
}
.agent-avatar img{width:100%;height:100%;display:block;object-fit:cover;object-position:66% 42%;transform:scale(1.2)}
.agent-avatar::after{content:"";position:absolute;right:0;bottom:0;width:10px;height:10px;border:2.5px solid var(--bg);border-radius:50%;background:var(--accent);box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 55%,transparent)}
.agent-meta{min-width:0}
.agent-name{
  font-family:var(--font-display);font-weight:800;font-size:1.02rem;letter-spacing:-.01em;
  display:flex;align-items:center;gap:8px;
}
.agent-dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 20%,transparent)}
.agent-tag{
  margin-top:1px;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.04em;
  color:var(--ink-soft);text-transform:none;
}
body.agent-thinking .agent-avatar{
  animation:agent-working 1.15s cubic-bezier(.16,1,.3,1) infinite alternate;
  box-shadow:0 6px 16px -10px var(--shadow),0 0 0 2px var(--bg),0 0 0 3px var(--accent);
}
body.agent-thinking .agent-dot{animation:agent-signal .9s cubic-bezier(.16,1,.3,1) infinite}
@keyframes agent-working{to{transform:translateY(-1px) scale(1.04)}}
@keyframes agent-signal{50%{transform:scale(.62);opacity:.45}}
@media (prefers-reduced-motion:reduce){.bar-home::after{transition:none}}

/* ── AI workspace ───────────────────────────────────────── */
.ai-workbench{
  flex:1;
  min-height:0;
  display:grid;
  grid-template-columns:minmax(284px,.68fr) minmax(0,1.42fr);
}
.ai-workbench{position:relative}
.workspace-sidebar{
  --spot-x:50%;--spot-y:20%;
  min-height:0;
  display:grid;
  grid-template-rows:minmax(0,1fr) minmax(0,1fr);
  border-right:1px solid var(--border);
  background-color:var(--surface-soft);
  background-image:radial-gradient(560px circle at var(--spot-x) var(--spot-y),color-mix(in srgb,var(--accent) 8%,transparent),transparent 60%);
}
.workspace-panel{min-height:0;display:flex;flex-direction:column;overflow:hidden}
.workspace-panel + .workspace-panel{border-top:1px solid var(--border)}
.panel-chrome{
  height:42px;flex:none;
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:0 14px 0 0;
  border-bottom:1px solid var(--border);
  background:color-mix(in srgb,var(--bg) 72%,transparent);
}
.panel-tab{
  align-self:stretch;display:flex;align-items:center;gap:8px;
  padding:0 14px;border-right:1px solid var(--border);
  font-family:var(--font-mono);font-size:.72rem;letter-spacing:.02em;
  color:var(--ink-soft);
}
.panel-tab.is-active{background:var(--surface);color:var(--ink)}
.panel-state{
  font-family:var(--font-mono);font-size:.7rem;letter-spacing:.04em;
  color:var(--ink-soft);white-space:nowrap;
}
.panel-file-icon{width:11px;height:14px;border:1px solid currentColor;border-radius:2px;position:relative;opacity:.85}
.panel-file-icon::after{content:"";position:absolute;right:-1px;top:-1px;width:4px;height:4px;border-left:1px solid currentColor;border-bottom:1px solid currentColor;background:var(--surface);transform:skewY(45deg)}
.panel-run-icon{width:9px;height:11px;background:var(--accent);clip-path:polygon(0 0,100% 50%,0 100%);filter:drop-shadow(0 0 4px color-mix(in srgb,var(--accent) 45%,transparent))}
.panel-body{flex:1;min-height:0;padding:20px clamp(16px,2.3vw,28px);overflow:auto}
.context-body{display:flex;flex-direction:column;align-items:flex-start;gap:0}
.context-collage{width:100%;height:154px;display:grid;grid-template-columns:1.14fr .86fr;gap:5px;margin-bottom:17px;overflow:hidden;perspective:800px}
.context-media{
  min-width:0;margin:0;overflow:hidden;background:var(--bg);position:relative;
  border-radius:4px;box-shadow:0 10px 22px -18px var(--shadow);
  transform:perspective(800px) rotateX(0) rotateY(0) scale(1);
  transition:transform .5s cubic-bezier(.16,1,.3,1),box-shadow .5s cubic-bezier(.16,1,.3,1);
  will-change:transform;
}
.context-media.is-tilting{transition:box-shadow .5s cubic-bezier(.16,1,.3,1)}
.context-media img{width:100%;height:100%;display:block;object-fit:cover;transition:transform .45s cubic-bezier(.16,1,.3,1),filter .3s ease}
.context-media-travel img{object-position:64% 57%}
.context-media-car img{object-position:54% 60%}
.context-media figcaption{position:absolute;inset:auto 0 0;margin:0;padding:6px 7px;background:color-mix(in srgb,var(--bg) 76%,transparent);color:var(--ink);font-family:var(--font-mono);font-size:.7rem;letter-spacing:.02em;line-height:1;text-transform:lowercase}
.context-media:hover,.context-media.is-tilting{box-shadow:0 18px 34px -18px color-mix(in srgb,var(--accent) 40%,var(--shadow))}
.context-media:hover img{transform:scale(1.08);filter:saturate(1.1)}
.context-title{margin:0;font-family:var(--font-display);font-size:1.36rem;font-weight:800;letter-spacing:-.03em}
.context-copy{display:flex;flex-direction:column;gap:7px;margin-top:5px;color:var(--ink-soft);font-size:.85rem;line-height:1.42}
.context-copy p{margin:0}
.context-interests{width:100%;display:flex;flex-direction:column;gap:11px;margin:16px 0 0;padding-top:15px;border-top:1px solid var(--border)}
.interest-row{display:flex;align-items:flex-start;gap:10px}
.interest-icon{flex:none;margin-top:3px}
.interest-icon-pin{width:10px;height:10px;border-radius:50% 50% 50% 0;background:var(--accent);transform:rotate(-45deg);box-shadow:0 0 6px color-mix(in srgb,var(--accent) 45%,transparent)}
.interest-icon-key{width:13px;height:9px;border:1.5px solid var(--accent);border-radius:3px;position:relative}
.interest-icon-key::after{content:"";position:absolute;left:50%;top:50%;width:5px;height:1.5px;background:var(--accent);transform:translate(-50%,-50%)}
.interest-text{min-width:0}
.interest-label{margin:0 0 2px;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.04em;text-transform:uppercase;color:var(--ink)}
.interest-copy{margin:0;color:var(--ink-soft);font-size:.8rem;line-height:1.4}
.context-tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:15px}
.context-tags span{
  padding:5px 9px;border-radius:999px;background:var(--accent);color:var(--accent-ink);
  font-family:var(--font-mono);font-size:.7rem;font-weight:600;line-height:1.1;
}
.trace-body{display:flex;flex-direction:column;gap:10px;overflow:hidden;background:color-mix(in srgb,var(--bg) 42%,transparent)}
.trace-intro{flex:none;margin:0;color:var(--ink-soft);font-size:.7rem;line-height:1.4;text-align:center}
.trace-intro span{color:var(--ink-soft)}
body.agent-thinking .trace-panel .panel-state{color:var(--accent)}

.terminal{
  flex:1;min-height:0;display:flex;flex-direction:column;
  border:1px solid var(--border);border-radius:8px;overflow:hidden;
  background:var(--surface);
  box-shadow:0 10px 26px -18px var(--shadow),0 0 0 1px transparent,0 0 0 transparent;
  transition:box-shadow .5s cubic-bezier(.16,1,.3,1),border-color .5s cubic-bezier(.16,1,.3,1);
}
body.agent-thinking .terminal{
  border-color:color-mix(in srgb,var(--accent) 55%,var(--border));
  box-shadow:0 10px 26px -18px var(--shadow),0 0 0 1px color-mix(in srgb,var(--accent) 40%,transparent);
}
.terminal-head{
  flex:none;display:flex;align-items:center;gap:6px;
  padding:8px 10px;
  background:linear-gradient(180deg,color-mix(in srgb,var(--ink) 7%,var(--surface)),color-mix(in srgb,var(--ink) 4%,var(--surface)));
  border-bottom:1px solid var(--border);
}
.terminal-dot{width:7px;height:7px;border-radius:50%;background:var(--ink-faint);opacity:.5}
.terminal-dot:nth-child(1){background:#e2564f;opacity:.85}
.terminal-dot:nth-child(2){background:#e2b04f;opacity:.85}
.terminal-dot:nth-child(3){background:#4fbf6b;opacity:.85}
.terminal-path{margin-left:6px;font-family:var(--font-mono);font-size:.64rem;letter-spacing:.02em;color:var(--ink-soft)}
.terminal-log{
  flex:1;min-height:0;overflow:hidden;padding:14px;
  display:flex;flex-direction:column;gap:10px;
  font-family:var(--font-mono);font-size:var(--term-log-size);line-height:1.5;
}
.term-line{margin:0;color:var(--ink-soft)}
.term-line.term-cmd{flex:none;color:var(--ink)}
.term-line.term-cmd::before{content:"$ ";color:var(--accent)}
.term-line.term-cmd.is-updating{animation:term-cmd-pulse .4s ease}
.term-cursor{display:inline-block;margin-left:1px;width:.5em;color:var(--accent);animation:term-blink 1s step-end infinite}
.term-cursor[hidden]{display:none}

/* One continuous, ever-growing log for the whole session — never cleared
   between questions. New lines are appended in normal flow right under the
   command and simply fill downward for the first five rows — full opacity,
   nothing moves. Only once a sixth line arrives does .has-overflowed switch
   on: JS drives scrollTop (scrollbar hidden) so it auto-advances like a real
   terminal, and the top mask fades whatever is about to scroll out of view. */
.term-viewport{flex:1;min-height:0;position:relative;overflow:hidden}
.term-stream{
  flex:none;
  height:calc(var(--term-rows) * 1.11rem + (var(--term-rows) - 1) * var(--term-line-gap));
  overflow-y:hidden;scroll-behavior:smooth;
  display:flex;flex-direction:column;gap:var(--term-line-gap);
}
.term-stream.has-overflowed{
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,black var(--term-mask-pct));
  mask-image:linear-gradient(to bottom,transparent 0,black var(--term-mask-pct));
}
.term-stream-line{
  flex:none;margin:0;color:var(--ink-soft);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.term-stream-line::before{content:"# ";color:var(--ink-faint)}
.term-stream-cursor{display:inline-block;margin-left:1px;width:.5em;color:var(--accent);animation:term-blink 1s step-end infinite}

/* The ASCII-art face: bare glyphs (no box/backdrop) pinned in the corner,
   not a real emoji — it never fully disappears once it's first appeared,
   it only morphs (a quick opacity dip, never to zero) between moods, and
   it visibly breathes and blinks while a reasoning burst is in flight
   (.is-thinking). Position, size and bob are all dev-tunable CSS vars. */
.term-reaction{
  position:absolute;left:var(--term-face-left);bottom:var(--term-face-bottom);margin:0;
  pointer-events:none;
  opacity:0;transform:translateY(6px) scale(.97);
  transition:opacity .4s cubic-bezier(.16,1,.3,1),transform .4s cubic-bezier(.16,1,.3,1);
}
.term-reaction.is-visible{opacity:1;transform:none}
.term-reaction.is-morphing{opacity:.62;transform:scale(.985)}
.term-reaction-face{
  display:inline-block;
  font-family:var(--font-mono);font-size:var(--term-face-size);line-height:1.12;white-space:pre;
  color:var(--ink-soft);transition:color .35s ease;
}
.term-reaction.is-thinking .term-reaction-face{
  color:var(--accent);
  animation-name:term-face-bob;
  animation-duration:var(--term-bob-dur);
  animation-timing-function:ease-in-out;
  animation-iteration-count:infinite;
}

@keyframes term-cmd-pulse{0%{color:var(--accent)}100%{color:var(--ink)}}
@keyframes term-blink{50%{opacity:0}}
@keyframes term-face-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(var(--term-bob-amp))}}
@media (prefers-reduced-motion: reduce){
  .term-line.term-cmd{animation:none}
  .term-stream{scroll-behavior:auto}
  .term-reaction{transition:none}
  .term-reaction.is-thinking .term-reaction-face{animation:none}
  .term-cursor,.term-stream-cursor{animation:none}
}

/* ── Chat shell ─────────────────────────────────────────── */
.chat{
  --spot-x:50%;--spot-y:30%;
  min-height:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  background-color:var(--bg);
  background-image:radial-gradient(620px circle at var(--spot-x) var(--spot-y),color-mix(in srgb,var(--accent) 6%,transparent),transparent 58%);
}
.mobile-view-note{display:none}

/* ── Start gate ─────────────────────────────────────────── */
/* Pre-JS, there's nothing to gate — the whole transcript already ships in
   the markup, so the gate stays hidden and .is-pending never hides anything
   (both rules below are scoped to .js). The gate itself has no background,
   so the chat pane's own ambient spotlight glow (see .chat) still shows
   through behind it instead of a flat blank layer. Deliberately NOT styled
   like the sidebar terminal — that motif stays put in .trace-panel; this is
   its own thing, closer in spirit to the landing page's constellation +
   glow than to a fake shell. */
.js .chat{position:relative}
.start-gate{
  display:none;
  position:absolute;inset:0;z-index:5;
  align-items:center;justify-content:center;
  padding:32px;
  overflow:hidden;
  transition:opacity .4s cubic-bezier(.16,1,.3,1),transform .4s cubic-bezier(.16,1,.3,1);
}
.js .chat.is-pending .start-gate{display:flex}
.js .chat.is-pending .transcript,
.js .chat.is-pending .dock{display:none}
.chat.is-starting .start-gate{opacity:0;transform:scale(.98);pointer-events:none}

/* A lighter cousin of index.html's canvas constellation — drifting,
   connected points contained to this box instead of the full viewport, with
   the same pointer-repel feel. Purely decorative: never intercepts clicks,
   and stops animating the moment the chat actually starts. */
.start-field{position:absolute;inset:0;z-index:0;opacity:.55;pointer-events:none}
@media (prefers-color-scheme:dark){.start-field{opacity:.7}}

.start-card{
  position:relative;z-index:1;isolation:isolate;
  width:min(100%,380px);
  padding:38px 30px 30px;
  border-radius:26px;
  display:flex;flex-direction:column;align-items:center;text-align:center;
  background:color-mix(in srgb,var(--surface) 78%,transparent);
  backdrop-filter:blur(20px) saturate(150%);
  -webkit-backdrop-filter:blur(20px) saturate(150%);
  box-shadow:0 34px 74px -30px var(--shadow);
  animation:start-card-arrive .7s .1s cubic-bezier(.16,1,.3,1) both;
}
/* A slow-turning gradient ring standing in for a border — masked to just
   the 1px edge so the glass fill in the middle stays untouched. */
.start-card::before{
  content:"";position:absolute;inset:-1px;z-index:-1;border-radius:inherit;padding:1px;
  background:conic-gradient(from var(--start-angle,0deg),
    color-mix(in srgb,var(--accent) 75%,transparent),
    transparent 28%,
    color-mix(in srgb,var(--accent) 45%,transparent) 55%,
    transparent 82%,
    color-mix(in srgb,var(--accent) 75%,transparent));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  animation:start-border-spin 7s linear infinite;
}
@property --start-angle{syntax:'<angle>';inherits:false;initial-value:0deg}
@keyframes start-border-spin{to{--start-angle:360deg}}
@keyframes start-card-arrive{from{opacity:0;transform:translateY(16px) scale(.94)}to{opacity:1;transform:none}}

.start-orb{position:relative;width:76px;height:76px;margin-bottom:18px;display:flex;align-items:center;justify-content:center}
.start-avatar{width:100%;height:100%;position:relative;z-index:1}
.start-orb-ring{
  position:absolute;inset:0;border-radius:50%;pointer-events:none;
  border:1.5px solid color-mix(in srgb,var(--accent) 55%,transparent);
  animation:start-orb-ping 2.6s cubic-bezier(.2,.7,.4,1) infinite;
}
.start-orb-ring-2{animation-delay:1.3s}
@keyframes start-orb-ping{0%{transform:scale(1);opacity:.7}100%{transform:scale(1.9);opacity:0}}

.start-eyebrow{
  margin:0;display:flex;align-items:center;justify-content:center;gap:7px;
  font-family:var(--font-mono);font-size:.7rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);
}
.start-eyebrow .agent-dot{animation:agent-signal 2.2s cubic-bezier(.16,1,.3,1) infinite}
.start-title{margin:8px 0 0;font-family:var(--font-display);font-weight:800;font-size:1.4rem;letter-spacing:-.02em}
.start-copy{margin:10px 0 22px;color:var(--ink-soft);font-size:.88rem;line-height:1.55}

.start-btn{
  position:relative;overflow:hidden;isolation:isolate;
  display:inline-flex;align-items:center;gap:8px;
  padding:13px 26px;border-radius:999px;border:none;
  background:var(--accent);color:var(--accent-ink);
  font:inherit;font-size:.92rem;font-weight:700;
  cursor:pointer;
  box-shadow:0 18px 38px -18px color-mix(in srgb,var(--accent) 78%,transparent);
  transition:transform .3s cubic-bezier(.22,1,.36,1),box-shadow .3s ease;
}
/* Same cursor-tracked wave used on the .chip tray — reused verbatim via
   --wave-x/--wave-y so the two feel like one system, not two buttons. */
.start-btn::before{
  content:"";position:absolute;inset:0;z-index:0;opacity:0;pointer-events:none;
  background:radial-gradient(120px circle at var(--wave-x,50%) var(--wave-y,50%),color-mix(in srgb,var(--accent-ink) 26%,transparent),transparent 68%);
  transition:opacity .3s ease;
}
.start-btn:hover::before{opacity:1}
.start-btn>*{position:relative;z-index:1}
.start-btn:hover{transform:translateY(-2px);box-shadow:0 22px 42px -16px color-mix(in srgb,var(--accent) 78%,transparent)}
.start-btn:active{transform:translateY(0) scale(.98)}
.start-btn svg{width:16px;height:16px;transition:transform .3s cubic-bezier(.22,1,.36,1)}
.start-btn:hover svg{transform:translateX(3px)}

.start-hint{margin:16px 0 0;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.03em;color:var(--ink-soft)}

@media (prefers-reduced-motion:reduce){
  .start-gate{transition:none}
  .start-field{display:none}
  .start-card,.start-card::before,.start-orb-ring,.start-eyebrow .agent-dot{animation:none}
  .start-btn,.start-btn svg,.start-btn::before{transition:none}
}

.transcript{
  flex:1;
  min-height:0;
  width:100%;
  display:flex;
  flex-direction:column;
  overflow-y:auto;
  overscroll-behavior:contain;
  scroll-padding-block:32px;
  padding:32px clamp(16px,4vw,32px) 28px;
}
/* A short conversation sits near the composer, like a real chat — not
   stranded at the top with a dead gap above the dock. margin-top:auto
   absorbs the slack while the transcript is shorter than the viewport;
   once it overflows, the margin collapses to 0 and normal scrolling takes
   over (the standard flexbox bottom-anchored-scroller pattern). */
.transcript-inner{width:min(100%,780px);margin:auto auto 0;display:flex;flex-direction:column;gap:var(--msg-gap)}

.turn{display:flex;flex-direction:column;gap:14px}

/* Pre-JS: every turn ships fully in the markup (no-script readers get the
   whole transcript at once). Once JS runs, messages start hidden and are
   revealed one at a time as their question is picked. */
.js .msg{display:none}
/* An unrevealed turn still sits in the flex flow even with display:none
   children, so it was picking up a full flex `gap` on either side of it —
   with 6 topics unrevealed at once, that's several turns worth of dead
   space before any question is asked. Drop the turn itself out of flow
   until it actually has something visible in it. */
.js .turn:not(:has(.msg-visible)){display:none}
.js .msg.msg-visible{display:flex;will-change:transform,opacity;animation:message-arrive .9s cubic-bezier(.16,1,.3,1) both}
.msg-user.msg-visible{--message-x:28px}
.msg-bot.msg-visible{--message-x:-28px;animation-delay:80ms}
@media (prefers-reduced-motion:reduce){.js .msg.msg-visible{animation:message-fade .2s ease-out both}}
@keyframes message-arrive{0%{opacity:0;transform:translate3d(var(--message-x,0),24px,0) scale(.92)}58%{opacity:1;transform:translate3d(0,-3px,0) scale(1.012)}78%{transform:translate3d(0,1px,0) scale(.998)}100%{opacity:1;transform:translate3d(0,0,0) scale(1)}}
@keyframes message-fade{from{opacity:0}to{opacity:1}}

.msg{max-width:min(84%,620px);display:flex;flex-direction:column;gap:7px}
.msg p{margin:0}
.msg p + p{margin-top:.6em}

.msg-user{align-self:flex-end;align-items:flex-end;margin-left:clamp(28px,8vw,120px)}
.msg::before{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.08em;color:var(--ink-soft);line-height:1;text-transform:uppercase}
.msg-user::before{content:"You"}
.msg-user .bubble{
  background:var(--accent);color:var(--accent-ink);
  border-radius:var(--bubble-radius) var(--bubble-radius) 5px var(--bubble-radius);
  box-shadow:0 16px 34px -18px color-mix(in srgb,var(--accent) 78%,transparent);
}
.msg-bot{align-self:flex-start;margin-right:clamp(28px,8vw,120px)}
.msg-bot:focus{outline:none}
.msg-bot::before{content:"Profile guide"}
.msg-bot .bubble{
  background:var(--surface);color:var(--ink);
  border:1px solid var(--border);
  border-radius:5px var(--bubble-radius) var(--bubble-radius) var(--bubble-radius);
  box-shadow:0 16px 34px -22px var(--shadow);
}
.bubble{
  padding:var(--bubble-pad-y) var(--bubble-pad-x);
  font-size:1rem;line-height:1.6;
}

/* ── Structured answer content ─────────────────────────────── */
.roles{display:flex;flex-direction:column;gap:20px;margin-top:14px;position:relative;padding-left:22px}
.roles::before{content:"";position:absolute;left:4px;top:6px;bottom:6px;width:1.5px;background:var(--border-strong)}
.role{position:relative}
.role::before{
  content:"";position:absolute;left:-22px;top:4px;width:9px;height:9px;border-radius:50%;
  background:var(--surface);border:2px solid var(--border-strong);
}
.role:first-child::before{
  background:var(--accent);border-color:var(--accent);
  box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 22%,transparent);
}
.role-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap}
.role-title{font-family:var(--font-display);font-weight:800;font-size:1rem;letter-spacing:-.01em}
.role-dates{font-family:var(--font-mono);font-size:.72rem;color:var(--ink-soft);white-space:nowrap}
.role-company{font-size:.85rem;color:var(--ink-soft);margin-top:1px}
.role p{font-size:.9rem;color:var(--ink-soft);margin-top:6px}
.role-steps{display:flex;flex-direction:column;gap:5px;margin-top:8px}
.role-step{font-size:.87rem}
.role-step b{font-weight:700}

.pill-current{
  font-family:var(--font-mono);font-size:.7rem;letter-spacing:.05em;font-weight:600;
  background:var(--accent);color:var(--accent-ink);
  border-radius:999px;padding:3px 8px;white-space:nowrap;
  box-shadow:0 6px 14px -10px color-mix(in srgb,var(--accent) 70%,transparent);
}

.certs{display:flex;flex-direction:column;gap:10px;margin-top:10px}
.certs + p{margin-top:12px}
.cert{
  display:flex;align-items:center;flex-wrap:wrap;gap:13px;row-gap:6px;
  padding:10px;border:1px solid var(--border);border-radius:12px;
  transition:transform .3s cubic-bezier(.22,1,.36,1),border-color .3s ease,box-shadow .3s ease;
}
a.cert{cursor:pointer;text-decoration:none;color:inherit}
a.cert:hover,a.cert:focus-visible{
  border-color:var(--accent);transform:translateY(-2px);
  box-shadow:0 14px 30px -20px color-mix(in srgb,var(--accent) 65%,transparent);
}
.cert img{width:46px;height:46px;object-fit:contain;border-radius:8px;flex:none;background:var(--surface-soft);transition:transform .35s cubic-bezier(.22,1,.36,1)}
a.cert:hover img{transform:scale(1.08)}
/* A real minimum, not 0 — 0 let the state pill's width squeeze this to
   nothing at narrow widths, and the name/issuer text would then overflow
   right on top of the pill instead of truncating. flex-wrap on .cert means
   a too-narrow row wraps the pill onto its own line instead. */
.cert-body{min-width:160px;flex:1 1 160px}
.cert-name{font-weight:750;font-size:.9rem}
.cert-issuer{font-size:.78rem;color:var(--ink-soft)}
.cert-state{
  font-family:var(--font-mono);font-size:.7rem;letter-spacing:.05em;
  border-radius:999px;padding:3px 8px;flex:none;white-space:nowrap;
  margin-left:auto;
}
.cert-state.is-active{background:var(--accent);color:var(--accent-ink);font-weight:600}
.cert-state.is-queued{background:var(--surface-soft);color:var(--ink-soft)}
.cert-state.is-skipped{background:transparent;color:var(--ink-soft);border:1px dashed var(--border-strong)}
.cert-verify{
  font-family:var(--font-mono);font-size:.7rem;letter-spacing:.05em;
  color:var(--accent);flex:none;text-decoration:none;
}
.cert-verify:hover{text-decoration:underline}

.groups{display:flex;flex-direction:column;gap:12px;margin-top:10px}
.group-name{font-family:var(--font-display);font-weight:700;font-size:.88rem}
.group p{font-size:.88rem;color:var(--ink-soft);margin-top:3px}

.links{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}

.typing{
  align-self:flex-start;display:flex;align-items:center;gap:4px;padding:14px 16px;
  background:var(--surface);border:1px solid var(--border);border-radius:4px 18px 18px 18px;
  opacity:0;transform:translate3d(-18px,12px,0) scale(.94);
  animation:typing-arrive .64s cubic-bezier(.16,1,.3,1) both;
  transition:opacity .48s cubic-bezier(.16,1,.3,1),transform .48s cubic-bezier(.16,1,.3,1);
}
.typing.is-leaving{opacity:0;transform:translateY(-4px) scale(.94);animation:none}
.typing span{width:6px;height:6px;border-radius:50%;background:var(--ink-faint);display:block}
@keyframes typing-arrive{0%{opacity:0;transform:translate3d(-18px,12px,0) scale(.94)}65%{opacity:1;transform:translate3d(0,-2px,0) scale(1.025)}100%{opacity:1;transform:translate3d(0,0,0) scale(1)}}
@media (prefers-reduced-motion:no-preference){
  .typing span{animation:typing-pulse 1.55s cubic-bezier(.4,0,.2,1) infinite}
  .typing span:nth-child(2){animation-delay:.18s}
  .typing span:nth-child(3){animation-delay:.36s}
}
@keyframes typing-pulse{0%,60%,100%{transform:translateY(0);opacity:.5}30%{transform:translateY(-4px);opacity:1}}
@media (prefers-reduced-motion:reduce){
  .typing{animation:none;opacity:1;transform:none}
  .typing.is-leaving{transition:none;opacity:0}
}

/* ── Chip tray + composer dock ─────────────────────────────── */
.dock{flex:none;width:100%;display:flex;flex-direction:column;align-items:center;padding:14px clamp(16px,4vw,32px) clamp(16px,3vw,24px);border-top:1px solid var(--border);background:color-mix(in srgb,var(--bg) 94%,var(--surface))}
.dock-inner{width:var(--shell)}

.chips{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;margin-bottom:12px}
.chip{
  position:relative;
  width:100%;min-height:52px;
  padding:12px 42px 12px 16px;
  border-radius:14px;
  background:var(--surface);
  border:1px solid var(--border-strong);
  color:var(--ink);
  font-size:.87rem;font-weight:650;line-height:1.25;text-align:left;
  cursor:pointer;overflow:hidden;isolation:isolate;
  transition:transform .3s cubic-bezier(.22,1,.36,1),border-color .3s ease,background .3s ease,color .3s ease,box-shadow .3s ease;
}
.chip::before{
  content:"";position:absolute;inset:0;z-index:0;opacity:0;pointer-events:none;
  background:radial-gradient(140px circle at var(--wave-x,50%) var(--wave-y,50%),color-mix(in srgb,var(--accent-ink) 24%,transparent),transparent 68%);
  transition:opacity .3s ease;
}
.chip::after{
  content:"";position:absolute;right:16px;top:50%;width:7px;height:7px;
  border-top:1.5px solid currentColor;border-right:1.5px solid currentColor;
  transform:translateY(-50%) rotate(45deg);opacity:.45;
  transition:transform .3s cubic-bezier(.22,1,.36,1),opacity .3s ease;
}
.chip:hover{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);transform:translateY(-3px) scale(1.008);box-shadow:0 16px 30px -16px color-mix(in srgb,var(--accent) 70%,transparent)}
.chip:hover::before{opacity:1}
.chip:hover::after{opacity:.8;transform:translate(2px,-50%) rotate(45deg)}
.chip:active{transform:translateY(0) scale(.99)}
.chip:disabled{cursor:default}
.chips.is-resolving .chip:not(.is-active){opacity:.38;transform:scale(.985)}
.chip.is-active{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);transform:translateY(-3px);box-shadow:0 16px 30px -16px color-mix(in srgb,var(--accent) 70%,transparent)}
.chip.is-active::after{opacity:.8;transform:translate(2px,-50%) rotate(45deg)}
@media (prefers-reduced-motion:no-preference){.chips:not(.is-resolving) .chip{animation:prompt-arrive .56s calc(var(--chip-index) * 75ms) cubic-bezier(.22,1,.36,1) both}}
@keyframes prompt-arrive{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.chip-restart{grid-column:1/-1;padding-right:14px;background:var(--accent);color:var(--accent-ink);border-color:transparent;text-align:center}
.chip-restart::after{display:none}
.chip-restart:hover,.chip-restart:focus-visible{color:var(--accent-ink);border-color:transparent;opacity:.92}

.composer{
  display:flex;align-items:center;gap:10px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--dock-radius);
  padding:6px 6px 6px 16px;
  transition:border-color .36s ease,box-shadow .36s ease;
}
.composer.is-composing{border-color:var(--accent);box-shadow:0 14px 32px -18px color-mix(in srgb,var(--accent) 55%,transparent),0 0 0 3px color-mix(in srgb,var(--accent) 14%,transparent)}
.composer-field{
  flex:1;min-height:26px;
  font-size:.9rem;color:var(--ink-faint);
  white-space:nowrap;overflow:hidden;
}
.composer-field.is-typing{color:var(--ink)}
.composer-caret{display:inline-block;width:1px;height:1em;background:var(--ink);margin-left:1px;vertical-align:-2px;opacity:0}
.composer-field.is-typing .composer-caret{opacity:1;animation:caret 1.4s step-end infinite}
@keyframes caret{50%{opacity:0}}
.composer-send{
  width:36px;height:36px;border-radius:50%;flex:none;
  background:var(--surface-soft);color:var(--ink-faint);
  display:flex;align-items:center;justify-content:center;
  transition:background .36s ease,color .36s ease,transform .36s cubic-bezier(.22,1,.36,1);
}
.composer.is-composing .composer-send{background:var(--accent);color:var(--accent-ink);transform:translateY(-1px) scale(1.05);box-shadow:0 8px 18px -10px color-mix(in srgb,var(--accent) 60%,transparent)}
.composer-send svg{width:16px;height:16px}

.done-note{font-family:var(--font-mono);font-size:.72rem;color:var(--ink-soft);text-align:center;margin-top:2px}

/* ── Themed browser surfaces ────────────────────────────────── */
.transcript{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
.transcript::-webkit-scrollbar{width:9px}
.transcript::-webkit-scrollbar-track{background:transparent}
.transcript::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:99px;border:2px solid var(--bg)}
.transcript::-webkit-scrollbar-thumb:hover{background:var(--accent)}

.context-toggle{display:none}

@media (max-width:860px){
  /* Explicit rows, not just columns: with .context-toggle now permanently in
     the grid alongside whichever of {sidebar, chat} is visible, undefined
     (auto) row tracks let the two auto-sized rows fight over the fixed
     .ai-workbench height unpredictably. Pin it down instead. */
  .ai-workbench{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr)}
  .transcript-inner{width:var(--shell)}

  /* The fixed-height two-row sidebar is built for a viewport-filling desktop
     workbench; on a phone it would starve the chat of space. Below this
     width the terminal panel (already aria-hidden, purely decorative) stays
     out, and the personal-context panel — photos and the "Beyond the
     terminal" copy — is reachable through .context-toggle instead of being
     dropped outright. */
  .context-toggle{
    display:flex;align-items:center;justify-content:center;gap:8px;
    width:100%;padding:11px 16px;border:0;border-bottom:1px solid var(--border);
    background:var(--surface-soft);color:var(--ink-soft);
    font-family:var(--font-mono);font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;
    cursor:pointer;min-height:44px;
  }
  .context-toggle svg{width:14px;height:14px;transition:transform .25s ease}
  .context-toggle[aria-expanded="true"] svg{transform:rotate(180deg)}
  /* .ai-workbench fills a fixed 100dvh app shell (see body, above) — it
     doesn't grow with content. So the expanded sidebar can't just reflow to
     its natural height like a normal block; it has to take over the same
     fixed box the chat uses (hidden via .is-hidden-mobile, in JS) and scroll
     internally, exactly like the desktop sidebar already does. */
  .workspace-sidebar{
    display:none;
    border-right:0;border-bottom:1px solid var(--border);
  }
  .workspace-sidebar.is-expanded{
    display:grid;
    grid-template-rows:minmax(0,1fr);
  }
  .workspace-sidebar .trace-panel{display:none}
  .workspace-sidebar .panel-body{overflow:auto}
  .chat.is-hidden-mobile{display:none}
}
@media (max-width:700px){
  /* Quiet on purpose: this runs for the whole session (not a one-time
     toast), so it stays out of the accent's way — that's reserved for
     things the visitor is actually choosing, not a standing disclaimer. */
  .mobile-view-note{
    display:block;width:100%;margin:0;padding:7px 16px;
    background:var(--surface-soft);color:var(--ink-soft);
    border-bottom:1px solid var(--border);
    font-family:var(--font-mono);font-size:.7rem;letter-spacing:.02em;line-height:1.4;text-align:center;
  }
  .transcript{scroll-padding-block:20px;padding:20px 16px 18px}
  .msg{max-width:94%;margin-left:0;margin-right:0}
  .bubble{font-size:.94rem}
  .dock{padding:9px 0 max(10px,env(safe-area-inset-bottom))}
  .dock-inner{width:100%}
  .chips{
    display:flex;gap:8px;margin:0 0 9px;padding:0 16px 3px;
    overflow-x:auto;overscroll-behavior-inline:contain;scroll-snap-type:inline mandatory;
    scrollbar-width:none;
  }
  .chips::-webkit-scrollbar{display:none}
  .chip{flex:0 0 min(76vw,300px);min-height:50px;scroll-snap-align:start}
  .chip-restart{flex-basis:calc(100% - 32px)}
  .composer{margin:0 16px;padding-left:14px}
}
@media (max-width:420px){
  .msg{max-width:94%;margin-left:0;margin-right:0}
  .bubble{font-size:.92rem}
  .chip{flex-basis:82vw}
}
@media (prefers-reduced-motion:reduce){
  .chip{transition:none}
}
