/**
 * The chat app: entry screen, room, panels.
 *
 * Mobile first, because the original was a phone UI that happened to run in a
 * browser. Every colour and size comes from tokens.css.
 */

/* `[hidden]` wins everywhere: see base.css. */

/* ------------------------------------------------------------------ layout */

/*
 * --app-h is the part of the screen the keyboard leaves visible, set by
 * js/app/viewport.js where the browser will not resize for the keyboard
 * itself (Safari). Everywhere else it is unset and 100dvh does the job.
 */
.app {
  height: var(--app-h, 100dvh);
  overflow: hidden;
}

/* ------------------------------------------------------------ entry screen */

/*
 * The original put nothing here but the form, centred on white
 * (docs/reference/app-ui/01_entry_screen.png). The wordmark is kept, small, so
 * a link opened cold still says whose site this is.
 */
.entry-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: 1.25rem;
  text-align: center;
}

.wordmark--large {
  margin: 0;
  font-size: 44px;
  line-height: 1;
}

.entry-screen__tagline {
  margin: 6px 0 28px;
  font-size: 15px;
  color: var(--text);
}

.entry-screen .entry {
  max-width: 320px;
}

.entry-screen__small {
  max-width: 320px;
  margin-top: 2rem;
  font-size: 12px;
  line-height: 18px;
  color: var(--text);
}

/* -------------------------------------------------------------------- room */

.chat {
  display: grid;
  grid-template-rows: var(--header-h) 1fr auto;
  height: var(--app-h, 100dvh);
}

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--header-h);
  padding: 0 10px;
  background: var(--header-bg);
}

.bar__title {
  margin: 0;
  color: #fff;
  font-size: var(--header-title);
  font-weight: 400;
  line-height: var(--header-h);
}

.bar__brand {
  font-size: var(--header-logo);
}

/*
 * The scrolling message list.
 *
 * The background is explicit: base.css gives the body the site's page gradient,
 * and without this the bottom half of an empty room fades to grey, which reads
 * as a rendering fault rather than as an empty room.
 */
.lines {
  display: grid;
  /*
   * The three columns live on the list, not on the row, so every row shares
   * them and the message text starts at one left edge down the whole room. The
   * name track is `auto`: it grows to the longest name actually in the room
   * instead of to a width guessed in advance, which is what a fixed track got
   * wrong (six characters and an ellipsis for everyone).
   */
  grid-template-columns: var(--dot-size) auto 1fr;
  align-content: start;
  column-gap: 4px;
  margin: 0;
  padding: 4px var(--chat-gutter);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  list-style: none;
  background: #fff;
}

/*
 * Two columns so the message text starts at the same left edge on every row and
 * wraps within its own column rather than under the name.
 */
.line {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: baseline;
  padding: var(--chat-row-pad) 0;
  font-size: var(--chat-size);
  line-height: var(--chat-lh);
}

/* Centred on the first line, beside the name, rather than on the whole row:
   a message that wraps keeps its dot by the name, as in the original. */
.dot {
  width: var(--dot-size);
  height: var(--dot-size);
  margin-top: calc((var(--chat-lh) - var(--dot-size)) / 2);
  border-radius: 50%;
  align-self: start;
}
.dot[data-gender="m"] { background: var(--dot-m); }
.dot[data-gender="f"] { background: var(--dot-f); }
.dot[data-gender="a"] { background: var(--dot-a); }

/* The cap stops one 16-character name from pushing every message in the room a
   third of the way across the screen. Past it, names ellipsize. */
