/* ==========================================================================
   app.css — Unblokia (PWA)
   Themes on <html>: theme-dragon | theme-samurai | theme-tormenta | theme-brasas | theme-marea | theme-tinta | theme-lluvia | theme-neon | theme-crt | theme-holograma | theme-papel | theme-leche | theme-orbita | theme-ejercito | theme-luciernagas | theme-contracorriente | theme-flexiones | theme-estrago
   (src/client/js/themes.js). A theme is a set of the variables below, a sky (--crt-sky) and, drawn on a canvas behind everything,
   a background (src/client/js/scenery.js). The variable names keep their old «crt» prefix: every rule below uses them.
   Panel effects: rhythm, feed and typos (src/client/js/fx.js); they belong to no theme.
   ========================================================================== */

/* ---------- Variables ---------- */
:root {
  /* Colour: the ink, what you type, the base, the sky behind everything and the soft dark patch behind the text.
     These are brasas, the default theme; every theme sets its own below. */
  --crt-fg: #efe7da;
  --crt-user: #f0a35e;                 /* what you type (the «>» and the prompt caret) */
  --crt-bg: #0b0e14;
  --crt-sky: radial-gradient(120% 80% at 50% 110%, #2a1a14 0%, #0b0e14 60%);
  --crt-scrim: rgba(0, 0, 0, 0.42);
  --crt-dim: color-mix(in srgb, var(--crt-fg) 50%, transparent);
  --crt-faint: color-mix(in srgb, var(--crt-fg) 8%, var(--crt-bg));

  /* Typography and reader: the text in the voice of the theme, the controls in a plain typeface */
  --crt-font: 'Cormorant Garamond', Georgia, serif;
  --crt-font-style: italic;
  --crt-font-weight: normal;
  --ui-font: 'Figtree', system-ui, sans-serif;
  --crt-reader-font-size: clamp(1.6rem, min(6.4vw, 26.37px), 2.1rem);
  --crt-reader-line-height: 1.5;
  --crt-reader-width: 24ch;
  --crt-reader-top: clamp(24px, 14vh, 150px);
  --crt-cursor-speed: 0.6s;
  --crt-glow: none;
}
@media (min-width: 820px) {
  :root { --crt-reader-width: 30ch; }
}

/* The themes (the first seven came with sound; the rest are silent for now) */
html.theme-dragon {
  --crt-fg: #f0f3fa; --crt-user: #ff8a3d; --crt-bg: #070b16;
  --crt-sky: radial-gradient(110% 65% at 65% 20%, #3a5285 0%, #1a2747 45%, #080c18 100%);
  --crt-scrim: rgba(6, 10, 22, 0.62);
  --crt-font: 'Lora', Georgia, serif; --crt-font-style: normal;      /* plain and easy to read: the uncial letters were not */
  --crt-reader-font-size: clamp(1.4rem, min(5.9vw, 24.3px), 1.9rem);
  --crt-reader-line-height: 1.75;
}
html.theme-samurai {
  --crt-fg: #f6ebe6; --crt-user: #f1b3b8; --crt-bg: #17132a;
  --crt-sky: linear-gradient(180deg, #141127 0%, #2b2142 45%, #6e4660 70%, #c98a86 84%, #2a1d2c 100%);
  --crt-scrim: rgba(20, 17, 39, 0.55);
  --crt-font: 'Shippori Mincho', serif; --crt-font-style: normal;
  --crt-reader-font-size: clamp(1.3rem, min(5.4vw, 22.25px), 1.75rem);
}
html.theme-tormenta {
  --crt-fg: #f2f5f9; --crt-user: #b9d4ff; --crt-bg: #0a0d12;
  --crt-sky: linear-gradient(180deg, #07090d 0%, #141a24 60%, #0a0d12 100%);
  --crt-scrim: rgba(8, 10, 14, 0.7);
  --crt-font: 'Literata', Georgia, serif; --crt-font-style: normal;
  --crt-reader-font-size: clamp(1.3rem, min(5.4vw, 22.25px), 1.75rem);
}
html.theme-brasas { /* the defaults of :root */ }
html.theme-marea {
  --crt-fg: #f6efe7; --crt-user: #f2c39b; --crt-bg: #0f1b2c;
  --crt-sky: linear-gradient(180deg, #0b1424 0%, #22385a 42%, #8f7184 60%, #f0b48c 68%, #0d1a2c 100%);
  --crt-scrim: rgba(14, 24, 42, 0.55);
  --crt-font: 'Marcellus', Georgia, serif; --crt-font-style: normal;
  --crt-reader-font-size: clamp(1.3rem, min(5.4vw, 22.25px), 1.75rem);
}
html.theme-tinta {
  --crt-fg: #f2f4fa; --crt-user: #ff4f9a; --crt-bg: #04060c;
  --crt-sky: var(--crt-bg);                                   /* the fluid covers it (scene-ink.js) */
  --crt-scrim: rgba(4, 6, 12, 0.55);
  --crt-font: 'Instrument Serif', Georgia, serif;
  --crt-reader-font-size: clamp(1.75rem, min(7.2vw, 29.66px), 2.35rem);
}
html.nogl.theme-tinta, html.nogl.theme-leche { --crt-sky: radial-gradient(80% 60% at 50% 40%, color-mix(in srgb, var(--crt-user) 30%, var(--crt-bg)), var(--crt-bg)); }   /* no WebGL2: a glow instead of the fluid */
html.theme-lluvia {
  --crt-fg: #e9eef2; --crt-user: #ffc27a; --crt-bg: #10151c;
  --crt-sky: linear-gradient(180deg, #0e131b 0%, #1a1f2a 60%, #2a2128 100%);
  --crt-font: 'Lora', Georgia, serif;
  --crt-reader-font-size: clamp(1.4rem, min(5.8vw, 23.9px), 1.85rem);
}
html.theme-neon {
  --crt-fg: #ffeefb; --crt-user: #ff4fd8; --crt-bg: #0d0518;
  --crt-sky: linear-gradient(180deg, #0d0518 0%, #25093a 40%, #5a1450 60%, #0d0518 60%);          /* the hard stop is the horizon (scene-draw.js) */
  --crt-scrim: rgba(13, 5, 24, 0.72);
  --crt-font: 'Chakra Petch', sans-serif; --crt-font-style: normal; --crt-font-weight: 300;
  --crt-reader-font-size: clamp(1.35rem, min(5.8vw, 23.9px), 1.8rem);
}                                                                                /* no glow on the text (--crt-glow): a blurred shadow behind every letter is dear to paint on a phone */
html.theme-crt {
  --crt-fg: #7dff9e; --crt-user: #ffb547; --crt-bg: #020a04;                    /* amber for what you type: a green screen, an amber caret */
  --crt-sky: #020a04;                                                           /* the rain of the scene paints over it (scene-draw.js) */
  --crt-scrim: rgba(2, 10, 4, 0.8);
  --crt-font: 'VT323', ui-monospace, monospace; --crt-font-style: normal;
  --crt-reader-font-size: clamp(1.6rem, min(7vw, 28.84px), 2.2rem);
  --crt-glow: 0 0 6px rgba(125, 255, 158, 0.75), 0 0 18px rgba(125, 255, 158, 0.25);
}
/* The terminal: the text is set from the left, not centred, the caret is a block and the screen has scan lines and dark corners */
html.theme-crt .reader-text:not(.kind-code) { text-align: left; text-wrap: wrap; }
html.theme-crt .crt-cursor:not([data-typo])::before { width: 0.55em; }
html.theme-crt body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 12;                                                                  /* over the text, under the buttons */
  pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 50%, transparent 55%, rgba(0, 0, 0, 0.75) 100%),
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.28) 0 1px, transparent 1px 3px);
  animation: crt-flicker 4s infinite;
}
@keyframes crt-flicker { 0%, 100% { opacity: 0.9; } 48% { opacity: 0.82; } 50% { opacity: 0.95; } 52% { opacity: 0.85; } }
@media (prefers-reduced-motion: reduce) { html.theme-crt body::after { animation: none; } }
html.theme-holograma {
  --crt-fg: #f1f4ff; --crt-user: #5ff3ff; --crt-bg: #07061a;
  --crt-sky: linear-gradient(180deg, #07061a 0%, #15123a 55%, #2b1a4a 80%, #07061a 100%);
  --crt-scrim: rgba(7, 6, 26, 0.6);
  --crt-font: 'Oxanium', sans-serif; --crt-font-style: normal; --crt-font-weight: 300;
  --crt-reader-font-size: clamp(1.35rem, min(5.6vw, 23.07px), 1.8rem);
}
html.theme-papel {
  color-scheme: light;                                                          /* a light theme: ink on paper (the range sliders and the scrollbars follow) */
  --crt-fg: #120d07; --crt-user: #9b6a2a; --crt-bg: #e9dec3;
  --crt-sky: radial-gradient(90% 60% at 50% 35%, #f7f0dd 0%, #e9dec3 70%, #d6c7a3 100%);
  --crt-scrim: rgba(243, 233, 208, 0.8);
  --crt-font: 'Newsreader', Georgia, serif; --crt-font-style: normal; --crt-font-weight: 400;
  --crt-reader-font-size: clamp(1.45rem, min(5.8vw, 23.9px), 1.9rem);
}
html.theme-leche {
  color-scheme: light;
  --crt-fg: #0a0806; --crt-user: #c2401f; --crt-bg: #f2eee6;
  --crt-sky: var(--crt-bg);                                   /* the fluid covers it (scene-ink.js) */
  --crt-scrim: rgba(244, 240, 232, 0.72);
  --crt-font: 'Fraunces', Georgia, serif; --crt-font-style: normal; --crt-font-weight: 400;
  --crt-reader-font-size: clamp(1.4rem, min(5.8vw, 23.9px), 1.85rem);
}
html.theme-orbita {
  --crt-fg: #f3f1ff; --crt-user: #ffbf7a; --crt-bg: #03040a;
  --crt-sky: radial-gradient(90% 60% at 100% 0%, #2a1d1a 0%, #03040a 55%);            /* the sun rising behind the planet, top right */
  --crt-scrim: rgba(3, 4, 10, 0.55);
  --crt-font: 'Exo 2', system-ui, sans-serif; --crt-font-style: normal; --crt-font-weight: 300;
  --crt-reader-font-size: clamp(1.35rem, min(5.6vw, 23.07px), 1.8rem);
}
html.theme-ejercito {
  --crt-fg: #fff3e6; --crt-user: #e8743a; --crt-bg: #160b0c;
  --crt-sky: linear-gradient(180deg, #1a0d10 0%, #4a1618 36%, #b2432b 58%, #f09a52 70%, #2a1210 100%);          /* the sunset behind the army */
  --crt-scrim: rgba(30, 12, 14, 0.62);
  --crt-font: 'Cormorant SC', Georgia, serif; --crt-font-style: normal; --crt-font-weight: 600;
  --crt-reader-font-size: clamp(1.45rem, min(6vw, 24.72px), 1.95rem);
}
html.theme-luciernagas {
  --crt-fg: #e8f1e1; --crt-user: #d9f27a; --crt-bg: #071510;
  --crt-sky: radial-gradient(120% 80% at 50% 100%, #12301f 0%, #071510 60%);          /* the glow of the forest floor */
  --crt-font: 'EB Garamond', Georgia, serif;                                          /* italic, as the default of the theme */
  --crt-reader-font-size: clamp(1.5rem, min(6.2vw, 25.54px), 2rem);
}
html.theme-contracorriente {
  --crt-fg: #eef1f6; --crt-user: #ff8a4c; --crt-bg: #0a0c10;
  --crt-sky: linear-gradient(180deg, #0b0d13 0%, #161c28 42%, #2a2230 62%, #3a2a2a 78%, #0a0b0e 100%);          /* the dusk behind the street (scene-draw.js draws the ground over it) */
  --crt-scrim: rgba(8, 10, 14, 0.62);
  --crt-font: 'Space Grotesk', sans-serif; --crt-font-style: normal; --crt-font-weight: 500;
  --crt-reader-font-size: clamp(1.3rem, min(5.6vw, 23.07px), 1.8rem);
}
html.theme-flexiones {
  --crt-fg: #f3ede2; --crt-user: #ff7a2f; --crt-bg: #0a0908;
  --crt-sky: linear-gradient(180deg, #0b0a09 0%, #15120f 60%, #090807 100%);
  --crt-scrim: rgba(10, 9, 8, 0.66);
  --crt-font: 'Barlow Condensed', sans-serif; --crt-font-style: normal; --crt-font-weight: 500;
  --crt-reader-font-size: clamp(1.6rem, min(6.8vw, 28.01px), 2.2rem);
}
html.theme-estrago {
  --crt-fg: #f2eee3; --crt-user: #ff2e63; --crt-bg: #0b0b0b;
  --crt-sky: radial-gradient(90% 70% at 50% 40%, #1a1918 0%, #0a0a0a 100%);
  --crt-scrim: rgba(8, 8, 8, 0.7);
  --crt-font: 'Special Elite', ui-monospace, monospace; --crt-font-style: normal; --crt-font-weight: 400;
  --crt-reader-font-size: clamp(1.2rem, min(5.2vw, 21.42px), 1.65rem);
  --crt-reader-line-height: 1.62;                                                     /* a touch looser than the 1.5 of the rest: the typewriter face is dense */
}
/* What never changes in these three is left to the browser (no canvas fill per frame): the dark corners, and the toner grain of estrago, a tile that scene-draw.js slides about */
html:is(.theme-contracorriente, .theme-flexiones, .theme-estrago) body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2;                                                                   /* over the background and the patch behind the text, under the text */
  pointer-events: none;
}
html.theme-contracorriente body::after { background: radial-gradient(ellipse 80% 72% at 50% 50%, transparent 42%, rgba(0, 0, 0, 0.66) 100%); }
html.theme-flexiones body::after { background: radial-gradient(ellipse 75% 70% at 50% 55%, transparent 38%, rgba(0, 0, 0, 0.74) 100%); }
html.theme-estrago body::after { background: radial-gradient(ellipse 80% 70% at 50% 50%, transparent 50%, rgba(0, 0, 0, 0.6) 100%); }
#grain { display: none; position: fixed; inset: 0; z-index: 2; pointer-events: none; }
html.theme-estrago #grain { display: block; }

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
html { background: var(--crt-bg); color-scheme: dark; -webkit-tap-highlight-color: transparent; }
body {
  background: var(--crt-sky);
  color: var(--crt-fg);
  font-family: var(--ui-font);
  overflow: hidden;
  height: 100dvh;
  user-select: none;
}

/* The background of the theme (src/client/js/scenery.js): a canvas behind everything and, for tinta, its own two (the fluid and its drops) */
#scene, #backdrop, #gl, #ov { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
html:is(.theme-tinta, .theme-leche) #scene, html:not(.theme-tinta, .theme-leche) :is(#gl, #ov) { display: none; }
/* The soft dark patch behind the text, so that it reads over any background */
body::before {
  content: "";
  position: fixed;
  left: 50%;
  top: calc(var(--crt-reader-top) + 130px);
  width: min(140vw, 620px);
  height: min(70vh, 440px);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, var(--crt-scrim) 0%, var(--crt-scrim) 45%, transparent 100%);
  pointer-events: none;
  z-index: 1;
}
::selection { background: var(--crt-fg); color: var(--crt-bg); }
button { font: inherit; color: inherit; }

/* ---------- Reader ---------- */
#reader {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: max(48px, env(safe-area-inset-top)) 24px max(24px, env(safe-area-inset-bottom));
  cursor: default;
}
html.is-prompt #reader { display: none; }
html.is-login #btn-avatars { display: none; }          /* before signing in there are no characters to choose from */

/* ---------- Start screen and sign-in (src/client/js/intro.js, auth.js) ---------- */
/* The start screen: «Despierta, humano.» bigger, and the hint under it that lights up a moment after the text (the next block clears it with the rest) */
.intro-title { font-size: 1.45em; }                                              /* «Despierta, humano.»: the line that matters */
.intro-hint {
  display: block;
  margin-top: 1.6em;
  font-size: 0.7em;
  color: color-mix(in srgb, var(--crt-fg) 62%, transparent);
  text-shadow: none;
  animation: intro-hint-in 1.2s ease-out 0.9s both;                             /* the text is there at once; the hint comes a moment later */
}
@keyframes intro-hint-in { from { opacity: 0; } to { opacity: 1; } }

/* The button at the very bottom, for those who already have an account */
#btn-login {
  position: fixed;
  left: 0;
  right: 0;
  bottom: max(32px, env(safe-area-inset-bottom));
  width: fit-content;                            /* centred with auto margins: «left: 50%» would leave it only half the screen to grow in */
  max-width: calc(100vw - 2 * 152px);            /* clear of the round buttons at the sides (the two on the left are the wider side) */
  margin: 0 auto;
  z-index: 30;
  padding: 5px 10px;
  border: 1px solid var(--crt-dim);
  background: transparent;
  color: var(--crt-fg);
  font-family: var(--ui-font);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-wrap: balance;                            /* on a phone it breaks in two even lines, not in three */
  opacity: 0.6;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#btn-login[hidden] { display: none; }
#btn-login:hover, #btn-login:focus-visible { opacity: 1; }

/* The form: the email and the send button, in the voice of the prompt (orange: it is you who writes) */
#login {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  width: min(30ch, 100%);
  margin: 1.2em auto 0;
  font-family: var(--crt-font);
  font-style: var(--crt-font-style);
  font-size: calc(var(--crt-reader-font-size) * var(--crt-text-scale, 1));
}
#login[hidden] { display: none; }
.reader-text:empty + #login { margin-top: 0; }   /* nothing above it: it sits where the text would start */
#login input {
  flex: 1 1 14ch;
  min-width: 0;
  padding: 0.15em 0.1em;
  border: 0;
  border-bottom: 1px solid var(--crt-dim);
  border-radius: 0;
  background: transparent;
  color: var(--crt-user);
  caret-color: var(--crt-user);
  font: inherit;
  outline: none;
  user-select: text;
  -webkit-user-select: text;
}
#login input::placeholder { color: var(--crt-dim); }
#login input:focus { border-bottom-color: var(--crt-user); }
#login button {
  padding: 0.1em 0.8em;
  border: 1px solid var(--crt-dim);
  background: transparent;
  color: var(--crt-fg);
  font: inherit;
  font-style: normal;
  cursor: pointer;
}
#login button:hover, #login button:focus-visible { border-color: var(--crt-fg); outline: none; }
#login button:disabled { opacity: 0.4; cursor: default; }

.reader-text {
  margin: var(--crt-reader-top) auto 0;
  flex-shrink: 0;
  width: min(var(--crt-reader-width), 100%);
  font-family: var(--crt-font);
  font-style: var(--crt-font-style);
  font-weight: var(--crt-font-weight);
  font-size: calc(var(--crt-reader-font-size) * var(--crt-text-scale, 1));       /* scales: the Aa and ≡ buttons */
  line-height: calc(var(--crt-reader-line-height) * var(--crt-lh-scale, 1));
  text-align: center;
  text-wrap: balance;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  text-shadow: var(--crt-glow);
  user-select: text;
}
.reader-text.kind-list, .reader-text.kind-quote { width: min(34ch, 100%); text-align: left; text-wrap: wrap; }
.reader-text.kind-code {
  width: min(80ch, 100%);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-style: normal;
  font-size: calc(var(--crt-reader-font-size) * var(--crt-text-scale, 1) * 0.6);
  text-align: left;
  text-wrap: wrap;
  padding: 0.6em 0.8em;
  border-left: 1px solid var(--crt-fg);
  background: var(--crt-faint);
}
.reader-end { display: block; margin-top: 0.8em; color: var(--crt-dim); }
.reader-error { color: var(--crt-fg); opacity: 0.85; }

/* Block cursor (reader and prompt): an inline box that takes no room, with the bar drawn out of the flow in its ::before. Two traps:
   as an inline-block it was an atomic inline, and the browser may break a line before and after one even in the middle of a word, so the
   line breaks while writing differed from the final ones and the lines slid about; and a cursor with nothing after it, at the end of a
   balanced paragraph (text-wrap: balance), is dropped to a line of its own, under the text. The word joiner after it (U+2060, no width)
   is something to stay with, and forbids the break there. It must come after: before the cursor it does not help. */
.crt-cursor {
  position: relative;
  animation: crt-blink var(--crt-cursor-speed) steps(1) infinite;
}
.crt-cursor::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 2px;
  height: 1em;
  transform: translateY(-50%);
  background: var(--crt-user);          /* the accent of the theme: it stands out from the text a little... */
  box-shadow: 0 0 10px var(--crt-user);  /* ...and it glows in it, as it did in the prototypes */
}
.crt-cursor::after { content: '\2060'; }
/* A mistyped letter (the "Erratas" effect) is only painted at the cursor, out of the flow, over the room of the right one: it takes none. */
.crt-cursor[data-typo]::before { content: attr(data-typo); top: auto; width: auto; height: auto; transform: none; background: none; box-shadow: none; }
html.effect-sincursor #reader .crt-cursor:not([data-typo])::before { display: none; }   /* MÁQUINA SIN CURSOR: no caret in the reader (a mistyped letter is still painted); the prompt keeps its own */
#reader.is-typing .crt-cursor { animation: none; }
.reader-text .wd { display: inline-block; }                                   /* LETRAS and LECTURA: a span per word (reveal.js) */
.crt-rest::after { content: attr(data-rest); visibility: hidden; }          /* what is still to be written: it takes its room, it is not seen */
@keyframes crt-blink { 50% { opacity: 0; } }

/* Waiting for the reply: three round dots that light up one after another and go out in the same order */
.crt-dots { display: inline-flex; align-items: center; gap: 0.3em; height: 1em; vertical-align: -0.12em; }
.crt-dots i {
  width: 0.26em;
  height: 0.26em;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.18;
  animation: crt-dot 1.2s steps(1) infinite;
}
.crt-dots i:nth-child(2) { animation-delay: 0.2s; }
.crt-dots i:nth-child(3) { animation-delay: 0.4s; }
@keyframes crt-dot { 0% { opacity: 0.18; } 10% { opacity: 1; } 60% { opacity: 1; } 70% { opacity: 0.18; } }

/* ---------- Prompt (only the caret) ---------- */
#prompt {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: none;
  flex-direction: column;
  padding: max(48px, env(safe-area-inset-top)) 24px 24px;
  cursor: text;
}
html.is-prompt #prompt { display: flex; }
#prompt .reader-text { user-select: none; width: min(36ch, 100%); text-align: left; text-wrap: wrap; }
/* What you type has a «>» in front and an orange caret, to tell your voice from the assistant's */
#prompt .prompt-display::before {
  content: '> ';
  color: var(--crt-user);
}
#prompt-input {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  border: 0;
  padding: 0;
  font-size: 16px;            /* avoids iOS zooming in on focus */
  resize: none;
}

/* ---------- Metadata and gear ---------- */
#meta {
  position: fixed;
  top: max(18px, env(safe-area-inset-top));
  right: 40px;
  z-index: 30;
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--crt-dim);
  letter-spacing: 0.2em;
  pointer-events: none;
}
#meta.is-toast { color: var(--crt-fg); }

