/* ============================================================
   Kova — calm chat for a real Anthropic-compatible endpoint
   tokens · shell · thread · composer · settings · overlays
   ============================================================ */

:root{
  --sans:"Instrument Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
  --serif:"Instrument Serif",Georgia,"Times New Roman",serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --read-font:var(--sans);          /* Interface → font */

  --bg:#F2EFE7;
  --canvas:#FAF8F3;
  --surface:#FFFEFB;
  --surface-2:#F3F0E8;
  --surface-3:#EAE5DB;
  --ink:#211F1A;
  --ink-2:#56514A;
  --ink-3:#8B857B;
  --ink-4:#B3ADA2;
  --line:rgba(var(--ink-rgb),.085);
  --line-2:rgba(var(--ink-rgb),.16);
  --accent:#3D5C4C;
  --accent-2:#547A66;
  --accent-soft:rgba(61,92,76,.085);
  --accent-line:rgba(61,92,76,.24);
  --danger:#A3463A;
  --danger-soft:rgba(163,70,58,.08);
  --danger-ink:var(--danger-ink);
  --on-accent:var(--on-accent);              /* text on a filled accent button */
  --ink-rgb:33,31,26;               /* every translucent ink in this file */
  /* Shadows must be darker than what they fall on. --ink-rgb is the ink, which
     inverts in dark mode — using it here turned every shadow into a white glow
     around the element. This token is black in both themes. */
  --shade-rgb:0,0,0;
  --canvas-rgb:250,248,243;
  --surface-rgb:255,254,251;
  --surface-hi:var(--surface-hi);             /* drag-over tint */
  --scroll-thumb:rgba(var(--ink-rgb),.14);
  --scroll-thumb-hover:rgba(var(--ink-rgb),.24);
  --avatar-a:var(--avatar-a);--avatar-b:var(--avatar-b);--avatar-ink:var(--avatar-ink);
  --tok-key:var(--tok-key);--tok-str:var(--tok-str);--tok-num:var(--tok-num);--tok-fn:var(--tok-fn);
  --warn-dot:var(--warn-dot);

  --r-sm:8px; --r-md:12px; --r-lg:16px;
  --shadow-1:0 1px 2px rgba(var(--ink-rgb),.04),0 6px 18px -14px rgba(var(--ink-rgb),.28);
  --shadow-2:0 2px 6px rgba(var(--ink-rgb),.05),0 26px 56px -22px rgba(var(--ink-rgb),.34);
  --ease:cubic-bezier(.22,1,.36,1);

  --sidebar-w:258px;
  --thread-w:720px;
  --read-size:15px;
}

/* ------------------------------- dark ---------------------------------
   The same page at night: warm ink instead of warm paper, the same green
   accent lifted a little so it still reads against a dark ground.
   ---------------------------------------------------------------------- */
html[data-theme="dark"]{
  --bg:#141412;
  --canvas:#191917;
  --surface:#201F1C;
  --surface-2:#262521;
  --surface-3:#2E2C27;
  --ink:#EDE9E0;
  --ink-2:#B5AFA3;
  --ink-3:#8A8478;
  --ink-4:#6B665C;
  --line:rgba(237,233,224,.085);
  --line-2:rgba(237,233,224,.16);
  --accent:#7FAE95;
  --accent-2:#95C2A9;
  --accent-soft:rgba(127,174,149,.12);
  --accent-line:rgba(127,174,149,.3);
  --danger:#E08B7C;
  --danger-soft:rgba(224,139,124,.1);
  --danger-ink:#F0B4A8;
  --on-accent:#12201A;
  --ink-rgb:237,233,224;
  --canvas-rgb:25,25,23;
  --surface-rgb:32,31,28;
  --surface-hi:#232521;
  --scroll-thumb:rgba(237,233,224,.14);
  --scroll-thumb-hover:rgba(237,233,224,.24);
  --avatar-a:#3A3730;--avatar-b:#2C2A25;--avatar-ink:#D8D2C4;
  --tok-key:#E3A887;--tok-str:#9CC9A8;--tok-num:#D9B37E;--tok-fn:#9FBBD6;
  --warn-dot:#D8A46C;
  --code-ink:#E3A887;
  --code-block-ink:#D6D0C4;
  --shadow-1:0 1px 2px rgba(0,0,0,.3),0 6px 18px -14px rgba(0,0,0,.6);
  --shadow-2:0 2px 6px rgba(0,0,0,.36),0 26px 56px -22px rgba(0,0,0,.7);
}

*,*::before,*::after{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--canvas);color:var(--ink);
  font:400 var(--read-size)/1.68 var(--read-font);
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;letter-spacing:-.006em;overflow:hidden;
}
::selection{background:rgba(61,92,76,.15)}
button,input,textarea,select{font:inherit;color:inherit;letter-spacing:inherit}
button{background:none;border:0;padding:0;cursor:pointer}
a{color:var(--accent);text-decoration:underline;text-decoration-color:var(--accent-line);text-underline-offset:2px}
img{max-width:100%}
svg{display:block;flex:none}
:focus-visible{outline:2px solid rgba(61,92,76,.45);outline-offset:2px;border-radius:6px}
button:focus:not(:focus-visible){outline:none}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border-radius:999px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--scroll-thumb-hover);background-clip:content-box}

.grain{
  position:fixed;inset:0;z-index:400;pointer-events:none;opacity:.4;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.05'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.hide-sm{display:inline}

/* ============================== shell ============================== */
/* the shell is a column now: site bar, then the app filling what is left.
   100dvh on #app alone would push the bar out of the viewport. */
body{display:flex;flex-direction:column}
#app{display:grid;grid-template-columns:var(--sidebar-w) minmax(0,1fr);flex:1;min-height:0;height:auto}
#app.rail-collapsed{grid-template-columns:0 minmax(0,1fr)}
#app.rail-collapsed .sidebar{transform:translateX(-12px);opacity:0;pointer-events:none}

.sidebar{
  position:relative;z-index:30;display:flex;flex-direction:column;min-height:0;
  background:var(--bg);
  border-right:1px solid var(--line);
  padding:12px 10px 10px;gap:11px;
  transition:transform .34s var(--ease),opacity .22s ease;
}
/* The join with the bar flares *outward*. Rounding the panel's own corner cut
   a bite out of it; this draws the opposite arc instead — a quarter-circle of
   canvas that sweeps from the panel's right edge into the bar, so the panel
   reads as growing out of the bar rather than being notched into it. The arc
   is tangent at both ends, so there is no seam: it meets the panel's edge
   vertically and the bar's edge horizontally.
   Its radius must stay under the rail's 12px bottom padding, or it would sit
   on top of the first row of controls. */
.sidebar::after{
  content:"";position:absolute;left:100%;top:0;width:12px;height:12px;
  background:radial-gradient(circle 12px at 100% 100%,
    transparent 0 10.6px, var(--line) 10.6px 11.7px, var(--bg) 11.7px);
  pointer-events:none;
}
/* a hidden rail has nothing to join */
#app.rail-collapsed .sidebar::after{content:none}
.sidebar-top{display:flex;align-items:center;gap:8px;padding:2px 4px 0 6px;height:36px}
.brand{display:flex;align-items:center;gap:9px;margin-right:auto;min-width:0}
.brand-mark{width:25px;height:25px;border-radius:8px;background:var(--accent);display:grid;place-items:center;color:var(--on-accent);box-shadow:inset 0 1px 0 rgba(255,255,255,.14)}
/* the GlitchyAPI mark replaces the drawn plate: no tile behind it, just the
   whale, flipped to pale ink on the dark surface where black would vanish */
.brand-mark--logo{background:none;border-radius:0;box-shadow:none;color:inherit}
.brand-mark--logo img{width:21px;height:21px;display:block;object-fit:contain;opacity:.92}
html[data-theme="dark"] .brand-mark--logo img{filter:invert(1) brightness(1.85);opacity:.8}
.brand-name{font-family:var(--serif);font-size:21px;line-height:1;padding-top:1px}

.new-chat{
  display:flex;align-items:center;gap:9px;width:100%;height:37px;padding:0 10px;
  border:1px solid var(--line-2);border-radius:11px;background:var(--surface);
  font-size:13.5px;font-weight:500;box-shadow:var(--shadow-1);
  transition:border-color .18s ease,transform .18s var(--ease);
}
.new-chat:hover{border-color:rgba(var(--ink-rgb),.26);transform:translateY(-1px)}
.new-chat:active{transform:none}
.new-chat .kbd{margin-left:auto}
.kbd{font:500 10px/1 var(--mono);color:var(--ink-3);background:var(--surface-2);border:1px solid var(--line);border-radius:5px;padding:3px 5px}

.side-search{display:flex;align-items:center;gap:9px;height:32px;padding:0 9px;border-radius:9px;color:var(--ink-3);font-size:12.8px;transition:background .16s,color .16s}
.side-search:hover{background:rgba(var(--ink-rgb),.045);color:var(--ink-2)}
.side-search .kbd{margin-left:auto;font-size:9.5px;padding:2.5px 4px}

.side-scroll{flex:1;min-height:0;overflow-y:auto;margin:0 -4px;padding:0 4px 6px}
.side-group{margin-top:13px}
.side-group:first-child{margin-top:2px}
.side-label{display:flex;align-items:center;justify-content:space-between;font:500 9.6px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-4);padding:0 8px 7px}
.side-label span:last-child{opacity:.42}

