/* Eturnal Rest -- on-site chat (/messages.html).

   The shape people already know from WhatsApp: a conversation list beside a
   thread of bubbles, a wallpapered scroll area, day dividers, read marks, and a
   pill composer pinned to the bottom. The palette stays Eturnal Rest, so
   outgoing bubbles are the brand blue tint rather than WhatsApp green. Familiar
   layout, our identity.

   Layout: two panes on desktop, one pane at a time on mobile with a back arrow,
   both driven by the same markup. The app owns the viewport height on this page,
   because a chat that scrolls the page instead of the message list feels broken
   on a phone. */

/* Every pane in here sets an explicit display, which outranks the browser's own
   [hidden] rule and leaves hidden panes on screen. With three panes visible the
   two-column grid wraps and the layout collapses, so this is load-bearing. */
.chat [hidden],
.sheet[hidden],
#deal-drawer[hidden] {
  display: none !important;
}

/* Off screen, still read aloud. Carries the new-message announcement, so the
   thread can be rebuilt on every poll without a screen reader re-reading it. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- shell -- */

.page-messages {
  /* The composer must sit above the on-screen keyboard, so the app is sized to
     the small viewport height where the browser supports it. */
  overflow: hidden;
}

.chat {
  --chat-header-h: 62px;
  --chat-bubble-me: #dcecf5; /* soft brand-blue tint, our answer to #dcf8c6 */
  --chat-bubble-them: var(--surface-0);
  --chat-wallpaper: #ebe6de;
  --chat-pane-w: 366px;

  display: grid;
  grid-template-columns: var(--chat-pane-w) 1fr;
  height: calc(100svh - var(--site-header-h, 0px));
  min-height: 520px;
  background: var(--surface-0);
  border-top: 1px solid var(--line);
  overflow: hidden;
}

/* ------------------------------------------------------------ left pane -- */

.chat__list {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-right: 1px solid var(--line);
  background: var(--surface-0);
}

.chat__list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  height: var(--chat-header-h);
  padding: 0 16px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.chat__list-head h1 {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 1.15rem;
  color: var(--blue-900);
}

.chat__search {
  flex: 0 0 auto;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
}

.chat__search input {
  width: 100%;
  padding: 9px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  font: inherit;
  font-size: 0.92rem;
  color: var(--ink);
}

.chat__search input:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-color: var(--blue-400);
}

