/* The console, in the app's own tokens.
 *
 * Same palette as lib/src/theme — the office and the client are looking at the
 * same practice, and a console in stock Bootstrap blue would be the only
 * surface that does not say so.
 *
 * No build step and no CDN: this is an office tool that has to open on the
 * morning the internet is down. One stylesheet, served from the app.
 */

:root {
  --ink:        #14201B;
  --ink-2:      #46534C;
  --ink-3:      #6E7A73;
  --navy:       #0E3B2E;
  --navy-deep:  #082A20;
  --navy-lift:  #16553F;
  --navy-tint:  #E4EDE7;
  --mint:       #7FD4B0;
  --caution:    #944906;
  --caution-bg: #FBEFE4;
  --ground:     #F1F2EE;
  --row-hover:  #FAFBF9;

  /* On a primary fill. Its own token because the fill inverts in dark
   * mode and white-on-mint is unreadable. */
  --on-primary: #FFFFFF;

  /* State. Every pill, flash and note draws from these — six components
   * reading one pair is what stops 'delivered' being green on one screen
   * and grey on the next. */
  --work-bg:    #E8F0FB;  --work-fg:   #1B4B8F;
  --good-bg:    #E6F5EE;  --good-fg:   #146B45;  --good-line: #BCE3D0;
  --dead-bg:    #F2F2F0;
  --bad-bg:     #FBE8E8;  --bad-fg:    #9B1C1C;  --bad-line:  #E8C4C4;
  --scrim:      rgba(8, 20, 15, 0.44);
  --surface:    #FFFFFF;
  --hairline:   #DCE0D8;
  --line:       #CBD2C6;

  --rail: 232px;
  --pad: 24px;
  --radius: 10px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}

a { color: var(--navy); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.01em; text-wrap: balance; }
h1 { font-size: 24px; }
h2 { font-size: 17px; }
h3 { font-size: 14px; }

/* -- shell ------------------------------------------------------------- */

.shell { display: grid; grid-template-columns: var(--rail) 1fr; min-height: 100vh; }

.rail {
  background: var(--navy-deep);
  color: #fff;
  padding: 20px 0;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.rail__mark { padding: 0 20px 20px; font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.rail__mark span { color: var(--mint); }
.rail__group { padding: 14px 20px 6px; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.08em; color: rgba(255,255,255,0.42); }
.rail a {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 20px; color: rgba(255,255,255,0.78); font-size: 14px;
}
.rail a:hover { background: rgba(255,255,255,0.06); color: #fff; text-decoration: none; }
.rail a.is-on { background: var(--navy-lift); color: #fff; font-weight: 600;
  box-shadow: inset 3px 0 0 var(--mint); }
.rail__count { font-size: 12px; background: rgba(255,255,255,0.14); color: #fff;
  border-radius: 999px; padding: 1px 7px; }
.rail a.is-on .rail__count { background: var(--mint); color: var(--navy-deep); }
.rail__foot { margin-top: auto; padding: 16px 20px 0; border-top: 1px solid rgba(255,255,255,0.1);
  font-size: 13px; color: rgba(255,255,255,0.6); }
.rail__foot strong { display: block; color: #fff; font-weight: 600; }
.rail__foot a { padding: 6px 0; color: var(--mint); }

.main { min-width: 0; }

.topbar {
  background: var(--surface); border-bottom: 1px solid var(--hairline);
  padding: 16px var(--pad); display: flex; align-items: center; gap: 16px;
  position: sticky; top: 0; z-index: 5;
}
.topbar__title { flex: 1; min-width: 0; }
.topbar__title p { margin: 2px 0 0; color: var(--ink-3); font-size: 13px; }

.page { padding: var(--pad); max-width: 1240px; }

/* -- cards, tables ------------------------------------------------------ */

.card { background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius); }
.card + .card { margin-top: 16px; }
.card__head { padding: 14px 18px; border-bottom: 1px solid var(--hairline);
  display: flex; align-items: center; gap: 12px; }
.card__head h2 { flex: 1; }
.card__body { padding: 18px; }
.card__body--flush { padding: 0; }

.grid { display: grid; gap: 16px; }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--side { grid-template-columns: minmax(0, 1fr) 340px; align-items: start; }

.stat { background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius); padding: 16px 18px; display: block; color: inherit; }
.stat:hover { border-color: var(--line); text-decoration: none; }
.stat__n { font-size: 30px; font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; }
.stat__k { font-size: 12px; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--ink-3); margin-top: 4px; }
.stat--alert { border-color: var(--caution); background: var(--caution-bg); }
.stat--alert .stat__n, .stat--alert .stat__k { color: var(--caution); }
.stat--on { border: 2px solid var(--caution); padding: 15px 17px; }

.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--ink-3); font-weight: 600; padding: 10px 14px;
  border-bottom: 1px solid var(--hairline); white-space: nowrap; }
