/* The look follows the README's illustration: a screenprint of a web at
   dusk. Dark is the night sky, deep blue-black with amber light; light is the
   cream paper the print sits on, inked in navy. Both share a faint grain. */

:root {
  color-scheme: light dark;
  /* Paper. */
  --bg: #efe5d1; --panel: #f7f0e1; --fg: #1d2a3d; --dim: #5f6878;
  --line: #d5c8ad; --amber: #c9811f; --amber-text: #8f520c; --amber-wash: #f3dfb8;
  --on-amber: #1d2a3d; --glow: none;
  --ok: #2f6b45; --bad: #a3401f; --bad-bg: #f5ddd0;
  --grain-opacity: .35;
  --radius: 10px;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}
@media (prefers-color-scheme: dark) {
  :root {
    /* Night. */
    --bg: #0f141d; --panel: #151c28; --fg: #ece1cb; --dim: #8d95a4;
    --line: #253043; --amber: #f0a94a; --amber-text: #f2b25e; --amber-wash: #2a2416;
    --on-amber: #11161f; --glow: 0 0 .6rem rgba(240, 169, 74, .35);
    --ok: #9fc98a; --bad: #e58a64; --bad-bg: #2b1a16;
    --grain-opacity: .5;
  }
}

* { box-sizing: border-box; }
/* The page is the viewport's height, and the chat log scrolls inside it;
   on a narrow screen the page scrolls instead (below). */
body {
  margin: 0; height: 100vh; height: 100dvh; display: flex; flex-direction: column;
  background: var(--bg); color: var(--fg);
  font: 15px/1.6 ui-sans-serif, -apple-system, "Segoe UI", system-ui, sans-serif;
}
/* Print grain over everything, never in the way of a click. */
body::after {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 10;
  opacity: var(--grain-opacity); mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}
h1 {
  font: 600 1.45rem/1 var(--serif); margin: 0; letter-spacing: .01em;
  /* A slight second-ink offset, as a screenprint misregisters. */
  text-shadow: .06em .05em 0 color-mix(in srgb, var(--amber) 40%, transparent);
}
h2 { font: 600 1rem/1.3 var(--serif); margin: 0 0 .75rem; }
a { color: var(--amber-text); }

.bar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0 1.25rem .6rem; border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: flex-end; gap: .55rem; }

/* The spider hangs from the top of the page by its thread, and lets itself
   down a little on arrival. */
.spider { display: block; overflow: visible; }
.spider .thread { stroke: var(--dim); stroke-width: .6; }
.spider .legs path { fill: none; stroke: var(--amber); stroke-width: 1.15; stroke-linecap: round; }
.spider .body { fill: var(--amber); }
@media (prefers-color-scheme: dark) {
  .spider { filter: drop-shadow(0 0 3px rgba(240, 169, 74, .55)); }
}
@media (prefers-reduced-motion: no-preference) {
  .spider { animation: descend 1.6s cubic-bezier(.3, .7, .3, 1) both; transform-origin: 12px 0; }
  .brand:hover .spider { animation: sway 2.4s ease-in-out infinite; }
}
@keyframes descend { from { transform: translateY(-14px); } to { transform: none; } }
@keyframes sway { 50% { transform: rotate(4deg); } }

.device { font-size: .85rem; color: var(--dim); padding-top: .6rem; }
.device[data-state="ok"] { color: var(--ok); }
.device[data-state="bad"] { color: var(--bad); }

.layout {
  flex: 1; display: grid; grid-template-columns: 17rem 1fr; grid-template-rows: minmax(0, 1fr);
  gap: 1rem; padding: 1rem 1.25rem; min-height: 0;
}
/* A narrow screen gives the chat the screen: the models panel becomes a
   drawer from the left, behind the menu button (drawer.js). */