/* Two round buttons at the bottom left: the next theme and the next effect of the text */
#quick {
  position: fixed;
  left: 40px;
  bottom: max(32px, env(safe-area-inset-bottom));
  z-index: 30;
  display: flex;
  gap: 10px;
}

/* Accumulated cost of the conversation, bottom left, beside the two buttons */
#cost {
  position: fixed;
  left: calc(40px + 98px + 14px);
  bottom: calc(max(32px, env(safe-area-inset-bottom)) + 16px);
  z-index: 30;
  font-family: var(--ui-font);
  font-size: 12px;
  color: var(--crt-dim);
  letter-spacing: 0.2em;
  white-space: pre;
}

/* Your messages when going through the history: a little dimmer than the assistant's */
.reader-text.is-user { opacity: 0.72; }

/* Column of round buttons at the bottom right: theme, type size, line spacing */
#dock {
  position: fixed;
  right: 40px;
  bottom: max(32px, env(safe-area-inset-bottom));
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
/* A single floating circle; tapping it unfolds the rest upwards (and it folds by itself) */
#dock-items { display: none; flex-direction: column; gap: 10px; }
#dock.is-open #dock-items { display: flex; animation: dock-appear 0.18s ease-out; }
@keyframes dock-appear { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
#btn-menu { opacity: 0.35; }
#dock.is-open #btn-menu { opacity: 0.9; }
#btn-menu .icon-close, #dock.is-open #btn-menu .icon-open { display: none; }
#dock.is-open #btn-menu .icon-close { display: block; }
#btn-settings { font-size: 19px; line-height: 1; padding: 0; }
.dock-btn {
  width: 44px;
  height: 44px;
  border: 1px solid var(--crt-dim);
  border-radius: 50%;
  background: transparent;
  display: grid;
  place-items: center;
  opacity: 0.55;
  cursor: pointer;
  color: var(--crt-fg);
  -webkit-tap-highlight-color: transparent;
}
.dock-btn:hover { opacity: 1; }
.dock-btn svg { width: 20px; height: 20px; }
#btn-size { font-family: var(--ui-font); font-size: 15px; line-height: 1; padding: 0; }
.dock-btn[hidden] { display: none; }

#gear {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 30;
  padding: 8px 6px 8px 8px;
  border: 1px solid var(--crt-dim);
  border-right: 0;
  border-radius: 6px 0 0 6px;
  background: var(--crt-bg);
  color: var(--crt-fg);
  font-size: 18px;
  line-height: 1;
  opacity: 0.4;
  cursor: pointer;
}
#gear:hover, #gear:focus-visible { opacity: 1; outline: none; }
#gear { display: none; }   /* replaced by the ⚙ circle of the floating menu (the P key still opens the panel) */

