/* ============================================================
   ClaimRepo — "The Claim File, digitized"
   Paper + ink + safety orange. Single screen: the viewport never
   scrolls; every list, feed and document scrolls inside its panel.
   The design authority is claimrepo-mockups/take-a.
   ============================================================ */

:root {
  --paper: #f2ede1;
  --paper-deep: #e7dfcc;
  --card: #fbf8f0;
  --card-2: #f4efe2;
  --ink: #1f2a35;
  --ink-2: #4b5865;
  --ink-3: #83817a;
  --line: #dad2bd;
  --line-2: #c6bca0;
  --accent: #e05e10;
  --accent-deep: #b34a09;
  --accent-soft: #fbe9dc;
  --ok: #256e4a;
  --ok-soft: #e3efe7;
  --warn: #a06d06;
  --warn-soft: #f7ecd2;
  --bad: #b3342c;
  --bad-soft: #f6e2e0;
  --info: #2b5ea7;
  --info-soft: #e2eaf6;
  /* Ink used as a FILL (nav pills, primary buttons, the clerk's head) needs to
     travel independently of ink-as-text, or dark mode paints cream on cream. */
  --fill-ink: #1f2a35;
  --fill-ink-hi: #2b3a49;
  --on-ink: #f4efe4;
  --field: #ffffff;
  --page-bg: linear-gradient(160deg, #f4efe4 0%, var(--paper) 45%, #ece5d2 100%);
  --page-dots: rgba(31, 42, 53, .045);
  --shadow: 0 1px 2px rgba(31, 42, 53, .07), 0 10px 28px rgba(31, 42, 53, .09);
  --shadow-big: 0 4px 10px rgba(31, 42, 53, .12), 0 24px 60px rgba(31, 42, 53, .22);
  --serif: "Newsreader", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  --r: 8px;
  --drawer-w: 300px;
  /* The Clerk rail: its open width (set by the drag, remembered per browser)
     and the width it collapses to — the edge tab. */
  --clerk-w: 336px;
  --clerk-tab: 34px;
}

html[data-theme="dark"] {
  --paper: #171c21;
  --paper-deep: #232a31;
  --card: #1e242b;
  --card-2: #242b33;
  --ink: #ece6d8;
  --ink-2: #b7bec7;
  --ink-3: #8d9299;
  --line: #333c46;
  --line-2: #45505c;
  --accent: #f2762c;
  --accent-deep: #ff9152;
  --accent-soft: #3a2317;
  --ok: #63c294;
  --ok-soft: #1c3025;
  --warn: #d9ad4e;
  --warn-soft: #33290f;
  --bad: #e8817a;
  --bad-soft: #35201e;
  --info: #7ba7e8;
  --info-soft: #1a2536;
  --fill-ink: #3b4652;
  --fill-ink-hi: #495666;
  --on-ink: #f4efe4;
  --field: #141a1f;
  --page-bg: linear-gradient(160deg, #1a2027 0%, var(--paper) 45%, #12171b 100%);
  --page-dots: rgba(236, 230, 216, .04);
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 28px rgba(0, 0, 0, .35);
  --shadow-big: 0 4px 10px rgba(0, 0, 0, .4), 0 24px 60px rgba(0, 0, 0, .55);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
/* `hidden` means hidden. Several of our own components set a display value on
   the same element (buttons, flex rows), which would otherwise win over the
   attribute and leave a "hidden" control on screen. */
[hidden] { display: none !important; }

/* Hard rule: the viewport never scrolls. */
html, body { height: 100%; overflow: hidden; }

body {
  font-family: var(--sans);
  font-size: 13.5px;
  color: var(--ink);
  background:
    radial-gradient(var(--page-dots) 1px, transparent 1.2px) 0 0 / 22px 22px,
    var(--page-bg);
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent-soft); }
a { color: var(--accent-deep); }

/* ---------- app frame: header row + main row, exactly 100vh ---------- */
.app {
  height: 100vh;
  display: grid;
  /* One column, and it may never be wider than the window. Left implicit, the
     column is an `auto` track sized to MAX-content, so the widest row in the
     frame (the top bar, once it has one section too many) silently pushed the
     whole app past the viewport — and since the viewport never scrolls, what
     went past it was simply cut off. Pinning the track to minmax(0, 1fr) hands
     the shortfall back to the rows, which know how to give: the bar shrinks its
     brand, and the panels ellipsize. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 54px 1fr;
}
/* Signed in, the frame has a second column: the Clerk rail. It is a TRACK, not
   a floating window — which is the whole of why opening it pushes the page
   across instead of covering the corner of it. Collapsed, the track narrows to
   the width of the edge tab and the page takes the rest back. The 46vw cap is
   the single-screen rule stated in the frame: the rail can never be dragged
   over the page it stands beside. */
.app.has-clerk { grid-template-columns: minmax(0, 1fr) min(var(--clerk-w), 46vw); }
.app.has-clerk.clerk-shut { grid-template-columns: minmax(0, 1fr) var(--clerk-tab); }
.app { transition: grid-template-columns .16s ease; }
@media (prefers-reduced-motion: reduce) { .app { transition: none; } }
/* The masthead is still one bar across the window; the rail hangs from under it
   to the floor, beside the working row. */
.app > .topbar { grid-column: 1 / -1; }
.app > main {
  grid-column: 1;
  min-height: 0;
  padding: 14px 16px 16px;
}

/* ---------- top bar ---------- */
.topbar {
  display: flex; align-items: center; gap: 20px;
  padding: 0 16px;
  border-bottom: 1px solid var(--line-2);
  background: linear-gradient(var(--card), var(--card-2));
}
/* The bar is a fixed row of things that all refuse to wrap, so below a certain
   width it used to push the page sideways. It has to give somewhere, and the
   brand is the one part that can lose characters without losing meaning: it
   shrinks and ellipsizes first, and the sections, the letter door and the
   account are never the thing that gets squeezed. */
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); min-width: 0; flex: 0 1 auto; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 7px;
  background: var(--fill-ink);
  color: #f6e9da;
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 13px; font-weight: 700;
  box-shadow: inset 0 0 0 1.5px rgba(246, 233, 218, .35), 0 2px 4px rgba(31, 42, 53, .25);
  position: relative;
}
.brand-mark::after {
  content: ""; position: absolute; inset: -3px;
  border: 1px dashed var(--accent); border-radius: 9px; opacity: .8;
}
.brand-name {
  font-family: var(--serif); font-size: 18px; letter-spacing: .01em;
  max-width: 380px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.brand-name b { color: var(--accent-deep); font-weight: 600; }

/* The headline on a gate card (a dead link, a confirmed address). It borrowed
   .brand-name, which is nowrap + ellipsis because that class lives in a fixed
   masthead — so a longer sentence came out clipped mid-word. Same face, allowed
   to wrap, because this one is a sentence rather than a brand line. */
.gate-head { font-family: var(--serif); font-size: 20px; letter-spacing: .01em; line-height: 1.3; }

.nav { display: flex; gap: 4px; margin-left: 8px; flex: none; }
.nav a {
  text-decoration: none; color: var(--ink-2);
  padding: 6px 12px; border-radius: 6px;
  font-size: 12.5px; font-weight: 600; letter-spacing: .02em;
  white-space: nowrap;
}
.nav a:hover { background: rgba(127, 127, 127, .12); color: var(--ink); }
.nav a.active { background: var(--fill-ink); color: var(--on-ink); box-shadow: 0 2px 5px rgba(31, 42, 53, .3); }
.nav a .claim-chip { font-family: var(--mono); font-size: 11px; opacity: .85; }

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 12px; flex: none; }
/* And when even that is not enough, the decoration goes before anything you
   navigate with: the append-only note is a label, and the name beside the
   avatar is already in the menu behind it. */
@media (max-width: 1240px) {
  .topbar .registry-note { display: none; }
  .avatar-btn .who-name { display: none; }
}
.registry-note {
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-deep); border: 1px dashed var(--accent); border-radius: 4px;
  padding: 3px 7px; text-decoration: none; white-space: nowrap;
}

.avatar {
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 11.5px; font-weight: 700; letter-spacing: .03em;
  background: #2f4b6e; color: #eef2f7; border: 2px solid var(--card);
  box-shadow: 0 0 0 1px var(--line-2);
  flex: none;
}
.avatar.sm { width: 26px; height: 26px; font-size: 10px; }
.avatar.lg { width: 62px; height: 62px; font-size: 20px; border-width: 3px; }
.avatar.shipper { background: #2f6e50; }
.avatar.ai { background: var(--accent); }
.avatar.carrier { background: #6e3a2f; }

/* avatar menu */
.avatar-menu { position: relative; }
.avatar-btn {
  display: flex; align-items: center; gap: 8px;
  background: none; border: 0; cursor: pointer; padding: 0; color: var(--ink);
}
.avatar-btn .who-name { font-size: 12px; font-weight: 600; color: var(--ink-2); max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avatar-dd {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 210;
  min-width: 216px; display: none;
  background: var(--card); border: 1px solid var(--line-2); border-radius: 8px;
  box-shadow: var(--shadow-big); overflow: hidden;
}
.avatar-dd.open { display: block; }
.avatar-dd .dd-head { padding: 9px 12px; border-bottom: 1px solid var(--line); background: var(--card-2); }
.avatar-dd .dd-head .n { font-weight: 650; font-size: 12.5px; }
.avatar-dd .dd-head .r { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-top: 2px; }
.avatar-dd a, .avatar-dd button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 12px; font: 600 12.5px var(--sans); color: var(--ink-2);
  background: none; border: 0; text-align: left; text-decoration: none; cursor: pointer;
}
.avatar-dd a:hover, .avatar-dd button:hover { background: var(--card-2); color: var(--ink); }
.avatar-dd svg { width: 15px; height: 15px; flex: none; }
.avatar-dd .dd-sep { height: 1px; background: var(--line); }

/* ---------- panels & cards ---------- */
.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  display: flex; flex-direction: column;
  min-height: 0; min-width: 0;
  overflow: hidden;
}
.panel-head {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(var(--card), var(--card-2));
  flex: none;
}
.panel-title {
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2);
  white-space: nowrap;
}
.panel-body { flex: 1; min-height: 0; overflow-y: auto; }
.panel-body.pad { padding: 12px; }
.count-pill {
  font-family: var(--mono); font-size: 10px; color: var(--ink-2);
  background: var(--paper-deep); border-radius: 99px; padding: 1px 7px; white-space: nowrap;
}

/* thin warm scrollbars */
.panel-body, .scrolly { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.panel-body::-webkit-scrollbar, .scrolly::-webkit-scrollbar { width: 8px; height: 8px; }
.panel-body::-webkit-scrollbar-thumb, .scrolly::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 99px; border: 2px solid transparent; background-clip: content-box;
}

/* ---------- stamps (status) ---------- */
.stamp {
  display: inline-block;
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  padding: 2px 7px; border: 1.6px solid currentColor; border-radius: 3px;
  transform: rotate(-1.5deg);
  background: rgba(255, 255, 255, .4);
  white-space: nowrap;
}
html[data-theme="dark"] .stamp { background: rgba(255, 255, 255, .05); }
.stamp.status-open     { color: var(--info); }
.stamp.status-filed    { color: var(--info); }
.stamp.status-in_review { color: var(--warn); }
.stamp.status-settled  { color: var(--ok); }
.stamp.status-denied   { color: var(--bad); }
.stamp.status-closed   { color: var(--ink-3); border-style: dashed; }
/* The lifecycle stamp, beside the status one. An ISSUE reads as ink — it is a
   fact of the record, not an alarm; a CLAIM carries the accent, because that is
   the brokerage having decided to pursue it. */
.stamp.stage-issue { color: var(--ink-2); }
.stamp.stage-claim { color: var(--accent-deep); }
.stamp.big { font-size: 12px; padding: 4px 12px; border-width: 2px; transform: rotate(-2deg); }
/* Two big stamps on the claim bar shouldn't lean the same way — a stack of
   parallel rubber stamps looks printed, not stamped. */
.claim-id .stamp.stage-issue.big, .claim-id .stamp.stage-claim.big { transform: rotate(1.5deg); }

