/* App shell + the screens the rebuild added. app.css supplies the token layer
   (neutrals, accent, lane hues) and the inbox internals — this file adds the
   frame around them and the new pages.
   Discipline is unchanged: accent appears on primary actions, active nav,
   focus rings and status dots. Everything else is neutral. */

/* ------------------------------ shell ------------------------------ */
/* ⚠️ The rail's width is STATE, not screen width (2026-08-20). It used to be
   three media queries; now the screen only picks the DEFAULT and the tab on
   the rail's edge overrides it (util.js railIsOpen, main.js applyRailState).
   One variable drives both the grid track and everything inside the rail, so
   the page can never be laid out for a width the rail is not using. */
.app-shell {
  height: 100%; display: grid; background: var(--bg);
  --rail-w: 232px;
  grid-template-columns: var(--rail-w) 1fr;
  transition: grid-template-columns .16s var(--ease);
}
.app-shell[data-rail="mini"] { --rail-w: 56px; }
@media (prefers-reduced-motion: reduce) { .app-shell { transition: none; } }

.rail {
  background: var(--surface); border-right: 1px solid var(--border);
  padding: 12px 10px; display: flex; flex-direction: column; gap: 2px;
  position: relative; overflow: visible;
}
.rail h5 {
  margin: 16px 0 6px; padding: 0 8px; font-size: 10.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-3);
}
.rail-spacer { flex: 1; }

/* The expand/collapse handle. It sits ON the rail's border rather than inside
   it, because inside a 56px rail it would be one more anonymous icon in a
   column of icons — the whole point is that it reads as an edge you can pull.
   Anchored beside the workspace switcher, clear of the ws-menu (top: 52px). */
/* ⚠️ -12px is the one number that clears BOTH neighbours, and it is why the
   tab grows in height rather than width. Any further in and it paints over the
   workspace logo, which sits 14px from the collapsed rail's right edge; any
   further out and it reaches the inbox filter column's headings, which start
   20px past the divider. Measured, not guessed. */
.rail-tab {
  position: absolute; top: 13px; right: -12px; z-index: 46;
  /* ⚠️ Size is a RATIO, not a number. 26×50 was "way too big" (Maycol) not
     because 50px is tall but because a 16px chevron inside it left the thing
     reading as an empty box. Keep the glyph filling the shape: ~22×32 with a
     14px icon. No shadow — on the dark theme it was what made it look bolted
     on rather than part of the divider. */
  width: 22px; height: 32px; border-radius: 8px;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-3); display: grid; place-items: center;
  transition: color .12s var(--ease), border-color .12s var(--ease), background .12s var(--ease);
}
.rail-tab:hover { color: var(--text); border-color: var(--border-strong); background: var(--surface-2); }
.rail-tab .ico { width: 14px; height: 14px; }

/* Sync: last thing above the divider, never inside the nav stack. */
.rail-sync { color: var(--text-3); margin-bottom: 2px; }
.rail-sync:hover { color: var(--text-2); }
.rail-sync.busy { pointer-events: none; color: var(--accent); }
.rail-sync.busy .ico { animation: rail-spin .9s linear infinite; transform-origin: 50% 50%; }
@keyframes rail-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .rail-sync.busy .ico { animation: none; } }

.rail-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 8px; border-radius: var(--radius); color: var(--text-2);
  transition: background .12s var(--ease), color .12s var(--ease);
}
.rail-item:hover { background: var(--surface-2); color: var(--text); }
.rail-item.active { background: var(--accent-soft); color: var(--text); }
.rail-item.active .ico { color: var(--accent); }
.rail-item .label { font-weight: 500; font-size: 12.5px; }
.rail-item .count {
  margin-left: auto; font-size: 11px; color: var(--text-3);
  background: var(--surface-2); padding: 1px 6px; border-radius: 20px;
}
/* "None match the current filter" — present, so it cannot be mistaken for a
   count that failed to load, but quiet enough not to compete with a real one. */
.rail-item .count.zero { opacity: .45; background: transparent; }

/* ---- auto-assignment rows (Settings) ---- */
.assign-grid { display: flex; flex-direction: column; gap: 10px; }
.assign-row {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2);
}
.assign-lane { flex: 1 1 0; min-width: 0; line-height: 1.35; }
.assign-lane b { display: block; font-size: 13px; }
.assign-lane .muted { font-size: 11.5px; }
.assign-row .select { flex: 0 0 auto; min-width: 190px; max-width: 240px; }
@media (max-width: 760px) {
  /* Stack: a label and a full-width picker, not two cramped halves. */
  .assign-row { flex-direction: column; align-items: stretch; gap: 8px; }
  .assign-row .select { max-width: none; width: 100%; }
}

