/* The web device: her face on black, everything said below it, a field to write. */
:root {
  --aria: #38e1ff;         /* her calm cyan, as on the face */
  --person: #e8eef2;
  --dim: #6b7780;
  --field: #12171b;
  color-scheme: dark;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }  /* even over a display rule */
html, body { margin: 0; height: 100%; background: #000; color: var(--person); }
body { font: 17px/1.45 system-ui, sans-serif; }

main {
  height: 100dvh;
  max-width: 720px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  padding: env(safe-area-inset-top) 16px calc(12px + env(safe-area-inset-bottom));
}

/* The face plugin draws in a 34x34 grid of 7 px LEDs: 238 px, scaled up a little. */
.face { flex: none; display: grid; place-items: center; height: 300px; }
.face iframe { width: 238px; height: 238px; border: 0; transform: scale(1.2); pointer-events: none; }

.status { margin: 0 0 8px; text-align: center; color: var(--dim); font-size: 14px; }

.talk {
  flex: 1;
  overflow-y: auto;
  margin: 0;
  padding: 8px 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 14px;
  mask-image: linear-gradient(transparent, #000 32px);
}
.talk li { max-width: 85%; white-space: pre-wrap; overflow-wrap: anywhere; }
.talk .user { align-self: flex-end; color: var(--person); text-align: right; }
.talk .aria { align-self: flex-start; color: var(--aria); }
.talk .error { align-self: center; color: #ff8a7a; font-size: 15px; }
.talk .from { display: block; color: var(--dim); font-size: 13px; }
/* Said aloud: a small microphone after the words. */
.talk .user.heard::after {
  content: "";
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-left: 6px;
  vertical-align: -1px;
  background: var(--dim);
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 15a3 3 0 0 0 3-3V6a3 3 0 0 0-6 0v6a3 3 0 0 0 3 3zm5-3a5 5 0 0 1-10 0H5a7 7 0 0 0 6 6.9V21h2v-2.1a7 7 0 0 0 6-6.9z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.talk .aria.pending::after { content: "▍"; animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.write { flex: none; display: flex; gap: 8px; margin-top: 8px; }
.write input, .token input {
  flex: 1;
  min-width: 0;
  font: inherit;
  color: inherit;
  background: var(--field);
  border: 1px solid #222a30;
  border-radius: 24px;
  padding: 12px 18px;
}
.write input:focus-visible, .token input:focus-visible, button:focus-visible {
  outline: 2px solid var(--aria);
  outline-offset: 2px;
}
.write button, .token button {
  flex: none;
  font: inherit;
  color: #000;
  background: var(--aria);
  border: 0;
  border-radius: 24px;
  cursor: pointer;
}
.write button { width: 48px; display: grid; place-items: center; }
.write .send:disabled { background: #2a3238; color: var(--dim); cursor: default; }
/* Held to talk: amber, the colour of her face when she speaks. */
.write .talk-button { touch-action: none; user-select: none; -webkit-user-select: none; }
.write .talk-button.listening { background: #ffa040; box-shadow: 0 0 0 6px rgb(255 160 64 / 0.25); }

.token {
  max-width: min(420px, calc(100vw - 32px));
  background: #0b0f12;
  color: var(--person);
  border: 1px solid #222a30;
  border-radius: 16px;
}
.token::backdrop { background: rgb(0 0 0 / 0.7); }
.token form { display: flex; flex-direction: column; gap: 12px; }
.token p { margin: 0; color: var(--dim); }
.token button { padding: 12px; }

/* Calling her: top right, away from writing, as in messaging apps. */
.call-button {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top));
  right: 16px;
  z-index: 1;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  color: var(--aria);
  background: var(--field);
  border: 1px solid #222a30;
  border-radius: 50%;
  cursor: pointer;
}
main { position: relative; }
body.call .call-button { display: none; }

/* Call: only her face is left, bigger, with a line of state and the hang-up button. */
.hangup {
  flex: none;
  align-self: center;
  width: 72px;
  height: 72px;
  margin: 24px 0 16px;
  display: grid;
  place-items: center;
  color: #fff;
  background: #e5484d;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}
body.call .talk, body.call .write { display: none; }
body.call .face { flex: 1; height: auto; }
body.call .face iframe { transform: scale(1.5); }  /* 357 px: fits a narrow phone */
body.call .status { font-size: 18px; color: var(--person); }
/* What she says, as she says it: one line, the newest words on the right, the
   oldest sliding out on the left. Only during a call (the chat shows it otherwise). */
.caption { display: none; }
body.call .caption {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 8px;
  overflow: hidden;
  white-space: nowrap;
  color: var(--aria);
  font-size: 20px;
  mask-image: linear-gradient(to right, transparent, #000 25%);
}

@media (prefers-reduced-motion: reduce) {
  .talk .aria.pending::after { animation: none; }
}