/* ---------- buttons, inputs, toggles ---------- */
.btn {
  font: 600 12.5px var(--sans);
  color: var(--ink); background: var(--card);
  border: 1px solid var(--line-2); border-radius: 6px;
  padding: 6px 12px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  box-shadow: 0 1px 2px rgba(31, 42, 53, .08);
  white-space: nowrap; text-decoration: none;
}
.btn:hover { border-color: var(--ink-3); background: var(--card-2); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--fill-ink); color: var(--on-ink); border-color: var(--fill-ink); }
.btn.primary:hover { background: var(--fill-ink-hi); }
.btn.accent { background: var(--accent); color: #fff; border-color: var(--accent-deep); }
.btn.accent:hover { background: #c95208; }
.btn.ghost { background: transparent; box-shadow: none; border-color: transparent; color: var(--ink-2); }
.btn.ghost:hover { background: rgba(127, 127, 127, .14); color: var(--ink); }
.btn.sm { padding: 3px 8px; font-size: 11.5px; }
.btn.icon { padding: 5px 7px; }
.btn.danger { color: var(--bad); }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

.input, textarea.input, select.input {
  font: 13px var(--sans); color: var(--ink);
  background: var(--field); border: 1px solid var(--line-2); border-radius: 6px;
  padding: 7px 10px; width: 100%;
}
.input:focus { outline: 2px solid rgba(224, 94, 16, .35); outline-offset: 0; border-color: var(--accent); }
/* A field you cannot type in should look like one — a filed letter is
   frozen, and the composer has to say so without a word. */
.input:disabled, textarea.input:disabled, select.input:disabled {
  background: var(--card-2); color: var(--ink-2); cursor: default; border-style: dashed;
}
textarea.input { resize: none; font-family: var(--sans); }
label.fld, div.fld { display: block; }
label.fld > span, div.fld > .fld-head, .fld-label {
  display: block;
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 4px;
}

/* toggle switch */
.switch { position: relative; display: inline-block; width: 34px; height: 19px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track {
  position: absolute; inset: 0; border-radius: 99px; cursor: pointer;
  background: var(--line-2); transition: background .15s;
}
.switch .track::before {
  content: ""; position: absolute; width: 13px; height: 13px; border-radius: 50%;
  left: 3px; top: 3px; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
  transition: transform .15s;
}
.switch input:checked + .track { background: var(--ok); }
.switch input:checked + .track::before { transform: translateX(15px); }

/* segmented control */
.seg { display: flex; border: 1px solid var(--line-2); border-radius: 6px; overflow: hidden; }
.seg button {
  border: 0; background: var(--card); font: 600 11.5px var(--sans);
  color: var(--ink-2); padding: 5px 11px; cursor: pointer;
}
.seg button.on { background: var(--fill-ink); color: var(--on-ink); }

/* ---------- misc ---------- */
.mono { font-family: var(--mono); }
.money { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-3); }
.small { font-size: 11.5px; }
.spacer { flex: 1; }
.hr { border: 0; border-top: 1px solid var(--line); margin: 10px 0; }
.nowrap { white-space: nowrap; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

.tag {
  display: inline-block; font-family: var(--mono); font-size: 10px;
  color: var(--ink-2); background: var(--paper-deep);
  border-radius: 4px; padding: 1px 6px; letter-spacing: .04em;
}
.tag.accent { color: var(--accent-deep); background: var(--accent-soft); }
.tag.ok { color: var(--ok); background: var(--ok-soft); }
.tag.warn { color: var(--warn); background: var(--warn-soft); }
.tag.bad { color: var(--bad); background: var(--bad-soft); }
.tag.info { color: var(--info); background: var(--info-soft); }

.empty {
  padding: 22px 16px; text-align: center; color: var(--ink-3); font-size: 12px; line-height: 1.6;
  background-image: repeating-linear-gradient(-45deg, transparent, transparent 7px, var(--card-2) 7px, var(--card-2) 8px);
}
.flash {
  font-size: 12px; padding: 7px 11px; border-radius: 6px;
  background: var(--ok-soft); color: var(--ok); border: 1px solid currentColor;
}
.flash.bad { background: var(--bad-soft); color: var(--bad); }
/* A change that has been asked for and not yet confirmed. Warn rather than
   bad: nothing is wrong, something is WAITING — and the two little forms sit
   on the same line as the words so the banner stays one thing. */
.flash.pending { background: var(--warn-soft); color: var(--warn); }
.flash.pending { display: flex; align-items: center; gap: 10px; line-height: 1.7; }
/* The words wrap as one block and the two buttons stay put beside them, rather
   than the buttons riding whichever line the text happens to end on. */
.pending-words { flex: 1 1 auto; min-width: 0; }
.pending-words .mono { overflow-wrap: anywhere; }
.pending-acts { flex: 0 0 auto; display: inline-flex; gap: 6px; }
.pending-acts form { display: inline; }

/* toast */
#toast {
  position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 20px);
  background: var(--fill-ink); color: var(--on-ink);
  font-size: 12.5px; padding: 9px 16px; border-radius: 8px;
  box-shadow: var(--shadow-big); opacity: 0; pointer-events: none;
  transition: opacity .2s, transform .2s; z-index: 400;
}
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- generic modal ---------- */
.modal-wrap {
  position: fixed; inset: 0; z-index: 250;
  background: rgba(31, 42, 53, .45);
  display: none; align-items: center; justify-content: center;
}
.modal-wrap.open { display: flex; }
.modal {
  width: 560px; max-width: calc(100vw - 40px); max-height: calc(100vh - 80px);
  background: var(--card); border: 1px solid var(--line-2); border-radius: 10px;
  box-shadow: var(--shadow-big); display: flex; flex-direction: column; overflow: hidden;
}
.modal .panel-body { padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.modal-foot {
  flex: none; display: flex; justify-content: flex-end; gap: 8px;
  padding: 10px 14px; border-top: 1px solid var(--line); background: var(--card-2);
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ---------- the masthead's letter door + its claim picker ---------- */
.topdoor { white-space: nowrap; }
.topdoor .pen { color: var(--accent-deep); font-size: 13px; line-height: 1; }
.picklist {
  min-height: 120px; max-height: min(46vh, 380px); overflow-y: auto;
  border: 1px solid var(--line); border-radius: 8px; background: var(--card-2);
}
.picklist .empty { padding: 18px 14px; }
.pickrow {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 11px; border: 0; border-bottom: 1px solid var(--line);
  background: transparent; cursor: pointer; font: inherit; color: inherit;
}
.pickrow:last-child { border-bottom: 0; }
.pickrow:hover, .pickrow:focus-visible { background: var(--card); box-shadow: inset 3px 0 0 var(--accent); }
.pickrow .pk-ref { flex: none; font-size: 10.5px; color: var(--ink-3); width: 84px; overflow: hidden; text-overflow: ellipsis; }
.pickrow .pk-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pickrow .pk-title { font-size: 12.5px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pickrow .pk-parties { font-size: 11px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pickrow .stamp { flex: none; }

@media (max-width: 1180px) {
  .topdoor { padding-left: 8px; padding-right: 8px; font-size: 0; gap: 0; }
  .topdoor .pen { font-size: 15px; }
}

/* ============================================================
   Clerk — the right-edge rail (every signed-in page).
   Slides out and PUSHES the page; dragged to width; collapses
   to a slim edge tab. Width and open/shut both persist.
   ============================================================ */
#clerk {
  grid-column: 2; grid-row: 2;
  position: relative; z-index: 30;
  min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  background: var(--card);
  border-left: 1px solid var(--line-2);
  box-shadow: -8px 0 20px rgba(31, 42, 53, .09);
}
#clerk.sizing { user-select: none; }

/* Collapsed: everything but the tab steps out of the way, and the tab becomes
   the rail. Nothing is destroyed — the conversation is still in the DOM, so
   opening it again is the same thread, not a fresh one. */
.app.clerk-shut #clerk > :not(.clerk-tab) { display: none; }
.app.clerk-shut #clerk { border-left-color: var(--line); box-shadow: none; }

.clerk-tab {
  display: none;
  flex: 1; width: 100%; min-height: 0; border: 0; padding: 14px 0; cursor: pointer;
  background: var(--fill-ink); color: var(--on-ink);
  writing-mode: vertical-rl; text-orientation: mixed;
  font: 700 10.5px var(--mono); letter-spacing: .18em; text-transform: uppercase;
  align-items: center; justify-content: center; gap: 12px;
}
.app.clerk-shut #clerk .clerk-tab { display: flex; }
.clerk-tab:hover { background: #2b3947; }

/* The inboard edge is the handle: drag it to set the rail's width. */
.clerk-railgrip {
  position: absolute; left: -4px; top: 0; bottom: 0; width: 12px;
  cursor: col-resize; z-index: 6; background: none; border: 0; padding: 0;
}
.clerk-railgrip::after {
  content: ""; position: absolute; left: 5px; top: 50%; height: 46px; width: 3px;
  transform: translateY(-50%); border-radius: 2px; background: var(--line-2);
}
.clerk-railgrip:hover::after, .clerk-railgrip:focus-visible::after { background: var(--accent); }

.clerk-head {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 8px 10px 8px 12px;
  background: var(--fill-ink); color: var(--on-ink);
  user-select: none;
}
.clerk-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px rgba(224, 94, 16, .25); flex: none;
  animation: clerkpulse 2.6s infinite;
}
@keyframes clerkpulse { 50% { box-shadow: 0 0 0 5px rgba(224, 94, 16, .12); } }
.clerk-name { font-family: var(--serif); font-size: 14.5px; letter-spacing: .02em; }
.clerk-sub { font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; opacity: .55; }
.clerk-head .btn.ghost { color: rgba(244, 239, 228, .8); padding: 3px 6px; }
.clerk-head .btn.ghost:hover { background: rgba(244, 239, 228, .15); color: #fff; }

.clerk-ctx {
  flex: none; display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-bottom: 1px solid var(--line);
  background: var(--card-2);
  font-family: var(--mono); font-size: 10px; color: var(--ink-2); letter-spacing: .03em;
}
.clerk-ctx .eye { color: var(--accent-deep); }
.clerk-ctx .ctx-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.clerk-body { flex: 1; min-height: 0; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.cmsg { max-width: 92%; line-height: 1.45; font-size: 12.5px; }
.cmsg .who {
  font-family: var(--mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: 3px;
}
.cmsg .bubble {
  padding: 8px 11px; border-radius: 10px;
  background: var(--card-2); border: 1px solid var(--line);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.cmsg.me { align-self: flex-end; text-align: right; }
.cmsg.me .bubble { background: var(--fill-ink); color: var(--on-ink); border-color: var(--fill-ink); text-align: left; }
.cmsg.sys .bubble { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }
.cmsg .did {
  display: block; margin-top: 6px; padding-top: 5px; border-top: 1px dashed var(--line-2);
  font-family: var(--mono); font-size: 10px; color: var(--accent-deep); white-space: normal;
}
.cmsg .bubble a { color: var(--accent-deep); }
.clerk-typing { font-family: var(--mono); font-size: 10px; color: var(--ink-3); letter-spacing: .1em; }

.clerk-input {
  flex: none; display: flex; gap: 6px; padding: 9px;
  border-top: 1px solid var(--line); background: var(--card);
}
.clerk-input input {
  flex: 1; min-width: 0; font: 12.5px var(--sans); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: 99px; padding: 7px 12px; background: var(--field);
}
.clerk-input input:focus { outline: 2px solid rgba(224, 94, 16, .35); border-color: var(--accent); }
.clerk-send {
  flex: none; width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); color: #fff; border: none; cursor: pointer;
  font-size: 14px; display: grid; place-items: center;
}
.clerk-send:hover { background: #c95208; }

/* drop box, pinned under the composer */
.clerk-drop {
  flex: none; margin: 0 9px 9px; padding: 9px 10px; text-align: center; cursor: pointer;
  border: 1px dashed var(--line-2); border-radius: 8px; background: var(--card-2);
  background-image: repeating-linear-gradient(-45deg, transparent, transparent 6px, rgba(127,127,127,.05) 6px, rgba(127,127,127,.05) 7px);
  font-family: var(--serif); font-size: 12.5px; color: var(--ink-2);
}
.clerk-drop:hover, #clerk.dropping .clerk-drop { border-color: var(--accent); color: var(--accent-deep); background: var(--accent-soft); }
.clerk-drop input[type=file] { display: none; }
.clerk-drop .hint { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-top: 2px; }

.drop-card { border: 1px solid var(--line-2); border-radius: 8px; background: var(--card-2); padding: 9px 10px; font-size: 12px; }
.drop-card .dc-file { font-weight: 650; overflow-wrap: anywhere; }
.drop-card .dc-q { color: var(--ink-2); margin: 4px 0 6px; line-height: 1.45; }
.drop-card select, .drop-card input { margin-bottom: 6px; }
.drop-card .dc-actions { display: flex; gap: 6px; }

/* ============================================================
   Dashboard — the claims desk
   ============================================================ */
main.dash { display: grid; gap: 14px; min-height: 0; grid-template-columns: 1.5fr 1fr; }
.col { display: grid; gap: 14px; min-height: 0; }
.col.left { grid-template-rows: auto 1fr; }
.col.right { grid-template-rows: auto 1fr 1.15fr; }

.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.stat {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); padding: 10px 14px 12px; min-width: 0;
}
.stat .k {
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3);
}
.stat .v { font-family: var(--serif); font-size: 26px; margin-top: 2px; letter-spacing: -.01em; }
.stat .v small { font-size: 14px; color: var(--ink-3); font-family: var(--sans); }
.stat .d { font-size: 11px; margin-top: 1px; color: var(--ink-3); }

.filters { display: flex; gap: 6px; flex-wrap: wrap; }
.fchip {
  font: 600 11.5px var(--sans); color: var(--ink-2);
  border: 1px solid var(--line-2); background: var(--card);
  border-radius: 99px; padding: 3px 10px; cursor: pointer; text-decoration: none;
}
.fchip:hover { border-color: var(--ink-3); }
.fchip.on { background: var(--fill-ink); color: var(--on-ink); border-color: var(--fill-ink); }
.fchip b { font-weight: 700; }
/* Two groups of chips on one line: which STAGE, then which STATUS. The hairline
   is what keeps them from reading as one long list of unrelated filters. */
.fsep { width: 1px; align-self: stretch; margin: 1px 3px; background: var(--line-2); }
.fchip.stage-claim { color: var(--accent-deep); }
.fchip.stage-claim.on, .fchip.stage-issue.on { color: var(--on-ink); }

.claim-row { border-bottom: 1px solid var(--line); }
.claim-row:last-child { border-bottom: 0; }
/* Eight columns, and the row stays ONE line: reference, who, what, the stage
   stamp, the age, the money, the status stamp, the caret. The stage cost the
   register width it did not have, so the mono columns around it were tightened
   to their actual content — a register whose rows wrap is a list, not a
   register. */
.claim-line {
  display: grid; align-items: center; gap: 8px;
  grid-template-columns: 70px 1.2fr 1.05fr 56px 48px 84px 100px 16px;
  padding: 10px 14px; cursor: pointer; width: 100%;
  background: none; border: 0; text-align: left; font: inherit; color: inherit;
}
.claim-line:hover { background: rgba(127, 127, 127, .07); }
.claim-no { font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--accent-deep); }
.claim-who .s { font-weight: 650; }
.claim-who .c { font-size: 11px; color: var(--ink-3); }
.claim-what { font-size: 12px; color: var(--ink-2); }
.claim-age { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); text-align: right; white-space: nowrap; }
.claim-amt { text-align: right; font-family: var(--mono); font-weight: 700; font-size: 13px; }
.claim-stage { text-align: center; }
.claim-st { text-align: center; }
.caret { color: var(--ink-3); font-size: 11px; transition: transform .15s; text-align: center; }
.claim-row.open .caret { transform: rotate(90deg); }

.claim-more { display: none; padding: 2px 14px 14px 106px; }
.claim-row.open .claim-more { display: block; }
.claim-row.open { background: rgba(127, 127, 127, .05); }
.more-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px 18px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 14px; margin-bottom: 8px;
}
.more-grid .k { font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.more-grid .v { font-size: 12px; margin-top: 1px; }
.more-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* The intake popup opens an ISSUE, and says in a sentence what that means and
   what a claim is, because the words are the whole point of the change. */
.intake-lede {
  font-size: 12px; line-height: 1.55; color: var(--ink-2); margin: 0;
  border-left: 3px solid var(--accent); padding: 2px 0 2px 11px;
}
.intake-lede b { color: var(--ink); font-weight: 700; }
.stagepick { border: 1px solid var(--line-2); border-radius: 8px; padding: 9px 11px 11px; margin: 0; background: var(--card-2); }
.stagepick legend {
  font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-3); padding: 0 5px;
}
.stageopt { display: flex; align-items: flex-start; gap: 8px; padding: 4px 0; cursor: pointer; }
.stageopt input { margin-top: 3px; accent-color: var(--accent); flex: none; }
.stageopt b { font-size: 12.5px; display: block; }
.stageopt .small { display: block; line-height: 1.4; }

/* The one lifecycle move, on the claim bar. It sits with the actions, not with
   the status picker — promoting is not a status change. A plain flex item, not
   `display: contents`: contents drops the form from the accessibility tree in
   every current browser, and it breaks hit-testing besides. */
.promote-form { display: flex; flex: none; }

.settings-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.setcard {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); padding: 11px 13px;
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
}
.setcard .who { display: flex; align-items: center; gap: 9px; min-width: 0; }
.setcard .who b { font-size: 13px; display: block; }
.setcard .who .small { display: block; }
.setrow { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-2); }
.setcard a.go { font-size: 11.5px; font-weight: 700; color: var(--accent-deep); text-decoration: none; margin-left: auto; white-space: nowrap; }
.setcard a.go:hover { text-decoration: underline; }

.search-wrap { padding: 10px 12px 8px; flex: none; border-bottom: 1px solid var(--line); }
.doc-result {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-bottom: 1px solid var(--line); cursor: pointer;
  text-decoration: none; color: inherit;
}
.doc-result:hover { background: rgba(127, 127, 127, .07); }
.doc-ico {
  width: 26px; height: 32px; flex: none; border-radius: 3px;
  background: #fff; border: 1px solid var(--line-2); position: relative;
  box-shadow: 1.5px 1.5px 0 var(--line); overflow: hidden;
}
.doc-ico::before {
  content: ""; position: absolute; left: 4px; right: 4px; top: 5px; height: 2px;
  background: var(--line-2); box-shadow: 0 5px 0 var(--line), 0 10px 0 var(--line), 0 15px 0 var(--line);
}
.doc-ico.photo { background: linear-gradient(135deg, #b9c7ad, #7d8f74 55%, #57684f); }
.doc-ico.photo::before { display: none; }
.doc-ico.evt { background: var(--info-soft); border-color: var(--info); }
.doc-ico.evt::before { background: var(--info); box-shadow: 0 5px 0 var(--info-soft), 0 10px 0 var(--info); }
.doc-ico.note { background: var(--warn-soft); border-color: var(--warn); }
.doc-ico.note::before { background: var(--warn); box-shadow: 0 5px 0 var(--warn), 0 10px 0 var(--warn); }
.doc-name { display: block; font-weight: 650; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-meta { display: block; font-size: 10.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.no-results { padding: 18px; text-align: center; color: var(--ink-3); font-size: 12px; }
.res-group { padding: 7px 12px 2px; }
.res-group .rg-head {
  display: flex; align-items: baseline; gap: 8px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent-deep); text-decoration: none;
}
.res-group .rg-head:hover { text-decoration: underline; }
.res-group .rg-head .stamp { flex: none; letter-spacing: .1em; }

.team-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--line); }
.team-row:last-child { border-bottom: 0; }
.team-row .tn { display: block; font-weight: 650; font-size: 12.5px; }
.team-row .te { display: block; font-size: 10.5px; color: var(--ink-3); font-family: var(--mono); }
/* A deactivated account on the dashboard's team list: still listed, visibly off. */
.team-row.off .tn, .team-row.off .te { opacity: .6; }
.team-row.off .avatar { filter: grayscale(1); opacity: .55; }

/* ============================================================
   Register — the working list
   ============================================================ */
/* One panel, edge to edge, and the single-screen rule holds the way it does
   everywhere else: the page never scrolls, the ROWS scroll inside the panel,
   and the head, the chips, the column labels and the closing line all stay put
   while they do. */
main.register { display: grid; grid-template-columns: minmax(0, 1fr); min-height: 0; }
.register-panel { min-height: 0; }

.reg-search { display: flex; align-items: center; gap: 6px; flex: 1; max-width: 420px; }
.reg-search .input { padding: 4px 9px; font-size: 12.5px; }

/* The chips get a rail of their own under the head: nine of them wrapping into
   a panel head that also holds a search box makes a page you have to read
   twice. */
.panel-sub {
  display: flex; align-items: center; gap: 10px; flex: none;
  padding: 7px 12px; border-bottom: 1px solid var(--line); background: var(--card);
}
.reg-lens { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }
.reg-lens a { color: var(--accent-deep); }

/* Seven columns, and a row is ONE line. The same discipline as the dashboard's
   register: a row that wraps is a list, not a register. */
.reg-head, .reg-row {
  display: grid; align-items: center; gap: 10px;
  grid-template-columns: 60px 82px minmax(0, 1.5fr) 92px minmax(0, 1.1fr) 96px 14px;
  padding: 0 14px;
}
.reg-head {
  flex: none; padding-top: 6px; padding-bottom: 6px;
  border-bottom: 1px solid var(--line); background: var(--card-2);
  font-family: var(--mono); font-size: 8.5px; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3);
}
.reg-head .r { text-align: right; }

.reg-row {
  padding-top: 9px; padding-bottom: 9px;
  border-bottom: 1px solid var(--line);
  text-decoration: none; color: inherit;
}
.reg-row:last-child { border-bottom: 0; }
.reg-row:hover { background: rgba(127, 127, 127, .07); }
.reg-row:focus-visible, .reg-row.on {
  outline: none; background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent);
}
.rg-ref { font-size: 12px; font-weight: 700; color: var(--accent-deep); }
.rg-what, .rg-last { min-width: 0; display: grid; }
.rg-what .t { font-weight: 650; font-size: 12.5px; }
.rg-what .w, .rg-last .w { font-size: 10.5px; color: var(--ink-3); }
.rg-last .t { font-size: 11.5px; color: var(--ink-2); }
.rg-last .t.muted { font-style: italic; }
.rg-amt { text-align: right; font-family: var(--mono); font-weight: 700; font-size: 13px; }
.rg-go { color: var(--ink-3); font-size: 12px; text-align: center; }
.reg-row:hover .rg-go { color: var(--accent); }
.reg-foot { display: flex; align-items: center; gap: 10px; }
.reg-foot kbd, .regnav kbd {
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  border: 1px solid var(--line-2); border-bottom-width: 2px; border-radius: 4px;
  padding: 0 4px; background: var(--card); color: var(--ink-2);
}