.chat-item{position:relative;display:flex;align-items:center;gap:8px;height:33px;padding:0 8px;border-radius:9px;cursor:pointer;font-size:13px;color:var(--ink-2);transition:background .15s,color .15s}
.chat-item .t{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.chat-item:hover{background:rgba(var(--ink-rgb),.05);color:var(--ink)}
.chat-item.active{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-1),inset 0 0 0 1px var(--line)}
.chat-item.active::before{content:"";position:absolute;left:-10px;top:11px;width:3px;height:11px;border-radius:2px;background:var(--accent);opacity:.9}
.chat-item .more{opacity:0;width:22px;height:22px;border-radius:6px;display:grid;place-items:center;color:var(--ink-3);flex:none;margin-left:-2px}
.chat-item:hover .more,.chat-item.menu-open .more{opacity:1}
.chat-item .more:hover{background:rgba(var(--ink-rgb),.08);color:var(--ink)}
.chat-item .rename{flex:1;min-width:0;border:1px solid var(--accent-line);border-radius:6px;background:var(--surface);padding:2px 6px;font-size:12.8px;height:24px}
.chat-item .dot-live{width:5px;height:5px;border-radius:50%;background:var(--accent);flex:none;box-shadow:0 0 0 3px var(--accent-soft);animation:pulse 2s infinite}
.side-empty{padding:22px 10px;font-size:12.4px;color:var(--ink-4);line-height:1.55}

.side-foot{border-top:1px solid var(--line);padding:10px 2px 0;margin:0 -2px}

.rail-btn{width:28px;height:28px;border-radius:7px;display:grid;place-items:center;color:var(--ink-3);transition:background .15s,color .15s;flex:none}
.rail-btn:hover{background:rgba(var(--ink-rgb),.06);color:var(--ink)}

/* ============================== main ============================== */
.main{position:relative;display:flex;flex-direction:column;min-width:0;height:100%;min-height:0;background:var(--canvas)}
/* There is no chat header. The controls that used to live in one are gone or
   moved: the theme switch went with the header, the reading font lives in
   Settings, chat options live on each row's own menu. What is left is the
   floating "controls" cluster in the top-right corner of the thread. */
.chat-tools{
  position:absolute;top:10px;right:12px;z-index:25;
  display:flex;align-items:center;gap:2px;
}

.ghost-btn{display:inline-flex;align-items:center;gap:6px;height:29px;padding:0 9px;border-radius:8px;color:var(--ink-3);font-size:12.4px;font-weight:500;transition:background .15s,color .15s,border-color .15s;border:1px solid transparent}
.ghost-btn:hover{background:rgba(var(--ink-rgb),.055);color:var(--ink)}
.ghost-btn.on{background:var(--accent-soft);color:var(--accent);border-color:rgba(61,92,76,.16)}
.think-toggle .ti{opacity:.55;transition:opacity .15s}
.think-toggle.on .ti{opacity:1}
/* the fineprint is a keyboard hint — hide it where there is no hardware keyboard */
@media (max-width:640px){ .fineprint{display:none} }
.icon-btn{width:30px;height:30px;border-radius:8px;display:inline-grid;place-items:center;color:var(--ink-3);transition:background .15s,color .15s}
.icon-btn:hover{background:rgba(var(--ink-rgb),.055);color:var(--ink)}
.icon-btn.sm{width:26px;height:26px;border-radius:7px}

/* ============================== thread ============================== */
.thread{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;scroll-behavior:smooth;overflow-anchor:none}
.thread-inner{max-width:var(--thread-w);margin:0 auto;padding:86px 24px 220px}

