/* C3 Inbox Robot — the web surface.

   Every colour, radius, shadow and font comes from tokens.css; a literal
   here is a bug. Components are named for what they are on screen, and
   the design language is the redesign foundation's turns 8-9: no top bar,
   no icons beyond the text glyphs, buttons that drop rather than scale.

   Only what a shipped surface uses lives here. The rest arrives with the
   surface that needs it. */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font);
  background: var(--ground);
  color: var(--ink);
  font-size: var(--text-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--blue); text-decoration: none; }
a:hover { color: var(--blue-btn-line); }
.muted { color: var(--mut); font-size: var(--text-meta); }
.serif { font-family: var(--font-serif); }

/* ---------- cards ---------- */
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card); }
.card-pad { padding: 20px 22px; }

/* ---------- buttons ----------
   "Raised": a 2px bottom edge that compresses on press so the button
   drops. Never a scale transform. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font); font-size: 13.5px; font-weight: 600; line-height: 1.3;
  border-radius: var(--radius-button); padding: 10px 20px; cursor: pointer;
  text-decoration: none;
  transition: background .12s ease, transform .06s ease, box-shadow .06s ease;
}
.btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.btn-primary {
  background: var(--blue); color: var(--on-blue); font-weight: 700;
  padding: 11px 26px;
  border: 1px solid var(--blue-btn-line); box-shadow: var(--edge-raised);
}
.btn-primary:hover { background: var(--blue-btn-line); }
.btn-primary:active { transform: translateY(2px); box-shadow: none; }

.btn-secondary {
  background: var(--card-raised); border: 1px solid var(--line-input); color: var(--ink);
  box-shadow: var(--edge-raised-secondary);
}
.btn-secondary:hover { background: var(--wash-head); }
.btn-secondary:active { transform: translateY(2px); box-shadow: none; }

/* Destructive is the secondary in maroon text — never a maroon fill. */
.btn-destructive { color: var(--maroon-2); }

.btn-lg { font-size: 14.5px; padding: 12px 22px; }
.btn-sm { font-size: var(--text-meta); font-weight: 600; border-radius: var(--radius-tile); padding: 6px 12px; }

.btn.gmail {
  background: var(--brand-gmail); color: var(--on-blue);
  border: 1px solid var(--brand-gmail-line); box-shadow: 0 2px 0 var(--brand-gmail-edge);
}
.btn.outlook {
  background: var(--brand-outlook); color: var(--on-blue);
  border: 1px solid var(--brand-outlook-line); box-shadow: 0 2px 0 var(--brand-outlook-edge);
}
.btn.gmail:active, .btn.outlook:active { transform: translateY(2px); box-shadow: none; }

/* ---------- notices ---------- */
.banner {
  padding: 12px 16px; border-radius: var(--radius-input);
  font-size: 13px; margin-bottom: 16px; background: var(--wash);
}
.banner.error { background: var(--maroon-card); color: var(--maroon); border: 1px solid var(--maroon-line); }

.disconnected-banner {
  display: flex; align-items: center; gap: 14px; margin-bottom: 16px;
  background: var(--maroon-card); border: 1px solid var(--maroon-line);
  border-radius: var(--radius-card); padding: 14px 18px;
  color: var(--maroon); font-size: 13.5px;
}

.badge {
  display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: .02em;
  border-radius: var(--radius-pill); padding: 2px 8px;
}
.badge.status-active { background: var(--green-wash); color: var(--green-text); }
.badge.status-expired, .badge.status-error { background: var(--maroon-wash); color: var(--maroon-2); }
.badge.status-revoked { background: var(--wash); color: var(--ink-3); }

/* ---------- the sign-in card ---------- */
.centered { display: flex; min-height: 100vh; align-items: center; justify-content: center; padding: 24px; }
.login { max-width: 420px; width: 100%; text-align: center; padding: 32px; }
.login-brand { font-family: var(--font-serif); font-size: 21px; font-weight: 600; color: var(--ink); padding-bottom: 4px; }
.login-brand-sub { font-size: var(--text-meta-sm); color: var(--mut); padding-bottom: 8px; }
.provider-buttons { display: flex; flex-direction: column; gap: 10px; margin: 22px 0; }
.fineprint { font-size: var(--text-meta-sm); color: var(--mut); }

/* ---------- the barless shell ----------
   No top bar. The rail is capped by the ☰ tile and the segmented tabs and
   footed by the sync line; the column starts at the very top of the
   window and gets every vertical pixel. */
.shell { display: flex; min-height: 100vh; align-items: stretch; }

.rail {
  width: var(--rail-width); flex: 0 0 var(--rail-width);
  display: flex; flex-direction: column;
  background: var(--card); border-right: 1px solid var(--line);
}
.shell-no-rail .rail { display: none; }

.rail-cap { display: flex; align-items: center; gap: 10px; padding: 14px 16px 12px; }
/* The drawer wrapper is inert above the breakpoint: always open, its
   summary hidden, so the rail is exactly the column it always was. */