td { padding: 12px 14px; border-bottom: 1px solid var(--hairline); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--row-hover); }
td .sub { display: block; color: var(--ink-3); font-size: 12.5px; margin-top: 2px; }
.mono { font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; }

/* -- status ------------------------------------------------------------- */

.pill { display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
  font-weight: 600; padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  border: 1px solid transparent; }
.pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; }
.pill--wait { background: var(--caution-bg); color: var(--caution); }
.pill--open { background: var(--navy-tint); color: var(--navy); }
.pill--work { background: var(--work-bg); color: var(--work-fg); }
.pill--done { background: var(--good-bg); color: var(--good-fg); }
.pill--dead { background: var(--dead-bg); color: var(--ink-3); }
.pill--late { background: var(--bad-bg); color: var(--bad-fg); }
/* Semantic aliases the views were already using. These three had no rule at
   all, so nine pills — "Lapsed" and "Covered" on Retainers among them —
   rendered identically to one another and to the neutral default. */
.pill--bad { background: var(--bad-bg); color: var(--bad-fg); }
.pill--good { background: var(--good-bg); color: var(--good-fg); }
.pill--warn { background: var(--caution-bg); color: var(--caution); }
/* The "you have not read past here" line. A rule with the count sitting in it,
   the way every messenger draws it, because that is the shape people already
   know how to read. */
.thread__new { display: flex; align-items: center; gap: 10px; margin: 4px 0;
  font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--navy); }
.thread__new::before,
.thread__new::after { content: ''; flex: 1; height: 1px; background: var(--navy-tint); }

/* Read receipts. Quiet enough to ignore when everything is fine, and only the
   "not opened" state is coloured — that is the one that changes what you do. */
.seen { color: var(--ink-3); }
.unseen { color: var(--caution); font-weight: 600; }

/* A template written for THIS kind of work. Outlined in the brand rather than
   filled: it is a hint about which chip to reach for, not a call to action. */
.btn--scoped { border-color: var(--navy); color: var(--navy); }

/* Somebody composing at the other end. Italic and quiet: it appears and
   disappears on its own, and anything with weight would pull the eye every
   few seconds for something that is not news. */
.typing {
  padding: 0 18px 12px; font-size: 13px; font-style: italic;
  color: var(--ink-3);
}

/* The keyboard cursor. A left edge rather than a background: a whole row
   shaded reads as "selected" and collides with the tick column, which means
   something else entirely. */
tr.is-cursor > td:first-child { box-shadow: inset 3px 0 0 var(--navy); }
tr.is-cursor > td { background: var(--navy-tint); }

/* Assigning from the list. Sized down so a column of these does not turn the
   queue into a form — the row is still a row, with one control in it. */
.inline-assign { margin: 0; }
.inline-assign select {
  font-size: 12px; padding: 3px 22px 3px 7px; border-radius: 6px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  max-width: 130px; }
.inline-assign select:hover { border-color: var(--navy); }

/* Unread. Solid rather than tinted like the status pills: this is not a state
   the order is IN, it is a thing waiting to be done, and it has to win the row
   against a status pill sitting four columns away. */
.pill--new { background: var(--navy); color: #fff; }
.pill--new::before { background: var(--mint); }
.pill--flat { background: transparent; border-color: var(--line); color: var(--ink-2); }
.pill--flat::before { display: none; }

/* -- controls ----------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font: inherit; font-size: 14px; font-weight: 600; padding: 9px 16px;
  border-radius: 8px; border: 1px solid var(--line); background: var(--surface);
  color: var(--ink); cursor: pointer; text-decoration: none;
}
.btn:hover { border-color: var(--ink-3); text-decoration: none; }
.btn--primary { background: var(--navy); border-color: var(--navy); color: var(--on-primary); }
.btn--primary:hover { background: var(--navy-lift); border-color: var(--navy-lift); }
.btn--danger { background: var(--surface); border-color: var(--bad-line); color: var(--bad-fg); }
.btn--danger:hover { background: var(--bad-bg); border-color: var(--bad-fg); }
.btn--sm { padding: 5px 11px; font-size: 13px; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.field { display: block; margin-bottom: 14px; }
.field > span { display: block; font-size: 13px; font-weight: 600; margin-bottom: 5px; }
.field .hint { font-weight: 400; color: var(--ink-3); font-size: 12.5px; }
/* `input:not([type])` is not redundant: an <input> with the attribute simply
   absent behaves as a text box but matches none of the selectors above, so it
   rendered as a bare browser control next to properly styled siblings. */
input[type=text], input[type=email], input[type=password], input[type=date],
input[type=number], input[type=search], input:not([type]), select, textarea {
  width: 100%; font: inherit; font-size: 14px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
  color: var(--ink);
}
textarea { min-height: 88px; resize: vertical; }
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--navy); outline-offset: -1px; border-color: var(--navy);
}