.ws-switch {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px;
  border-radius: var(--radius); text-align: left;
}
.ws-switch:hover { background: var(--surface-2); }
.ws-switch .ico { margin-left: auto; color: var(--text-3); width: 14px; height: 14px; }
.ws-name { min-width: 0; line-height: 1.25; }
.ws-name b { display: block; font-size: 13px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-name span { font-size: 11px; color: var(--text-3); text-transform: capitalize; }

.logo-mark {
  width: 28px; height: 28px; flex-shrink: 0; border-radius: 8px;
  background: var(--accent); color: var(--on-accent);
  display: grid; place-items: center; font-weight: 700; font-size: 14px;
}
.logo-mark.sm { width: 22px; height: 22px; font-size: 11px; border-radius: 6px; }

.ws-menu {
  position: absolute; top: 52px; left: 10px; right: 10px; z-index: 40;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg); padding: 5px; box-shadow: var(--shadow-pop);
}
.ws-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px; border-radius: var(--radius); font-size: 12.5px;
}
.ws-menu-item:hover { background: var(--surface-2); }
.ws-menu-item.on { background: var(--accent-soft); }
.ws-menu-item span { flex: 1; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-menu-item em { font-style: normal; font-size: 11px; color: var(--text-3); }

/* ---- footer ----
   Avatar, name, email, bell and sign-out shared ONE 232px row until
   2026-08-20 — five things in a strip narrower than a phone. Maycol: "they're
   right next to each other, and it looks cramped... we could make way better
   use of this space." Stacked now: identity on its own line, then the two
   actions splitting the row below it, each wide enough to carry a label. */
.rail-footer {
  display: flex; flex-direction: column; gap: 8px; padding: 10px 2px 2px;
  border-top: 1px solid var(--border); margin-top: 8px;
}
.rail-user { display: flex; align-items: center; gap: 9px; padding: 0 6px; min-width: 0; }
.rail-footer .who { min-width: 0; flex: 1; line-height: 1.25; }
.rail-footer .who b { display: block; font-size: 12.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ⚠️ text-transform is a RESET, not a style. app.css capitalizes .rail-footer
   .role because in the legacy console that line held the word "owner" — here
   it holds the email, and it was rendering "Support@Olivinebeauty.Com". */
.rail-footer .role { font-size: 10.5px; color: var(--text-3); text-transform: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rail-actions { display: flex; gap: 6px; }
.rail-action {
  flex: 1 1 0; min-width: 0; display: flex; align-items: center; justify-content: center;
  gap: 7px; padding: 7px 8px; min-height: 34px;
  border: 1px solid var(--border); border-radius: var(--radius);
  color: var(--text-2); font-size: 12px; font-weight: 500; white-space: nowrap;
  transition: background .12s var(--ease), color .12s var(--ease), border-color .12s var(--ease);
}
.rail-action .ico { width: 15px; height: 15px; flex-shrink: 0; }
.rail-action:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-strong); }
.rail-action.off { color: var(--text-3); }
/* Sign-out is the one control here you cannot undo with the same click. */
.rail-action[data-logout]:hover {
  color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
}
.avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  background: var(--surface-3); color: var(--text-2);
  display: grid; place-items: center; font-size: 10.5px; font-weight: 600;
}
.avatar.sm { width: 30px; height: 30px; font-size: 11px; }
.icon-only {
  padding: 5px; border-radius: 6px; color: var(--text-3); display: grid; place-items: center;
}
.icon-only:hover { background: var(--surface-2); color: var(--text); }

.page-outlet { overflow: hidden; min-width: 0; }

/* ------------------------------ page frame ------------------------------ */
.page { height: 100%; overflow-y: auto; padding: 26px 30px 60px; }
.page.narrow > * { max-width: 940px; }
.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 22px; flex-wrap: wrap;
}
.page-head h1 { margin: 0; font-size: 21px; font-weight: 650; letter-spacing: -.015em; text-wrap: balance; }
.page-sub { margin: 4px 0 0; font-size: 12.5px; color: var(--text-2); }
.head-actions { display: flex; gap: 8px; }

.panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); margin-bottom: 16px; overflow: hidden;
}
.panel-head {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 16px; border-bottom: 1px solid var(--border);
}
.panel-head h3 { margin: 0; font-size: 13px; font-weight: 600; }
.panel-note { margin-left: auto; font-size: 11px; color: var(--text-3); }

.hint { font-size: 11.5px; color: var(--text-3); line-height: 1.5; padding: 10px 16px 14px; }
.hint code { background: var(--surface-2); padding: 1px 5px; border-radius: 4px; }
.hint .ico { display: inline-block; vertical-align: -3px; margin-right: 4px; width: 14px; height: 14px; }
.muted { color: var(--text-3); font-weight: 400; }
.empty-sm { padding: 22px 16px; text-align: center; font-size: 12.5px; color: var(--text-3); }

/* ------------------------------ stats ------------------------------ */
.stat-grid, .skeleton-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
  gap: 12px; margin-bottom: 16px;
}
.stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 14px 16px 15px;
}
.stat.warn { border-color: color-mix(in srgb, var(--warn) 45%, var(--border)); }
.stat-label { font-size: 11px; font-weight: 500; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-3); }
.stat-value { font-size: 27px; font-weight: 650; line-height: 1.15; margin-top: 5px; letter-spacing: -.02em; }
.stat-sub { font-size: 11.5px; color: var(--text-2); margin-top: 2px; }
.tone-warn { color: var(--warn); }