.rail-drawer { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.rail-drawer-toggle { display: none; }
.rail-body { flex: 1; overflow-y: auto; padding: 0 12px; }
.rail-foot { padding: 10px 16px 14px; border-top: 1px solid var(--line); }

.column {
  flex: 1; min-width: 0;
  max-width: var(--column-width); margin: 0 auto;
  padding: 22px 24px 64px;
}
/* §1: 760px everywhere, 880px on Operator, whose table needs the room. */
.column-wide { max-width: var(--column-width-wide); }

/* ---------- the ☰ menu ---------- */
.menu { position: relative; }
.menu-tile {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: var(--radius-tile);
  background: var(--card-raised); border: 1px solid var(--line-input);
  color: var(--ink); font-size: 15px; cursor: pointer; list-style: none;
}
.menu-tile::-webkit-details-marker { display: none; }
.menu-tile:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.menu-sheet {
  position: absolute; z-index: 20; top: calc(100% + 6px); left: 0; min-width: 220px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-rail-card); padding: 6px;
  box-shadow: var(--shadow-sheet);
}
.menu-item {
  display: block; width: 100%; text-align: left;
  padding: 8px 10px; border-radius: var(--radius-tile);
  color: var(--ink); font-size: 13.5px; text-decoration: none;
}
.menu-item:hover { background: var(--wash); color: var(--ink); }
.menu-item-button {
  background: none; border: 0; font-family: var(--font); font-size: 13.5px;
  cursor: pointer;
}
.menu-signed-in { padding: 8px 10px 4px; border-top: 1px solid var(--line); margin-top: 4px; }

/* ---------- the segmented tabs ---------- */
.tabs {
  display: flex; flex: 1; gap: 3px; padding: 3px;
  background: var(--wash); border-radius: var(--radius-button);
}
.tab {
  flex: 1; text-align: center; padding: 6px 10px;
  border-radius: var(--radius-tile);
  font-size: 13px; font-weight: 600; color: var(--ink-2); text-decoration: none;
}
.tab:hover { color: var(--ink); }
.tab-active {
  background: var(--card); color: var(--ink);
  box-shadow: var(--edge-segment);
}

/* ---------- the ambient sync line ---------- */
.sync-line { display: flex; align-items: center; gap: 7px; }
.sync-dot {
  width: 7px; height: 7px; border-radius: var(--radius-pill);
  background: var(--green); flex: 0 0 auto;
}



/* ---------- the interim shell (connections and the sign-in page) ---------- */
.app-shell { max-width: 720px; margin: 0 auto; padding: 20px 16px 48px; }
.topbar { display: flex; align-items: center; gap: 12px; padding: 4px 2px 18px; }
.topbar-brand { font-family: var(--font-serif); font-size: 18px; font-weight: 600; color: var(--ink); flex: 1; }
.topbar-brand a { color: inherit; }
.topbar form { margin: 0; }
.app-main { display: flex; flex-direction: column; gap: 16px; }
.section-title { font-family: var(--font-serif); font-size: var(--text-title); font-weight: 600; color: var(--ink); margin: 0 0 12px; }

.connection-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.connection-row:last-of-type { border-bottom: none; }
.connection-row > div:first-child { flex: 1; }
.connection-name { font-family: var(--font-serif); font-size: 14.5px; font-weight: 600; color: var(--ink); }

/* The Connections pill (§8): green when the robot can reach it, maroon when
   it cannot. Same shape as .badge, but keyed on a fact rather than on a
   provider's status vocabulary. */
.pill {
  display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: .02em;
  border-radius: var(--radius-pill); padding: 2px 8px;
}
.pill-connected, .pill-green { background: var(--green-wash); color: var(--green-text); }
.pill-disconnected, .pill-maroon { background: var(--maroon-wash); color: var(--maroon-2); }
.pill-blue { background: var(--blue-wash); color: var(--blue); }
.pill-grey { background: var(--wash); color: var(--ink-3); }

/* An honest card, and the not-set-up agent address: dashed rather than
   hairline, because the state is an absence rather than a thing. */
.card-dashed { border-style: dashed; background: transparent; }

/* §8: the word "Saved" beside the button, not a banner above the form. */
.saved-marker { font-size: var(--text-meta); font-weight: 600; color: var(--green-text); }

/* §8's link control: two inputs and an Insert, revealed by the toolbar's
   link button. Built by editor.js, styled here. */
.editor-link-row {
  display: flex; gap: 8px; align-items: center;
  padding: 8px 10px; border-bottom: 1px solid var(--line);
  background: var(--wash-head);
}
.editor-link-row .field-input { flex: 1 1 auto; min-width: 0; }

/* Preview is a button (§8). <details> is the button, and copy.js swaps
   its label between the two states. */
.signature-preview { margin-top: 14px; }
.signature-preview > summary { display: inline-flex; list-style: none; cursor: pointer; }
.signature-preview > summary::-webkit-details-marker { display: none; }

/* A section within a panel — what the voice profile and the taught rules
   became when §8 cut the rail to four tabs. */
.settings-section { padding-top: 20px; margin-top: 20px; border-top: 1px solid var(--line); }
.section-subtitle {
  font-family: var(--font-serif); font-size: 15px; font-weight: 600;
  color: var(--ink); margin: 0 0 8px;
}