/* EVERYTHING focusable, not just form fields. Buttons, links, summaries and
   the table rows the keyboard walks all had the browser's default outline —
   which several browsers draw as a one-pixel dotted line nobody can see on a
   white card. A console somebody works in all day has to show where they are.

   `:focus-visible`, so a mouse click does not leave a ring behind it. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Off-screen until tabbed to. The rail is a dozen links and it comes before
   the page on every screen, so working by keyboard meant tabbing through all
   of it to reach the queue — every time. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--navy); color: #fff; padding: 10px 16px;
  border-radius: 0 0 8px 0; font-size: 14px; font-weight: 600;
}
.skip:focus { left: 0; }

/* The page itself takes focus when the skip link lands, and must not draw a
   ring around the entire screen when it does. */
.page:focus { outline: none; }
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; }
.filters .field { margin: 0; min-width: 150px; }

.err { color: var(--bad-fg); font-size: 13px; margin-top: 5px; }
.note { background: var(--navy-tint); border-radius: 8px; padding: 12px 14px;
  font-size: 13.5px; color: var(--navy); }
.note--caution { background: var(--caution-bg); color: var(--caution); }
.note--bad { background: var(--bad-bg); color: var(--bad-fg); }
.note--bad a { color: inherit; }

/* PAN and GSTIN checks — the client's Taxpayers card and the edit page. */
.pill--green { background: var(--good-bg); color: var(--good-fg); }
.pill--amber { background: var(--caution-bg); color: var(--caution); }
.pill--red { background: var(--bad-bg); color: var(--bad-fg); }
.pill--grey { background: var(--dead-bg); color: var(--ink-2); }
.checks td { vertical-align: middle; }
.checks td .sub { margin-top: 5px; }
.said { margin: 0; display: grid; grid-template-columns: auto minmax(0, 1fr);
  column-gap: 12px; row-gap: 8px; font-size: 13px; }
.said dt { color: var(--ink-3); }
.said dd { margin: 0; }
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip { display: inline-flex; align-items: center; gap: 8px; font-size: 13px;
  font-weight: 600; padding: 8px 12px; border-radius: 10px; }
.chip::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.chip--good { background: var(--good-bg); color: var(--good-fg); }
.chip--bad { background: var(--bad-bg); color: var(--bad-fg); }
.chip--idle { background: var(--dead-bg); color: var(--ink-2); }
.setup-steps { margin: 0; padding: 14px 16px 14px 34px; background: var(--dead-bg);
  border-radius: 10px; font-size: 13.5px; line-height: 1.65; }

.flash { margin-bottom: 16px; padding: 12px 16px; border-radius: 8px;
  background: var(--good-bg); color: var(--good-fg); font-weight: 500;
  border: 1px solid var(--good-line);
  /* Positioned, not flexed. A flash is written as prose — a bare <strong>
   * followed by a text node — and making the box a flex container turned that
   * <strong> into a column of its own, so "The scheduler has never run."
   * stacked one word per line beside the rest of the sentence. The dismiss
   * button gets a reserved gutter instead, which holds whatever the message
   * is made of. */
  position: relative; padding-right: 40px; }
.flash--bad { background: var(--bad-bg); color: var(--bad-fg); border-color: var(--bad-line); }
/* Saved, but not entirely. The third outcome a form can have: the row was
   written and something beside it was not, which is neither a success worth
   a tick nor a failure worth stopping for. */
.flash--warn { background: var(--caution-bg); color: var(--caution); border-color: var(--caution); }
.flash__x { position: absolute; top: 8px; right: 10px;
  background: none; border: 0; color: inherit; opacity: 0.55;
  font-size: 20px; line-height: 1; cursor: pointer; padding: 0 2px; }