.banner {
  display: flex; align-items: center; gap: 11px; padding: 12px 15px; margin-bottom: 16px;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong); border-radius: var(--radius-lg);
  font-size: 12.5px;
}
.banner > .ico { color: var(--text-3); flex-shrink: 0; }
.banner > div { flex: 1; min-width: 0; }
.banner.warn { border-left-color: var(--warn); }
.banner.warn > .ico { color: var(--warn); }
.banner.danger { border-left-color: var(--danger); }
.banner.danger > .ico { color: var(--danger); }
.banner.ok { border-left-color: var(--st-resolved); }
.banner.ok > .ico { color: var(--st-resolved); }
.banner .hint { padding: 4px 0 0; }

.dash-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 16px; }
.dash-cols .panel { margin-bottom: 0; }
.dash-cols + .dash-cols { margin-top: 16px; }

/* bar list — lane and tag distributions */
.bar-list { padding: 12px 16px 14px; display: flex; flex-direction: column; gap: 9px; }
.bar-row { display: grid; grid-template-columns: 118px 1fr 34px; align-items: center; gap: 10px; }
.bar-label { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-track { height: 6px; background: var(--surface-2); border-radius: 4px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--text-3); border-radius: 4px; }
.bar-fill.lane-comments { background: var(--c-comments); }
.bar-fill.lane-messenger { background: var(--c-messenger); }
.bar-fill.lane-ig { background: var(--c-ig); }
.bar-fill.lane-email { background: var(--c-email); }
.bar-num { text-align: right; font-size: 12px; color: var(--text-2); }

.lane-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); flex-shrink: 0; }
.lane-dot.lane-comments { background: var(--c-comments); }
.lane-dot.lane-messenger { background: var(--c-messenger); }
.lane-dot.lane-ig { background: var(--c-ig); }
.lane-dot.lane-email { background: var(--c-email); }

/* reply windows */
.win-list { padding: 6px 0 8px; }
.win-row { display: flex; align-items: center; gap: 10px; padding: 8px 16px; }
.win-row + .win-row { border-top: 1px solid var(--border); }
.win-main { flex: 1; min-width: 0; }
.win-text { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.win-meta { font-size: 11px; color: var(--text-3); margin-top: 1px; }
.win-left { font-size: 11.5px; color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.win-left.urgent { color: var(--danger); font-weight: 600; }

/* system list */
.sys-list { padding: 4px 0 6px; }
.sys-row { display: flex; align-items: center; gap: 10px; padding: 8px 16px; font-size: 12.5px; }
.sys-row + .sys-row { border-top: 1px solid var(--border); }
.sys-label { display: flex; align-items: center; gap: 8px; min-width: 152px; }
.sys-val { margin-left: auto; text-align: right; }
.sys-val.muted { font-size: 11.5px; max-width: 330px; }
.dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.dot.on { background: var(--st-resolved); }
.dot.off { background: var(--text-3); }

/* ------------------------------ rows + forms ------------------------------ */
.row-list { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; gap: 11px; padding: 11px 16px; }
.row + .row { border-top: 1px solid var(--border); }
.row-main { flex: 1; min-width: 0; }
.row-title { font-size: 13px; font-weight: 500; }
.row-sub { font-size: 11.5px; color: var(--text-3); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row-sub.full { white-space: normal; }

.form-panel { border-color: var(--border-strong); }
.form-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 13px; padding: 15px 16px;
}
.field label { display: block; font-size: 11.5px; font-weight: 500; color: var(--text-2); margin-bottom: 5px; }
.field input, .field textarea, .select {
  width: 100%; padding: 8px 10px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius); font-size: 12.5px;
}
.field textarea { resize: vertical; line-height: 1.5; }
.field input:focus, .field textarea:focus, .select:focus { outline: none; border-color: var(--accent-line); }
.field input:disabled, .field textarea:disabled { opacity: .55; cursor: not-allowed; }
.field .hint { padding: 4px 0 0; }
.select.sm { width: auto; padding: 5px 8px; font-size: 12px; }
.form-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 0 16px 14px;
}
.form-foot .hint { padding: 0; }

.color-field { display: flex; gap: 7px; align-items: center; }
.color-field input[type="color"] {
  width: 34px; height: 34px; padding: 2px; flex-shrink: 0;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
}
.unit-field { display: flex; align-items: center; gap: 8px; }
.unit-field span { font-size: 11.5px; color: var(--text-3); }

.btn-primary {
  display: inline-flex; align-items: center; gap: 6px; justify-content: center;
  padding: 8px 13px; border-radius: var(--radius); font-size: 12.5px; font-weight: 550;
  background: var(--accent); color: var(--on-accent); text-decoration: none;
}
.btn-primary:hover { background: var(--accent-hover); }
.btn-ghost {
  display: inline-flex; align-items: center; gap: 6px; justify-content: center;
  padding: 7px 12px; border-radius: var(--radius); font-size: 12.5px;
  border: 1px solid var(--border); color: var(--text-2); background: var(--surface);
  text-decoration: none;
}
.btn-ghost:hover { border-color: var(--border-strong); color: var(--text); }
.btn-ghost.sm { padding: 5px 9px; font-size: 11.5px; }
.btn-ghost.danger:hover { border-color: var(--danger); color: var(--danger); }