@media (max-width: 1100px) {
  .reg-head, .reg-row { grid-template-columns: 56px 74px minmax(0, 1.6fr) 88px 88px 14px; }
  .rg-last { display: none; }
  .reg-head > span:nth-child(5) { display: none; }
}

/* ============================================================
   Claim room
   ============================================================ */
/* The column is pinned to minmax(0, 1fr) for the same reason the app frame's
   is: left implicit it is an `auto` track sized to MAX-content, so the widest
   thing in the room (the claim bar, or the three panels of the workspace) made
   the room wider than the space it was given — and since the viewport never
   scrolls, whatever went past the edge was simply cut off. Pinned, the
   shortfall is handed back to the room, which knows how to give. */
main.claim { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; gap: 12px; min-height: 0; }
/* Reached from the register, the room grows one row above the claim bar for the
   strip that carries the list in with it. */
main.claim.reg { grid-template-rows: auto auto 1fr; }

/* The register, carried into the room: the way back, where you are in the list,
   and the two rooms either side. */
.regnav {
  display: flex; align-items: center; gap: 10px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r);
  padding: 5px 10px; box-shadow: var(--shadow); flex-wrap: wrap;
}
.regnav-back { font-weight: 650; }
.regnav-lens { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.regnav-lens b { color: var(--ink); font-weight: 700; }
.regnav-off { color: var(--warn); }
.regnav-step { display: inline-flex; align-items: center; gap: 6px; max-width: 240px; }
.regnav-step .regnav-ref { font-size: 11px; color: var(--accent-deep); min-width: 0; }
.regnav-step.off { opacity: .38; cursor: default; pointer-events: none; }
@media (max-width: 900px) {
  .regnav-step .regnav-ref { display: none; }
}

.claimbar {
  display: flex; align-items: center; gap: 18px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); padding: 10px 16px; flex-wrap: wrap;
}
/* The doors out of the claim room, kept together so the bar wraps them as one
   group rather than scattering when it runs out of width. */
.claim-doors { display: flex; align-items: center; gap: 8px; flex: none; }
.claim-id { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; min-width: 0; }
.claim-id h1 { font-family: var(--serif); font-size: 24px; font-weight: 600; letter-spacing: .01em; white-space: nowrap; }
.claim-id .vs { font-size: 12.5px; color: var(--ink-2); }
.claim-id .vs b { color: var(--ink); }
.claimbar .meta { display: flex; gap: 16px; margin-left: 8px; }
.claimbar .meta .m .k { font-family: var(--mono); font-size: 8.5px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3); }
.claimbar .meta .m .v { font-size: 12.5px; font-weight: 600; }
.claim-amt-big { font-family: var(--mono); font-size: 21px; font-weight: 700; letter-spacing: -.01em; }
.claim-amt-big small { font-size: 11px; color: var(--ink-3); font-weight: 500; display: block; text-align: right; letter-spacing: .08em; }
.status-form { display: flex; align-items: center; gap: 6px; }
.status-form select { font: 600 11.5px var(--sans); padding: 4px 7px; border-radius: 6px; border: 1px solid var(--line-2); background: var(--field); color: var(--ink); }

.workspace { display: flex; gap: 12px; min-height: 0; position: relative; }

/* The three panels of the room give in a fixed order when it is squeezed — by a
   narrow window, or by the Clerk rail taking width. The record in the middle is
   the point of the room, so it holds its column; the facts and the documents
   thin around it, down to a floor, rather than one of them being pushed off the
   edge of a page that cannot scroll. */
aside.facts { width: 286px; flex: 0 1 286px; min-width: 180px; }
.factgroup { padding: 11px 13px; border-bottom: 1px solid var(--line); }
.factgroup:last-child { border-bottom: 0; }
.factgroup h3 {
  font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent-deep); margin-bottom: 7px;
}
.frow { display: flex; justify-content: space-between; gap: 10px; padding: 2.5px 0; font-size: 12px; }
.frow .k { color: var(--ink-3); flex: none; }
.frow .v { text-align: right; font-weight: 550; overflow-wrap: anywhere; }
.party { display: flex; gap: 9px; align-items: center; padding: 5px 0; }
.party .nm { font-weight: 650; font-size: 12.5px; }
.party .rl { font-size: 10.5px; color: var(--ink-3); }
.desc-quote {
  font-size: 12px; color: var(--ink-2); background: var(--field);
  border: 1px solid var(--line); border-left: 3px solid var(--info);
  border-radius: 4px; padding: 7px 10px; margin-top: 6px; line-height: 1.5;
}

