

:root {
  --sb-bg: #1a191c;
  --sb-edge: #262529;
  --sb-hover: #2a292d;
  --sb-ink: #d9d8dc;
  --main-bg: color-mix(in srgb, var(--surface) 55%, var(--bg));
  --panel: var(--surface);
  --col: 768px;
  --sb-w: 260px;
}
/* The signed-in app wears the dashboard's greys, so moving between the chat
   and the console is one place, not two: #222125 behind, #2b2a2e for panels
   like the composer, the sidebar a step darker. Dark only; light keeps its own. */
@media not (prefers-color-scheme: light) {
  html.in-app {
    --main-bg: #222125;
    --panel: #2b2a2e;
    --surface: #2b2a2e;
    --chip: #333236;
    --chip-hover: #3a383e;
    --line: #38363c;
  }
}
@media (prefers-color-scheme: light) {
  :root {
    --sb-bg: var(--surface);
    --sb-edge: var(--line);
    --sb-hover: var(--chip);
    --sb-ink: var(--ink);
    --main-bg: var(--bg);
    --panel: var(--bg);
  }
}

/* While a stored session is being checked, hide the sign-in card and nothing
   else. It used to hide the whole sheet, which traded a flash of the wrong
   screen for a blank one: a returning visitor stared at an empty page for the
   length of a round trip. Now the shell is there and only the card that would
   have been wrong is held back. */
html.booting #gate { visibility: hidden; }
html.booting .foot-spacer,
html.booting footer.ed-foot { visibility: hidden; }

/* Signed in: the marketing sheet and red footer step aside for the app. */
html.in-app,
html.in-app body { height: 100%; overflow: hidden; background: var(--main-bg); }
html.in-app .sheet,
html.in-app .foot-spacer,
html.in-app footer.ed-foot,
html.in-app body > header,
html.in-app .burger,
html.in-app #menu,
html.in-app .rail { display: none !important; }

[data-icon] { display: inline-flex; align-items: center; justify-content: center; flex: none; }
[data-icon] svg { width: 18px; height: 18px; }

/* Sign in ---------------------------------------------------------------- */

.signin {
  min-height: calc(100vh - var(--header-h) - 64px);
  min-height: calc(100dvh - var(--header-h) - 64px);
  display: grid;
  place-items: center;
  padding: 40px 16px;
}
.signin-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border-radius: 20px;
  padding: 32px;
}
/* The card is the first thing a signed-out visitor sees and it carried no
   identity at all, so it could have been any product's login box. The mark
   sits above the heading at the same size it has in the header. */
.signin-logo {
  display: inline-flex; align-items: center; gap: 9px;
  margin-bottom: 20px;
  font-family: var(--sans, inherit); font-weight: 400; font-size: 20px;
  letter-spacing: -0.04em; color: var(--ink); text-decoration: none;
}
.signin-logo:hover { text-decoration: none; }
.signin-logo .mark-svg { flex: none; display: block; transform: translateY(-0.0263em); }
.signin-card h1 { font-size: 26px; letter-spacing: -0.03em; line-height: 1.15; margin: 0 0 10px; }
.signin-card p { color: var(--muted); margin: 0 0 22px; }
.signin-card input { width: 100%; margin-bottom: 14px; background: var(--bg); }
.signin-card .btn { width: 100%; padding-block: 12px; }
.signin-card .notice { margin: 16px 0 0; }
.signin-alt { margin: 16px 0 0 !important; font-size: 13px; text-align: center; }
.signin-note { margin: 22px 0 0 !important; padding-top: 18px; border-top: 1px solid var(--line-soft); font-size: 12.5px; text-align: center; color: var(--faint) !important; }
/* It is a link now rather than a disclaimer, so it has to look like one without
   shouting: the card is a form and the way out is not the thing to press. */
.signin-note a { color: var(--muted); }
.signin-note a:hover { color: var(--ink); text-decoration: none; }
@media (max-width: 640px) {
  .signin { padding: 28px 16px; place-items: start center; }
  .signin-card { padding: 24px 20px; }
}

/* Shell ------------------------------------------------------------------ */

/* Signed out, the chat opens straight away and the sign-in card waits over it,
   invisible but rendered, so its Turnstile check is ready the moment something
   needs an account (sending, the sidebar, settings). */
html.in-app.guest #gate {
  position: fixed; inset: 0; z-index: 300; min-height: 0; margin: 0;
  display: grid; place-items: center; padding: 16px;
  background: rgba(6, 6, 8, .72);
  opacity: 0; pointer-events: none; transition: opacity .15s ease;
}
html.in-app.guest.gate-open #gate { opacity: 1; pointer-events: auto; }
.signin-card { position: relative; }
.gate-x { display: none; }
html.guest .gate-x {
  display: block; position: absolute; top: 12px; right: 12px;
  background: none; border: 0; color: var(--muted); font-size: 24px; line-height: 1; padding: 4px 8px; cursor: pointer;
}
html.guest .gate-x:hover { color: var(--ink); }
/* The way back to the site is the close button here. */
html.guest .signin-note { display: none; }