.chip {
  display: inline-block; padding: 2px 7px; border-radius: 20px; font-size: 10.5px;
  background: var(--surface-2); color: var(--text-2); white-space: nowrap;
}
.chip.role-owner { background: var(--accent-soft); color: var(--accent); }
.chip.st-resolved { color: var(--st-resolved); }
.chip.prio { color: var(--warn); }

.link-box {
  margin-top: 7px; padding: 8px 10px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius);
  font-size: 11px; word-break: break-all; overflow-x: auto;
}
.shortcut, .shortcut-input {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px;
  color: var(--accent); background: var(--surface-2);
  padding: 3px 7px; border-radius: 5px; flex-shrink: 0;
}
.shortcut-input { width: 130px; border: 1px solid var(--border); }
.qr-add { display: flex; gap: 8px; padding: 12px 16px 0; }
.qr-add input:not(.shortcut-input) {
  flex: 1; padding: 7px 10px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius); font-size: 12.5px;
}

/* workspace cards */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 460px)); gap: 13px; margin-bottom: 16px; }
.ws-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
.ws-card.needs-attention { border-color: color-mix(in srgb, var(--warn) 50%, var(--border)); }
.ws-card-head { display: flex; align-items: center; gap: 10px; padding: 14px 15px; border-bottom: 1px solid var(--border); }
.ws-card-head > div:not(.logo-mark) { min-width: 0; flex: 1; line-height: 1.3; }
.ws-card-head b { display: block; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-card-head .muted { font-size: 11.5px; }
.ws-card-body { padding: 11px 15px 13px; }
.ws-card-foot { padding: 0 15px 13px; }
.kv { display: flex; justify-content: space-between; gap: 12px; font-size: 12px;
  color: var(--text-3); padding: 3px 0; }
.kv b { color: var(--text); font-weight: 500; text-align: right; }
.kv.flag-row b { color: var(--warn); }

.steps { margin: 0; padding: 14px 16px 14px 34px; font-size: 12.5px; color: var(--text-2); line-height: 1.6; }
.steps li + li { margin-top: 7px; }
.steps b { color: var(--text); font-weight: 550; }

/* activity feed */
.feed { padding: 4px 0; }
.feed-row { display: flex; gap: 11px; padding: 9px 16px; align-items: flex-start; }
.feed-row + .feed-row { border-top: 1px solid var(--border); }
.feed-kind { width: 6px; height: 6px; border-radius: 50%; margin-top: 6px; background: var(--text-3); flex-shrink: 0; }
.feed-kind.kind-team { background: var(--c-messenger); }
.feed-kind.kind-invite { background: var(--c-comments); }
.feed-kind.kind-settings { background: var(--st-pending); }
.feed-main { flex: 1; min-width: 0; }
.feed-text { font-size: 12.5px; line-height: 1.45; }
.feed-time { font-size: 11px; color: var(--text-3); margin-top: 1px; }

/* skeletons */
.skeleton, .skeleton-grid .skeleton {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); height: 92px;
  animation: pulse 1.4s var(--ease) infinite;
}
.skeleton.tall { height: 240px; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

/* ------------------------------ inbox inside the shell ------------------------------ */
/* The old console owned the full window; here it lives inside the outlet, so
   the lane filters move into their own column and the shell keeps the rail. */
/* ⚠️ `height: 100%` alone does NOT bound the row. The single implicit row is
   sized by its tallest child, so a 240-conversation list made this grid 9440px
   tall — the outlet clipped the overflow and the composer sat far below the
   fold, invisible. An explicit minmax(0, 1fr) row is what caps it so the list
   and the thread scroll inside their own panes. */
.inbox-layout {
  height: 100%; display: grid; min-width: 0;
  grid-template-columns: 184px 330px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
}
.filter-col, .list-pane, .thread-pane { min-height: 0; }
.filter-col {
  background: var(--surface); border-right: 1px solid var(--border);
  padding: 12px 10px; overflow-y: auto;
}
.filter-col h5 {
  margin: 4px 0 6px; padding: 0 8px; font-size: 10.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-3);
}
.filter-col h5:not(:first-child) { margin-top: 16px; }

/* Which business am I looking at? The rail answers that at full width, but it
   collapses to icons below 1500px — and every laptop is below 1500px. */
.list-head-ws { font-size: 11px; color: var(--text-3); margin-top: 1px; }
.list-head-row > div:first-child { min-width: 0; flex: 1; }

@media (max-width: 1180px) {
  .inbox-layout { grid-template-columns: 160px 300px 1fr; }
}

/* ---- reconciling with app.css ----
   app.css was written for a console that owned the whole window. It loads
   first, so equal-specificity rules here already win; these are the cases
   where it wrote a value the shell cannot simply restate. */

/* The thread pane was pinned to the viewport. Inside the outlet it must fill
   its grid row instead, or it runs past the bottom of the page. */
.thread-pane { height: 100%; }

/* ⚠️ `1fr` means `minmax(auto, 1fr)`, so the thread column refused to shrink
   below its content: the header's controls pushed the details sidebar off the
   right edge and the messages ran underneath it. It only showed once the shell
   rail took 232px away from this pane. minmax(0, …) lets it shrink and scroll. */
.thread-with-details { grid-template-columns: minmax(0, 1fr) 258px; }
.thread-controls .select { max-width: 116px; text-overflow: ellipsis; }

