/* MESSAGES, the design system shared by all four concepts.
 *
 * THE RULE THIS FILE EXISTS TO KEEP: build ON the site, not beside it. Nothing
 * here redefines a token. Every colour, radius, easing and type step comes from
 * appts-shell.css, which is the verbatim extract of the home page, so a
 * messages page cannot drift from the client app. If you find yourself typing a
 * hex value into this file, stop and use the token.
 *
 * COLOUR DISCIPLINE, applied to a conversation:
 *   MAGENTA is the person. Their own messages, and the send button. It is the
 *     accent and the primary action everywhere else in this app, and in a
 *     conversation the thing you did is the action.
 *   The TEAM's messages are a plain raised card. They are the content, and
 *     content does not need a colour to be important. What is coloured is the
 *     small TYPE TAG, which is real data (service_messages.reply_type).
 *   TEAL means live or positive system state, so it marks "read" and "the
 *     inbox is open", never a person.
 *   GOLD is a soft warning: waiting, out of hours, nobody has replied yet.
 *   --system-error is reserved for the gate being shut and for nothing else.
 * The spectrum gradient is not used anywhere in this file. It belongs to Rivo.
 *
 * British English. No em dashes.
 */

/* =========================================================================
   THE THREAD
   ====================================================================== */

.tx-thread { display: flex; flex-direction: column; gap: 16px }

/* A date separator. Quiet: it is furniture, not information. */
.tx-daysep { display: flex; align-items: center; gap: 14px; margin: 12px 0 4px;
  font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase; font-weight: 700;
  color: var(--ink-3) }
.tx-daysep::before, .tx-daysep::after { content: ''; height: 1px; background: var(--hair); flex: 1 }

.tx-msg { display: flex; gap: 12px; max-width: 100%; align-items: flex-end }
.tx-msg.is-me { flex-direction: row-reverse }

/* The avatar carries initials, never a photograph we do not have. */
.tx-av { width: 36px; height: 36px; border-radius: 50%; flex: none; display: grid;
  place-items: center; font-family: var(--display); font-size: 12.5px; font-weight: 650;
  letter-spacing: .01em; background: var(--raise-2); color: var(--ink-2);
  border: 1px solid var(--hair) }
.tx-msg.is-me .tx-av { background: rgba(181,37,85,.16); color: var(--secondary-soft);
  border-color: rgba(181,37,85,.3) }
html[data-theme="light"] .tx-msg.is-me .tx-av { background: #FBE6EC; color: var(--secondary);
  border-color: rgba(181,37,85,.24) }
/* The avatar only appears on the FIRST message of a run, but the space it held
   is kept so the column of bubbles does not jog left and right. */
.tx-av.is-ghost { visibility: hidden }

.tx-bub { min-width: 0; max-width: min(640px, 76%); border-radius: var(--r-lg);
  padding: 14px 17px 12px; background: var(--raise); border: 1px solid var(--hair);
  border-bottom-left-radius: 8px }
.tx-msg.is-me .tx-bub { background: var(--secondary); border-color: transparent; color: #fff;
  border-bottom-left-radius: var(--r-lg); border-bottom-right-radius: 8px;
  box-shadow: 0 8px 22px rgba(181,37,85,.28) }
