/* ============================================================================
   Ticket detail screen.

   Two columns: the conversation reads left-to-right at a comfortable measure,
   the properties rail stays put on the right. Below 1080px the rail drops
   under the conversation rather than squeezing it.
   ========================================================================== */

.tms-detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 18px;
  align-items: start;
}
@media (max-width: 1080px) { .tms-detail { grid-template-columns: 1fr; } }

/* --- header ------------------------------------------------------------ */
.tms-t-head { margin-bottom: 16px; }
.tms-t-head .tms-t-badges { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; flex-wrap: wrap; }
.tms-t-head h1 {
  font-size: 21px; font-weight: 650; letter-spacing: -.024em; line-height: 1.28;
  margin: 0; text-wrap: balance; max-width: 56ch;
}
.tms-t-head .tms-t-sub {
  margin: 9px 0 0; font-size: var(--tms-fs-cap); color: var(--tms-text-3);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.tms-t-head .tms-t-sub .sl { opacity: .5; }

/* --- description ------------------------------------------------------- */
.tms-t-desc { font-size: var(--tms-fs-body); line-height: 1.66; color: var(--tms-text); overflow-wrap: anywhere; }
.tms-t-desc p { margin: 0 0 11px; }
.tms-t-desc p:last-child { margin-bottom: 0; }
.tms-t-desc ul, .tms-t-desc ol { margin: 0 0 11px; padding-left: 19px; }
.tms-t-desc li { margin-bottom: 4px; }
.tms-t-desc img { max-width: 100%; height: auto; border-radius: var(--tms-r); }
.tms-t-desc pre {
  overflow-x: auto; background: var(--tms-surface-2); border: 1px solid var(--tms-border);
  border-radius: var(--tms-r); padding: 10px 12px; font-family: var(--tms-font-mono); font-size: var(--tms-fs-cap);
}
.tms-t-desc code {
  font-family: var(--tms-font-mono); font-size: var(--tms-fs-cap);
  background: var(--tms-surface-2); border: 1px solid var(--tms-border);
  border-radius: var(--tms-r-sm); padding: 1px 5px;
}
.tms-t-desc pre code { background: none; border: none; padding: 0; }

.tms-t-attach {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--tms-border);
}

/* --- conversation ------------------------------------------------------ */
.tms-thread { margin-top: 20px; }
.tms-thread-h { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.tms-thread-h h2 {
  font-size: var(--tms-fs-data); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--tms-text-2); margin: 0;
}
.tms-thread-h .tms-line { flex: 1; height: 1px; background: var(--tms-border); }

.tms-msg { display: flex; gap: 11px; margin-bottom: 14px; }
.tms-msg-body {
  flex: 1; min-width: 0; background: var(--tms-surface);
  border: 1px solid var(--tms-border); border-radius: var(--tms-r-lg);
  padding: 12px 14px; box-shadow: var(--tms-shadow-1);
}
/* An internal note is amber all the way through — nobody should mistake one
   for a client-visible reply. */
.tms-msg.is-internal .tms-msg-body { background: var(--tms-warn-tint); border-color: var(--tms-warn-line); }

.tms-msg-h { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.tms-msg-h .tms-msg-who { font-size: var(--tms-fs-data); font-weight: 650; }
.tms-msg-h .tms-msg-when {
  font-size: 11.5px; color: var(--tms-text-3);
  font-variant-numeric: tabular-nums; margin-left: auto;
}
.tms-msg-c { font-size: 13.5px; line-height: 1.62; color: var(--tms-text); overflow-wrap: anywhere; }
.tms-msg-c p { margin: 0 0 8px; }
.tms-msg-c p:last-child { margin: 0; }

/* --------------------------------------------------------------------------
   Embedded media in stored comment / description HTML.

   Both bodies render HTML authored elsewhere — pasted screenshots carry their
   own intrinsic width, and a 2000px screenshot pasted into a comment used to
   push straight through the card and under the sidebar. The description block
   already capped images; the comment body did not, which is where it showed.

   Everything that can carry its own width is capped here, not just <img>:
   tables and <pre> from pasted content overflow the same way.
   -------------------------------------------------------------------------- */
.tms-msg-c img, .tms-t-desc img,
.tms-msg-c video, .tms-t-desc video {
  max-width: 100%;
  height: auto;                    /* keeps aspect ratio when width is clamped */
  border-radius: var(--tms-r);
}

/* <pre> scrolls itself instead of widening the card. */
.tms-msg-c pre, .tms-t-desc pre {
  max-width: 100%;
  overflow-x: auto;
}

/* Tables cannot scroll without a wrapper element, and the HTML here is stored, so there
   is nothing to add one to. display:block drops the table out of table layout; its
   table-row children then generate an anonymous table that shrinks to the available
   width, so a wide table compresses and wraps rather than escaping the card. Columns get
   narrow, but the alternative is the card blowing out under the sidebar. overflow-x
   still catches a single unbreakable cell. */
.tms-msg-c table, .tms-t-desc table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}