.shell {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  background: var(--main-bg);
  color: var(--ink);
  font: 400 14px/1.55 var(--sans);
}
.shell button { font-family: inherit; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border: 0; border-radius: 10px;
  background: transparent; color: var(--muted);
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.icon-btn:hover { background: var(--chip); color: var(--ink); }
.icon-btn svg { width: 20px; height: 20px; }

.avatar {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; border-radius: 50%;
  background: linear-gradient(96deg, #e10600 0%, #ff4d0a 46%, #ff9a1f 100%); color: #fff;
  font-weight: 700; font-size: 14px; text-transform: uppercase;
}
.avatar.model { background: var(--chip); color: var(--accent); }
.avatar.sm { width: 22px; height: 22px; font-size: 11px; }
.avatar.lg { width: 44px; height: 44px; font-size: 19px; }

.muted { color: var(--muted); }

/* Sidebar ---------------------------------------------------------------- */

.sb {
  width: var(--sb-w);
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--sb-bg);
  border-right: 1px solid var(--sb-edge);
  padding: 10px 10px 0;
  transition: margin-left .22s ease;
  min-height: 0;
}
.shell.sb-collapsed .sb { margin-left: calc(-1 * var(--sb-w)); }

.sb-head { display: flex; align-items: center; justify-content: space-between; padding: 2px 2px 8px 10px; }
.sb-head .logo { font-size: 19px; }

.sb-new,
.pop.menu button,
.pop.menu > a {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: 0; background: transparent; color: var(--ink);
  padding: 9px 10px; border-radius: 10px;
  font-size: 14px; font-weight: 400; text-align: left;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.sb-new { text-decoration: none; }
.sb-new:hover,
.pop.menu button:hover,
.pop.menu > a:hover { background: var(--chip); }

.sb-search {
  display: flex; align-items: center; gap: 8px;
  margin: 4px 0 8px; padding: 0 10px;
  border-radius: 10px; color: var(--faint);
  cursor: text;
}
.sb-search:focus-within { background: var(--chip); color: var(--muted); }
.shell .sb-search input,
.shell .pop-search input {
  flex: 1; min-width: 0;
  border: 0; background: transparent; padding: 8px 0;
  color: var(--ink); font-size: 14px;
}
.shell .sb-search input:focus,
.shell .pop-search input:focus { background: transparent; }
.shell input[type="search"]::-webkit-search-cancel-button { filter: grayscale(1); opacity: .6; }

.sb-list { flex: 1; overflow-y: auto; min-height: 0; margin: 0 -4px; padding: 0 4px 12px; scrollbar-width: thin; }
.sb-group + .sb-group { margin-top: 14px; }
.sb-group-label { font-size: 12px; font-weight: 400; color: var(--faint); padding: 4px 10px 6px; }
.sb-empty { color: var(--faint); font-size: 13px; padding: 10px; }

.sb-item {
  position: relative;
  display: flex; align-items: center;
  border-radius: 10px;
  transition: background-color .15s ease;
}
.sb-item:hover,
.sb-item.menu-open { background: var(--chip); }
.sb-item.active { background: var(--chip); }
.sb-link {
  flex: 1; min-width: 0;
  border: 0; background: transparent; color: var(--ink);
  padding: 8px 10px; text-align: left; font-size: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
}
.sb-item:not(.active) .sb-link { color: color-mix(in srgb, var(--ink) 86%, var(--muted)); }
.sb-more {
  width: 28px; height: 28px; margin-right: 4px; border-radius: 8px;
  opacity: 0;
}
.sb-more svg { width: 16px; height: 16px; }
.sb-item:hover .sb-more,
.sb-item.active .sb-more,
.sb-item.menu-open .sb-more,
.sb-more:focus-visible { opacity: 1; }
.sb-more:hover { background: var(--chip-hover); }
@media (hover: none) { .sb-more { opacity: 1; } }
.sb-rename {
  flex: 1; min-width: 0; margin: 3px;
  padding: 5px 8px !important; font-size: 14px !important;
  border-radius: 8px !important;
}

.sb-foot { padding: 8px 0 10px; }
.sb-user {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: 0; background: transparent; color: var(--ink);
  padding: 8px; border-radius: 12px; text-align: left; cursor: pointer; text-decoration: none;
  transition: background-color .15s ease;
}
.sb-user:hover,
.sb-user[aria-expanded="true"] { background: var(--chip); }
/* The account row, the same one the dashboard rail ends with: person glyph,
   email, and a dots button. The whole row opens the account menu. */
.sb-user { gap: 10px; padding: 10px 8px; border-radius: 8px; font-size: 14px; color: var(--sb-ink); }
.sb-user > svg { flex: none; width: 18px; height: 18px; opacity: .85; }
.sb-user-email { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-user-more { flex: none; width: 30px; text-align: center; color: var(--muted); font-size: 18px; line-height: 1; }
.sb-user:hover, .sb-user[aria-expanded="true"] { background: var(--sb-hover); }
.sb-user:hover .sb-user-more { color: var(--ink); }
.sb-user-text { display: grid; min-width: 0; line-height: 1.3; flex: 1; }
/* The chip opened a menu with nothing on it saying so. The caret is the whole
   affordance, and it turns over when the menu is up. */
.sb-user-caret {
  display: inline-flex; flex: none; color: var(--muted);
  transition: transform .15s ease;
}
.sb-user-caret svg { width: 16px; height: 16px; }
.sb-user[aria-expanded="true"] .sb-user-caret { transform: rotate(180deg); }
/* Before an email has loaded the avatar shows the person glyph rather than a
   stray initial; once there is an email, app.js swaps in the letter. */
.avatar[data-icon] svg { width: 18px; height: 18px; }
.sb-email { font-size: 13.5px; font-weight: 400; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-bal { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.scrim { display: none; }

/* Main ------------------------------------------------------------------- */

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; position: relative; }

.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  height: 56px; padding: 0 12px;
  flex: none;
}
.tb-left, .tb-right { display: flex; align-items: center; gap: 4px; min-width: 0; }
.tb-sb, .tb-new { display: none; }
.shell.sb-collapsed .tb-sb,
.shell.sb-collapsed .tb-new { display: inline-flex; }

.mp-btn {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0;
  border: 0; background: transparent; color: var(--ink);
  padding: 7px 10px; border-radius: 10px;
  font-size: 17px; font-weight: 400; letter-spacing: -0.01em;
  cursor: pointer;
  transition: background-color .15s ease;
}
.mp-btn:hover,
.mp-btn[aria-expanded="true"] { background: var(--chip); }
.mp-btn-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 46vw; }
.mp-btn [data-icon] { color: var(--muted); }
.mp-btn [data-icon] svg { width: 16px; height: 16px; }

/* Popovers --------------------------------------------------------------- */

.pop {
  position: fixed;
  z-index: 60;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
}
/* Scoped to .pop, because `.menu` is ALSO the site chrome's full-screen nav
   overlay. Unscoped, these rules squeezed that overlay into a 220px box on
   /app, so opening the menu mid sign-in spilled the links out of the left
   edge and left the card floating over them. The app's own popups all carry
   .pop, so scoping costs nothing and ends the collision. */
.pop.menu { width: 220px; padding: 6px; }
.pop.menu button,
.pop.menu > a { font-weight: 400; padding: 8px 10px; text-decoration: none; }
.pop.menu button [data-icon],
.pop.menu > a [data-icon] { color: var(--muted); }
.pop.menu button.danger { color: var(--bad); }
.pop.menu button.danger [data-icon] { color: var(--bad); }
.menu-sep { height: 1px; background: var(--line); margin: 6px 4px; }

.mp-menu { width: min(460px, calc(100vw - 24px)); padding: 8px; }
.pop-search { display: flex; align-items: center; gap: 8px; padding: 0 10px; color: var(--faint); border-radius: 10px; background: var(--chip); }
.pop-search:focus-within { color: var(--muted); }

.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.mp-menu .chips { margin: 8px 2px; }
.chip {
  border: 0; cursor: pointer;
  background: var(--chip); color: var(--ink);
  font: 400 12.5px var(--sans); padding: 6px 11px; border-radius: 8px;
  transition: background-color .15s ease, color .15s ease;
}
.chip:hover { background: var(--chip-hover); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--bg); }

.mp-list { max-height: min(380px, 52vh); overflow-y: auto; display: grid; gap: 1px; scrollbar-width: thin; }
.mp-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 18px 28px; align-items: center; gap: 12px;
  width: 100%; border: 0; background: transparent; color: var(--ink);
  /* Less on the right, so the open arrow sits at the row's edge, level with the name's inset. */
  padding: 8px 4px 8px 10px; border-radius: 10px; text-align: left; cursor: pointer;
  transition: background-color .12s ease;
}
.mp-row:hover,
.mp-row.hi { background: var(--chip); }
.mp-main { display: grid; gap: 1px; min-width: 0; }
.mp-name { font-size: 14px; font-weight: 400; display: flex; align-items: center; gap: 6px; min-width: 0; }
.mp-name > span:first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-id { font: 400 11.5px/1.35 var(--mono); color: var(--faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-price { text-align: right; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; line-height: 1.3; }
.mp-price small { display: block; font-size: 11px; color: var(--faint); }
.mp-check { color: var(--ink); visibility: hidden; }
.mp-check svg { width: 16px; height: 16px; }
/* Opens the model's own page, with its prices, in a new tab. */
.mp-open { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px; color: var(--faint); transition: color .12s ease, background-color .12s ease; }
.mp-open:hover { color: var(--ink); background: var(--chip-hover, rgba(255, 255, 255, .08)); }
.mp-open svg { width: 15px; height: 15px; }
.mp-row[aria-selected="true"] .mp-check { visibility: visible; }
.mp-empty { color: var(--muted); font-size: 13px; padding: 18px 10px; text-align: center; }

.tag {
  flex: none;
  display: inline-block;
  padding: 1px 7px; border-radius: 6px;
  background: var(--accent-soft); color: var(--accent);
  font-size: 11px; font-weight: 400; line-height: 1.6;
}

.ctrl-menu { width: 280px; padding: 14px 16px 16px; }
.ctrl-title { font-weight: 400; margin-bottom: 12px; }
.ctrl-field + .ctrl-field { margin-top: 16px; }
.ctrl-label { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.ctrl-label label { margin: 0; font-size: 13px; }
.ctrl-label span { font-variant-numeric: tabular-nums; color: var(--ink); }
.ctrl-field input[type="range"] { width: 100%; accent-color: var(--accent); padding: 0; border: 0; background: transparent; }
.ctrl-field input[type="number"] { width: 100%; background: var(--surface); }
.ctrl-help { margin: 6px 0 0; font-size: 12px; color: var(--faint); }

/* Skeletons are the only place a shimmer is allowed. */
.skel {
  display: block; height: 12px; border-radius: 6px;
  background: linear-gradient(90deg, var(--chip) 25%, var(--chip-hover) 50%, var(--chip) 75%);
  background-size: 200% 100%;
  animation: skel 1.2s linear infinite;
}
@keyframes skel { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.skel-row { display: grid; gap: 7px; padding: 10px; }

/* Thread ----------------------------------------------------------------- */

.thread { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-width: thin; }
.col { width: 100%; max-width: var(--col); margin: 0 auto; padding-inline: 20px; }
.messages { display: flex; flex-direction: column; gap: 26px; padding-block: 16px 36px; min-height: 100%; }
.thread.is-empty .messages { justify-content: center; padding-block: 24px; }

.msg { min-width: 0; }
.msg.user { align-self: flex-end; max-width: min(85%, 620px); display: flex; flex-direction: column; align-items: flex-end; }
.bubble {
  background: var(--chip);
  border-radius: 22px;
  padding: 10px 18px;
  font-size: 15px; line-height: 1.6;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
/* An image that was sent with the message. Capped rather than cropped: a
   thumbnail of the thing you asked about is only useful if you can still see
   what it is. */
.bubble-imgs { display: flex; flex-wrap: wrap; gap: 6px; }
.bubble-img { display: block; max-width: 260px; max-height: 260px; width: auto; height: auto; border-radius: 12px; }
.bubble-text { display: block; }
/* What is left of an image after a reload, since the picture itself is never
   written to storage. */
.bubble-img.gone {
  display: grid; place-items: center; width: 96px; height: 72px;
  border: 1px dashed var(--line); color: var(--faint); font-size: 12px;
}
.bubble-imgs + .bubble-text { margin-top: 8px; }

/* The model's workings. Muted and set small, because it is not the answer,
   and capped in height so a long think does not push the reply off screen. */
.think { margin: 0 0 12px; font-size: 13px; }
.think-h {
  display: block; color: var(--faint); font-size: 12px;
  letter-spacing: .04em; text-transform: uppercase; margin-bottom: 6px; cursor: pointer;
}
details.think > .think-h::marker, details.think > .think-h::-webkit-details-marker { color: var(--faint); }
.think-b {
  color: var(--muted); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere;
  border-left: 1px solid var(--line); padding-left: 12px;
  max-height: 240px; overflow-y: auto; scrollbar-width: thin;
}
.think.live .think-h { cursor: default; }
/* The fold's own line: the live Thinking count while it reasons, "Thought for N tokens" after.
   A click opens the trace under it. */
.think-sum { list-style: none; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; color: var(--faint); font-size: 13px; padding: 2px 0; }
.think-sum::-webkit-details-marker { display: none; }
.think-sum:hover { color: var(--muted); }
.think-sum .wc-chev { width: 14px; height: 14px; flex: none; transition: transform .15s ease; }
details.think[open] > .think-sum .wc-chev { transform: rotate(180deg); }
details.think > .think-b { margin-top: 8px; }
.think.live { margin: 0; }
/* While it is the only thing on screen it gets the room; once the answer is
   there it is workings and stays out of the way. */
.think.live .think-b { max-height: 260px; }

.msg.assistant { width: 100%; }
.msg-model { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; font-size: 13.5px; font-weight: 400; color: var(--ink); }
.msg-model .mid { color: var(--faint); font-weight: 400; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.msg-actions { display: flex; align-items: center; gap: 2px; margin-top: 6px; flex-wrap: wrap; min-height: 28px; }
/* Copy, regenerate and the cost line sit under every message but only show
   while that message is hovered or focused; on touch there is no hover, so
   they stay. The row keeps its height so nothing jumps when it appears. */
.msg .msg-actions { opacity: 0; transition: opacity .15s ease; }
.msg:hover .msg-actions,
.msg:focus-within .msg-actions { opacity: 1; }
@media (hover: none) { .msg .msg-actions { opacity: 1; } }
.act {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  height: 28px; min-width: 28px; padding: 0 6px;
  border: 0; border-radius: 8px; background: transparent; color: var(--faint);
  font-size: 12px; cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.act:hover { background: var(--chip); color: var(--ink); }
.act svg { width: 16px; height: 16px; }
.meta { font: 400 11.5px/1.4 var(--mono); color: var(--faint); margin-left: 6px; }
.meta button { border: 0; background: none; padding: 0; font: inherit; color: inherit; cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }
.meta button:hover { color: var(--ink); }

.msg-error {
  margin-top: 8px;
  padding: 10px 14px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--bad) 13%, transparent);
  color: var(--bad);
  font-size: 14px;
}
.msg-error .btn { margin-left: 8px; vertical-align: middle; }
.msg-note { margin-top: 6px; font-size: 12.5px; color: var(--faint); }


.typing {
  display: block; width: 24px; height: 24px; margin: 4px 0;
  background: url("/_/strip.png") 0 0 / 24px 2640px no-repeat;
  animation: ucx-static 4.4s steps(110, jump-none) infinite alternate;
  filter: grayscale(1); /* the sheet is drawn orange; the loader reads grey */
}
.typing i { display: none; }
@keyframes ucx-static { from { background-position: 0 0; } to { background-position: 0 -2616px; } }
@media (prefers-reduced-motion: reduce) { .typing { animation: none; } }

/* Empty state ------------------------------------------------------------ */

.hero { width: 100%; max-width: min(1100px, 100%); margin: 0 auto; padding-bottom: 6vh; }
.hero-model { display: flex; align-items: center; gap: 14px; }
/* The model you are about to talk to, not a headline. It was set at 700 and
   read as the page title. */
.hero-name { font-weight: 400; font-size: clamp(20px, 2.6vw, 26px); letter-spacing: -0.02em; line-height: 1.2; overflow-wrap: anywhere; }
.hero-sub { font-size: 13px; color: var(--faint); margin-top: 3px; overflow-wrap: anywhere; }
.hero-sub .mono { font-size: 12px; }
.hero-q { font-size: clamp(18px, 2.4vw, 22px); color: var(--muted); margin: 18px 0 26px; letter-spacing: -0.01em; }
.hero-pick { margin-top: 18px; }
/* Composer --------------------------------------------------------------- */

/* Wider than the reading column. The thread is text and wants a measure; the
   composer is a control and does not, and matching them left the box looking
   like another paragraph rather than the thing you type in. */
.composer-wrap { flex: none; width: 100%; max-width: min(1100px, 100%); margin: 0 auto; padding: 0 20px 10px; }
.composer {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 26px;
  padding: 12px 10px 10px 20px;
  transition: border-color .15s ease;
}
.composer:focus-within { border-color: var(--chip-hover); }
.shell .composer textarea {
  display: block; width: 100%;
  min-height: 26px; max-height: 220px;
  resize: none; border: 0; outline: 0; padding: 2px 10px 2px 0;
  background: transparent; color: var(--ink);
  font: 400 15px/1.6 var(--sans);
  overflow-y: auto;
}
.composer textarea::placeholder { color: var(--faint); }
/* Attachments -------------------------------------------------------------- */
/* The strip sits above the message box, not inside it. */
.composer { position: relative; }
.attached { position: absolute; left: 4px; right: 4px; bottom: calc(100% + 10px); display: flex; gap: 10px; flex-wrap: wrap; padding: 0; }
.chip-img { position: relative; display: block; width: 72px; height: 72px; }
.chip-img img { width: 100%; height: 100%; object-fit: cover; display: block; border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 6px 18px rgba(0,0,0,.35); }
/* The remove control overlaps its own thumbnail, which is the only place it can
   go without the strip reflowing every time one is added. */
.chip-img button {
  position: absolute; top: -8px; right: -8px; width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--line); background: #2b2a2e; color: var(--ink);
  font-size: 14px; line-height: 1; cursor: pointer; padding: 0; display: grid; place-items: center;
}
.chip-img button:hover { color: var(--ink); border-color: var(--faint); }

.attach {
  border: 0; background: transparent; color: var(--faint);
  font-size: 19px; line-height: 1; width: 28px; height: 28px; cursor: pointer; padding: 0;
  flex: none;
}
.attach:hover { color: var(--ink); }
/* The mic sits beside the attach button and looks like it until it is live.
   While recording it turns the accent colour and breathes slowly, so it is
   plain from across the room that the browser is listening. */
.mic { display: inline-flex; align-items: center; justify-content: center; margin-left: -8px; }
.composer-row .composer-hint { flex: 1; }
.mic svg { width: 18px; height: 18px; }
.mic.live { color: var(--accent); animation: mic-breathe 1.6s ease-in-out infinite; }
.mic.busy { opacity: .5; cursor: progress; }
@keyframes mic-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .mic.live { animation: none; } }

.composer-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 6px; }
.composer-hint { font-size: 12px; color: var(--faint); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-left: 0; }
.composer-hint.bad { color: var(--bad); }
.send {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 36px; height: 36px; border: 0; border-radius: 50%;
  background: linear-gradient(96deg, #e10600 0%, #ff4d0a 46%, #ff9a1f 100%); color: #fff;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.send:hover { background: color-mix(in srgb, var(--accent) 82%, #000); }
.send:disabled { background: var(--chip); color: var(--faint); cursor: default; }
.send.stop { background: var(--ink); color: var(--bg); }
.send.stop:hover { background: var(--muted); }
.send svg { width: 18px; height: 18px; }
.composer-note { text-align: center; font-size: 12px; color: var(--faint); margin: 8px 0 0; }

/* Markdown --------------------------------------------------------------- */

.md { font-size: 15px; line-height: 1.7; color: var(--ink); overflow-wrap: anywhere; }
.md > :first-child { margin-top: 0; }
.md > :last-child { margin-bottom: 0; }
.md p { margin: 0 0 12px; }
.md h1, .md h2, .md h3, .md h4, .md h5, .md h6 { font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; margin: 22px 0 8px; }
.md h1 { font-size: 22px; }
.md h2 { font-size: 19px; }
.md h3 { font-size: 17px; }
.md h4, .md h5, .md h6 { font-size: 15px; }
.md ul, .md ol { margin: 0 0 12px; padding-left: 1.5em; }
.md li { margin: 4px 0; }
.md li > ul, .md li > ol { margin: 4px 0 0; }
.md strong { font-weight: 700; }
.md a { color: var(--link); }
.md hr { border: 0; border-top: 1px solid var(--line); margin: 18px 0; }
.md blockquote { margin: 0 0 12px; padding: 10px 14px; background: var(--surface); border-radius: 12px; color: var(--muted); }
.md blockquote > :last-child { margin-bottom: 0; }
.md code { font: 400 13px/1.5 var(--mono); background: var(--chip); padding: 2px 6px; border-radius: 6px; }
.md-code { margin: 12px 0; border-radius: 14px; overflow: hidden; background: var(--code-bg); border: 1px solid var(--line-soft); }
.md-code-head { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 4px 14px; background: #1a1a1a; color: #8f8f8f; font: 400 12px var(--mono); }
.md-copy {
  display: inline-flex; align-items: center; gap: 5px;
  border: 0; background: transparent; color: #aaaaaa;
  padding: 5px 8px; border-radius: 8px; font: 400 12px var(--sans); cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.md-copy:hover { background: #2c2c2c; color: #f1f1f1; }
.md-copy svg { width: 14px; height: 14px; }
.md .md-code pre { margin: 0; border-radius: 0; padding: 14px 16px; background: transparent; font: 400 13px/1.65 var(--mono); }
.md .md-code code { background: none; padding: 0; border-radius: 0; color: #f1f1f1; font-size: 13px; }
/* Syntax colouring. The block already stays dark in both themes (the head is
   fixed #1a1a1a), so one palette serves both. Keywords take the brand
   red-orange; the rest is One Dark so the four colours stay apart at 13px. */
.md .md-code .tok-c { color: #7a7f87; font-style: italic; }
.md .md-code .tok-s { color: #98c379; }
.md .md-code .tok-n { color: #56b6c2; }
.md .md-code .tok-k { color: #ff6a3d; }
.md .md-code .tok-b { color: #61afef; }
.md-table { overflow-x: auto; margin: 0 0 12px; }
.md-table table { width: auto; min-width: 50%; font-size: 14px; }
.md-table th, .md-table td { padding: 7px 14px 7px 0; }
.md-table th { font-size: 13px; color: var(--ink); font-weight: 700; }
.md-table tbody tr:hover { background: transparent; }

/* Settings modal --------------------------------------------------------- */

.modal {
  position: fixed; inset: 0; z-index: 70;
  display: grid; place-items: center;
  padding: 24px;
  background: rgba(0, 0, 0, .6);
}
.modal-card {
  width: 100%; max-width: 900px;
  height: min(680px, calc(100dvh - 48px));
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: 20px;
  overflow: hidden;
}
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px 6px 24px; }
.modal-head h2 { font-size: 18px; margin: 0; }
.modal-body { flex: 1; min-height: 0; display: flex; gap: 8px; padding: 0 8px 0 14px; }
.tabs { width: 190px; flex: none; display: flex; flex-direction: column; gap: 2px; padding: 8px 0 16px; }
.tab {
  display: flex; align-items: center; gap: 10px;
  border: 0; background: transparent; color: var(--muted);
  padding: 8px 12px; border-radius: 10px;
  font-size: 14px; text-align: left; cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.tab:hover { background: var(--chip); color: var(--ink); }
.tab[aria-selected="true"] { background: var(--chip); color: var(--ink); }
.panes { flex: 1; min-width: 0; overflow-y: auto; padding: 8px 16px 28px 16px; scrollbar-width: thin; }
.pane { display: none; }
.pane.on { display: block; }
.pane h3 { font-size: 16px; font-weight: 400; margin: 0 0 6px; }
.pane h3:not(:first-child) { margin-top: 28px; }
.pane h4 { font-size: 14px; font-weight: 400; margin: 26px 0 8px; }
.pane .sub { font-size: 13.5px; margin-bottom: 16px; }
.pane-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.pane-head h3 { margin: 0; }
.pane .notice { margin-bottom: 16px; }
.pane table { font-size: 13.5px; }
.pane th, .pane td { padding: 9px 12px 9px 0; }
.pane td.n, .pane th.n { padding-right: 0; }
.pane td.n + td.n, .pane th.n + th.n { padding-left: 18px; }
.shell tbody tr:hover { background: transparent; }
.pane .tablewrap table { min-width: 520px; }
.pane .tablewrap.slim table { min-width: 0; }
.pane .row { justify-content: space-between; }

.facts { margin: 12px 0 0; display: grid; gap: 0; }
.facts div { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--line-soft); }
.facts dt { color: var(--muted); }
.facts dd { margin: 0; text-align: right; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }

.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-bottom: 6px; }
.stats.three { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 20px; }
.stat { background: var(--chip); border-radius: 12px; padding: 12px 14px; min-width: 0; }
.stat .k { font-size: 12px; color: var(--muted); }
.stat .v { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }

.formrow { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-bottom: 18px; }
.formrow > div { flex: 1 1 150px; min-width: 0; }
.formrow input { width: 100%; }
.formrow .topup-field { flex: 0 1 170px; }
.pane input { background: var(--surface); }
.pane input:focus { background: var(--bg); }

.keyout-row { display: flex; gap: 8px; align-items: stretch; margin-top: 10px; }
.keyout-row .keyout { flex: 1; margin: 0; }
.key-name { font-weight: 400; }
.key-actions { display: inline-flex; gap: 6px; justify-content: flex-end; white-space: nowrap; }
.key-edit { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 10px; padding: 6px 0 4px; }
.key-edit label { margin-bottom: 4px; }
.key-edit input[type="text"],
.key-edit input[type="number"] { width: 100%; padding: 8px 12px; }
.key-edit-foot { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.switch { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: 13.5px; color: var(--ink); cursor: pointer; }
.switch input { width: 16px; height: 16px; accent-color: var(--accent); padding: 0; margin: 0; }
.amount.credit { color: var(--good); }

/* Toast ------------------------------------------------------------------ */

.toast {
  position: fixed; left: 50%; top: 14px; z-index: 90;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 12px;
  max-width: calc(100vw - 32px);
  padding: 10px 12px 10px 16px;
  border-radius: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
  font-size: 14px;
}
.toast.bad { color: var(--bad); }
.toast button { border: 0; background: var(--chip); color: var(--ink); border-radius: 8px; padding: 5px 10px; font-size: 13px; cursor: pointer; }
.toast button:hover { background: var(--chip-hover); }

/* Mobile ----------------------------------------------------------------- */

@media (max-width: 767px) {
  .sb {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 50;
    width: min(300px, 86vw);
    margin-left: 0 !important;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: none;
  }
  .shell.drawer-open .sb { transform: none; box-shadow: 0 0 40px rgba(0, 0, 0, .5); }
  .scrim { display: block; position: fixed; inset: 0; z-index: 45; background: rgba(0, 0, 0, .55); opacity: 0; pointer-events: none; transition: opacity .2s ease; }
  .shell.drawer-open .scrim { opacity: 1; pointer-events: auto; }

  .tb-sb, .tb-new { display: inline-flex; }
  .topbar { height: 52px; padding: 0 6px; }
  .tb-left { flex: 1; }
  .tb-new { order: 3; margin-left: auto; }
  .mp-btn { font-size: 16px; padding: 7px 8px; }
  .mp-btn-name { max-width: calc(100vw - 170px); }

  .col { padding-inline: 16px; }
  .messages { gap: 22px; }
  .msg.user { max-width: 90%; }
  .hero { padding-bottom: 2vh; }

  .composer-wrap { padding: 0 10px max(8px, env(safe-area-inset-bottom)); }
  .composer { padding: 10px 8px 8px 16px; border-radius: 22px; }
  .shell .composer textarea { font-size: 16px; padding: 2px 8px 2px 0; }
  .composer-hint { display: none; }
  .composer-row { justify-content: flex-end; margin-top: 4px; }
  .composer-note { font-size: 11px; margin-top: 6px; }

  .mp-row { grid-template-columns: minmax(0, 1fr) 28px; gap: 8px; }
  .mp-price { text-align: left; font-size: 12px; }
  .mp-price small { display: inline; margin-left: 4px; }
  .mp-check { display: none; }

  .modal { padding: 0; place-items: stretch; }
  .modal-card { height: 100%; max-width: none; border-radius: 0; border: 0; }
  .modal-head { padding: 10px 8px 4px 16px; }
  .modal-body { flex-direction: column; padding: 0; gap: 0; }
  .tabs { width: auto; flex-direction: row; overflow-x: auto; padding: 4px 12px 10px; gap: 4px; scrollbar-width: none; }
  .tab { flex: none; padding: 7px 12px; }
  .tab [data-icon] { display: none; }
  .pane th { white-space: nowrap; }
  .pane .tablewrap.fit table { min-width: 0; }
  .col-note { display: none; }
  .panes { padding: 6px 16px 28px; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats.three { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats.three .stat:first-child { grid-column: 1 / -1; }
  .split { grid-template-columns: 1fr; gap: 0; }
  .key-edit { grid-template-columns: 1fr 1fr; }
  .key-edit > div:first-child { grid-column: 1 / -1; }
  .formrow > .btn { flex: 1 1 100%; }
  .formrow .topup-field { flex: 1 1 100%; }
}

/* Embedded checkout. Stripe renders its own iframe in here, so it only needs
   room and a little air above the ledger. */
.pay-mount { margin: 18px 0 10px; min-height: 340px; }
.pay-mount.hide { display: none; }

/* Thirty-day usage under the balance: what a key holder actually wants to see
   without opening a panel. */
.sb-usage { display: block; font-size: 11px; line-height: 1.5; color: var(--muted, #8c9199); }

/* The desktop sidebar does not collapse, so its close button belongs to the
   mobile drawer only. */
@media (min-width: 861px) { #sbClose { display: none; } }

/* Sidebar links: usage, keys and billing are what a key holder opens most, so
   they sit in the rail rather than behind the settings gear. */
.sb-links { margin-top: auto; padding: 8px 8px 4px; display: grid; gap: 2px; }
.sb-link {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 8px 10px;
  background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 13.5px; text-align: left;
  color: var(--muted, #8c9199);
}
.sb-link { text-decoration: none; border-radius: 8px; }
.sb-link:hover { background: rgba(255, 255, 255, .05); color: #f2f3f5; }
.sb-usage { cursor: default; }

/* The marketing chrome never belongs in the app shell, and the dropdown panel
   stays closed regardless of load order. */
html.in-app .navdrop-menu { display: none !important; }

/* Install card on the empty state: the chat is the demo, the agent is the
   product, and this is the one command that gets someone from one to the other. */
.install { margin: 30px auto 0; max-width: 640px; padding: 18px; border: 1px solid #23222a; background: #121116; text-align: left; }
.install-h { font-family: var(--display, inherit); font-weight: 700; font-size: 14.5px; color: #f2f3f5; margin-bottom: 6px; }
.install-p { margin: 0 0 10px; font-size: 12.5px; line-height: 1.6; color: #8b9099; }
.install-p a { color: #ff9a4a; }
.install-cmd { position: relative; }
.install-cmd code {
  display: block; padding: 12px 84px 12px 12px; background: #0b0a0c; border: 1px solid #23222a;
  font: 400 12px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #d4d7dd;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.install-cmd button {
  position: absolute; top: 8px; right: 8px; padding: 6px 12px; cursor: pointer;
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14); border-radius: 999px;
  color: #f2f3f5; font-size: 12px; font-weight: 700;
}
.install-cmd button:hover { background: rgba(255,255,255,.14); }

/* Simplified chat --------------------------------------------------------- */
/* One column for the thread and the composer, and nothing on screen that is
   not the conversation. An empty chat is the composer alone, in the middle of
   the page; once there is a message it drops back to the bottom edge. */
.composer-wrap { max-width: calc(var(--col) + 40px); }
.main:has(.thread.is-empty) .thread,
.main:has(.thread.is-empty) .composer-wrap { flex: 1 1 0; }
.main:has(.thread.is-empty) .thread { display: flex; flex-direction: column; justify-content: flex-end; }
.main:has(.thread.is-empty) .messages { min-height: 0; padding-block: 0 18px; }
.messages:empty { display: none; }
.composer-hint:empty { visibility: hidden; }
/* The composer floats: lifted off the bottom edge, a soft shadow under it and
   a warm ring when it has focus, so it reads as the one control on the page.
   The text and the controls share one left edge, and + and the mic are round
   chips that fill on hover rather than bare glyphs. */
.composer-wrap { padding: 0 20px 22px; }
.composer {
  background: color-mix(in srgb, var(--surface) 88%, #fff 3%);
  border-radius: 24px;
  padding: 14px 10px 8px 14px;
  box-shadow: 0 10px 32px rgba(0, 0, 0, .28), inset 0 1px 0 rgba(255, 255, 255, .04);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.composer:focus-within {
  border-color: color-mix(in srgb, #ff4d0a 45%, var(--line));
  box-shadow: 0 10px 32px rgba(0, 0, 0, .28), 0 0 0 3px color-mix(in srgb, #ff4d0a 14%, transparent);
}
.shell .composer textarea { padding: 2px 10px 2px 6px; }
.composer-row { margin-top: 16px; gap: 4px; }
.attach {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  color: var(--muted); font-size: 20px;
  transition: background-color .15s ease, color .15s ease;
}
.attach:hover { background: var(--chip); color: var(--ink); }
.mic { margin-left: 0; }
.send { width: 34px; height: 34px; }
@media (prefers-color-scheme: light) {
  .composer { background: var(--surface); box-shadow: 0 8px 26px rgba(20, 20, 30, .08); }
}
@media (max-width: 640px) {
  .composer-wrap { padding: 0 10px max(10px, env(safe-area-inset-bottom)); }
  .composer { padding: 10px 8px 6px 10px; }
  .composer-row { margin-top: 12px; }
}
/* Cost and token counts are there when the reply is pointed at, not under
   every answer. */
.msg.assistant .meta { opacity: 0; transition: opacity .15s ease; }
.msg.assistant:hover .meta,
.msg.assistant:focus-within .meta { opacity: 1; }
@media (hover: none) { .msg.assistant .meta { opacity: 1; } }
.msg.assistant .meta.live { opacity: 1; }
.sb-list { padding-top: 8px; }
.think-h { text-transform: none; letter-spacing: 0; font: 400 13px/1.4 var(--sans); }
.mp-row:focus, .mp-row:focus-visible { outline: none; box-shadow: none; }

/* Empty chat: the model's name and its one line, above the composer. */
.intro { text-align: center; padding: 0 16px; }
.intro-name { margin: 0; font: 400 clamp(26px, 2.6vw, 34px)/1.15 var(--sans); letter-spacing: -0.02em; color: var(--ink); }
.intro-desc { margin: 10px auto 0; max-width: 46ch; font-size: 14.5px; line-height: 1.55; color: var(--muted); }

/* Profile: one button at the foot of the sidebar. Who you are and what you
   have left live in the menu it opens. */
.sb-foot { padding: 10px 0 12px; }
.sb-user {
  gap: 10px; padding: 6px 12px 6px 6px;
  border: 1px solid var(--line); border-radius: 999px;
  transition: background-color .15s ease, border-color .15s ease;
}
.sb-user:hover,
.sb-user[aria-expanded="true"] { background: var(--chip); border-color: transparent; }
.sb-user .avatar { width: 28px; height: 28px; font-size: 12.5px; }
.sb-user-label { font-size: 14px; }
.menu-who { display: grid; gap: 2px; padding: 8px 10px 4px; min-width: 0; }
.menu-email { font-size: 13.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-bal { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }


.pop.menu {
  inset: auto; height: auto; opacity: 1; visibility: visible;
  display: flex; flex-direction: column; justify-content: flex-start; gap: 0;
  background: var(--panel); transition: none;
}
.pop.menu.hide { display: none; }
.pop.menu > a { font-family: var(--sans); font-size: 14px; line-height: 1.4; letter-spacing: 0; color: var(--ink); max-width: none; }
.pop.menu > a::after { content: none; }

/* Balance the empty-chat lines so neither is left with one word. */
.intro-name, .intro-desc { text-wrap: balance; }

/* The rating card: asked once, above the composer, easy to dismiss. */
.rate {
  margin: 0 auto 10px; max-width: var(--col, 760px); padding: 12px 14px;
  border-radius: 14px; background: var(--panel, #16151a); box-shadow: inset 0 0 0 1px var(--line, #26252b);
}
.rate-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.rate-q { font-size: 14px; color: var(--ink); }
.rate-flames { display: inline-flex; gap: 2px; }
.rate-f { background: none; border: 0; padding: 2px; font-size: 20px; line-height: 1; cursor: pointer; filter: grayscale(1) opacity(.35); transition: filter .2s ease; }
.rate-f.on, .rate-f:hover { filter: none; }
.rate-x { margin-left: auto; background: none; border: 0; color: var(--muted); font: inherit; font-size: 13px; cursor: pointer; }
.rate-x:hover { color: var(--ink); }
.rate-more { margin-top: 10px; display: grid; gap: 8px; }
.rate-more textarea, .rate-more input {
  width: 100%; box-sizing: border-box; resize: vertical; padding: 9px 11px; border-radius: 10px;
  background: var(--bg, #0b0a0c); border: 1px solid var(--line, #26252b); color: var(--ink); font: inherit; font-size: 14px;
}
.rate-row { display: flex; gap: 8px; }
.rate-send {
  flex: none; height: 38px; padding: 0 18px; border-radius: 999px; border: 0; cursor: pointer; color: #fff; font: inherit; font-size: 14px;
  background: linear-gradient(180deg, rgba(40,38,44,.9), rgba(20,19,22,.94)); box-shadow: inset 0 0 0 1px rgba(255,255,255,.1);
  transition: background .35s ease, box-shadow .35s ease;
}
.rate-send:hover { box-shadow: inset 0 0 0 1px rgba(255,255,255,.18); }

.intro-name .xpl { cursor: pointer; }
/* In the model picker the brand word is plain text, the same colour as the name: the glow and the moving
   gradient on every row were too much next to the names and prices. */
.mp-btn .xpl, .mp-menu .xpl {
  background: none; -webkit-background-clip: border-box; background-clip: border-box;
  color: inherit; -webkit-text-fill-color: currentColor; filter: none; animation: none;
}

/* First visit: no model is chosen for you. The empty chat lists the line. */
.choose { width: 100%; max-width: 720px; margin: 0 auto; padding: 0 16px 4vh; text-align: center; }
.choose-h { margin: 0; font: 400 clamp(26px, 2.6vw, 34px)/1.15 var(--sans); letter-spacing: -0.02em; color: var(--ink); }
.choose-sub { margin: 10px auto 0; max-width: 34em; font-size: 14.5px; line-height: 1.55; color: var(--muted); }
.choose-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin-top: 28px; text-align: left; }
.choose-card {
  display: flex; flex-direction: column; gap: 8px; width: 100%; padding: 18px 18px 16px; border: 0; border-radius: 16px; cursor: pointer;
  background: var(--panel); color: var(--ink); font: inherit; text-align: left; height: auto; min-height: 0;
  box-shadow: inset 0 0 0 1px var(--line-soft); transition: background .15s, box-shadow .15s;
}
.choose-card:hover { background: var(--chip); box-shadow: inset 0 0 0 1px rgba(255, 138, 68, .45); }
.choose-card:focus-visible { outline: 2px solid rgba(255, 138, 68, .6); outline-offset: 2px; }
.choose-name { font: 400 19px/1.2 var(--sans); letter-spacing: -0.01em; }
.choose-desc { font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.choose-facts { margin-top: auto; padding-top: 4px; font: 400 12px var(--mono); color: var(--faint); }

/* Voice typing, live. While dictating the composer row is cancel, a waveform
   of the room, done and send; the plus, the mic and the hint step aside. The
   text box stays exactly where it is and the words land in it. */
.dict-btn, .dict-wave, .dict-busy { display: none; }
.composer.dictating .attach, .composer.dictating .composer-hint { display: none; }
.composer.dictating .dict-btn {
  display: inline-grid; place-items: center; flex: none; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%;
  background: var(--chip); color: var(--muted); cursor: pointer; transition: color .15s, background .15s;
}
.composer.dictating .dict-btn:hover { color: var(--ink); }
.composer.dictating .dict-btn svg { width: 16px; height: 16px; }
.composer.dictating .dict-wave:not(.hide) { display: block; flex: 1; min-width: 0; height: 26px; color: #ff8a44; }
.composer.dictating .dict-busy:not(.hide) { display: block; flex: 1; min-width: 0; text-align: center; font-size: 13px; color: var(--muted); }

/* The web search, drawn the way DHC draws a tool call: one quiet line above
   the answer, no border and no background, so it reads as working rather than
   as content. The globe spins while it runs and the words shimmer; done, it
   settles to grey and folds the sources under a chevron. */
.web-chip { display: block; margin: 0 0 10px; font-size: 14px; color: var(--muted); }
div.web-chip { display: flex; align-items: center; gap: 8px; padding: 2px 0; }
.web-chip summary { display: inline-flex; align-items: center; gap: 8px; padding: 2px 0; }
.web-chip summary { cursor: pointer; list-style: none; user-select: none; }
.web-chip summary::-webkit-details-marker { display: none; }
.web-chip summary:hover, .web-chip[open] summary { color: var(--ink); }
.wc-ico { position: relative; flex: none; width: 16px; height: 16px; display: grid; place-items: center; color: var(--faint); }
.wc-ico svg { width: 14px; height: 14px; }
.wc-t { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.wc-q { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--faint); max-width: 52ch; }
.wc-n { color: var(--faint); }
.wc-n::before { content: '\00b7'; margin-right: 8px; }
.wc-chev { width: 14px; height: 14px; flex: none; color: var(--faint); transition: transform .15s ease; }
.web-chip[open] .wc-chev { transform: rotate(180deg); }
.wc-live {
  background: linear-gradient(90deg, var(--muted) 0%, var(--ink) 45%, var(--muted) 90%); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  animation: wc-sweep 1.8s linear infinite;
}
.wc-src { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 2px 24px; }
.wc-src a {
  padding: 3px 10px; border-radius: 999px; background: rgba(255, 255, 255, .05); font-size: 12.5px;
  color: var(--muted); text-decoration: none; transition: color .15s ease, background-color .15s ease;
}
.wc-src a:hover { color: var(--ink); background: rgba(255, 255, 255, .09); }
@keyframes wc-sweep { from { background-position: 100% 0; } to { background-position: -100% 0; } }
/* While a search runs the magnifier circles, the way a hand sweeps a glass
   over a page, so the line reads as working even before the shimmer is seen. */
.wc-ico.busy { color: var(--ink); }
.wc-ico.busy svg { animation: wc-seek 1.4s linear infinite; }
@keyframes wc-seek {
  0% { transform: translate(-2px, 0); }
  25% { transform: translate(0, -2px); }
  50% { transform: translate(2px, 0); }
  75% { transform: translate(0, 2px); }
  100% { transform: translate(-2px, 0); }
}
@media (prefers-reduced-motion: reduce) { .wc-ico.busy svg, .wc-live { animation: none; } }
/* The searches once the answer is in: one line, opened to each query with the
   pages it brought back under it. */
.ws-list { display: grid; gap: 10px; margin: 8px 0 4px 24px; }
.ws-q { min-width: 0; }
.ws-qt { color: var(--muted); font-size: 13.5px; overflow-wrap: anywhere; }
.ws-qn { margin-left: 8px; color: var(--faint); font-size: 12.5px; }
.ws-q .wc-src { margin: 6px 0 0; }
.web-chip .thinking-row .typing { width: 16px; height: 16px; background-size: 16px 1760px; animation-name: ucx-static-sm; }
@keyframes ucx-static-sm { from { background-position: 0 0; } to { background-position: 0 -1744px; } }
.web-chip .thinking { margin: 0; font-size: 14px; }
@media (prefers-reduced-motion: reduce) { .web-chip .thinking-row .typing { animation: none; } }

/* Marks the one standard (not uncensored) model on the line. */
.std-tag { display: inline-block; margin-left: 6px; padding: 1px 7px; border: 1px solid var(--line); border-radius: 999px; font: 400 11px var(--sans); color: var(--muted); vertical-align: 2px; -webkit-text-fill-color: currentColor; }

/* Keys, usage and billing, one click from the chat: the API dashboard sits
   right above the account button rather than inside its menu. */
.sb-dash {
  display: flex; align-items: center; gap: 10px; margin: 0 0 6px; padding: 9px 10px;
  border: 1px solid var(--line, rgba(255,255,255,.08)); border-radius: 10px;
  color: var(--sb-ink, var(--ink)); font-size: 14px; text-decoration: none;
  transition: background-color .15s ease, border-color .15s ease;
}
.sb-dash:hover { background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .16); text-decoration: none; }
.sb-dash [data-icon] { display: inline-flex; width: 18px; height: 18px; opacity: .85; }
.sb-dash [data-icon] svg { width: 18px; height: 18px; }
.sb-dash-go { margin-left: auto; opacity: .5; font-size: 18px; line-height: 1; }

/* Report a bug: a quiet link at the foot of the sidebar, and a small dialog. */
.sb-bug {
  display: flex; align-items: center; gap: 10px; width: 100%; margin: 0 0 4px; padding: 7px 10px;
  border: 0; border-radius: 10px; background: transparent; color: var(--sb-muted, var(--muted)); font: inherit; font-size: 13.5px;
  text-align: left; cursor: pointer; transition: background-color .15s ease, color .15s ease;
}
.sb-bug:hover { background: rgba(255, 255, 255, .05); color: var(--sb-ink, var(--ink)); }
.sb-bug [data-icon] { display: inline-flex; width: 18px; height: 18px; opacity: .8; }
.sb-bug [data-icon] svg { width: 18px; height: 18px; }
.bug-dlg { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: 16px; background: rgba(0, 0, 0, .55); }
.bug-dlg.hide { display: none; }
.bug-box { width: min(520px, 100%); padding: 22px; border-radius: 16px; background: var(--panel); border: 1px solid var(--line); box-shadow: 0 24px 80px rgba(0, 0, 0, .5); }
.bug-box h2 { margin: 0 0 6px; font-size: 18px; font-weight: 600; }
.bug-box p { margin: 0 0 14px; font-size: 14px; line-height: 1.5; color: var(--muted); }
.bug-box textarea { width: 100%; box-sizing: border-box; resize: vertical; min-height: 120px; padding: 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg, #0b0a0c); color: var(--ink); font: inherit; font-size: 14.5px; line-height: 1.5; }
.bug-box textarea:focus { outline: none; border-color: rgba(255, 255, 255, .28); }
.bug-btns { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.bug-cancel, .bug-send { font: inherit; font-size: 14px; padding: 9px 16px; border-radius: 10px; cursor: pointer; }
.bug-cancel { background: transparent; border: 1px solid var(--line); color: var(--ink); }
.bug-send { border: 0; color: #fff; background: linear-gradient(100deg, #e10600, #ff4d0a); }
.bug-send:disabled { opacity: .6; cursor: progress; }

/* The composer's buttons are one family: the same circle, the same size, the
   same line icon. Send keeps its fill because it is the one that goes. */
.composer-row .attach, .composer-row .send, .composer.dictating .dict-btn {
  display: inline-grid; place-items: center; flex: none;
  width: 36px; height: 36px; padding: 0; margin: 0; border: 0; border-radius: 50%;
  font-size: 0; line-height: 0; cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.composer-row .attach, .composer.dictating .dict-btn { background: var(--chip); color: var(--muted); }
.composer-row .attach:hover, .composer.dictating .dict-btn:hover { background: color-mix(in srgb, var(--chip) 70%, var(--ink) 12%); color: var(--ink); }
.composer-row .attach svg, .composer-row .send svg, .composer.dictating .dict-btn svg { width: 18px; height: 18px; }
.composer-row .mic.live { color: var(--accent); }
.composer-row { gap: 8px; }

/* Waiting on the model: the word, with a band of light running through it.
   A loading state, so it is the one place a shimmer belongs. */
.thinking {
  display: inline-block; margin: 2px 0; font-size: 15px; font-weight: 500;
  color: transparent; -webkit-background-clip: text; background-clip: text;
  /* A tile with one bright band, repeated, moved by exactly one tile per
     loop: the last frame is the first, so there is no jump. */
  background-image: linear-gradient(100deg, var(--faint) 0%, var(--faint) 35%, var(--ink) 50%, var(--faint) 65%, var(--faint) 100%);
  background-size: 9em 100%; background-repeat: repeat-x; background-position: 0 0;
  animation: think-shimmer 1.9s linear infinite;
}
@keyframes think-shimmer { from { background-position: 0 0; } to { background-position: 9em 0; } }
@media (prefers-reduced-motion: reduce) { .thinking { animation: none; color: var(--muted); background: none; } }

/* The queue: what goes next, above the box it was typed in. */
.queued { display: flex; flex-direction: column; gap: 4px; margin: 0 0 8px; }
.q-item { display: flex; align-items: center; gap: 10px; min-width: 0; padding: 7px 8px 7px 12px; border-radius: 10px; background: var(--chip); font-size: 13.5px; }
.q-n { flex: none; font-size: 11.5px; font-weight: 500; color: var(--faint); }
.q-t { flex: 1 1 auto; min-width: 0; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.q-x { flex: none; display: inline-grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--faint); cursor: pointer; }
.q-x:hover { color: var(--ink); background: color-mix(in srgb, var(--chip) 60%, var(--ink) 10%); }
.q-x svg { width: 14px; height: 14px; }

/* One scroller, one bar, the full height of the sidebar, the way Lux and
   ChatGPT do it. The whole column scrolls; the top block (wordmark, New chat,
   search) is pinned to its top and the account block to its bottom, and the
   chats pass under both. The bar belongs to the column, so it runs edge to
   edge instead of stopping at the list.

   No scrollbar-width or scrollbar-color on it: either one switches Chromium to
   the native bar, which on Windows is the one with arrow buttons on the ends.
   The ::-webkit-scrollbar rules are the only family that can drop them. */
.sb { padding: 0; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; }
/* scrollbar-color is inherited, and the page sets it on html, so without this
   the sidebar inherits it and Chromium switches to the native bar (black
   track, arrow buttons) and ignores every rule below. */
.sb { scrollbar-color: auto; scrollbar-width: auto; }
.sb::-webkit-scrollbar { width: 8px; background: transparent; }
.sb::-webkit-scrollbar-track { background: transparent; margin: 0; }
.sb::-webkit-scrollbar-thumb { background: rgba(128, 128, 128, .3); border-radius: 4px; }
.sb::-webkit-scrollbar-thumb:hover { background: rgba(128, 128, 128, .45); }
.sb::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
.sb-top { position: sticky; top: 0; z-index: 3; flex: none; padding: 10px 10px 4px; background: var(--sb-bg); }
.sb .sb-list { flex: 1 0 auto; overflow: visible; min-height: 0; margin: 0; padding: 8px 6px 12px 10px; scrollbar-width: auto; }
.sb .sb-foot { position: sticky; bottom: 0; z-index: 3; flex: none; padding: 10px 10px 12px; background: var(--sb-bg); }

/* Paperclip on the left; the mic sits with send on the right, where the hand
   already is. The hint takes the space between. */
.composer-row .composer-hint { order: 1; flex: 1 1 auto; }
.composer-row #attach { order: 0; }
.composer-row .dict-btn, .composer-row .dict-wave, .composer-row .dict-busy { order: 2; }
.composer-row #mic { order: 3; }
.composer-row .send { order: 4; }

/* Send: one flat colour, no gradient, no glow. Orange when there is something
   to send, a quiet grey when there is not, white with a dark square to stop. */
.composer-row .send { background: #f2610a; color: #fff; box-shadow: none; }
.composer-row .send:hover:not(:disabled) { background: #ff7424; }
.composer-row .send:disabled { background: var(--chip); color: var(--faint); }
.composer-row .send.stop { background: var(--ink); color: var(--bg); }
.composer-row .send.stop:hover { background: color-mix(in srgb, var(--ink) 85%, var(--bg)); }


.thinking-row { display: inline-flex; align-items: center; gap: 8px; }
.thinking-row .typing { margin: 0; flex: none; }

/* Dragging a file over the chat: the composer is the target. */
.composer.dropping { position: relative; border-color: #ff6a1a; box-shadow: 0 0 0 3px color-mix(in srgb, #ff4d0a 22%, transparent); }
.composer.dropping > * { opacity: .25; }
.composer.dropping::after {
  content: 'Drop to attach'; position: absolute; inset: 0; display: grid; place-items: center;
  border-radius: inherit; background: color-mix(in srgb, #ff4d0a 7%, transparent);
  color: var(--ink); font-size: 14.5px; font-weight: 500; pointer-events: none;
}

/* The model looked through earlier chats for this answer. */
.recall-note { display: inline-flex; align-items: center; gap: 7px; margin: 0 0 8px; font-size: 12.5px; color: var(--faint); }
.recall-note svg { width: 14px; height: 14px; }

/* Sign in: a title, one line, one field, one button. */
.signin h1 { margin-bottom: 6px; }
.signin #step1 > p, .signin #step2 > p { margin: 0 0 18px; }
.signin input { margin-bottom: 10px; }
.signin .signin-note { border-top: 0; margin-top: 14px; padding-top: 0; }

/* Google and GitHub above the email field, then a rule with the words in it. */
.gate-oauth { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
.gate-oauth-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px; height: 44px; padding: 0 14px;
  border-radius: 12px; background: #0f0e11; border: 1px solid #2e2c33;
  color: var(--ink); font: 500 14px/1 var(--sans); transition: background .15s ease, border-color .15s ease;
}
.gate-oauth-btn:hover { text-decoration: none; background: #1c1a20; border-color: #3a3840; }
.gate-oauth-btn svg { width: 18px; height: 18px; flex: none; }
.gate-or { display: flex; align-items: center; gap: 14px; margin: 18px 0; color: var(--faint); font-size: 13px; }
.gate-or::before, .gate-or::after { content: ''; flex: 1; height: 1px; background: #2e2c33; }

/* Turnstile sits above the button and takes no room unless it has to ask. */
.ts-box:empty { display: none; }
.ts-box { margin: 0 0 10px; display: flex; justify-content: center; }

/* A chat row is one surface: the link's own hover tint (meant for the links
   at the foot of the sidebar) stays off it, so the title and the dots never
   read as two shades. */
.sb-item .sb-link, .sb-item .sb-link:hover { background: transparent; color: inherit; }
.sb-item:not(.active) .sb-link { color: color-mix(in srgb, var(--ink) 86%, var(--muted)); }
.sb-item:hover .sb-link { color: var(--ink); }
.sb-item .sb-more { background: transparent; }
.sb-item .sb-more:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }

/* One scrollbar everywhere in the app, the sidebar's: an 8px rounded thumb on
   a transparent track, no arrow buttons. The standard properties are reset
   because either one (inherited from html, or set as `thin` on a scroller)
   makes Chromium draw the native bar and ignore these rules. */
.shell, .shell * { scrollbar-width: auto !important; scrollbar-color: auto !important; }
.shell ::-webkit-scrollbar { width: 8px; height: 8px; background: transparent; }
.shell .sb::-webkit-scrollbar { width: 8px; }
.shell ::-webkit-scrollbar-track { background: transparent; margin: 0; }
.shell ::-webkit-scrollbar-thumb { background: rgba(128, 128, 128, .3); border-radius: 4px; }
.shell ::-webkit-scrollbar-thumb:hover { background: rgba(128, 128, 128, .45); }
.shell ::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
.shell ::-webkit-scrollbar-corner { background: transparent; }

/* An empty chat sits above the middle of the screen, where the eye lands,
   rather than dead centre. */
.main:has(.thread.is-empty) .thread { flex: 1 1 0; }
.main:has(.thread.is-empty) .composer-wrap { flex: 2.4 1 0; }

/* Send: a warm gradient disc with a soft glow and a bolder arrow when there
   is something to send; quiet grey when there is not. Feedback on hover is
   colour only, it never moves. */
.composer-row .send:not(:disabled):not(.stop) {
  background: linear-gradient(140deg, #ff8a3d 0%, #f2610a 55%, #d9400a 100%);
  box-shadow: 0 4px 14px rgba(242, 97, 10, .38), inset 0 1px 0 rgba(255, 255, 255, .28);
}
.composer-row .send:not(:disabled):not(.stop):hover {
  background: linear-gradient(140deg, #ff9a52 0%, #ff6f1a 55%, #e64a0d 100%);
  box-shadow: 0 4px 18px rgba(242, 97, 10, .5), inset 0 1px 0 rgba(255, 255, 255, .32);
}
.composer-row .send svg { stroke-width: 2.4; }
.composer-row .send:disabled { box-shadow: none; }

/* Sign in, refined: a quiet card with a faint warm glow behind it, the mark
   on its own line, rounded fields with a warm focus ring, and one orange
   button. Hover is colour only. */
.signin { background: radial-gradient(60% 50% at 50% 38%, rgba(242, 97, 10, .07), transparent 70%), var(--bg); }
.signin .signin-card {
  max-width: 380px; padding: 34px 32px 26px; border-radius: 20px;
  background: linear-gradient(180deg, #1c1b20, #17161a);
  border: 1px solid rgba(255, 255, 255, .07);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .04);
}
.signin .signin-logo { margin-bottom: 26px; font-size: 16px; }
.signin .signin-card h1 { font-size: 24px; font-weight: 400; letter-spacing: -0.02em; margin: 0 0 6px; }
.signin #step1 > p, .signin #step2 > p { font-size: 14px; line-height: 1.5; margin: 0 0 20px; }
.signin .signin-card input {
  height: 46px; padding: 0 14px; margin-bottom: 12px; border-radius: 12px;
  background: #0f0e11; border: 1px solid #2e2c33; color: var(--ink); font-size: 15px;
  transition: border-color .15s, box-shadow .15s;
}
.signin .signin-card input::placeholder { color: #6b6872; }
.signin .signin-card input:focus { outline: none; border-color: color-mix(in srgb, #ff4d0a 60%, #2e2c33); box-shadow: 0 0 0 3px color-mix(in srgb, #ff4d0a 16%, transparent); }
.signin .signin-card .btn {
  height: 46px; padding: 0; border: 0; border-radius: 12px; font-size: 15px; font-weight: 500; color: #fff;
  background: linear-gradient(140deg, #ff8a3d 0%, #f2610a 55%, #d9400a 100%);
  box-shadow: 0 6px 20px rgba(242, 97, 10, .28), inset 0 1px 0 rgba(255, 255, 255, .25);
  transition: filter .15s, box-shadow .15s;
}
.signin .signin-card .btn:hover:not(:disabled) { filter: brightness(1.07); box-shadow: 0 6px 24px rgba(242, 97, 10, .4), inset 0 1px 0 rgba(255, 255, 255, .3); }
.signin .signin-card .btn:disabled { opacity: .6; }
.signin .signin-card .notice { border-radius: 12px; font-size: 13.5px; }
.signin .signin-note { margin-top: 18px; font-size: 12.5px; }
@media (max-width: 480px) { .signin .signin-card { padding: 28px 22px 22px; } }

/* No faint fades over the flat page: some screens render them as a white
   dotted ring. The sign-in backdrop is a real image (the USGS Kilauea photo,
   blurred and darkened in the file), and glows sit only on solid surfaces. */
.signin .signin-card { box-shadow: none; border-color: rgba(255, 150, 90, .14); background: #18171b; }
.signin .signin-card .btn { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25); }
.signin .signin-card .btn:hover:not(:disabled) { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3); }
.composer-row .send:not(:disabled):not(.stop), .composer-row .send:not(:disabled):not(.stop):hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28); }
.signin { min-height: 100vh; min-height: 100dvh; background-attachment: fixed; }

/* One scroller for the chat column, like the sidebar: the bar runs the full
   height of the window. The top bar is pinned to its top and the composer to
   its bottom, both solid, and the conversation passes under them. */
.main { overflow-y: auto; overflow-x: hidden; min-height: 0; height: 100%; }
.main > .topbar { position: sticky; top: 0; z-index: 6; background: var(--main-bg); }
.main > .thread { flex: 1 0 auto; overflow: visible; min-height: 0; }
.main > .composer-wrap { position: sticky; bottom: 0; z-index: 6; background: var(--main-bg); padding-top: 8px; }
.main:has(.thread.is-empty) > .thread { flex: 1 1 0; }
.main:has(.thread.is-empty) > .composer-wrap { flex: 2.4 1 0; position: static; background: transparent; }

/* The code as six boxes. */
.otp { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; margin: 0 0 12px; }
.signin .signin-card .otp input {
  width: 100%; height: 54px; margin: 0; padding: 0; text-align: center;
  font: 500 22px/1 var(--mono, ui-monospace, monospace); color: var(--ink);
  border-radius: 12px; background: #0f0e11; border: 1px solid #2e2c33; caret-color: #ff6a1a;
}
.signin .signin-card .otp input:focus { outline: none; border-color: color-mix(in srgb, #ff4d0a 60%, #2e2c33); box-shadow: 0 0 0 3px color-mix(in srgb, #ff4d0a 16%, transparent); }

/* The empty chat sat too high on a tall screen: a little above the middle. */
.main:has(.thread.is-empty) > .composer-wrap { flex: 1.45 1 0; }

/* Model prices: cache hit, cache miss and output side by side, per 1M tokens. */
.mp-price { display: inline-flex; gap: 14px; align-items: flex-end; }
.mp-fig { display: inline-flex; flex-direction: column; align-items: flex-end; min-width: 52px; }
.mp-fig b { font-weight: 500; font-size: 12.5px; color: var(--ink); }
.mp-fig small { display: block; margin: 1px 0 0; font-size: 10.5px; color: var(--faint); }
.mp-fig.hit b { color: var(--ink); }
@media (max-width: 640px) {
  /* Name on top, then the three prices as even columns across the full row. */
  .mp-row { padding: 12px 8px 12px 14px; gap: 8px; }
  .mp-price { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; width: 100%; }
  .mp-fig { align-items: flex-start; min-width: 0; }
  .mp-fig b { font-size: 14.5px; }
  .mp-fig small { font-size: 11px; margin-top: 2px; }
  .mp-price small { display: block; margin-left: 0; }
}

/* Attached files: a chip with the name, in the composer and in the bubble. */
.chip-file { position: relative; display: inline-flex; align-items: center; gap: 8px; max-width: 260px; height: 52px; padding: 0 30px 0 12px; border-radius: 12px; background: var(--chip); border: 1px solid var(--line); vertical-align: top; }
.chip-file svg { width: 18px; height: 18px; flex: none; color: var(--muted); }
.chip-file .cf-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; color: var(--ink); }
.chip-file small { position: absolute; left: 38px; bottom: 6px; font-size: 10.5px; color: var(--faint); }
.chip-file .cf-name { margin-top: -12px; }
.chip-file button { position: absolute; top: 6px; right: 6px; width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--muted); font-size: 14px; line-height: 1; cursor: pointer; }
.chip-file button:hover { color: var(--ink); }
.bubble-files { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.bubble-file { display: inline-flex; align-items: center; gap: 7px; max-width: 240px; padding: 6px 10px; border-radius: 10px; background: color-mix(in srgb, var(--ink) 7%, transparent); font-size: 13px; }
.bubble-file svg { width: 15px; height: 15px; flex: none; color: var(--muted); }
.bubble-file span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Reply footer: small soft pills, the sans face, no dotted underlines. */
.meta { display: inline-flex; align-items: center; gap: 6px; margin-left: 6px; font: 500 11.5px/1 var(--sans); color: var(--faint); }
.meta .mt { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 5%, transparent); font-variant-numeric: tabular-nums; }
.meta .mt svg { width: 12px; height: 12px; }
.meta .mt-btn { border: 0; cursor: pointer; color: var(--faint); text-decoration: none; font: inherit; }
.meta .mt-btn:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 10%, transparent); }
/* Send now, inside a queued message. */
.q-now { flex: none; height: 24px; padding: 0 10px; border: 0; border-radius: 999px; background: color-mix(in srgb, #f2610a 22%, transparent); color: #ffb489; font: 500 12px var(--sans); cursor: pointer; }
.q-now:hover { background: color-mix(in srgb, #f2610a 32%, transparent); color: #fff; }

/* A chat's title runs the full width of its row; the dots float over the end
   only while the row is hovered, open or current. */
/* .sb-link is also the rail link class further up, which makes it a flex box,
   and text-overflow does nothing on a flex container. Chat titles need a
   plain block so long ones end in an ellipsis instead of running off. */
.sb-item .sb-link { display: block; padding-right: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-item .sb-more { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); margin: 0; }
.sb-item:hover .sb-link, .sb-item.active .sb-link, .sb-item.menu-open .sb-link { padding-right: 38px; }
@media (hover: none) { .sb-item .sb-link { padding-right: 38px; } }

/* The arrow up at the model picker, shown on a first visit and now and then
   after. Hand-drawn on purpose: it is a nudge, not part of the interface. */
.pick-hint { position: absolute; top: 6px; left: clamp(70px, 9vw, 120px); display: flex; align-items: flex-end; gap: 10px;
  color: #c9cbd1; pointer-events: none; animation: pick-in .5s ease both; }
.pick-hint svg { width: 118px; height: 84px; flex: none; color: #8a8d95; }
.pick-hint span { margin: 0 0 -10px -16px; font: 500 27px/1 "Caveat", "Segoe Print", cursive; color: #9a9da5; transform: rotate(-6deg); white-space: nowrap; }
/* Drawn on, line first, then the head. */
.pick-hint .ph-line { stroke-dasharray: 260; stroke-dashoffset: 260; animation: ph-draw .9s .15s ease-out forwards; }
.pick-hint .ph-head { opacity: 0; animation: ph-head .2s 1s ease-out forwards; }
@keyframes ph-draw { to { stroke-dashoffset: 0; } }
@keyframes ph-head { to { opacity: 1; } }
.thread.is-empty { position: relative; }
@keyframes pick-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .pick-hint, .pick-hint .ph-line, .pick-hint .ph-head { animation: none; stroke-dashoffset: 0; opacity: 1; } }

/* Reply footer: no boxes. Plain icons and small grey figures that brighten on hover.
   The numbers are there for whoever looks, and do not frame the answer. */
.msg-actions .act,
.meta .mt {
  height: 24px; min-width: 24px; padding: 0 6px; gap: 5px;
  border: 0; border-radius: 6px; background: none;
  color: var(--faint);
  font: 400 11.5px/1 var(--sans); font-variant-numeric: tabular-nums;
}
.msg-actions .act { padding: 0; width: 24px; }
.msg-actions .act svg, .meta .mt svg { width: 13px; height: 13px; flex: none; opacity: .75; }
.msg-actions .act:hover, .meta .mt-btn:hover { background: none; color: var(--ink); }
.msg-actions { gap: 2px; }
.meta { gap: 2px; margin-left: 0; }

/* Same rail as the dashboard: width, padding, wordmark and nav rows all match
   .dash-rail so moving between chat and dashboard does not shift anything. */
:root { --sb-w: 272px; }
.sb-top { padding: 14px 16px 4px; }
.sb-head { padding: 0 0 22px 4px; }
.sb-head .logo { font-size: 19px; gap: 9px; letter-spacing: -0.03em; }
.sb-head .logo .mark-svg { width: 26px; height: 26px; }
.sb-top .sb-new { gap: 12px; padding: 8px 12px; border-radius: 8px; font-size: 14.5px; color: var(--sb-ink); }
.sb-top .sb-new + .sb-new { margin-top: 2px; }
.sb-top .sb-new [data-icon] svg { width: 18px; height: 18px; opacity: .85; }
.sb-top .sb-new:hover { background: #232226; color: var(--ink); }
/* New chat sits in its own small box so it reads as the main action. */
.sb-top #newChat.sb-new { border: 1px solid var(--line, #38363c); background: #1d1c20; padding: 9px 12px; }
.sb-top #newChat.sb-new:hover { background: #26252a; border-color: #4a484f; }
/* New chat and the account button are one style: same box, radius, height and type. */
.sb-top #newChat.sb-new, .sb-foot .sb-user { box-sizing: border-box; min-height: 44px; padding: 0 12px; gap: 12px; border: 1px solid var(--line, #38363c); border-radius: 10px; background: #1d1c20; font-size: 14.5px; color: var(--sb-ink); }
.sb-top #newChat.sb-new:hover, .sb-foot .sb-user:hover, .sb-foot .sb-user[aria-expanded="true"] { background: #26252a; border-color: #4a484f; }
/* The break between the two actions and the history below them: a hairline that
   fades out at both ends with one small diamond in the middle. */
.sb-delim { position: relative; height: 1px; margin: 14px 12px 6px; background: linear-gradient(90deg, transparent, var(--sb-edge) 22%, var(--sb-edge) 78%, transparent); }
.sb-delim::after { content: ""; position: absolute; left: 50%; top: 50%; width: 5px; height: 5px; background: #e5484d; transform: translate(-50%, -50%) rotate(45deg); box-shadow: 0 0 0 4px var(--sb-bg); }
.sb .sb-list { padding: 8px 8px 12px 16px; }
.sb .sb-group-label { padding-left: 12px; }
.sb .sb-item .sb-link { padding-left: 12px; }
.sb .sb-foot { padding: 10px 16px 12px; }

/* The reasoning-token count that ticks up inside the Thinking line. It is part
   of the same shimmering text, just not italic or heavier than the word. */
.thinking .think-n { font-weight: 600; font-variant-numeric: tabular-nums; }

/* The brand word moves a little: the molten highlight drifts across it and the glow breathes.
   The picker rows keep it plain (.mp-btn .xpl, .mp-menu .xpl above). */
.xpl { animation: xpl-drift 6s ease-in-out infinite alternate, xpl-breathe 3.6s ease-in-out infinite; }
@keyframes xpl-drift { to { background-position: 100% 0, 0 0; } }
@keyframes xpl-breathe {
  50% {
    filter: drop-shadow(0 .03em 0 #c22a00) drop-shadow(0 .03em 0 #7e1200) drop-shadow(0 .04em .02em #3a0600)
            drop-shadow(0 0 .2em rgba(255, 90, 0, .75)) drop-shadow(0 0 .6em rgba(255, 50, 0, .45));
  }
}
@media (prefers-reduced-motion: reduce) { .xpl { animation: none; } }

/* What Xploded means, in a small card under the word while it is hovered (xplTip in app.js). */
.xpl-tip {
  position: fixed; z-index: 2147482000; width: 320px; max-width: calc(100vw - 16px); box-sizing: border-box; padding: 12px 14px;
  border-radius: 12px; background: var(--panel); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line), 0 12px 32px rgba(0, 0, 0, .35);
  font: 400 13px/1.5 var(--sans); text-align: left; pointer-events: none;
  opacity: 0; visibility: hidden; transform: translateY(-4px); transition: opacity .15s ease, transform .15s ease, visibility .15s;
}
.xpl-tip.on { opacity: 1; visibility: visible; transform: none; }
.xpl-tip b { display: block; margin-bottom: 4px; font-weight: 600; color: #ff8a44; }
.xpl-tip span { display: block; color: var(--muted); }

/* Zero data retention, said where people type. */
.composer-zdr { margin: 8px 0 0; text-align: center; font-size: 12px; color: var(--faint); }


.mr-ui .intro-name.mr-greet { font-size: clamp(30px, 3.4vw, 42px); letter-spacing: -0.03em; }
.mr-ui .composer-row { justify-content: flex-start; }
.mr-ui .composer-row .composer-hint { flex: 0 1 auto; }
.mr-ui .composer-row .mp-btn,
.mr-ui .tk-btn {
  display: inline-flex; align-items: center; gap: 6px; flex: none; min-width: 0;
  height: 32px; padding: 0 9px; border: 0; border-radius: 10px;
  background: transparent; color: var(--ink);
  font: 400 13.5px/1 var(--sans); letter-spacing: 0; cursor: pointer;
  transition: background-color .15s ease;
}
.mr-ui .composer-row .mp-btn:hover,
.mr-ui .composer-row .mp-btn[aria-expanded="true"],
.mr-ui .tk-btn:hover,
.mr-ui .tk-btn[aria-expanded="true"] { background: var(--chip); }
.mr-ui .composer-row .mp-btn-name { display: inline-flex; align-items: center; gap: 7px; max-width: none; }
.mr-ui .mp-btn-text { max-width: 220px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mr-ui .composer-row .mp-btn [data-icon] svg,
.mr-ui .tk-btn svg { width: 15px; height: 15px; }
.mr-ui .tk-btn svg { color: var(--muted); flex: none; }
/* Everything after the pickers (the hint, voice and send) sits at the right. */
.mr-ui .tk-btn { margin-right: auto; }


.mr-ui .mr-mark { flex: none; position: relative; width: 18px; height: 18px; }
.mr-ui .mr-mark::before {
  content: ""; position: absolute; inset: 0; background: linear-gradient(135deg, #e10600, #ff4d0a 50%, #ff9a1f);
  -webkit-mask: var(--m) center / contain no-repeat; mask: var(--m) center / contain no-repeat;
}
.mr-ui .mr-mark-letter { display: inline-grid; place-items: center; font: 600 13px/1 var(--sans); color: transparent;
  background: linear-gradient(135deg, #e10600, #ff4d0a 50%, #ff9a1f); -webkit-background-clip: text; background-clip: text; }
.mr-ui .mr-mark-letter::before { content: none; }

/* The model menu: mark, name, one line of what it is for, the check, and the page link. */
.mr-ui .mp-row { grid-template-columns: 30px minmax(0, 1fr) 18px 28px; }
.mr-ui .mp-row .mr-mark { width: 30px; height: 30px; border-radius: 9px; }
.mr-ui .mp-row .mr-mark::before { inset: 7px; }
.mr-ui .mp-row .mr-mark-letter { font-size: 13px; }
.mr-ui .mp-desc { font-size: 12.5px; line-height: 1.35; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The Thinking menu. */
.mr-ui .tk-menu { width: min(280px, calc(100vw - 24px)); padding: 6px; }
.mr-ui .tk-h { padding: 8px 10px 6px; font-size: 12px; color: var(--faint); }
.mr-ui .tk-menu button {
  display: flex; align-items: center; gap: 12px; width: 100%;
  border: 0; background: transparent; color: var(--ink);
  padding: 8px 10px; border-radius: 10px; text-align: left; font: inherit; cursor: pointer;
  transition: background-color .12s ease;
}
.mr-ui .tk-menu button:hover,
.mr-ui .tk-menu button:focus-visible { background: var(--chip); outline: none; }
.mr-ui .tk-txt { flex: 1; display: grid; gap: 2px; min-width: 0; }
.mr-ui .tk-txt b { font-weight: 600; font-size: 14px; }
.mr-ui .tk-txt small { font-size: 12.5px; color: var(--muted); }
.mr-ui .tk-check { flex: none; color: var(--ink); visibility: hidden; }
.mr-ui .tk-check svg { width: 16px; height: 16px; display: block; }
.mr-ui .tk-menu [aria-checked="true"] .tk-check { visibility: visible; }

/* Attachments inside the box, above the text, with the file's name over a thumbnail on hover. */
.mr-ui .attached { position: static; margin: 2px 0 12px; }
.mr-ui .chip-img { width: 92px; height: 92px; }
.mr-ui .chip-img img { border-radius: 14px; box-shadow: none; }
.mr-ui .chip-img button { top: 6px; right: 6px; width: 24px; height: 24px; background: rgba(18, 17, 21, .88); border-color: rgba(255, 255, 255, .14); }
.mr-ui .chip-img[data-name]::after {
  content: attr(data-name); position: absolute; left: 50%; bottom: calc(100% + 8px); transform: translateX(-50%);
  max-width: 220px; padding: 4px 9px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--ink); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; pointer-events: none; transition: opacity .12s ease;
}
.mr-ui .chip-img:hover::after { opacity: 1; }

/* On a phone the model's name gives way first, so voice and send always fit on the row. */
.mr-ui .composer-row .mp-btn { flex: 0 1 auto; }
.mr-ui .composer-row .mp-btn-name { min-width: 0; overflow: hidden; }
.mr-ui .composer-row .mp-btn-name .mr-mark { flex: none; }
.mr-ui .mp-btn-text { min-width: 0; }
@media (max-width: 720px) {
  .mr-ui .composer-row { justify-content: flex-start; gap: 2px; }
  .mr-ui .mp-btn-text { max-width: 30vw; }
  .mr-ui .composer-row .mp-btn, .mr-ui .tk-btn { padding: 0 6px; font-size: 14px; gap: 5px; }
  .mr-ui .mp-row { grid-template-columns: 30px minmax(0, 1fr) 28px; }
  .mr-ui .chip-img { width: 76px; height: 76px; }
}

/* The composer in the console look (7 Nov 2026): cut corners with a 1px edge that runs along them,
   built like the dashboard's panels (the edge colour clipped to an octagon, the box colour 1px
   inside), so a clipped box-shadow is not needed for the outline. The send button is cut too. */
.mr-ui .composer { --cut: 12px; isolation: isolate; border: 0; border-radius: 0; box-shadow: none; background: var(--line);
  clip-path: polygon(var(--cut) 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, var(--cut) 100%, 0 calc(100% - var(--cut)), 0 var(--cut)); }
.mr-ui .composer::before { content: ""; position: absolute; inset: 1px; z-index: -1; background: color-mix(in srgb, var(--surface) 97%, #fff 3%);
  clip-path: polygon(calc(var(--cut) - .4px) 0, calc(100% - var(--cut) + .4px) 0, 100% calc(var(--cut) - .4px), 100% calc(100% - var(--cut) + .4px), calc(100% - var(--cut) + .4px) 100%, calc(var(--cut) - .4px) 100%, 0 calc(100% - var(--cut) + .4px), 0 calc(var(--cut) - .4px)); }
.mr-ui .composer:focus-within { box-shadow: none; background: color-mix(in srgb, #ff4d0a 45%, var(--line)); }
.mr-ui .send, .mr-ui .attach { --cut: 7px; border-radius: 0;
  clip-path: polygon(var(--cut) 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, var(--cut) 100%, 0 calc(100% - var(--cut)), 0 var(--cut)); }
.mr-ui .composer-row .mp-btn, .mr-ui .tk-btn { border-radius: 0; }

/* Out of credit: one line under the composer with the way to top up. */
.mr-ui .mr-credit { display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; margin: 16px 0 0; font-size: 14px; color: var(--muted); }
.mr-ui .mr-credit-btn { --cut: 7px; display: inline-flex; align-items: center; padding: 10px 14px; background: #f2621c; color: #fff;
  font: 500 13px/1 var(--sans); letter-spacing: .02em; text-transform: uppercase; text-decoration: none;
  clip-path: polygon(var(--cut) 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, var(--cut) 100%, 0 calc(100% - var(--cut)), 0 var(--cut)); transition: background .15s; }
.mr-ui .mr-credit-btn:hover { background: #ff7430; color: #fff; text-decoration: none; }

/* A change of model inside a thread: a quiet rule with both models on it, the line running out to either side. */
.mr-ui .model-switch { display: flex; align-items: center; gap: 12px; min-width: 0; font-size: 13.5px; line-height: 1.3; color: var(--muted); }
.mr-ui .model-switch::before, .mr-ui .model-switch::after { content: ""; flex: 1 1 0; min-width: 10px; height: 1px; background: var(--line); }
.mr-ui .ms-m { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.mr-ui .ms-m .mr-mark { width: 16px; height: 16px; }
.mr-ui .ms-n { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mr-ui .ms-arrow { flex: none; color: var(--faint); }
@media (max-width: 480px) { .mr-ui .model-switch { gap: 8px; font-size: 12.5px; } .mr-ui .ms-m { gap: 6px; } .mr-ui .ms-m .mr-mark { width: 14px; height: 14px; } }