.tx-bub p { font-size: 15px; line-height: 1.52; margin: 0; overflow-wrap: anywhere }
.tx-msg.is-me .tx-bub p { color: #fff }

/* who wrote it and when. sender_staff_id is a real column, so the name is real
   data rather than a decoration; see the note in tx-data.js. */
.tx-who { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 6px }
.tx-who b { font-size: 13px; font-weight: 650; letter-spacing: -.005em }
.tx-who time { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums }
.tx-msg.is-me .tx-who time { color: rgba(255,255,255,.72) }

/* the foot of a bubble: read state, and nothing that pretends to be one */
.tx-foot { display: flex; align-items: center; gap: 7px; margin-top: 8px; font-size: 11.5px;
  color: var(--ink-3) }
.tx-msg.is-me .tx-foot { color: rgba(255,255,255,.78); justify-content: flex-end }
.tx-foot svg { width: 13px; height: 13px; flex: none }
.tx-foot.is-read { color: var(--teal-soft) }
html[data-theme="light"] .tx-foot.is-read { color: var(--teal) }
.tx-msg.is-me .tx-foot.is-read { color: rgba(255,255,255,.92) }

/* =========================================================================
   THE TYPE TAG
   The five values of service_messages.reply_type, and nothing else. Word AND
   colour, never colour alone, exactly as the risk rule in Nexus.
   ====================================================================== */

.tx-tag { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: 999px; font-size: 11px; font-weight: 650; letter-spacing: .02em;
  background: var(--raise-2); color: var(--ink-2); border: 1px solid var(--hair) }
.tx-tag i { width: 6px; height: 6px; border-radius: 50%; background: currentColor;
  font-style: normal; flex: none }
.tx-tag.t-appointment { background: rgba(0,119,200,.16); color: var(--cyan-soft);
  border-color: rgba(0,119,200,.3) }
.tx-tag.t-check_in    { background: rgba(0,164,153,.16); color: var(--teal-soft);
  border-color: rgba(0,164,153,.32) }
.tx-tag.t-signposting { background: rgba(185,138,47,.18); color: #E3C078;
  border-color: rgba(185,138,47,.34) }
.tx-tag.t-safety      { background: rgba(181,37,85,.18); color: var(--secondary-soft);
  border-color: rgba(181,37,85,.34) }
html[data-theme="light"] .tx-tag.t-appointment { background: #E4F0FB; color: var(--cyan); border-color: rgba(0,119,200,.22) }
html[data-theme="light"] .tx-tag.t-check_in    { background: #E4F8F2; color: #0B7A52; border-color: rgba(11,122,82,.22) }
html[data-theme="light"] .tx-tag.t-signposting { background: #FBEFD5; color: var(--amber); border-color: rgba(148,97,10,.24) }
html[data-theme="light"] .tx-tag.t-safety      { background: #FBE6EC; color: #A8385B; border-color: rgba(181,37,85,.22) }

/* ON THE PERSON'S OWN BUBBLE the tag sits on magenta, so the tone colours have
   nothing to work against: a magenta "Safety" pill on a magenta bubble is
   unreadable. It goes white on glass instead and keeps its WORD, because the
   word is what carries the meaning and the colour never was.
   BOTH selectors are written out deliberately. The light rules above are
   (0,3,1) and would beat a lone (0,2,0) rule here however far down the file it
   sat, which is exactly the kind of quiet cascade loss this project keeps
   re-learning. Escalating with !important would have hidden it rather than
   fixed it. */
.tx-msg.is-me .tx-tag,
html[data-theme="light"] .tx-msg.is-me .tx-tag {
  background: rgba(255,255,255,.2); color: #fff; border-color: rgba(255,255,255,.34) }

/* =========================================================================
   WAITING FOR A REPLY
   The state a messaging design is judged on and the one most of them skip.
   It is GOLD, a soft warning, because waiting is not an error and must never
   be dressed as one.
   ====================================================================== */

.tx-wait { display: flex; align-items: flex-start; gap: 12px; padding: 15px 18px;
  border-radius: var(--r-lg); background: rgba(185,138,47,.1);
  border: 1px solid rgba(185,138,47,.28) }
html[data-theme="light"] .tx-wait { background: #FBEFD5; border-color: rgba(148,97,10,.24) }
.tx-wait .ic { width: 34px; height: 34px; border-radius: 10px; flex: none; display: grid;
  place-items: center; background: rgba(185,138,47,.2); color: #E3C078 }
html[data-theme="light"] .tx-wait .ic { background: rgba(148,97,10,.14); color: var(--amber) }
.tx-wait .ic svg { width: 17px; height: 17px }
.tx-wait b { display: block; font-size: 14px; font-weight: 650; margin-bottom: 3px }
.tx-wait span { display: block; font-size: 13px; line-height: 1.5; color: var(--ink-2) }

/* =========================================================================
   THE COMPOSER
   ====================================================================== */

.tx-comp { border-radius: var(--r-lg); background: var(--raise); border: 1px solid var(--hair);
  padding: 14px; transition: border-color .18s var(--ease) }
.tx-comp:focus-within { border-color: var(--secondary) }
.tx-comp textarea { width: 100%; min-height: 78px; max-height: 260px; resize: none;
  background: none; border: none; outline: none; font: inherit; font-size: 15px;
  line-height: 1.55; color: var(--ink); padding: 4px 6px }
.tx-comp textarea::placeholder { color: var(--ink-3) }
.tx-comp-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin-top: 10px; padding-top: 11px; border-top: 1px solid var(--hair); flex-wrap: wrap }
.tx-count { font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums }
.tx-count.is-over { color: var(--secondary-soft); font-weight: 650 }
.tx-comp-hint { font-size: 12.5px; color: var(--ink-3); line-height: 1.45 }
/* A refusal, reported in the box the words came from. --system-error is used
   here and in the shut gate, and nowhere else. */
.tx-comp-err { margin: 8px 6px 0; padding: 10px 12px; border-radius: var(--r-sm);
  background: rgba(180,35,24,.12); border: 1px solid rgba(180,35,24,.32);
  font-size: 13px; line-height: 1.5; color: var(--ink) }
html[data-theme="light"] .tx-comp-err { background: #FBE6EC;
  border-color: rgba(180,35,24,.22); color: #7A1B12 }

.tx-comp[aria-disabled="true"] { opacity: .55 }
.tx-comp[aria-disabled="true"] textarea { cursor: not-allowed }

/* =========================================================================
   THE GATE
   What this page says when the service has switched messaging off. Not a
   toast, not a disabled button with no explanation: a panel that says what is
   true, and what to do instead. --system-error is used here and nowhere else
   in this file.
   ====================================================================== */

.tx-gate { display: flex; gap: 16px; padding: 20px 22px; border-radius: var(--r-lg);
  background: var(--raise); border: 1px solid var(--hair) }
.tx-gate.is-shut { background: rgba(180,35,24,.09); border-color: rgba(180,35,24,.3) }
html[data-theme="light"] .tx-gate.is-shut { background: #FBE6EC; border-color: rgba(180,35,24,.22) }
.tx-gate .ic { width: 42px; height: 42px; border-radius: 12px; flex: none; display: grid;
  place-items: center; background: var(--raise-2); color: var(--ink-2) }
.tx-gate.is-shut .ic { background: rgba(180,35,24,.18); color: #FFC9C4 }
html[data-theme="light"] .tx-gate.is-shut .ic { background: rgba(180,35,24,.1); color: var(--system-error) }
.tx-gate .ic svg { width: 20px; height: 20px }
.tx-gate .tt { min-width: 0 }
.tx-gate .tt b { display: block; font-family: var(--display); font-size: 17px; font-weight: 650;
  letter-spacing: -.015em; margin-bottom: 6px }
.tx-gate .tt p { font-size: 14px; line-height: 1.55; color: var(--ink-2); margin: 0 0 4px }
.tx-gate .tt p + p { margin-top: 8px }
.tx-gate-acts { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px }

/* =========================================================================
   THE TEAM
   ====================================================================== */

.tx-person { display: flex; align-items: center; gap: 14px; padding: 15px 17px;
  border-radius: var(--r-lg); background: var(--raise); border: 1px solid var(--hair) }
.tx-person .tx-av { width: 46px; height: 46px; font-size: 15px }
.tx-person .tt { min-width: 0; flex: 1 }
.tx-person .tt b { display: block; font-family: var(--display); font-size: 16px; font-weight: 650;
  letter-spacing: -.015em }
.tx-person .tt span { display: block; font-size: 13px; color: var(--ink-3); margin-top: 3px;
  line-height: 1.45 }
.tx-person.is-lead { background: var(--raise-2); border-color: var(--hair-2) }
.tx-person.is-lead .tx-av { background: rgba(0,164,153,.18); color: var(--teal-soft);
  border-color: rgba(0,164,153,.34) }
html[data-theme="light"] .tx-person.is-lead .tx-av { background: #E4F8F2; color: #0B7A52;
  border-color: rgba(11,122,82,.22) }

/* the open/closed light. TEAL because it is live system state. */
.tx-open { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px;
  font-weight: 600; color: var(--ink-2) }
.tx-open i { width: 8px; height: 8px; border-radius: 50%; background: var(--teal);
  font-style: normal; flex: none; box-shadow: 0 0 0 3px rgba(0,164,153,.2) }
.tx-open.is-shut i { background: var(--gold); box-shadow: 0 0 0 3px rgba(185,138,47,.2) }

/* =========================================================================
   SHARED FURNITURE
   ====================================================================== */

.tx-hero-glass { background: var(--hero-glass); border: 1px solid var(--hero-hair);
  border-radius: var(--r-lg); padding: 22px 24px; backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur); min-width: 320px; max-width: 384px;
  box-shadow: inset 0 1px 0 var(--glass-hi), 0 14px 34px rgba(0,0,0,.3) }
@media (max-width: 940px) { .tx-hero-glass { min-width: 0; max-width: none } }
.tx-hero-glass .lbl { display: block; font-size: 11.5px; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 700; color: rgba(255,255,255,.7); margin-bottom: 12px }
.tx-hero-glass h3 { font-family: var(--display); font-size: 20px; font-weight: 650;
  letter-spacing: -.025em; color: #fff; margin-bottom: 8px; line-height: 1.24 }
.tx-hero-glass p { font-size: 13.5px; line-height: 1.55; color: rgba(255,255,255,.78); margin: 0 }
.tx-hero-glass .row { display: flex; align-items: center; gap: 11px; margin-top: 14px;
  padding-top: 14px; border-top: 1px solid rgba(255,255,255,.16) }
.tx-hero-glass .row .tx-av { background: rgba(255,255,255,.16); color: #fff;
  border-color: rgba(255,255,255,.24) }
.tx-hero-glass .row b { display: block; font-size: 14px; font-weight: 600; color: #fff }
.tx-hero-glass .row span { display: block; font-size: 12px; color: rgba(255,255,255,.7);
  margin-top: 2px }

.tx-card { border-radius: var(--r-lg); background: var(--raise); border: 1px solid var(--hair);
  padding: 22px 24px }
.tx-card > h3 { font-family: var(--display); font-size: 17px; font-weight: 650;
  letter-spacing: -.015em; margin-bottom: 6px }
.tx-card > p { font-size: 14px; line-height: 1.55; color: var(--ink-2) }

/* the standing two-column workspace: the conversation, and whatever the
   concept believes belongs beside it */
.tx-grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, .85fr);
  gap: var(--gutter); align-items: start }
@media (max-width: 1040px) { .tx-grid { grid-template-columns: minmax(0, 1fr) } }
.tx-side { display: flex; flex-direction: column; gap: 16px }

/* A scrolling thread panel. minmax(0,1fr) everywhere a track could refuse to
   shrink: a 1fr track will not go below the min-content width of a nowrap
   label, which is how a column ends up off screen. */
.tx-panel { border-radius: var(--r-xl); background: var(--raise); border: 1px solid var(--hair);
  overflow: hidden; display: grid; grid-template-rows: auto minmax(0, 1fr) auto }
.tx-panel-head { display: flex; align-items: center; gap: 14px; padding: 18px 22px;
  border-bottom: 1px solid var(--hair); background: var(--raise-2); flex-wrap: wrap }
.tx-panel-head .tt { min-width: 0; flex: 1 }
.tx-panel-head .tt b { display: block; font-family: var(--display); font-size: 17px;
  font-weight: 650; letter-spacing: -.018em }
.tx-panel-head .tt span { display: block; font-size: 12.5px; color: var(--ink-3); margin-top: 3px }
.tx-panel-body { overflow-y: auto; padding: 22px; min-height: 0 }
.tx-panel-foot { padding: 16px 22px 20px; border-top: 1px solid var(--hair) }

/* a quiet inline link. No underline in any state, ever, including hover. */
.tx-link { color: var(--secondary-soft); font-weight: 600; text-decoration: none;
  transition: opacity .16s var(--ease) }
html[data-theme="light"] .tx-link { color: var(--secondary) }
.tx-link:hover, .tx-link:focus { text-decoration: none; opacity: .7 }

/* =========================================================================
   MOTION
   Content must never depend on an animation to be seen. The resting style is
   visible and the hidden state lives in the `from` keyframe, so a page where
   the animation never runs still shows every message.
   ====================================================================== */

@keyframes tx-rise { from { opacity: 0; transform: translateY(10px) } }
.tx-msg { animation: tx-rise .34s var(--ease) both }
@media (prefers-reduced-motion: reduce) {
  .tx-msg { animation: none }
  .tx-comp, .tx-gate, .tx-person { transition: none }
}