.tms-msg-c iframe, .tms-t-desc iframe { max-width: 100%; }
.tms-msg-att { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }

/* system events sit between messages as a quiet line, not a card */
.tms-event {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 0 5px 34px; font-size: var(--tms-fs-cap);
  color: var(--tms-text-3); margin-bottom: 8px;
}
.tms-event .tms-event-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--tms-border-strong); flex: none; margin-left: -19px;
}
.tms-event b { color: var(--tms-text-2); font-weight: 600; }

/* --- composer ---------------------------------------------------------- */
.tms-composer {
  background: var(--tms-surface); border: 1px solid var(--tms-border-strong);
  border-radius: var(--tms-r-lg); box-shadow: var(--tms-shadow-1);
  overflow: hidden; margin-top: 6px;
}
.tms-composer.is-internal { border-color: var(--tms-warn-line); }
.tms-comp-tabs { display: flex; gap: 1px; padding: 8px 10px 0; border-bottom: 1px solid var(--tms-border); }
.tms-comp-tabs button {
  padding: 7px 13px; font-size: var(--tms-fs-data); font-weight: 600; color: var(--tms-text-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color var(--tms-fast), border-color var(--tms-fast);
}
.tms-comp-tabs button:hover { color: var(--tms-text); }
.tms-comp-tabs button[aria-selected="true"] { color: var(--tms-accent); border-bottom-color: var(--tms-accent); }
.tms-composer.is-internal .tms-comp-tabs button[aria-selected="true"] {
  color: var(--tms-warn); border-bottom-color: var(--tms-warn);
}
.tms-composer .tms-editor { border: none; border-radius: 0; }
.tms-comp-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; border-top: 1px solid var(--tms-border); flex-wrap: wrap;
}
.tms-comp-foot .tms-right { margin-left: auto; display: flex; gap: 8px; align-items: center; }
.tms-comp-note {
  font-size: var(--tms-fs-cap); color: var(--tms-warn);
  display: inline-flex; align-items: center; gap: 5px; font-weight: 600;
}
.tms-comp-drop { padding: 0 12px 10px; display: none; }
.tms-comp-drop.is-shown { display: block; }

/* --- properties rail --------------------------------------------------- */
.tms-props {
  background: var(--tms-surface); border: 1px solid var(--tms-border);
  border-radius: var(--tms-r-lg); box-shadow: var(--tms-shadow-1);

  /* NOT overflow:hidden. The assignee picker's dropdown is pinned to the viewport, and
     a clipping ancestor swallowed it on a phone — the control was there and the list it
     opened was not. The radius is applied to the first and last rows instead. */
  overflow: visible;
}
.tms-props > :first-child { border-radius: var(--tms-r-lg) var(--tms-r-lg) 0 0; }
.tms-props > :last-child { border-radius: 0 0 var(--tms-r-lg) var(--tms-r-lg); }

/* Sticky only where there is a column for it to stick in — scoped by min-width so a
   later rule cannot quietly reinstate it once stacked. */