/* empty state */
.empty{max-width:560px;margin:0 auto;padding:max(20px,6vh) 0 0;animation:rise .5s var(--ease) both}
.empty-mark{width:38px;height:38px;border-radius:11px;background:var(--accent);display:grid;place-items:center;color:var(--on-accent);margin-bottom:22px;box-shadow:0 8px 24px -12px rgba(61,92,76,.55),inset 0 1px 0 rgba(255,255,255,.16)}
.empty h1{font-family:var(--serif);font-weight:400;font-size:clamp(28px,3.6vw,38px);line-height:1.1;letter-spacing:-.012em;margin:0 0 10px}
.empty h1 em{font-style:italic;color:var(--accent)}
.empty p.sub{margin:0 0 24px;color:var(--ink-3);font-size:13.8px;max-width:44ch;line-height:1.62}
.suggestions{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.sug{display:flex;align-items:flex-start;gap:10px;padding:12px;border:1px solid var(--line);border-radius:12px;background:linear-gradient(180deg,rgba(var(--surface-rgb),.7),rgba(var(--surface-rgb),.32));text-align:left;transition:.2s var(--ease)}
.sug:hover{border-color:var(--accent-line);background:var(--surface);transform:translateY(-2px);box-shadow:var(--shadow-1)}
.sug .ico{width:24px;height:24px;border-radius:7px;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;flex:none;margin-top:1px}
.sug>span:last-child{display:flex;flex-direction:column;min-width:0}
.sug .t{display:block;font-size:13px;font-weight:500;line-height:1.35}
.sug .d{display:block;font-size:11.8px;color:var(--ink-3);line-height:1.45;margin-top:2px}
.empty-note{display:flex;align-items:center;gap:7px;margin-top:22px;font-size:11.6px;color:var(--ink-4)}
.empty-note kbd{font:500 9.6px/1 var(--mono);border:1px solid var(--line-2);border-radius:4px;padding:3px 4px;color:var(--ink-3);background:var(--surface)}

/* messages */
.msg{position:relative;animation:rise .4s var(--ease) both}
.msg + .msg{margin-top:26px}
.msg--user{display:flex;justify-content:flex-end;margin-top:30px}
.u-col{display:flex;flex-direction:column;align-items:flex-end;max-width:84%}
.bubble{
  background:var(--surface);border:1px solid var(--line);border-radius:15px 15px 5px 15px;
  padding:9px 13px 10px;font-size:14.4px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere;
  box-shadow:var(--shadow-1);
}
.bubble img{display:block;width:74px;height:74px;object-fit:cover;border-radius:8px;border:1px solid var(--line);margin-bottom:8px}
.msg-time{font:500 9.6px/1 var(--mono);color:var(--ink-4);margin-top:5px;opacity:0;transition:opacity .18s;letter-spacing:.03em}

.ai-body{font-size:var(--read-size);line-height:1.74;letter-spacing:-.004em;overflow-wrap:break-word}
.ai-body > *:first-child{margin-top:0}
.ai-body > *:last-child{margin-bottom:0}
.ai-body p{margin:0 0 13px}
.ai-body strong{font-weight:600}
.ai-body h3{font-size:15.6px;font-weight:600;letter-spacing:-.012em;margin:24px 0 9px;display:flex;align-items:center;gap:8px}
.ai-body h3::before{content:"";width:3px;height:13px;border-radius:2px;background:var(--accent);opacity:.55;flex:none}
.ai-body h4{font-size:14.2px;font-weight:600;margin:20px 0 7px;letter-spacing:-.01em}
.ai-body ul,.ai-body ol{list-style:none;margin:0 0 14px;padding:0}
.ai-body li{position:relative;padding-left:19px;margin:6px 0;line-height:1.7}
.ai-body ul > li::before{content:"";position:absolute;left:4px;top:.72em;width:5px;height:5px;border-radius:50%;background:var(--accent);opacity:.42}
.ai-body ol{counter-reset:n}
.ai-body ol > li{counter-increment:n;padding-left:23px}
.ai-body ol > li::before{content:counter(n);position:absolute;left:1px;top:.2em;font:500 10.5px/1.6 var(--mono);color:var(--ink-3);width:16px}
.ai-body blockquote{margin:18px 0;padding:2px 0 2px 16px;border-left:2px solid var(--accent-line);font-family:var(--serif);font-size:calc(var(--read-size) + 3px);line-height:1.55;color:var(--ink-2)}
.ai-body hr{border:0;border-top:1px solid var(--line);margin:22px 0}
.ai-body :not(pre) > code{font:400 12.6px/1.5 var(--mono);background:var(--surface-2);border:1px solid var(--line);border-radius:5px;padding:1.5px 5px;color:var(--code-ink);white-space:nowrap}
.ai-body table{border-collapse:collapse;width:100%;margin:14px 0;font-size:13.4px}
.ai-body th,.ai-body td{border:1px solid var(--line);padding:7px 9px;text-align:left;vertical-align:top}
.ai-body th{background:var(--surface-2);font-weight:600;font-size:12.6px}

.codeblock{margin:15px 0;border:1px solid var(--line);border-radius:11px;overflow:hidden;background:var(--surface)}
.codeblock-head{display:flex;align-items:center;gap:8px;height:31px;padding:0 6px 0 12px;background:var(--surface-2);border-bottom:1px solid var(--line)}
.codeblock-head .lang{font:500 10.2px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.codeblock-head .spacer{flex:1}
.codeblock pre{margin:0;padding:12px 14px;overflow-x:auto;font:400 12.6px/1.72 var(--mono);color:var(--code-block-ink);letter-spacing:-.012em;tab-size:2}
.codeblock pre code{font:inherit;background:none;border:0;padding:0;color:inherit;white-space:pre}
.tok-key{color:var(--tok-key)}.tok-str{color:var(--tok-str)}.tok-num{color:var(--tok-num)}.tok-com{color:var(--ink-4);font-style:italic}.tok-fn{color:var(--tok-fn)}

/* message actions */
.msg-actions{display:flex;align-items:center;gap:1px;margin:10px 0 0 -6px;opacity:0;transition:opacity .2s}
.msg:hover .msg-actions,.msg:focus-within .msg-actions{opacity:1}
.msg-actions .meta{font:500 9.8px/1 var(--mono);color:var(--ink-4);margin-left:8px;letter-spacing:.03em}
.msg-actions .gap{width:4px}
.msg-actions .icon-btn.done{color:var(--accent)}
.u-actions{opacity:0;gap:0;margin:4px 2px 0}
.msg--user:hover .u-actions,.msg--user:focus-within .u-actions{opacity:1}
.msg--user .msg-time{margin:0 2px 0 6px}

/* thinking */
.think{
  border:1px solid var(--line);background:linear-gradient(180deg,var(--surface),rgba(var(--surface-rgb),.65));
  border-radius:11px;margin:0 0 14px;overflow:hidden;box-shadow:0 1px 0 rgba(var(--shade-rgb),.02);
}
.think-head{display:flex;align-items:center;gap:9px;width:100%;padding:9px 12px;text-align:left;font-size:12.4px;color:var(--ink-2);min-height:36px;transition:background .16s}
.think-head:hover{background:rgba(var(--ink-rgb),.022)}
.think-ico{color:var(--accent);display:grid;place-items:center;flex:none;width:15px;height:15px}
.think-title{font-weight:500}
.think-sub{color:var(--ink-4);font:500 10px/1 var(--mono);letter-spacing:.03em;margin-left:auto}
.think .chev{color:var(--ink-4);transition:transform .25s var(--ease)}
.think[data-open="true"] .chev{transform:rotate(180deg)}
/* live = tokens (thinking or answer) are still arriving */
.think.live .think-title{color:var(--ink)}
.think.live .think-ico{animation:pulse 2.2s ease-in-out infinite}
/* shimmer sweeps across the label while work is in flight */
.think.live .shimmer{
  background:linear-gradient(96deg,var(--ink-3) 16%,var(--ink-2) 34%,var(--ink) 50%,var(--ink-2) 66%,var(--ink-3) 84%);
  background-size:240% 100%;-webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent;
  animation:shimmerSweep 2.1s linear infinite;
}
/* travelling dots: only while live, so the resting state stays plain */
.think-title .d1,.think-title .d2,.think-title .d3{display:none}
.think.live .think-title .d1,.think.live .think-title .d2,.think.live .think-title .d3{display:inline;color:var(--ink-3);animation:dotFade 1.4s ease-in-out infinite}
.think.live .think-title .d2{animation-delay:.18s}
.think.live .think-title .d3{animation-delay:.36s}
/* waiting = request is out, no bytes back yet: no disclosure affordance */
.think.waiting .think-head{cursor:default;min-height:38px}
.think.waiting .think-head:hover{background:transparent}
.think.waiting .chev{display:none}
.think.waiting .think-sub{visibility:hidden}
.think.waiting .think-sub:not(:empty){visibility:visible;text-transform:none}
.think-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows .32s var(--ease)}
.think[data-open="true"] .think-body{grid-template-rows:1fr}
.think-body-in{overflow:hidden}
.think-text{
  padding:0 14px 12px;font-size:12.6px;line-height:1.66;color:var(--ink-3);white-space:pre-wrap;
  max-height:260px;overflow:auto;border-top:1px solid transparent;
  font-variant-numeric:tabular-nums;
}
.think-text em{font-style:italic;color:var(--ink-2)}

/* errors */
.err{
  display:flex;gap:10px;padding:11px 12px;border:1px solid rgba(163,70,58,.22);border-radius:10px;
  background:var(--danger-soft);font-size:12.8px;line-height:1.55;color:var(--danger-ink);
}
.err .ei{color:var(--danger);flex:none;margin-top:1px}
.err b{font-weight:600;display:block;margin-bottom:2px;color:#5C241D}
.err code{font:400 11.4px/1.5 var(--mono);background:rgba(163,70,58,.1);border:1px solid rgba(163,70,58,.18);border-radius:4px;padding:1px 4px;color:var(--danger-ink)}
.err .fix{margin-top:7px;display:flex;gap:6px}

/* streaming caret + note */
.caret{display:inline-block;width:2px;height:1.02em;background:var(--accent);vertical-align:-.17em;margin-left:2px;border-radius:2px;animation:blink 1.05s steps(1) infinite}
.streaming-note{display:inline-flex;align-items:center;gap:6px;font:500 9.6px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-4);margin-top:12px;padding:4px 7px;border:1px solid var(--line);border-radius:5px;background:var(--surface-2)}
.streaming-note .pd{width:4px;height:4px;border-radius:50%;background:var(--accent);animation:pulse 1.6s infinite}

/* follow ups */
.followups{display:flex;flex-wrap:wrap;gap:6px;margin-top:16px}
.followup{font-size:12.2px;color:var(--ink-2);border:1px solid var(--line-2);border-radius:999px;padding:5px 10px;display:inline-flex;align-items:center;gap:5px;transition:.16s;animation:rise .4s var(--ease) both;line-height:1.2}
.followup:hover{border-color:var(--accent-line);color:var(--accent);background:var(--accent-soft)}
.followup svg{color:var(--ink-4)}
.followup:hover svg{color:var(--accent)}

/* jump */
/* sits on the thread's own left edge, not the window's: centred it drifted
   over the prose and clipped itself against the composer's gradient */
/* the composer grows with the text, so a fixed offset overlaps it. The pill
   lives inside the thread and hangs from the composer's own top edge. */
/* Seated in the composer's fade rather than floating over the last line of
   prose: it hangs from the composer's top edge, which is where the text has
   already been faded out, and a canvas ring cuts the surrounding text away
   cleanly instead of letting a sentence show through beside the circle. */
.jump{
  position:absolute;bottom:calc(100% + 6px);
  left:max(24px, calc(50% - var(--thread-w) / 2 + 24px));
  transform:translateY(6px);z-index:20;width:32px;height:32px;padding:0;
  border-radius:999px;background:var(--surface);border:1px solid var(--line-2);
  box-shadow:0 0 0 6px var(--canvas),var(--shadow-2);
  display:grid;place-items:center;color:var(--ink-2);
  opacity:0;pointer-events:none;transition:.22s var(--ease);
}
.jump.show{opacity:1;pointer-events:auto;transform:translateY(0)}
.jump:hover{color:var(--ink);border-color:var(--line-3)}

/* ============================== composer ============================== */
.composer-wrap{position:absolute;left:0;right:0;bottom:0;z-index:22;padding:0 22px 14px;background:linear-gradient(to top,var(--canvas) 58%,rgba(var(--canvas-rgb),.92) 80%,rgba(var(--canvas-rgb),0));pointer-events:none}
.composer-zone{max-width:var(--thread-w);margin:0 auto;pointer-events:auto}
.composer{position:relative;background:var(--surface);border:1px solid var(--line-2);border-radius:19px;box-shadow:0 1px 2px rgba(var(--shade-rgb),.04),0 18px 40px -26px rgba(var(--shade-rgb),.35);padding:9px 9px 9px 11px;transition:border-color .2s,box-shadow .25s}
/* Focus is shown by the border and the caret, not by a lit-up box. The 4px
   accent halo read as a glow bleeding out of the composer, especially on the
   dark surface where the soft accent is at its most visible. */
.composer:focus-within{border-color:var(--accent-line);box-shadow:var(--shadow-1)}
.composer.dragover{border-color:var(--accent);background:var(--surface-hi);box-shadow:0 0 0 4px var(--accent-soft)}
.input-row{display:flex;align-items:flex-end;gap:8px}
.input-row textarea{flex:1;min-width:0;border:0;outline:0;background:transparent;resize:none;font-size:15.1px;line-height:1.55;padding:7px 4px 6px;max-height:224px;min-height:32px;color:var(--ink);letter-spacing:-.004em}
.input-row textarea::placeholder{color:var(--ink-4)}
.composer-bar{display:flex;align-items:center;gap:3px;padding:5px 1px 1px 2px;flex-wrap:wrap}
.cbtn{height:29px;min-width:29px;padding:0 7px;border-radius:8px;display:inline-flex;align-items:center;gap:6px;color:var(--ink-2);font-size:12.4px;font-weight:500;transition:.16s;border:1px solid transparent}
.cbtn:hover{background:rgba(var(--ink-rgb),.05);color:var(--ink)}
.cbtn.active{background:var(--accent-soft);color:var(--accent);border-color:rgba(61,92,76,.16)}
.composer-spacer{flex:1}
.send{width:33px;height:33px;border-radius:10px;display:grid;place-items:center;flex:none;background:var(--surface-2);color:var(--ink-4);border:1px solid var(--line);transition:.2s var(--ease)}
.send.can{background:var(--accent);border-color:var(--accent);color:var(--on-accent);box-shadow:0 6px 16px -10px rgba(61,92,76,.7)}
.send.can:hover{background:var(--accent-2);transform:translateY(-1px)}
.send.stop{background:var(--ink);border-color:var(--ink);color:var(--surface);box-shadow:none}
.fineprint{max-width:var(--thread-w);margin:7px auto 0;text-align:center;font-size:11px;color:var(--ink-4)}
.attach-row{display:flex;gap:6px;flex-wrap:wrap;padding:2px 2px 7px}
.attach{position:relative;border:1px solid var(--line);border-radius:9px;overflow:hidden;background:var(--surface-2);animation:popIn .26s var(--ease) both}
.attach img{width:52px;height:52px;object-fit:cover;display:block}
.attach .x{position:absolute;top:3px;right:3px;width:16px;height:16px;border-radius:5px;display:grid;place-items:center;background:rgba(25,23,19,.72);color:#fff;opacity:0;transition:opacity .15s;backdrop-filter:blur(3px)}
.attach:hover .x{opacity:1}

/* ============================== settings ============================== */
/* Settings is not a modal. It is a surface docked beside the rail: no
   backdrop, no blur, nothing full-screen to swallow a click. It sits at a
   fixed height near the top so it never re-centres as you change panes —
   a panel that jumps when you switch tabs reads as broken. */
.modal{
  position:fixed;inset:0;z-index:300;display:flex;align-items:flex-start;justify-content:flex-start;
  padding:58px 0 0 var(--sidebar-w);
  pointer-events:none;
}
.modal[hidden]{display:none}
.modal-card{
  pointer-events:auto;
  width:min(560px, calc(100vw - var(--sidebar-w) - 40px));
  height:min(560px, calc(100dvh - 96px));
  display:flex;flex-direction:column;background:var(--surface);
  border:1px solid var(--line-2);border-radius:16px;
  box-shadow:0 2px 6px rgba(var(--shade-rgb),.05),0 30px 70px -34px rgba(var(--shade-rgb),.4);
  overflow:hidden;animation:popIn .2s var(--ease) both;
}
.sheet-grab{display:none}
@keyframes popIn{from{opacity:0;transform:translateY(-6px) scale(.99)}to{opacity:1;transform:none}}
.modal-head{display:flex;align-items:flex-start;gap:14px;padding:16px 16px 14px 20px;border-bottom:1px solid var(--line);flex:none}
.modal-head h2{margin:0 0 3px;font-size:15.4px;font-weight:600;letter-spacing:-.012em}
.modal-head p{margin:0;font-size:11.8px;color:var(--ink-3);line-height:1.5}
.modal-head .mt{flex:1;min-width:0}
.modal-body{flex:1;min-height:0;display:grid;grid-template-columns:186px minmax(0,1fr)}
.settings-nav{display:flex;flex-direction:column;gap:1px;padding:12px 10px;border-right:1px solid var(--line);background:var(--canvas);overflow-y:auto}
.snav{text-align:left;font-size:12.8px;color:var(--ink-2);padding:7px 10px;border-radius:8px;transition:background .14s,color .14s}
.snav:hover{background:rgba(var(--ink-rgb),.05);color:var(--ink)}
.snav.active{background:var(--surface);color:var(--ink);font-weight:500;box-shadow:var(--shadow-1),inset 0 0 0 1px var(--line)}
.settings-panes{padding:18px 20px 22px;overflow-y:auto;min-height:0}
.spane{display:none;animation:fadeIn .18s ease both}
.spane.active{display:block}

.field{margin-bottom:16px}
.field.tight{margin-bottom:0}
.field:last-child{margin-bottom:0}
.field > label,.field > .label{display:block;font-size:12.2px;font-weight:500;color:var(--ink);margin-bottom:6px}
.label-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:6px}
.label-row label{font-size:12.2px;font-weight:500}
.field input[type="text"],.field input[type="password"],.field input[type="number"],.field textarea,.text-input,.mini-select select{
  width:100%;border:1px solid var(--line-2);border-radius:9px;background:var(--surface);padding:0 10px;height:34px;
  font-size:12.8px;outline:0;transition:border-color .16s,box-shadow .16s;color:var(--ink);
}
.field textarea{height:auto;padding:9px 10px;line-height:1.62;resize:vertical;min-height:120px;font-size:12.6px}
.field input:focus,.field textarea:focus,.text-input:focus,.mini-select select:focus{border-color:var(--accent-line);box-shadow:0 0 0 3px var(--accent-soft)}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-4)}
.hint{margin:6px 0 0;font-size:11.2px;color:var(--ink-3);line-height:1.5}
.hint code{font:400 10.8px/1.4 var(--mono);background:var(--surface-2);border:1px solid var(--line);border-radius:4px;padding:1px 4px;color:var(--ink-2)}
.key-wrap{position:relative}
.key-wrap input{padding-right:56px;font-family:var(--mono);letter-spacing:.02em}
.reveal{position:absolute;right:5px;top:50%;transform:translateY(-50%);font:500 10.4px/1 var(--mono);letter-spacing:.03em;text-transform:uppercase;color:var(--ink-3);padding:5px 7px;border-radius:6px}
.reveal:hover{background:var(--surface-2);color:var(--ink-2)}
.mini-select{position:relative}
.mini-select select{appearance:none;-webkit-appearance:none;padding-right:26px;cursor:pointer}
.mini-select svg{position:absolute;right:9px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--ink-3)}
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px}
.conn-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:2px}