/* ---------- Avatars: burger at the top left and a panel that slides in from that side ---------- */
#btn-avatars {
  position: fixed;
  left: 40px;
  top: max(12px, env(safe-area-inset-top));
  z-index: 50;                                  /* above the panel: it works as the close button */
}
#btn-avatars.is-open { opacity: 0.9; }
#btn-avatars .icon-close, #btn-avatars.is-open .icon-open { display: none; }
#btn-avatars.is-open .icon-close { display: block; }
#avatars-scrim {
  position: fixed;
  inset: 0;
  z-index: 44;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s;
}
#avatars-scrim.is-open { opacity: 1; pointer-events: auto; }
#avatars {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 45;
  width: min(280px, 80vw);
  padding: calc(max(12px, env(safe-area-inset-top)) + 60px) 0 24px;
  overflow-y: auto;
  background: var(--crt-bg);
  border-right: 1px solid var(--crt-dim);
  box-shadow: 6px 0 30px rgba(0, 0, 0, 0.35);
  transform: translateX(-105%);
  visibility: hidden;
  transition: transform 0.2s ease-out, visibility 0s 0.2s;
}
#avatars.is-open { transform: none; visibility: visible; transition: transform 0.2s ease-out; }
.avatar-item {
  display: block;
  width: 100%;
  padding: 14px 24px;
  border: 0;
  background: transparent;
  color: var(--crt-fg);
  font-family: var(--ui-font);
  font-size: 17px;
  text-align: left;
  opacity: 0.6;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.avatar-item:hover, .avatar-item:focus-visible { opacity: 1; outline: none; }
.avatar-item.is-active { opacity: 1; }
.avatar-item.is-active::before { content: "▸ "; }
@media (prefers-reduced-motion: reduce) {
  #avatars, #avatars.is-open, #avatars-scrim { transition: none; }
}

/* ---------- Panel (settings + effects) ---------- */
#panel {
  position: fixed;
  left: 24px;
  bottom: 24px;
  z-index: 40;
  width: min(460px, calc(100vw - 48px));
  max-height: min(78vh, calc(100dvh - 48px));
  overflow-y: auto;
  padding: 12px 14px 10px;
  background: var(--crt-bg);
  color: var(--crt-fg);
  border: 1px solid var(--crt-dim);
  font: 15px/1.35 var(--ui-font);
  box-shadow: 0 6px 30px rgba(0, 0, 0, 0.35);
  user-select: text;
}
#panel[hidden] { display: none; }
#panel h3 {
  margin: 12px 0 6px;
  font-size: 12px;
  font-weight: normal;
  letter-spacing: 0.18em;
  opacity: 0.6;
}
#panel .p-head {
  display: flex; justify-content: space-between; align-items: center;
  letter-spacing: 0.15em; font-size: 13px;
  padding-bottom: 6px; border-bottom: 1px solid var(--crt-dim);
}
#panel button { all: unset; cursor: pointer; font: inherit; }
#panel .p-close { font-size: 18px; padding: 0 4px; }
#panel label { display: block; margin: 6px 0 2px; font-size: 13px; opacity: 0.75; }
#panel input[type="text"], #panel input[type="password"], #panel select, #panel textarea {
  width: 100%;
  padding: 5px 7px;
  background: transparent;
  color: var(--crt-fg);
  border: 1px solid var(--crt-dim);
  border-radius: 0;
  font: 14px/1.3 var(--ui-font);
  user-select: text;
}
#panel select option { background: var(--crt-bg); color: var(--crt-fg); }
#panel textarea { min-height: 64px; resize: vertical; }
#panel .p-inline { display: flex; gap: 8px; align-items: center; }
#panel .p-inline > input, #panel .p-inline > select { flex: 1; }
#panel .p-themes { flex-wrap: wrap; }
#panel .p-knob { display: grid; grid-template-columns: minmax(0, 1fr) minmax(90px, 150px) 3.4rem; align-items: center; gap: 10px; padding: 3px 0; }
#panel .p-knob label { margin: 0; opacity: 1; }
#panel .p-knob output { text-align: right; font-variant-numeric: tabular-nums; opacity: 0.6; }
#panel .p-knob.is-changed output { color: var(--crt-user); opacity: 1; }
#panel .p-btn {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid var(--crt-dim);
  font-size: 13px;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
