/* ============================================================================
   Merrowfield — demonstration messaging service. FICTIONAL. Not a product.
   ============================================================================

   PIXEL REPRODUCIBILITY IS A REQUIREMENT OF THIS PAGE. It exists to be captured
   three ways and compared side by side: as served, after a DOM edit made in
   devtools, and after an image model has been asked to alter the words. If two
   loads of the same file can differ by a single pixel, the comparison stops
   meaning anything and the demonstration is worthless.

   Every rule below that looks over-specified is load-bearing. Before changing
   anything here, read these constraints:

     1. NO ANIMATION, NO TRANSITION. Anything that moves can be captured
        mid-state. The global guard at the bottom of this file enforces it;
        do not remove it, and do not add a keyframe expecting it to run.

     2. NO TIME-VARYING VALUES. Every timestamp on this page is a literal
        string in thread.json. Nothing calls Date.now() or
        new Date(). A relative time ("2 hours ago") changes between two loads
        minutes apart, which is precisely the failure this page cannot have.

     3. NO RANDOMNESS. No shuffling, no generated ids, no random avatar
        colours. Avatar colours come from a fixed lookup keyed on name.

     4. FIXED DIMENSIONS ON ANYTHING WHOSE SIZE FOLLOWS ITS CONTENT. Sidebar
        width, header height, avatar size, bubble max-width, row heights. A
        longer message must not move anything outside its own bubble, or an
        edit to one message shifts the whole page and every capture disagrees
        for a reason that has nothing to do with the edit.

     5. FONTS MUST BE LOADED BEFORE FIRST PAINT. Inter is self-hosted and
        preloaded, with font-display: block, so no capture can catch a
        fallback face. A fallback render is a different render.

     6. NO EXTERNAL REQUESTS. Every subresource is same-origin. A CDN that is
        slow, cached differently, or down produces a different page.

     7. NO ELLIPSIS THAT DEPENDS ON MEASUREMENT. Sidebar previews are
        pre-truncated in the data, not clipped by the browser, so subpixel
        text metrics cannot change where the truncation falls.

   ============================================================================ */

/* Inter 4.1, static instances at pinned weights. NOT the variable font: its
   metrics can shift between releases, which would silently desynchronise old
   captures from new ones. Version and SHA-256 of each file are recorded in
   README.md. */
@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: block;
}

:root {
  /* Warm earth palette, chosen so this cannot be mistaken for a real service.
     Slack owns aubergine, Telegram and Signal own blue, WhatsApp owns
     green-on-beige, iMessage owns blue-and-grey. None of them look like this,
     and neither does Shorenet's own navy and teal. */
  --ground: #F5F2ED;
  --sidebar: #2E2A26;
  --sidebar-hover: #3A342E;
  --header: #3A342E;
  --accent: #C4682B;
  --bubble-own: #E9DFD2;
  --bubble-them: #FFFFFF;
  --bubble-them-edge: #DED6CA;
  --ink: #2B2621;
  --ink-inverse: #F5F2ED;
  --muted: #8A8078;
  --muted-dark: #A79C91;
  --rule: #E2DACE;
  --demo: #D94F4F;

  /* Fixed metrics. Every one of these exists so that content length cannot
     move anything. */
  --sidebar-w: 320px;
  --header-h: 60px;
  --avatar: 38px;
  --avatar-sm: 34px;
  --bubble-max: 560px;
  --convo-row-h: 76px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  overflow: hidden; /* the app owns its own scrolling; the page never scrolls */
}

body {
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ===== Header ===== */
.appbar {
  height: var(--header-h);
  background: var(--header);
  color: var(--ink-inverse);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  flex: 0 0 auto;
}

.brand { display: flex; align-items: center; gap: 11px; }

.brand .mark {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: var(--accent);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 15px;
  flex: 0 0 auto;
}

.brand .name { font-size: 17px; font-weight: 600; letter-spacing: 0.2px; }

/* Deliberately conspicuous, and deliberately present in EVERY capture. This
   page is designed to be indistinguishable from a real messenger, so the badge
   is the one thing that stops a stray screenshot being mistaken for evidence —
   and it survives into the devtools-edited and AI-altered images, which a
   caption would not. Do not remove it, do not fade it, do not make it subtle. */
.demo-flag {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1px;
  background: var(--demo);
  color: #fff;
  padding: 3px 9px;
  border-radius: 4px;
  font-weight: 600;
  margin-left: 4px;
}

.signed-in { font-size: 13px; color: var(--muted-dark); }
.signed-in strong { color: var(--ink-inverse); font-weight: 500; }

/* ===== Shell ===== */
.shell {
  display: flex;
  height: calc(100% - var(--header-h));
}

/* ===== Sidebar ===== */
.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--sidebar);
  color: var(--ink-inverse);
  overflow-y: auto;
}