.btn{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 12px;border-radius:8px;font-size:12.4px;font-weight:500;border:1px solid var(--line-2);color:var(--ink-2);background:var(--surface);transition:.16s}
.btn:hover{border-color:var(--accent-line);color:var(--accent);background:var(--accent-soft)}
.btn.small{height:29px;font-size:12px}
.btn.danger{color:var(--danger);border-color:rgba(163,70,58,.28)}
.btn.danger:hover{background:var(--danger-soft);border-color:rgba(163,70,58,.45);color:var(--danger)}
.btn.solid{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.btn.solid:hover{background:var(--accent-2);color:#fff}
.toggle-row{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;padding:8px 0;font-size:12.4px;color:var(--ink-2);text-align:left;border-bottom:1px solid var(--line)}
.toggle-row:last-of-type{border-bottom:0}
.switch{width:30px;height:18px;border-radius:999px;background:var(--surface-3);position:relative;transition:background .2s;flex:none;border:1px solid var(--line)}
.switch::after{content:"";position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--surface);box-shadow:0 1px 2px rgba(var(--shade-rgb),.25);transition:transform .22s var(--ease)}
.switch.on{background:var(--accent);border-color:var(--accent)}
.switch.on::after{transform:translateX(12px)}
.ctrl{margin-bottom:15px}
.c-row{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:5px}
.c-row label{font-size:12.2px;color:var(--ink-2)}
.c-val{font:500 11px/1 var(--mono);color:var(--ink);font-variant-numeric:tabular-nums}
.c-scale{display:flex;justify-content:space-between;font:400 9.6px/1 var(--mono);color:var(--ink-4);margin-top:3px}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:-4px}
.chip{font-size:11.4px;color:var(--ink-2);border:1px solid var(--line);border-radius:999px;padding:5px 9px;transition:.15s;line-height:1.1}
.chip:hover{border-color:var(--accent-line);color:var(--accent);background:var(--accent-soft)}
.link-btn{font-size:11.2px;color:var(--ink-3);transition:color .15s}
.link-btn:hover{color:var(--accent)}