#panel .p-btn:hover, #panel .p-btn[aria-pressed="true"] { border-color: var(--crt-fg); }
#panel .p-btn:disabled { opacity: 0.35; cursor: default; }
#panel .p-btn[aria-pressed="true"] { background: color-mix(in srgb, var(--crt-fg) 14%, transparent); }
#panel .p-row { display: grid; grid-template-columns: auto 1fr auto; column-gap: 8px; align-items: baseline; padding: 4px 0; }
#panel .p-desc { grid-column: 2 / 4; opacity: 0.55; font-size: 13px; }
#panel .fx-toggle { white-space: pre; }
#panel .fx-toggle[aria-pressed="false"] { opacity: 0.6; }
#panel .p-note { font-size: 12px; opacity: 0.55; margin-top: 4px; }
#panel .p-foot { margin-top: 10px; padding-top: 6px; border-top: 1px solid var(--crt-dim); opacity: 0.5; font-size: 12px; }
#panel input[type="range"] { width: 100%; accent-color: var(--crt-fg); }

@media (max-width: 600px) {
  #panel { left: 8px; right: 8px; bottom: 8px; width: auto; }
  #meta { right: 16px; }
  #quick { left: 16px; }
  #btn-login { max-width: calc(100vw - 2 * 128px); }
  #cost { left: calc(16px + 98px + 14px); }
  #dock { right: 16px; }
  #btn-avatars { left: 16px; }
}