/* ---------- the queue ---------- */
.rail-list { padding: 4px 0 12px; }
.rail-heading {
  font-family: var(--font-serif); font-size: 13px; font-weight: 600;
  color: var(--ink-2); margin: 14px 4px 8px;
}
.rail-card {
  display: block; padding: 11px 13px; margin-bottom: 7px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-rail-card); color: inherit; text-decoration: none;
}
.rail-card:hover { border-color: var(--line-input); color: inherit; }
.rail-card-selected { border: 1.5px solid var(--blue); background: var(--blue-wash); }
.rail-card-head { display: flex; align-items: baseline; gap: 8px; }
.rail-card-from {
  font-family: var(--font-serif); font-size: 14px; font-weight: 600;
  color: var(--ink); flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail-card-when { flex: 0 0 auto; font-size: var(--text-meta-sm); }
.rail-card-subject { font-size: 13.5px; color: var(--ink-body); margin-top: 2px; }
.rail-card-why { font-size: var(--text-meta-sm); margin-top: 3px; }

/* A card is a link plus its hide control, side by side — the control is its
   own form so it works with the script absent. */
.rail-card { display: flex; align-items: flex-start; gap: 6px; }
.rail-card-body { flex: 1; min-width: 0; color: inherit; text-decoration: none; }
.rail-card-body:hover { color: inherit; }
/* Honest cards: never a fake draft, and dashed so you can see that. */
.rail-card-honest { border: 1px dashed var(--line-dashed); }
.rail-card-dismiss { margin: 0; }
.card-dismiss {
  background: none; border: 0; cursor: pointer; padding: 0 2px;
  color: var(--mut); font-family: var(--font); font-size: 13px; line-height: 1;
}
.card-dismiss:hover { color: var(--maroon-2); }
.card-dismiss:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
/* Hiding a queue card is not discarding it: the eye-slash says "out of my
   queue", where ✕ read as "delete". The mailbox is untouched either way,
   and the title says so. */
.card-hide {
  background: none; border: 0; cursor: pointer; padding: 2px;
  display: flex; align-items: center; color: var(--mut); line-height: 0;
}
.card-hide:hover { color: var(--blue); }
.card-hide:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.rail-more { display: block; padding: 8px 6px 12px; font-size: var(--text-meta); }
.rail-more-link { color: var(--blue); }

/* Others: the demoted and the finished, folded into one group that opens
   where it sits. A <details>, so it costs no request and no script. */
.rail-others { margin-top: 14px; }
.rail-others-summary {
  cursor: pointer; list-style: none;
  font-family: var(--font-serif); font-size: 13px; font-weight: 600;
  color: var(--ink-2); padding: 4px 4px 8px;
}
.rail-others-summary::-webkit-details-marker { display: none; }
.rail-others-summary:hover { color: var(--ink); }
.rail-others-summary:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
/* One of the arrows docs/guides/web.md allows by name, turned rather than
   swapped for a second glyph. */
.rail-caret {
  display: inline-block; color: var(--mut); font-weight: 400;
  margin-right: 4px; transition: transform 120ms ease;
}
.rail-others[open] .rail-caret { transform: rotate(90deg); }

/* An empty Primary is a state, not an absence: dashed like the honest
   card, and it says when the robot last looked so "nothing" is legible. */
.rail-nothing {
  padding: 16px 14px; margin-bottom: 7px;
  border: 1px dashed var(--line-dashed); border-radius: var(--radius-rail-card);
}
.rail-nothing p { margin: 0; }
.rail-nothing-head {
  font-family: var(--font-serif); font-size: 14px; font-weight: 600;
  color: var(--ink); margin-bottom: 3px;
}
.rail-nothing .muted { font-size: var(--text-meta); }

/* ---------- the review column ---------- */
.inbound-card {
  background: var(--wash); border-radius: var(--radius-card);
  padding: 18px 20px; margin-bottom: 18px;
}
/* Subject, then when, then who — the order somebody scans a message in.
   The count sits opposite the subject: how many turns are in here is a
   fact about the card, not about the message under it. */
.inbound-header { display: flex; align-items: baseline; gap: 12px; }
.inbound-subject {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--font-serif); font-size: var(--text-title); font-weight: 600;
  color: var(--ink); margin: 0;
}
.inbound-count { flex: 0 0 auto; font-size: var(--text-meta-sm); }

/* The sender's own sign-off: name, role, then address · phone. Quiet,
   because it is provenance rather than content. */
.sender-signature { margin-top: 10px; font-size: var(--text-meta); }
.inbound-from {
  font-family: var(--font-serif); font-size: 15px; font-weight: 600;
  color: var(--ink); margin-top: 2px;
}

.ticket-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--line); color: inherit;
}
.ticket-row:hover .ticket-subject { color: var(--blue); }
.ticket-row:last-of-type { border-bottom: none; }
.ticket-row > div:first-child { flex: 1; }
.ticket-subject { font-family: var(--font-serif); font-size: 14.5px; font-weight: 600; color: var(--ink); }
.inbound-cc { font-size: var(--text-meta-sm); margin-top: 2px; }