.center { flex: 1 1 0; min-width: min(280px, 100%); }
/* The strip has to hold every tab the room offers, and the room gets narrow:
   with the documents drawer and the Clerk rail both out at 1366px the center
   column is under 400px and the strip wants 443. It used to overflow VISIBLE,
   which meant the last tab — Sharing, i.e. who else can see this claim — was
   simply off the edge with no way to reach it. The strip scrolls inside itself
   instead: the panel gives, never the viewport, and no tab is unreachable. */
.tabs {
  display: flex; gap: 2px; padding: 0 8px; flex: none;
  border-bottom: 1px solid var(--line); background: linear-gradient(var(--card), var(--card-2));
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { height: 0; }
.tab {
  font: 700 12px var(--sans); color: var(--ink-3);
  padding: 10px 14px 8px; cursor: pointer; border: 0; background: none;
  border-bottom: 2.5px solid transparent; margin-bottom: -1px; letter-spacing: .02em;
  display: inline-flex; align-items: center; gap: 6px;
  flex: none; white-space: nowrap;
}
.tab:hover { color: var(--ink); }
.tab.on { color: var(--accent-deep); border-bottom-color: var(--accent); }
.tabpane { display: none; flex: 1; min-height: 0; flex-direction: column; }
.tabpane.on { display: flex; }

/* the record: one dated stream */
.feed { flex: 1; min-height: 0; overflow-y: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
.evt { align-self: center; display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); text-align: center; max-width: 92%; }
.evt .doclink { color: var(--accent-deep); cursor: pointer; text-decoration: underline dotted; background: none; border: 0; font: inherit; padding: 0; }
.evt .when { color: var(--line-2); }
.msg { display: flex; gap: 10px; max-width: 88%; }
.msg.mine { align-self: flex-end; flex-direction: row-reverse; }
.msg .bub { background: var(--field); border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; box-shadow: 0 1px 2px rgba(31, 42, 53, .05); min-width: 0; }
.msg.mine .bub { background: var(--info-soft); border-color: var(--line-2); }
.msg.ai .bub { background: var(--accent-soft); border-color: var(--accent); }
/* A note the broker team wrote to itself. The customer is not reading this one,
   and the paper it sits on says so without a word — a dashed edge, which is how
   the rest of the app already draws "this does not leave the building". */
.msg.brokeronly .bub { background: var(--warn-soft); border-color: var(--warn); border-style: dashed; }
.msg .hdr { display: flex; align-items: baseline; gap: 7px; margin-bottom: 3px; flex-wrap: wrap; }
.msg .hdr b { font-size: 12px; }
.msg .hdr .when { font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); }
.msg .txt { font-size: 12.5px; line-height: 1.5; color: var(--ink-2); white-space: pre-wrap; overflow-wrap: anywhere; }
.msg .txt .doclink { color: var(--accent-deep); cursor: pointer; text-decoration: underline dotted; font-weight: 600; background: none; border: 0; font-family: inherit; font-size: inherit; padding: 0; }

.composer { flex: none; border-top: 1px solid var(--line); background: var(--card); padding: 9px 12px; display: flex; flex-direction: column; gap: 7px; }
.composer .row { display: flex; gap: 8px; }
.composer textarea { flex: 1; height: 46px; }
.composer .vis { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--ink-3); flex-wrap: wrap; }
.composer select { font: 12px var(--sans); padding: 4px 7px; border-radius: 6px; border: 1px solid var(--line-2); background: var(--field); color: var(--ink); }

/* strategy pane */
.strategy { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 20px; }
.strategy h4 { font-family: var(--mono); font-size: 10px; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3); margin: 18px 0 6px; }
.strategy h4:first-child { margin-top: 0; }
.strategy .lede { font-family: var(--serif); font-size: 15.5px; line-height: 1.55; }
.strategy ul { list-style: none; display: flex; flex-direction: column; gap: 7px; }
.strategy li { font-size: 12.5px; line-height: 1.5; padding-left: 15px; position: relative; }
.strategy li::before { content: "▸"; position: absolute; left: 0; color: var(--accent); }
.strategy li .d { color: var(--ink-2); }

/* story pane — the record told back as a dated list.

   Rusty, on the prose this used to be: "I assumed the story would be bullets
   and links, not an actual thing a human had to wade through." So the telling
   is a list: a date column, one short line per movement of the file, and the
   rows that line came from as chips you can open. The pane (never the page)
   does the scrolling — the single-screen rule holds here the same as
   everywhere else in the room. The prose block below it is still here because
   tellings written before this are still on file, and are still readable. */
.story { flex: 1; min-height: 0; overflow-y: auto; padding: 14px 20px 22px; display: flex; flex-direction: column; }
.story-head { display: flex; align-items: center; gap: 10px; flex: none; padding-bottom: 10px; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.story h4 { font-family: var(--mono); font-size: 10px; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3); margin: 22px 0 8px; }

.story-prose { font-family: var(--serif); font-size: 15.5px; line-height: 1.62; color: var(--ink); max-width: 62ch; }
.story-prose p { margin: 0 0 13px; }
.story-prose p:last-child { margin-bottom: 0; }
/* The opening sentence carries the record's own weight — the same trick the
   claim bar plays with the reference, one size up and set in small caps. */
.story-prose p:first-child::first-line { font-variant-caps: small-caps; letter-spacing: .01em; }

/* The telling itself. Each line is one movement of the record; the chips after
   it are the rows it was written from, and each opens the real thing — the
   document in the floating viewer, the message on the Mail tab, the letter on
   its own page, the entry under your eye on the record feed. */
.story-bullets { list-style: none; margin: 0; padding: 0; }
.sb {
  display: grid; grid-template-columns: 86px 1fr; gap: 0 12px; align-items: baseline;
  padding: 7px 0 8px; border-top: 1px dashed var(--line);
}
/* The room has four columns and the middle one gets thin: at 1100px, with the
   documents drawer and the Clerk rail both open, this pane is about 240px
   across and a fixed date column would eat half of it. So the measurement is
   the PANE's, not the window's — below 380px the date stops being a column and
   sits above its line. */
.story { container-type: inline-size; }
@container (max-width: 380px) {
  .sb { grid-template-columns: 1fr; gap: 2px; }
  .sb-date:empty { display: none; }
}
.sb:first-child { border-top: 0; padding-top: 0; }
.sb-date { font-size: 10.5px; letter-spacing: .04em; color: var(--ink-3); white-space: nowrap; }
.sb-body { font-family: var(--serif); font-size: 15px; line-height: 1.5; color: var(--ink); }
.sb-line { margin-right: 5px; }

/* A ref chip: a pointer at a row, not part of the sentence — so it is set in
   the mono face the rest of the app uses for record-keeping marks. */
.sref {
  display: inline-flex; align-items: baseline; gap: 5px;
  margin: 2px 4px 0 0; padding: 1px 8px 2px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--card-2);
  font-family: var(--mono); font-size: 10.5px; line-height: 1.6; color: var(--ink-2);
  text-decoration: none; max-width: 100%;
}
a.sref:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-deep); }
.sref-k { font-size: 9px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3); }
a.sref:hover .sref-k { color: var(--accent-deep); }
/* A row that no longer resolves — superseded, removed, or not this reader's to
   open — is plain text. A dead link in a chronology is worse than no link. */
.sref.dead { border-style: dashed; border-color: var(--line); background: transparent; color: var(--ink-3); cursor: default; }

/* An earlier telling, opened underneath the current one. */
.story-bullets.compact .sb { padding: 5px 0; }
.story-bullets.compact .sb-body { font-size: 13.5px; }
.story-old .story-bullets { margin-top: 8px; padding-left: 12px; border-left: 2px solid var(--line-2); }

/* A telling written before the Story became a list says so, and is left
   exactly as it was told. */
.story-legacy { margin-bottom: 10px; font-style: italic; }

/* The record row a Story chip just jumped to. */
.feed .flash { animation: rec-flash 1.8s ease-out 1; border-radius: var(--r); }
@keyframes rec-flash { 0%, 30% { background: var(--accent-soft); } 100% { background: transparent; } }

/* The freshness flag. It is a statement about the RECORD, not a warning about
   the story, so it reads in the warn palette rather than the error one — and
   the button that fixes it sits inside the same strip. */
.story-flag {
  flex: none; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 16px; padding: 9px 12px; border-radius: var(--r);
  border: 1px dashed var(--warn); background: var(--warn-soft); color: var(--ink);
  font-size: 12.5px; line-height: 1.45;
}
.story-flag form { margin-left: auto; }
.story-flag.bad { border-style: solid; border-color: var(--bad); background: var(--bad-soft); }

.story-foot { flex: none; display: flex; align-items: center; gap: 10px; margin-top: 20px; padding-top: 12px; border-top: 1px dashed var(--line); }

.story-old { border-top: 1px dashed var(--line); padding: 8px 0; }
.story-old summary { cursor: pointer; color: var(--ink-2); }
.story-old summary:hover { color: var(--ink); }
.story-old .story-prose { font-size: 14px; margin-top: 10px; padding-left: 12px; border-left: 2px solid var(--line-2); }
.story-old .story-prose p:first-child::first-line { font-variant-caps: normal; }

/* sharing pane */
.sharing { flex: 1; min-height: 0; overflow-y: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
.share-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--line); font-size: 12px; }
.share-row .lnk { font-family: var(--mono); font-size: 11px; color: var(--accent-deep); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-row.dead { opacity: .55; }
/* Who outside is reading this file with an account of their own, under the
   links. Separated by a rule rather than a panel: it is the same question the
   links answer, asked about a person instead of a credential. */
.uwblock { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.uwblock .flash { margin-bottom: 10px; }

/* ---------- documents drawer (thumbnails) ---------- */
#drawer { width: var(--drawer-w); flex: 0 1 var(--drawer-w); min-width: 168px; position: relative; }
#drawer.closed { display: none; }
.thumbgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 10px; padding: 12px 12px 12px 16px; }
.thumb { cursor: pointer; text-align: center; background: none; border: 0; padding: 0; font: inherit; color: inherit; min-width: 0; }
.thumb .pv {
  display: grid; height: 84px; border-radius: 5px; background: #fff; border: 1px solid var(--line-2);
  box-shadow: 2px 2px 0 var(--line); position: relative; overflow: hidden;
  display: grid; place-items: center; transition: transform .12s, box-shadow .12s;
}
.thumb:hover .pv, .thumb:focus-visible .pv { transform: translateY(-2px) rotate(-.7deg); box-shadow: 3px 4px 0 var(--line-2); border-color: var(--accent); }
.thumb.on .pv { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft), 2px 2px 0 var(--line-2); }
.thumb .pv img { width: 100%; height: 100%; object-fit: cover; display: block; }
.thumb .pv canvas { width: 100%; height: 100%; object-fit: cover; display: block; }
.thumb .pv .lines {
  position: absolute; left: 10px; right: 10px; top: 12px; height: 2px; background: var(--line-2);
  box-shadow: 0 7px 0 var(--line), 0 14px 0 var(--line), 0 21px 0 var(--line), 0 28px 0 var(--line), 0 35px 0 var(--line), 0 42px 0 var(--line), 0 49px 0 var(--line);
}
.thumb .pv .cornertag {
  position: absolute; top: 0; left: 0; font-family: var(--mono); font-size: 7.5px; font-weight: 700;
  letter-spacing: .08em; padding: 2px 5px; color: #fff; background: var(--info); border-radius: 0 0 4px 0; z-index: 2;
}
.thumb .nm { display: block; font-size: 10.5px; font-weight: 650; margin-top: 5px; line-height: 1.25; overflow-wrap: anywhere; }
.thumb .mt { display: block; font-family: var(--mono); font-size: 8.5px; color: var(--ink-3); margin-top: 1px; }
.thumb .anno-ct {
  position: absolute; bottom: 4px; right: 4px; font-family: var(--mono); font-size: 8px; font-weight: 700;
  background: var(--fill-ink); color: var(--on-ink); border-radius: 99px; padding: 1px 5px; z-index: 2;
}
/* Only a document with more than one page wears this; a single page and an
   image say nothing, because there is nothing to say. */
.thumb .page-ct {
  position: absolute; bottom: 4px; left: 4px; font-family: var(--mono); font-size: 8px; font-weight: 700;
  background: rgba(31, 42, 53, .82); color: #fff; border-radius: 99px; padding: 1px 5px; z-index: 2;
}
/* Where a document came from, on hover. A small card in the house's own paper
   — same fill, same rule, same hard shadow the thumbnails wear — placed beside
   the thumbnail by public/js/claim.js and never inside it, because the grid is
   rebuilt on every filter keystroke. It floats above the room, so it is fixed
   and it is the one thing here allowed to sit over the panels. */
.provcard[hidden] { display: none; }
.provcard {
  position: fixed; z-index: 90; max-width: 260px; display: flex; flex-direction: column; gap: 3px;
  background: var(--card); border: 1px solid var(--line-2); border-radius: 6px;
  box-shadow: 3px 4px 0 var(--line-2); padding: 8px 10px; pointer-events: none;
}
.provcard .pc-door { font-size: 11.5px; font-weight: 700; line-height: 1.25; color: var(--ink); }
.provcard .pc-who { font-size: 11px; color: var(--ink-2); line-height: 1.3; }
.provcard .pc-when { font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); }
.provcard .pc-notes {
  font-size: 11px; color: var(--ink-2); line-height: 1.35; margin-top: 3px;
  padding-top: 5px; border-top: 1px solid var(--line-2); overflow-wrap: anywhere;
}
.drawer-tab {
  position: absolute; right: 0; top: 42%; z-index: 6;
  writing-mode: vertical-rl; text-orientation: mixed;
  background: var(--fill-ink); color: var(--on-ink); border: 0; border-radius: 6px 0 0 6px;
  font: 700 10.5px var(--mono); letter-spacing: .14em; text-transform: uppercase;
  padding: 12px 6px; cursor: pointer; box-shadow: var(--shadow); display: none;
}
.workspace.drawer-hidden .drawer-tab { display: block; }

