/* ============================================================
   BUREAU OF LOST TIMELINES — DISPATCH WIRE  (css/dispatch.css)
   Consumes js/dispatch.js and the tokens in css/tokens.css.
   Loaded on index.html (the public wire) and dashboard.html
   (the same wire with its internal items).

   The one idea: a published record is a newspaper clipping. It arrives
   inverted — paper on the dark desk, the contributor's own title in the
   display face, a red edge where it was cut — while Bureau activity stays
   ink on ink as a single mono line. You can tell what made the archive from
   across the room, and you never have to read a label to know which is which.

   Colour rules, same as everywhere else: red is the desk's authority,
   gold is an honour, phosphor is only ever a counter (the XP figure), and
   amber is left to the folklore markers.
   ============================================================ */

.dispatch {
  border-top: var(--spine) solid var(--alert);
  padding-top: var(--s-3);
}

/* ---------- the strip: ledger line across the top ---------- */
.dispatch-desk {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s-2);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--line);
}

.dispatch-led {
  align-self: center;
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--alert);
  box-shadow: 0 0 12px var(--alert-glow);
  transform: rotate(45deg);
  animation: dispatch-led 2.6s var(--ease) infinite;
}

@keyframes dispatch-led {
  0%, 100% { opacity: 1; }
  45%      { opacity: .35; }
}

.dispatch-strip,
.dispatch-today {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--muted-strong);
}

.dispatch-today {
  margin-left: auto;
  color: var(--alert-bright);
}

/* .dispatch- prefixes are needed because the dashboard wraps the wire in a
   .dash-section, whose own `h3` rule is a class + element and would otherwise
   outrank a bare class and shrink the heading to a 12px label. */
.dispatch .dispatch-word {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(20px, 2.4vw, 28px);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-flat);
  text-transform: uppercase;
  color: var(--paper-bright);
}

.dispatch-word-my {
  font-family: var(--font-my);
  font-size: 13px;
  color: var(--paper-dim);
}

/* ---------- filters ---------- */
.dispatch-filters {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-1);
  padding: var(--s-2) 0 0;
}

.dispatch-filter {
  padding: 5px 10px;
  background: transparent;
  border: 1px solid var(--line-strong);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--paper-dim);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              background var(--dur-1) var(--ease);
}

.dispatch-filter:hover,
.dispatch-filter:focus-visible {
  color: var(--paper-bright);
  border-color: var(--paper-dim);
}

.dispatch-filter.is-on {
  color: var(--paper-bright);
  border-color: var(--alert);
  background: var(--alert-wash);
}

.dispatch-filter:focus-visible {
  outline: 2px solid var(--alert-bright);
  outline-offset: 2px;
}

.dispatch-total {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-mono);
  color: var(--muted);
}

/* ---------- the wire ---------- */
.dispatch-list {
  display: flex;
  flex-direction: column;
  margin-top: var(--s-1);
}

.dispatch-row {
  display: grid;
  grid-template-columns: var(--gutter-id) minmax(0, 1fr);
  gap: var(--s-3);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line-hair);
}

.dispatch-row:last-child {
  border-bottom: 0;
}

.dispatch-margin {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 3px;
}

.dispatch-stamp {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--muted-strong);
}

.dispatch-ref {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-mono);
  color: var(--muted);
  /* a file number split over two lines reads as two different codes; the
     margin is sized so the whole stamp fits on one */
  white-space: nowrap;
}

.dispatch-main {
  min-width: 0;
}

/* ---------- chips: what kind of transmission this is ---------- */
.dispatch-chip {
  display: inline-block;
  padding: 2px 7px;
  border: 1px solid var(--line-strong);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--muted-strong);
}

.dispatch-chip--record,
.dispatch-chip--accept {
  border-color: var(--alert);
  color: var(--alert-bright);
}

/* an amendment is a correction, not a refusal — the phosphor of the AMEND tab
   on the record card, so the wire and the control read as the same act */
.dispatch-chip--amend {
  border-color: var(--phosphor-dim);
  color: var(--phosphor-dim);
}

.dispatch-chip--record {
  background: var(--alert);
  color: var(--ink-0);
}

.dispatch-chip--badge,
.dispatch-chip--promotion {
  border-color: var(--gold);
  color: var(--gold);
}

.dispatch-chip--reject {
  border-style: dashed;
  border-color: var(--alert-deep);
  color: var(--alert);
}

/* Correspondence and rooms are the Bureau talking to itself, so they take the two
   colours the sheets that hold them already use: the stamp for a letter that carries
   authority, the division purple for a line an operative is on. */
.dispatch-chip--letter {
  border-color: var(--alert);
  color: var(--alert-bright);
}

.dispatch-chip--room {
  border-color: var(--cat-timeline);
  color: var(--cat-timeline);
}

/* The wire cannot open a letter in place — it hands the reader to mail.html.
   A link, not a button, because it leaves the page. */
.dispatch-jump {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--muted-strong);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}

.dispatch-jump:hover {
  color: var(--alert-bright);
  border-bottom-color: var(--alert);
}

.dispatch-jump:focus-visible {
  outline: 2px solid var(--alert-bright);
  outline-offset: 2px;
}

/* ---------- the clipping: a record that made the archive ---------- */
.dispatch-kicker {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-1);
  margin-bottom: var(--s-2);
}

.dispatch-type,
.dispatch-note {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
}

.dispatch-row--record .dispatch-main {
  padding: var(--s-3) var(--s-4) var(--s-2);
  background: var(--paper-bright);
  border: 1px solid var(--line-strong);
  border-left: var(--spine) solid var(--alert);
  box-shadow: var(--shadow-1);
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}

.dispatch-row--record:hover .dispatch-main,
.dispatch-row--record:focus-within .dispatch-main {
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
}