@media (min-width: 1081px) {
  .tms-props {
    position: sticky; top: calc(var(--tms-topbar-h) + 16px);

    /* Its own scroll, capped to the viewport. A sticky panel taller than the screen
       cannot be scrolled at all — the page scrolls the thread, the panel just sits
       there with its bottom cut off, which is where Close ticket lives. */
    max-height: calc(100vh - var(--tms-topbar-h) - 32px);
    overflow-y: auto;

    /* Scrollbar hidden on both engines: this is a narrow side panel and a visible bar
       eats its width and doubles the chrome next to the page's own bar. Wheel, trackpad
       and touch still scroll it; the dropdowns inside are viewport-pinned so nothing is
       clipped by the overflow. */
    scrollbar-width: none;

    /* Wheel-over-panel stays in the panel. Without this, hitting the panel's end hands
       the leftover scroll to the page, the page moves, the sync fires, and the position
       the user just set by hand gets yanked back — scrolling the panel deliberately felt
       like fighting it. */
    overscroll-behavior: contain;
  }
  .tms-props::-webkit-scrollbar { width: 0; height: 0; }
}

.tms-prop { padding: 11px 14px; border-bottom: 1px solid var(--tms-border); }
.tms-prop:last-child { border-bottom: none; }
.tms-prop > .tms-prop-l {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--tms-text-3); margin-bottom: 6px; display: block;
}
.tms-prop .tms-prop-v {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--tms-fs-data); font-weight: 550; flex-wrap: wrap;
}
/* One control height for the whole rail.
   Left alone, four kinds of control land on three different heights: .tms-input is
   40px, .tms-select-control was overridden to 32 here, .tms-btn-sm is 29, and
   .tms-segment button has no height at all (its size falls out of padding). Stacked in
   a narrow column the mismatch reads as broken alignment. 34px keeps the rail dense
   while staying a comfortable target. */
.tms-props { --tms-h-prop: 34px; }

.tms-prop .tms-input,
.tms-prop .tms-btn { height: var(--tms-h-prop); }

.tms-prop .tms-select-control {
  min-height: var(--tms-h-prop);
  padding-top: 3px; padding-bottom: 3px;
}

/* min-height, not height: the type picker wraps to two or three rows in a narrow rail
   and a fixed height would crop it. Buttons stretch to fill whichever row they land in. */
.tms-prop .tms-segment { min-height: var(--tms-h-prop); align-items: stretch; }

/* Vertical padding has to go, or the buttons' own content height (padding + line-height)
   exceeds the min-height and the group renders 2px taller than everything else. With it
   removed they stretch to the row instead of defining it. */
.tms-prop .tms-segment button { height: auto; padding-top: 0; padding-bottom: 0; }

.tms-prop .tms-tagrow { display: flex; flex-wrap: wrap; gap: 5px; }

/* deadline block — the one thing people check first, so it leads the rail */
.tms-deadline { padding: 12px 14px; border-bottom: 1px solid var(--tms-border); }
.tms-deadline .tms-dl-l {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
}
.tms-deadline .tms-dl-v {
  font-family: var(--tms-font-mono); font-size: 17px; font-weight: 600;
  margin-top: 3px; font-variant-numeric: tabular-nums;
}
.tms-deadline .tms-dl-m { font-size: 11.5px; opacity: .85; margin-top: 2px; }
.tms-deadline.is-ok      { background: var(--tms-surface-2); }
.tms-deadline.is-ok      .tms-dl-l, .tms-deadline.is-ok .tms-dl-v, .tms-deadline.is-ok .tms-dl-m { color: var(--tms-text-2); }
.tms-deadline.is-soon    { background: var(--tms-warn-tint);   border-bottom-color: var(--tms-warn-line); }
.tms-deadline.is-soon    .tms-dl-l, .tms-deadline.is-soon .tms-dl-v, .tms-deadline.is-soon .tms-dl-m { color: var(--tms-warn); }
.tms-deadline.is-overdue { background: var(--tms-danger-tint); border-bottom-color: var(--tms-danger-line); }
.tms-deadline.is-overdue .tms-dl-l, .tms-deadline.is-overdue .tms-dl-v, .tms-deadline.is-overdue .tms-dl-m { color: var(--tms-danger); }

/* --- read-only / closed state ------------------------------------------ */
.tms-closed-banner {
  display: flex; align-items: center; gap: 9px; padding: 11px 15px; margin-bottom: 16px;
  background: var(--tms-ok-tint); border: 1px solid var(--tms-ok-line);
  border-radius: var(--tms-r-lg); color: var(--tms-ok);
  font-size: var(--tms-fs-data); font-weight: 600;
}