/* The latest message's own quoted trail, under its signature block.
   Collapsed by default: the reviewer asked for one message, and the
   history inside it is context they can call for. The rows above the
   separator are a different mechanism and are never hidden. */
.message-history { margin: 10px 0 0; }
.nested-trail {
  margin: 8px 0 0; padding: 0;
  font-family: inherit; font-size: var(--text-meta);
  color: var(--ink-3); white-space: pre-wrap; overflow-wrap: anywhere;
}
.message-history-summary {
  cursor: pointer; list-style: none;
  font-size: var(--text-meta); color: var(--blue);
}
.message-history-summary::-webkit-details-marker { display: none; }
.message-history-summary:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.message-history-rows { margin-top: 6px; }

.message-row { border-top: 1px solid var(--line); }
.message-row:first-child { border-top: none; }
.message-row-summary {
  display: flex; align-items: baseline; gap: 8px;
  cursor: pointer; list-style: none; padding: 7px 0;
  font-size: var(--text-meta);
}
.message-row-summary::-webkit-details-marker { display: none; }
.message-row-summary:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.message-row-sender {
  flex: 0 0 auto; font-family: var(--font-serif); font-weight: 600; color: var(--ink);
}
/* The snippet yields first: the sender and the time are what a reviewer
   scans, and a long one would push them off the row. */
.message-row-snippet {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.message-row-when { flex: 0 0 auto; font-size: var(--text-meta-sm); }
.message-row-body { padding: 2px 0 10px; }

/* The turn the robot answered, marked so the last history row and the
   body below it cannot read as one message. */
.latest-separator {
  margin: 12px 0 10px; padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: var(--text-meta); color: var(--ink-3);
}

/* Attachment chips: the files, not the bytes — each is a link back to
   the mailbox that still holds the original. */
/* A list, because that is what it is — but the chips are the markers, so
   the browser's own bullets go. */
.attachment-chips {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px;
  list-style: none; padding-left: 0;
}
.attachment-chip {
  display: inline-flex; align-items: baseline; gap: 8px;
  background: var(--card-raised); border: 1px solid var(--line-input);
  border-radius: var(--radius-pill); padding: 6px 12px;
  font-size: var(--text-meta); color: var(--ink-body);
}
.attachment-chip:hover { border-color: var(--blue-line); color: var(--blue); }
.attachment-chip:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.attachment-chip-size { font-size: var(--text-meta-sm); }

/* Real mail carries 1000-character tracking URLs, table layouts, and
   images sized for a desktop client. Anything that renders somebody
   else's markup keeps it inside the card. */
.message-body {
  color: var(--ink-body); margin: 12px 0 0;
  overflow-wrap: anywhere; word-break: break-word;
}
.message-body img { max-width: 100%; height: auto; }
.message-body table { max-width: 100%; border-collapse: collapse; }
.message-body p { margin: 0 0 8px; }
.message-body p:last-child { margin-bottom: 0; }
.message-body blockquote {
  margin: 8px 0; padding-left: 12px;
  border-left: 2px solid var(--blue-line); color: var(--ink-2);
}

/* The draft card: the assembled email, editable. Never a summary card. */
.draft-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-card); padding: 18px 20px;
}
/* position: relative so the recipient panel can hang under the box it
   was opened from without joining this row's flex flow. */
.field-row {
  display: flex; align-items: center; gap: 10px; padding: 6px 0;
  position: relative;
}
.field-label {
  flex: 0 0 62px; font-size: var(--text-meta); color: var(--ink-3);
}
.field-input {
  flex: 1; min-width: 0; font-family: var(--font); font-size: 13.5px;
  color: var(--ink-body); background: var(--card-raised);
  border: 1px solid var(--line-input); border-radius: var(--radius-button);
  padding: 8px 12px;
}
.field-input:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
/* Why these recipients — quiet, blue, and never quoting the mail. */
.provenance {
  color: var(--blue); font-size: var(--text-meta-sm);
  padding: 0 0 6px 72px;
}
.copies { padding: 2px 0 6px; }
.copies-toggle {
  cursor: pointer; font-size: var(--text-meta-sm); padding: 2px 0 2px 72px;
  list-style: none;
}
.copies-toggle::-webkit-details-marker { display: none; }

/* The second signature editor, opened only when a member asks for one.
   The summary is plain text and the checkbox sits inside the body (#92):
   a browser never toggles a details from a click on an interactive
   descendant of its summary, so a checkbox in there left nothing that
   opened the disclosure. Two controls, and they cannot disagree — the
   checkbox is the only thing that posts, and `open` comes from what was
   saved. */
.signature-reply { margin: 10px 0 4px; }
.signature-reply > summary {
  padding-left: 0; cursor: pointer; list-style: none;
}
.signature-reply > summary::-webkit-details-marker { display: none; }
.signature-reply > summary:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* ---------- the recipient panel ----------
   Markup the server rendered, dropped under the box a member is typing
   in. Absolutely positioned so it overlays what is below rather than
   pushing the draft card down every time somebody touches the To line —
   a card that jumps as you type is a card you stop typing in. */