.name {
  max-width: var(--name-col);
  overflow: hidden;
  color: var(--name-color, var(--name));
  font-style: italic;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * The colon belongs to the layout, not to the name, so it is drawn here rather
 * than concatenated into the text node. That keeps the rule in
 * docs/frontend.md §4.1 — a username reaches the DOM as its own textContent and
 * nothing is ever built around it by string.
 */
.name::after {
  content: ":";
}

.text {
  color: var(--msg-color, var(--text));
  overflow-wrap: anywhere;
}

/* Your own lines, in bold (D52). */
.line--own .text {
  font-weight: 700;
}

/* `#room` inside a message. The pink is what marks it as somewhere to go; no
   underline, which in a dense chat line reads as noise. */
.room-link {
  color: var(--link);
  text-decoration: none;
}

.room-link:hover,
.room-link:focus-visible {
  text-decoration: underline;
}

/*
 * The placeholder standing in for a private message's text, for everyone who is
 * not a party to it. Italic so a glance down the room separates "something was
 * said" from "something was said to someone", without reading either.
 *
 * Set from the line's own shape, never from the text: see chat-view.js.
 */
.text--private {
  font-style: italic;
}

/* Notices have no columns to line up, so they opt out of the subgrid and run
   the full width of the row. */
.line.system {
  grid-template-columns: 1fr;
  padding-top: 4px;
  padding-bottom: 4px;
  color: var(--notice);
  font-size: var(--notice-size);
}

/* ---------------------------------------------------------- floating buttons */

.fabs {
  position: fixed;
  top: var(--fab-top-1);
  right: var(--fab-right);
  display: flex;
  flex-direction: column;
  /* The gaps reproduce the original's 50 / 115 / 180px stack. */
  gap: calc(var(--fab-top-2) - var(--fab-top-1) - var(--fab-size));
}

.fab {
  width: var(--fab-size);
  height: var(--fab-size);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-color: transparent;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  cursor: pointer;
}

.fab--rooms { background-image: url("/icons/rooms.svg"); }
.fab--share { background-image: url("/icons/share.svg"); }
.fab--settings { background-image: url("/icons/settings.svg"); }

/* ---------------------------------------------------------------- composer */

/* Two greys, as in docs/reference/app-ui/02_chat_room.jpg: the strip is lighter
   than the button, and neither is white. */
.composer {
  display: flex;
  height: var(--composer-h);
  border-top: 1px solid var(--composer-line);
  background: var(--composer-bg);
}

.composer__input {
  flex: 1;
  min-width: 0;
  padding: 0 10px;
  border: 0;
  background: var(--composer-bg);
  color: var(--text);
  font: inherit;
  font-size: var(--chat-size);
}

.composer__input::placeholder {
  color: #6e6e6e;
}

.composer__input:disabled {
  background: #bdbdbd;
}

.composer__send {
  width: 88px;
  border: 0;
  background: var(--composer-send-bg);
  color: var(--text);
  font: inherit;
  font-size: var(--chat-size);
  letter-spacing: 0.04em;
  cursor: pointer;
}

.composer__send:disabled {
  opacity: 0.5;
  cursor: default;
}

/* ------------------------------------------------------------------ panels */

.panel {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  background: var(--page-bg, #fff);
}

.panel__header {
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--header-h);
  padding: 0 10px;
  background: var(--header-bg);
}

/* Pushed right so the panel bar reads the same way round as the room bar. */
.panel__brand {
  margin-left: auto;
  font-size: var(--header-logo);
}

.panel__title {
  margin: 0;
  color: #fff;
  font-size: var(--header-title);
  font-weight: 400;
}

/* The pink close circle, drawn in CSS so it needs no extra asset. */
.panel__close {
  position: relative;
  width: var(--close-size);
  height: var(--close-size);
  border: 0;
  border-radius: 50%;
  background: var(--close-bg);
  cursor: pointer;
}
.panel__close::before,
.panel__close::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 3px;
  background: #fff;
}
.panel__close::before { transform: translate(-50%, -50%) rotate(45deg); }
.panel__close::after { transform: translate(-50%, -50%) rotate(-45deg); }

.panel__body {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  max-width: var(--content-max);
  width: 100%;
  margin: 0 auto;
}

/* Bold and black, unlike the thin headings on the content pages: in the app
   these label a list you are about to tap, not a paragraph you are about to
   read (docs/reference/app-ui/03_rooms_panel.jpg). */