input[type="range"]{-webkit-appearance:none;appearance:none;width:100%;height:18px;background:transparent;cursor:pointer;display:block}
input[type="range"]::-webkit-slider-runnable-track{height:3px;border-radius:2px;background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--fill,50%),var(--surface-3) var(--fill,50%),var(--surface-3) 100%)}
input[type="range"]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border-radius:50%;background:var(--surface);border:1.5px solid var(--accent);box-shadow:0 1px 3px rgba(var(--shade-rgb),.18);margin-top:-5.5px;transition:transform .16s var(--ease),box-shadow .16s}
input[type="range"]:hover::-webkit-slider-thumb{transform:scale(1.08)}
input[type="range"]:active::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--accent-soft)}
input[type="range"]::-moz-range-track{height:3px;border-radius:2px;background:var(--surface-3)}
input[type="range"]::-moz-range-progress{height:3px;border-radius:2px;background:var(--accent)}
input[type="range"]::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:var(--surface);border:1.5px solid var(--accent)}

/* ============================== popovers / misc ============================== */
/* A menu is as wide as its longest row, not as wide as the window. Without a
   max-width the row buttons stretched to the viewport, which made the popover
   report a 994px width and pushed every alignment calculation off the screen. */
.pop{
  position:fixed;z-index:220;min-width:222px;max-width:280px;width:max-content;
  background:var(--surface);border:1px solid var(--line-2);border-radius:12px;
  box-shadow:var(--shadow-2);padding:4px;animation:popIn .16s var(--ease) both;
}
.pop-item .pi-t{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pop-item{display:flex;align-items:center;gap:9px;width:100%;padding:7px 8px;border-radius:7px;text-align:left;font-size:12.8px;color:var(--ink-2);transition:background .13s,color .13s}
.pop-item:hover{background:var(--surface-2);color:var(--ink)}
.pop-item .pi-ico{color:var(--ink-3);display:grid;place-items:center;flex:none;width:16px}
.pop-item:hover .pi-ico{color:var(--accent)}
.pop-item .pi-t{font-weight:500;color:var(--ink)}
.pop-sep{height:1px;background:var(--line);margin:4px 5px}

/* no blur here either: a flat veil keeps the page readable behind the
   palette instead of turning the whole screen into fog */
/* The palette belongs to the conversation, so it sits over the conversation's
   own column rather than floating somewhere on the page. `--rail-live` is
   written by the app from the rail's measured width (see openPalette): a
   sibling selector cannot do this, because the overlay is appended to <body>
   while the rail lives inside #app. */
.overlay{
  position:fixed;inset:0;z-index:310;background:rgba(20,18,15,.34);
  display:flex;align-items:flex-start;justify-content:center;
  padding:clamp(64px,9vh,104px) 16px 16px calc(var(--rail-live, 0px) + 16px);
  animation:fadeIn .18s both;
}
.palette{width:min(560px,100%);max-height:72vh;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line-2);border-radius:14px;box-shadow:0 4px 12px rgba(var(--shade-rgb),.08),0 40px 80px -30px rgba(var(--shade-rgb),.45);overflow:hidden;animation:scaleIn .2s var(--ease) both}
.palette-input{position:relative;display:flex;align-items:center;gap:10px;padding:12px 46px 12px 14px;border-bottom:1px solid var(--line)}
.palette-input svg{color:var(--ink-3)}
.palette-input input{flex:1;border:0;outline:0;background:transparent;font-size:14px;min-width:0}
/* the badge was absolutely positioned with no positioned ancestor, so it
   drifted out of the field and landed over the results */