/* --- skeleton ---------------------------------------------------------- */
.tms-skel { background: var(--tms-surface-2); border-radius: var(--tms-r-sm); animation: tms-skel 1.3s ease-in-out infinite; }
.tms-skel-line { height: 12px; margin-bottom: 9px; }
@keyframes tms-skel { 50% { opacity: .5; } }

/* ============================================================================
   TICKET HISTORY — grouped timeline

   The old modal printed ActionDescription verbatim, so every row repeated the
   ticket number and title and status changes looked exactly like comments.
   Here the boilerplate is parsed off, the timestamp is time-only under a date
   heading, and a transition renders as two chips.
   ========================================================================== */
.tms-hist-filters {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding-bottom: 10px; margin-bottom: 2px;
  border-bottom: 1px solid var(--tms-border);
}
.tms-f {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--tms-fs-cap); padding: 3px 10px; border-radius: 999px;
  background: var(--tms-surface-2); border: 1px solid var(--tms-border);
  color: var(--tms-text-2); transition: background-color var(--tms-fast), color var(--tms-fast);
}
.tms-f:hover { color: var(--tms-text); }
.tms-f.is-on {
  background: var(--tms-accent-tint); border-color: var(--tms-accent-line);
  color: var(--tms-accent-dark);
}
.tms-f-n { font-family: var(--tms-font-mono); font-size: var(--tms-fs-micro); opacity: .8; }

.tms-hist-day { display: flex; align-items: center; gap: 9px; margin: 14px 0 4px; }
.tms-hist-day b {
  font-size: var(--tms-fs-micro); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--tms-text-3);
}
.tms-hist-day i { flex: 1; height: 1px; background: var(--tms-border); display: block; }

.tms-hist-ev {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 6px 0; font-size: var(--tms-fs-data); line-height: 1.55;
}
.tms-hist-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; margin-top: 7px; }
.tms-hist-st { background: var(--tms-info); }
.tms-hist-cm { background: var(--tms-border-strong); }
.tms-hist-as { background: var(--tms-progress); }
.tms-hist-ty { background: var(--tms-ok); }
.tms-hist-cr { background: var(--tms-accent); }
.tms-hist-dl { background: var(--tms-warn); }
.tms-hist-ot { background: var(--tms-border-strong); }