/* Below this width the three inbox columns plus a labelled rail stop fitting,
   so the rail DEFAULTS to icons — dropping navigation labels costs a moment of
   hesitation, while dropping the contact panel costs the reason that pane
   exists. The tab overrides this either way; see the [data-rail] block below. */
@media (max-width: 1500px) {
  .inbox-layout { grid-template-columns: 172px 306px minmax(0, 1fr); }
  .filter-col, .list-pane, .thread-pane { min-height: 0; }
  .thread-with-details { grid-template-columns: minmax(0, 1fr) 240px; }
}

/* ---- the two rail shapes -------------------------------------------------
   ⚠️ Everything here is walled inside min-width: 761px. These selectors carry
   an attribute AND a class, so they out-specify the phone block below — which
   turns the rail into a bottom bar and must always win there. */
@media (min-width: 761px) {
  /* collapsed: icons only, 56px */
  .app-shell[data-rail="mini"] .rail { padding: 12px 8px; align-items: center; }
  /* The sign-out control stays — it is the only way out of the app.
     ⚠️ So does the workspace chevron. Hiding it left the switcher looking
     like a plain logo with no hint it could be clicked, which is exactly how
     a second business gets reported as "everything is under one dashboard". */
  .app-shell[data-rail="mini"] .rail h5,
  .app-shell[data-rail="mini"] .rail .label,
  .app-shell[data-rail="mini"] .rail .count,
  .app-shell[data-rail="mini"] .ws-name,
  .app-shell[data-rail="mini"] .rail-footer .who { display: none; }
  .app-shell[data-rail="mini"] .rail-item { justify-content: center; padding: 8px; }
  .app-shell[data-rail="mini"] .ws-switch { flex-direction: column; gap: 1px; padding: 6px 8px 4px; }
  .app-shell[data-rail="mini"] .ws-switch .ico { margin-left: 0; width: 12px; height: 12px; }
  .app-shell[data-rail="mini"] .ws-menu { left: 8px; width: 210px; right: auto; }
  .app-shell[data-rail="mini"] .rail-footer { padding: 10px 0 2px; }
  .app-shell[data-rail="mini"] .rail-user { justify-content: center; padding: 0; }
  .app-shell[data-rail="mini"] .rail-actions { flex-direction: column; gap: 4px; }
  .app-shell[data-rail="mini"] .rail-action { flex: 0 0 auto; padding: 7px; }

  /* expanded: labelled, 232px.
     ⚠️ These restatements are load-bearing, not redundancy. app.css still
     carries a 1040px block that hides rail labels for the LEGACY console, and
     the rail can now be expanded at 900px — without these, expanding on a
     small window would widen the column and show nothing in it. */
  .app-shell[data-rail="open"] .rail h5,
  .app-shell[data-rail="open"] .rail .rail-item .label,
  .app-shell[data-rail="open"] .ws-name,
  .app-shell[data-rail="open"] .rail-footer .who { display: block; }
  .app-shell[data-rail="open"] .rail .rail-item .count { display: inline-block; }
  .app-shell[data-rail="open"] .rail .rail-item { justify-content: flex-start; padding: 7px 8px; }
  .app-shell[data-rail="open"] .rail-footer { justify-content: flex-start; }
}

/* Expanding the rail on a laptop takes 176px away from the inbox. Tighten the
   two fixed inbox columns instead of dropping the details pane — Assignee and
   Priority live there, and below 1040px they have nowhere else to go. */
@media (min-width: 761px) and (max-width: 1400px) {
  .app-shell[data-rail="open"] .inbox-layout { grid-template-columns: 150px 268px minmax(0, 1fr); }
  .app-shell[data-rail="open"] .thread-with-details { grid-template-columns: minmax(0, 1fr) 224px; }
}

/* .field carries a bottom margin for the stacked login form; inside a grid
   the gap already does that job. */
.form-grid .field { margin-bottom: 0; }

/* ⚠️ app.css title-cases every .select (`text-transform: capitalize`) — a trap
   this codebase has now hit THREE times (.wf-row .select, .rail-footer .role,
   and the 2026-08-21 settings selects rendering "Send Immediately — No Undo").
   Settings selects carry sentences, not one-word statuses: reset them. */
.field .select, .assign-row .select { text-transform: none; }

/* .btn-primary was written as the login card's submit button — full width
   with a top margin. On a settings panel that made "Save" span the whole row.
   Buttons size to their label everywhere except inside the login/join card. */
.btn-primary { width: auto; margin-top: 0; white-space: nowrap; }
.btn-ghost { white-space: nowrap; }
.login-card .btn-primary { width: 100%; margin-top: 6px; }

/* ═══════════════════════════════════════════════════════════════════════
   PHONE (2026-08-08)
   ═══════════════════════════════════════════════════════════════════════
   ⚠️ Before this the narrowest breakpoint was 1040px and the inbox still
   demanded `160px 300px 1fr`. On a 390px phone that is ~470px of columns in
   390px of screen: Maycol's screenshot showed the list running off the right
   edge with the thread pane not reachable at all, and an icon rail plus a
   172px column of centred icons eating half the width for navigation.

   The fix is not narrower columns — three panes never fit. It is a different
   ARCHITECTURE: one column, one pane at a time, navigation moved to the thumb.
   Desktop is untouched; every rule here lives inside the query. */