.palette-input .esc{
  position:absolute;right:12px;top:50%;transform:translateY(-50%);
  font:500 9.4px/1 var(--mono);color:var(--ink-3);
  border:1px solid var(--line-2);border-radius:4px;padding:3px 5px;
  background:var(--surface-2);pointer-events:none;
}
.palette-list{overflow-y:auto;padding:4px;min-height:0}
.pal-group{font:500 9.4px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-4);padding:9px 9px 5px}
.pal-item{display:flex;align-items:center;gap:9px;width:100%;padding:7px 8px;border-radius:7px;font-size:12.8px;color:var(--ink-2);text-align:left;transition:background .1s}
.pal-item .pi{color:var(--ink-3);display:grid;place-items:center;width:16px;flex:none}
.pal-item .pt{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pal-item .meta{font:500 9.6px/1 var(--mono);color:var(--ink-4);flex:none}
.pal-item.active{background:var(--accent-soft);color:var(--ink)}
.pal-item.active .pi{color:var(--accent)}
.palette-empty{padding:30px 16px;text-align:center;color:var(--ink-3);font-size:12.4px}
.palette-foot{display:flex;gap:12px;padding:7px 11px;border-top:1px solid var(--line);font:500 9.6px/1 var(--mono);color:var(--ink-4);letter-spacing:.03em}
.palette-foot kbd{font:500 9.2px/1 var(--mono);border:1px solid var(--line-2);border-radius:4px;padding:2.5px 4px;background:var(--surface-2);color:var(--ink-3)}

.lightbox{position:fixed;inset:0;z-index:320;background:rgba(26,24,20,.84);backdrop-filter:blur(10px);display:grid;place-items:center;padding:40px;animation:fadeIn .2s both}
.lightbox[hidden]{display:none}
.lightbox img{max-width:min(1100px,92vw);max-height:86vh;border-radius:10px;box-shadow:0 30px 80px -20px rgba(0,0,0,.6);animation:scaleIn .28s var(--ease) both}
.lb-close{position:fixed;top:16px;right:16px;width:34px;height:34px;border-radius:9px;background:rgba(255,255,255,.1);color:rgba(255,255,255,.88);display:grid;place-items:center;transition:.15s}
.lb-close:hover{background:rgba(255,255,255,.18)}

.toast{position:fixed;bottom:128px;left:50%;transform:translate(-50%,8px);z-index:60;display:flex;align-items:center;gap:8px;height:31px;padding:0 8px 0 12px;background:var(--surface);color:var(--ink);border:1px solid var(--line-2);border-radius:8px;font-size:12px;font-weight:500;box-shadow:0 1px 2px rgba(var(--shade-rgb),.05),0 14px 34px -18px rgba(var(--shade-rgb),.4);opacity:0;pointer-events:none;transition:opacity .2s,transform .26s var(--ease)}
.toast.show{opacity:1;transform:translate(-50%,0)}
.toast .t-ico{color:var(--accent);display:grid;place-items:center}
/* A flat veil, no blur. Blurring the page behind the drawer made the whole
   screen look out of focus and cost a compositor layer on every phone. */
.scrim{position:fixed;inset:46px 0 0 0;background:rgba(30,28,24,.22);z-index:29;opacity:0;pointer-events:none;transition:opacity .25s}
#app.rail-open .scrim{opacity:1;pointer-events:auto}

/* ============================== responsive ============================== */
@media (max-width:900px){
  #app{grid-template-columns:minmax(0,1fr)}
  .sidebar{position:fixed;top:46px;bottom:0;left:0;width:280px;z-index:40;transform:translateX(-102%);
    box-shadow:none;border-right:1px solid var(--line-2)}
  #app.rail-open .sidebar::after{content:""}
  /* The shadow belongs to the *open* drawer. A closed drawer is parked off the
     left edge, but box-shadow paints outside the border box regardless — at
     translateX(-102%) its 48px blur still landed across the first 30px of the
     conversation. A closed panel casts nothing, so it now has no shadow. */
  #app.rail-open .sidebar{box-shadow:0 0 0 1px rgba(var(--shade-rgb),.06),18px 0 48px -16px rgba(var(--shade-rgb),.45)}
  #app.rail-open .sidebar{transform:none;opacity:1}
  .modal{padding-left:0}
  .hide-lg{display:inline-grid}
  .thread-inner{padding:70px 18px 200px}
  .composer-wrap{padding:0 12px 12px}
  .empty{padding:2vh 0 0}
  .msg--user .u-col{max-width:88%}
  .msg-actions{opacity:1}
  .modal{align-items:flex-end;justify-content:center;padding:0}
  .modal-card{
    width:100%;height:auto;max-height:82dvh;border-radius:18px 18px 0 0;
    border-bottom:0;animation:sheetUp .24s var(--ease) both;
  }
  .sheet-grab{display:block;width:36px;height:4px;border-radius:999px;background:var(--line-2);margin:9px auto 2px;flex:none}
  @keyframes sheetUp{from{transform:translateY(24px);opacity:.6}to{transform:none;opacity:1}}
  .modal-body{grid-template-columns:minmax(0,1fr)}
  .settings-nav{flex-direction:row;overflow-x:auto;border-right:0;border-bottom:1px solid var(--line);padding:8px 10px;gap:4px;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;scroll-snap-type:x proximity}
  .settings-nav::-webkit-scrollbar{display:none}
  .snav{white-space:nowrap;font-size:12.2px;padding:6px 10px;scroll-snap-align:start;flex:none}
  .modal-card{max-height:92vh}
  .settings-panes{padding:14px 14px 20px}
}
@media (max-width:640px){
  .suggestions{grid-template-columns:1fr;gap:7px}
  .sug{padding:10px 11px}
  .sug .d{display:none}
  .pick .suggestions{display:none}
  .hide-sm{display:none}
  .composer{padding:8px 8px 7px 9px;border-radius:17px}
  .modal-head{padding:13px 12px 11px 14px}
  .modal-head h2{font-size:14.6px}
  .modal-head p{font-size:11px}
  .two-col{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  /* no sweep while it is paused mid-animation — use a steady colour instead */
  .think.live .shimmer{background:none;color:var(--ink);-webkit-text-fill-color:currentColor}
  .think.live .think-title .d1,.think.live .think-title .d2,.think.live .think-title .d3{opacity:.6}
}
@keyframes rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
@keyframes popIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes scaleIn{from{opacity:0;transform:scale(.98)}to{opacity:1;transform:none}}
@keyframes blink{0%,49%{opacity:1}50%,100%{opacity:0}}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.9)}}
@keyframes shimmerSweep{from{background-position:200% 0}to{background-position:-140% 0}}
@keyframes dotFade{0%,70%,100%{opacity:.22}35%{opacity:1}}
@keyframes spin{to{transform:rotate(360deg)}}

/* ══════════════════════════════════════════════════════════════════════════
   The start screen, the doors, the prompts
   One decision at a time: no composer until there is an image to talk about.
   ══════════════════════════════════════════════════════════════════════════ */

/* -------------------------------- picker -------------------------------- */
.pick{
  max-width:520px;margin:0 auto;padding:clamp(8px,3vh,40px) 0 0;text-align:center;
  animation:rise .5s var(--ease) both;
}
.pick-mark{
  width:auto;height:auto;border-radius:0;margin:0 auto 26px;display:grid;place-items:center;
  background:none;color:inherit;box-shadow:none;
}
.pick-mark img{width:42px;height:42px;display:block;object-fit:contain;opacity:.92}
html[data-theme="dark"] .pick-mark img{filter:invert(1) brightness(1.85);opacity:.82}
.pick h1{
  font-family:var(--serif);font-weight:400;font-size:clamp(30px,4.2vw,40px);line-height:1.14;
  letter-spacing:-.015em;color:var(--ink);margin:0 0 12px;
}
.pick h1 em{font-style:italic;color:var(--accent)}
.pick .sub{
  font-size:13.6px;line-height:1.6;color:var(--ink-3);margin:0 auto 26px;max-width:380px;
}

body.dropping .door,body.dropping .composer{border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}

/* ------------------------------- prompts -------------------------------- */
.prompts{animation:rise .45s .06s var(--ease) both}
.prompts-label{
  font:500 9.8px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4);
  margin:0 2px 11px;
}
.prompts .suggestions{grid-template-columns:1fr 1fr}

@keyframes shimmerSk{from{background-position:140% 0}to{background-position:-60% 0}}

@media (max-width:640px){
  .pick{padding-top:2vh}
  .pick h1{font-size:27px;max-width:300px;margin-left:auto;margin-right:auto}
  .pick .sub{font-size:12.8px;max-width:290px;margin-bottom:20px}
  .prompts{padding-bottom:8px}
}
@media (prefers-reduced-motion:reduce){
  .shot,.tray-cell{animation:none}
}