.recipient-panel {
  position: absolute; top: calc(100% - 2px); left: 72px; right: 0; z-index: 20;
  background: var(--card); border: 1px solid var(--line-input);
  border-radius: var(--radius-button); padding: 8px 0 4px;
  box-shadow: var(--shadow-sheet);
}
.recipient-panel-head {
  font-size: var(--text-meta-sm); padding: 0 12px 6px;
}
.recipient-panel-list { list-style: none; margin: 0; padding: 0; }
.recipient-panel-row a {
  display: flex; align-items: baseline; gap: 8px;
  padding: 7px 12px; text-decoration: none; color: var(--ink-body);
  font-size: 13.5px;
}
.recipient-panel-row a:hover { background: var(--blue-wash); }
.recipient-panel-row a:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.recipient-panel-name { color: var(--ink); }
.recipient-panel-address { font-size: var(--text-meta-sm); }
.recipient-panel-note {
  color: var(--maroon-2); font-size: var(--text-meta-sm); padding: 0 12px 6px;
}
.recipient-panel-close {
  display: inline-block; padding: 6px 12px 2px;
  font-size: var(--text-meta-sm); text-decoration: none;
}

/* The compose pane: body, signature, quoted thread — one surface, in the
   order a mail client puts them. The textarea gives up its own border to
   the pane so nothing reads as a divider between what you wrote and the
   thread you are answering. */
.compose-pane {
  margin-top: 10px; background: var(--card-raised);
  border: 1px solid var(--line-input); border-radius: var(--radius-button);
  padding: 12px 14px;
}
.compose-pane:focus-within { outline: 2px solid var(--blue); outline-offset: 1px; }
.draft-editor {
  width: 100%; display: block; padding: 0; background: none; border: 0;
  font-family: var(--font); font-size: 13.5px; line-height: 1.55;
  color: var(--ink-body); resize: vertical;
}
.draft-editor:focus-visible { outline: none; }
/* display: block above wins over the browser's own [hidden] rule, so the
   textarea editor.js hides has to be hidden here or it shows twice. */
.draft-editor[hidden] { display: none; }
/* The contenteditable editor.js puts in the textarea's place. Same face,
   same size, same colour: switching the script on must not make somebody's
   draft look like a different draft. */
.draft-editor-rich { min-height: 260px; outline: none; }
/* §8's signature editors: their own minimums, and resizable by the corner
   rather than only vertically. A signature is a small block, and 260px of
   empty box above the buttons reads as a field somebody failed to fill. */
.settings-signature-editor { min-width: 320px; min-height: 190px; resize: both; overflow: auto; }
.settings-signature-editor-reply { min-height: 150px; }
.draft-editor-rich p { margin: 0 0 12px; }
.draft-editor-rich ul, .draft-editor-rich ol { margin: 0 0 12px; padding-left: 22px; }
.draft-editor-rich a { color: var(--blue); }
/* A signature stacks tight. The rule above is the draft body's, and a
   signature is written in the same rich editor — so a three-line block
   arrived with 12px between every line, in the editor, in the "How it
   lands" preview, and in the assembled mail. The name, the address and
   the phone number are one block, not three paragraphs. Covers markup
   already stored as <p> by members who signed up before this landed,
   which is why there is no data migration. */
.settings-signature-editor p, .draft-signature p { margin: 0; }

/* The formatting strip. Shipped inert in the markup and revealed by the
   script, so a browser without it shows no controls rather than controls
   that do nothing. Sits on the pane's own head wash with a hairline under
   it — a strip, not a card. */
.editor-toolbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin: -12px -14px 10px; padding: 6px 10px;
  background: var(--wash-head); border-bottom: 1px solid var(--line);
  border-radius: var(--radius-button) var(--radius-button) 0 0;
}
.editor-toolbar[hidden] { display: none; }
.editor-btn {
  min-width: 28px; height: 28px; padding: 0 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); border: 1px solid var(--line-input);
  border-radius: var(--radius-tile); color: var(--ink);
  font-family: var(--font); font-size: var(--text-meta); cursor: pointer;
}
.editor-btn:hover { background: var(--wash); }
.editor-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.editor-font, .editor-size {
  height: 28px; background: var(--card); color: var(--ink);
  border: 1px solid var(--line-input); border-radius: var(--radius-tile);
  font-family: var(--font); font-size: var(--text-meta); padding: 0 6px;
}
.editor-colour {
  width: 28px; height: 28px; padding: 2px; cursor: pointer;
  background: var(--card); border: 1px solid var(--line-input);
  border-radius: var(--radius-tile);
}

