/* ==========================================================================
   Telegram Messages — parchment theme, iPhone-app structure
   ========================================================================== */

:root {
  --paper: #f5f0e8;
  --paper-2: #ece4d4;
  --ink: #1a1a1a;
  --muted: #5c5446;
  --rule: #ddd3c0;
  --head: #1a1a1a;
  --head-ink: #f5f0e8;
  --head-muted: #c8bfaa;
  --accent: #2b4a6f;
  --muted-2: #6b6253;
  --enl: #8a4b0f;
  --enl-tint: #efe0c8;
  --bubble-in: #faf7f0;
  --bubble-in-rule: #c8bfaa;
  --bad: #9b2c1f;
}

* { box-sizing: border-box; }

/* An author `display` rule would otherwise beat the UA's [hidden] */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

/* No rubber-band bounce on the page. On the iPhone a tap at the top of the
   list caught the bounce and became a drag, and the next tap landed while
   it settled, so taps kept failing until a double tap (tap trace). */
html, body { overscroll-behavior: none; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--paper);
  color: var(--ink);
  font: 17px/1.4 'Times New Roman', Times, serif;
}

button, input { font: inherit; }
button, a { touch-action: manipulation; }

/* Header. From the home screen the status bar overlays the page, so the
   header grows by the top inset; in Safari the insets are 0. */
.head {
  background: var(--head);
  color: var(--head-ink);
  padding: calc(8px + env(safe-area-inset-top)) calc(16px + env(safe-area-inset-right))
           12px calc(16px + env(safe-area-inset-left));
}
.head-row {
  display: flex; align-items: center; min-height: 28px;
}
/* The large title, with New Message beside it (list page) */
.title-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 4px;
}
.brand {
  font-size: 13px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--head-muted);
}
.head h1 { margin: 4px 0 0; font-size: 34px; letter-spacing: -.01em; }
.head .title-row h1 { margin: 0; }

.linkish {
  min-height: 44px; min-width: 44px; padding: 0 4px;
  border: 0; background: none; color: var(--head-ink);
  cursor: pointer; font-size: 16px;
}
.inline { display: inline; margin: 0; }

.main {
  padding: 20px calc(16px + env(safe-area-inset-right))
           calc(20px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left));
  max-width: 640px;
  margin: 0 auto;
}