/* ============================================================
   Floating document viewer — draggable, resizable, never covers
   the thumbnail rail it was opened from.
   ============================================================ */
#viewer {
  position: fixed; z-index: 240; display: none;
  left: 90px; top: 90px; width: 720px; height: 620px;
  min-width: 380px; min-height: 300px;
  flex-direction: column; background: #2b3138; border-radius: 12px;
  box-shadow: var(--shadow-big); overflow: hidden; border: 1px solid #1c2127;
}
#viewer.open { display: flex; }
#viewer.dragging, #viewer.sizing { user-select: none; }
.v-head { flex: none; display: flex; align-items: center; gap: 12px; padding: 9px 14px; background: #232830; color: #e8e4d8; cursor: grab; }
#viewer.dragging .v-head { cursor: grabbing; }
.v-head .nm { font-family: var(--serif); font-size: 15px; }
.v-head .mt { font-family: var(--mono); font-size: 10px; color: #8f97a1; }
.v-nav { display: flex; gap: 4px; }
.v-btn {
  background: transparent; color: #cfd4da; border: 1px solid #454c55; border-radius: 6px;
  font: 600 12px var(--sans); padding: 4px 10px; cursor: pointer; text-decoration: none;
}
.v-btn:hover { background: #39404a; color: #fff; }
.v-btn.close { border-color: transparent; font-size: 15px; padding: 2px 9px; }
.v-btn[disabled] { opacity: .4; cursor: not-allowed; }

.v-tools { flex: none; display: flex; align-items: center; gap: 6px; padding: 7px 14px; background: #2f353d; border-top: 1px solid #232830; border-bottom: 1px solid #232830; flex-wrap: wrap; }
.tool {
  background: transparent; color: #cfd4da; border: 1px solid transparent; border-radius: 6px;
  font: 600 11.5px var(--sans); padding: 5px 10px; cursor: pointer; display: inline-flex; gap: 6px; align-items: center;
}
.tool:hover { background: #39404a; }
.tool.on { background: var(--accent); color: #fff; border-color: var(--accent-deep); }
.tool[disabled] { opacity: .4; cursor: not-allowed; }
.swatch { width: 17px; height: 17px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; flex: none; padding: 0; }
.swatch.on { border-color: #fff; box-shadow: 0 0 0 1.5px var(--accent); }
.v-tools .sep { width: 1px; height: 20px; background: #454c55; margin: 0 4px; }
.v-tools .hint { font-family: var(--mono); font-size: 9.5px; color: #767f89; letter-spacing: .05em; }

.v-body { flex: 1; min-height: 0; display: flex; }
.v-stage { flex: 1; min-width: 0; overflow: auto; padding: 22px; display: block; }
.v-stage.busy { display: grid; place-items: center; }
.doc-holder { position: relative; margin: 0 auto; width: max-content; }
/* One box per page, stacked down the stage. The box exists before the page is
   painted — that is what keeps the scrollbar honest and gives a mark somewhere
   to land — so it wears the paper itself, and the canvas drops in on top. */
.v-pagewrap { position: relative; margin: 0 auto 18px; background: #fdfcf7; box-shadow: 0 10px 40px rgba(0, 0, 0, .5); }
.v-pagewrap:last-child { margin-bottom: 0; }
.v-pagewrap::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(#f3f0e6 0 100%); opacity: .55; transition: opacity .18s;
}
.v-pagewrap.painted::after { opacity: 0; }
.v-page { display: block; position: absolute; left: 0; top: 0; background: #fdfcf7; max-width: none; }
.v-pagewrap .anno { position: absolute; left: 0; top: 0; touch-action: none; z-index: 2; }
.v-pagewrap .anno.draw { cursor: crosshair; }
.v-pagewrap .anno.note { cursor: copy; }
.v-pagewrap .pins { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 3; }
.pin {
  position: absolute; width: 22px; height: 22px; margin: -11px 0 0 -11px;
  background: var(--accent); color: #fff; border: 2px solid #fff; border-radius: 50% 50% 50% 4px;
  display: grid; place-items: center; font: 800 10.5px var(--mono);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .4); transform: rotate(-8deg);
  pointer-events: auto; cursor: default; transition: transform .12s;
}
.pin.hot { transform: rotate(-8deg) scale(1.35); background: #1f2a35; }
.v-msg { color: #cfd4da; font-size: 12.5px; text-align: center; line-height: 1.6; max-width: 320px; }
.v-msg .v-btn { margin-top: 10px; display: inline-block; }

.v-notes { flex: none; width: 240px; background: var(--card); border-left: 1px solid #1c2127; display: flex; flex-direction: column; min-height: 0; }
.v-notes h3 { flex: none; font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2); padding: 11px 13px; border-bottom: 1px solid var(--line-2); }
.notelist { flex: 1; min-height: 0; overflow-y: auto; padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.noteitem { background: var(--field); border: 1px solid var(--line-2); border-radius: 7px; padding: 8px 10px; }
.noteitem .nh { display: flex; align-items: center; gap: 7px; margin-bottom: 4px; }
.noteitem .n { width: 17px; height: 17px; flex: none; background: var(--accent); color: #fff; border-radius: 50%; display: grid; place-items: center; font: 800 9.5px var(--mono); }
.noteitem .npage {
  font-family: var(--mono); font-size: 8.5px; color: var(--ink-3);
  background: var(--paper-deep); border-radius: 99px; padding: 1px 5px; white-space: nowrap;
}
.noteitem { cursor: pointer; }
.noteitem .nh .x { margin-left: auto; cursor: pointer; color: var(--ink-3); font-size: 12px; border: 0; background: none; }
.noteitem .nh .x:hover { color: var(--bad); }
.noteitem .body { font-size: 12px; color: var(--ink-2); line-height: 1.45; overflow-wrap: anywhere; }
.noteitem input { width: 100%; border: 0; font: 12px var(--sans); color: var(--ink); background: transparent; }
.noteitem input:focus { outline: none; }
.nempty { font-size: 11.5px; color: var(--ink-3); text-align: center; padding: 22px 12px; line-height: 1.5; }
.v-grip { position: absolute; z-index: 3; }
.v-grip.e { right: 0; top: 0; bottom: 0; width: 8px; cursor: ew-resize; }
.v-grip.s { left: 0; right: 0; bottom: 0; height: 8px; cursor: ns-resize; }
.v-grip.w { left: 0; top: 0; bottom: 0; width: 8px; cursor: ew-resize; }
.v-grip.n { left: 0; right: 0; top: 0; height: 8px; cursor: ns-resize; }
.v-grip.se {
  right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 4;
  background: linear-gradient(135deg, transparent 46%, #6a737d 46%, #6a737d 56%, transparent 56%,
              transparent 68%, #6a737d 68%, #6a737d 78%, transparent 78%);
}
.v-grip.sw { left: 0; bottom: 0; width: 16px; height: 16px; cursor: nesw-resize; z-index: 4; }

/* ============================================================
   Profile — the person, and their settings. The letterhead studio
   that used to sit beside this moved onto the letter itself; see
   "the letter desk" below, which is where the paper is now edited.
   ============================================================ */
/* The Settings column got a second job — the account — so it got the width to
   hold it without the sign-in log falling off the bottom of the screen. The
   viewport still never scrolls; the panel body does, and now rarely has to. */
main.user { display: grid; grid-template-columns: 780px 1fr; gap: 14px; min-height: 0; }
.profile-body { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.avatar-row { display: flex; align-items: center; gap: 14px; }
.frow2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sigcard { background: var(--card-2); border: 1px dashed var(--line-2); border-radius: 8px; padding: 10px 12px; }
.sigcard .scr { font-family: var(--serif); font-style: italic; font-size: 21px; color: var(--info); }
/* The signature line reads the way the signature is set to print. */
.sigcard .scr.print { font-family: var(--sans); font-style: normal; font-size: 16px; font-weight: 600; }
/* The log keeps its own height. It is the last thing in a flex column that
   can now be taller than the panel (the account section landed above it), and
   a shrinkable flex item at the bottom of an overflowing column collapses to
   nothing — which is how the log went invisible for a shipper. It scrolls
   inside itself (.signin-list) and the panel body scrolls past it. */
.sigcard.signins { flex: none; display: flex; flex-direction: column; }
.used-by { font-size: 11px; color: var(--ink-3); display: flex; gap: 6px; align-items: flex-start; line-height: 1.5; }

/* Account — the credentials, on the same page as everything else that is
   yours. Two small cards rather than one long form: the two changes are
   independent acts, each proven with the current password, and each says
   what it costs before you make it. */
.acct { display: flex; flex-direction: column; gap: 9px; }
/* The two changes stand side by side because they are two independent acts,
   not two halves of one form — you do one of them, not both. */
.acct-forms { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; align-items: start; }
.acct-form {
  background: var(--card-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 12px; display: flex; flex-direction: column; gap: 8px;
}
.acct-head { font-size: 12px; font-weight: 600; color: var(--ink); }
.acct-form .btn { align-self: flex-start; }
.acct-form .small { margin-top: -2px; }

/* The accent swatch, which now lives on the paper's own toolbar. */
.csw { width: 18px; height: 18px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; box-shadow: 0 0 0 1px rgba(31, 42, 53, .15); padding: 0; }
.csw.on { border-color: #fff; box-shadow: 0 0 0 2px var(--fill-ink); }

/* The sheet itself. This is the object the whole feature is about: it is what
   the Profile page used to preview, what the desk is now written on, and what
   the print view renders — one description of one piece of paper. */
.letter {
  width: 620px; min-height: 780px; margin: 0 auto; background: #fdfcf7; color: #21262c;
  box-shadow: 0 12px 44px rgba(31, 42, 53, .45); padding: 48px 56px;
  font-size: 12.5px; line-height: 1.55; font-family: var(--sans);
}
.letter .lh { margin-bottom: 26px; }
.letter .lh.center { text-align: center; }
.letter .lh .co { font-family: var(--serif); font-size: 23px; letter-spacing: .02em; }
.letter .lh .addr { font-family: var(--mono); font-size: 9px; letter-spacing: .1em; color: #6d747c; margin-top: 4px; text-transform: uppercase; }
.letter .lh .rule { height: 3px; width: 140px; margin-top: 10px; }
.letter .lh.center .rule { margin-left: auto; margin-right: auto; }
.letter .lh .sealbox { margin-top: 10px; }
.letter .seal { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 2.5px double #21262c; font: 800 13px var(--mono); }
.letter p { margin: 0 0 11px; }
.letter .re { font-family: var(--mono); font-size: 11px; font-weight: 700; }
.letter .sig-name { font-family: var(--serif); font-size: 21px; color: #27436b; margin-top: 26px; font-style: italic; }
.letter .sig-name.print { font-family: var(--sans); font-style: normal; font-size: 16px; font-weight: 600; }
.letter .sig-line { border-top: 1px solid #21262c; width: 240px; padding-top: 3px; font-size: 10.5px; }
.letter .foot { margin-top: 34px; padding-top: 8px; border-top: 1px solid #cdd2d8; font-family: var(--mono); font-size: 8.5px; letter-spacing: .08em; color: #6d747c; text-transform: uppercase; }
/* The parts of the paper the composer and the print view fill in. */
.letter .dateline { text-align: right; font-family: var(--mono); font-size: 11px; }
.letter .to, .letter .body { white-space: pre-wrap; }
.letter .body { min-height: 120px; }
.letter p:not([contenteditable]):not(.le):empty { display: none; }

/* ---------- writing ON the paper ----------
   The parts of a letter a person writes are contenteditable regions ON the
   letterhead, set in the type they print in. The affordance has to be there
   without ever looking like a form: nothing at rest, a faint tint on hover, a
   dashed accent rule on focus, and grey placeholder text in an empty region so
   it is obvious where the writing goes. None of it is on the paper itself —
   it is all outline and background, so what prints is only what was typed. */
.letter .le { outline: none; }
/* Like a word processor: the page is simply writable. No hover tint, no focus
   ring, no rectangles — the caret is the only sign of where you are, and the
   grey placeholders are the only sign of where writing can go. */
.letter.writable { cursor: text; }
.letter.writable .le { cursor: text; }
/* An empty region says what belongs in it. ::before, so the placeholder is
   never part of the letter's text and can never be saved or printed. */
.letter.writable .le.blank::before {
  content: attr(data-ph);
  color: #a09a8e; font-style: italic; white-space: pre-line; pointer-events: none;
}
/* "RE:" is the paper's, not the writer's — it sits in front of the region the
   writer owns, and only once there is something to be RE about. */
.letter .re[data-prefix]:not(.blank)::before { content: attr(data-prefix); }
/* The recipient block is three lines, each its own region, stacked so they read
   as one block. The block itself must NOT be pre-wrap: the newlines and indents
   between the three spans in the template are source formatting, and pre-wrap
   renders them — which put four blank lines through the middle of the address.
   Each line keeps pre-wrap of its own, because an address has real lines in it. */
.letter .to { white-space: normal; }
.letter .to .line { display: block; white-space: pre-wrap; }
.letter .dateline.le { display: block; }
/* Room to write is an edit-mode affordance. In view mode the letter is exactly
   as tall as the letter — an empty region does not hold a gap open, and a body
   of two sentences does not sit above 200px of nothing. */
.letter.writable .to .line, .letter.writable .dateline.le { min-height: 1.55em; }
.letter.writable .body.le { min-height: 200px; }
/* A signed letter is frozen: the regions stop being writable and stop
   pretending to be — no hover, no placeholder, no caret. */
.letter.frozen .le { cursor: default; }
.letter.frozen .le:hover, .letter.frozen .le:focus { background: transparent; box-shadow: none; }
.letter.frozen .le.blank::before { content: none; }

/* ---------- the identity blocks, written in place ----------
   The company heading and the signature block are regions too, in edit mode.
   They default to the Company page and the Profile and are stored as THIS
   letter's overrides, so one letter can carry its own hat without rewriting
   anybody's record. The paper says so, in the margin, and only while writing. */
.letter .lh .co.le, .letter .lh .addr.le { display: block; min-height: 1.4em; }
.letter .lh.center .co.le, .letter .lh.center .addr.le { text-align: center; }
.letter .sig-name.le { display: block; min-height: 1.1em; }
.letter .sig-line .sigbit { display: inline; }
.letter .foot.le { min-height: 1.2em; }
.letter .le[data-prefix]:not(.blank)::before { content: attr(data-prefix); }
/* An empty region only reserves room while it can be written in — a view-mode
   letter with no title under the signature simply has no line there. */
.letter:not(.writable) .le.blank { min-height: 0; }
.letter:not(.writable) .foot.le.blank,
.letter:not(.writable) .sig-line .sigbit.blank { display: none; }

/* The margin notes that say where an edit goes. They are part of the desk, not
   of the letter: they exist only in edit mode and never reach the print view. */
.papernote {
  display: none;
  font: 400 9.5px var(--mono); letter-spacing: .02em; line-height: 1.5;
  color: #8a8272; border-left: 2px solid var(--accent); padding: 1px 0 1px 8px;
  margin: -2px 0 10px;
}
.papernote a { color: #6a6252; }
.papernote b { color: #6a6252; font-weight: 700; }
.editing .papernote.on { display: block; }

/* ============================================================
   The letter desk — the Letter page itself: the paper on the
   left, written on directly, and the clerk in a panel beside
   it. It used to float over the claim room as an overlay; it
   does not any more, so there is one desk in one place. Each
   column scrolls its own; the viewport still never moves.
   ============================================================ */
.deskwrap { display: block; min-height: 0; min-width: 0; }
.desk {
  width: 100%; height: 100%;
  background: var(--card); border: 1px solid var(--line-2); border-radius: 10px;
  box-shadow: var(--shadow); display: flex; flex-direction: column; overflow: hidden; min-height: 0;
}
.desk-head {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-bottom: 1px solid var(--line);
  background: linear-gradient(var(--card), var(--card-2));
}
.desk-head .stamp { transform: rotate(-2deg); }
.desk-send {
  flex: none; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 12px; border-bottom: 1px solid var(--line); background: var(--accent-soft);
}
.desk-send .input { flex: 1; min-width: 180px; }
.desk-confirm {
  flex: none; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px; border-bottom: 1px solid var(--line); background: var(--warn-soft);
}
/* The paper, and nothing beside it. The clerk that used to be docked here is
   the rail down the right edge of the page now — one Clerk, one home. */
.desk-body { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.desk-main { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.desk-tools {
  flex: none; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 7px 12px; border-bottom: 1px solid var(--line); background: var(--card-2);
}
.desk-tools .deskhint { white-space: nowrap; }
.prefills { display: flex; gap: 6px; flex-wrap: wrap; }
.prefill {
  font: 600 11px var(--sans); padding: 3px 9px; border-radius: 99px; cursor: pointer;
  border: 1px dashed var(--line-2); background: var(--card-2); color: var(--ink-2);
}
.prefill:hover { border-color: var(--accent); color: var(--accent-deep); background: var(--accent-soft); }
.clerkdraft { display: flex; gap: 6px; }
.clerkdraft .input { flex: 1; min-width: 0; }
.clerkdraft .btn { flex: none; white-space: nowrap; }
/* The desk's first pass, in the rail: the instruction and the one button that
   writes a first draft onto the paper. The panel around it is the Clerk rail,
   which is the same on every page — this is the only part of it the Letter page
   adds. */
#clerk > .clerkdraft { flex: none; padding: 9px 10px 0; }
#clerk > .small.muted { flex: none; padding: 4px 10px 8px; line-height: 1.45; }
/* A letter the clerk is proposing: shown as the paper would take it, with the
   one action that puts it there. Applying is one step, and so is taking it back. */
.dc-prop {
  border: 1px dashed var(--accent); border-radius: 8px; background: var(--accent-soft);
  padding: 8px 10px; margin-top: 7px; font-size: 12px; line-height: 1.5;
}
.dc-prop .pv {
  max-height: 190px; overflow-y: auto; white-space: pre-wrap;
  font-family: var(--sans); color: var(--ink); background: var(--card); border: 1px solid var(--line);
  border-radius: 6px; padding: 7px 9px;
}
.dc-prop .pa { display: flex; align-items: center; gap: 7px; margin-top: 7px; flex-wrap: wrap; }
.dc-prop .pk { font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-deep); }

.desk-paper { flex: 1; min-height: 0; overflow: auto; padding: 22px; background: #857f70; }
.desk-paper .letter { box-shadow: 0 10px 34px rgba(31, 42, 53, .4); }

/* ---------- the paper's own toolbar ----------
   The letterhead choices that are not text. It is clipped to the top edge of
   the sheet rather than floated over the page, because these choices belong to
   this piece of paper — and it is only there in edit mode, so the letter in
   view mode is the letter and nothing else. Deliberately slim and quiet: it
   sits on the desk surface, not on the letter. */
.papertool {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 10px; border-radius: 7px; flex-wrap: wrap; flex: none;
  margin-bottom: 8px;
  background: rgba(31, 42, 53, .55); border: 1px solid rgba(253, 252, 247, .18);
  backdrop-filter: blur(3px);
}
.papertool .pt-group { display: flex; align-items: center; gap: 5px; }
.papertool .pt-sep { width: 1px; height: 16px; background: rgba(253, 252, 247, .22); }
.papertool .csw { width: 15px; height: 15px; box-shadow: 0 0 0 1px rgba(0, 0, 0, .3); }
.papertool .csw.on { border-color: #fdfcf7; box-shadow: 0 0 0 2px rgba(253, 252, 247, .85); }
.papertool .seg { border-color: rgba(253, 252, 247, .28); background: transparent; }
.papertool .seg button { background: transparent; color: #e6e0d4; }
.papertool .seg button.on { background: #fdfcf7; color: #21262c; }
.papertool .pt-switch { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.papertool .pt-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.papertool .pt-switch .track {
  position: relative; width: 28px; height: 15px; border-radius: 99px; flex: none;
  background: rgba(253, 252, 247, .3); transition: background .15s;
}
.papertool .pt-switch .track::before {
  content: ""; position: absolute; width: 11px; height: 11px; border-radius: 50%;
  left: 2px; top: 2px; background: #fdfcf7; transition: transform .15s;
}
.papertool .pt-switch input:checked + .track { background: var(--accent); }
.papertool .pt-switch input:checked + .track::before { transform: translateX(13px); }
.papertool .pt-lab, .papertool .pt-note { font: 600 10.5px var(--sans); color: #e6e0d4; }
.papertool .pt-note { font: 400 9.5px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: #cfc8b8; }
.papertool + .letter { border-radius: 0; }
.seg.sm button { padding: 4px 9px; font-size: 11px; }
.seg.xs button { padding: 3px 8px; font-size: 10.5px; }
.seg button:disabled { opacity: .45; cursor: not-allowed; }

/* Where the letter lives, and the way back to it: a claim (a link to the claim
   room, because the desk is a page you travelled to now, not an overlay you
   close) or the writer's own folder. */
.where-chip {
  font: 600 10.5px var(--mono); letter-spacing: .04em; padding: 2px 8px; border-radius: 99px;
  background: var(--fill-2); color: var(--ink-2); border: 1px solid var(--line-2); white-space: nowrap;
  text-decoration: none;
}
a.where-chip:hover { border-color: var(--accent); color: var(--accent); }
.where-chip.unfiled { border-style: dashed; color: var(--ink-3); }

/* Which version of itself the letter on the desk is. One slim line under the
   desk head — the version, who signed each one, and links to the letter it
   revises and the letter that revises it. Only there when the letter is
   actually one of several; a letter in no chain has no line at all. */
.desk-lineage {
  flex: none; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 5px 12px; border-bottom: 1px solid var(--line); background: var(--card-2);
  font-size: 11px; color: var(--ink-3);
}
.desk-lineage .lin-ver { font: 700 10.5px var(--mono); letter-spacing: .04em; color: var(--ink-2); white-space: nowrap; }
.desk-lineage .lin-chain { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desk-lineage .lin-links { white-space: nowrap; }
.desk-lineage a { color: var(--accent); text-decoration: none; }
.desk-lineage a:hover { text-decoration: underline; }
/* Looking at a version something newer has replaced. Said, never enforced —
   an older version can still be revised again. */
.desk-lineage.superseded { background: var(--warn-soft); }
.desk-lineage .lin-newer { font-weight: 700; color: var(--ink-2); }
/* The revise question wears the same bar as filing, because it is the same
   kind of decision — with the calmer ground, since nothing is being frozen. */
.desk-confirm.revise { background: var(--fill-2); }

/* A letter's version, in a list row: "v2 · revises L#7". */
.lr-ver {
  font: 700 10px var(--mono); letter-spacing: .04em; color: var(--accent);
  white-space: nowrap;
}
.lr-ver.old { color: var(--ink-3); }
.letter-row > .lr-ver { flex: none; }

/* Filing a letter onto a claim — the same bar shape as sending and revising,
   because it is the same kind of decision. It is the only freeze there is now,
   so this bar took over the one the finalize step used to have rather than
   being added beside it. */
.desk-file {
  flex: none; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px; border-bottom: 1px solid var(--line); background: var(--fill-2);
}
.desk-undernote { width: 620px; max-width: 100%; margin: 12px auto 0; color: #e6e0d4; line-height: 1.5; }
.desk-undernote a { color: #fff; }

/* The letters filed on a claim. */
.letterlist { flex: 1; min-height: 0; overflow-y: auto; }
.letter-row { display: flex; align-items: center; gap: 10px; padding: 9px 14px; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.letter-row:last-child { border-bottom: 0; }
.letter-row .lr-re { font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.letter-row .lr-to { font-size: 11px; color: var(--ink-3); }
.letter-row .lr-when { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); white-space: nowrap; }
.letters-head { flex: none; display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--line); }

/* ---------- the Letter page ----------
   My Letters down the left, the paper and its clerk filling the rest. Same
   two-column shape the Profile page has, so the split reads as one idea. */
main.letterpage { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 14px; min-height: 0; }
/* The left lane: one panel, two tabs — the person and their letters, each
   getting the whole lane when it is the one open. Profile is the default. */
.panel.lane { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.panel.lane #lanepane-me > .scrolly { flex: 1; min-height: 0; overflow-y: auto; }
.panel.folder { display: flex; flex-direction: column; min-height: 0; }
.folder-note {
  flex: none; padding: 8px 12px; border-bottom: 1px solid var(--line);
  background: var(--card-2); line-height: 1.5;
}
.letter-row .lr-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.letter-row .stamp { flex: none; }
/* Only the folder's rows open a letter by being clicked; the claim's list has
   its own buttons and must not pretend the whole row is one. */
.panel.folder .letter-row {
  cursor: pointer; display: grid; gap: 2px 8px; align-items: center;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
}
.panel.folder .letter-row .btn.lr-del { grid-column: 4; grid-row: 1 / span 2; padding-left: 4px; padding-right: 4px; }
.panel.folder .letter-row .lr-main { grid-column: 2; min-width: 0; }
.panel.folder .letter-row .lr-re, .panel.folder .letter-row .lr-to {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.panel.folder .letter-row .lr-when { grid-column: 2; font-size: 10px; }
.panel.folder .letter-row .btn { grid-column: 3; grid-row: 1 / span 2; }
.panel.folder .letter-row .stamp { grid-column: 1; grid-row: 1 / span 2; }
.panel.folder .letter-row:hover { background: var(--card-2); }
.panel.folder .letter-row.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }

@media (max-width: 1360px) {
  main.letterpage { grid-template-columns: 250px minmax(0, 1fr); }
}
@media (max-width: 1100px) {
  main.letterpage { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .panel.folder .letterlist { max-height: 30vh; }
}

/* ============================================================
   Agent (Clerk) settings
   ============================================================ */
main.agent { display: grid; grid-template-columns: 380px 1fr; gap: 14px; min-height: 0; }
.col-body { padding: 13px; display: flex; flex-direction: column; gap: 12px; }
/* "on letters" tick beside a contact detail: include it in the signature block. */
.onletter {
  float: right; display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3); cursor: pointer; font-weight: 500;
}
.onletter input { accent-color: var(--accent); margin: 0; cursor: pointer; }

/* Visibility badges — who sees this field. External = leaves the company. */
.vis-badge {
  display: inline-block; margin-left: 6px; padding: 2px 7px; border-radius: 4px;
  font-family: var(--mono); font-size: 9px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  vertical-align: 1px;
}
.vis-badge.external { color: var(--warn); background: var(--warn-soft); border: 1px dashed var(--warn); }
.vis-badge.internal { color: var(--ok); background: var(--ok-soft); border: 1px solid var(--ok-soft); }

/* sign-in audit rows (profile + company page) */
.signin-list { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 8px; background: var(--card-2); max-height: 180px; overflow-y: auto; }
.signin-row {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 10px; font-size: 11.5px; border-bottom: 1px solid var(--line);
}
.signin-row:last-child { border-bottom: 0; }
.signin-row .mono { font-family: var(--mono); font-size: 10px; color: var(--ink-2); white-space: nowrap; }
.signin-row .oc { margin-left: auto; font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--ok); }
.signin-row.failed .oc { color: var(--bad); }
.signin-row.failed { background: var(--bad-soft); }

.clerk-card { display: flex; align-items: center; gap: 12px; }
.clerk-face {
  width: 54px; height: 54px; border-radius: 14px; flex: none;
  background: var(--accent); color: #fff; display: grid; place-items: center;
  font: 700 22px var(--serif); box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .35), var(--shadow);
  position: relative;
}
.clerk-face::after { content: ""; position: absolute; inset: -4px; border: 1px dashed var(--accent); border-radius: 17px; }
.clerk-card b { font-family: var(--serif); font-size: 17px; display: block; }
.keyrow { display: flex; gap: 6px; }
.keyrow .input { font-family: var(--mono); font-size: 11.5px; }
.keynote { font-size: 11px; color: var(--ink-3); line-height: 1.45; }
.model-filter { margin-bottom: 6px; }

.memitem {
  display: flex; gap: 9px; align-items: flex-start;
  background: var(--field); border: 1px solid var(--line); border-radius: 7px;
  padding: 8px 10px; font-size: 12.5px; line-height: 1.4;
}
.memitem .pin-ic { color: var(--accent-deep); flex: none; font-size: 11px; margin-top: 1px; }
.memitem .src { display: block; font-family: var(--mono); font-size: 9px; color: var(--ink-3); margin-top: 3px; }
.memitem .x { margin-left: auto; border: 0; background: none; color: var(--ink-3); cursor: pointer; font-size: 12px; flex: none; }
.memitem .x:hover { color: var(--bad); }
.memadd { display: flex; gap: 7px; padding: 10px 13px; border-top: 1px solid var(--line); background: var(--card); flex: none; }

/* ============================================================
   Team / company / plain pages
   ============================================================ */

/* ============================================================
   Team — the members, and what an admin does to them
   The register of people, read the way the claims register is: one row per
   member, the facts in mono columns, the state as a word rather than a colour
   alone. It is a wide table beside a narrow column of doors (invite, pending),
   because the rows are the page and the forms are the sidebar.
   ============================================================ */
main.team { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 14px; min-height: 0; }
/* The invite form takes what it needs; the pending list takes the rest and
   scrolls inside itself, so the viewport still never does. */
.teamside { display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 14px; min-height: 0; }

.mrow {
  display: grid;
  /* Every column is a fixed width and the NAME takes the slack — including the
     actions, which would otherwise be sized by their own buttons and leave each
     row's columns landing somewhere different from the row above it. A register
     whose columns do not line up is not a register. */
  grid-template-columns: 26px minmax(140px, 1fr) 104px 84px 92px 92px 86px 236px;
  align-items: center; gap: 10px;
  padding: 8px 13px; border-bottom: 1px solid var(--line);
  font-size: 12.5px;
}
/* Tags and state words hug their text rather than stretching to their column. */
.mrow > .tag, .mrow > .mstate, .mrow > .scoped { justify-self: start; }
/* The column labels ride along the top of the list while it scrolls — without
   them the mono columns are four dates with no names on them. */
.mrow.head {
  position: sticky; top: 0; z-index: 2;
  background: var(--card-2); border-bottom: 1px solid var(--line-2);
  padding-top: 6px; padding-bottom: 6px;
  font-family: var(--mono); font-size: 9px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
}
.mrow .ln { display: block; font-weight: 650; }
.mrow .lm { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }
.mcell { font-family: var(--mono); font-size: 10.5px; color: var(--ink-2); white-space: nowrap; }
/* "you" / "owner" beside a name — a note about the row, not a status of it, so
   it is quieter than the role tag next to it. */
.mini {
  font-family: var(--mono); font-size: 8.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
  border: 1px solid var(--line-2); border-radius: 3px; padding: 0 4px;
}
/* A deactivated member is greyed, never gone: they are still on the record and
   the row still says everything it said before. */
.mrow.off { background: var(--paper-deep); }
.mrow.off .ln, .mrow.off .lm, .mrow.off .mcell { opacity: .6; }
.mrow.off .avatar { filter: grayscale(1); opacity: .55; }

.mstate {
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .11em; text-transform: uppercase; white-space: nowrap;
}
.mstate.on { color: var(--ok); }
.mstate.off { color: var(--warn); }

.macts { display: flex; align-items: center; justify-content: flex-end; gap: 6px; white-space: nowrap; }
.macts form { display: inline-flex; }

/* What a shipper can see, from the claims themselves. Closed it is a count
   (the whole list is in its tooltip); opened it names them, in place, and the
   row grows — the rows scroll in their panel, so nothing else has to move. */
.scoped > summary {
  cursor: pointer; list-style: none;
  font-family: var(--mono); font-size: 10.5px; color: var(--accent-deep);
  text-decoration: underline; text-underline-offset: 2px; white-space: nowrap;
}
.scoped > summary::-webkit-details-marker { display: none; }
.scoped[open] > summary { color: var(--ink-2); }
.scoped-list { display: flex; flex-direction: column; gap: 2px; padding: 5px 0 1px; }
.scoped-list a { font-size: 11px; color: var(--ink-2); text-decoration: none; }
.scoped-list a:hover { color: var(--accent-deep); text-decoration: underline; }
.scoped-list .mono { font-size: 10px; color: var(--ink-3); }
/* A shipper is scoped to files, and a file is an issue or a claim. The list
   says which, in the same stamp the register uses. */
.scoped-list .stamp { font-size: 8px; padding: 1px 4px; border-width: 1.2px; }

/* A closing line under a list, in the panel's own frame rather than as one more
   scrolling row — it is about the whole list, so it does not scroll with it. */
.panel-foot {
  flex: none; padding: 8px 13px; border-top: 1px solid var(--line);
  background: var(--card-2); line-height: 1.5;
}

/* ---------- support: the form, and the tickets you may read ---------- */
/* Two lanes, single-screen like everything else: the page never scrolls, each
   panel does. The form lane is fixed so the ticket lane gets the width — the
   tickets are the part that grows. */
/* ============================================================
   The PARKED support composer — bottom-left, on every signed-in
   page. Not a modal: no backdrop, nothing dimmed, the page behind
   it live and clickable. That is the feature — "it stays open and
   follow the users page changes so user can navigat and write
   proper ticket while using the system".

   The right edge is the Clerk rail's (a grid column, z-30). This
   parks in the one corner of every page in this app that is
   furniture rather than content.
   ============================================================ */
.tcomposer {
  position: fixed; left: 14px; bottom: 0; z-index: 34;
  display: flex; flex-direction: column; align-items: flex-start;
}
/* Shut is GONE — no parked tab, no remnant. The draft waits in
   sessionStorage; the doors back in are the masthead and the avatar menu. */
.tcomposer[data-shut="1"] { display: none; }
.composer-mark { font-size: 12px; letter-spacing: 0; }
/* Dragged off the bottom edge it becomes a floating card: all four corners,
   a full border, and wherever the person parked it. */
.tcomposer.afloat .composer-panel { border-radius: 10px; border-bottom: 1px solid var(--line-2); box-shadow: 0 8px 28px rgba(31, 42, 53, .2); }
.composer-head { cursor: move; }
.composer-panel {
  width: 348px; max-width: calc(100vw - 28px);
  max-height: min(70vh, 620px);
  display: flex; flex-direction: column; min-height: 0;
  background: var(--card);
  border: 1px solid var(--line-2); border-bottom: 0;
  border-radius: 10px 10px 0 0;
  box-shadow: 0 -6px 26px rgba(31, 42, 53, .17);
  overflow: hidden;
}
.composer-head {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 8px 9px 8px 12px;
  background: var(--fill-ink); color: var(--on-ink);
  user-select: none;
}
.composer-title { min-width: 0; }
.composer-title .n { font: 650 12px/1.2 var(--sans); }
.composer-title .s { font-size: 10px; opacity: .74; }
.composer-link { color: inherit; opacity: .8; font-size: 10.5px; text-decoration: none; border-bottom: 1px solid currentColor; }
.composer-link:hover { opacity: 1; }
.composer-x {
  background: none; border: 0; color: inherit; opacity: .78;
  font-size: 14px; line-height: 1; cursor: pointer; padding: 2px 3px;
}
.composer-x:hover { opacity: 1; }

.composer-form { display: flex; flex-direction: column; min-height: 0; flex: 1; }
/* THE FIELDS SCROLL, the panel does not grow. Same rule as every panel body on
   every page: the container is fixed, the contents move inside it. */
.composer-fields {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 11px 12px; display: flex; flex-direction: column; gap: 9px;
}
.composer-send {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; border-top: 1px solid var(--line); background: var(--card-2);
}
.composer-flash {
  font-size: 11.5px; line-height: 1.45; padding: 7px 9px; border-radius: 6px;
  background: var(--ok-soft);
}
.composer-flash.bad { background: var(--bad-soft); }
.composer-flash a { color: var(--accent-deep); }

@media (max-width: 720px) {
  .tcomposer { left: 0; right: 0; }
  .composer-panel { width: 100vw; border-radius: 0; border-left: 0; border-right: 0; }
}

/* Settings — the support notification address. A field and its sentence, not
   a boxed sub-form: it sits under the Support line it belongs to. */
.notify-form { display: flex; flex-direction: column; gap: 7px; margin-top: 11px; max-width: 460px; }
.notify-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

main.support { display: grid; grid-template-columns: 380px minmax(0, 1fr); gap: 14px; min-height: 0; }
/* The TRACKER — the broker team's room at the same URL. Wider list than the
   submitter's filing form needs, because the list IS the work here. Both
   panels are grid children of a min-height:0 row, so each scrolls in its own
   body and the viewport never does. */
main.support > .tracker-list { min-height: 0; }
main.support > .tracker-detail { min-height: 0; }
main.support:has(> .tracker-list) { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); }
.tracker-list .panel-sub { flex: none; }
/* THE STAMP COLUMN IS SIZED TO THE STAMP. A stamp is `white-space: nowrap` on
   purpose — a rubber stamp does not wrap — so a track narrower than the words
   in it does not clip them, it lets them run out of the box and print over the
   subject beside it. That is what "Fix awaiting review", the longest of the
   four statuses, did in a fixed 118px track.
   So the floor is the width the whole vocabulary needs, which keeps every row's
   subject on the same left edge, and the ceiling is max-content, so a status
   the app has never heard of (the pipeline may write one, and it reads as its
   raw value) takes the room it needs instead of covering a row. */
.tkrow {
  --tk-stamp-col: 144px;
  display: grid; align-items: center; gap: 10px;
  grid-template-columns: minmax(var(--tk-stamp-col), max-content) minmax(0, 1fr) auto 74px 44px;
  padding: 9px 12px; border-bottom: 1px solid var(--line);
  text-decoration: none; color: inherit;
}
.tkrow:last-child { border-bottom: 0; }
.tkrow:hover { background: var(--card-2); }
.tkrow.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.tkrow-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tkrow-subject { font-weight: 650; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The first line of the body, under the category. Quieter than the category
   above it and quieter than nothing else — it is there to tell four Bugs
   apart at a glance, not to be read from here. */
.tkrow-hint { font-size: 11px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tkrow-who { font-size: 10.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tkrow-marks { display: flex; gap: 4px; }
.tkmark { font-size: 11px; color: var(--ink-3); }
.tkmark.note { color: var(--accent-deep); }
.tkrow-when { font-size: 10.5px; color: var(--ink-3); white-space: nowrap; }
.tkrow-id { font-size: 10px; color: var(--ink-3); text-align: right; }
.tkd-subject { font-size: 16px; font-weight: 650; margin: 0 0 5px; overflow-wrap: anywhere; }
.tracker-detail .tk-body { font-size: 13px; }
.tracker-detail .tk-answer { margin-top: 13px; }
@media (max-width: 1080px) {
  /* The date is the first thing to go — it frees more than the stamp column
     needs, so the stamp keeps its full width rather than being squeezed into
     the subject again. */
  .tkrow { grid-template-columns: minmax(var(--tk-stamp-col), max-content) minmax(0, 1fr) auto 44px; }
  .tkrow-when { display: none; }
}
.support-form { display: flex; flex-direction: column; gap: 10px; }
.support-send { display: flex; align-items: center; gap: 10px; }

.ticket { padding: 11px 13px; border-bottom: 1px solid var(--line); }
.ticket:last-child { border-bottom: 0; }
.ticket.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.ticket-top { display: flex; align-items: center; gap: 9px; }
.ticket-top .tk-subject { font-weight: 650; font-size: 13px; min-width: 0; overflow-wrap: anywhere; }
.tk-id { font-size: 10px; color: var(--ink-3); }
.tk-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 5px;
  font-size: 11px; color: var(--ink-3); margin-top: 4px;
}
.tk-meta .tk-who { font-weight: 600; color: var(--ink-2); }
.tk-meta .tk-dot { opacity: .5; }
.tk-page { font-size: 10.5px; color: var(--ink-2); text-decoration: none; }
.tk-page:hover { color: var(--accent-deep); text-decoration: underline; }
/* The submitted words, as the text they are: the newlines are CSS, and nothing
   in them is ever markup. */
.tk-body { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 12.5px; line-height: 1.55; margin-top: 7px; }
/* An attachment on a ticket: the screenshot beside what it is, and the
   reference link under it. The image is capped so a tall screenshot cannot
   push the list around — clicking opens it full size. */
.tk-attach { display: flex; gap: 11px; align-items: flex-start; margin-top: 9px; flex-wrap: wrap; }
.tk-shot {
  display: block; flex: none; line-height: 0;
  border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: var(--card-2);
}
.tk-shot img { display: block; max-width: 260px; max-height: 170px; width: auto; height: auto; }
.tk-attach-side { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; }
.tk-shot-meta { display: flex; align-items: center; gap: 5px; min-width: 0; }
.tk-shot-meta .ellipsis { max-width: 190px; }
.tk-link { display: flex; align-items: baseline; gap: 7px; min-width: 0; font-size: 11.5px; }
.tk-link-k {
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); flex: none;
}
.tk-link a { color: var(--accent-deep); min-width: 0; }
/* "optional" beside a field label, so nothing on the form reads as required
   that is not. */
.fld > span .opt {
  font-family: var(--mono); font-size: 9px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-3); margin-left: 5px;
}
.input.file { padding: 6px 8px; font-size: 11.5px; }

.tk-reply { margin-top: 9px; padding: 8px 11px; border-radius: 6px; background: var(--ok-soft); }
.tk-reply .tk-body { margin-top: 3px; }
.tk-archive { margin-top: 9px; }

.tk-agent {
  margin-top: 9px; padding: 8px 11px; border-radius: 6px;
  background: var(--card-2); border: 1px dashed var(--line-2);
}
.tk-agent .fld-label { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
.tk-answer { margin-top: 9px; display: flex; flex-direction: column; gap: 6px; }
.tk-answer-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tk-tick { display: flex; align-items: center; gap: 5px; }

/* The status stamp, in the same ink the register's stamps use: received is a
   fact, being-worked-on is in flight, a fix waiting on a human is the one that
   wants an eye, resolved is done. */
.stamp.ticket-open { color: var(--info); }
.stamp.ticket-agent_assigned { color: var(--accent-deep); }
.stamp.ticket-fix_proposed { color: var(--warn); }
.stamp.ticket-resolved { color: var(--ok); border-style: dashed; }

main.plain { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; min-height: 0; }
main.split2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; min-height: 0; }
.stack { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.list-row { display: flex; align-items: center; gap: 10px; padding: 9px 13px; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.list-row:last-child { border-bottom: 0; }
.list-row .ln { font-weight: 650; }
.list-row .lm { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }

/* auth pages (login / setup / invite) */
main.gate { display: grid; place-items: center; min-height: 0; overflow-y: auto; }
.gate-card { width: 420px; max-width: 100%; }
.gate-card .panel-body { padding: 16px; display: flex; flex-direction: column; gap: 11px; }
.gate-mark { text-align: center; padding: 18px 0 4px; }
/* The wordmark carries the brokerage's own name, and a real brokerage name is
   longer than "Claim Repository". It wraps inside the card instead of running
   off the edge of it — which is what a long name did on the invite page, and
   would have done again on the reset page. */
.gate-mark .brand-name {
  font-size: 24px; display: block; max-width: 100%;
  white-space: normal; overflow-wrap: anywhere; line-height: 1.2;
  padding: 0 14px;
}
.gate-sub { font-size: 12px; color: var(--ink-3); text-align: center; line-height: 1.55; }

/* ============================================================
   Print — the one place the page is allowed to flow
   ============================================================ */
@media print {
  html, body { height: auto; overflow: visible; background: #fff; }
  .app { height: auto; display: block; }
  .topbar, #clerk, #viewer, #drawer, .drawer-tab, .btn, .tabs { display: none !important; }
  .panel { box-shadow: none; border-color: #ccc; }
  .panel-body { overflow: visible; }
}

/* Narrow windows: the desk stacks rather than crushing. Panels still own
   their own scrolling — the viewport itself never scrolls. */
/* The claim bar is one row. Below ~1460 the "On file" counts are the first
   thing to go — they are the one item on the bar that the facts rail already
   states in full ("Evidence" and "Record") — so the actions stay up top with
   the claim rather than dropping to a second line. */
@media (max-width: 1460px) {
  .claimbar .meta .m:nth-child(3) { display: none; }
}
/* The register thins the same way: "day N" is the first thing to go, because
   the row's own expander states the date of loss in full. The stage and the
   status are the two things the register exists to show, and never move. */
@media (max-width: 1420px) {
  .claim-line { grid-template-columns: 70px 1.2fr 1.05fr 56px 84px 100px 16px; }
  .claim-age { display: none; }
}
@media (max-width: 1340px) {
  .claimbar .meta .m:nth-child(2) { display: none; }  /* "Where" — the rail says it too */
}
/* An ISSUE's bar carries one door a claim's does not — Promote — and the bar is
   ONE row. So it gives up "Where" at every width rather than wrapping: the
   facts rail states it in full two inches below, and a bar folded onto a second
   line states nothing better. */
.claimbar.promotable .meta .m:nth-child(2) { display: none; }
/* The roster thins the same way the claim bar does: the columns that go first
   are the ones the record states elsewhere. JOINED is on the member's own
   account log; the name, the role, what they can see, whether they are on and
   the buttons are the point of the page and never move. */
@media (max-width: 1370px) {
  main.team { grid-template-columns: minmax(0, 1fr) 300px; }
  .mrow { grid-template-columns: 26px minmax(140px, 1fr) 104px 92px 92px 86px 236px; }
  .mrow > :nth-child(4) { display: none; }
}
@media (max-width: 1220px) {
  .mrow { grid-template-columns: 26px minmax(130px, 1fr) 104px 92px 86px 236px; }
  .mrow > :nth-child(5) { display: none; }  /* LAST SIGN-IN — the account log has it */
}
@media (max-width: 1180px) {
  main.dash { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  main.user, main.agent, main.split2, main.team, main.support { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  /* Narrow: the roster keeps the name, the state and the buttons — the mono
     date columns are the first thing to go, not the last. */
  .mrow { grid-template-columns: 26px minmax(120px, 1fr) 96px 86px 236px; }
  .mrow > :nth-child(4), .mrow > :nth-child(5), .mrow > :nth-child(6) { display: none; }
  .acct-forms { grid-template-columns: 1fr; }
  .claimbar .meta { display: none; }
}
@media (max-width: 900px) {
  aside.facts { display: none; }
  .stats { grid-template-columns: repeat(2, 1fr); }
}

/* the viewer's document-details editor (append-only supersede) */
/* Where the open document came from, at the top of its notes pane — the same
   sentence the drawer's hover card carries, with room for the notes in full.
   Everyone on the file reads this. The Downloads line inside it is the broker
   team's alone and is only rendered for them (views/partials/viewer.ejs). */
.v-prov[hidden] { display: none; }
.v-prov {
  flex: none; padding: 9px 12px; border-bottom: 1px solid var(--line-2); background: var(--card-2);
  display: flex; flex-direction: column; gap: 3px;
}
.v-prov .pv-door { font-size: 11.5px; line-height: 1.3; color: var(--ink-2); }
.v-prov .pv-door b { color: var(--ink); }
.v-prov .pv-when { font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); }
.v-prov .pv-when[hidden], .v-prov .pv-notes[hidden], .v-prov .pv-trail[hidden] { display: none; }
.v-prov .pv-notes {
  font-size: 11px; color: var(--ink-2); line-height: 1.35;
  margin-top: 3px; padding-top: 5px; border-top: 1px solid var(--line-2); overflow-wrap: anywhere;
}
.v-prov .pv-trail {
  font-size: 10.5px; color: var(--ink-2); line-height: 1.35;
  margin-top: 3px; padding-top: 5px; border-top: 1px solid var(--line-2); overflow-wrap: anywhere;
}
.v-details[hidden] { display: none; }
.v-details { flex: none; padding: 10px 12px; border-bottom: 1px solid var(--line-2); display: flex; flex-direction: column; gap: 8px; background: var(--card-2); }
.v-details .small { line-height: 1.4; }

/* ============================================================
   Mail — the claim's own mailbox, inside the claim room.
   Two columns like the rest of the room: the threads down the
   left, the letter on the right. Everything inbound is drawn as
   evidence, not as a live web page.
   ============================================================ */
.mail-head {
  flex: none; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--card-2);
}
.mail-head .eyebrow { font: 600 10px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.mail-addr {
  font-size: 13px; font-weight: 600; color: var(--accent-deep); background: var(--accent-soft);
  border: 1px dashed var(--accent); border-radius: 6px; padding: 3px 9px; cursor: copy;
}
.mail-addr:hover { background: var(--card); }
.mail-status-bad { color: var(--bad); }

.mail-body { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(220px, 300px) 1fr; }
.mail-list { border-right: 1px solid var(--line); overflow-y: auto; background: var(--card-2); }
.mail-view { overflow-y: auto; padding: 16px 20px; display: flex; flex-direction: column; gap: 12px; }
.mail-view > .empty { margin: auto; }
/* A letter is read in a column, not across a whole pane — and keeping the
   content (and its buttons) out of the far right corner keeps them clear of
   wherever the clerk has parked itself. */
.mail-view > * { max-width: 840px; width: 100%; }

.mail-thread {
  display: flex; flex-direction: column; gap: 3px; width: 100%; text-align: left;
  padding: 10px 12px; border: 0; border-bottom: 1px solid var(--line); background: transparent; cursor: pointer;
}
.mail-thread:hover { background: var(--card); }
.mail-thread.on { background: var(--card); box-shadow: inset 3px 0 0 var(--accent); }
.mail-thread.unread .mt-subj { font-weight: 700; }
.mt-top { display: flex; align-items: baseline; gap: 8px; }
.mt-who { flex: 1; min-width: 0; font-size: 12px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mt-when { font: 500 11px/1 var(--mono); color: var(--ink-3); flex: none; }
.mt-subj { font-family: var(--serif); font-size: 14.5px; color: var(--ink); line-height: 1.3; }
.mt-meta { display: flex; gap: 5px; flex-wrap: wrap; }
.count-pill.unread { color: var(--on-ink); background: var(--accent); }

.mail-msg-head { border-bottom: 1px solid var(--line); padding-bottom: 10px; }
.mm-subject { font-family: var(--serif); font-size: 20px; line-height: 1.25; color: var(--ink); margin-bottom: 5px; }
.mm-line { font-size: 13px; color: var(--ink-2); }

/* Said plainly, every time a message from outside is opened: this is data, not
   direction. The same rule the clerk is held to is the one the reader is told. */
.mail-flag {
  margin-top: 9px; padding: 7px 10px; border-radius: 6px; font-size: 12.5px; line-height: 1.45;
  color: var(--warn); background: var(--warn-soft); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
}
.mail-flag.untrusted { color: var(--ink-2); background: var(--card-2); border-color: var(--line-2); }

.mail-msg-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mail-msg-body { min-height: 60px; }
.mail-text { margin: 0; font: 13.5px/1.6 var(--sans); white-space: pre-wrap; word-break: break-word; color: var(--ink); }
.mail-html-frame { width: 100%; height: 460px; border: 1px solid var(--line); border-radius: var(--r); background: var(--card); }

.mail-atts { display: flex; flex-direction: column; gap: 6px; }
.mail-att { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; align-self: flex-start; max-width: 460px; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r); background: var(--card-2); }
.ma-name { font-weight: 600; font-size: 13px; flex: 1 0 100%; word-break: break-all; }
.mail-ask { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mail-ask .input.sm { width: auto; padding: 3px 6px; font-size: 12px; }

.mail-thread-nav { display: flex; gap: 6px; flex-wrap: wrap; }
.mail-attach-pick { display: flex; flex-direction: column; gap: 4px; max-height: 130px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r); padding: 6px 8px; background: var(--card-2); }
.mail-attach-opt { display: flex; align-items: center; gap: 6px; font-size: 13px; }

/* An entry the claim did not make itself reads differently on the record. */
.evt.external { border-left: 2px solid var(--warn); padding-left: 8px; }

@media (max-width: 1180px) {
  .mail-body { grid-template-columns: 1fr; grid-template-rows: minmax(120px, 34%) 1fr; }
  .mail-list { border-right: 0; border-bottom: 1px solid var(--line); }
}
