:root {
  --bg: #16191d;
  --bg-side: #101215;
  --bg-raised: #1d2127;
  --bg-hover: #242930;
  --bg-input: #21262d;
  --border: #2b3139;
  --text: #e6e8eb;
  --text-dim: #9ba4ae;
  --text-faint: #6d7682;
  --accent: #2bb3a3;
  --accent-hover: #35c4b3;
  --accent-text: #06201c;
  --accent-soft: rgba(43, 179, 163, 0.16);
  --danger: #e5534b;
  --danger-soft: rgba(229, 83, 75, 0.14);
  --link: #5cc3ee;
  --code-bg: #0e1013;
  --online: #3fbf6f;
  --mention: #e3a92f;
  --mention-soft: rgba(227, 169, 47, 0.1);
  --code-comment: #7d9a74;
  --code-string: #e3c55f;
  --code-number: #f0907f;
  --code-keyword: #f29e5d;
  --code-constant: #ee8fb4;
  --code-builtin: #6cb6ff;
  --code-function: #7fd4c1;
  --code-variable: #c59cf2;
  --code-local: #f1e7a8;
  --code-type: #6cb6ff;
  --code-meta: #9ba4ae;
  --shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  --radius: 8px;
  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) {
    --bg: #ffffff;
    --bg-side: #f0f2f4;
    --bg-raised: #ffffff;
    --bg-hover: #e6e9ed;
    --bg-input: #f0f2f4;
    --border: #d9dee3;
    --text: #1b2025;
    --text-dim: #56606b;
    --text-faint: #87909a;
    --accent: #12857a;
    --accent-hover: #0f7469;
    --accent-text: #ffffff;
    --accent-soft: rgba(18, 133, 122, 0.12);
    --danger: #c7372f;
    --danger-soft: rgba(199, 55, 47, 0.1);
    --link: #0a6cb3;
    --code-bg: #f0f2f4;
    --online: #23994f;
    --mention: #b47700;
    --mention-soft: rgba(180, 119, 0, 0.1);
    --code-comment: #7a8691;
    --code-string: #1a7f37;
    --code-number: #c0392b;
    --code-keyword: #b3540a;
    --code-constant: #b02a6f;
    --code-builtin: #0b62b8;
    --code-function: #0f7469;
    --code-variable: #7b3fc4;
    --code-local: #7d5a00;
    --code-type: #0b62b8;
    --code-meta: #56606b;
    --shadow: 0 12px 40px rgba(20, 30, 40, 0.18);
    color-scheme: light;
  }
}

:root[data-theme='light'] {
  --bg: #ffffff;
  --bg-side: #f0f2f4;
  --bg-raised: #ffffff;
  --bg-hover: #e6e9ed;
  --bg-input: #f0f2f4;
  --border: #d9dee3;
  --text: #1b2025;
  --text-dim: #56606b;
  --text-faint: #87909a;
  --accent: #12857a;
  --accent-hover: #0f7469;
  --accent-text: #ffffff;
  --accent-soft: rgba(18, 133, 122, 0.12);
  --danger: #c7372f;
  --danger-soft: rgba(199, 55, 47, 0.1);
  --link: #0a6cb3;
  --code-bg: #f0f2f4;
  --online: #23994f;
  --mention: #b47700;
  --mention-soft: rgba(180, 119, 0, 0.1);
  --code-comment: #7a8691;
  --code-string: #1a7f37;
  --code-number: #c0392b;
  --code-keyword: #b3540a;
  --code-constant: #b02a6f;
  --code-builtin: #0b62b8;
  --code-function: #0f7469;
  --code-variable: #7b3fc4;
  --code-local: #7d5a00;
  --code-type: #0b62b8;
  --code-meta: #56606b;
  --shadow: 0 12px 40px rgba(20, 30, 40, 0.18);
  color-scheme: light;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font: 15px/1.45 system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  overflow: hidden;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

a {
  color: var(--link);
}

h1,
h2,
h3,
p {
  margin: 0;
}

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 18px 0;
}

.icon {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.spacer {
  flex: 1;
}

/* ---------- Buttons and forms ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.btn:hover {
  background: var(--bg-hover);
}

.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}

.btn.primary:hover {
  background: var(--accent-hover);
}

.btn.danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

.btn.danger-outline {
  color: var(--danger);
  border-color: var(--danger);
  background: transparent;
}

.btn.danger-outline:hover {
  background: var(--danger-soft);
}

.btn.small {
  padding: 5px 10px;
  font-size: 13px;
}

.btn.block {
  width: 100%;
  padding: 10px;
}

.btn:disabled,
.icon-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: none;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
}

.icon-btn:hover:not(:disabled),
.icon-btn.active {
  background: var(--bg-hover);
  color: var(--text);
}

.icon-btn.small {
  width: 28px;
  height: 28px;
}

.icon-btn.small .icon {
  width: 17px;
  height: 17px;
}

.icon-btn.danger:hover:not(:disabled) {
  background: var(--danger-soft);
  color: var(--danger);
}

.icon-btn.accent {
  color: var(--accent);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-bottom: 14px;
}

.field-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
}

.field-hint {
  font-size: 12.5px;
  color: var(--text-faint);
}

input[type='text'],
input[type='password'],
input[type='number'],
select,
textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-input);
  color: var(--text);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: none;
  border-color: var(--accent);
}

.check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  cursor: pointer;
}

.check input {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
}

.form-error {
  min-height: 0;
  margin: 0 0 12px;
  color: var(--danger);
  font-size: 13.5px;
}

.form-error:empty {
  display: none;
}

.form-notice {
  margin-bottom: 14px;
  padding: 9px 11px;
  border-radius: var(--radius);
  background: var(--accent-soft);
  font-size: 13.5px;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* ---------- Sign-in ---------- */

.login {
  display: grid;
  place-items: center;
  height: 100%;
  padding: 16px;
  background: var(--bg-side);
  overflow: auto;
}

.login-card {
  width: 100%;
  max-width: 380px;
  padding: 30px 28px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg);
  box-shadow: var(--shadow);
}

.logo {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 16px;
  border-radius: 12px;
  background: var(--accent);
  color: var(--accent-text);
}

.logo .icon {
  width: 26px;
  height: 26px;
  stroke-width: 2.2;
}

.login-card h1 {
  font-size: 22px;
}

.login-sub {
  margin: 4px 0 20px;
  color: var(--text-dim);
}

/* ---------- Layout ---------- */

.app {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr) auto;
  height: 100dvh;
}

.sidebar {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--bg-side);
  border-right: 1px solid var(--border);
}

.ws {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: 52px;
  flex: none;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
  font-size: 16px;
  font-weight: 700;
}

.ws > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.side-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 40px;
  padding: 8px 10px 0 16px;
  color: var(--text-faint);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.side-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.channel-list {
  padding: 4px 8px 12px;
}

.channel-list:empty {
  display: none;
}

.chan {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin-bottom: 2px;
  padding: 7px 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-dim);
  text-align: left;
  cursor: pointer;
}

.chan .icon {
  width: 17px;
  height: 17px;
  color: var(--text-faint);
}

.chan:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.chan.active {
  background: var(--accent-soft);
  color: var(--text);
}

.chan.unread {
  color: var(--text);
  font-weight: 700;
}

.chan-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The button that changes the side between the channels and the conversations with one
   person: pressed while it shows those, and with how many of their messages wait. */
.ws .icon-btn {
  flex: none;
  margin-right: -8px;
}

.ws .icon-btn.active {
  background: var(--accent-soft);
  color: var(--accent);
}

.pins-count.dms-count {
  background: var(--danger);
  color: #fff;
}

/* A conversation with one person, in the list: their picture, and whether they are around. */
.chan.dm .avatar {
  width: 22px;
  height: 22px;
  font-size: 9.5px;
}

.chan.dm .avatar-wrap {
  position: relative;
  flex: none;
  margin: -2px 0;
}

.chan.dm .dot {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 8px;
  height: 8px;
  border: 2px solid var(--bg-side);
  border-radius: 50%;
  background: var(--text-faint);
}

.chan.dm.online .dot {
  background: var(--online);
}

.dm-empty {
  margin: 2px 8px 8px;
  color: var(--text-faint);
  font-size: 13px;
}

/* The mark of a private channel, after its name. */
.chan .chan-lock {
  width: 13px;
  height: 13px;
  flex: none;
  opacity: 0.7;
}

.chan-private {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: none;
  color: var(--text-faint);
  font-size: 12px;
}

.chan-private .icon {
  width: 14px;
  height: 14px;
}

/* People to choose from: who a private channel is for, or who to write to. */
.person-list {
  display: grid;
  gap: 2px;
  max-height: 46vh;
  overflow-y: auto;
}

.person-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.person-row:hover,
.person-row:focus-visible {
  background: var(--bg-hover);
}

.person-row .avatar {
  width: 28px;
  height: 28px;
  font-size: 11px;
}

.person-row small {
  color: var(--text-faint);
}

.check-list .check .avatar {
  width: 22px;
  height: 22px;
  font-size: 9.5px;
}

.badge {
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 10px;
  background: var(--danger);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  text-align: center;
}

.unread-dot {
  width: 8px;
  height: 8px;
  flex: none;
  margin-right: 4px;
  border-radius: 50%;
  background: var(--text);
}

/* ---------- Folders ---------- */

.side-actions {
  display: flex;
  gap: 2px;
}

.folder-head {
  justify-content: flex-start;
  gap: 4px;
  width: 100%;
  padding-left: 8px;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  -webkit-touch-callout: none;
  user-select: none;
}

.folder-head:hover {
  color: var(--text);
}

.folder-head .icon {
  width: 14px;
  height: 14px;
  flex: none;
  transition: transform 0.12s;
}

.folder.closed .folder-head .icon {
  transform: rotate(-90deg);
}