/* Sign-in */
.signin { max-width: 360px; margin: 32px auto 0; }
.signin h2 { margin: 0 0 16px; font-size: 24px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label { font-size: 15px; color: var(--muted); }
/* 16px+ stops iOS zooming into the field on focus */
.field input {
  min-height: 44px; padding: 8px 12px;
  border: 1px solid #b9ad95; border-radius: 10px;
  background: #fffdf8; color: var(--ink); font-size: 17px;
}
.field input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.primary {
  width: 100%; min-height: 48px; margin-top: 6px;
  border: 0; border-radius: 10px;
  background: var(--accent); color: #fff; font-size: 17px; font-weight: bold;
  cursor: pointer;
}
.error {
  margin: 0 0 14px; padding: 10px 12px;
  border-radius: 10px; background: #f3dcd5; color: var(--bad); font-size: 15px;
}

/* Pills (line badges) */
.pill {
  display: inline-block; padding: 1px 7px; flex: none;
  border-radius: 999px; background: #4a4438; color: var(--paper);
  font: 700 10px/1.6 -apple-system, system-ui, sans-serif; letter-spacing: .08em;
}
.pill.enl { background: var(--enl); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.avatar {
  width: 44px; height: 44px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #4a4438; color: var(--paper); font-size: 16px; font-weight: bold;
}
.enl .avatar { background: var(--enl); }

/* ---------- Conversation list ---------- */
.list { max-width: 720px; margin: 0 auto; }
.empty { color: var(--muted); padding: 24px 16px; margin: 0; }

.row {
  display: flex; align-items: center; gap: 10px;
  min-height: 76px;
  padding: 0 calc(16px + env(safe-area-inset-right)) 0 calc(6px + env(safe-area-inset-left));
  color: inherit; text-decoration: none;
  background: var(--paper);           /* opaque: covers its Delete button */
}
.row.enl { background: var(--enl-tint); }
.row:active { background: var(--paper-2); }
.row.enl:active { background: #e6d3b5; }
.dot { width: 10px; height: 10px; flex: none; border-radius: 50%; }
.row.unread .dot { background: var(--accent); }
.row-body {
  flex: 1; min-width: 0; align-self: stretch;
  display: flex; flex-direction: column; justify-content: center; gap: 3px;
  padding: 12px 0; border-bottom: 1px solid var(--rule);
}
.row-top { display: flex; align-items: baseline; gap: 6px; }
.row-name {
  flex: 1; min-width: 0; font-weight: bold;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row-time { flex: none; font-size: 14px; color: var(--muted-2); }
.row-snippet { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 15px; }
.row-snippet .ico { flex: none; }
.row-text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---------- Search ---------- */
.search {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 10px calc(16px + env(safe-area-inset-right)) 8px calc(16px + env(safe-area-inset-left));
  border-bottom: 1px solid var(--rule);
}
/* 17px keeps iOS from zooming in on focus */
.search input {
  flex: 1; min-width: 0; min-height: 38px; padding: 6px 12px;
  border: 1px solid var(--rule); border-radius: 10px; -webkit-appearance: none; appearance: none;
  background: var(--paper-2); color: var(--ink); font-size: 17px;
}
.search input::placeholder { color: var(--muted-2); }
.search input:focus { outline: 2px solid var(--accent); outline-offset: 0; background: #fffdf8; }
.search-cancel { color: var(--accent); text-decoration: none; font-size: 16px; padding: 8px 0; }
.results-head {
  margin: 0; padding: 14px calc(16px + env(safe-area-inset-right)) 4px calc(16px + env(safe-area-inset-left));
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted-2);
}
.row.hit .dot { visibility: hidden; }
mark { background: #f0d98a; color: inherit; border-radius: 2px; }
.bubble.out mark { background: #f0d98a; color: var(--ink); }
.bubble.hit { box-shadow: 0 0 0 3px #f0d98a; }

/* ---------- Layout: list pane + detail pane ----------
   One page holds both. On a phone only one shows: the list, or (with a
   thread or new message open) the detail pane, which is exactly the
   viewport so its header and composer stay put and only messages scroll.
   From 768px (iPad portrait and up) they sit side by side. */
.app .pane-detail { display: none; }
.app.has-detail .pane-list { display: none; }
.app.has-detail .pane-detail {
  height: 100vh; height: 100dvh; min-height: 0;
  display: flex; flex-direction: column;
}
.detail-empty { display: none; }
.compose-pane { flex: 1; min-height: 0; overflow-y: auto; width: 100%; }

@media (min-width: 768px) {
  .app {
    height: 100vh; height: 100dvh; min-height: 0; overflow: hidden;
    display: grid; grid-template-columns: minmax(280px, 360px) minmax(0, 1fr);
  }
  .app .pane-list, .app.has-detail .pane-list {
    display: flex; flex-direction: column; min-height: 0; min-width: 0;
    border-right: 1px solid var(--bubble-in-rule);
  }
  .app .pane-detail, .app.has-detail .pane-detail {
    display: flex; flex-direction: column; min-height: 0; min-width: 0; height: auto;
  }
  .pane-list .head h1 { font-size: 28px; }
  /* Line the two dark headers up */
  .pane-list .head, .pane-detail .thread-head { min-height: calc(108px + env(safe-area-inset-top)); }
  .pane-list .list {
    flex: 1; min-height: 0; max-width: none; margin: 0;
    overflow-y: auto; overscroll-behavior: contain;
  }
  /* Both panes are always on screen: no back button, but keep its space so
     the name stays centred */
  .pane-detail .back { visibility: hidden; }
  .detail-empty {
    display: flex; flex: 1; margin: 0; align-items: center; justify-content: center;
    color: var(--muted); font-size: 18px;
  }
  .pane-list .account { max-width: none; margin: 0; border-top: 1px solid var(--rule); padding-top: 10px; padding-bottom: calc(10px + env(safe-area-inset-bottom)); }
  .row.selected { background: var(--paper-2); }
  .row.enl.selected { background: #e6d3b5; }
  .bubble { max-width: min(70%, 520px); }
}

/* ---------- Thread ---------- */
.thread-head {
  flex: none; display: flex; align-items: center; gap: 4px;
  background: var(--head); color: var(--head-ink);
  padding: calc(6px + env(safe-area-inset-top)) calc(8px + env(safe-area-inset-right))
           10px calc(8px + env(safe-area-inset-left));
}
.back, .head-spacer, .head-btn {
  width: 44px; height: 44px; flex: none;
  display: flex; align-items: center; justify-content: center; color: #e8e0d0;
}
.who-block {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center;
}
.who-block .avatar { width: 40px; height: 40px; font-size: 15px; }
.who-block h1 {
  margin: 0; max-width: 100%; font-size: 15px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.who-block .sub { font-size: 12px; color: var(--head-muted); }

.band {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 8px calc(16px + env(safe-area-inset-right)) 8px calc(16px + env(safe-area-inset-left));
  background: var(--enl-tint); color: #5a3108; font-size: 13px;
  border-bottom: 1px solid #d9c3a0;
}

/* column-reverse with a single child opens scrolled to the newest message,
   with no script, while the messages keep their reading order. */
.scroller {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column-reverse;
}
.msgs {
  width: 100%; max-width: 720px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 6px;
  padding: 14px calc(14px + env(safe-area-inset-right))
           calc(14px + env(safe-area-inset-bottom)) calc(14px + env(safe-area-inset-left));
}
.sep { margin: 10px 0 4px; text-align: center; font-size: 12px; color: var(--muted-2); }

.bubble {
  margin: 0; max-width: min(78%, 480px);
  padding: 9px 13px; font-size: 17px; line-height: 1.3;
  overflow-wrap: anywhere;
}
.bubble.in {
  align-self: flex-start; background: var(--bubble-in);
  border: 1px solid var(--bubble-in-rule); border-radius: 18px 18px 18px 6px;
}
.bubble.out {
  align-self: flex-end; background: var(--accent); color: var(--paper);
  border-radius: 18px 18px 6px 18px;
}
.enl .bubble.out { background: var(--enl); }
.bubble.missing { font-style: italic; color: var(--muted); }
.bubble.out.missing { color: var(--paper); }
.bubble.file { text-decoration: underline; }
.bubble.in.file { color: var(--accent); }
.bubble.out.file { color: var(--paper); }

.media { max-width: min(70%, 320px); }
.media.in { align-self: flex-start; }
.media.out { align-self: flex-end; }
.media img, video.media {
  display: block; max-width: 100%; max-height: 360px; height: auto;
  border-radius: 18px; border: 1px solid var(--bubble-in-rule); background: var(--paper-2);
}
audio.media { width: 260px; max-width: 78%; }

.bubble.vm {
  width: min(300px, 85%); padding: 10px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.bubble.vm audio { width: 100%; height: 44px; }
.vm-label {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--muted-2); letter-spacing: .04em; text-transform: uppercase;
}

.status { margin: -2px 6px 0 0; align-self: flex-end; font-size: 12px; color: var(--muted-2); }
.status.failed { color: var(--bad); }

/* ---------- Sending ---------- */
.icon-btn {
  width: 44px; height: 44px; flex: none;
  display: flex; align-items: center; justify-content: center; color: var(--head-ink);
}
/* New message: a filled round button, the header's only action */
.compose-btn { width: 48px; height: 48px; margin-right: -2px; }
.compose-btn span {
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff;
}
.compose-btn:active span { background: #223b59; }

/* Sign out lives under the list, out of reach of a stray tap in the
   header (a repeated Back, or aiming for New Message). On a computer or
   iPad the list scrolls and this stays at the bottom of its pane. */
.account {
  flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  max-width: 720px; margin: 0 auto;
  padding: 16px calc(16px + env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom))
           calc(16px + env(safe-area-inset-left));
  font-size: 15px; color: var(--muted-2);
}
.account-out {
  min-height: 44px; padding: 0 16px;
  border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-2);
  color: var(--bad); font-size: 16px; cursor: pointer;
}

.composer {
  flex: none; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 6px;
  border-top: 1px solid var(--bubble-in-rule); background: var(--bubble-in);
  padding: 8px calc(10px + env(safe-area-inset-right))
           calc(8px + env(safe-area-inset-bottom)) calc(14px + env(safe-area-inset-left));
}
.enl .composer { background: #f6ecdc; border-top-color: #d9c3a0; }
/* 17px keeps iOS from zooming in on focus */
.composer textarea {
  flex: 1; min-width: 0; min-height: 38px; max-height: 40vh;
  padding: 8px 14px; resize: none; field-sizing: content;
  border: 1px solid var(--bubble-in-rule); border-radius: 19px;
  background: #fff; color: var(--ink); font-size: 17px; line-height: 1.25; font-family: inherit;
}
.composer textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; }
.enl .composer textarea:focus { outline-color: var(--enl); }
.send {
  width: 44px; height: 44px; flex: none; padding: 0;
  border: 0; background: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.send span {
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--paper);
}
.enl .send span { background: var(--enl); }
.send:disabled span { opacity: .5; }
.send-error {
  flex: none; margin: 0; padding: 8px 16px;
  background: #f3dcd5; color: var(--bad); font-size: 14px; text-align: center;
}
/* Picture to send: the button is a label around a hidden file input, so
   it works without script too */
.attach {
  width: 44px; height: 44px; flex: none; margin-left: -8px;
  display: flex; align-items: center; justify-content: center;
  color: #4a4438; cursor: pointer;
}
.enl .attach { color: #5a3108; }
.attach input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.attach:focus-within { outline: 2px solid var(--accent); border-radius: 50%; }
.attach-preview { flex-basis: 100%; position: relative; display: flex; padding: 2px 0 4px 36px; }
.attach-preview[hidden] { display: none; }
.attach-preview img {
  max-height: 120px; max-width: 60%; border-radius: 12px;
  border: 1px solid var(--bubble-in-rule); background: var(--paper-2);
}
.attach-remove {
  width: 44px; height: 44px; margin-left: -22px; margin-top: -14px; padding: 0;
  border: 0; background: none; cursor: pointer;
  display: flex; align-items: flex-start; justify-content: flex-start;
  font-size: 0;
}
.attach-remove::before {
  content: '×'; width: 24px; height: 24px; border-radius: 50%;
  background: var(--ink); color: var(--paper); font: bold 18px/24px sans-serif; text-align: center;
}

.composer-off {
  flex: none; margin: 0; text-align: center; font-size: 14px; color: var(--muted);
  border-top: 1px solid var(--rule);
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
}

.compose { max-width: 480px; margin: 8px auto 0; }
.compose textarea {
  min-height: 120px; padding: 10px 12px; resize: vertical;
  border: 1px solid #b9ad95; border-radius: 10px;
  background: #fffdf8; color: var(--ink); font-size: 17px; font-family: inherit;
}
.compose textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.lines { border: 0; padding: 0; margin: 0 0 14px; flex-direction: row; gap: 8px; flex-wrap: wrap; }
.lines legend { font-size: 15px; color: var(--muted); padding: 0; margin-bottom: 6px; width: 100%; }
.line-choice {
  display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px;
  border: 1px solid #b9ad95; border-radius: 999px; background: #fffdf8; cursor: pointer;
}
.line-choice.enl { border-color: #d9c3a0; background: var(--enl-tint); }
.from-note { margin: 0 0 14px; font-size: 15px; color: var(--muted); }

/* ---------- Notifications ---------- */
.notify-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px calc(16px + env(safe-area-inset-right)) 10px calc(16px + env(safe-area-inset-left));
  background: var(--paper-2); border-bottom: 1px solid var(--rule); font-size: 15px;
}
.notify-bar span { flex: 1; min-width: 0; }
.notify-btn {
  flex: none; min-height: 44px; padding: 0 16px;
  border: 0; border-radius: 10px; background: var(--accent); color: #fff;
  font-weight: bold; cursor: pointer;
}
.notify-x {
  flex: none; width: 44px; height: 44px; border: 0; background: none;
  font-size: 26px; color: var(--muted); cursor: pointer;
}

@media (max-width: 480px) {
  .head h1 { font-size: 30px; }
}

/* ---------- Busy (app.js showBusy()) ----------
   Takes taps at once; the tint and spinner fade in after 250ms, so a quick
   answer shows nothing. */
.busy {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  background: rgba(26, 26, 26, .2);
  animation: busy-in .2s ease .25s both;
}
.spinner {
  width: 64px; height: 64px; border-radius: 16px;
  background: rgba(26, 26, 26, .78);
  display: flex; align-items: center; justify-content: center;
}
.spinner::after {
  content: ''; width: 30px; height: 30px; border-radius: 50%;
  border: 3px solid rgba(245, 240, 232, .3); border-top-color: var(--paper);
  animation: spin .8s linear infinite;
}
/* While the page loads (index.php): shown almost at once, and given up
   after 20s in case app.js never arrives, so the page still works with
   plain links */
.busy.boot { animation: busy-in .2s ease .1s both, boot-giveup 0s linear 20s forwards; }
@keyframes busy-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes boot-giveup { to { visibility: hidden; } }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner::after { animation-duration: 2.4s; }
}

/* ---------- Deleting a conversation ----------
   A row slides left over its Delete button (app.js). pan-y leaves vertical
   scrolling to the browser; sideways drags come to the script. */
.swipe { position: relative; overflow: hidden; }
.swipe .row {
  position: relative; z-index: 1;
  touch-action: pan-y; transition: transform .2s ease;
}
.swipe.dragging .row { transition: none; }
.row-delete {
  position: absolute; top: 0; right: 0; bottom: 0; width: 96px;
  border: 0; background: var(--bad); color: #fff;
  font: 600 16px -apple-system, system-ui, sans-serif; cursor: pointer;
}
.head-btn { color: #e8e0d0; }
.primary.danger { background: var(--bad); }

/* ---------- Picture viewer ---------- */
.viewer {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  background: #000;
  padding: calc(52px + env(safe-area-inset-top)) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}
.viewer img { max-width: 100%; max-height: 100%; object-fit: contain; }
.viewer-bar {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; justify-content: flex-end;
  padding: calc(4px + env(safe-area-inset-top)) calc(8px + env(safe-area-inset-right)) 4px 8px;
}
.viewer-close {
  min-height: 44px; padding: 0 12px; border: 0; background: none;
  color: #fff; font: 600 17px -apple-system, system-ui, sans-serif; cursor: pointer;
}
.viewer-close:focus:not(:focus-visible) { outline: none; }
body.viewing { overflow: hidden; }

/* ---------- Message actions (app.js) ----------
   A long press on a message (right-click with a mouse) opens a sheet with
   Copy and Delete. On touch screens the browser's own callout and text
   selection would fight the press, so they are off; Copy replaces them. */
@media (pointer: coarse) {
  [data-m] { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
}
[data-m] { transition: transform .15s ease; }
[data-m].pressing { transform: scale(.96); }
[data-m].picked { position: relative; z-index: 81; }
.sheet {
  position: fixed; inset: 0; z-index: 80;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
  background: rgba(26, 26, 26, .35);
  padding: 0 calc(8px + env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom))
           calc(8px + env(safe-area-inset-left));
  animation: busy-in .15s ease both;
}
.sheet-group {
  width: 100%; max-width: 420px; margin-top: 8px;
  border-radius: 14px; overflow: hidden; background: #fffdf8;
}
.sheet-note {
  margin: 0; padding: 12px 16px; text-align: center;
  font-size: 13px; color: var(--muted-2); border-bottom: 1px solid var(--rule);
}
.sheet button {
  display: block; width: 100%; min-height: 56px; padding: 0 16px;
  border: 0; border-top: 1px solid var(--rule); background: none;
  color: var(--accent); font: 400 19px -apple-system, system-ui, sans-serif; cursor: pointer;
}
.sheet button:first-of-type { border-top: 0; }
.sheet button.danger { color: var(--bad); }
.sheet button.cancel { font-weight: 600; }
.sheet button:active { background: var(--paper-2); }
