/* ⚠️ THE SEND SCREEN'S CSS IS NOT IN THIS FILE ANY MORE — css/send-kit.css.
   339 rules for .bx-sendhero / .bx-mailframe / .bx-sched / .bx-wm-* /
   .bx-cal-* / .bx-sent-* / .bx-mailfull-* moved out with js/send-kit.js, so the
   marketplace and work.runmai.app render the same screen from the same rules.
   Adding a send-screen rule back here would style it in ONE of the two apps,
   which is indistinguishable from the rule not working. The shared chrome
   (.bx-sheet-*, .bx-btn, .bx-input, .bx-pick-row) is still here, because a dozen
   other sheets use it. */
/* ═══════════════════════════════════════════════════════════════════════════
   App Registry (#/admin) + the app editor sheet.

   A separate file on purpose: css/styles.css and css/browse.css are both being
   edited in another session, and nothing in here needs to reach into either.
   The editor sheet reuses .bx-sheet / .bx-field / .bx-input from browse.css and
   only adds the two blocks that are new (the app header and the tag pickers).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Header ───────────────────────────────────────────────────────────────── */
.reg-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin: 0 0 22px;
}
.reg-head h1 { margin: 0 0 6px; letter-spacing: -0.02em; }
.reg-sub { margin: 0; color: var(--muted, #64748b); font-size: 14.5px; line-height: 1.6; max-width: 74ch; }

/* ── The list ─────────────────────────────────────────────────────────────
   A list, not a table: every row has a logo, two lines of text and a wrapping
   set of chips, none of which a <td> lays out well. Grid columns keep the
   type / tags / date / action lanes aligned down the page anyway. */
.reg-list {
  display: flex; flex-direction: column; gap: 10px;
}
.reg-row {
  display: grid;
  grid-template-columns: minmax(210px, 1.5fr) 104px minmax(200px, 2fr) 128px 40px;
  gap: 18px; align-items: center;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
  transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.reg-row:hover {
  border-color: #cbd5e1;
  box-shadow: 0 6px 20px rgba(15, 23, 42, .07);
}

/* App identity — logo + name + what it is */
.reg-id {
  display: flex; align-items: center; gap: 13px;
  min-width: 0; text-decoration: none; color: inherit;
}
.reg-id-text { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.reg-name {
  font-size: 15.5px; font-weight: 700; color: var(--ink, #0f172a);
  letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.reg-id:hover .reg-name { color: var(--brand, #0b63a6); }
.reg-desc {
  font-size: 12.5px; color: var(--muted, #64748b); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Type — one quiet chip, tinted per type so the column reads at a glance */
.reg-type {
  justify-self: start;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 5px 10px; border-radius: 999px; white-space: nowrap;
  background: #f1f5f9; color: #475569;
}
.reg-type[data-type="data"]       { background: #e0f2fe; color: #075985; }
.reg-type[data-type="workflow"]   { background: #dcfce7; color: #15803d; }
.reg-type[data-type="automation"] { background: #ede9fe; color: #6d28d9; }
.reg-type[data-type="dashboard"]  { background: #fef3c7; color: #92400e; }
.reg-type[data-type="tracker"]    { background: #ccfbf1; color: #115e59; }
.reg-type[data-type="admin"]      { background: #ffe4e6; color: #9f1239; }

/* Departments + roles — each one navigates to its own page */
.reg-tags { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.reg-tagline { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.reg-tagkind {
  font-size: 9.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  color: #94a3b8; margin-right: 2px;
}
.reg-tag {
  font-size: 11.5px; font-weight: 600; color: #475569;
  background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 7px;
  padding: 3px 8px; text-decoration: none; white-space: nowrap;
  transition: background .13s ease, border-color .13s ease, color .13s ease;
}
.reg-tag:hover { background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8; }
.reg-none { font-size: 12px; color: #94a3b8; font-style: italic; }

/* Updated — label above, date below, both left-aligned in their own lane.
   The old table had this indented under a wide header and it read as a stray. */
.reg-updated { display: flex; flex-direction: column; gap: 2px; }
.reg-updated-lbl {
  font-size: 9.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  color: #94a3b8;
}
.reg-updated time { font-size: 13px; font-weight: 600; color: #334155; white-space: nowrap; }

/* Edit */
.reg-edit {
  width: 34px; height: 34px; border-radius: 10px;
  display: grid; place-items: center;
  background: #fff; border: 1px solid var(--line, #e2e8f0);
  color: #64748b; cursor: pointer;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.reg-edit:hover { background: #0f172a; border-color: #0f172a; color: #fff; }
.reg-edit:focus-visible { outline: 2px solid var(--brand, #0b63a6); outline-offset: 2px; }
.reg-edit-gap { width: 34px; }

.reg-acts { display: flex; gap: 8px; }

/* ── Multi-select: pick apps, then hand them out in bulk ──────────────────── */
.reg-list.is-editing .reg-row {
  grid-template-columns: 24px minmax(190px, 1.5fr) 100px minmax(180px, 2fr) 132px 76px;
  gap: 16px;
}
.reg-pick, .reg-selall {
  background: none; border: 0; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 9px;
  font: inherit; color: var(--muted, #64748b);
}
.reg-selall { font-size: 13px; font-weight: 650; }
.reg-selall:hover { color: var(--ink, #0f172a); }
.reg-box {
  width: 20px; height: 20px; flex: 0 0 20px; border-radius: 6px;
  border: 1.5px solid #cbd5e1; background: #fff;
  display: grid; place-items: center;
  transition: background .13s ease, border-color .13s ease;
}
.reg-box i { font-size: 10px; color: #fff; opacity: 0; transition: opacity .13s ease; }
.reg-pick:hover .reg-box, .reg-selall:hover .reg-box { border-color: #94a3b8; }
.reg-pick.is-on .reg-box, .reg-selall.is-on .reg-box {
  background: var(--brand, #0b63a6); border-color: var(--brand, #0b63a6);
}
.reg-pick.is-on .reg-box i, .reg-selall.is-on .reg-box i { opacity: 1; }
.reg-pick:focus-visible, .reg-selall:focus-visible { outline: 2px solid var(--brand, #0b63a6); outline-offset: 3px; }
.reg-row.is-picked {
  border-color: var(--brand, #0b63a6);
  box-shadow: 0 0 0 1px var(--brand, #0b63a6), 0 6px 20px rgba(11, 99, 166, .12);
}

/* The bulk bar. Sticks under the header so a long selection stays actionable. */
.reg-bulk {
  position: sticky; top: 8px; z-index: 4;
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; margin: 0 0 14px;
  background: #0f172a; color: #fff;
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, .22);
}
.reg-bulk[hidden] { display: none; }
.reg-bulk-count { font-size: 13.5px; font-weight: 700; letter-spacing: -0.01em; }
.reg-bulk .bx-btn-ghost { color: #cbd5e1; border-color: rgba(255, 255, 255, .22); background: transparent; }
.reg-bulk .bx-btn-ghost:hover { color: #fff; border-color: rgba(255, 255, 255, .45); }

/* Who can use it — painted after the roster read, never rendered inline. */
.reg-accslot:empty { display: none; }
.reg-acc {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 3px; font-size: 11px; font-weight: 700;
  padding: 2px 7px; border-radius: 999px;
}
.reg-acc i { font-size: 9px; }
.reg-acc.is-all { background: #f0f5f9; color: #64748b; }
.reg-acc.is-some { background: #fdf2e4; color: #9a6414; }

@media (max-width: 1080px) {
.reg-row { grid-template-columns: minmax(180px, 1.4fr) 96px minmax(160px, 1.6fr) 40px; }
  .reg-list.is-editing .reg-row { grid-template-columns: 24px minmax(170px, 1.4fr) 96px minmax(150px, 1.6fr) 76px; }
  .reg-updated { display: none; }
}
@media (max-width: 760px) {
.reg-row,
  .reg-list.is-editing .reg-row {
    grid-template-columns: 24px 1fr 76px;
    row-gap: 12px; align-items: start;
  }
  .reg-row { grid-template-columns: 1fr 40px; }
  .reg-pick { grid-column: 1; grid-row: 1; }
  .reg-id { grid-column: 1; }
  .reg-list.is-editing .reg-id { grid-column: 2; }
  .reg-edit, .reg-edit-gap, .reg-acts { grid-column: 2; grid-row: 1; }
  .reg-list.is-editing .reg-acts { grid-column: 3; }
  .reg-type { grid-column: 1 / -1; }
  .reg-tags { grid-column: 1 / -1; }
  .reg-updated { display: flex; grid-column: 1 / -1; flex-direction: row; align-items: baseline; gap: 7px; flex-wrap: wrap; }
}

/* ── App editor sheet ───────────────────────────────────────────────────────
   ⚠️ .bx-apphead itself is styled in css/browse.css, next to the rest of the
   editor. It used to be redefined here as well, with a flat #f8fafc ground — and
   because registry.css loads AFTER browse.css, that grey silently won: the head
   is tinted with the app's own two colours, and nothing was showing. One block,
   one file. Only what is genuinely extra lives here. */
.bx-apphead { margin: 0 0 18px; }
.bx-apphead-name { font-size: 17px; font-weight: 750; color: var(--ink, #0f172a); letter-spacing: -0.01em; }
.bx-apphead-sub { font-size: 13px; color: var(--muted, #64748b); margin-top: 2px; line-height: 1.5; }

/* Tag pickers — every department / role, tap to include */
.bx-tagpick { display: flex; flex-wrap: wrap; gap: 6px; }
.bx-tagpick-i {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  padding: 6px 11px; border-radius: 999px; cursor: pointer;
  background: #fff; border: 1px solid var(--line, #e2e8f0); color: #475569;
  transition: background .13s ease, border-color .13s ease, color .13s ease;
}
.bx-tagpick-i i { font-size: 9.5px; opacity: .75; }
.bx-tagpick-i:hover { border-color: #94a3b8; color: #0f172a; }
.bx-tagpick-i.is-on {
  background: #0f172a; border-color: #0f172a; color: #fff;
}
.bx-tagpick-i.is-on i { opacity: 1; }
.bx-tagpick-i:focus-visible { outline: 2px solid var(--brand, #0b63a6); outline-offset: 2px; }

/* App icon at two extra sizes: the registry row and the editor header. */
.app-icon.app-icon-md { width: 46px; height: 46px; border-radius: 12px; font-size: 20px; }
.app-icon.app-icon-md .app-icon-img { width: 46px; height: 46px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Editor sheet, round 2: the picked-apps strip, a full-height picker, and the
   note that says a dimension is owned upstream. Still in this file rather than
   browse.css — that one is being edited in another session and none of this
   overlaps it.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── What you have picked, as icons, above the list ────────────────────────
   The list is long enough that the chosen apps scroll out of view; this keeps
   the answer on screen while you are still answering it. */
.bx-picked {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 10px; margin: 0 0 2px;
  background: #f8fafc; border: 1px solid var(--line, #e2e8f0); border-radius: 12px;
}
.bx-picked[hidden] { display: none; }
.bx-picked-i {
  position: relative; padding: 0; border: 0; background: none; cursor: pointer;
  line-height: 0; border-radius: 10px;
  transition: transform .14s ease, filter .14s ease;
}
.bx-picked-i:hover { transform: translateY(-2px); }
.bx-picked-i:hover .app-icon { filter: saturate(.5) brightness(.92); }
.bx-picked-i:focus-visible { outline: 2px solid var(--brand, #0b63a6); outline-offset: 3px; }
.bx-picked-x {
  position: absolute; top: -5px; right: -5px;
  width: 17px; height: 17px; border-radius: 50%;
  display: grid; place-items: center;
  background: #0f172a; color: #fff; font-size: 8.5px;
  box-shadow: 0 0 0 2px #fff;
  opacity: 0; transition: opacity .14s ease;
}
.bx-picked-i:hover .bx-picked-x,
.bx-picked-i:focus-visible .bx-picked-x { opacity: 1; }

/* ── The picker uses the height it has ─────────────────────────────────────
   browse.css caps the list at min(46vh, 420px), which left the right column
   short while the left column ran on. The apps column is a flex column, so the
   list can simply take whatever is left. */
.bx-sheet-cols .bx-col-apps { align-self: stretch; }
.bx-sheet-cols .bx-col-apps .bx-field-apps {
  display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
}
.bx-sheet-cols .bx-col-apps .bx-pick-list {
  flex: 1 1 auto; min-height: 220px;
  max-height: none;          /* overrides browse.css's min(46vh, 420px) cap */
}
@media (max-width: 720px) {
/* Stacked, the list is one section among many again — give it a sane cap so
     it cannot push Save off the bottom of a phone. */
  .bx-sheet-cols .bx-col-apps .bx-pick-list { max-height: 260px; flex: 0 1 auto; }
}

/* ── "This dimension is owned upstream" ───────────────────────────────────── */
.bx-upstream-note {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12.5px; font-weight: 600; color: #475569;
  background: #f1f5f9; border: 1px solid var(--line, #e2e8f0);
  border-radius: 999px; padding: 7px 14px;
}
.bx-upstream-note i { color: #64748b; font-size: 11.5px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Send an app to someone — the sheet, the recipient chips, and the little
   preview of the email they will actually receive.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The Send button on an app page: the same object as .btn.primary, in the other
   house colour. Handing an app to somebody sits beside Install at the same
   weight, and blue says it is a different KIND of act than getting it yourself.
   Lives here rather than in styles.css because registry.css loads after it on
   every route, so this wins without an !important. */
.btn.btn-blue {
  background: linear-gradient(135deg, #0b6fb2, #16a3c9);
  color: #fff; border-color: transparent;
  box-shadow: 0 8px 22px -8px rgba(11,111,178,.55), inset 0 1px 0 rgba(255,255,255,.2);
}
.btn.btn-blue:hover {
  filter: brightness(1.08);
  box-shadow: 0 14px 30px -10px rgba(11,111,178,.72), inset 0 1px 0 rgba(255,255,255,.25);
}
.btn.btn-blue:focus-visible { outline: 2px solid #0b6fb2; outline-offset: 3px; }

/* ── The sheet itself ───────────────────────────────────────────────────────
   Wider and taller than an editor on purpose: this is two jobs at full size
   side by side — choosing people, and looking at the email that will reach
   them. At editor width the preview was a thumbnail of a thumbnail. */
.bx-sheet.bx-sheet-send {
  width: min(1160px, 100%);
  height: min(92vh, 980px);
}
.bx-sheet.bx-sheet-send .bx-sheet-body {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; gap: 16px;
}
.bx-send-block .bx-textarea { min-height: 76px; resize: vertical; }
.bx-tagpick { position: relative; flex: 0 0 auto; }

/* The quiet half of a field label: "optional", or what the field actually
   controls. Not italic and not uppercase — it is an aside, not a second label. */
.bx-field-label em {
  font-style: normal; text-transform: none; letter-spacing: 0;
  font-weight: 600; color: #94a3b8;
}

/* On a laptop the fixed furniture (hero, note, "who this is from") eats the
   directory down to a row and a half — the one part of this sheet you browse.
   So on a short window the furniture gets smaller, not the list. */
@media (max-height: 880px) {
.bx-sheet.bx-sheet-send { height: 96vh; }
  .bx-sheet.bx-sheet-send .bx-sheet-body { gap: 13px; padding: 15px 18px; }
  .bx-send-block .bx-textarea { min-height: 56px; }
}

@media (max-width: 900px) {
.bx-sheet.bx-sheet-send { height: min(94vh, 980px); }
}

/* (the from-line's own rules are with the subject row — see SEND FROM below.
   `.bx-send-col > .bx-note` used to be it, back when it was a bare note.) */

/* "Manage access", under the Install / Open buttons on an app page */
.send-link {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 600; color: var(--muted, #64748b);
  background: none; border: 0; padding: 4px 2px; cursor: pointer;
  transition: color .14s ease;
}
.send-link:hover { color: var(--brand, #0b63a6); }
.send-link:focus-visible { outline: 2px solid var(--brand, #0b63a6); outline-offset: 3px; border-radius: 6px; }
/* Their real face over their initials — see .bx-face for why the picture is
   laid over the letters rather than swapped for them. */
.bx-chip-face {
  position: relative; overflow: hidden;
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 9.5px; font-weight: 800; letter-spacing: .02em; color: #fff;
  background: linear-gradient(135deg, #0b6fb2, #16a3c9);
}
.bx-rlist .bx-pick-row { border-radius: 12px; }
.bx-pick-row .bx-pick-body { flex: 1 1 auto; }
.bx-pick-new .bx-pick-check { background: transparent; border-color: transparent; color: #0b6fb2; }

/* ── Faces and company marks ───────────────────────────────────────────────
   Initials underneath, the real picture laid OVER them: a photo that 404s
   reveals letters instead of leaving a hole. Company logos sit on white with a
   little padding, because a logo drawn edge-to-edge in a circle is a crop. */
.bx-face {
  position: relative; flex: none; overflow: hidden;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 11.5px; font-weight: 800; letter-spacing: .02em;
  color: #475569; background: #eef2f6; border: 1px solid var(--line, #e2e8f0);
}
/* ⚠️ A COMPANY MARK IS NOT A FACE, AND 34px WAS UNREADABLE. Ours are mostly
   wordmarks, so at face size with 3px of padding you got a ~28px grey smear —
   "the company logo is way too small, can't even see it, especially in the
   sending". A person is recognised by their features at 34px; a company is
   recognised by letters, which need room. So a company mark is 46px on the
   picker (the thing you are choosing) and keeps face size only in a chip. */
.bx-face-co { border-radius: 10px; background: #fff; }
.bx-face-co .bx-face-img { object-fit: contain; padding: 3px; }
.bx-cobtn .bx-face-co,
.bx-corow .bx-face-co { width: 46px; height: 46px; border-radius: 12px; font-size: 14px; }
.bx-cobtn .bx-face-co .bx-face-img,
.bx-corow .bx-face-co .bx-face-img { padding: 4px; }
.bx-face-sender { width: 30px; height: 30px; font-size: 10.5px; }
.bx-pick-search-sm .bx-input { font-size: 12.5px; }
.bx-prevhint { font-size: 11.5px; font-weight: 600; color: #94a3b8; }
.bx-prevhint i { margin-right: 5px; color: #0b6fb2; }
.bx-subjrow .bx-input { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 600; }

/* ── SEND FROM ──────────────────────────────────────────────────────────────
   Who it is from, with their face. A STATEMENT, so it is styled like one: a
   quiet card, not a control. It replaced two pickers that used to sit here — a
   four-button "Reads as" segment and a two-button from-voice segment (`.bx-seg`,
   `.bx-tplrow`, `.bx-fromseg`, all deleted with them). Nothing on this screen
   asks a question that has an obvious answer any more.
   Sits with the subject because they are both the envelope: the things you
   check, not the things you write. */
.bx-fromrow {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; border-radius: 12px;
  background: var(--tint, #f6f9fc); border: 1px solid var(--line, #e2e8f0);
  font-size: 12px; line-height: 1.6; color: #475569;
}
.bx-fromrow.is-anon { align-items: center; }
.bx-fromrow > i { flex: none; margin-top: 3px; color: var(--brand, #0b6fb2); }
.bx-sender-t { min-width: 0; }
/* The label above the name, so the row says what it IS before it says who. */
.bx-fromlbl {
  display: block; margin-bottom: 1px;
  font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: #94a3b8;
}
.bx-fromrow b { color: #0f172a; font-weight: 800; }
.bx-mailfull-subj {
  font-size: 14.5px; font-weight: 800; color: var(--ink, #0f172a);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bx-mailfull-from {
  margin-top: 2px; font-size: 11.5px; color: var(--muted, #64748b);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bx-mailfull-hint { flex: none; font-size: 11.5px; font-weight: 600; color: #94a3b8; }
.bx-mailfull-hint i { margin-right: 5px; color: #0b6fb2; }
.bx-mailfull-railhead {
  flex: none; padding: 14px 16px 10px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: #94a3b8; border-bottom: 1px solid var(--line, #e2e8f0);
}
.bx-mailfull-railfoot .bx-btn-primary { width: 100%; justify-content: center; }
/* A narrow window has no room for a rail; it goes back under the email, and the
   scroller keeps its padding so nothing is hidden behind it. */
@media (max-width: 900px) {
.bx-mailfull-railhead { padding-bottom: 8px; }
}
/* ── The device segment: ONE control, used in two places ───────────────────
   `.bx-devseg` is in the sheet's preview head AND in the full-screen bar, so
   there is one set of styles and one set of states. It replaced
   `.bx-mailfull-dev`, which only ever existed in the overlay — which is why the
   sheet had no way to see the phone layout at all. */
.bx-devseg {
  flex: none; display: flex; gap: 2px; padding: 3px;
  background: #f1f5f9; border: 1px solid var(--line, #e2e8f0); border-radius: 999px;
}

/* ── Full screen is a WORKING view, not a lightbox ─────────────────────────
   The foot carries who it is going to and the real Send, so checking the email
   and acting on it are the same visit. Both mirror the sheet underneath. */
/* ⚠️ `.bx-mailfull-foot` IS GONE — see .bx-mailfull-rail for where it went and
   why a bar under the email read as the email being cut off. */
.bx-mailfull-to {
  flex: 1 1 auto; min-width: 0; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; align-items: stretch;
  gap: 6px; padding: 12px 14px;
}
.bx-mailfull-tolbl {
  font-size: 9.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: #94a3b8;
}
.bx-mailfull-chip {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 10px 5px 5px; border-radius: 999px;
  background: #f1f5f9; border: 1px solid var(--line, #e2e8f0);
  font-size: 12.5px; font-weight: 650; color: #334155;
  max-width: 100%;
}
.bx-mailfull-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bx-mailfull-face { width: 20px; height: 20px; flex: 0 0 20px; font-size: 8px; }
.bx-mailfull-more { font-size: 12px; font-weight: 650; color: #64748b; }
.bx-mailfull-none { font-size: 12.5px; color: #94a3b8; }
.bx-mailfull-foot .bx-btn-primary { flex: none; }
/* A phone reading pane is not the place for a three-column bar. */
@media (max-width: 720px) {
.bx-mailfull-bar, .bx-mailfull-foot { flex-wrap: wrap; }
  .bx-mailfull-to { order: 3; width: 100%; }
}

/* ── The title block: the subject IS the title, the sender is its byline ────
   Tyler: *"make send from more subtle and take up less space so preview has
   more, and send from is always top title, under that then the preview."*
   `.bx-fromrow` was a bordered row with a 34px avatar and three lines of text —
   about 86px to restate something nobody on this screen can change. */
.bx-subjrow-lg > span { font-size: 10.5px; }
.bx-subjrow-lg .bx-input {
  font-size: 15.5px; font-weight: 700; color: var(--ink, #0f172a);
  letter-spacing: -0.01em;
}

/* The one action in the footer, at the weight of the thing it does. */
.bx-btn.bx-btn-send {
  padding: 10px 20px; font-size: 13.5px;
  background: linear-gradient(135deg, #0b6fb2, #16a3c9);
}
@keyframes bxWhenIn { from { opacity: 0; transform: translateY(6px) scale(.97); } }
@keyframes bxPaneIn { from { opacity: 0; transform: translateX(6px); } }
@keyframes bxPaneInR { from { opacity: 0; transform: translateX(-6px); } }
@keyframes bxSentIn { from { opacity: 0; transform: translateY(10px); } }
@keyframes bxMarkPop { from { opacity: 0; transform: scale(.4); } 60% { transform: scale(1.08); } to { opacity: 1; transform: scale(1); } }
@keyframes bxTickIn { from { opacity: 0; transform: scale(.5) rotate(-12deg); } }

/* Send status, next to the button */
.bx-sendstatus { font-size: 12.5px; font-weight: 600; color: #64748b; }
.bx-sendstatus.is-warn { color: #b45309; }
.bx-sendstatus.is-bad { color: #b91c1c; }
.bx-sendstatus.is-ok { color: #15803d; }

/* ═══════════════════════════════════════════════════════════════════════════
   App access — who may actually use an app.
   One list of real accounts with a switch each. The sheet runs tall on purpose:
   this is a roster you scan, and a 46vh box turns twenty people into scrolling.
   ═══════════════════════════════════════════════════════════════════════════ */
.bx-sheet.bx-sheet-tall {
  height: min(88vh, 900px);
  display: flex; flex-direction: column;
}
.bx-sheet.bx-sheet-tall .bx-sheet-body {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
}

/* The apps in play, as icons — the same "show me what I picked" strip the
   bundle editor uses, one size up because here it is the subject. */
.bx-picked-lg { gap: 8px; margin: 0 0 16px; }
.bx-picked-lg .bx-picked-item {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 7px; border-radius: 11px;
  background: #f8fafc; border: 1px solid var(--line, #e2e8f0);
  font-size: 12.5px; font-weight: 650; color: #334155;
}

.bx-acc-pick { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.bx-acc-bulk { display: flex; gap: 8px; margin: 10px 0 0; flex-wrap: wrap; }
.bx-btn-sm { font-size: 12.5px; padding: 7px 12px; }

.bx-acc-list {
  flex: 1 1 auto; min-height: 180px; overflow-y: auto;
  margin-top: 12px; padding-right: 2px;
  border-top: 1px solid var(--line, #e2e8f0);
}
.bx-acc-loading { padding: 26px 0; text-align: center; color: #94a3b8; font-size: 13px; }

.bx-acct {
  display: grid; grid-template-columns: 34px 1fr auto 46px;
  gap: 12px; align-items: center;
  padding: 10px 4px;
  border-bottom: 1px solid #f1f5f9;
}
.bx-acct-face {
  width: 34px; height: 34px; border-radius: 50%; object-fit: cover;
  background: #e2e8f0; display: grid; place-items: center;
  font-size: 11.5px; font-weight: 800; color: #475569; letter-spacing: .02em;
}
.bx-acct-id { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bx-acct-name {
  font-size: 14px; font-weight: 650; color: var(--ink, #0f172a);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bx-acct-sub {
  font-size: 11.5px; color: var(--muted, #64748b);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The state word, not a colour alarm. "Locked" is a fact, not a failure. */
.bx-acct-state { font-size: 11px; font-weight: 700; color: #94a3b8; white-space: nowrap; }
.bx-acct[data-state="open"] .bx-acct-state { color: #15803d; }
.bx-acct[data-state="all"] .bx-acct-state { color: #64748b; }
.bx-acct[data-state="part"] .bx-acct-state { color: #9a6414; }
.bx-acct[data-state="locked"] .bx-acct-state { color: #64748b; }

.bx-toggle {
  width: 42px; height: 24px; border-radius: 999px; cursor: pointer;
  border: 0; padding: 0; position: relative;
  background: #cbd5e1; transition: background .16s ease;
}
.bx-toggle-dot {
  position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, .28);
  transition: transform .16s ease;
}
.bx-toggle.is-on { background: var(--brand, #0b63a6); }
.bx-toggle.is-on .bx-toggle-dot { transform: translateX(18px); }
.bx-toggle:focus-visible { outline: 2px solid var(--brand, #0b63a6); outline-offset: 3px; }

/* Said before you save, not discovered after: this change restricts somebody
   who currently has everything. */
.bx-acc-warn {
  margin: 12px 0 0; padding: 10px 13px;
  display: flex; align-items: flex-start; gap: 9px;
  background: #fdf6e7; border: 1px solid #f0dcb0; border-radius: 11px;
  font-size: 12.5px; line-height: 1.55; color: #7c5310;
}
.bx-acc-warn[hidden] { display: none; }

/* Turned away at sign-in and sent to the app's page instead of a dead tab. */
.app-locked-note {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px; margin: 0 0 20px;
  background: #f8fafc; border: 1px solid var(--line, #e2e8f0);
  border-left: 3px solid #94a3b8; border-radius: 12px;
}
.app-locked-note > i { color: #64748b; font-size: 15px; }
.app-locked-note > div { display: flex; flex-direction: column; gap: 3px; flex: 1 1 auto; }
.app-locked-note strong { font-size: 14.5px; color: var(--ink, #0f172a); }
.app-locked-note span { font-size: 13px; color: var(--muted, #64748b); line-height: 1.55; }

@media (max-width: 720px) {
.bx-sheet.bx-sheet-tall { height: auto; max-height: 92vh; }
  .bx-acct { grid-template-columns: 30px 1fr 46px; }
  .bx-acct-state { display: none; }
  .app-locked-note { flex-wrap: wrap; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE INSTALL LEDGER — how many people have an app, and which people.

   Lives here rather than in styles.css for the reason at the top of this file
   (that one is open in another session), and it loads last, so .chip.dl-chip
   sits with its siblings without editing them.

   Deliberately the QUIETEST chip on a card: slate, not a colour. "Featured" and
   "Updated" are claims the catalogue makes; an install count is just a fact,
   and a fact that shouts outranks the buttons underneath it.
   ═══════════════════════════════════════════════════════════════════════════ */
.chip.dl-chip {
  background: #f1f5f9;
  color: #64748b;
  border-color: #e6ecf3;
}
.chip.dl-chip i { font-size: 9.5px; opacity: .75; }

/* ── An app's own page: the faces strip ──────────────────────────────────── */
/* Painted after the page renders and only for an admin, so it must cost
   nothing at all when empty — no margin, no border, no gap. */
.install-roster:empty { display: none; }
.inst-strip {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 20px;
  padding: 11px 15px;
  background: #f8fafc;
  border: 1px solid #eef2f7;
  border-radius: 12px;
}
.inst-faces { display: inline-flex; align-items: center; }
/* Overlapped, newest first — the standard "and N others" stack. */
.inst-face { margin-left: -8px; line-height: 0; }
.inst-face:first-child { margin-left: 0; }
.inst-face .bx-acct-face {
  width: 28px; height: 28px; font-size: 10px;
  border: 2px solid #fff; box-shadow: 0 1px 2px rgba(15, 23, 42, .12);
}
.inst-face.inst-more {
  display: grid; place-items: center;
  width: 28px; height: 28px; border-radius: 50%;
  border: 2px solid #fff; background: #e2e8f0;
  font-size: 10.5px; font-weight: 800; color: #475569; line-height: 1;
}
.inst-txt { font-size: 13.5px; color: #475569; }
.inst-txt b { color: var(--ink, #0f172a); font-weight: 750; }
.inst-gone { color: #94a3b8; }
.inst-see { margin-left: auto; }

/* ── The registry row chip ───────────────────────────────────────────────── */
.reg-instslot:empty { display: none; }
.reg-inst {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 3px; padding: 2px 7px;
  font: inherit; font-size: 11px; font-weight: 700;
  border: 0; border-radius: 999px;
  background: #eef4fb; color: #3f6f9e;
  cursor: pointer;
}
.reg-inst:hover { background: #e2edf9; color: #23557f; }
.reg-inst i { font-size: 9px; }
/* Nobody yet is a fact, not a warning — it should read fainter than a number. */
.reg-inst.is-none { background: transparent; color: #b6c2d0; cursor: default; }

/* ── The roster sheet ────────────────────────────────────────────────────── */
.inst-sum {
  margin: 0 0 10px; padding-bottom: 10px;
  border-bottom: 1px solid #f1f5f9;
  font-size: 13px; color: #64748b;
}
.inst-sum b { color: var(--ink, #0f172a); font-size: 14px; }
.inst-row {
  display: grid; grid-template-columns: 34px 1fr auto;
  gap: 12px; align-items: center;
  padding: 9px 4px;
  border-bottom: 1px solid #f5f8fa;
}
/* Somebody who removed it still belongs on the list — dimmed, not deleted. */
.inst-row.is-gone { opacity: .58; }
.inst-who { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.inst-who b {
  font-size: 14px; font-weight: 650; color: var(--ink, #0f172a);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.inst-mail {
  font-size: 11.5px; color: var(--muted, #64748b);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.inst-when { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.inst-tag { font-size: 11px; font-weight: 700; color: #94a3b8; white-space: nowrap; }
.inst-tag.is-on { color: #47845f; }
.inst-times { font-size: 10.5px; color: #b6c2d0; }

@media (max-width: 720px) {
.inst-strip { gap: 10px; padding: 10px 12px; }
  .inst-see { margin-left: 0; }
  .inst-row { grid-template-columns: 34px 1fr; }
  .inst-when { align-items: flex-start; grid-column: 2; }
}
.bx-mailfull-subjslot .bx-input {
  width: 100%; font-size: 13.5px; font-weight: 700; padding: 7px 10px;
  color: var(--ink, #0f172a);
}
@keyframes bxQmIn { from { opacity: 0; transform: translateY(-5px) scale(.98); } }