.sidebar-head {
  padding: 16px 18px 10px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--muted-dark);
  font-weight: 600;
}

.convo {
  height: var(--convo-row-h);
  padding: 0 18px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-left: 3px solid transparent;
  cursor: default;
}

.convo.selected {
  background: var(--sidebar-hover);
  border-left-color: var(--accent);
}

.convo .avatar { flex: 0 0 var(--avatar-sm); width: var(--avatar-sm); height: var(--avatar-sm); font-size: 12px; }

.convo-text { min-width: 0; flex: 1 1 auto; }

.convo-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.convo-name { font-size: 14px; font-weight: 500; }
.convo-date { font-size: 11px; color: var(--muted-dark); flex: 0 0 auto; }

/* Pre-truncated in the data, never clipped by the browser: text-overflow
   depends on measured width, so a font-metric change would move the ellipsis
   and two captures could differ on a character. */
.convo-preview {
  font-size: 12.5px;
  color: var(--muted-dark);
  white-space: nowrap;
  overflow: hidden;
  margin-top: 2px;
}

/* ===== Avatars: initials on a flat colour from a fixed lookup. No images, no
   gradients, no generated identicons. ===== */
.avatar {
  width: var(--avatar);
  height: var(--avatar);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  flex: 0 0 auto;
  letter-spacing: 0.3px;
}

/* ===== Thread ===== */
.main { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }

.thread-head {
  height: 64px;
  flex: 0 0 64px;
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 24px;
  background: #FBF9F6;
}

.thread-head .who { font-size: 15px; font-weight: 600; }
.thread-head .sub { font-size: 12.5px; color: var(--muted); }

.thread {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 22px 24px 28px;
}

.daybreak {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 4px 0 18px;
  font-size: 11.5px;
  color: var(--muted);
  font-weight: 500;
}
.daybreak::before, .daybreak::after {
  content: '';
  flex: 1 1 auto;
  height: 1px;
  background: var(--rule);
}
.msg + .daybreak { margin-top: 22px; }

.msg { display: flex; gap: 11px; margin-bottom: 14px; align-items: flex-end; }
.msg.own { flex-direction: row-reverse; }

.bubble {
  max-width: var(--bubble-max);
  padding: 9px 13px 8px;
  border-radius: 12px;
  background: var(--bubble-them);
  border: 1px solid var(--bubble-them-edge);
}

.msg.own .bubble {
  background: var(--bubble-own);
  border-color: var(--bubble-own);
}

.bubble .body { font-size: 14px; white-space: pre-wrap; }

.bubble .meta {
  margin-top: 4px;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums; /* digits must not change width */
}
.msg.own .bubble .meta { text-align: right; }

/* A disabled composer, shown rather than hidden: its absence would look like a
   cropped screenshot, and a working one would invite interaction that changes
   the render. */
.composer {
  flex: 0 0 auto;
  border-top: 1px solid var(--rule);
  padding: 14px 24px;
  background: #FBF9F6;
}
.composer .field {
  height: 42px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: #F2EEE8;
  color: var(--muted);
  display: flex;
  align-items: center;
  padding: 0 14px;
  font-size: 13.5px;
  user-select: none;
}

/* ===== Error state ===== */
.error {
  margin: 40px auto;
  max-width: 520px;
  border: 1px solid var(--bubble-them-edge);
  border-left: 3px solid var(--demo);
  background: #fff;
  padding: 20px 22px;
  border-radius: 8px;
}
.error h2 { font-size: 15px; font-weight: 600; margin-bottom: 6px; }
.error p { font-size: 13.5px; color: var(--muted); }

/* ============================================================================
   GLOBAL MOTION GUARD — constraint 1. Anything that moves can be captured
   mid-state, so nothing moves. This is deliberately unconditional and
   deliberately last, so it wins. Do not scope it, do not add exceptions.
   ============================================================================ */
*, *::before, *::after {
  animation: none !important;
  transition: none !important;
  scroll-behavior: auto !important;
}