.action-row { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.action-row form { margin: 0; }
.action-caption { flex: 1; min-width: 220px; font-size: var(--text-meta-sm); }
.publish-actions { display: flex; align-items: center; gap: 14px; margin-top: 12px; }
.publish-actions .muted { flex: 1; }

/* Outgoing attachments: the chips, and the form that adds one. The form
   sits outside the save form — an upload is multipart and a save is not,
   and HTML cannot nest the two. */
.draft-attachments { margin-top: 12px; }
.draft-attachments .attachment-chips { margin-top: 0; }
.draft-attachments .attachment-chip:hover { border-color: var(--line-input); color: var(--ink-body); }
.attachment-chip-remove {
  background: none; border: 0; padding: 0 0 0 2px; cursor: pointer;
  color: var(--ink-2); font-family: var(--font); font-size: var(--text-meta-sm);
  line-height: 1;
}
.attachment-chip-remove:hover { color: var(--maroon); }
.attachment-chip-remove:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.attachment-chip form { display: inline; margin: 0; }
.attach-form { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.attach-input { font-family: var(--font); font-size: var(--text-meta); color: var(--ink-body); max-width: 100%; }
/* editor.js flags the root once the toolbar's Attach label is live, so
   one card carries one Attach control. The flag is on the root because
   this form sits inside the subtree an upload swaps out, and a class put
   on the form itself would vanish with the first file. Clipped, never
   display: none — a label cannot open an input the browser has removed
   from the box tree, and that input is what the label exists to open. */
.has-editor-attach .attach-form {
  position: absolute; width: 1px; height: 1px; margin: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.draft-attachments-error {
  margin: 0 0 8px; padding: 8px 10px;
  background: var(--maroon-card); color: var(--maroon);
  border: 1px solid var(--maroon-line); border-radius: var(--radius-tile);
  font-size: var(--text-meta);
}
/* The toolbar's Attach is a label pointing at the input below, and the
   input stays on screen rather than being hidden behind it. The toolbar
   itself is hidden until the editor script runs, so a control that lived
   only there would take attaching a file away from a browser with no
   script — and a file input hidden well enough to look tidy is one a
   label can no longer open. Two affordances for one act, deliberately:
   the redundancy is what makes the act unconditional. */

/* The instruction box. No canned chips — the note under it is the
   product's promise that manual edits survive a redraft.

   The prompt: box on the left, Submit and the mic stacked on the right, the
   way a chat composer reads. Below the stack breakpoint the controls drop
   under the box rather than squeezing it. */
.instruction-form { margin-top: 16px; }
.prompt { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: start; }
.prompt-controls { display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.prompt-controls .dictate-status { text-align: center; }
.instruction-box {
  width: 100%; font-family: var(--font); font-size: 13.5px; line-height: 1.5;
  color: var(--ink-body); background: var(--card);
  border: 1px solid var(--line-input); border-radius: var(--radius-input);
  box-shadow: var(--shadow-inset-input); padding: 12px 14px; resize: vertical;
}
.instruction-box:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.edits-kept { margin: 8px 2px 10px; font-size: var(--text-meta-sm); }

/* The honest card: an offer to write, never a written reply. */
.honest-card {
  background: var(--card); border: 1px dashed var(--line-dashed);
  border-radius: var(--radius-card); padding: 18px 20px;
}
.honest-headline {
  font-family: var(--font-serif); font-size: var(--text-title); font-weight: 600;
  color: var(--ink); margin: 0 0 6px;
}

/* The signature and the quoted thread, inside the pane and in the order
   they will land. Both break long tokens: a real signature carries
   tracking URLs that would otherwise run past the card. */
.draft-signature {
  margin-top: 14px; color: var(--ink-body); font-size: 13.5px;
  overflow-wrap: anywhere; word-break: break-word;
}
.draft-signature img { max-width: 100%; height: auto; }
.signature-note { margin: 6px 2px 0; font-size: var(--text-meta-sm); }
.quoted-thread {
  margin: 16px 0 0; padding-left: 12px;
  border-left: 2px solid var(--blue-line); color: var(--ink-2);
  font-size: 13px; overflow-wrap: anywhere; word-break: break-word;
}

/* ---------- settings ----------
   The rail becomes the sub-tab list; the panel fills the column. Same
   anatomy as the queue, so settings looks like a place in the product
   rather than a modal bolted onto it. */
.settings-back { display: block; padding: 10px 6px 4px; font-size: var(--text-meta); }
.settings-tabs { display: flex; flex-direction: column; gap: 2px; padding-bottom: 12px; }
.settings-tab {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 10px; border-radius: var(--radius-tile);
  color: var(--ink-2); font-size: 13.5px; text-decoration: none;
}
.settings-tab:hover { background: var(--wash); color: var(--ink); }
.settings-tab-active {
  background: var(--blue-wash); color: var(--ink); font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--blue-line);
}
.settings-tab-count {
  background: var(--maroon-wash); color: var(--maroon-2);
  border-radius: var(--radius-pill); padding: 1px 7px; font-size: 11px; font-weight: 600;
}

.checkline { display: flex; align-items: center; gap: 8px; padding: 6px 0; font-size: 13.5px; }

/* The signature in context: tinted so it reads as a preview, not a second
   editor a member might type into. */
.in-context {
  margin-top: 16px; padding: 14px 16px;
  background: var(--wash); border-radius: var(--radius-input);
  color: var(--ink-body); font-size: 13.5px;
}
.in-context-label {
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  margin-bottom: 8px;
}

.rule-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.rule-row:last-of-type { border-bottom: none; }
.rule-row > div:first-child { flex: 1; }
.rule-row form { margin: 0; }
.rule-label { font-family: var(--font-serif); font-size: 14.5px; font-weight: 600; color: var(--ink); }

.plain-list { margin: 10px 0; padding-left: 18px; color: var(--ink-body); font-size: 13.5px; }
.plain-list li { margin-bottom: 6px; }

/* ---------- compose ---------- */
.new-email-button { display: block; text-align: center; margin: 8px 0 4px; }
.rail-foot-note { padding: 14px 6px 6px; font-size: var(--text-meta-sm); }

.chat { margin-bottom: 18px; }
/* §6's asymmetry: what the member said is a right-aligned wash bubble,
   capped so a long instruction still reads as one side of an exchange;
   what the robot said is unbubbled prose, because it is reporting on the
   draft below rather than chatting back. */
.chat-turn { margin-bottom: 12px; }
.chat-turn-user {
  max-width: 80%; margin-left: auto;
  padding: 12px 16px; border-radius: var(--radius-card);
  background: var(--wash); color: var(--ink-body); text-align: left;
}
.chat-turn-robot { padding: 0 2px; }
.chat-who { font-size: var(--text-meta-sm); margin-bottom: 4px; }
.chat-text { font-size: 13.5px; }

/* The chat input. Empty, the shell is one line and no taller than its
   buttons; non-empty, the text takes the full width and the controls drop
   beneath it. chatinput.js sets data-filled — with no script the box
   renders filled, which costs the polish and no capability. */
.chat-input { margin-top: 4px; }
.chat-input[data-filled="false"] .prompt { align-items: center; }
/* "No taller than its buttons" means the buttons sit beside each other,
   not stacked — a column of two is two rows tall whatever the box does. */
.chat-input[data-filled="false"] .prompt-controls {
  flex-direction: row; align-items: center;
}
.chat-input[data-filled="false"] .instruction-box {
  min-height: 0; height: 40px; padding-top: 9px; resize: none; overflow: hidden;
}
.chat-input[data-filled="true"] .prompt { grid-template-columns: 1fr; }
.chat-input[data-filled="true"] .prompt-controls {
  flex-direction: row; align-items: center; justify-content: flex-end;
}
.chat-input[data-filled="true"] .instruction-box { max-height: 15em; overflow-y: auto; }

/* ---------- dictation ----------
   The mic is created by the script, never by a template: a browser
   with JavaScript off shows a textarea that already worked, rather than
   a button that does nothing. It dictates the instruction to the robot —
   there is deliberately no dictation on the email body. */
.dictate-row { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.dictate {
  display: flex; align-items: center; justify-content: center;
  background: var(--card-raised); border: 1px solid var(--line-input);
  border-radius: var(--radius-tile); color: var(--ink);
  padding: 6px 10px; cursor: pointer; line-height: 0;
}
.dictate:hover { background: var(--wash-head); }
.dictate:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.dictate-recording { color: var(--maroon-2); border-color: var(--maroon-line); }
.dictate-status { font-size: var(--text-meta-sm); }

/* ---------- toasts ----------
   One pill, green dot, gone in a few seconds. Confirmations only: a
   message about something the member did not just do belongs in a banner
   that stays, where they can read it in their own time. */
.toasts { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.toast {
  display: flex; align-items: center; gap: 9px; margin: 0;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius-pill); padding: 9px 16px;
  font-size: 13.5px; color: var(--ink-body);
  box-shadow: var(--shadow-sheet);
  transition: opacity .24s ease;
}
.toast-dot {
  width: 7px; height: 7px; border-radius: var(--radius-pill);
  background: var(--green); flex: 0 0 auto;
}
.toast-error { border-color: var(--maroon-line); color: var(--maroon); }
.toast-error .toast-dot { background: var(--maroon-2); }
.toast-going { opacity: 0; }

/* ---------- the receipt strip ----------
   What state the draft is in, above the card it describes. Quiet by
   default; maroon when it is a refusal rather than a record, because
   "this cannot be sent" is the one line here somebody has to act on. */
.receipt-strip {
  margin: 0 0 10px; padding: 8px 14px;
  background: var(--wash); border-radius: var(--radius-input);
  font-size: var(--text-meta); color: var(--ink-3);
}
.receipt-strip-blocked {
  background: var(--maroon-card); border: 1px solid var(--maroon-line);
  color: var(--maroon);
}

/* ---------- the busy treatment ----------
   On the control that was pressed, never on the page: a member who
   clicked Save needs to know Save is working, and a whole-page veil
   tells them the product is working, which they can see. */
/* §10's busy treatment, and only on the control that was pressed: wash
   fill, the hard edge removed, a 14px spinner in place of any icon, the
   label at 70% opacity, pointer events off. No page-level spinner and no
   skeletons — a veil over everything tells a member the product is busy,
   which they can already see. */
.is-busy, .htmx-request {
  background: var(--wash) !important;
  border-color: transparent !important;
  box-shadow: none !important;
  color: var(--ink-2) !important;
  pointer-events: none;
  position: relative;
}
.is-busy > *, .htmx-request > * { opacity: .7; }
.is-busy::before, .htmx-request::before {
  content: ""; display: inline-block;
  width: 14px; height: 14px; margin-right: 8px;
  border-radius: var(--radius-pill);
  border: 2px solid var(--line-input); border-top-color: var(--blue);
  animation: busy-spin .6s linear infinite;
}
@keyframes busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .is-busy::before, .htmx-request::before { animation-duration: 2.4s; }
}

/* The one banner louder than the disconnected one: somebody else's mail
   is on screen, and it says so until the look ends. */
/* §9: dark, spanning the top of the app. Not a wash strip inside the
   column — an operator who forgets whose mail they are reading is what a
   read-only session exists to prevent, and a banner sharing the column's
   width reads as one more notice among the notices. */
.impersonation-banner {
  display: flex; align-items: center; gap: 14px;
  background: var(--banner-dark); color: var(--on-banner-dark);
  padding: 12px 24px; font-size: 13.5px;
}
.impersonation-banner span { flex: 1; }

/* The first-login progress line. Quiet: it is information, not a problem. */
.progress-banner {
  display: flex; flex-direction: column; gap: 4px; margin-bottom: 16px;
  background: var(--wash); border-radius: var(--radius-card);
  padding: 12px 18px; font-size: 13.5px; color: var(--ink-body);
}

/* ---------- the operator console ----------
   A table, and only a table: every cell is a count, a status, or a date,
   so nothing here needs the card treatment the mail surfaces use. */
.console { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 13.5px; }
.console th {
  text-align: left; padding: 8px 10px 8px 0;
  border-bottom: 1px solid var(--line);
  color: var(--mut); font-size: var(--text-meta-sm);
  font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
.console td {
  padding: 12px 10px 12px 0; border-bottom: 1px solid var(--line);
  color: var(--ink-body); vertical-align: top;
}
.console tr:last-of-type td { border-bottom: none; }
.console-member { font-family: var(--font-serif); font-weight: 600; color: var(--ink); }
.console-action { text-align: right; }
.console-action form { margin: 0; }
.console-note { margin-top: 16px; }

/* ---------- small screens ----------
   Beyond the requirements document, which lists mobile layouts as out of
   scope (§10). Everything here is additive: no capability appears or
   disappears at the breakpoint, and the whole block could be deleted
   without touching anything above it.

   Last in the file on purpose. A media query adds no specificity, so
   these override by source order alone — sitting above the component
   rules, half of them silently lost.

   The rail stacks above the column as a drawer, the draft card's label
   and field stop competing for one line, the toolbar wraps rather than
   scrolling sideways, and every control is at least a fingertip. */
@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .rail {
    width: 100%; flex: 0 0 auto;
    border-right: 0; border-bottom: 1px solid var(--line);
  }
  .rail-body { max-height: 42vh; }
  .column { max-width: 100%; padding: 18px 16px 48px; }
  /* The prompt's controls drop under the box rather than squeezing it. */
  .prompt { grid-template-columns: 1fr; }
  .prompt-controls { flex-direction: row; align-items: center; }

  /* The drawer's own bar. A summary, so closing it needs no script. */
  .rail-drawer-toggle {
    display: flex; align-items: center; justify-content: space-between;
    min-height: var(--tap-target);
    padding: 10px 16px; margin: 0 4px 4px;
    border-radius: var(--radius-tile); background: var(--wash);
    color: var(--ink-2); font-size: 13.5px; font-weight: 600;
    cursor: pointer; list-style: none;
  }
  .rail-drawer-toggle::-webkit-details-marker { display: none; }
  .rail-drawer-toggle::after { content: "↓"; }
  .rail-drawer[open] > .rail-drawer-toggle::after { content: "↑"; }
  .rail-drawer-toggle:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

  /* One column: a fixed-width label beside a field leaves nothing for
     the field on a phone. */
  .field-row { flex-direction: column; align-items: stretch; gap: 4px; }
  .field-label { flex: 0 0 auto; text-align: left; }
  /* The sender yields before the timestamp leaves the card. */
  .message-row-sender { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .connection-row { flex-wrap: wrap; }
  .inbound-header { flex-direction: column; align-items: flex-start; gap: 2px; }

  /* The toolbar wraps to a second row rather than scrolling sideways —
     a control off the edge of a phone is a control nobody finds. */
  .editor-toolbar { flex-wrap: wrap; row-gap: 4px; }
  .editor-link-row { flex-wrap: wrap; }
  .action-row { flex-wrap: wrap; row-gap: 8px; }

  /* A fingertip, everywhere. The glyph buttons are the ones that were
     nowhere near it. */
  .btn, .menu-item, .tab, .settings-tab { min-height: var(--tap-target); }
  .editor-btn, .card-hide, .card-dismiss {
    min-width: var(--tap-target); min-height: var(--tap-target);
  }
  .menu-sheet { min-width: min(280px, calc(100vw - 32px)); }
}