.folder-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.folder-head .badge {
  letter-spacing: 0;
}

.folder-empty {
  margin: 0;
  padding: 4px 16px 12px 26px;
  color: var(--text-faint);
  font-size: 13px;
}

/* While a channel is being dragged: the places it can be dropped in, and the one under the pointer. */
.drop-zone {
  border-radius: 10px;
  outline: 1px dashed var(--text-faint);
  outline-offset: -4px;
}

.drop-zone.drop-over {
  outline: 2px solid var(--accent);
  background: var(--accent-soft);
}

/* A line where the channel would land: above the one it would go in front of, or below the last. */
.drop-before,
.drop-after {
  position: relative;
}

.drop-before::before,
.drop-after::after {
  content: '';
  position: absolute;
  right: 4px;
  left: 4px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
  pointer-events: none;
}

.drop-before::before {
  top: -2px;
}

.drop-after::after {
  bottom: -2px;
}

/* The channels to tick in the folder dialog. */
.check-list {
  max-height: 232px;
  padding: 10px 12px 2px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.check-list .check {
  margin-bottom: 8px;
}

.check-list .icon {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--text-faint);
}

.check-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.check-note {
  flex: none;
  margin-left: auto;
  color: var(--text-faint);
  font-size: 12.5px;
}

/* The text box copyText selects when the clipboard API is not available; never seen. */
.copy-helper {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* ---------- Context menus ---------- */

.context-menu {
  position: fixed;
  z-index: 40;
  display: flex;
  flex-direction: column;
  min-width: 190px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

.context-item {
  display: flex;
  flex: none;
  align-items: center;
  gap: 9px;
  padding: 5px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.context-item .icon {
  width: 17px;
  height: 17px;
  color: var(--text-dim);
}

.context-item:hover,
.context-item:focus-visible {
  outline: none;
  background: var(--bg-hover);
}

.context-item.danger,
.context-item.danger .icon {
  color: var(--danger);
}

.context-item.danger:hover,
.context-item.danger:focus-visible {
  background: var(--danger-soft);
}

.context-menu {
  max-height: calc(100vh - 8px);
  overflow-y: auto;
}

.context-label {
  flex: 1;
}

/* A letter or two where other items have an icon. */
.context-mark {
  width: 17px;
  flex: none;
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 700;
  text-align: center;
}

/* The keys that do the same. */
.context-hint {
  padding-left: 14px;
  color: var(--text-faint);
  font-size: 12px;
}

.context-separator {
  flex: none;
  height: 1px;
  margin: 4px 6px;
  background: var(--border);
}

/* Long-pressing a channel on a touch screen opens its menu, not the system's text selection. */
.chan {
  -webkit-touch-callout: none;
  user-select: none;
}

/* ---------- Voice channels ---------- */

.voice-group .chan {
  margin-bottom: 0;
}

.voice-group {
  margin-bottom: 2px;
}

.voice-people {
  padding: 2px 0 6px 30px;
}

.voice-person {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 6px;
  color: var(--text-dim);
  font-size: 13.5px;
}

.voice-person .avatar {
  width: 22px;
  height: 22px;
  font-size: 10px;
  box-shadow: 0 0 0 2px transparent;
}

.voice-person.speaking .avatar {
  box-shadow: 0 0 0 2px var(--online);
}

.voice-person.speaking {
  color: var(--text);
}

.voice-person.connecting {
  opacity: 0.5;
}

.voice-person-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.voice-person .icon {
  width: 15px;
  height: 15px;
  color: var(--text-faint);
}

/* Next to the name of whoever is sharing their screen. From inside the call it is a button
   that brings the screen back into view. */
.voice-screen {
  display: inline-flex;
  flex: none;
  padding: 2px;
  border: 0;
  border-radius: 4px;
  background: none;
}

.voice-person .voice-screen .icon {
  color: var(--danger);
}

button.voice-screen {
  cursor: pointer;
}

button.voice-screen:hover {
  background: var(--bg-hover);
}

/* A control of the call that is switched on (the screen is being shared). */
.icon-btn.on,
.icon-btn.on:hover:not(:disabled) {
  background: var(--accent-soft);
  color: var(--accent);
}

/* The sound of the shared screen was turned off here. */
.screen-head .icon-btn.off {
  color: var(--danger);
}

/* The screen someone shares in the call: it floats in a corner over whatever is open, or,
   made large, covers everything under the header. */
.screen-view {
  position: absolute;
  right: 16px;
  bottom: 88px;
  z-index: 6;
  display: flex;
  flex-direction: column;
  width: min(460px, calc(100% - 32px));
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #000;
  box-shadow: var(--shadow);
}

.screen-view.large {
  inset: 60px 12px 12px;
  width: auto;
}

.screen-head {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: none;
  padding: 4px 6px 4px 12px;
  background: var(--bg-raised);
  color: var(--text-dim);
  font-size: 13px;
}

.screen-head > .icon {
  width: 16px;
  height: 16px;
  color: var(--danger);
}

.screen-title {
  flex: 1;
  min-width: 0;
  margin-left: 4px;
  overflow: hidden;
  color: var(--text);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.screen-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  object-fit: contain;
}

.screen-view.large .screen-video {
  flex: 1;
  min-height: 0;
  aspect-ratio: auto;
}

/* The cameras that are on in the call: under the header, over whatever is open. */
.camera-view {
  position: absolute;
  top: 60px;
  right: 16px;
  z-index: 7;
  display: flex;
  flex-direction: column;
  width: min(300px, calc(100% - 32px));
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #000;
  box-shadow: var(--shadow);
}

.camera-view:not([data-count='1']) {
  width: min(420px, calc(100% - 32px));
}

.camera-view.large {
  inset: 60px 12px 12px;
  width: auto;
}

.camera-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 2px;
  min-height: 0;
  overflow-y: auto;
}

.camera-view.large .camera-grid {
  flex: 1;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  align-content: center;
}

.camera-tile {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #111;
}

.camera-tile video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Oneself, as in a mirror. */
.camera-tile.mine video {
  transform: scaleX(-1);
}

.camera-name {
  position: absolute;
  left: 6px;
  bottom: 5px;
  max-width: calc(100% - 12px);
  padding: 1px 7px;
  border-radius: 9px;
  background: rgb(0 0 0 / 0.6);
  overflow: hidden;
  color: #fff;
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.voice-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 2px;
  flex: none;
  padding: 8px 6px 8px 12px;
  border-top: 1px solid var(--border);
}

.voice-bar-text {
  flex: 1 1 100%;
  min-width: 0;
  line-height: 1.25;
}

/* The controls of the call, in a row of their own under what it says about it. */
.voice-bar-buttons {
  display: flex;
  gap: 2px;
  margin-left: -6px;
}

/* Talking by holding a key: the microphone waits, and opens while the key is down. */
.voice-bar .icon-btn.waiting {
  opacity: 0.5;
}

.voice-bar .icon-btn.talking {
  color: var(--online);
}

.talk-key {
  align-items: center;
  margin-bottom: 6px;
  color: var(--text-dim);
  font-size: 13.5px;
}

.voice-bar-status {
  overflow: hidden;
  color: var(--online);
  font-size: 12.5px;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Four controls and the state of the call share the width of the sidebar. */
.voice-bar .icon-btn {
  width: 30px;
  height: 30px;
}

.voice-bar-channel {
  overflow: hidden;
  color: var(--text-faint);
  font-size: 12.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.icon-btn.off {
  color: var(--danger);
}

.user-panel {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: none;
  padding: 10px 8px 10px 12px;
  border-top: 1px solid var(--border);
}

/* A person who has put up a picture goes by it instead of by their initials. */
.avatar.pictured {
  overflow: hidden;
  background: var(--bg-hover);
}

.avatar.pictured img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* One's own picture and name, at the top of one's settings. */
.profile {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 14px;
}

.profile-picture .avatar {
  width: 76px;
  height: 76px;
  font-size: 27px;
}

.profile-side {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.profile-side .modal-actions {
  margin: 0;
}

/* Where a new picture is framed: it shows round, as it will be seen. */
.avatar-frame {
  display: block;
  width: 240px;
  height: 240px;
  margin: 4px auto 14px;
  border-radius: 50%;
  outline: 2px solid var(--border);
  background: var(--bg-input);
  cursor: grab;
  touch-action: none;
}

.avatar-frame.held {
  cursor: grabbing;
}

.avatar-frame:focus-visible {
  outline-color: var(--accent);
}

.avatar-zoom {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 280px;
  margin: 0 auto 12px;
  color: var(--text-dim);
  font-size: 13px;
}

.avatar-zoom input {
  flex: 1;
  accent-color: var(--accent);
}

.me-text {
  flex: 1;
  min-width: 0;
  margin-left: 6px;
  line-height: 1.25;
}

.me-name,
.me-username {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.me-name {
  font-weight: 600;
}

.me-username {
  color: var(--text-faint);
  font-size: 12.5px;
}

.avatar {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 50%;
  color: #fff;
  font-size: 13.5px;
  font-weight: 700;
  user-select: none;
}

.main {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

/* Several channels open side by side: the middle of the window is split among them. Each
   pane is a frame with this same application showing one channel. */
.panes {
  display: flex;
  flex: 1;
  min-height: 0;
  overflow-x: auto;
}

.pane {
  position: relative;
  display: flex;
  flex: 1 0 0;
  min-width: 220px;
  border-top: 2px solid transparent;
  border-right: 1px solid var(--border);
}

/* The one the list of channels acts on. */
.pane.active {
  border-top-color: var(--accent);
}

.pane-frame {
  flex: 1;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Over a pane that did not start: what happened, and a way out. */
.pane-stuck {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 12px;
  padding: 24px;
  background: var(--bg);
  color: var(--text-dim);
}

/* The edge between two panes: dragged to give one more of the width and the other less. */
.pane-grip {
  position: absolute;
  top: 0;
  right: -4px;
  bottom: 0;
  z-index: 3;
  width: 8px;
  cursor: col-resize;
  touch-action: none;
}

.pane-grip:hover,
.panes.resizing .pane-grip {
  background: var(--accent-soft);
}

.pane.last .pane-grip {
  display: none;
}

/* While an edge is dragged the pointer stays with the window, not with the frames under it. */
.panes.resizing {
  cursor: col-resize;
  user-select: none;
}

.panes.resizing .pane-frame {
  pointer-events: none;
}

/* The pane being dragged by its header to another place among the others. */
.pane.moving {
  z-index: 2;
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  opacity: 0.85;
}

/* Side by side, the panes show the channels: what this window would show of its own gives way. */
.main.split > :not(.panes):not(.screen-view):not(.camera-view):not(.conn-banner):not(.notify-banner) {
  display: none !important;
}

/* Being a pane: nothing around the channel. */
body.in-pane .app {
  grid-template-columns: minmax(0, 1fr);
}

body.in-pane .sidebar,
body.in-pane .members,
body.in-pane .backdrop,
body.in-pane .conn-banner,
body.in-pane .notify-banner {
  display: none !important;
}

/* The header of a pane is what it is dragged by, to move it among the others. */
body.in-pane .chan-header {
  cursor: grab;
  user-select: none;
}

body.in-pane.pane-moving,
body.in-pane.pane-moving .chan-header {
  cursor: grabbing;
}

/* The button that opens the list of channels on a narrow screen: a pane is always narrow,
   so it goes by the window around it. */
body.in-pane:not(.host-narrow) #btn-menu {
  display: none !important;
}

/* On a narrow screen each pane takes the whole width: they are swiped through. */
@media (max-width: 760px) {
  .panes {
    scroll-snap-type: x mandatory;
  }

  .pane {
    flex-basis: 100%;
    min-width: 100%;
    scroll-snap-align: start;
  }

  .pane-grip {
    display: none;
  }
}

.chan-header {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 52px;
  flex: none;
  padding: 0 12px 0 16px;
  border-bottom: 1px solid var(--border);
}

.chan-header h1 {
  flex: none;
  max-width: 50%;
  overflow: hidden;
  font-size: 16px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chan-hash {
  color: var(--text-faint);
}

.chan-topic {
  min-width: 0;
  padding-left: 12px;
  border-left: 1px solid var(--border);
  overflow: hidden;
  color: var(--text-dim);
  font-size: 13.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chan-topic:empty {
  display: none;
}

.only-mobile {
  display: none;
}

.conn-banner {
  flex: none;
  padding: 6px 16px;
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 13.5px;
  text-align: center;
}

.notify-banner {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 7px 16px;
  background: var(--accent-soft);
  font-size: 13.5px;
}

/* ---------- Messages ---------- */

.scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-anchor: auto;
}

.message-list {
  padding-bottom: 18px;
}

.history-start {
  padding: 40px 16px 8px 72px;
}

.history-start h2 {
  font-size: 20px;
}

.history-start p {
  margin-top: 4px;
  color: var(--text-dim);
}

.empty-state {
  display: grid;
  flex: 1;
  place-content: center;
  justify-items: center;
  gap: 10px;
  padding: 24px;
  color: var(--text-dim);
  text-align: center;
}

.empty-state h2 {
  color: var(--text);
  font-size: 20px;
}

.day-sep {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 16px 4px;
  color: var(--text-faint);
  font-size: 12.5px;
  font-weight: 600;
}

.day-sep::before,
.day-sep::after {
  content: '';
  flex: 1;
  border-top: 1px solid var(--border);
}

.msg {
  position: relative;
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  margin-top: 14px;
  padding: 2px 16px;
}

.msg.compact {
  margin-top: 0;
}

.msg:hover,
.msg.editing {
  background: var(--bg-raised);
}

/* Messages that mention whoever is reading them. */
.msg.mentions-me,
.msg.mentions-me:hover {
  background: var(--mention-soft);
  box-shadow: inset 3px 0 0 var(--mention);
}

.mention {
  padding: 0 3px;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

.mention.me {
  background: var(--mention-soft);
  color: var(--mention);
}

/* Something of a module named in a text: it opens what it names. */
.ref-chip {
  padding: 0 4px;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.ref-chip:hover {
  text-decoration: underline;
}

.ref-chip .icon {
  width: 14px;
  height: 14px;
  margin-right: 3px;
  vertical-align: -2px;
}

.ref-chip.gone {
  background: var(--bg-hover);
  color: var(--text-faint);
  font-weight: 400;
}

.mention-popup {
  position: fixed;
  z-index: 30;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

.mention-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 8px;
  border-radius: 6px;
  cursor: pointer;
}

.mention-item.active,
.mention-item:hover {
  background: var(--bg-hover);
}

.mention-item .avatar {
  width: 26px;
  height: 26px;
  font-size: 11px;
}

/* A small picture in the place of the icon (what a module offers). Pixel art, kept sharp. */
.mention-item .avatar.plain img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  image-rendering: pixelated;
}

.mention-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mention-user {
  flex: none;
  color: var(--text-faint);
  font-size: 12.5px;
}

.msg-side {
  padding-top: 2px;
}

.msg-clock {
  display: none;
  padding-top: 3px;
  color: var(--text-faint);
  font-size: 11px;
}

.msg.compact .avatar,
.msg.compact .msg-head {
  display: none;
}

.msg.compact:hover .msg-clock {
  display: block;
}

.msg-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.msg-author {
  font-weight: 700;
}

.msg-stamp {
  color: var(--text-faint);
  font-size: 12px;
}

.msg-body {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.msg-body code,
.msg-body pre {
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--code-bg);
  font: 13px/1.5 ui-monospace, 'Cascadia Code', Consolas, monospace;
}

.msg-body code {
  padding: 1px 5px;
}

.msg-body pre {
  margin: 4px 0;
  padding: 9px 11px;
  overflow-x: auto;
  white-space: pre;
}

/* Code that says its language: the language in a corner, and each kind of thing in it in
   its own colour (see code.js). The colours are given twice: to the pieces of code that is
   only read, and to the stretches of text the browser is told to paint where it is written. */
.msg-body pre,
.md pre {
  tab-size: 4;
}

.msg-body pre[data-lang],
.md pre[data-lang] {
  position: relative;
}

.msg-body pre[data-lang]::after,
.md pre[data-lang]::after {
  content: attr(data-lang);
  position: absolute;
  top: 0;
  right: 0;
  padding: 1px 7px;
  border-bottom-left-radius: 5px;
  background: var(--bg-hover);
  color: var(--text-faint);
  font: 600 10px/1.6 system-ui, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  pointer-events: none;
  user-select: none;
}

.tok-comment {
  color: var(--code-comment);
}

.tok-string {
  color: var(--code-string);
}

.tok-number {
  color: var(--code-number);
}

.tok-keyword {
  color: var(--code-keyword);
}

.tok-constant {
  color: var(--code-constant);
}

.tok-builtin {
  color: var(--code-builtin);
}

.tok-function {
  color: var(--code-function);
}

.tok-variable {
  color: var(--code-variable);
}

.tok-local {
  color: var(--code-local);
}

.tok-type {
  color: var(--code-type);
}

.tok-meta {
  color: var(--code-meta);
}

/* Apart from the ones above: a browser that does not know ::highlight() would drop them too. */
::highlight(code-comment) {
  color: var(--code-comment);
}

::highlight(code-string) {
  color: var(--code-string);
}

::highlight(code-number) {
  color: var(--code-number);
}

::highlight(code-keyword) {
  color: var(--code-keyword);
}

::highlight(code-constant) {
  color: var(--code-constant);
}

::highlight(code-builtin) {
  color: var(--code-builtin);
}

::highlight(code-function) {
  color: var(--code-function);
}

::highlight(code-variable) {
  color: var(--code-variable);
}

::highlight(code-local) {
  color: var(--code-local);
}

::highlight(code-type) {
  color: var(--code-type);
}

::highlight(code-meta) {
  color: var(--code-meta);
}

.edited {
  color: var(--text-faint);
  font-size: 11.5px;
}

.edit-box {
  margin: 4px 0;
}

/* ---------- Search ---------- */

.search-box {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-input);
  color: var(--text-faint);
}

.search-box:focus-within {
  border-color: var(--accent);
}

.search-box .search-input {
  padding: 10px 0;
  border: 0;
  background: transparent;
}

/* Where to search: one of the two is always on. */
.seg-group {
  display: flex;
  gap: 6px;
  margin: 10px 0 12px;
}

.seg {
  max-width: 50%;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: transparent;
  overflow: hidden;
  color: var(--text-dim);
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.seg:hover {
  color: var(--text);
}

/* What narrows a search down: who wrote it, what it has, and between which days. */
.search-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px 10px;
  margin: 0 0 12px;
}

.search-filter {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  color: var(--text-dim);
  font-size: 12px;
}

.search-filter select,
.search-filter input {
  width: auto;
  max-width: 190px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-input);
  color: var(--text);
  font-size: 13px;
  /* A list to choose from and a date are as tall as each other. */
  height: 32px;
  box-sizing: border-box;
}

.seg.active {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text);
}

.search-results {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}

.search-results:empty {
  display: none;
}

.search-result {
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  cursor: pointer;
}

.search-result:hover,
.search-result:focus-visible {
  outline: none;
  border-color: var(--accent);
}

/* The list of one's mentions: each is a message, drawn as the ones found by a search. The
   ones not read yet stand out. */
.mention-entry.unread {
  border-left: 3px solid var(--mention);
  background: var(--mention-soft);
}

.mention-entry .search-text {
  max-height: 7.5em;
  overflow: hidden;
}

/* What was answered, over an answer. */
.mention-quote {
  margin-bottom: 3px;
  padding-left: 8px;
  border-left: 2px solid var(--border);
  overflow: hidden;
  color: var(--text-dim);
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 3px;
}

.search-meta .avatar {
  align-self: center;
  width: 22px;
  height: 22px;
  flex: none;
  font-size: 10px;
}

.search-meta .msg-author {
  flex: none;
}

.search-place {
  min-width: 0;
  overflow: hidden;
  color: var(--text-dim);
  font-size: 12.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-meta .msg-stamp {
  flex: none;
  margin-left: auto;
}

.search-text {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.search-files {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 3px;
  color: var(--text-dim);
  font-size: 13px;
  overflow-wrap: anywhere;
}

.search-files .icon {
  width: 14px;
  height: 14px;
  flex: none;
}

/* The words that were searched for. */
.search-result mark {
  border-radius: 3px;
  background: var(--mention-soft);
  box-shadow: 0 0 0 1px var(--mention-soft);
  color: var(--mention);
  font-weight: 600;
}

/* ---------- Link previews ---------- */

.msg-previews {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin: 6px 0 2px;
}

/* What a page says about itself: where it is, its title, a line or two, its picture. */
.link-card {
  display: flex;
  gap: 12px;
  width: min(520px, 100%);
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
}

.link-card-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.link-card-site {
  overflow: hidden;
  color: var(--text-dim);
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.link-card-title {
  display: -webkit-box;
  overflow: hidden;
  font-weight: 600;
  text-decoration: none;
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.link-card-title:hover {
  text-decoration: underline;
}

.link-card-desc {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  color: var(--text-dim);
  font-size: 13.5px;
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.link-card-image {
  flex: none;
  align-self: center;
  width: 96px;
  height: 96px;
  border-radius: 6px;
  background: var(--bg-input);
  object-fit: cover;
}

/* ---------- Reactions ---------- */

.msg-reactions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 4px 0 2px;
}

.reaction {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-input);
  color: var(--text-dim);
  font-size: 13px;
  cursor: pointer;
}

.reaction:hover {
  border-color: var(--text-faint);
}

/* One the reader has given. */
.reaction.mine {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text);
}

.reaction-emoji {
  font-size: 15px;
  line-height: 1.45;
}

.reaction-count {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* An emoji to choose: in the row at the top of a message's menu, and in the picker. */
.emoji-btn {
  padding: 5px 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font-size: 19px;
  line-height: 1.2;
  cursor: pointer;
}

.emoji-btn:hover,
.emoji-btn:focus-visible {
  outline: none;
  background: var(--bg-hover);
}

.context-emojis {
  display: flex;
  gap: 2px;
  margin-bottom: 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}

.context-emojis .emoji-btn {
  flex: 1;
}

.emoji-picker {
  position: fixed;
  z-index: 40;
  width: 300px;
  max-width: calc(100vw - 8px);
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

.emoji-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
  max-height: 236px;
  margin-bottom: 8px;
  overflow-y: auto;
}

.emoji-picker .emoji-input {
  padding: 7px 10px;
  font-size: 13.5px;
}

/* ---------- Pinned messages ---------- */

/* Above a pinned message, also when it is grouped under the previous one. */
/* Above a message that answers another: who it answers and the start of what they said.
   A click goes to that message. */
.msg-reply {
  display: flex;
  align-items: center;
  min-width: 0;
  margin-bottom: 2px;
  color: var(--text-dim);
  font-size: 13px;
}

.msg-reply[hidden] {
  display: none;
}

.msg-reply .icon {
  flex: none;
  width: 14px;
  height: 14px;
  margin-right: 6px;
  color: var(--text-faint);
}

.msg-reply-link {
  display: flex;
  align-items: center;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.msg-reply-link:hover .msg-reply-text {
  color: var(--text);
}

.msg-reply-author {
  flex: none;
  margin-right: 6px;
  font-weight: 600;
}

.msg-reply-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.msg-reply.gone {
  color: var(--text-faint);
  font-style: italic;
}

/* The picture of whoever answers stays level with their name, under the line above. */
.msg.has-reply .msg-side {
  padding-top: 24px;
}

/* Over the box to write in, while what is written will answer a message. */
.reply-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 6px 6px 6px 12px;
  border-bottom: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 13px;
}

.reply-bar[hidden] {
  display: none;
}

.reply-bar > .icon {
  flex: none;
  width: 15px;
  height: 15px;
}

.reply-bar-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reply-bar-text strong {
  color: var(--text);
}

.msg-pinned {
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--text-faint);
  font-size: 12px;
}

.msg-pinned .icon {
  width: 13px;
  height: 13px;
  color: var(--accent);
}

/* The message someone has just jumped to. */
.msg.flash {
  animation: msg-flash 2.2s ease-out;
}

@keyframes msg-flash {
  0%,
  40% {
    background: var(--accent-soft);
  }
}

.pins-btn {
  position: relative;
}

.pins-count {
  position: absolute;
  top: 1px;
  right: 0;
  min-width: 15px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-text);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
}

.pin-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.pin-card {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}

.pin-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}

.pin-head .avatar {
  width: 24px;
  height: 24px;
  font-size: 10px;
}

.pin-body {
  max-height: 150px;
  overflow-y: auto;
}

.pin-files {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  color: var(--text-dim);
  font-size: 13px;
  overflow-wrap: anywhere;
}

.pin-files .icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.pin-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}

.pin-by {
  flex: 1;
  min-width: 0;
  color: var(--text-faint);
  font-size: 12px;
}

.edit-box textarea {
  display: block;
  resize: none;
}

.edit-box small {
  color: var(--text-faint);
  font-size: 12px;
}

/* ---------- Database channels ---------- */

.db-view {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

/* ---------- Whiteboard channels ---------- */

.wb-view {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  /* The board in a dark theme: its surface, and what each colour to draw with (--wb-ink-N)
     and each paper of a note (--wb-paper-N) looks like on it. Things on the board keep the
     colour they have on a light board; the rules further down show them as these. */
  --wb-surface: #1a1e23;
  --wb-dot: #2d343c;
  --wb-hint: #7d8792;
  --wb-note-text: #f0f2f4;
  --wb-ink-0: #e6e8eb;
  --wb-ink-1: #9aa4af;
  --wb-ink-2: #ff7b72;
  --wb-ink-3: #f69d50;
  --wb-ink-4: #e3b341;
  --wb-ink-5: #56d364;
  --wb-ink-6: #58a6ff;
  --wb-ink-7: #bc8cff;
  --wb-paper-0: #3b424b;
  --wb-paper-1: #333a43;
  --wb-paper-2: #5c2b30;
  --wb-paper-3: #5e3d1f;
  --wb-paper-4: #5a4b14;
  --wb-paper-5: #1f4d2c;
  --wb-paper-6: #1d4170;
  --wb-paper-7: #44337a;
}

/* In a light theme, and for whoever asked for a light board on a dark one (.wb-light):
   every colour as it is. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) .wb-view {
    --wb-surface: #fcfcfa;
    --wb-dot: #cfd4da;
    --wb-hint: #6e7781;
    --wb-note-text: #1f2328;
    --wb-ink-0: #1f2328;
    --wb-ink-1: #6e7781;
    --wb-ink-2: #d1242f;
    --wb-ink-3: #e16f24;
    --wb-ink-4: #bf8700;
    --wb-ink-5: #1a7f37;
    --wb-ink-6: #0969da;
    --wb-ink-7: #8250df;
    --wb-paper-0: #e8eaed;
    --wb-paper-1: #eceff1;
    --wb-paper-2: #ffd6d9;
    --wb-paper-3: #ffe0c2;
    --wb-paper-4: #fff2a8;
    --wb-paper-5: #cdf2cf;
    --wb-paper-6: #cfe4ff;
    --wb-paper-7: #e6d8ff;
  }
}

:root[data-theme='light'] .wb-view,
.wb-view.wb-light {
  --wb-surface: #fcfcfa;
  --wb-dot: #cfd4da;
  --wb-hint: #6e7781;
  --wb-note-text: #1f2328;
  --wb-ink-0: #1f2328;
  --wb-ink-1: #6e7781;
  --wb-ink-2: #d1242f;
  --wb-ink-3: #e16f24;
  --wb-ink-4: #bf8700;
  --wb-ink-5: #1a7f37;
  --wb-ink-6: #0969da;
  --wb-ink-7: #8250df;
  --wb-paper-0: #e8eaed;
  --wb-paper-1: #eceff1;
  --wb-paper-2: #ffd6d9;
  --wb-paper-3: #ffe0c2;
  --wb-paper-4: #fff2a8;
  --wb-paper-5: #cdf2cf;
  --wb-paper-6: #cfe4ff;
  --wb-paper-7: #e6d8ff;
}

.wb-svg [stroke='#1f2328'] {
  stroke: var(--wb-ink-0);
}

.wb-svg [fill='#1f2328'] {
  fill: var(--wb-ink-0);
}

.wb-svg [stroke='#6e7781'] {
  stroke: var(--wb-ink-1);
}

.wb-svg [fill='#6e7781'] {
  fill: var(--wb-ink-1);
}

.wb-svg [stroke='#d1242f'] {
  stroke: var(--wb-ink-2);
}

.wb-svg [fill='#d1242f'] {
  fill: var(--wb-ink-2);
}

.wb-svg [stroke='#e16f24'] {
  stroke: var(--wb-ink-3);
}

.wb-svg [fill='#e16f24'] {
  fill: var(--wb-ink-3);
}

.wb-svg [stroke='#bf8700'] {
  stroke: var(--wb-ink-4);
}

.wb-svg [fill='#bf8700'] {
  fill: var(--wb-ink-4);
}

.wb-svg [stroke='#1a7f37'] {
  stroke: var(--wb-ink-5);
}

.wb-svg [fill='#1a7f37'] {
  fill: var(--wb-ink-5);
}

.wb-svg [stroke='#0969da'] {
  stroke: var(--wb-ink-6);
}

.wb-svg [fill='#0969da'] {
  fill: var(--wb-ink-6);
}

.wb-svg [stroke='#8250df'] {
  stroke: var(--wb-ink-7);
}

.wb-svg [fill='#8250df'] {
  fill: var(--wb-ink-7);
}

.wb-svg [fill='#e8eaed'] {
  fill: var(--wb-paper-0);
}

.wb-svg [fill='#eceff1'] {
  fill: var(--wb-paper-1);
}

.wb-svg [fill='#ffd6d9'] {
  fill: var(--wb-paper-2);
}

.wb-svg [fill='#ffe0c2'] {
  fill: var(--wb-paper-3);
}

.wb-svg [fill='#fff2a8'] {
  fill: var(--wb-paper-4);
}

.wb-svg [fill='#cdf2cf'] {
  fill: var(--wb-paper-5);
}

.wb-svg [fill='#cfe4ff'] {
  fill: var(--wb-paper-6);
}

.wb-svg [fill='#e6d8ff'] {
  fill: var(--wb-paper-7);
}

/* What a note says is read on its paper, whatever the colour of the pens. */
.wb-svg .wb-note-text {
  fill: var(--wb-note-text);
}

/* The tools, in a row over the board: what to draw with, in which colour and how thick. */
.wb-tools {
  display: flex;
  flex: none;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 14px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--border);
}

.wb-group {
  display: flex;
  flex: none;
  align-items: center;
  gap: 2px;
}

.wb-tool,
.wb-width {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--text-dim);
  cursor: pointer;
}

.wb-tool:hover:not(:disabled),
.wb-width:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.wb-tool.active,
.wb-width.active {
  background: var(--accent-soft);
  color: var(--accent);
}

.wb-tool:disabled {
  opacity: 0.35;
  cursor: default;
}

.wb-tool .icon {
  width: 19px;
  height: 19px;
}

/* A line as thick as what it stands for. */
.wb-width span {
  width: 16px;
  border-radius: 4px;
  background: currentColor;
}

/* Whether shapes are filled: a square that is, or is not. */
.wb-fill span {
  width: 15px;
  height: 15px;
  border: 2px solid currentColor;
  border-radius: 3px;
}

.wb-fill.active span {
  background: currentColor;
}

.wb-colour {
  width: 22px;
  height: 22px;
  margin: 0 2px;
  padding: 0;
  border: 2px solid var(--bg);
  border-radius: 50%;
  background: var(--wb-colour);
  box-shadow: 0 0 0 1px var(--border);
  cursor: pointer;
}

.wb-colour.active {
  box-shadow: 0 0 0 2px var(--accent);
}

/* The board itself, in the colours of the theme (see .wb-view). */
.wb-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background-color: var(--wb-surface);
  background-image: radial-gradient(circle, var(--wb-dot) 1px, transparent 1.3px);
  outline: none;
  cursor: crosshair;
  touch-action: none;
  user-select: none;
}

.wb-stage.far {
  background-image: none;
}

.wb-stage[data-tool='select'] {
  cursor: default;
}

.wb-stage[data-tool='hand'],
.wb-stage.grab {
  cursor: grab;
}

.wb-stage.panning {
  cursor: grabbing;
}

.wb-stage[data-tool='text'] {
  cursor: text;
}

.wb-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.wb-stage[data-tool='select'] .wb-items [data-id] {
  cursor: move;
}

/* What is not finished, here or elsewhere, and what frames the selection, are not pointed at. */
.wb-drafts,
.wb-own,
.wb-frame,
.wb-band {
  pointer-events: none;
}

.wb-draft {
  opacity: 0.75;
}

.wb-erasing {
  opacity: 0.25;
}

.wb-frame {
  fill: none;
  stroke: #0969da;
  stroke-width: 1;
  stroke-dasharray: 4 3;
}

.wb-band {
  fill: rgb(9 105 218 / 0.08);
  stroke: #0969da;
  stroke-width: 1;
}

.wb-handle {
  fill: #fff;
  stroke: #0969da;
  stroke-width: 1.5;
  cursor: nwse-resize;
}

/* Where the others are pointing, with their names. */
.wb-pointers {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.wb-pointer {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: flex-start;
  transition: transform 0.09s linear;
}

.wb-pointer svg {
  flex: none;
  fill: var(--wb-colour);
  stroke: #fff;
  stroke-width: 1;
  stroke-linejoin: round;
}

.wb-pointer-name {
  margin: 12px 0 0 -2px;
  padding: 1px 7px;
  border-radius: 9px;
  background: var(--wb-colour);
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}

/* Writing on the board: right where the text will be, as large as it will be. */
.wb-editor {
  position: absolute;
  z-index: 2;
  margin: 0;
  border: 0;
  border-radius: 0;
  outline: 1px dashed #0969da;
  outline-offset: 3px;
  overflow: hidden;
  font-family: system-ui, 'Segoe UI', Roboto, sans-serif;
  resize: none;
}

.wb-editor.note {
  border-radius: 3px;
  outline-style: solid;
  outline-offset: 0;
  overflow-wrap: anywhere;
}

.wb-hint {
  position: absolute;
  top: 38%;
  right: 24px;
  left: 24px;
  margin: 0;
  color: var(--wb-hint);
  font-size: 15px;
  text-align: center;
  pointer-events: none;
}

/* How close the board is seen from, in a corner. */
.wb-zoom {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-raised);
  box-shadow: 0 2px 10px rgb(0 0 0 / 0.15);
  cursor: default;
}

.wb-zoom .icon-btn {
  font-size: 17px;
}

.wb-zoom-level {
  min-width: 50px;
  padding: 4px 2px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--text-dim);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.wb-zoom-level:hover {
  background: var(--bg-hover);
  color: var(--text);
}

/* ---------- Page channels ---------- */

.page-view {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.page-scroll {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding: 18px 16px 0;
  overflow-y: auto;
}

/* Over a page that is inside another one: the pages on the way down to it, each a link. */
.page-path {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px;
  padding: 0 4px 12px;
  color: var(--text-dim);
  font-size: 13.5px;
}

.page-path-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 260px;
  padding: 3px 6px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.page-path-item > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.page-path-item:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.page-path-item.here {
  color: var(--text);
  font-weight: 600;
  cursor: default;
}

.page-path-item.here:hover {
  background: none;
}

.page-path-item .icon {
  width: 15px;
  height: 15px;
}

.page-path-sep {
  color: var(--text-faint);
}

/* The same over a database made inside a page: at the left, where its table starts. */
.db-path {
  width: auto;
  max-width: none;
  margin: 0;
  padding: 10px 12px 0;
}

/* The document: a column of comfortable reading width, written in directly. */
.page-path,
.page-doc,
.page-tail {
  width: 100%;
  max-width: 820px;
  margin: 0 auto;
}

.page-doc {
  position: relative;
  flex: none;
  padding: 0 10px;
  cursor: text;
}

.page-doc:focus-visible {
  outline: none;
}

.page-doc.empty::before {
  content: attr(data-placeholder);
  position: absolute;
  top: 8px;
  left: 10px;
  color: var(--text-faint);
  pointer-events: none;
}

/* A paragraph someone else has their cursor in. */
.page-doc > [data-writer] {
  position: relative;
  box-shadow: -7px 0 0 -4px var(--mention);
}

.page-doc > [data-writer]::after {
  content: attr(data-writer);
  position: absolute;
  top: -15px;
  right: 0;
  color: var(--mention);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
}

/* Pictures, players and files are things on the page: they are picked as a whole. */
.page-doc .md-image,
.page-doc .md-file,
.page-doc video,
.page-doc audio {
  cursor: pointer;
}

/* The corner a picture is resized by: it sits on the bottom right of the picture the pointer
   is over, and scrolls with the page. */
.page-grip {
  position: absolute;
  z-index: 2;
  width: 16px;
  height: 16px;
  margin: -20px 0 0 -20px;
  border: 2px solid #fff;
  border-radius: 5px;
  background: var(--accent);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.55);
  cursor: nwse-resize;
  touch-action: none;
}

/* On a video it sits at the top right, clear of the controls of the player. */
.page-grip.above {
  margin-top: 4px;
  cursor: ew-resize;
}

.page-grip.dragging {
  background: var(--mention);
}

/* All the room under the text: clicking there goes on writing at the end. */
.page-tail {
  flex: 1;
  min-height: 160px;
  cursor: text;
}

/* "Saving…" and "Saved", out of the way. */
.page-status {
  position: absolute;
  top: 8px;
  right: 22px;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--bg-raised);
  color: var(--text-faint);
  font-size: 12px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s;
}

.page-status.shown {
  opacity: 1;
  transition: none;
}

/* Markdown, as it reads in a page. */
.md {
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.md h1,
.md h2,
.md h3,
.md h4,
.md h5,
.md h6 {
  margin: 20px 0 6px;
  line-height: 1.25;
}

.md h1 {
  font-size: 28px;
}

.md h2 {
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
  font-size: 22px;
}

.md h3 {
  font-size: 18px;
}

.md h4,
.md h5,
.md h6 {
  font-size: 15px;
}

.md h5,
.md h6 {
  color: var(--text-dim);
}

.md p,
.md ul,
.md ol,
.md blockquote,
.md pre,
.md .md-table {
  margin: 8px 0;
}

.md ul,
.md ol {
  padding-left: 26px;
}

.md li {
  margin: 2px 0;
}

.md li > ul,
.md li > ol {
  margin: 2px 0;
}

.md li.md-task {
  margin-left: -22px;
  list-style: none;
}

.md li.md-task > input {
  width: 15px;
  height: 15px;
  margin: 0 8px 0 0;
  vertical-align: -2px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* What the browser's own commands write while editing reads like the rest. */
.md b {
  font-weight: 700;
}

.md a {
  color: var(--link);
}

.md blockquote {
  padding: 2px 14px;
  border-left: 3px solid var(--border);
  color: var(--text-dim);
}

.md code,
.md pre {
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--code-bg);
  font: 13px/1.5 ui-monospace, 'Cascadia Code', Consolas, monospace;
}

.md code {
  padding: 1px 5px;
}

.md pre {
  padding: 10px 12px;
  overflow-x: auto;
}

.md pre code {
  padding: 0;
  border: 0;
  background: transparent;
  white-space: pre;
}

.md hr {
  margin: 18px 0;
  border: 0;
  border-top: 1px solid var(--border);
}

.md-table {
  overflow-x: auto;
}

.md table {
  border-collapse: collapse;
  font-size: 14px;
}

.md th,
.md td {
  padding: 6px 12px;
  border: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.md th {
  background: var(--bg-raised);
}

/* Room to click in a cell that has nothing in it yet. */
.page-doc th,
.page-doc td {
  min-width: 90px;
}

/* Pictures and players that were uploaded to the page. */
.md-image {
  display: inline-block;
  max-width: 100%;
  vertical-align: top;
}

.md-image img,
.md-video {
  display: block;
  max-width: 100%;
  max-height: 560px;
  border-radius: var(--radius);
}

/* A picture or a video that was given a width keeps its proportions at that width. */
.md-image img[width],
.md-video[width] {
  height: auto;
  max-height: none;
}

.md-video {
  background: #000;
}

.md-audio {
  display: block;
  width: 100%;
  max-width: 460px;
}

/* A link to a file kept here looks like an attachment. */
.md a.md-file {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
}

.md a.md-file:hover {
  border-color: var(--accent);
}

.md-file .icon {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--text-faint);
}

/* A person or another page named in the text. */
.md a.md-mention {
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: default;
}

.md a.md-mention[data-kind='channel'],
.md a.md-mention[data-kind='module'] {
  cursor: pointer;
}

.md a.md-mention[data-kind='channel']:hover,
.md a.md-mention[data-kind='module']:hover {
  text-decoration: underline;
}

/* Whoever is reading is the one mentioned. */
.md a.md-mention.me {
  background: var(--mention-soft);
  color: var(--mention);
}

/* Someone who no longer has an account, or a page that was deleted. */
.md a.md-mention.gone {
  background: var(--bg-hover);
  color: var(--text-faint);
  font-weight: 400;
  cursor: default;
}

.md-mention .icon {
  width: 0.95em;
  height: 0.95em;
  margin-right: 3px;
  vertical-align: -0.12em;
}

/* Whoever is reading was mentioned in that page and has not opened it yet. */
.md-mention-count {
  display: inline-block;
  min-width: 1.35em;
  margin-left: 5px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 0.72em;
  font-weight: 700;
  line-height: 1.35;
  text-align: center;
  vertical-align: 0.1em;
}

/* What is offered after an @ or a /page in a page: it hangs from the text, not from a field. */
.page-mentions {
  width: 300px;
  max-width: calc(100vw - 16px);
}

/* A line that only says what to type: there is nothing to pick. */
.page-mentions .mention-item.hint,
.page-mentions .mention-item.hint:hover {
  background: none;
  color: var(--text-dim);
  cursor: default;
}

.page-mentions .mention-user {
  max-width: 55%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mention-item .avatar.plain {
  background: var(--bg-hover);
  color: var(--text-dim);
}

.mention-item .avatar .icon {
  width: 15px;
  height: 15px;
}

/* With an entry open, the table gives way to that entry's fields, which sit above its
   conversation and take only the room they need. */
.db-entry {
  display: none;
}

.db-view.entry-open {
  flex: none;
  max-height: 48%;
  border-bottom: 1px solid var(--border);
  overflow-y: auto;
}

.db-view.entry-open .db-toolbar,
.db-view.entry-open .db-scroll {
  display: none;
}

.db-view.entry-open .db-entry {
  display: block;
  padding: 10px 16px 14px;
}

.db-entry-bar {
  display: flex;
  align-items: center;
  gap: 8px;
}

.db-entry-title {
  margin: 10px 0 8px;
  overflow-wrap: anywhere;
  font-size: 22px;
}

.db-props {
  width: 100%;
  max-width: 760px;
  border-collapse: collapse;
  font-size: 14px;
}

.db-props th {
  width: 190px;
  padding: 7px 10px 7px 0;
  color: var(--text-dim);
  font-weight: 400;
  text-align: left;
  vertical-align: top;
}

.db-prop-name {
  display: flex;
  align-items: center;
  gap: 7px;
}

.db-prop-name .icon {
  width: 15px;
  height: 15px;
  color: var(--text-faint);
}

.db-props .db-cell,
.db-props .db-cell.type-number {
  max-width: none;
  border-radius: 6px;
  text-align: left;
}

.db-props .db-cell:hover {
  background: var(--bg-raised);
}

/* The button that opens an entry sits at the end of the first cell of its row. */
.db-cell.db-first {
  position: relative;
  min-width: 250px;
  padding-right: 58px;
}

.db-open {
  position: absolute;
  top: 5px;
  right: 5px;
  display: none;
  align-items: center;
  gap: 4px;
  height: 25px;
  padding: 0 7px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-raised);
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.db-open .icon {
  width: 14px;
  height: 14px;
}

/* Always visible once the entry has messages; otherwise when pointing at the row. */
.db-open.has-messages,
.db-table tr:hover .db-open,
.db-open:focus-visible {
  display: inline-flex;
}

@media (hover: none) {
  .db-open {
    display: inline-flex;
  }
}

.db-open:hover {
  color: var(--text);
}

.db-open.unread {
  border-color: var(--text);
  color: var(--text);
}

.db-open.mention {
  border-color: var(--danger);
  background: var(--danger);
  color: #fff;
}

.db-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
  padding: 10px 16px;
}

.db-search {
  display: flex;
  align-items: center;
  gap: 6px;
  width: min(260px, 45%);
  padding: 0 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-input);
  color: var(--text-faint);
}

.db-search:focus-within {
  border-color: var(--accent);
}

.db-search .icon {
  width: 16px;
  height: 16px;
}

.db-search input.db-search-input {
  padding: 6px 0;
  border: 0;
  background: transparent;
  outline: none;
}

.db-count {
  color: var(--text-faint);
  font-size: 13px;
  white-space: nowrap;
}

.db-scroll {
  flex: 1;
  min-height: 0;
  padding: 0 16px 16px;
  overflow: auto;
}

.db-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}

.db-table th,
.db-table td {
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.db-table th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 0;
  border-top: 1px solid var(--border);
  background: var(--bg);
  font-weight: 600;
}

.db-table th:first-child,
.db-table td:first-child {
  border-left: 1px solid var(--border);
}

.db-th-inner {
  display: flex;
  align-items: center;
  min-width: 150px;
  max-width: 360px;
  padding-right: 3px;
}

.db-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.db-head:hover {
  color: var(--text);
}

.db-head .icon {
  width: 15px;
  height: 15px;
  color: var(--text-faint);
}

.db-head-name {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Next to the count of rows: how many columns the table leaves out. */
.db-hidden-note {
  color: var(--text-dim);
  font-size: 12.5px;
  font-weight: 400;
  white-space: nowrap;
}

/* In an entry opened on its own: a field the table does not show. */
.db-prop-hidden {
  display: block;
  margin-top: 2px;
  color: var(--text-faint);
  font-size: 11.5px;
  font-weight: 400;
}

.db-th-rest .db-head {
  color: var(--text-faint);
  font-weight: 400;
}

/* A column someone gave a width to: heading and cells are exactly that wide, and what does
   not fit wraps or is cut instead of pushing the column wider. */
.db-th.sized .db-th-inner {
  min-width: 0;
  max-width: none;
}

.db-cell.sized {
  overflow: hidden;
}

.db-cell.sized.db-automatic {
  text-overflow: ellipsis;
}

.db-cell.sized.type-link a {
  max-width: none;
}

/* A heading being dragged to move its column: it fades, and a line shows where it would go. */
.db-reordering,
.db-reordering * {
  cursor: grabbing !important;
  user-select: none;
}

.db-th.dragging {
  opacity: 0.45;
}

.db-th.drop-left::before,
.db-th.drop-right::after {
  content: '';
  position: absolute;
  top: -1px;
  bottom: -1px;
  z-index: 4;
  width: 3px;
  background: var(--accent);
  pointer-events: none;
}

.db-th.drop-left::before {
  left: -2px;
}

.db-th.drop-right::after {
  right: 0;
}

/* The edge of a heading that is dragged to change the width of its column. */
.db-resize {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 7px;
  cursor: col-resize;
  touch-action: none;
}

.db-resize:hover,
.db-resizing .db-resize:active {
  background: var(--accent);
}

.db-resizing {
  cursor: col-resize;
  user-select: none;
}

.db-table .db-gutter {
  width: 46px;
  min-width: 46px;
  padding: 0;
  color: var(--text-faint);
  font-size: 12px;
  text-align: center;
  vertical-align: middle;
}

/* The row number gives way to the button that opens the row when pointing at it. */
.db-gutter .db-row-open {
  display: none;
  margin: 0 auto;
}

.db-table tr:hover .db-gutter .db-row-open,
.db-gutter:focus-within .db-row-open {
  display: inline-flex;
}

.db-table tr:hover .db-number,
.db-gutter:focus-within .db-number {
  display: none;
}

.db-cell {
  min-width: 150px;
  max-width: 360px;
  height: 36px;
  padding: 7px 10px;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  cursor: text;
}

.db-cell:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.db-table tbody tr:hover td {
  background: var(--bg-raised);
}

.db-cell.type-number {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* A long address stays on one line instead of making the whole row taller. */
.db-cell.type-link a {
  display: block;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.db-cell.type-checkbox {
  cursor: default;
}

/* Columns the rows fill in by themselves: shown, not edited. */
.db-cell.db-automatic {
  color: var(--text-dim);
  white-space: nowrap;
  cursor: default;
}

.db-person {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.db-person .avatar {
  width: 20px;
  height: 20px;
  font-size: 9px;
}

.db-cell.type-checkbox input {
  width: 17px;
  height: 17px;
  margin: 1px 0 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.db-cell.type-image {
  padding: 4px 6px;
  cursor: default;
}

.db-cell.editing {
  padding: 0;
}

.db-editor,
select.db-editor,
input[type='text'].db-editor {
  display: block;
  width: 100%;
  min-height: 35px;
  padding: 6px 9px;
  border: 2px solid var(--accent);
  border-radius: 0;
  background: var(--bg-input);
  font: inherit;
  resize: none;
}

.db-filler {
  width: 100%;
  border-right: 0 !important;
}

.db-empty {
  padding: 28px 16px;
  color: var(--text-dim);
  text-align: center;
}

.db-images {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.db-thumb {
  width: 40px;
  height: 28px;
  border-radius: 4px;
  background: var(--bg-input);
  object-fit: cover;
  cursor: zoom-in;
}

/* The add button only shows when pointing at the cell, unless the cell is empty. */
.db-add-image {
  opacity: 0;
}

.db-cell:hover .db-add-image,
.db-add-image:focus-visible,
.db-images > .db-add-image:only-child {
  opacity: 1;
}

.db-uploading {
  color: var(--text-faint);
  font-size: 12.5px;
}

.db-option-pill {
  display: inline-block;
  max-width: 100%;
  padding: 1px 8px;
  border-radius: 10px;
  overflow: hidden;
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.db-options {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

.db-option-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.db-option-dot {
  width: 14px;
  height: 14px;
  flex: none;
  border-radius: 50%;
}

/* Colours of the options of a select column. */
.opt-0 { background: hsl(210 10% 50% / 0.3); }
.opt-1 { background: hsl(172 60% 42% / 0.32); }
.opt-2 { background: hsl(212 80% 55% / 0.32); }
.opt-3 { background: hsl(265 70% 62% / 0.32); }
.opt-4 { background: hsl(325 70% 58% / 0.32); }
.opt-5 { background: hsl(3 75% 58% / 0.32); }
.opt-6 { background: hsl(28 85% 54% / 0.34); }
.opt-7 { background: hsl(48 90% 50% / 0.34); }
.opt-8 { background: hsl(135 50% 45% / 0.32); }

/* ---------- Attachments ---------- */

.msg-files {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
  margin: 6px 0 2px;
}

.att-image {
  display: block;
  max-width: min(420px, 100%);
  max-height: 320px;
  border-radius: var(--radius);
  background: var(--bg-input);
  cursor: zoom-in;
}

.att-media {
  max-width: min(480px, 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  overflow: hidden;
}

.att-media video {
  display: block;
  width: 100%;
  max-height: 340px;
  background: #000;
}

.att-media.audio {
  width: 380px;
}

.att-media audio {
  display: block;
  width: 100%;
}

.att-caption {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 4px 4px 10px;
  font-size: 13px;
}

.att-name {
  min-width: 0;
  overflow: hidden;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.att-caption .att-name {
  flex: 1;
}

.att-size {
  flex: none;
  color: var(--text-faint);
  font-size: 12.5px;
}

.att-file {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 380px;
  max-width: 100%;
  padding: 8px 8px 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}

.att-file > .icon {
  width: 26px;
  height: 26px;
  color: var(--accent);
}

.att-file-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}

.att-file-text a {
  text-decoration: none;
}

.att-file-text a:hover {
  text-decoration: underline;
}

/* ---------- Composer ---------- */

.composer {
  flex: none;
  margin: 0 16px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-input);
}

.composer:focus-within {
  border-color: var(--accent);
}

.composer-row {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  padding: 5px 6px;
}

.composer textarea {
  flex: 1;
  min-height: 34px;
  max-height: 220px;
  padding: 6px 4px;
  border: 0;
  background: transparent;
  resize: none;
  outline: none;
}

.pending {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 10px 4px;
}

.pending-item {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 260px;
  padding: 6px 6px 6px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}

.pending-item img {
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 5px;
  object-fit: cover;
}

.pending-item > .icon {
  width: 26px;
  height: 26px;
  color: var(--accent);
}

.pending-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-size: 13px;
}

.upload-progress {
  position: relative;
  height: 20px;
  margin: 8px 10px 2px;
  border-radius: 5px;
  background: var(--bg);
  overflow: hidden;
}

.upload-progress .bar {
  width: 0;
  height: 100%;
  background: var(--accent-soft);
  border-right: 2px solid var(--accent);
  transition: width 0.15s linear;
}

.upload-progress .label {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
}

.dropzone {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  padding: 24px;
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  pointer-events: none;
}

.dropzone div {
  padding: 28px 40px;
  border: 2px dashed var(--accent);
  border-radius: 14px;
  background: var(--bg-raised);
  font-size: 17px;
  font-weight: 600;
}

/* ---------- People ---------- */

.members {
  width: 230px;
  padding: 8px;
  border-left: 1px solid var(--border);
  background: var(--bg-side);
  overflow-y: auto;
}

.member-group {
  padding: 14px 8px 6px;
  color: var(--text-faint);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.member {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 8px;
  border-radius: 6px;
}

.member .avatar {
  width: 30px;
  height: 30px;
  font-size: 12px;
}

.member.offline {
  opacity: 0.5;
}

.member-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.avatar-wrap {
  position: relative;
  flex: none;
}

.dot {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 11px;
  height: 11px;
  border: 2px solid var(--bg-side);
  border-radius: 50%;
  background: var(--online);
}

.member.offline .dot {
  background: var(--text-faint);
}

.tag {
  flex: none;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
  vertical-align: 1px;
}

.tag.muted {
  background: var(--bg-hover);
  color: var(--text-dim);
}

/* ---------- Dialogs ---------- */

.modal {
  width: min(440px, calc(100vw - 24px));
  max-height: calc(100dvh - 24px);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  box-shadow: var(--shadow);
}

.modal[open] {
  display: flex;
  flex-direction: column;
}

.modal.wide {
  width: min(720px, calc(100vw - 24px));
}

.modal::backdrop {
  background: rgba(0, 0, 0, 0.6);
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex: none;
  padding: 14px 14px 10px 20px;
}

.modal-head h2 {
  min-width: 0;
  overflow: hidden;
  font-size: 17px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.modal-body {
  padding: 6px 20px 20px;
  overflow-y: auto;
}

.modal-body h3 {
  margin-bottom: 12px;
  font-size: 14.5px;
}

.modal-text {
  margin-bottom: 14px;
}

.modal-text.dim {
  color: var(--text-dim);
  font-size: 13.5px;
}

.modal-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 6px;
}

.modal-actions.start {
  justify-content: flex-start;
}

/* Administration > Modules: each module, and under it whatever it has to set up. */
.module-row {
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}

.module-row:last-child {
  border-bottom: 0;
}

.module-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.module-name {
  flex: 1;
  min-width: 0;
  font-weight: 600;
}

.module-name small {
  margin-left: 6px;
  color: var(--text-faint);
  font-weight: 400;
}

.module-about {
  margin: 4px 0 0;
  color: var(--text-dim);
  font-size: 13.5px;
}

.module-panel {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.credentials {
  margin: 0 0 14px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--code-bg);
  font: 14px/1.6 ui-monospace, 'Cascadia Code', Consolas, monospace;
  white-space: pre-wrap;
  user-select: all;
}

/* The viewer of a picture. The stage is what is seen of it: all of it at first, and a part
   once it is zoomed into. */
.modal.viewer {
  width: min(1100px, calc(100vw - 24px));
}

.lightbox-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--code-bg);
  touch-action: none;
  user-select: none;
}

.lightbox-img {
  display: block;
  flex: none;
  max-width: 100%;
  max-height: calc(100dvh - 190px);
  border-radius: var(--radius);
}

/* Once its size is known it is laid out fitted, and brought nearer with a transform. */
.lightbox-stage.ready .lightbox-img {
  max-width: none;
  max-height: none;
  cursor: zoom-in;
}

.lightbox-stage.zoomed .lightbox-img {
  border-radius: 0;
  cursor: grab;
}

.lightbox-stage.panning .lightbox-img {
  cursor: grabbing;
}

.lightbox-zoom {
  display: flex;
  gap: 4px;
  margin-right: auto;
}

.lightbox-zoom .btn {
  min-width: 38px;
  padding: 8px 10px;
}

.lightbox-zoom .lightbox-level {
  min-width: 64px;
  font-variant-numeric: tabular-nums;
}

.tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

.tab {
  margin-bottom: -1px;
  padding: 8px 14px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--text-dim);
  font-weight: 600;
  cursor: pointer;
}

.tab.active {
  border-bottom-color: var(--accent);
  color: var(--text);
}

.user-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.user-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px;
  border-radius: var(--radius);
}

.user-row:hover {
  background: var(--bg-raised);
}

.user-row.disabled .avatar,
.user-row.disabled .user-text {
  opacity: 0.55;
}

.user-text {
  flex: 1;
  min-width: 0;
}

.user-name {
  font-weight: 600;
}

.user-username {
  color: var(--text-faint);
  font-size: 13px;
}

/* ---------- Alerts ---------- */

.toasts {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 2147483647;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  pointer-events: none;
}

/* Shown over everything when what is in front of the server wants the person to sign in again. */
.gate-notice {
  position: fixed;
  top: 12px;
  left: 50%;
  z-index: 2147483647;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  max-width: calc(100vw - 32px);
  padding: 10px 14px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
  box-shadow: var(--shadow);
  transform: translateX(-50%);
}

.gate-notice[hidden] {
  display: none;
}

.toast {
  max-width: min(420px, calc(100vw - 32px));
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

.toast.error {
  border-color: var(--danger);
}

.toast.clickable {
  border-color: var(--accent);
  cursor: pointer;
  pointer-events: auto;
}

.backdrop {
  display: none;
}

/* ---------- Narrow screens ---------- */

@media (max-width: 1000px) {
  .members {
    position: absolute;
    top: 52px;
    right: 0;
    bottom: 0;
    z-index: 8;
    box-shadow: var(--shadow);
  }
}

@media (max-width: 760px) {
  .app {
    grid-template-columns: minmax(0, 1fr);
  }

  .only-mobile {
    display: inline-flex;
  }

  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 20;
    width: min(290px, 86vw);
    transform: translateX(-100%);
    transition: transform 0.18s ease;
  }

  .sidebar-open .sidebar {
    transform: none;
  }

  .sidebar-open .backdrop {
    position: fixed;
    inset: 0;
    z-index: 15;
    display: block;
    background: rgba(0, 0, 0, 0.55);
  }

  .chan-header {
    padding-left: 8px;
  }

  .chan-topic {
    display: none;
  }

  .msg {
    grid-template-columns: 46px minmax(0, 1fr);
    padding: 3px 12px;
  }

  .history-start {
    padding-left: 12px;
  }

  .composer {
    margin: 0 8px 8px;
  }

  .grid-2 {
    grid-template-columns: 1fr;
  }

  .att-media.audio,
  .att-file {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}

/* Installed on a phone, Wilson reaches the bottom edge of the screen: what it shows keeps
   clear of the bar phones have there. (Anywhere else that room is none, and nothing changes.) */
@media (display-mode: standalone) {
  .app {
    box-sizing: border-box;
    padding-bottom: env(safe-area-inset-bottom);
  }
}

@media (display-mode: standalone) and (max-width: 760px) {
  .sidebar {
    padding-bottom: env(safe-area-inset-bottom);
  }
}

/* ---------- A database as a board or as a calendar ---------- */

.db-modes {
  display: flex;
  flex: none;
  border: 1px solid var(--border);
  border-radius: 7px;
  overflow: hidden;
}

.db-mode {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: 0;
  border-right: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  font-size: 13px;
  cursor: pointer;
}

.db-mode:last-child {
  border-right: 0;
}

.db-mode .icon {
  width: 15px;
  height: 15px;
}

.db-mode:hover {
  color: var(--text);
}

.db-mode.active {
  background: var(--accent-soft);
  color: var(--text);
}

.db-board,
.db-calendar {
  display: none;
  flex: 1;
  min-height: 0;
  padding: 0 16px 16px;
  overflow: auto;
}

.db-view[data-mode='board'] .db-board,
.db-view[data-mode='calendar'] .db-calendar {
  display: block;
}

.db-view[data-mode='board'] .db-scroll,
.db-view[data-mode='calendar'] .db-scroll,
.db-view[data-mode='board'] .db-hidden-slot,
.db-view[data-mode='calendar'] .db-hidden-slot,
.db-view.entry-open .db-board,
.db-view.entry-open .db-calendar {
  display: none;
}

.dbv-empty {
  max-width: 560px;
  margin: 30px auto;
  color: var(--text-dim);
  text-align: center;
}

.dbv-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.dbv-bar .spacer {
  flex: 1;
}

.dbv-pick {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-dim);
  font-size: 13px;
}

.dbv-pick select {
  width: auto;
  padding: 4px 26px 4px 8px;
  font-size: 13px;
}

/* The board: lanes side by side, each as tall as its cards. */
.board-lanes {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-width: min-content;
}

.board-lane {
  display: flex;
  flex-direction: column;
  flex: none;
  gap: 8px;
  width: 270px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-side);
}

.board-lane.over,
.cal-day.over,
.cal-undated.over {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.board-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.board-none {
  color: var(--text-faint);
  font-size: 13px;
}

.board-count {
  color: var(--text-faint);
  font-size: 12px;
  font-weight: 700;
}

.board-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 6px;
}

.board-card {
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg-raised);
  cursor: pointer;
}

.board-card:hover,
.board-card:focus-visible {
  border-color: var(--text-faint);
}

.board-card.dragging,
.cal-chip.dragging {
  opacity: 0.45;
}

.board-cover {
  display: block;
  width: 100%;
  max-height: 130px;
  margin-bottom: 8px;
  border-radius: 5px;
  object-fit: cover;
}

.board-title {
  overflow-wrap: anywhere;
  font-weight: 600;
}

.board-fields {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin-top: 6px;
}

.board-field {
  max-width: 100%;
  overflow: hidden;
  color: var(--text-dim);
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.board-foot {
  display: flex;
  justify-content: flex-end;
  margin-top: 6px;
}

.board-add {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 6px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-faint);
  font-size: 13px;
  cursor: pointer;
}

.board-add:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.board-add .icon {
  width: 14px;
  height: 14px;
}

/* The calendar: a month, a week on each row. */
.cal-month {
  min-width: 150px;
  margin: 0 4px;
  font-size: 15px;
}

.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(110px, 1fr));
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
}

.cal-weekday {
  padding: 5px 8px;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  color: var(--text-faint);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
}

.cal-day {
  min-height: 104px;
  padding: 5px 6px 7px;
  border: 1px solid transparent;
  border-right-color: var(--border);
  border-bottom-color: var(--border);
}

.cal-day.other {
  background: var(--bg-side);
}

.cal-day.other .cal-num {
  color: var(--text-faint);
}

.cal-num {
  display: inline-block;
  min-width: 22px;
  margin-bottom: 3px;
  padding: 1px 5px;
  border-radius: 11px;
  color: var(--text-dim);
  font-size: 12.5px;
  text-align: center;
}

.cal-day.today .cal-num {
  background: var(--accent);
  color: var(--accent-text);
  font-weight: 700;
}

.cal-chips {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-height: 150px;
  overflow-y: auto;
}

.cal-chip {
  display: block;
  width: 100%;
  padding: 2px 7px;
  border: 0;
  border-radius: 5px;
  overflow: hidden;
  color: var(--text);
  font-size: 12.5px;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

/* An entry with no option to take its colour from. */
.cal-chip:not([class*='opt-']) {
  background: var(--bg-hover);
}

.cal-chip:hover {
  filter: brightness(1.15);
}

.cal-undated {
  margin-top: 12px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.cal-undated-label {
  display: block;
  margin-bottom: 6px;
  color: var(--text-faint);
  font-size: 12.5px;
}

.cal-undated .cal-chips {
  flex-direction: row;
  flex-wrap: wrap;
  max-height: none;
}

.cal-undated .cal-chip {
  width: auto;
  max-width: 220px;
}

/* The window a file of text or code is read in: as wide as there is room for and as tall
   as the file needs, with the numbers of its lines staying put while the lines are moved
   sideways. */
.modal.viewer {
  width: min(1100px, calc(100vw - 24px));
}

.modal.viewer .modal-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.viewer-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  margin-bottom: 10px;
}

.viewer-bar .btn {
  text-decoration: none;
}

.viewer-bar .btn[aria-pressed='true'] {
  border-color: var(--accent);
  color: var(--accent);
}

.viewer-info {
  flex: 1;
  min-width: 0;
  color: var(--text-dim);
  font-size: 13px;
}

.viewer-scroll {
  display: flex;
  flex: 1;
  align-items: flex-start;
  min-height: 0;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--code-bg);
}

.viewer-scroll > p {
  margin: 14px;
}

.viewer-lines,
.viewer-code {
  margin: 0;
  padding: 10px 12px;
  font: 13px/1.5 ui-monospace, 'Cascadia Code', Consolas, monospace;
  tab-size: 4;
}

.viewer-lines {
  position: sticky;
  left: 0;
  flex: none;
  border-right: 1px solid var(--border);
  background: var(--code-bg);
  color: var(--text-faint);
  text-align: right;
  user-select: none;
}

.viewer-code {
  flex: 1;
  min-width: 0;
  white-space: pre;
}

/* With the lines wrapped, their numbers would no longer be beside them. */
.viewer-scroll.wrapped .viewer-lines {
  display: none;
}

.viewer-scroll.wrapped .viewer-code {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

/* The mark of a message a program posted, after the name it goes by. */
.msg-app {
  margin: 0 6px 0 -2px;
}

/* The webhooks of a channel. */
.hook-list {
  display: grid;
  gap: 4px;
  margin-bottom: 4px;
}

.hook-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
}

.hook-text {
  flex: 1;
  min-width: 0;
}

.hook-name {
  overflow: hidden;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hook-used {
  color: var(--text-faint);
  font-size: 13px;
}

.hook-help summary {
  color: var(--text-dim);
  cursor: pointer;
}

.hook-help summary + * {
  margin-top: 8px;
}

/* The backups that are kept, in Administration. */
.backup-list {
  display: grid;
  gap: 4px;
  margin-bottom: 12px;
}

.backup-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}

.backup-row:last-child {
  border-bottom: 0;
}

.backup-row .dim {
  color: var(--text-dim);
}

/* In place of the box to write in, where only administrators write. */
.composer-note {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0 16px 16px;
  padding: 11px 14px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--text-dim);
  font-size: 13.5px;
}

.composer-note .icon {
  width: 16px;
  height: 16px;
  flex: none;
}

/* What administrators have done, in Administration. */
.audit-tools {
  margin-bottom: 10px;
}

.audit-tools select {
  width: auto;
}

.audit-list {
  display: grid;
  margin-bottom: 12px;
}

.audit-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}

.audit-row:last-child {
  border-bottom: 0;
}

.audit-when {
  flex: none;
  width: 150px;
  color: var(--text-dim);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}

.audit-what {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Who a private channel is for, before its description in the header. */
.chan-topic .chan-private {
  margin-right: 8px;
  vertical-align: -2px;
}