.dispatch-row--record .dispatch-type {
  color: var(--alert-deep);
}

.dispatch-row--record .dispatch-note {
  color: rgba(11, 12, 14, 0.55);
}

.dispatch .dispatch-title {
  margin: 0 0 var(--s-1);
  /* the dashboard's h3 rule adds a rule and padding; a clipping has its own
     edge, so both come off */
  border-bottom: 0;
  padding-bottom: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(19px, 2.3vw, 26px);
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-flat);
  text-transform: uppercase;
  color: var(--ink-0);
  overflow-wrap: anywhere;
}

.dispatch-excerpt {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: rgba(11, 12, 14, 0.84);
  overflow-wrap: anywhere;
}

.dispatch-my {
  font-family: var(--font-my);
  font-size: 13px;
  line-height: 1.65;
  color: var(--paper-dim);
  overflow-wrap: anywhere;
}

.dispatch-row--record .dispatch-my {
  margin: 0 0 var(--s-2);
  color: rgba(11, 12, 14, 0.7);
}

.dispatch-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-2);
  padding-top: var(--s-1);
  border-top: 1px solid rgba(11, 12, 14, 0.14);
}

.dispatch-row--record .dispatch-who,
.dispatch-row--record .dispatch-when {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: rgba(11, 12, 14, 0.6);
}

.dispatch-open {
  margin-left: auto;
  padding: 6px 12px;
  background: transparent;
  border: 1px solid rgba(11, 12, 14, 0.34);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--ink-0);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease);
}

.dispatch-open:hover,
.dispatch-open:focus-visible {
  background: var(--alert);
  border-color: var(--alert);
  color: var(--paper-bright);
}

.dispatch-open:focus-visible {
  outline: 2px solid var(--alert);
  outline-offset: 2px;
}

/* ---------- activity: one mono line, ink on ink ---------- */
.dispatch-line {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-2);
}

.dispatch-who {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  font-weight: 400;
  color: var(--paper-dim);
}

.dispatch-text {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--paper);
  overflow-wrap: anywhere;
}

.dispatch-xp {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-mono);
  color: var(--phosphor);
}

.dispatch-row:not(.dispatch-row--record) .dispatch-when {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-mono);
  color: var(--muted);
}

.dispatch-row:not(.dispatch-row--record) .dispatch-my {
  margin-top: var(--s-1);
  padding-left: var(--s-2);
  border-left: var(--spine) solid var(--line-strong);
}

.dispatch-row--promotion .dispatch-who,
.dispatch-row--badge .dispatch-who,
.dispatch-row--amend .dispatch-who {
  color: var(--paper-bright);
}

.dispatch-more {
  padding: var(--s-2) 0;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- an empty wire is an open desk ---------- */
.dispatch-empty {
  padding: var(--s-5) var(--s-4);
  border: 1px dashed var(--line-red);
  background: var(--alert-wash);
}

.dispatch-empty-line {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(18px, 2.2vw, 24px);
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-flat);
  text-transform: uppercase;
  color: var(--paper-bright);
}

.dispatch-empty-my {
  margin-top: var(--s-1);
  font-family: var(--font-my);
  font-size: 13px;
  line-height: 1.65;
  color: var(--paper-dim);
}

.dispatch-cta {
  display: inline-block;
  margin-top: var(--s-3);
  padding: 10px 16px;
  background: var(--alert);
  border: 1px solid var(--alert);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--paper-bright);
  text-decoration: none;
  transition: background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}

.dispatch-cta:hover,
.dispatch-cta:focus-visible {
  background: var(--alert-bright);
  border-color: var(--alert-bright);
  box-shadow: 0 0 18px var(--alert-glow);
}

.dispatch-cta:focus-visible {
  outline: 2px solid var(--alert-bright);
  outline-offset: 2px;
}

.dispatch-cta-my {
  display: block;
  margin-top: 4px;
  font-family: var(--font-my);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: rgba(244, 241, 234, 0.82);
}

/* ---------- the tab carries the count ---------- */
.dispatch-tab-count {
  margin-left: 6px;
  padding: 1px 5px;
  border: 1px solid var(--line-strong);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: var(--tr-mono);
  color: var(--alert-bright);
}

/* ---------- the dashboard wire is the same document, tighter ---------- */
.dispatch--desk .dispatch-row {
  grid-template-columns: 86px minmax(0, 1fr);
  gap: var(--s-2);
  padding: var(--s-2) 0;
}

.dispatch--desk .dispatch-row--record .dispatch-main {
  padding: var(--s-2) var(--s-3);
}

.dispatch--desk .dispatch-title {
  font-size: clamp(17px, 2vw, 20px);
}

.dispatch--desk .dispatch-excerpt {
  font-size: 14px;
}

/* ---------- small screens ---------- */
@media (max-width: 720px) {
  .dispatch-row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-1);
  }
  .dispatch-margin {
    flex-direction: row;
    gap: var(--s-2);
    align-items: baseline;
    padding-top: 0;
  }
  .dispatch--desk .dispatch-row {
    grid-template-columns: minmax(0, 1fr);
  }
  .dispatch-today,
  .dispatch-total {
    margin-left: 0;
    width: 100%;
  }
  .dispatch-row:not(.dispatch-row--record) .dispatch-when {
    margin-left: 0;
  }
  .dispatch-open {
    margin-left: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dispatch-led {
    animation: none;
  }
  .dispatch-row--record .dispatch-main,
  .dispatch-filter,
  .dispatch-open,
  .dispatch-cta {
    transition: none;
  }
  .dispatch-row--record:hover .dispatch-main,
  .dispatch-row--record:focus-within .dispatch-main {
    transform: none;
  }
}