.menu-button, .drawer-close, .scrim, .choose-model { display: none; }
.side-head { display: flex; align-items: center; justify-content: space-between; }
.side-head h2 { margin: 0; }
.side:focus { outline: none; }
@media (max-width: 720px) {
  /* The visual viewport's height (viewport.js): with the keyboard up, the
     page fits above it, and the notice and footer step aside. */
  body { height: var(--app-height, 100dvh); }
  .keyboard-open .platform-notice, .keyboard-open .foot { display: none; }
  /* 16px or more, or iOS zooms the page into a field it focuses; specific
     enough to win over the fields' own sizes, set later in this sheet. */
  :root .layout :is(input, textarea) { font-size: 16px; }
  .bar { padding: env(safe-area-inset-top) .75rem .5rem; gap: .5rem; }
  .bar .brand { margin-right: auto; }
  .menu-button, .drawer-close {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; min-height: 44px; padding: 0; cursor: pointer;
    background: none; border: 0; border-radius: 8px;
  }
  .menu-button { margin-left: -.5rem; align-self: flex-end; margin-bottom: -.4rem; }
  .menu-button svg { stroke: var(--fg); stroke-width: 2; stroke-linecap: round; fill: none; }
  .drawer-close { font-size: 1.6rem; line-height: 1; color: var(--dim); margin-right: -.5rem; }
  .layout { grid-template-columns: 1fr; padding: .5rem; }
  .chat { padding: .75rem; }
  .side {
    position: fixed; inset: 0 auto 0 0; z-index: 30; width: min(20rem, 86vw);
    border-radius: 0 var(--radius) var(--radius) 0; border-left: 0;
    padding: calc(env(safe-area-inset-top) + 1rem) 1rem calc(env(safe-area-inset-bottom) + 1rem);
    transform: translateX(-105%);   /* closed, it is inert too (drawer.js) */
    box-shadow: 0 0 2rem rgba(0, 0, 0, .35);
  }
  .drawer-open .side { transform: none; }
  .scrim { display: block; position: fixed; inset: 0; z-index: 25; background: rgba(0, 0, 0, .45); }
  .scrim[hidden] { display: none; }
  .choose-model { display: inline-flex; margin-top: .75rem; }
  .platform-notice, .diagnostics { margin: .5rem .5rem 0; font-size: .85rem; }
  .foot { padding: 0 .75rem calc(env(safe-area-inset-bottom) + .5rem); font-size: .72rem; }
}
@media (max-width: 720px) and (prefers-reduced-motion: no-preference) {
  .side { transition: transform .22s ease; }
}
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem; min-width: 0;
}
.panel[hidden] { display: none; }
.empty { color: var(--dim); margin: 0; font-family: var(--serif); font-style: italic; }
button, input, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.side { display: flex; flex-direction: column; gap: 1rem; min-height: 0; overflow-y: auto; }
.models { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.model {
  width: 100%; text-align: left; cursor: pointer; display: grid; gap: .1rem;
  padding: .55rem .7rem; background: none;
  border: 1px solid var(--line); border-radius: 8px;
}
.model:hover { border-color: var(--dim); }
.model[aria-pressed="true"] { border-color: var(--amber); background: var(--amber-wash); box-shadow: var(--glow); }
.model-name { font-weight: 500; }
.model-facts { font-size: .8rem; color: var(--dim); }

.url-form { display: grid; gap: .35rem; font-size: .85rem; }
.url-form label { color: var(--dim); }
.url-row { display: flex; gap: .4rem; min-width: 0; }   /* shrinks with its grid track */
.url-row input {
  flex: 1; min-width: 0; padding: .35rem .5rem; font-family: var(--mono); font-size: .8rem;
  background: none; border: 1px solid var(--line); border-radius: 6px;
}
.url-row button, .action {
  padding: .35rem .8rem; cursor: pointer; background: none;
  border: 1px solid var(--line); border-radius: 6px;
}
.url-row button:hover, .action:hover { border-color: var(--amber); }
.action.primary {
  background: var(--amber); border-color: var(--amber); color: var(--on-amber); font-weight: 500;
}
.action.primary:hover { box-shadow: var(--glow); filter: brightness(1.05); }
.field-error { color: var(--bad); margin: 0; min-height: 1em; }

.model-panel:empty { display: none; }
.model-panel { font-size: .85rem; border-radius: 8px; padding: .6rem .75rem; border: 1px solid var(--line);
  display: grid; gap: .4rem; }
.model-panel p, .model-panel ul { margin: 0; }
.model-panel ul { padding-left: 1.1rem; }
.model-panel[data-state="bad"] { border-color: var(--bad); background: var(--bad-bg); }
.model-panel[data-state="ok"] { border-color: var(--amber); }
.model-heading { font-weight: 500; }
.later summary { cursor: pointer; color: var(--dim); }
.model-fit { color: var(--fg); }
.later ul { margin-top: .3rem; }
.model-panel .model-facts { color: var(--dim); font-size: .8rem; }
.actions { display: flex; gap: .4rem; }
.progress { display: grid; gap: .2rem; font-size: .8rem; color: var(--dim); }
.progress progress { width: 100%; accent-color: var(--amber); }

.cache { margin-top: auto; font-size: .85rem; }
.cache h2 { font-size: .9rem; margin-bottom: .4rem; }
.cached { list-style: none; margin: 0 0 .4rem; padding: 0; display: grid; gap: .3rem; }
.cached li { display: flex; justify-content: space-between; align-items: center; gap: .5rem; }
.cache-summary { color: var(--dim); font-size: .78rem; margin: 0; }

.platform-notice {
  margin: 1rem 1.25rem 0; padding: .7rem .9rem; font-size: .9rem;
  border: 1px solid var(--amber); border-radius: var(--radius); background: var(--amber-wash);
}
.platform-notice p { margin: 0; }
.platform-notice .platform-heading { font: 600 1rem/1.3 var(--serif); margin-bottom: .25rem; }
.platform-notice .actions { margin-top: .5rem; }

.diagnostics {
  margin: 1rem 1.25rem 0; padding: .7rem .9rem; font-size: .9rem; display: grid; gap: .75rem;
  border: 1px solid var(--bad); border-radius: var(--radius); background: var(--bad-bg);
}
.diagnostics[hidden] { display: none; }
.diagnostics-part { display: grid; gap: .35rem; }
.diagnostics p { margin: 0; overflow-wrap: anywhere; }
.diagnostics-heading { font: 600 1rem/1.3 var(--serif); }
.diagnostics-record {
  margin: 0; max-height: 12rem; overflow: auto; font: .75rem/1.4 var(--mono); white-space: pre-wrap;
  user-select: all;
}

.fake-banner {
  margin: 0; padding: .5rem 1.25rem; font-size: .85rem; font-weight: 500;
  background: var(--bad); color: #fff8ef;
}

/* The chat panel carries a faint web in its corner, strung with dew. */
.chat {
  display: flex; flex-direction: column; min-height: 0;
  background-repeat: no-repeat; background-position: top right; background-size: 15rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120' fill='none' stroke='%23c9811f' stroke-opacity='.28' stroke-width='.6'%3E%3Cpath d='M120 0 L20 0 M120 0 L45 55 M120 0 L80 100 M120 0 L120 110'/%3E%3Cpath d='M98 0 Q100 14 120 18 M76 0 Q80 30 120 38 M54 0 Q60 46 120 60 M34 0 Q40 64 120 84'/%3E%3Cg fill='%23f0a94a' fill-opacity='.45' stroke='none'%3E%3Ccircle cx='99' cy='9' r='1.1'/%3E%3Ccircle cx='79' cy='22' r='1.3'/%3E%3Ccircle cx='60' cy='38' r='1.1'/%3E%3Ccircle cx='104' cy='34' r='1.2'/%3E%3Ccircle cx='86' cy='58' r='1.3'/%3E%3Ccircle cx='48' cy='52' r='1'/%3E%3C/g%3E%3C/svg%3E");
}
.conversation { flex: 1; display: flex; flex-direction: column; gap: .75rem; min-height: 0; }
.chat-heading {
  margin: 0; font: 600 1.05rem/1.3 var(--serif);
  padding-bottom: .5rem; border-bottom: 1px solid var(--line);
}
.chat-log { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: .75rem; }
.message { max-width: 85%; white-space: pre-wrap; overflow-wrap: anywhere; }
.message p { margin: 0; }
.message.user {
  align-self: flex-end; background: var(--amber-wash); border: 1px solid var(--line);
  border-radius: 12px; padding: .45rem .8rem;
}
.message.assistant { align-self: flex-start; display: grid; gap: .35rem; }
.thinking { font-size: .85rem; color: var(--dim); border-left: 2px solid var(--amber); padding-left: .6rem; }
.thinking summary { cursor: pointer; }
.message-facts { font-size: .75rem; color: var(--dim); }
.chat-error { color: var(--bad); margin: 0; font-size: .85rem; }
.chat-error:empty { display: none; }
.composer {
  display: grid; gap: .4rem; border: 1px solid var(--line); border-radius: 12px; padding: .5rem .6rem;
  background: var(--bg);
}
.composer:focus-within { border-color: var(--amber); }
.composer textarea {
  background: none; border: 0; resize: vertical; outline: none;
}
.composer-row { display: flex; justify-content: space-between; align-items: center; }
.toggle { font-size: .85rem; color: var(--dim); display: flex; align-items: center; gap: .3rem; }
.toggle input { accent-color: var(--amber); }

/* The search panel (search.js) shares the chat's frame and composer, and
   scrolls as a whole: the document, the query and the results together are
   taller than a phone's screen. */
.search-panel { overflow-y: auto; overscroll-behavior: contain; }
.search-panel > * { flex: none; }
.search-query .composer-row { gap: .5rem; }
.search-query input { flex: 1; min-width: 0; background: none; border: 0; outline: none; }
.composer-row .message-facts { margin-right: .5rem; }
.search-results { margin: 0; padding: 0; list-style: none; display: grid; gap: .6rem; }
.search-results li { display: grid; grid-template-columns: auto 1fr; gap: .75rem; align-items: baseline; }
.search-results p { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.score { font: .8rem var(--mono); color: var(--amber-text); }

.foot { color: var(--dim); font-size: .8rem; padding: 0 1.25rem 1rem; }