.flash__x:hover { opacity: 1; }

/* On a mint fill in dark mode, white at 60% is barely there. */
.msg--us .msg__who { color: color-mix(in srgb, var(--on-primary) 62%, transparent); }

.empty { padding: 44px 20px; text-align: center; color: var(--ink-3); }
.empty strong { display: block; color: var(--ink); font-weight: 600; margin-bottom: 4px; }

.row { display: flex; align-items: center; gap: 10px; }
.row--between { justify-content: space-between; }
.wrap { flex-wrap: wrap; }
.spacer { flex: 1; }
.muted { color: var(--ink-3); }
.small { font-size: 13px; }
.stack > * + * { margin-top: 12px; }

/* -- the thread --------------------------------------------------------- */

/* A conversation, not a transcript stapled to the page.
   The newest message is at the BOTTOM, so a thread that grew past a screen
   pushed the composer — and everything said recently — below the fold, and
   sending scrolled you back to the oldest line in it. Its own scrolling pane,
   parked at the newest, is what every messenger does and what console.js
   keeps it at. */
.thread {
  display: flex; flex-direction: column; gap: 12px; padding: 18px;
  max-height: 55vh; overflow-y: auto; overscroll-behavior: contain;
}
.msg { max-width: 76%; padding: 10px 13px; border-radius: 12px; font-size: 14px; }
.msg__who { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-3); margin-bottom: 3px; }
.msg--them { background: var(--ground); border: 1px solid var(--hairline); align-self: flex-start; }
.msg--us { background: var(--navy); color: var(--on-primary); align-self: flex-end; }

.msg--note { background: var(--caution-bg); border: 1px dashed var(--caution);
  color: var(--caution); align-self: flex-end; }
.msg--note .msg__who { color: var(--caution); }
.msg--system { align-self: center; max-width: 100%; background: transparent;
  color: var(--ink-3); font-size: 12.5px; text-align: center; padding: 2px; }
.msg time { display: block; font-size: 11px; opacity: 0.65; margin-top: 4px; }

/* -- the acceptance gate, drawn ---------------------------------------- */

.gate { border: 1px solid var(--caution); background: var(--caution-bg);
  border-radius: var(--radius); padding: 18px; }
.gate h2 { color: var(--caution); margin-bottom: 6px; }
.gate p { margin: 0 0 14px; color: var(--caution); font-size: 13.5px; }

.steps { display: flex; gap: 4px; margin: 0 0 4px; padding: 0; list-style: none; }
.steps li { flex: 1; font-size: 11px; color: var(--ink-3); text-align: center; }
.steps li::before { content: ''; display: block; height: 4px; border-radius: 2px;
  background: var(--hairline); margin-bottom: 6px; }
.steps li.is-done::before { background: var(--navy); }
.steps li.is-now::before { background: var(--mint); }
.steps li.is-now { color: var(--ink); font-weight: 600; }

/* -- the permission matrix --------------------------------------------- */

.matrix th:first-child { width: 40%; }
.matrix td { text-align: center; }
.matrix td:first-child { text-align: left; }
.matrix .yes { color: var(--good-fg); font-weight: 700; }
.matrix .own { color: var(--caution); font-weight: 700; font-size: 12px; }
.matrix .no { color: var(--line); }
.matrix tr.is-sensitive td:first-child::after {
  content: 'sensitive'; margin-left: 8px; font-size: 10px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--caution); border: 1px solid var(--caution);
  border-radius: 3px; padding: 0 4px; vertical-align: middle;
}

/* -- sign-in ------------------------------------------------------------ */

.signin { min-height: 100vh; display: grid; place-items: center; padding: 24px;
  background: var(--navy-deep); }
.signin__card { background: var(--surface); border-radius: 14px; padding: 32px;
  width: 100%; max-width: 380px; }
.signin__mark { font-size: 22px; font-weight: 700; letter-spacing: -0.02em;
  margin-bottom: 4px; }
.signin__mark span { color: var(--navy-lift); }
.signin__sub { color: var(--ink-3); font-size: 13.5px; margin: 0 0 22px; }

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .rail { position: static; height: auto; flex-direction: row; flex-wrap: wrap;
    align-items: center; padding: 12px; }
  .rail__group, .rail__foot { display: none; }
  .rail a { padding: 6px 10px; }
  .grid--4, .grid--3, .grid--2, .grid--side { grid-template-columns: 1fr; }
}