.tms-hist-b { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* The actor / verb / chips sit on a flex row with a real gap. Spacing them with the
   whitespace between elements does not survive Razor, which strips it. */
.tms-hist-line {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 5px;
}
.tms-hist-who { font-weight: 650; color: var(--tms-text); }
.tms-hist-sys { font-weight: 650; color: var(--tms-text-3); font-style: italic; }
.tms-hist-note { font-size: var(--tms-fs-cap); }

.tms-hist-chip {
  display: inline-block; font-size: var(--tms-fs-micro); padding: 1px 7px;
  border-radius: var(--tms-r-sm); background: var(--tms-surface-3);
  color: var(--tms-text-2); font-family: var(--tms-font-mono); white-space: nowrap;
}
.tms-hist-chip.is-to {
  background: var(--tms-info-tint); color: var(--tms-info); border: 1px solid var(--tms-info-line);
}

/* Two lines by default. One long comment otherwise occupies as much height as six
   status changes, which buries the status trail people open this modal to read. */
.tms-hist-q {
  color: var(--tms-text-2); margin-top: 3px; cursor: pointer;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tms-hist-q.is-open { display: block; }

/* Time only — the date is in the heading. Fixed width stops the ragged wrap the
   old modal had, where "15 Jul 2026, 15:22" broke across three lines. */
.tms-hist-t {
  flex: none; font-family: var(--tms-font-mono); font-size: var(--tms-fs-micro);
  color: var(--tms-text-3); white-space: nowrap; margin-top: 3px;
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   TICKET TRAIL — time spent per status

   The journey bar carries the sequence, the totals list carries the answer to
   "which status is eating the time". The old chart drew one row per visit and
   encoded each duration twice, as bar length and as a chip.
   ========================================================================== */
.tms-trail-now {
  display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
  font-size: var(--tms-fs-data); margin-bottom: 10px;
}
.tms-trail-now b { font-size: var(--tms-fs-sub); font-weight: 650; }
.tms-trail-sw { width: 10px; height: 10px; border-radius: 2px; align-self: center; flex: none; }
.tms-trail-el {
  margin-left: auto; font-family: var(--tms-font-mono);
  font-size: var(--tms-fs-cap); color: var(--tms-text-3); white-space: nowrap;
}

.tms-trail-bar {
  display: flex; height: 26px; border-radius: var(--tms-r);
  overflow: hidden; background: var(--tms-surface-3);
}
.tms-trail-bar i { display: block; height: 100%; min-width: 2px; }
/* A hairline between segments so two adjacent visits to different statuses read
   as two blocks even when their colours are close. */
.tms-trail-bar i + i { box-shadow: inset 1px 0 0 var(--tms-surface); }

.tms-trail-axis {
  display: flex; justify-content: space-between;
  font-size: var(--tms-fs-micro); color: var(--tms-text-3);
  font-family: var(--tms-font-mono); margin: 5px 0 14px;
}

.tms-trail-totals { display: flex; flex-direction: column; gap: 5px; }
.tms-trail-row {
  display: grid; grid-template-columns: minmax(0, 130px) 32px minmax(0, 1fr) 66px;
  gap: 9px; align-items: center; font-size: var(--tms-fs-data);
}
.tms-trail-nm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tms-trail-ct {
  font-family: var(--tms-font-mono); font-size: var(--tms-fs-micro);
  color: var(--tms-text-3); text-align: right;
}
.tms-trail-tr { background: var(--tms-surface-3); height: 7px; border-radius: 999px; overflow: hidden; }
.tms-trail-tr i { display: block; height: 100%; border-radius: 999px; }
.tms-trail-dv {
  font-family: var(--tms-font-mono); font-size: var(--tms-fs-cap);
  color: var(--tms-text-2); text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 560px) {
  .tms-trail-row { grid-template-columns: minmax(0, 1fr) 28px 58px; }
  .tms-trail-tr { display: none; }
}

/* --- trail: section headings, per-person bars, legend --------------------- */
.tms-trail-hd {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: var(--tms-fs-micro); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--tms-text-3);
  margin: 16px 0 7px;
}
.tms-trail-hint {
  font-size: var(--tms-fs-cap); font-weight: 400; letter-spacing: 0;
  text-transform: none; color: var(--tms-text-3); font-style: italic;
}
.tms-trail-sys { color: var(--tms-text-3); font-style: italic; }

/* The per-person track holds several status-coloured pieces rather than one fill,
   so it is a flex row; a hairline keeps adjacent pieces distinct. */
.tms-trail-tr { display: flex; }
.tms-trail-tr i + i { box-shadow: inset 1px 0 0 var(--tms-surface); }

.tms-trail-leg {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-top: 14px; padding-top: 11px; border-top: 1px solid var(--tms-border);
  font-size: var(--tms-fs-cap); color: var(--tms-text-2);
}
.tms-trail-leg span { display: inline-flex; align-items: center; gap: 5px; }
.tms-trail-sw { width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none; }

/* --- trail: swimlanes ---------------------------------------------------- */
.tms-trail-lanes { display: flex; flex-direction: column; gap: 4px; }
.tms-trail-lane {
  display: grid; grid-template-columns: minmax(0, 132px) minmax(0, 1fr);
  gap: 9px; align-items: center; font-size: var(--tms-fs-data);
}
/* The track is a positioning context: a lane is mostly empty, so its blocks are
   placed at their real point on the shared timeline rather than packed left. */
.tms-trail-track {
  position: relative; height: 16px;
  background: var(--tms-surface-2); border-radius: var(--tms-r-sm); overflow: hidden;
}
.tms-trail-track i {
  position: absolute; top: 0; height: 100%;
  min-width: 2px;                 /* a seconds-long hold must not vanish */
  border-radius: 2px;
}

@media (max-width: 560px) {
  .tms-trail-lane { grid-template-columns: minmax(0, 92px) minmax(0, 1fr); }
}

/* --- organisation eyebrow ------------------------------------------------ */
.tms-t-org {
  margin: 0 0 7px; font-size: var(--tms-fs-cap); color: var(--tms-text-3);
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
}
.tms-t-orgname {
  font-weight: 650; color: var(--tms-accent-dark);
  letter-spacing: .02em;
}
.tms-t-org .sl { opacity: .5; }

/* --- condensed sticky header --------------------------------------------- */
/* Zero-height marker; the observer watches this leave the viewport. */
.tms-t-sentinel { height: 0; }

.tms-t-stuck {
  /* FIXED, not sticky — this strip must take no space in the document.

     It appears when a zero-height sentinel above the header scrolls out of view. As a
     sticky (in-flow) element, appearing ADDED its own height to the page, which pushed
     the sentinel back into view, which removed the strip, which pulled the sentinel out
     again — an intersection-observer feedback loop that blinked the whole page for as
     long as the scroll position sat near the boundary. An overlay cannot feed back. */
  position: fixed;
  top: var(--tms-topbar-h);
  left: calc(var(--tms-rail-w) + 20px);
  right: 20px;
  z-index: 40;
  display: flex; align-items: center; gap: 9px;
  margin: 0; padding: 7px 12px;
  background: var(--tms-surface); border: 1px solid var(--tms-border);
  border-radius: 0 0 var(--tms-r) var(--tms-r); box-shadow: var(--tms-shadow-2);

  /* Hidden until the real header goes. visibility rather than display:none so the
     transition has something to animate, and height 0 so it claims no space while hidden. */
  visibility: hidden; opacity: 0; height: 0; padding-top: 0; padding-bottom: 0;
  border-width: 0; overflow: hidden;
  transition: opacity var(--tms-fast) var(--tms-ease);
}
.tms-t-stuck.is-shown {
  visibility: visible; opacity: 1; height: auto;
  padding-top: 7px; padding-bottom: 7px; border-width: 1px;
}

.tms-t-stuck-id { color: var(--tms-text-3); flex: none; }
.tms-t-stuck-t {
  flex: 1; min-width: 0; font-size: var(--tms-fs-data);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tms-t-stuck-t b { font-weight: 650; }
.tms-t-stuck-t .sl { color: var(--tms-text-3); }

/* Back link inside the condensed header. The label collapses on narrow screens so the
   ticket title keeps the space; the arrow alone still reads as "back". */
.tms-t-stuck-back { flex: none; padding-left: 6px; padding-right: 8px; }
@media (max-width: 720px) {
  .tms-t-stuck-backtext { display: none; }
}

/* The customer's own words about what they thought the ticket was, shown under the
   verdict. Quiet on purpose — it is context for the person classifying, not a field. */
.tms-prop .tms-claim {
  margin-top: 6px; padding-top: 6px;
  border-top: 1px dashed var(--tms-border);
  color: var(--tms-text-3);
}
.tms-prop .tms-claim b { color: var(--tms-text-2); font-weight: 600; }

/* --- pasted content in dark theme -----------------------------------------
   Ticket bodies and comments are authored elsewhere — Outlook, Word, the old
   portal — and arrive carrying inline colours: color:#000, color:black, dark
   greys, plus Word's highlight backgrounds. On the light theme that is
   invisible and harmless. On dark it renders black text on a near-black card,
   so whole paragraphs disappear; ticket 15874 had two bullets that simply were
   not there.

   Inline styles can only be beaten with !important, and the override is scoped
   to dark theme and to authored content only, so nothing the design system
   styles is affected. Colour is discarded rather than remapped because these
   values are Word artefacts, not meaning — nobody chose them.

   Backgrounds are neutralised for the same reason: a Word highlight is a pale
   yellow that swallows light text. Genuine emphasis still survives through
   bold, italic and headings, which carry no colour of their own. --------- */

:root[data-theme="dark"] .tms-t-desc [style*="color"],
:root[data-theme="dark"] .tms-msg-c [style*="color"],
:root[data-theme="dark"] .tms-t-desc font[color],
:root[data-theme="dark"] .tms-msg-c font[color] {
  color: var(--tms-text) !important;
}

:root[data-theme="dark"] .tms-t-desc [style*="background"],
:root[data-theme="dark"] .tms-msg-c [style*="background"] {
  background-color: transparent !important;
}

/* Links keep their own colour - that IS meaning, and the token is readable on
   both themes. */
:root[data-theme="dark"] .tms-t-desc a[style*="color"],
:root[data-theme="dark"] .tms-msg-c a[style*="color"] {
  color: var(--tms-accent-dark) !important;
}

/* Pasted tables arrive with white cell fills and hairline borders that vanish. */
:root[data-theme="dark"] .tms-t-desc table,
:root[data-theme="dark"] .tms-msg-c table,
:root[data-theme="dark"] .tms-t-desc td,
:root[data-theme="dark"] .tms-msg-c td,
:root[data-theme="dark"] .tms-t-desc th,
:root[data-theme="dark"] .tms-msg-c th {
  background-color: transparent !important;
  border-color: var(--tms-border) !important;
  color: var(--tms-text) !important;
}

/* ============================================================================
   PHONE — Phase 3: detail and forms stack in a usable order
   ========================================================================== */

/* The toggle exists only on a phone. On a desktop the panel is simply open. */
.tms-props-toggle { display: none; }

@media (max-width: 720px) {

  /* ---- ticket detail ---- */
  .tms-detail { gap: 10px; }

  /* Left in document order, which puts them BELOW the conversation.
     They were pulled above it on the reasoning that Status and Close ticket should not
     sit behind a long thread. In practice that pushed the ticket itself — the subject,
     the description, the replies — off the first screen, and the thing you open a ticket
     to do is read it. The panel stays where it reads naturally; the toggle folds it away
     when it is in the way. */

  .tms-props-toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    width: 100%; min-height: 46px; padding: 8px 12px;
    background: var(--tms-surface); border: 1px solid var(--tms-border);
    border-radius: var(--tms-r); text-align: left;
  }
  .tms-props-sum { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
  .tms-props-sum b { font-size: 13.5px; }
  .tms-props-sum span {
    font-size: 11.5px; color: var(--tms-text-3);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .tms-props-chev { color: var(--tms-text-3); font-size: 11px; }

  /* Collapsed by default. Hidden rather than shrunk: a squashed panel of half-legible
     fields is worse than one honest tap. */
  .tms-props.is-collapsed { display: none; }

  /* The header wraps rather than truncating — a subject is the one thing worth the
     vertical space on a small screen. */
  .tms-t-head h1 { font-size: 18px; max-width: none; }

  /* Comment bodies keep images inside the card. An image at its natural width is what
     turns a thread into a horizontally scrolling page. */
  .tms-msg-c img, .tms-t-desc img { max-width: 100%; height: auto; }

  /* ---- new ticket ---- */
  .tms-create { gap: 10px; }

  /* Also left in document order: the form comes first, then the quota and Create
     ticket at the end of it, which is where a submit button belongs anyway. */
}

/* The rail sits at the bottom on phones, so the strip spans the full width there. */
@media (max-width: 720px) {
  .tms-t-stuck { left: 10px; right: 10px; }
}

/* Jump to latest — floats left of the 300px properties column so it never covers the
   panel's own controls; the chevron in the sprite points down already. */
.tms-jump-end {
  position: fixed;
  right: calc(300px + 44px);
  bottom: 24px;
  z-index: 45;
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--tms-surface);
  border: 1px solid var(--tms-border-strong);
  box-shadow: var(--tms-shadow-2);
  color: var(--tms-text);
  cursor: pointer;
}
.tms-jump-end:hover { background: var(--tms-surface-2, var(--tms-surface)); }
.tms-jump-end .tms-i { width: 18px; height: 18px; }

/* The panel is in-flow below 1081px, so the button can hug the edge. */
@media (max-width: 1080px) { .tms-jump-end { right: 18px; } }

/* Above the bottom rail bar on phones. */
@media (max-width: 720px) {
  .tms-jump-end { bottom: calc(var(--tms-railbar-h) + 14px); }
}

