/* Panel stylesheet. It lives in a file rather than in a <style> block in the
   layout so the panel's Content-Security-Policy can be a plain
   "default-src 'self'" with no inline-style exemption (phase 14.A). Any rule
   added here must therefore stay here: an inline style="..." attribute in a
   template is blocked by that policy and silently does nothing. */

:root { color-scheme: light dark; }
* { box-sizing: border-box; }
body {
  font: 15px/1.5 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  margin: 0; padding: 2rem 1rem; background: #f6f7f9; color: #1b1f24;
}
@media (prefers-color-scheme: dark) {
  body { background: #14171a; color: #e6e8eb; }
  .card { background: #1d2125 !important; border-color: #2b3138 !important; }
  input { background: #14171a !important; color: inherit !important; border-color: #2b3138 !important; }
}
main { max-width: 42rem; margin: 0 auto; }
h1 { font-size: 1.4rem; margin: 0 0 1rem; }
.card {
  background: #fff; border: 1px solid #e2e5e9; border-radius: 10px;
  padding: 1.5rem; margin: 0 auto;
}
.card.narrow { max-width: 24rem; }
label { display: block; font-weight: 600; margin: 0.9rem 0 0.3rem; }
input {
  width: 100%; padding: 0.55rem 0.7rem; font-size: 1rem;
  border: 1px solid #cfd4da; border-radius: 6px; background: #fff;
}
/* One vocabulary for actions. Anything that performs an action looks like a
   button: a <button>, or an <a> carrying .btn/.danger where the action is a
   plain navigation (the delete confirmation page, the full queue view).
   Several of these used to render as bold blue text instead — a POST wrapped
   in form.inline, a <details> toggle, the delete links — which read as links
   and left two appearances for the same kind of control. They all get the
   button look now: filled for a card's own action, and the compact outlined
   variant further down where actions cluster (table rows, the nav bar). Bare
   <a> is left for links that read as part of a sentence or a list. */
button, a.btn, a.danger {
  display: inline-block; margin-top: 1.2rem; padding: 0.6rem 1.1rem;
  font: inherit; font-size: 1rem; font-weight: 600; text-decoration: none;
  color: #fff; background: #2563eb; border: 0; border-radius: 6px; cursor: pointer;
}
button:hover, a.btn:hover { background: #1d4ed8; }
.error { color: #b42318; margin: 0.6rem 0 0; font-weight: 600; }
.muted { color: #6b7280; }
.topbar { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 1.2rem; }
.topbar .actions { display: flex; gap: 0.9rem; align-items: baseline; }
/* form.inline only exists so a POST can sit next to other content without a
   form's block layout; its button is styled like any other. */
form.inline { display: inline; margin: 0; }
main { max-width: 48rem; }
/* 48rem is a reading measure: right for the forms and prose that make up most
   of the panel, and the width the navigation bar's two rows were sized for. The
   three monitoring pages hold data instead — seven columns of send-log, and raw
   mail.log lines that are long by nature — and at that width the send-log's
   Subject and Status were fighting over the last inch while the log pages wrapped
   every second line. They get a wider measure; every other page keeps the narrow
   one. The class comes from the layout, which stamps the page name onto <main>. */
main.page-deliveries, main.page-mail_queue, main.page-system_log { max-width: 64rem; }
.card + .card { margin-top: 1.2rem; }
.flash { background: #ecfdf3; border: 1px solid #abefc6; color: #067647; padding: 0.7rem 1rem; border-radius: 8px; margin-bottom: 1.2rem; }
@media (prefers-color-scheme: dark) { .flash { background: #0d2818 !important; border-color: #1a5336 !important; color: #75d99b !important; } }
table { width: 100%; border-collapse: collapse; }
/* A table column is at least as wide as the longest unbreakable run inside it,
   and the panel's tables are full of runs with nothing to break on: email
   addresses, domains, queue ids. One 40-character recipient was enough to widen
   the send-log past its card and hang Status over the edge. Cells may break mid
   word, so a column can always be squeezed to the width available. */
th, td { text-align: left; padding: 0.5rem 0.4rem; border-bottom: 1px solid #e2e5e9; overflow-wrap: anywhere; }
/* The exception: a timestamp broken across two lines is unreadable, and it is
   short enough to never be the reason a row does not fit. */
td.time { white-space: nowrap; }
@media (prefers-color-scheme: dark) { th, td { border-color: #2b3138 !important; } }
th { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.03em; color: #6b7280; }
td.actions { text-align: right; }
/* Subject is the one cell whose text we do not control. Breaking mid word (the
   rule above) keeps it inside the card, but a long subject would do it by
   growing the row several lines tall, which buries the rows around it. So the
   subject is clipped to one line instead, with the whole of it in the tooltip.
   The clamp sits on an inner block box rather than the cell because max-width
   on a <td> is only advisory in the automatic table layout. */
td.subject span {
  display: block; max-width: 18rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.code { display: block; white-space: pre-wrap; word-break: break-all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
        font-size: 0.85rem; background: #f0f2f4; border: 1px solid #e2e5e9; border-radius: 6px; padding: 0.7rem 0.8rem; margin: 0.3rem 0 0; }
@media (prefers-color-scheme: dark) { .code { background: #14171a !important; border-color: #2b3138 !important; } }
h2 { font-size: 1.05rem; margin: 0 0 0.4rem; }
.back { display: inline-block; margin-bottom: 1rem; }
/* Build version, closing every authenticated page. Quiet on purpose: it is
   reference material, not something to read on the way past. */
.version { margin-top: 1.6rem; text-align: right; font-size: 0.8rem; color: #6b7280; }
select, textarea {
  width: 100%; padding: 0.55rem 0.7rem; font-size: 1rem;
  border: 1px solid #cfd4da; border-radius: 6px; background: #fff; color: inherit;
  font-family: inherit;
}
textarea { resize: vertical; }
@media (prefers-color-scheme: dark) {
  select, textarea { background: #14171a !important; color: inherit !important; border-color: #2b3138 !important; }
}
button.danger, a.danger { background: #b42318; }
button.danger:hover, a.danger:hover { background: #912018; }
/* The disclosure toggle is an action too, so it is drawn as a button (see the
   compact rule below); the marker is dropped because the pressed background
   already shows the open state. */
.actions summary { display: inline-block; list-style: none; cursor: pointer; }
.actions summary::-webkit-details-marker { display: none; }
/* Applications are a list of blocks, not table rows. As a table it fell apart:
   four columns of which the last held six controls — two of them <details>
   panels with textareas — never fit the panel's 48rem. The controls wrapped
   into a staircase, .code on the login cell grew into a slab as tall as the
   row, and the two text cells sat on the baseline halfway down it. One block
   per application gives the identity a line of its own and the controls a row
   of their own, at the width they actually need. */
.apps { list-style: none; margin: 1.2rem 0 0; padding: 0; }
.app { padding: 0.9rem 0; border-top: 1px solid #e2e5e9; }
.app:last-child { padding-bottom: 0; }
@media (prefers-color-scheme: dark) { .app { border-color: #2b3138 !important; } }
.app-login { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 600; }
.app-addr { margin: 0.15rem 0 0; word-break: break-all; }
.app .actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.7rem; }
/* An open panel claims a row to itself: its textareas and number inputs want
   the block's full width, not the width of the summary that opened them. */
.app .actions > details[open] { flex: 1 0 100%; }
details form { margin-top: 0.6rem; }
.credential { border-color: #f5c518; background: #fffbeb; }
@media (prefers-color-scheme: dark) { .credential { background: #2a2408 !important; border-color: #6b5a10 !important; } }
/* Panel navigation: rendered once from the layout, so it is present on every
   authenticated page without each content template having to include it. */
/* Two deliberate rows, not one. The six page entries need about 660px and the
   session block another 260px, against the 738px the panel is wide — so the bar
   was wrapping on its own, and the session landed left-aligned directly under
   the entries, reading as a third row of navigation. Shortening labels would buy
   the ~200px back but undo the point of naming each entry after its page. Rows
   rather than columns: a two-column grid of entries came out a third taller
   (107px against 83px) and no easier to read.
   The session sits on top, at the right edge, and the page entries below — the
   usual arrangement, and the layout template puts the session first so the
   reading and tab order follow what the eye sees rather than being flipped by a
   CSS `order`. The cost is that Sign out is the bar's first tab stop; nothing
   activates on focus, so that is a reordering, not a hazard. */
.nav {
  display: flex; flex-direction: column; align-items: stretch;
  gap: 0.5rem; margin-bottom: 1.2rem; padding-bottom: 0.6rem;
  border-bottom: 1px solid #e2e5e9;
}
@media (prefers-color-scheme: dark) { .nav { border-color: #2b3138 !important; } }
.nav .links, .nav .session { display: flex; flex-wrap: wrap; gap: 0.2rem 0.9rem; align-items: center; }
/* Pushed to the far edge so the two rows read as two blocks rather than as one
   ragged list that happened to wrap. */
.nav .session { justify-content: flex-end; }
/* Each entry pairs an icon with its label, so the entry itself is a flex row
   rather than a run of text — that is also why the bar centres its items
   instead of aligning them on the text baseline. Account is included: it is a
   page like the others and would otherwise be the one bare word in the bar. */
.nav a, .nav [aria-current] {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.2rem 0.5rem; border-radius: 6px;
}
.nav [aria-current] {
  font-weight: 600; color: #1b1f24; background: #e6ebf5; box-shadow: inset 0 -2px 0 #2563eb;
}
@media (prefers-color-scheme: dark) {
  .nav [aria-current] { color: #e6e8eb !important; background: #22303f !important; }
}
/* Sign out carries an icon too, so it needs the same row layout; its padding
   and colours come from the compact button rule further down. */
.nav button { display: inline-flex; align-items: center; gap: 0.4rem; }
/* The icons draw in the entry's own colour, so the active entry's darker text,
   a link's blue and Sign out's red all carry through without a rule apiece. */
.nav .icon { width: 1rem; height: 1rem; flex: none; }
/* Status badges: one vocabulary (ok/warn/error/unknown) shared by the server
   status page and the per-domain DNS checks, so a colour means the same thing
   everywhere. The class suffix is the check's own status value. */
.st {
  display: inline-block; padding: 0.05rem 0.45rem; border-radius: 999px;
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  vertical-align: middle; border: 1px solid transparent;
}
.st-ok { background: #ecfdf3; color: #067647; border-color: #abefc6; }
.st-warn { background: #fffaeb; color: #b54708; border-color: #fedf89; }
.st-error { background: #fef3f2; color: #b42318; border-color: #fecdca; }
.st-unknown { background: #f0f2f4; color: #6b7280; border-color: #e2e5e9; }
@media (prefers-color-scheme: dark) {
  .st-ok { background: #0d2818 !important; color: #75d99b !important; border-color: #1a5336 !important; }
  .st-warn { background: #2e2308 !important; color: #f5c86b !important; border-color: #6b5210 !important; }
  .st-error { background: #2d1211 !important; color: #f5a29b !important; border-color: #6b201a !important; }
  .st-unknown { background: #22262b !important; color: #9aa3ad !important; border-color: #2b3138 !important; }
}
.code-row { display: flex; align-items: flex-start; gap: 0.5rem; }
.code-row .code { flex: 1; min-width: 0; }
/* Compact outlined button: same affordance as the filled one but quiet enough
   that several can sit together without shouting — the Copy buttons beside a
   value, the controls of a table row or of an application block. Sign out
   overrides this with .danger below since signing out is a deliberate,
   singular action. .actions is the shared hook: a cell that holds controls, or
   the control row of an application. */
button.copy, .actions button, .actions summary, .actions a.danger, .nav button {
  margin: 0; padding: 0.45rem 0.7rem; font-size: 0.8rem; font-weight: 600;
  border-radius: 6px; white-space: nowrap;
  background: #eef1f5; color: #2563eb; border: 1px solid #cfd4da;
}
button.copy:hover, .actions button:hover, .actions summary:hover,
.actions a.danger:hover, .nav button:hover { background: #e2e7ee; }
button.copy { flex: none; margin-top: 0.3rem; }
.actions details[open] > summary { background: #dde3ec; }
.actions button.danger, .actions a.danger, .nav button.danger {
  color: #b42318; background: #fef3f2; border-color: #fecdca;
}
.actions button.danger:hover, .actions a.danger:hover, .nav button.danger:hover { background: #fee4e2; }
@media (prefers-color-scheme: dark) {
  button.copy, .actions button, .actions summary, .actions a.danger, .nav button {
    background: #22262b !important; border-color: #2b3138 !important;
  }
  button.copy:hover, .actions button:hover, .actions summary:hover,
  .actions a.danger:hover, .nav button:hover { background: #2b3138 !important; }
  .actions details[open] > summary { background: #313841 !important; }
  .actions button.danger, .actions a.danger, .nav button.danger {
    color: #f5a29b !important; background: #2d1211 !important; border-color: #6b201a !important;
  }
  .actions button.danger:hover, .actions a.danger:hover, .nav button.danger:hover { background: #3d1a18 !important; }
}