@media print {
  .rail, .topbar, .btn, form { display: none !important; }
  .shell { grid-template-columns: 1fr; }
  .card { border-color: #999; break-inside: avoid; }
}

/* -- dark ---------------------------------------------------------------
 *
 * Three states, not two. An explicit choice stamps data-theme on <html>; the
 * default "follow the machine" stamps nothing, so only prefers-color-scheme
 * separates it. Both blocks below redefine TOKENS ONLY — a component whose
 * colour is declared inside one of them would render one theme's ink on the
 * other theme's ground for everybody who never touched the toggle.
 *
 * Filing season runs late. An office tool that is a white rectangle at 11pm
 * is the one people complain about.
 */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink:        #E7EDE9;
    --ink-2:      #AFBBB4;
    --ink-3:      #7F8C85;
    --navy:       #6FCFA6;
    --navy-deep:  #0A1310;
    --navy-lift:  #1E4A3A;
    --navy-tint:  #17342A;
    --mint:       #7FD4B0;
    --caution:    #E8A33D;
    --caution-bg: #33240F;
    --ground:     #0E1512;
    --surface:    #161F1B;
    --hairline:   #26312B;
    --line:       #36443C;
    --row-hover:  #1B2621;
    --on-primary: #06231A;
    --work-bg:    #16243A;  --work-fg:   #8FB6EC;
    --good-bg:    #12291F;  --good-fg:   #6FCFA6;  --good-line: #22523E;
    --dead-bg:    #1C231F;
    --bad-bg:     #331819;  --bad-fg:    #F1928F;  --bad-line:  #5A2A2A;
    --scrim:      rgba(0, 0, 0, 0.62);
  }
}

:root[data-theme="dark"] {
  --ink:        #E7EDE9;
  --ink-2:      #AFBBB4;
  --ink-3:      #7F8C85;
  --navy:       #6FCFA6;
  --navy-deep:  #0A1310;
  --navy-lift:  #1E4A3A;
  --navy-tint:  #17342A;
  --mint:       #7FD4B0;
  --caution:    #E8A33D;
  --caution-bg: #33240F;
  --ground:     #0E1512;
  --surface:    #161F1B;
  --hairline:   #26312B;
  --line:       #36443C;
  --row-hover:  #1B2621;
  --on-primary: #06231A;
  --work-bg:    #16243A;  --work-fg:   #8FB6EC;
  --good-bg:    #12291F;  --good-fg:   #6FCFA6;  --good-line: #22523E;
  --dead-bg:    #1C231F;
  --bad-bg:     #331819;  --bad-fg:    #F1928F;  --bad-line:  #5A2A2A;
  --scrim:      rgba(0, 0, 0, 0.62);
}

/* The browser's own widgets — date pickers, selects, scrollbars — read this
 * and stop rendering a white calendar on a dark field. */
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

/* -- theme switch -------------------------------------------------------- */

.themer { display: flex; gap: 2px; padding: 3px; margin-top: 12px;
  background: rgba(255,255,255,0.07); border-radius: 8px; }