.chat__convos {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.convo {
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 12px;
  width: 100%;
  padding: 11px 14px;
  border: 0;
  border-bottom: 1px solid var(--line-soft);
  background: transparent;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.convo:hover {
  background: var(--blue-25);
}

.convo.is-on {
  background: var(--blue-50);
}

.convo__avatar {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--blue-600);
  color: var(--white);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: 0.02em;
  user-select: none;
}

.convo__avatar--concierge {
  background: var(--blue-800);
}

.convo__main {
  min-width: 0;
}

.convo__top,
.convo__bottom {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.convo__bottom {
  align-items: center;
  margin-top: 2px;
}

.convo__name {
  font-weight: 600;
  color: var(--ink);
  font-size: 0.98rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.convo__when {
  flex: 0 0 auto;
  font-size: 0.74rem;
  color: var(--ink-3);
}

.convo.has-unread .convo__when {
  color: var(--blue-600);
  font-weight: 600;
}

.convo__preview {
  min-width: 0;
  font-size: 0.86rem;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.convo__badge {
  flex: 0 0 auto;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  background: var(--blue-600);
  color: var(--white);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 20px;
  text-align: center;
}

.convo__plot {
  display: block;
  margin-top: 3px;
  font-size: 0.76rem;
  color: var(--ink-4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ----------------------------------------------------------- right pane -- */

.chat__thread {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--chat-wallpaper);
}

.chat__thread-head {
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--chat-header-h);
  padding: 0 14px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.chat__back {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin-left: -6px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--blue-700);
  cursor: pointer;
  font-size: 1.35rem;
  line-height: 1;
}

.chat__back:hover {
  background: var(--blue-100);
}

.chat__who {
  min-width: 0;
  flex: 1 1 auto;
}

.chat__who-name {
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat__who-sub {
  font-size: 0.78rem;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat__who-sub a {
  color: var(--blue-700);
}

/* The message scroller. The wallpaper is a faint diagonal weave rather than a
   photograph, so text stays readable and nothing has to be downloaded. */
.chat__scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 16px clamp(12px, 5vw, 64px) 10px;

  /* A short conversation sits at the BOTTOM, against the composer, the way
     every phone messenger does it. Block layout would strand three messages at
     the top of an empty screen. margin-top:auto on the first child rather than
     justify-content:flex-end, because the latter clips the top of the list once
     the thread grows past one screen. */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background-color: var(--chat-wallpaper);
  background-image:
    repeating-linear-gradient(
      45deg,
      rgba(255, 255, 255, 0.5) 0 2px,
      transparent 2px 9px
    ),
    repeating-linear-gradient(
      -45deg,
      rgba(29, 55, 68, 0.028) 0 2px,
      transparent 2px 9px
    );
}

.chat__scroll > *:first-child {
  margin-top: auto;
}

.chat__day {
  display: flex;
  align-self: stretch;
  justify-content: center;
  margin: 14px 0 10px;
}

.chat__day span {
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: var(--shadow-xs);
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ------------------------------------------------------------- bubbles -- */

.bub {
  position: relative;
  /* Hug the text. A block-level bubble fills the column up to max-width, which
     left every message the same 560px slab with the timestamp marooned at the
     far right. */
  width: fit-content;
  max-width: min(78%, 560px);
  margin: 2px 0;
  padding: 7px 11px 6px;
  border-radius: 9px;
  background: var(--chat-bubble-them);
  box-shadow: var(--shadow-xs);
  font-size: 0.945rem;
  line-height: 1.42;
  color: var(--ink);
  word-wrap: break-word;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.bub--me {
  align-self: flex-end;
  background: var(--chat-bubble-me);
}

/* The tail, drawn only on the last bubble of a run so a burst of messages reads
   as one block the way it does in a phone client. */
.bub--tail-them {
  border-top-left-radius: 2px;
}

.bub--tail-me {
  border-top-right-radius: 2px;
}

.bub__meta {
  float: right;
  margin: 6px -2px -2px 10px;
  font-size: 0.68rem;
  color: var(--ink-4);
  user-select: none;
  white-space: nowrap;
}

.bub__ticks {
  margin-left: 3px;
  letter-spacing: -2px;
  color: var(--ink-4);
}

.bub__ticks.is-read {
  color: var(--blue-600);
}

.bub__who {
  display: block;
  margin-bottom: 2px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--blue-700);
}

/* System lines: the thread narrating itself (a price proposed, an agreement
   signed). Centered, quiet, never attributed to a person. */
.bub--system {
  align-self: center;
  max-width: min(86%, 620px);
  margin: 10px auto;
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.86);
  box-shadow: var(--shadow-xs);
  text-align: center;
  font-size: 0.82rem;
  color: var(--ink-2);
  white-space: pre-wrap;
}

/* ------------------------------------------------------------ composer -- */

.chat__composer {
  display: flex;
  align-items: flex-end;
  gap: 9px;
  flex: 0 0 auto;
  padding: 10px clamp(10px, 4vw, 24px);
  background: var(--surface-2);
  border-top: 1px solid var(--line);
}

.chat__composer textarea {
  flex: 1 1 auto;
  min-height: 42px;
  max-height: 148px;
  padding: 10px 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-xl);
  background: var(--surface-0);
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.4;
  color: var(--ink);
  resize: none;
}

.chat__composer textarea:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-color: var(--blue-400);
}

.chat__send {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: var(--blue-600);
  color: var(--white);
  cursor: pointer;
  transition:
    background 0.15s ease,
    transform 0.1s ease;
}

.chat__send:hover:not(:disabled) {
  background: var(--blue-700);
}

.chat__send:active:not(:disabled) {
  transform: scale(0.94);
}

.chat__send:disabled {
  background: var(--blue-300);
  cursor: default;
}

.chat__send svg {
  width: 21px;
  height: 21px;
  fill: currentColor;
}

/* --------------------------------------------------------- deal drawer -- */

/* The sale agreement, pinned under the thread header. It is part of the
   conversation, so it lives in the thread rather than on a separate page. */
.deal {
  flex: 0 0 auto;
  padding: 11px 14px;
  background: var(--blue-50);
  border-bottom: 1px solid var(--blue-150);
}

.deal--signed {
  background: #eaf3ec;
  border-bottom-color: #c9e0cf;
}

.deal__row {
  display: flex;
  align-items: center;
  gap: 10px 14px;
  flex-wrap: wrap;
}

.deal__label {
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--blue-700);
}

.deal--signed .deal__label {
  color: #3d6b4a;
}

.deal__price {
  font-family: var(--font-serif);
  font-size: 1.22rem;
  color: var(--blue-900);
}

.deal__note {
  flex: 1 1 220px;
  min-width: 0;
  font-size: 0.83rem;
  color: var(--ink-2);
}

.deal__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-left: auto;
}

.deal__btn {
  padding: 7px 14px;
  border: 1px solid var(--blue-600);
  border-radius: var(--radius-pill);
  background: var(--surface-0);
  color: var(--blue-700);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.deal__btn:hover {
  background: var(--blue-100);
}

.deal__btn--primary {
  background: var(--blue-600);
  border-color: var(--blue-600);
  color: var(--white);
}

.deal__btn--primary:hover {
  background: var(--blue-700);
}

.deal__btn--quiet {
  border-color: var(--line-strong);
  color: var(--ink-2);
}

.deal__btn--quiet:hover {
  background: var(--surface-3);
}

.deal__sigs {
  display: flex;
  gap: 8px 18px;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: 0.8rem;
  color: var(--ink-2);
}

.deal__sig--done::before {
  content: "\2713\00a0";
  color: #3d7a52;
  font-weight: 700;
}

.deal__sig--wait::before {
  content: "\25cb\00a0";
  color: var(--ink-4);
}

/* ------------------------------------------------------- contact unlock -- */

/* The line under the thread header explaining why a message looks redacted.
   Quiet on purpose: it is context, not an offer, and both parties see it. */
.chat__notice {
  flex: 0 0 auto;
  margin: 0;
  padding: 8px 14px;
  background: var(--surface-1);
  border-bottom: 1px solid var(--line);
  font-size: 0.8rem;
  color: var(--ink-3);
}

/* Where an email address or a phone number used to be.

   THE BAR IS DECORATION AND NOTHING ELSE. There is no value behind the blur,
   real or invented: the contact details never reached the browser, which is the
   whole point, so there is nothing here for an inspector to recover. The words
   next to it are what actually tells the reader what happened. */
.bub__redact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 1px;
  padding: 1px 9px 1px 5px;
  border-radius: var(--radius-pill);
  background: rgba(15, 41, 66, 0.07);
  font-size: 0.78em;
  font-weight: 600;
  color: var(--ink-3);
  vertical-align: baseline;
  white-space: nowrap;
}

.bub__redact-bar {
  width: 46px;
  height: 0.62em;
  border-radius: 3px;
  background: repeating-linear-gradient(
    90deg,
    var(--ink-3) 0 9px,
    transparent 9px 13px
  );
  filter: blur(2.2px);
  opacity: 0.75;
}

/* The panel that sells, and then shows, the seller's contact details. Sits
   above the agreement drawer because that is the order of the story: reach the
   seller, agree a price, sign. */
.unlock {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px 14px;
  flex-wrap: wrap;
  padding: 11px 14px;
  background: var(--blue-50);
  border-bottom: 1px solid var(--blue-150);
}

.unlock--open {
  background: #eaf3ec;
  border-bottom-color: #c9e0cf;
}

.unlock__label {
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--blue-700);
}