.panel__heading {
  margin: 14px 0 6px;
  font-size: 18px;
  line-height: 24px;
  font-weight: 700;
  color: var(--text-strong);
}

.panel__body > .panel__heading:first-child {
  margin-top: 4px;
}

.panel__label {
  display: block;
  margin-top: 0.75rem;
  margin-bottom: 0.25rem;
}

/* ------------------------------------------------------------------- pills */

.pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pill-gap);
  margin: 0.5rem 0;
  padding: 0;
  list-style: none;
}

.pill {
  padding: var(--pill-pad);
  border: 0;
  color: #fff;
  font: inherit;
  font-size: var(--pill-text);
  line-height: var(--pill-h);
  cursor: pointer;
}

.pill--amber { background: var(--pill-amber); }
.pill--cyan { background: var(--pill-cyan); }

/* ------------------------------------------------------------------ shared */

.field {
  width: 100%;
  height: var(--field-h);
  padding-left: var(--field-pad-left, 10px);
  border: var(--field-border);
  border-radius: 0;
  background: #fff;
  color: var(--text);
  font-size: var(--field-text);
}

.button {
  display: block;
  width: 100%;
  height: var(--field-h);
  margin-top: 10px;
  border: var(--field-border);
  border-radius: 0;
  font-family: inherit;
  font-size: 17px;
  cursor: pointer;
}

.button--light { background: #fff; color: var(--text); }

/* ------------------------------------------------------------------ dialog */

/*
 * A small popup over the chat, for the one thing that has to be confirmed
 * before it happens: a report (D40). A native <dialog>, opened with
 * showModal(), so Escape closes it and focus stays inside it.
 */
.dialog {
  width: min(420px, calc(100% - 32px));
  padding: 0;
  border: 0;
  background: var(--page-bg, #fff);
  color: var(--text);
  box-shadow: 0 18px 50px rgb(0 0 0 / 0.3);
}

.dialog::backdrop {
  background: rgb(0 0 0 / 0.45);
}

.dialog__form {
  padding: 18px 18px 16px;
}

.dialog__title {
  margin: 0 0 4px;
  font-size: 20px;
  font-weight: 600;
}

.dialog__actions {
  display: flex;
  gap: 10px;
}

.field--area {
  height: auto;
  padding: 8px 10px;
  font-family: inherit;
  line-height: 1.4;
  resize: vertical;
}
.button--dark { background: var(--btn-dark); color: #fff; border-color: var(--btn-dark); }

.hint {
  margin: 0.35rem 0;
  font-size: 13px;
  line-height: 18px;
  color: var(--text);
  list-style: none;
}

.smallprint {
  margin-top: 1.5rem;
  font-size: 12px;
  line-height: 17px;
  color: var(--text);
}

.error {
  min-height: 1.2em;
  margin: 0.35rem 0;
  color: var(--error);
  text-align: center;
}

.toast {
  position: fixed;
  bottom: calc(var(--field-h) + 12px);
  left: 50%;
  z-index: 20;
  transform: translateX(-50%);
  padding: 8px 14px;
  border-radius: 4px;
  background: rgb(0 0 0 / 0.82);
  color: #fff;
  font-size: 14px;
}

/* -------------------------------------------------------------- wider screens */

@media (min-width: 500px) {
  .line { font-size: 16px; line-height: 20px; }
}

/*
 * The room fills the window at every width.
 *
 * It used to cap .lines and .composer at --content-max and centre them, which
 * is right for a page of prose and wrong for a chat room: on a laptop it left
 * the conversation in a floating column with the composer as a stub in the
 * middle of the screen. --content-max governs the content pages, not this.
 */
@media (min-width: 800px) {
  .line { font-size: 17px; line-height: 21px; }

  .panel { inset: 0 auto 0 0; width: min(480px, 100%); box-shadow: 0 0 40px rgb(0 0 0 / 0.2); }
}