/* ==========================================================================
   Reader effects (panel)
   ========================================================================== */
/* Paper feed: the previous text slides down and fades while the next one is written */
.feed-ghost { position: fixed !important; pointer-events: none; animation: crt-feed 0.6s cubic-bezier(0.3, 0, 0.2, 1) forwards; }
@keyframes crt-feed { to { transform: translateY(3.2em); opacity: 0; filter: blur(0.6px); } }

/* ---------- Ideas under the reply (carousel) ---------- */
#ideas {
  position: fixed;
  left: 50%;
  bottom: calc(max(32px, env(safe-area-inset-bottom)) + 56px);       /* above the cost row and the round buttons */
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  gap: 12px;
  width: min(760px, calc(100vw - 48px));
  padding: 4px 2px 10px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--crt-dim) transparent;
  font-family: var(--crt-font);
  font-style: var(--crt-font-style);
  font-size: calc(var(--crt-reader-font-size) * var(--crt-text-scale, 1) * 0.72);
  line-height: 1.2;
}
#ideas[hidden] { display: none; }
html.has-ideas #reader { padding-bottom: calc(210px + env(safe-area-inset-bottom)); }   /* long text is not covered */
.idea {
  flex: 0 0 min(15em, 78%);
  display: flex;
  flex-direction: column;
  gap: 0.35em;
  padding: 0.6em 0.8em;
  text-align: left;
  scroll-snap-align: start;
  cursor: pointer;
  user-select: none;
  color: var(--crt-fg);
  text-shadow: var(--crt-glow);
  background: var(--crt-faint);
  border: 1px solid var(--crt-dim);
}
.idea:hover, .idea:focus-visible { border-color: var(--crt-fg); box-shadow: var(--crt-glow); outline: none; }
.idea-title { font-size: 1.15em; }
.idea-label { color: var(--crt-dim); font-family: var(--ui-font); font-size: 0.8em; letter-spacing: 0.2em; text-transform: uppercase; }
.idea-hook {
  font-size: 0.9em;
  opacity: 0.8;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* ↻ at the end of the carousel: asks for new cards. A small button, not a card */
.idea-refresh {
  flex: 0 0 auto;
  align-self: center;
  display: grid;
  place-items: center;
  width: 2.6em;
  height: 2.6em;
  padding: 0;
  cursor: pointer;
  color: var(--crt-dim);
  background: transparent;
  border: 1px solid var(--crt-dim);
  border-radius: 50%;
}
.idea-refresh svg { width: 55%; height: 55%; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.idea-refresh:hover, .idea-refresh:focus-visible { color: var(--crt-fg); border-color: var(--crt-fg); box-shadow: var(--crt-glow); outline: none; }
/* While the new ones arrive: everything dimmed and the icon spinning */
#ideas.is-loading .idea, #ideas.is-loading .idea-refresh { opacity: 0.4; pointer-events: none; }
#ideas.is-loading .idea-refresh svg { animation: idea-spin 0.9s linear infinite; }
@keyframes idea-spin { to { transform: rotate(360deg); } }
@media (max-width: 600px) {
  #ideas { width: calc(100vw - 32px); }
}