/* sidebar rows lead with the image they belong to */
.chat-item .ci-thumb{
  width:22px;height:22px;border-radius:6px;overflow:hidden;flex:none;display:grid;place-items:center;
  background:rgba(var(--ink-rgb),.06);color:var(--ink-4);
}
.chat-item .ci-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.chat-item .ci-thumb--empty svg{width:12px;height:12px}
.chat-item{padding-left:8px}

/* The composer is always on screen: the start screen is an offer, not a gate. */

/* ------------------------------ two doors ------------------------------- */
.pick-doors{
  display:grid;grid-template-columns:1fr 1fr;gap:10px;text-align:left;
}
.door{
  display:flex;flex-direction:column;gap:2px;padding:18px 16px 16px;text-align:left;
  border:1px solid var(--line);border-radius:15px;background:var(--surface);
  transition:border-color .2s,background .2s,transform .2s var(--ease),box-shadow .25s;
}
.door:hover{border-color:var(--accent-line);background:#FFFEFB;transform:translateY(-1px);box-shadow:var(--shadow-1)}
.door.over{border-color:var(--accent);background:var(--surface-hi);box-shadow:0 0 0 4px var(--accent-soft)}
.door-ic{
  width:28px;height:28px;border-radius:9px;display:grid;place-items:center;margin-bottom:10px;
  background:var(--accent-soft);color:var(--accent);
}
.door-ic svg{width:16px;height:16px}
.door-t{font-size:13.4px;font-weight:500;color:var(--ink);letter-spacing:-.004em}
.door-d{font-size:11.8px;color:var(--ink-3);line-height:1.4}
.door:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* the offer sits on the same 520 column as the doors above it */
.thread-inner>.prompts{max-width:520px;margin:20px auto 0}

@media (max-width:640px){
  .pick-doors{gap:8px}
  .door{padding:13px 12px 12px;border-radius:13px}
  .door-ic{width:25px;height:25px;margin-bottom:8px;border-radius:8px}
  .door-t{font-size:12.6px}
  .door-d{font-size:10.8px}
  .thread-inner>.prompts{margin-top:16px}
}


/* ══════════════════════════════════════════════════════════════════════════
   Images on messages — a tray while composing, thumbnails in the bubble
   ══════════════════════════════════════════════════════════════════════════ */

.tray{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  max-width:var(--thread-w);margin:0 auto 8px;padding:0 4px;
}
.tray[hidden]{display:none}
.tray-cell{
  position:relative;width:56px;height:56px;border-radius:10px;overflow:hidden;flex:none;
  border:1px solid var(--line);background:var(--surface);
  animation:shotIn .3s var(--ease) both;
}
.tray-cell img{width:100%;height:100%;object-fit:cover;display:block;cursor:zoom-in}
.tray-x{
  position:absolute;top:3px;right:3px;width:17px;height:17px;border-radius:50%;
  display:grid;place-items:center;color:#fff;background:rgba(var(--ink-rgb),.62);
  backdrop-filter:blur(3px);transition:background .15s;
}
.tray-x:hover{background:rgba(var(--ink-rgb),.85)}
.tray-x svg{width:9px;height:9px}
.tray-label{
  font:500 9.8px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-4);
  margin-left:2px;
}

@keyframes shotIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}

/* thumbnails inside the user's own message */
.u-col{display:flex;flex-direction:column;align-items:flex-end;gap:7px;max-width:min(78%,560px)}
.shots{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
.shot{
  position:relative;display:block;padding:0;border-radius:11px;overflow:hidden;
  border:1px solid var(--line);background:var(--surface);line-height:0;
  transition:transform .2s var(--ease),box-shadow .2s;
  animation:shotIn .32s var(--ease) both;
}
.shot:hover{transform:translateY(-1px);box-shadow:var(--shadow-1)}
.shot img{
  display:block;width:auto;height:auto;
  max-width:176px;max-height:176px;              /* a thumbnail, not a poster */
  object-fit:cover;
}
.shots--many .shot img{max-width:112px;max-height:112px}
.shot-dims{
  position:absolute;right:6px;bottom:6px;padding:2px 5px;border-radius:5px;
  font:500 9px/1 var(--mono);letter-spacing:.04em;color:#fff;
  background:rgba(var(--ink-rgb),.5);backdrop-filter:blur(4px);
  opacity:0;transition:opacity .18s;line-height:1.3;
}
.shot:hover .shot-dims{opacity:1}

/* the attachments menu reuses .pop; these are its rows */
.pop .pop-group{
  padding:8px 10px 6px;font:500 9.4px/1 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-4);
}
.att-grid{display:flex;flex-direction:column;gap:1px;max-height:232px;overflow-y:auto;padding:0 4px 4px}
.att-row{
  display:flex;align-items:center;gap:9px;padding:5px;border-radius:8px;text-align:left;
  transition:background .15s;
}
.att-row:hover{background:var(--hover,rgba(var(--ink-rgb),.05))}
.att-row img{width:34px;height:34px;border-radius:6px;object-fit:cover;flex:none;border:1px solid var(--line);cursor:zoom-in}
.att-use{
  margin-left:auto;flex:none;padding:5px 9px;border-radius:7px;font-size:11.6px;font-weight:500;
  color:var(--accent);background:var(--accent-soft);transition:background .15s;
}
.att-use:hover{background:var(--accent);color:var(--on-accent)}
.att-meta{display:flex;flex-direction:column;gap:1px;min-width:0}
.att-t{font-size:12.4px;color:var(--ink)}
.att-d{font:500 9.6px/1 var(--mono);color:var(--ink-4)}
.att-empty{padding:10px 12px 14px;font-size:12.2px;color:var(--ink-4)}

@media (max-width:640px){
  .tray-cell{width:46px;height:46px}
  .shot img{max-width:168px;max-height:168px}
  .shots--many .shot img{max-width:104px;max-height:104px}
}