@media (max-width: 760px) {
  /* ⚠️ dvh, not vh. Mobile browsers count the URL bar inside 100vh, so a vh
     layout puts its last ~90px under the browser chrome — which for this app
     is the composer, the one control that must never be unreachable. */
  html, body, #root { height: 100dvh; }

  /* ---- 2026-08-20 QA fixes ---- */
  /* The desktop rail's active-lane indicator (a bar hanging at left:-12px)
     paints as a detached sliver both in the bottom tab bar and at the filter
     screen's edge — it has no meaningful anchor on a phone. */
  .rail-item.active::before { display: none; }
  /* iOS zoom law: EVERY input ≥16px, including the ones whose desktop rules
     out-specify the bare-input bump below (.field's 12.5px, .select.sm's
     12px — Settings, Team, Login were all zooming). */
  .field input, .field textarea, .select.sm { font-size: 16px; }
  /* Team member rows: controls wrap under the name instead of overlaying it
     and pushing Deactivate off the card edge. */
  .row { flex-wrap: wrap; row-gap: 6px; }
  /* The filters screen's escape hatch (see inbox.js filter-col). */
  .filter-done { width: 100%; justify-content: center; margin-bottom: 12px; }

  /* ---- shell: rail becomes a bottom bar ---- */
  .app-shell {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 1fr) auto;
    height: 100dvh;
  }
  .page-outlet { grid-row: 1; }
  .rail {
    grid-row: 2; flex-direction: row; align-items: center;
    gap: 2px; padding: 6px 8px; overflow-x: auto; overflow-y: hidden;
    border-right: 0; border-top: 1px solid var(--border);
    /* Home-indicator clearance on iPhone. Zero on anything without one. */
    padding-bottom: max(6px, env(safe-area-inset-bottom));
  }
  .rail::-webkit-scrollbar { display: none; }
  .rail h5, .rail-spacer, .ws-name, .rail-footer .who, .rail-footer .avatar { display: none; }
  /* A bottom bar has no edge to pull, and no room to widen into. */
  .rail-tab { display: none; }
  .rail-user { display: none; }
  /* ⚠️ `width: auto` is load-bearing. The rail is a COLUMN everywhere else, so
     .rail-item is full-width by default — turning the container into a row did
     not undo that, and every item stayed 374px. Measured: the bar scrolled
     3118px wide inside a 390px screen, so seven of nine destinations sat off
     the edge of a bar whose whole job is being reachable. */
  .rail-item, .rail-footer .icon-only, .rail-footer .rail-action, .ws-switch {
    flex: 0 0 auto; width: auto; min-width: 44px; min-height: 44px;
    justify-content: center; padding: 8px;
  }
  /* In the bar these are tab-sized icons, not labelled buttons. */
  .rail-action { border: 0; }
  .rail-action .label { display: none; }
  /* Two controls earn their place on a 1500px rail and not on a 390px one.
     Sync runs on its own loop, and the send sound is a preference you set
     once — neither is worth a slot that a destination could use. */
  .rail [data-sync-now], .rail [data-sound] { display: none; }
  /* Anything tappable clears 40px. Measured two at 26px: the list refresh and
     the new filters button. */
  .icon-only { min-width: 40px; min-height: 40px; display: inline-flex;
               align-items: center; justify-content: center; }
  /* ⚠️ flex-direction is restated: the footer stacks into two rows on desktop
     since 2026-08-20, and a bottom bar has exactly one row. */
  .rail-footer { border-top: 0; padding: 0; margin: 0; gap: 2px; flex: 0 0 auto; flex-direction: row; }
  .rail-actions { flex: 0 0 auto; gap: 2px; }
  .ws-menu { left: 8px; right: 8px; width: auto; bottom: 100%; top: auto; }

  /* ---- inbox: one column, one pane ---- */
  .inbox-layout { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr); }
  .inbox-layout > .filter-col,
  .inbox-layout > .list-pane,
  .inbox-layout > .thread-pane { grid-area: 1 / 1; min-width: 0; display: none; }
  .inbox-layout[data-mview="filters"] > .filter-col,
  .inbox-layout[data-mview="list"]    > .list-pane,
  .inbox-layout[data-mview="thread"]  > .thread-pane { display: block; }
  .inbox-layout[data-mview="list"] > .list-pane,
  .inbox-layout[data-mview="thread"] > .thread-pane { display: grid; }
  .filter-col { border-right: 0; }
  .thread-pane { height: 100%; }

  /* The details sidebar is already hidden below 1040; make sure the thread
     column is a single full-width track rather than a 1fr + 240px grid. */
  .thread-with-details { grid-template-columns: 1fr; }
  .details { display: none; }

  /* ---- the two phone-only controls ---- */
  .mobile-only { display: inline-flex !important; }
  .back-btn svg { transform: rotate(90deg); }   /* chevron-down reused as a back arrow */

  /* ⚠️ THE FILTER ROW MUST GROW WITH THE TEXT ON A PHONE (2026-08-20).
     The iOS zoom law above forces .select.sm to 16px — inside the desktop's
     32px box with a 30px line-height, that clipped the descenders clean off:
     "Category", "All" and "Newest" all lost their bottoms in Maycol's
     screenshot. So the box stops being a fixed height down here and grows to
     fit the type instead, at a 44px thumb minimum. The button matches the
     selects at 16px so the three still read as one row. */
  /* ⚠️ TWO PER ROW ON A PHONE, not three. At 16px (the zoom law) three equal
     controls across a 390px screen leaves ~110px each, and "Category" plus its
     chevron does not fit — it came back as "Categor…" (Maycol). Halves fit
     every label at full size, and they stay equal to each other, which is what
     made the earlier lopsided wrap look broken. */
  .fs-row { gap: 8px; flex-wrap: wrap; }
  .fs-row > * { flex: 1 1 calc(50% - 4px); }
  .fs-btn, .fs-row .fs-sel, .fs-clear {
    height: auto; min-height: 44px; line-height: 1.3; padding: 10px 12px; font-size: 16px;
  }
  .fs-btn > span { overflow: visible; }
  .fs-clear { padding: 10px; }
  .list-head .segmented .seg { padding: 10px 6px; font-size: 14px; }
  .tag-opt { padding: 9px 8px; font-size: 14px; }

  /* ---- density: a phone has one third the width, not one third the content ---- */
  .list-head { padding: 10px 12px; }
  .list-head-row { gap: 8px; align-items: center; }
  .list-head h2 { font-size: 16px; }
  .conv-item { padding: 12px; }
  .thread-head { padding: 10px 12px; gap: 8px; flex-wrap: wrap; }
  .thread-head h3 { font-size: 14.5px; }
  .thread-controls { gap: 5px; width: 100%; }
  .thread-controls .select { max-width: none; flex: 1; min-width: 0; }
  .thread-body { padding: 14px 14px; }
  .msg { max-width: 82%; }
  .composer { padding: 10px 12px 12px; }
  /* The draft card matches the composer's phone gutter, and its buttons get a
     thumb-sized hit area like every other control down here. */
  .draft-card { padding: 10px 12px 0; }
  .draft-text { max-height: 34vh; overflow-y: auto; }
  .draft-use { min-height: 38px; padding: 8px 14px; }
  .draft-x { min-width: 32px; min-height: 32px; }

  /* ⚠️ 16px is not a taste decision. iOS Safari ZOOMS the whole page when a
     focused input is under 16px, and it never zooms back out — the composer
     was 13.5px, so tapping to reply silently broke the layout. */
  .composer textarea, .search, .select, input, textarea { font-size: 16px; }
  .btn-send { min-height: 44px; padding: 10px 18px; }

  /* The ⋯ hangs 24px outside the bubble, which fell outside a 14px gutter.
     Bring it in and grow the hit area to a thumb. */
  .react-dots { right: -20px; padding: 6px 8px; opacity: .55; }
  .msg.out .react-dots { right: auto; left: -20px; }
  .react-picker { max-width: calc(100vw - 32px); flex-wrap: wrap; }
  .react-picker.cmt-combo { min-width: 0; width: max-content; max-width: calc(100vw - 40px); }
  .cmt-opt, .react-opt { min-height: 38px; }

  /* Lane list is the whole screen here, so it can breathe. */
  .filter-col { padding: 12px; }
  .rail-item.lane-all, .filter-col .rail-item { min-height: 44px; justify-content: flex-start; }
  .tag-filter { max-height: none; }
}