.themer button {
  flex: 1; font: inherit; font-size: 11.5px; font-weight: 600; padding: 5px 4px;
  border: 0; border-radius: 6px; background: transparent; cursor: pointer;
  color: rgba(255,255,255,0.6);
}
.themer button:hover { color: #fff; }
.themer button[aria-pressed="true"] { background: var(--navy-lift); color: #fff; }

/* -- command palette ----------------------------------------------------- */

body.is-locked { overflow: hidden; }

.cmdk { position: fixed; inset: 0; z-index: 90; display: grid;
  grid-template-rows: 12vh auto; justify-items: center;
  /* start, not the default stretch: the second row takes the rest of the
   * viewport, and a stretched panel paints its own background all the way to
   * the bottom of the screen under an empty list. */
  align-items: start; }
.cmdk__scrim { position: fixed; inset: 0; background: var(--scrim);
  backdrop-filter: blur(2px); }
.cmdk__panel {
  position: relative; grid-row: 2; width: min(620px, calc(100vw - 32px));
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 24px 60px rgba(0,0,0,0.28);
}

.cmdk__search { display: flex; align-items: center; gap: 10px; padding: 14px 16px;
  border-bottom: 1px solid var(--hairline); color: var(--ink-3); }
.cmdk__search input {
  flex: 1; border: 0; padding: 0; background: transparent; font-size: 15.5px;
  color: var(--ink);
}
.cmdk__search input:focus { outline: 0; }

.cmdk__list { max-height: min(420px, 56vh); overflow-y: auto; padding: 6px; }
.cmdk__group { padding: 10px 10px 5px; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); }
.cmdk__row { display: flex; align-items: baseline; gap: 9px; padding: 9px 10px;
  border-radius: 8px; cursor: pointer; }
.cmdk__row.is-on { background: var(--navy-tint); }
.cmdk__title { font-weight: 600; font-size: 14px; white-space: nowrap; }
.cmdk__row.is-on .cmdk__title { color: var(--navy); }
.cmdk__detail { flex: 1; min-width: 0; color: var(--ink-3); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk__meta { flex: none; color: var(--ink-3); font-size: 12px; }
.cmdk__empty { padding: 34px 16px; text-align: center; color: var(--ink-3);
  font-size: 13.5px; }

.cmdk__foot { display: flex; align-items: center; gap: 14px; padding: 9px 16px;
  border-top: 1px solid var(--hairline); background: var(--ground);
  color: var(--ink-3); font-size: 12px; }
.cmdk__hint { margin-left: auto; }

kbd { font: inherit; font-size: 11px; font-weight: 600; padding: 2px 6px;
  border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px;
  background: var(--surface); color: var(--ink-2); white-space: nowrap; }

.cmdk--sheet .cmdk__panel { padding: 20px 22px 22px; }
.cmdk__sheethead { font-size: 16px; font-weight: 700; margin-bottom: 14px; }
.keys { margin: 0; display: grid; gap: 9px; }
.keys > div { display: flex; align-items: center; gap: 12px; }
.keys dt { flex: none; width: 170px; display: flex; align-items: center; gap: 4px; }
/* 'then' and 'or' are words in a sentence about keys, not keys. */
.keys dt i { font-style: normal; color: var(--ink-3); font-size: 11.5px; }
.keys dd { margin: 0; color: var(--ink-2); font-size: 13.5px; }
.cmdk__note { margin: 16px 0 0; color: var(--ink-3); font-size: 12.5px; }

/* -- the search cue in the topbar ---------------------------------------- */

.seek {
  display: flex; align-items: center; gap: 9px; min-width: 260px;
  padding: 8px 11px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface); color: var(--ink-3); font-size: 13.5px;
  cursor: pointer; text-align: left;
}
.seek:hover { border-color: var(--ink-3); }
.seek span { flex: 1; }

/* -- applied filters ------------------------------------------------------
 *
 * Arriving from "Past the date" on the dashboard used to show a filtered list
 * above an empty filter form: the page was answering a question it never
 * displayed. A chip per active filter is the answer to "why does the list
 * look like this", and each one comes off on its own.
 */

.views { display: flex; flex-wrap: wrap; gap: 6px; }
.views a {
  padding: 6px 13px; border-radius: 999px; font-size: 13px; font-weight: 600;
  border: 1px solid var(--line); color: var(--ink-2); background: var(--surface);
}
.views a:hover { border-color: var(--ink-3); text-decoration: none; }
.views a.is-on { background: var(--navy); border-color: var(--navy);
  color: var(--on-primary); }
.views .views__n { opacity: 0.65; font-weight: 500; }

.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; padding: 4px 6px 4px 11px;
  border-radius: 999px; font-size: 12.5px; font-weight: 500;
  background: var(--navy-tint); color: var(--navy); border: 1px solid transparent;
}
.chip b { font-weight: 700; }
.chip a {
  display: grid; place-items: center; width: 17px; height: 17px; border-radius: 50%;
  background: rgba(0,0,0,0.08); color: inherit; font-size: 13px; line-height: 1;
}
.chip a:hover { background: var(--navy); color: var(--on-primary); text-decoration: none; }

/* -- sortable columns ---------------------------------------------------- */

th a.sort { display: inline-flex; align-items: center; gap: 4px; color: inherit; }
th a.sort:hover { color: var(--ink); text-decoration: none; }
th a.sort::after { content: '↕'; opacity: 0.35; font-size: 11px; }
th a.sort.is-asc::after { content: '↑'; opacity: 1; }
th a.sort.is-desc::after { content: '↓'; opacity: 1; }
th a.sort.is-asc, th a.sort.is-desc { color: var(--navy); }

/* Long queues are read by scrolling; a header that scrolls away with them
 * means counting columns to work out what you are looking at. */