/* ------------------------- theme: small fixes ------------------------- */
/* code blocks need their own ground in the dark */
html[data-theme="dark"] .codeblock{background:#171614}
html[data-theme="dark"] .codeblock-head{background:#1D1C19}
html[data-theme="dark"] .grain{opacity:.16}
html[data-theme="dark"] .shot-dims{background:rgba(0,0,0,.55)}
html[data-theme="dark"] .attach .x{background:rgba(0,0,0,.6)}
html[data-theme="dark"] .tray-x{color:#141412}

/* the theme flips on the root, so transitions stay cheap */
html{color-scheme:light}
html[data-theme="dark"]{color-scheme:dark}

/* ==========================================================================
   copy affordance — a small pill that sits centred under its own message and
   turns into a tick when the text is on the clipboard
   ========================================================================== */
.msg-actions{position:relative}
/* the row hangs under the bubble, centred on it, and takes no width of its
   own — so a short message still has its copy button directly beneath it */
.u-col{position:relative;padding-bottom:28px}
/* The control sits on the bubble's top-right corner, not centred under it.
   `.u-col` is align-items:flex-end, so its right edge *is* the bubble's right
   edge — anchoring here keeps the button in the corner whatever the column
   width or the message length. The time hangs to the left so it can never
   push the button inward. */
.u-actions{
  position:absolute;right:0;bottom:2px;
  margin:0;gap:0;align-items:center;
}
.u-actions .icon-btn.sm{width:26px;height:22px;border-radius:7px;color:var(--ink-4)}
/* the time sits outside the flow to the left of the button, so it can never
   take part in positioning and push the button away from the corner */
.u-actions .msg-time{position:absolute;right:100%;margin-right:6px;white-space:nowrap;order:0}
.msg-actions .icon-btn.sm{width:26px;height:24px;border-radius:7px;color:var(--ink-4)}
.msg-actions .icon-btn.sm:hover{color:var(--ink-2)}
.msg-actions .icon-btn.copied{
  color:var(--accent);background:var(--accent-soft);
}
.msg-actions .icon-btn.copied svg{animation:tickIn .22s var(--ease) both}
@keyframes tickIn{from{opacity:0;transform:scale(.6)}to{opacity:1;transform:none}}

/* sidebar settings row (replaces the old account block) */
.side-settings{
  display:flex;align-items:center;gap:9px;width:100%;padding:7px 8px;border-radius:9px;
  color:var(--ink-3);font-size:12.6px;transition:background .15s,color .15s;
}
.side-settings:hover{background:rgba(var(--ink-rgb),.05);color:var(--ink)}
.side-settings .kbd{margin-left:auto}

/* the typeface list in settings, styled like the rest of the panel */
/* the typeface list. The popup that used to own .font-row is gone; the
   settings pane uses the same markup, so the row rules live here now. */
.fsel{display:flex;flex-direction:column;gap:2px;margin-top:2px}
.fsel .font-row{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:8px 10px;border-radius:9px;border:1px solid transparent;
  text-align:left;transition:background .14s,border-color .14s;
}
.fsel .font-row:hover{background:rgba(var(--ink-rgb),.045)}
.fsel .font-row[aria-checked="true"]{background:var(--accent-soft);border-color:var(--accent-line)}
.fsel .font-row .sample{font-size:16px;line-height:1.1;color:var(--ink);flex:none;width:32px}
.fsel .font-row .nm{font-size:12.9px;color:var(--ink-2)}
.fsel .font-row[aria-checked="true"] .nm{color:var(--ink);font-weight:550}
.fsel .font-row .tick{margin-left:auto;display:grid;place-items:center;color:var(--accent);opacity:0}
.fsel .font-row[aria-checked="true"] .tick{opacity:1}

/* the "a newer version exists" bar */
.stale-bar{
  position:fixed;left:50%;bottom:18px;transform:translateX(-50%);z-index:80;
  display:flex;align-items:center;gap:10px;padding:8px 8px 8px 13px;
  background:var(--surface);color:var(--ink);border:1px solid var(--line-2);
  border-radius:10px;font-size:12.4px;box-shadow:var(--shadow-2);
  animation:scaleIn .2s var(--ease) both;
}
.stale-bar button{
  padding:5px 11px;border-radius:7px;background:var(--accent);color:var(--on-accent);
  font-size:12px;font-weight:500;
}
.stale-bar button:hover{background:var(--accent-2)}

/* the chat now lives at /chat, under a shared site bar — the rail's own
   brand row would be a second logo two centimetres apart */
/* The bar is the one surface that must never dim. Give it its own stacking
   context above the drawer's veil, so opening the rail veils the conversation
   and nothing else — the panel then reads as attached to the bar. */
.site-bar{
  position:relative;z-index:41;
  height:46px;flex:none;display:flex;align-items:center;gap:18px;
  padding:0 18px;border-bottom:1px solid var(--line);background:var(--canvas);
}
.site-bar .sb-brand{
  display:inline-flex;align-items:center;gap:8px;
  font-size:13.4px;font-weight:600;letter-spacing:-.01em;color:var(--ink);
}
.site-bar .sb-brand img{width:19px;height:19px;object-fit:contain;opacity:.92}
html[data-theme="dark"] .site-bar .sb-brand img{filter:invert(1) brightness(1.85);opacity:.8}
.site-bar nav{display:flex;gap:1px;margin-left:4px}
.site-bar nav a{
  padding:5px 10px;border-radius:8px;font-size:12.9px;color:var(--ink-2);
  transition:background .16s,color .16s;
}
.site-bar nav a:hover{background:var(--surface-2);color:var(--ink)}
.site-bar nav a[aria-current="page"]{color:var(--ink);font-weight:600}
.site-bar nav a[aria-current="page"]:hover{background:transparent}
.site-bar .sb-spacer{flex:1}
.site-bar .sb-tg{
  font-size:12.6px;color:var(--ink-3);padding:5px 9px;border-radius:8px;transition:.16s;
}
.site-bar .sb-tg:hover{color:var(--ink);background:var(--surface-2)}
@media (max-width:640px){
  .site-bar{padding:0 12px;gap:10px}
  .site-bar nav a{padding:5px 8px}
  .site-bar .sb-tg{display:none}
}

/* ======================= rail: icons, edge, quiet =======================

   The rail's head is three icons. No mark (the site bar has it), no wordmark,
   no "New chat" pill with a shortcut badge. The thread below is the content;
   the rail is a tool, and tools get out of the way.

   When the rail is closed it leaves a 14px strip against the window edge.
   Hovering that strip slides it back; moving away returns it to closed. The
   toggle keeps working for people who would rather pin it. */

.rail-top{
  display:flex;align-items:center;gap:2px;padding:6px 6px 10px;
}
.rail-gap{flex:1}
.rail-act{
  width:32px;height:32px;border-radius:9px;display:grid;place-items:center;
  color:var(--ink-2);transition:background .16s,color .16s,transform .16s var(--ease);
}
.rail-act:hover{background:rgba(var(--ink-rgb),.055);color:var(--ink)}
.rail-act:active{transform:scale(.94)}

/* the strip that brings a closed rail back */
.rail-edge{
  position:fixed;top:46px;bottom:0;left:0;width:14px;z-index:35;
  opacity:0;pointer-events:none;
}
/* the edge lives inside #app, so a descendant selector is enough — the
   sibling form silently matched nothing and the strip stayed inert */
#app.rail-collapsed .rail-edge{opacity:1;pointer-events:auto}
#app.rail-collapsed.rail-peek .rail-edge{opacity:0;pointer-events:none}

/* a pointer resting at the edge slides the rail out; leaving puts it back */
#app.rail-collapsed.rail-peek{
  grid-template-columns:var(--sidebar-w) minmax(0,1fr);
}
#app.rail-collapsed.rail-peek .sidebar{
  transform:none;opacity:1;pointer-events:auto;
  box-shadow:24px 0 60px -34px rgba(var(--shade-rgb),.34);
}

/* on a narrow screen the panel is a drawer; the toggle floats instead of
   owning a header row */
.rail-fab{
  display:none;position:absolute;top:10px;left:12px;z-index:24;
  width:32px;height:32px;border-radius:9px;place-items:center;
  background:var(--surface);border:1px solid var(--line-2);color:var(--ink-2);
  box-shadow:var(--shadow-1);
}
.rail-fab:hover{color:var(--ink);border-color:var(--ink-4)}

/* nothing on this page grows a visible scrollbar. Scrolling still works —
   wheel, trackpad, keyboard — it just stops drawing a gutter down the side. */
.side-scroll,.thread,.settings-panes,.settings-nav,.modal-body,.tray{scrollbar-width:none;-ms-overflow-style:none}
.side-scroll::-webkit-scrollbar,.thread::-webkit-scrollbar,
.settings-panes::-webkit-scrollbar,.settings-nav::-webkit-scrollbar,
.modal-body::-webkit-scrollbar,.tray::-webkit-scrollbar{width:0;height:0}
html{scrollbar-width:none;scrollbar-gutter:auto}
textarea{scrollbar-width:none;-ms-overflow-style:none}
textarea::-webkit-scrollbar{width:0;height:0}
body::-webkit-scrollbar{width:0}

/* three states, one row. A switch can only say on or off, and "follow the
   system" is neither. */
.theme-pick{display:flex;gap:6px;margin-top:2px}
.theme-opt{
  flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  height:34px;border-radius:9px;border:1px solid var(--line-2);background:var(--surface);
  font-size:12.6px;color:var(--ink-2);transition:.16s var(--ease);
}
.theme-opt:hover{border-color:var(--ink-4);color:var(--ink)}
.theme-opt.on{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent);font-weight:550}
.theme-opt svg{opacity:.85}

/* ---- narrow screens: last word on the fab and the edge ----
   These live here, not in the 900px block above, because the rail rules are
   appended after it — the same rule written earlier loses the cascade. */
@media (max-width:900px){
  .rail-fab{display:grid}
  .rail-edge{display:none}
}