.unlock--open .unlock__label {
  color: #3d6b4a;
}

.unlock__note {
  flex: 1 1 220px;
  min-width: 0;
  font-size: 0.83rem;
  color: var(--ink-2);
}

.unlock__row {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}

.unlock__key {
  font-size: 0.74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-3);
}

.unlock__val {
  font-size: 0.92rem;
  color: var(--blue-800);
  overflow-wrap: anywhere;
}

.unlock__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-left: auto;
}

/* A blur is a static filter rather than motion, so it stays. What goes is the
   suggestion of texture, which is the part that reads as visual noise to
   somebody who asked for less of it. */
@media (prefers-reduced-motion: reduce) {
  .bub__redact-bar {
    background: var(--ink-4);
    filter: none;
    opacity: 0.6;
  }
}

/* ---------------------------------------------------------------- modal -- */

.sheet[hidden] {
  display: none !important;
}

.sheet {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(22, 42, 53, 0.55);
}

.sheet__panel {
  width: min(660px, 100%);
  max-height: min(88svh, 820px);
  display: flex;
  flex-direction: column;
  background: var(--surface-0);
  border-radius: var(--radius);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
}

.sheet__head {
  flex: 0 0 auto;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--line);
}

.sheet__head h2 {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 1.2rem;
  color: var(--blue-900);
}