/* A phone-only control is invisible everywhere else. Declared OUTSIDE the
   query so it is the default, and the query above turns it on. */
.mobile-only { display: none; }

/* Double-Enter sends now (2026-08-24): the whisper next to Undo that teaches
   the shortcut exactly when it is usable, and never any other time. */
.undo-hint { font-size: 11px; color: var(--text-3); white-space: nowrap; align-self: center; }

/* ---- Connection health (2026-08-24) --------------------------------------
   "I must be able to see whether it is connected or not." Green tick / red
   cross, plain words, and the fix next to anything broken. */
.hc-yes { color: var(--ok, #3fa66a); font-weight: 700; }
.hc-no  { color: var(--danger, #d4574f); font-weight: 700; }
.hc-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 8px; padding: 14px 16px;
}
.hc-item {
  display: flex; gap: 9px; align-items: flex-start; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2);
  font-size: 13px;
}
.hc-item.bad { border-color: color-mix(in srgb, var(--danger, #d4574f) 40%, var(--border)); }
.hc-item b { font-weight: 600; display: block; }
.hc-note { display: block; color: var(--text-3); font-size: 11.5px; margin-top: 2px; }
.hc-problems { padding: 0 16px 14px; display: grid; gap: 8px; }
.hc-problem {
  padding: 10px 12px; border-radius: 8px; font-size: 13px;
  border-left: 3px solid var(--danger, #d4574f); background: var(--surface-2);
}
.hc-problem.warn { border-left-color: var(--warn, #d19a3d); }
.hc-problem b { display: block; font-weight: 600; margin-bottom: 3px; }
.hc-problem span { color: var(--text-2); }
.hc-orphans { padding: 0 16px 14px; }
.hc-orphans > b { display: block; font-size: 13px; margin-bottom: 8px; }
.hc-orphan {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 9px 12px; margin-bottom: 6px; border-radius: 8px;
  background: var(--surface-2); border: 1px dashed var(--border-strong); font-size: 13px;
}
.hc-handle { font-weight: 700; }
.hc-orphan em { color: var(--text-3); font-style: normal; font-size: 12px; }
.hc-detail { padding: 0 16px 14px; display: grid; gap: 5px; }
.hc-scopes { padding: 0 16px 16px; font-size: 13px; }
.hc-scopes summary { cursor: pointer; color: var(--text-2); padding: 6px 0; }
.hc-scope { display: flex; gap: 8px; align-items: baseline; padding: 4px 0; }
.hc-scope span { color: var(--text-3); font-size: 12px; }

/* ---- Dashboard rebuild + Activity rebuild (2026-08-25) ---- */
/* Work-next: each row is a DOOR into the thread, styled like win-rows but
   pressable. Text truncates; the row never wraps the layout. */
.wn-list { display: flex; flex-direction: column; gap: 2px; }
.wn-row {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 8px; border-radius: 8px; text-align: left;
  transition: background .1s;
}
.wn-row:hover { background: var(--surface-2); }
.wn-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.wn-title { font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wn-meta { font-size: 11px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Public-comment headline numbers, side by side. */
.pub-split { display: flex; gap: 26px; margin: 2px 0 12px; }
.pub-big { display: flex; flex-direction: column; }
.pub-big .stat-value.muted { color: var(--text-3); }
/* Team / rollup column groups. */
.team-cols { display: grid; grid-template-columns: repeat(3, 58px); text-align: right; gap: 4px; }
.team-cols.four { grid-template-columns: repeat(4, 58px); }
.team-head .team-cols span { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-3); }
/* Activity filters + failed rows. */
.act-filters { display: flex; gap: 8px; margin: 14px 0 4px; align-items: center; }
.act-filters select {
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: 7px; padding: 6px 9px; font-size: 12.5px; color: var(--text);
}
.act-day { margin-top: 14px; }
.feed-row.feed-fail { border-left: 2px solid var(--danger); padding-left: 8px; border-radius: 3px; }
/* The rebuilt feed uses an emoji glyph as the kind marker, not the 6px dot —
   override the legacy dot sizing inside .feed-list only. */
.feed-list .feed-kind {
  width: auto; height: auto; border-radius: 0; background: none;
  margin-top: 1px; font-size: 13px; line-height: 1.4;
}
.feed-list .feed-main { flex: 1; min-width: 0; }

/* ---- Activity cleanup (2026-08-25, "really messy… hard to read") ---- */
/* The rollup as a REAL table: one shared grid template, numbers under their
   labels, zebra hover. A dot means zero — quieter than a dash column. */
.roll-table { display: flex; flex-direction: column; }
.roll-row {
  display: grid; grid-template-columns: 1fr 82px 82px 82px 82px;
  align-items: center; padding: 8px 16px; gap: 6px;
}
.roll-row + .roll-row { border-top: 1px solid var(--border); }
.roll-row > .num { text-align: right; font-size: 13px; }
.roll-head { padding: 6px 16px; }
.roll-head span {
  text-align: right; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-3); font-weight: 600;
}
.roll-who { font-size: 12.5px; font-weight: 550; }
/* Collapsed day headers: the whole strip is the button. */
.act-day { margin-top: 10px; overflow: hidden; }
.act-day-head {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 11px 16px; text-align: left; cursor: pointer;
}
.act-day-head:hover { background: var(--surface-2); }
.act-day-head h3 { margin: 0; font-size: 13px; font-weight: 600; flex-shrink: 0; }
.act-chevron { color: var(--text-3); font-size: 11px; width: 12px; flex-shrink: 0; }
.act-summary {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11.5px; color: var(--text-3);
}
.act-day.open .act-day-head { border-bottom: 1px solid var(--border); }
/* Feed rows: ONE line each — glyph, sentence, time — instead of two-line
   cards with dead air between them. */
.feed-list .feed-row { display: flex; align-items: baseline; gap: 9px; padding: 6px 16px; }
.feed-list .feed-text {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12.5px; line-height: 1.5;
}
.feed-list .feed-time { flex-shrink: 0; font-size: 11px; color: var(--text-3); margin: 0; }

/* ---- Edit our own reply in the bubble (2026-09-25, Sweet's ask) ---------- */
.cmt-edit-btn { background: none; border: 0; padding: 0; font: inherit; font-size: inherit; color: var(--text-3); cursor: pointer; }
.cmt-edit-btn:hover { color: var(--text); text-decoration: underline; }
.msg.is-editing { width: min(640px, 100%); }
.cmt-edit-box { display: block; width: 100%; box-sizing: border-box; min-height: 72px; resize: vertical;
  font: inherit; line-height: 1.5; color: var(--text); background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: 9px; padding: 8px 10px; }
.cmt-edit-box:focus { outline: 2px solid color-mix(in srgb, var(--accent, #3b82f6) 40%, transparent); }
.cmt-edit-row { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.cmt-edit-row .btn, .cmt-edit-row .btn-ghost { padding: 6px 11px; font-size: 12.5px; }
.cmt-edit-btn.danger:hover { color: var(--danger); }