.table-wrap--tall { max-height: calc(100vh - 300px); overflow-y: auto; }
.table-wrap--tall th { position: sticky; top: 0; z-index: 2;
  background: var(--surface); box-shadow: inset 0 -1px 0 var(--hairline); }

/* -- bulk bar -------------------------------------------------------------
 *
 * Sticky, because it used to sit under thirty rows: you ticked a row at the
 * top of the queue and the controls for it were a scroll away.
 */

.bulkbar {
  position: sticky; bottom: 0; z-index: 3;
  background: var(--surface); border-top: 1px solid var(--line);
  box-shadow: 0 -6px 20px rgba(0,0,0,0.06);
  padding: 14px 18px;
}
.bulkbar__count { display: inline-flex; align-items: center; gap: 7px; }
.bulkbar__n {
  display: grid; place-items: center; min-width: 24px; height: 24px; padding: 0 7px;
  border-radius: 999px; background: var(--navy); color: var(--on-primary);
  font-size: 13px; font-weight: 700;
}

/* -- misc ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* -- list footer --------------------------------------------------------- */

.listfoot { display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  margin-top: 16px; }
.listfoot > :last-child { margin-left: auto; }

.perpage { display: flex; align-items: center; gap: 4px; }
.perpage a {
  padding: 3px 9px; border-radius: 7px; font-size: 13px; font-weight: 600;
  color: var(--ink-3); border: 1px solid transparent;
}
.perpage a:hover { border-color: var(--line); text-decoration: none; }
.perpage a.is-on { background: var(--navy-tint); color: var(--navy); }
.perpage__of { margin-left: 8px; }

/* -- permission matrix, editable ---------------------------------------- */

.matrix select.grant {
  width: auto; min-width: 72px; padding: 4px 6px; font-size: 12.5px;
  font-weight: 600; text-align: center;
}
.matrix tfoot td { border-bottom: 0; padding-top: 14px; }
.matrix th .sub { display: block; font-weight: 400; text-transform: none;
  letter-spacing: 0; color: var(--ink-3); font-size: 11px; margin-top: 2px; }

/* ------------------------------------------------------------------ banner
   The app's promotional card, drawn at the app's own proportions so a banner
   can be seen before it is published. Colours are AppTokens: navyLift
   (#16553F) to navyDeep (#082A20), which is the one dark surface in the app,
   and the chip accents are the five the app will actually draw.

   This lives here and not in a <style> on the page because the console layout
   has no styles stack — a @push('styles') would have been silently dropped. */