.sheet__head p {
  margin: 5px 0 0;
  font-size: 0.88rem;
  color: var(--ink-2);
}

.sheet__body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 16px 20px;
}

.sheet__foot {
  flex: 0 0 auto;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  flex-wrap: wrap;
  padding: 13px 20px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}

.sheet__error {
  margin: 0 20px 12px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger);
  font-size: 0.87rem;
}

.sheet label {
  display: block;
  margin-bottom: 6px;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--ink-2);
}

.sheet input[type="text"] {
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-0);
  font: inherit;
  color: var(--ink);
}

.sheet input[type="text"]:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-color: var(--blue-400);
}

.sheet__hint {
  margin: 6px 0 0;
  font-size: 0.81rem;
  color: var(--ink-3);
}

/* The agreement itself. Monospaced-adjacent, scrollable, and deliberately
   readable in full: nobody signs a document they were shown three lines of. */
.doc {
  max-height: 320px;
  overflow-y: auto;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--ink);
  white-space: pre-wrap;
}

.sheet__consent {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin-top: 14px;
  font-size: 0.88rem;
  color: var(--ink);
}

.sheet__consent input {
  margin-top: 3px;
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  accent-color: var(--blue-600);
}

.sheet__consent label {
  margin: 0;
  font-weight: 400;
}

/* ---------------------------------------------------------- empty state -- */

.chat__empty {
  display: grid;
  place-items: center;
  align-self: stretch;
  height: 100%;
  margin: auto 0;
  padding: 30px;
  text-align: center;
  color: var(--ink-3);
}

.chat__empty-inner {
  max-width: 380px;
}

.chat__empty h2 {
  margin: 0 0 8px;
  font-family: var(--font-serif);
  font-size: 1.2rem;
  color: var(--blue-900);
}

.chat__empty p {
  margin: 0 0 6px;
  font-size: 0.92rem;
}

/* The First Access lock banner on a pending thread: contact on this listing is
   still members-only, said before anybody writes a message. */
.chat__lock-note {
  margin-top: 14px;
  padding: 10px 14px;
  border: 1px solid var(--line, #d8ded9);
  border-radius: 10px;
  background: var(--paper-2, #f4f6f4);
  font-size: 0.88rem;
}
.chat__lock-note a {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
}

.chat__signin {
  display: grid;
  place-items: center;
  height: 100%;
  padding: 30px;
  text-align: center;
}

/* ---------------------------------------------------------------- mobile -- */

@media (max-width: 860px) {
  .chat {
    grid-template-columns: 1fr;
  }

  /* One pane at a time. data-view on the root decides which. */
  .chat[data-view="list"] .chat__thread,
  .chat[data-view="thread"] .chat__list {
    display: none;
  }

  .chat__list {
    border-right: 0;
  }

  .chat__back {
    display: flex;
  }

  .bub {
    max-width: 86%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .chat__send {
    transition: none;
  }

  .chat__scroll {
    scroll-behavior: auto;
  }
}