.bnr { position: relative; width: 100%; max-width: 420px;
  aspect-ratio: 328 / 192; border-radius: 20px; overflow: hidden;
  background: linear-gradient(135deg, #16553F, #082A20); }
.bnr__art { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; }
.bnr__scrim { position: absolute; inset: 0;
  background: linear-gradient(100deg, rgba(8,42,32,.90) 0%,
    rgba(8,42,32,.74) 46%, rgba(8,42,32,.10) 88%); }
.bnr__body { position: absolute; inset: 0; padding: 16px 16px 24px;
  display: flex; flex-direction: column; justify-content: center; }
/* NO text-transform. The app draws the chip exactly as it is typed — its own
   built-in chip reads "Free to use" — so a preview that shouts it would be
   showing something the phone will not. */
.bnr__chip { align-self: flex-start; font-size: 10px; font-weight: 600;
  letter-spacing: .08em; color: #082A20;
  background: #C7D2E2; padding: 3px 9px; border-radius: 999px; }
.bnr__chip:empty { display: none; }
.bnr__chip[data-accent="mint"]   { background: #7FD4B0; }
.bnr__chip[data-accent="amber"]  { background: #E8A33D; }
.bnr__chip[data-accent="violet"] { background: #B79BE8; }
.bnr__chip[data-accent="slate"]  { background: #A3B6C4; }
.bnr__title { margin: 12px 0 4px; max-width: 62%; font-size: 20px;
  line-height: 1.25; font-weight: 600; color: #fff; }
.bnr__sub { margin: 0; max-width: 62%; font-size: 12.5px; line-height: 1.45;
  color: rgba(255,255,255,.66); }
.bnr__sub:empty { display: none; }

/* The whole-banner mode: the picture is shown complete and nothing is drawn
   over it, so the preview drops the scrim and the words and contains rather
   than covers. */
.bnr--whole .bnr__art { object-fit: contain; }
.bnr--whole .bnr__scrim,
.bnr--whole .bnr__body { display: none; }

/* Both artwork modes, side by side on the banner form. The chosen one is lit
   and the other dimmed but still readable, because the point is the
   comparison: artwork that already carries its own headline looks obviously
   wrong under backdrop mode and obviously right under whole. */
.bnrpair { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.bnrpair > figure { margin: 0; flex: 1 1 280px; max-width: 420px; }
.bnrpair figcaption { margin-top: 8px; font-size: 12px; color: var(--ink-3); }
.bnrpair__off { opacity: .45; }
.bnrpair__on figcaption { color: var(--ink); font-weight: 600; }
@media (prefers-reduced-motion: no-preference) {
  .bnrpair > figure { transition: opacity .18s ease; }
}

/* -- problems ----------------------------------------------------------- */
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.muted2 { color: var(--ink-2); }
.bad { color: var(--bad-fg); }
.prob-head { display: flex; justify-content: flex-end; margin-bottom: 14px; }
.prob { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.prob__list { flex: 1 1 300px; max-width: 360px; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.prob__search .seek { display: block; }
.prob__search input { width: 100%; }
.prob__item { display: flex; flex-direction: column; gap: 6px; padding: 14px; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--hairline); color: var(--ink); text-decoration: none; }
.prob__item:hover { text-decoration: none; border-color: var(--line); }
.prob__item.is-on { border: 1.5px solid var(--navy); }
.prob__item .row { gap: 8px; }
.prob__title { flex: 1; }
.prob__detail { flex: 999 1 520px; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.prob__top { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; padding: 16px 18px;
  border-bottom: 1px solid var(--hairline); }
.prob__history { display: flex; flex-wrap: wrap; gap: 16px; padding: 10px 18px; color: var(--ink-2);
  background: var(--row-hover); border-bottom: 1px solid var(--hairline); }
.prob__history b { color: var(--ink); }
.prob__facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; padding: 14px 18px; }
.prob__facts > div { display: flex; flex-direction: column; gap: 3px; align-items: flex-start; }
.prob__said { margin: 0 18px 16px; padding: 12px 14px; border-radius: 8px; background: var(--row-hover);
  line-height: 1.55; white-space: pre-line; }
.prob__thread { padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.prob__line { display: flex; gap: 10px; }
.prob__line time { width: 64px; flex: none; padding-top: 2px; }
.prob__line > div { flex: 1; min-width: 0; white-space: pre-line; }
.prob__note { padding: 8px 12px; border-radius: 8px; background: var(--caution-bg);
  border: 1px dashed var(--caution); color: var(--ink); }
.prob__note .mono { font-size: 10.5px; letter-spacing: 0.06em; color: var(--caution); }
.prob__event { color: var(--ink-2); }
.prob__reply { padding: 0 18px 16px; }
.prob__acts { display: flex; flex-direction: column; gap: 16px; }
.prob__act { padding: 14px; border-radius: 8px; border: 1px solid var(--hairline); display: flex;
  flex-direction: column; gap: 10px; }
.prob__act summary { cursor: pointer; list-style: none; }
.prob__act--danger { border-color: var(--bad-line); background: color-mix(in srgb, var(--bad-bg) 30%, var(--surface)); }
.prob__big { font-size: 15px; font-weight: 600; min-height: 36px; display: flex; align-items: center; }
.prob__return { padding: 0 10px; border-radius: 8px; background: var(--good-bg); color: var(--good-fg); font-weight: 700; }
@media (max-width: 720px) {
  .prob__list { max-width: none; }
  .prob__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.prob-head .views { padding: 4px; border-radius: 10px; background: var(--hairline); gap: 4px; }
.prob-head .views a { border: 0; border-radius: 7px; background: transparent; padding: 7px 14px; }
.prob-head .views a.is-on { background: var(--surface); color: var(--ink); font-weight: 700; }

/* Munim's brief at the head of an order's thread (orders/show). */
.brief { margin: 0 var(--pad) 4px; padding: 14px 16px; border: 1px solid var(--good-line); background: color-mix(in srgb, var(--good-bg) 55%, var(--surface)); border-radius: var(--radius); }
.brief__head { display: flex; align-items: center; gap: 10px; }
.brief__mark { width: 24px; height: 24px; border-radius: 7px; background: var(--navy); color: var(--mint); font-weight: 800; font-size: 12px; display: inline-flex; align-items: center; justify-content: center; }
.brief__lines { margin: 8px 0 6px; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; font-size: 14px; }
.brief__lines li.muted { list-style: none; margin-left: -18px; }
.brief__foot { margin: 0; }
