/* Monitor pages (P2; restyled 30 September 2026 with the rest of the site).
 *
 * A separate file so firm.css stays the shared foundation. Everything below
 * is built out of its tokens, so both themes follow automatically.
 *
 * Loaded from base.html on every signed-in page.
 */

.mon-grid{
  display:grid;gap:14px;margin-top:16px;
  grid-template-columns:repeat(auto-fill,minmax(330px,1fr));
}
.mon-card{padding:18px 20px;display:flex;flex-direction:column;gap:12px;transition:transform .25s var(--ease-out),box-shadow .3s ease}
.mon-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-1)}
.mon-card .head{display:flex;align-items:flex-start;gap:10px}
.mon-card .head .name{
  font-weight:650;font-size:14.5px;line-height:1.35;flex:1;min-width:0;
  overflow-wrap:anywhere;
}
.mon-card .head .name a{color:inherit;text-decoration:none}
.mon-card .head .name a:hover{color:var(--gold-ink)}
.mon-card .plat{
  font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);
}

.mon-stats{
  display:grid;grid-template-columns:repeat(4,1fr);gap:8px;
  border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);
  padding:10px 0;
}
.mon-stats div{display:flex;flex-direction:column;gap:2px;min-width:0}
.mon-stats .k{
  font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
}
.mon-stats .v{font-family:var(--display);font-size:20px;font-weight:800;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.mon-stats .v.good{color:var(--ok)}
.mon-stats .v.bad{color:var(--danger)}

.mon-line{color:var(--muted);font-size:12.5px;overflow-wrap:anywhere}
.mon-err{
  color:var(--warn);font-size:12.5px;border-left:2px solid var(--warn);
  padding-left:10px;overflow-wrap:anywhere;
}
.mon-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.mon-actions .spacer{flex:1}
.mon-actions form{display:inline}

/* wizard */
.wizard{max-width:760px}
.wizard .step{margin-bottom:18px}
.wizard .step-n{
  display:inline-grid;place-items:center;width:22px;height:22px;margin-right:8px;
  border-radius:50%;border:1px solid rgba(var(--gold-rgb),.4);color:var(--gold-ink);
  font-size:11px;font-weight:700;
}
.found{
  display:flex;gap:12px;align-items:flex-start;padding:12px 14px;border-radius:12px;
  border:1px solid rgba(var(--gold-rgb),.35);background:rgba(var(--gold-rgb),.06);
  animation:found-in .45s var(--ease-spring) both;
}
@keyframes found-in{from{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:none}}
.found .t{font-weight:650}
.found .s{color:var(--muted);font-size:12.5px;overflow-wrap:anywhere}
.not-found{
  padding:12px 14px;border-radius:12px;color:var(--danger);
  border:1px solid rgba(var(--danger-rgb),.4);background:rgba(var(--danger-rgb),.07);
}
.radio-row{display:flex;gap:18px;flex-wrap:wrap;align-items:center}
.radio-row label{display:flex;gap:7px;align-items:center;font-size:13px}
.radio-row ul{list-style:none;margin:0;padding:0;display:flex;gap:18px}

/* The activity pane lives in firm.css (.log-drawer / .log-pane): it keeps its
   dark console ground in both themes. Nothing here. */

/* settings tables */
/* firm.css sets `table{min-width:760px}` and `td{white-space:nowrap}` for the
 * wide dashboard-style task table. A .cred-table lives inside a half-width .split
 * panel, where those two pushed the action column clean off the panel: on
 * 14 September 2026 the webhooks page at 1280px had a Delete button that could
 * not be reached or even seen, and a failure message cut off mid-sentence. */
.cred-table{width:100%;min-width:0;border-collapse:collapse;table-layout:auto}
.cred-table th{
  text-align:left;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);font-weight:700;padding:0 12px 8px 0;
}
.cred-table td{
  padding:10px 12px 10px 0;border-top:1px solid var(--line-soft);vertical-align:middle;
  white-space:normal;overflow-wrap:anywhere;
}
.cred-table td.right{text-align:right;padding-right:0;white-space:nowrap}
.cred-table form{display:inline}
/* The proxy Test button's one-line result. Colour is never the only signal:
 * the words say "3/3 exits reachable" or the failure, and the dot only helps
 * you find them. */
.test-slot{display:block;margin-top:4px}
.test-line{
  display:inline-flex;align-items:baseline;gap:6px;
  font-size:12px;line-height:1.45;color:var(--muted);
}
.test-line .dot{
  flex:none;width:6px;height:6px;border-radius:50%;
  background:var(--dot-off);transform:translateY(-1px);
}
.test-line.tone-ok{color:var(--ok)}
.test-line.tone-ok .dot{background:var(--ok)}
.test-line.tone-warn{color:var(--warn)}
.test-line.tone-warn .dot{background:var(--warn)}
.test-line.tone-danger{color:var(--danger)}
.test-line.tone-danger .dot{background:var(--danger)}
.test-slot.htmx-request .test-line{opacity:.4}
.test-slot.htmx-request::after{content:"testing...";font-size:12px;color:var(--muted);margin-left:6px}
.cred-table td.right form + form{margin-left:6px}

.rejected{
  margin-top:10px;font-size:12.5px;color:var(--warn);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
/* align-items:start, or the shorter of two side-by-side panels is stretched to
 * the height of the taller one and ends in a long empty box - which is what
 * "Add a list of exits" looked like next to the gateway form. */
.split{
  display:grid;gap:16px;align-items:start;
  grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
}

/* The `.why` block inside a monitor card is always in a narrow column, so it
 * stacks there whatever the viewport is. At 1280px in the three-up grid the
 * row layout squeezed "the exits were refused by the site (blocked)" into a
 * four-word column beside the button. */
.mon-card .why{flex-direction:column;align-items:stretch}
.mon-card .why .btn{margin-left:0;align-self:flex-start}
/* Cards in one grid row are all as tall as the tallest; without this the
 * buttons stop wherever the text ended and no two cards line up. */
.mon-card .mon-actions{margin-top:auto}

@media (max-width:760px){
  /* Stacked-card mode puts every cell on one flex row. The proxy detail cell
   * holds two things, so let the test result drop to its own line rather than
   * fight the summary for the width. */
  .cred-table td{flex-wrap:wrap}
  .cred-table td .test-slot{flex-basis:100%;margin-top:2px}
  .cred-table td.right{justify-content:flex-end}
}

@media (max-width:640px){
  .mon-stats{grid-template-columns:repeat(2,1fr)}
}

/* settings: the tab strip and the landing page (17 September 2026) ----- */
/* Until now the sub-navigation was seven .btn buttons, the current one a gold
 * primary: it competed with the page's real primary, the buttons lifted 2px on
 * hover and then the page reloaded them flat, and at 400px they wrapped into a
 * two-row grid. This is a tab strip: one row at every width (it scrolls
 * sideways inside itself on a phone; the page never does), an underline for
 * the current tab, and no transform anywhere. */
.subnav{
  display:flex;gap:2px;margin:0 0 18px;border-bottom:1px solid var(--line);
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
}
.subnav::-webkit-scrollbar{display:none}
.subnav a{
  flex:none;padding:9px 12px 11px;margin-bottom:-1px;
  color:var(--muted);font-weight:700;font-size:13px;text-decoration:none;white-space:nowrap;
  border-bottom:2px solid transparent;border-radius:6px 6px 0 0;
  transition:color .15s ease,border-color .15s ease,background-color .15s ease;
}
.subnav a:hover{color:var(--text);background:rgba(var(--gold-rgb),.06);text-decoration:none}
.subnav a[aria-current="page"]{color:var(--gold-ink);border-bottom-color:var(--gold);border-image:linear-gradient(90deg,var(--gold-deep),var(--gold-bright)) 1}
/* the tab you clicked lights up at once, while its page is on the way */
.subnav a.htmx-request{color:var(--gold-ink);border-bottom-color:var(--gold);opacity:.6}
/* the strip clips its overflow, so the focus ring has to sit inside the tab */
.subnav a:focus-visible{outline-offset:-3px;border-radius:6px}

.settings-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
.set-card{
  display:flex;flex-direction:column;gap:5px;padding:16px 18px;
  color:inherit;text-decoration:none;transition:border-color .2s ease;
}
.set-card:hover{text-decoration:none}
.set-card:hover .set-title{color:var(--gold-ink)}
.set-title{transition:color .2s ease}
.set-title{font-weight:800;font-size:15px}
.set-status{font-size:13.5px;overflow-wrap:anywhere}
.set-status.tone-ok{color:var(--ok)}
.set-status.tone-warn{color:var(--warn)}
.set-status.tone-danger{color:var(--danger)}
.set-sub{color:var(--muted);font-size:12.5px}

/* A phone shows a table as stacked cards, one line per cell. Cells marked
 * .optional (Kind, Used by) repeat what the Detail cell already says, so
 * they go, and a row is three lines and its buttons instead of five. */
@media (max-width:760px){
  .cred-table .optional{display:none}
}
.rejected-more{color:var(--muted)}

/* schedules: the panel on the monitor page and the chip on a card ------ */
.schedule-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.schedule-head h2{margin:0;flex:1;min-width:0}
.schedule-empty{margin:12px 0 4px;font-size:13.5px;line-height:1.6;max-width:62ch}
.schedule-next{margin:12px 0 4px;font-weight:650;font-size:14px}
.schedule-note{
  margin:6px 0 0;padding:8px 12px;border-left:2px solid var(--gold);
  color:var(--muted);font-size:12.5px;line-height:1.55;max-width:70ch;
}
.schedule-list{list-style:none;margin:14px 0 8px;padding:0}
.schedule-item{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:9px 0;border-top:1px solid var(--line-soft);
}
.schedule-item:last-child{border-bottom:1px solid var(--line-soft)}
.schedule-item form{display:inline;margin-left:auto}
.schedule-kind{
  flex:none;min-width:62px;font-size:10.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);
}
.schedule-sum{font-size:13.5px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere;min-width:0}
.schedule-item.ended .schedule-sum{color:var(--muted);text-decoration:line-through}
.schedule-flag{
  font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);border:1px solid var(--line);border-radius:999px;padding:1px 8px;
}
.schedule-flag.on{color:var(--ok);border-color:currentColor}
.schedule-add{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-start;margin-top:12px}
.schedule-form{flex:0 1 auto;min-width:0}
.schedule-form[open]{flex-basis:100%}
.schedule-form > summary{list-style:none;cursor:pointer}
.schedule-form > summary::-webkit-details-marker{display:none}
.schedule-form[open] > summary{border-color:var(--gold);color:var(--gold-ink)}
.schedule-form > form{
  margin-top:10px;padding:14px;border:1px solid var(--line);border-radius:10px;
}
.schedule-fields{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
.schedule-days{border:0;margin:0 0 12px;padding:0;min-width:0}
.schedule-days legend{
  padding:0;margin-bottom:6px;color:var(--muted);font-size:11px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;
}
.day-picks{display:flex;flex-wrap:wrap;gap:6px}
.day-pick{
  display:inline-flex;align-items:center;gap:6px;padding:5px 10px;
  border:1px solid var(--line);border-radius:8px;font-size:13px;cursor:pointer;
}
.day-pick input{width:15px;height:15px;margin:0;accent-color:var(--gold)}
.day-pick:has(input:checked){border-color:var(--gold);color:var(--gold-ink)}

.schedule-chip{
  align-self:flex-start;display:inline-block;max-width:100%;
  padding:2px 10px;border-radius:999px;border:1px solid var(--line);
  font-size:11.5px;font-weight:600;color:var(--muted);text-decoration:none;
  overflow-wrap:anywhere;
}
.schedule-chip.on{color:var(--ok);border-color:currentColor}
.schedule-chip:hover{border-color:var(--gold);color:var(--gold-ink)}

@media (max-width:420px){
  .schedule-item form{margin-left:0}
  .schedule-form{flex-basis:100%}
  .schedule-form > summary{width:100%}
}

/* The new-monitor wizard (P9, 15 September 2026). Five steps on one page:
 * finished ones shrink to a ticked line with Change, the current one is open,
 * the rest wait as a title. */
.wizard{max-width:820px}
/* The example card beside the steps, on a screen wide enough to have a beside.
 * :has() so a club monitor's wizard, which has no card, stays one column. */
.wiz-side{display:none}
@media (min-width:1100px){
  .wizard:has(> .wiz-side){max-width:none;display:grid;gap:26px;align-items:start;grid-template-columns:minmax(0,1fr) 340px}
  .wiz-side{display:block;position:sticky;top:96px}
  .wiz-side .section-title{display:block;margin:6px 0 12px}
  .wiz-side .discord-mock{padding:12px;font-size:12.5px}
  .wiz-side .discord-mock .dc-msg{gap:10px}
  .wiz-side .discord-mock .dc-avatar{width:30px;height:30px;font-size:10px}
  .wiz-side .discord-mock .dc-avatar::after{width:10px;height:10px;border-width:2px}
  .wiz-side .discord-mock .embed-grid{grid-template-columns:1fr 1fr}
  .wiz-side .discord-mock .thumb{width:48px;height:48px;margin-left:10px}
  .wiz-side .helptext{margin:12px 2px 0}
}
.wiz-stepper{list-style:none;margin:0 0 14px;padding:0;display:flex;gap:6px;flex-wrap:wrap}
.wiz-stepper li{
  display:flex;align-items:center;gap:7px;padding:4px 11px 4px 5px;
  border:1px solid var(--line);border-radius:999px;
  color:var(--muted);font-size:12px;font-weight:700;
}
.wiz-stepper .n{
  display:grid;place-items:center;width:20px;height:20px;border-radius:50%;
  border:1px solid var(--line);font-size:10.5px;line-height:1;
}
/* A future step is a label, not a control: no box around it. A finished
 * step that can be reopened holds a link that fills its pill. */
.wiz-stepper li.is-todo{border-color:transparent;opacity:.62}
.wiz-stepper li a{
  display:flex;align-items:center;gap:7px;margin:-4px -11px -4px -5px;padding:4px 11px 4px 5px;
  border-radius:999px;color:inherit;text-decoration:none;
  transition:color .15s ease,background-color .15s ease;
}
.wiz-stepper li a:hover{color:var(--text);background:rgba(var(--gold-rgb),.08);text-decoration:none}
.wiz-stepper li a:focus-visible{outline-offset:1px;border-radius:999px}
.wiz-stepper li.is-ticked .n{border-color:rgba(var(--ok-rgb),.5);color:var(--ok);background:rgba(var(--ok-rgb),.10)}
.wiz-stepper li.is-current{color:var(--text);border-color:rgba(var(--gold-rgb),.55);background:rgba(var(--gold-rgb),.09);box-shadow:0 0 18px rgba(var(--gold-rgb),.18)}
.wiz-stepper li.is-current .n{
  border-color:var(--gold-deep);color:var(--accent-ink);
  background:linear-gradient(180deg,var(--gold-bright),var(--gold-deep));
}

.wiz-step{padding:13px 18px;margin-bottom:10px;transition:border-color .25s ease,opacity .25s ease}
.wiz-step.is-current,.wiz-step.is-open{padding:20px 22px 22px;box-shadow:var(--shadow-1)}
.wiz-step.is-current::before,.wiz-step.is-open::before{background:linear-gradient(150deg,var(--gold) 0%,var(--hairline) 35%,var(--line) 100%)}
/* A step that opens animates its body in; the heading stays put so the eye
 * has an anchor. Not the payment-wait box, which re-polls every three seconds
 * and would blink. No fill mode, so the in-flight dimming below still applies
 * once the entrance has finished. */
@keyframes wiz-open{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.wiz-step.is-current > :not(.wiz-head):not(.wiz-wait),
.wiz-step.is-open > :not(.wiz-head):not(.wiz-wait){animation:wiz-open .28s var(--ease-out)}
/* hx-indicator puts .htmx-request on the step while its form is in flight */
.wiz-step.htmx-request > :not(.wiz-head){opacity:.55;transition:opacity .15s ease}
@media (prefers-reduced-motion:reduce){
  .wiz-step.is-current > :not(.wiz-head),.wiz-step.is-open > :not(.wiz-head){animation:none}
  .wiz-step.is-done .wiz-n,.found{animation:none}
  .mon-card:hover{transform:none}
}
.wiz-step.is-todo{opacity:.62}
.wiz-head{display:flex;align-items:center;gap:10px}
.wiz-head h2{margin:0;flex:1;min-width:0;font-size:15.5px}
.wiz-step.is-current .wiz-head,.wiz-step.is-open .wiz-head{margin-bottom:12px}
.wiz-step.is-done .wiz-head{margin-bottom:8px}
.wiz-step.is-todo .wiz-head h2{font-weight:650}
.wiz-n{
  display:grid;place-items:center;flex:none;width:24px;height:24px;border-radius:50%;
  border:1px solid rgba(var(--gold-rgb),.45);color:var(--gold-ink);
  font-size:11.5px;font-weight:800;line-height:1;
}
.wiz-step.is-done .wiz-n{border-color:rgba(var(--ok-rgb),.5);color:var(--ok);background:rgba(var(--ok-rgb),.1);animation:tick-pop .4s var(--ease-spring) both}
@keyframes tick-pop{from{transform:scale(.5);opacity:0}to{transform:none;opacity:1}}
.wiz-step.is-todo .wiz-n{border-color:var(--line);color:var(--muted)}
.wiz-change{flex:none;font-size:12.5px;font-weight:700}

.wiz-lede{color:var(--muted);font-size:13.5px;margin:0 0 14px;max-width:68ch}
.wiz-summary{
  display:flex;align-items:center;gap:8px 14px;flex-wrap:wrap;
  padding-left:34px;font-size:13.5px;
}
.wiz-said{flex:1 1 260px;min-width:0;overflow-wrap:anywhere}
.wiz-status{display:inline-flex;align-items:center;gap:6px 10px;flex-wrap:wrap;min-width:0}
.wiz-status form{display:inline}
.wiz-status .test-line{overflow-wrap:anywhere}
.wiz-status.htmx-request{opacity:.7}
.wiz-status.htmx-request::after{content:"working...";font-size:12px;color:var(--muted)}
.wiz-found{margin-left:34px}
.wiz-notice{margin:8px 0 0 34px;font-size:12.5px;overflow-wrap:anywhere}
.wiz-notice.tone-ok{color:var(--ok)}
.wiz-notice.tone-warn{color:var(--warn)}
.wiz-step.is-done .helptext.mt-s{margin-left:34px}

.wiz-fields{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr);gap:14px}
.wiz-form .form-actions.row{gap:8px 14px}
.wiz-choose{display:flex;gap:0 12px;align-items:flex-end;flex-wrap:wrap}
.wiz-choose .field{flex:1 1 280px;min-width:0}
.wiz-choose .btn{margin-top:12px}
.wiz-aside{margin-left:auto}
.opt{text-transform:none;letter-spacing:0;font-weight:500}

.wiz-add,.wiz-more{margin-top:16px;padding-top:12px;border-top:1px solid var(--line-soft)}
.wiz-add > summary,.wiz-more > summary{
  display:inline-flex;align-items:center;gap:8px;cursor:pointer;list-style:none;
  color:var(--gold-ink);font-size:13px;font-weight:700;
}
.wiz-add > summary::-webkit-details-marker,.wiz-more > summary::-webkit-details-marker{display:none}
.wiz-add > summary::before,.wiz-more > summary::before{
  content:"+";display:inline-block;width:12px;text-align:center;font-weight:800;
  transition:transform .25s var(--ease-out);
}
.wiz-add[open] > summary::before,.wiz-more[open] > summary::before{transform:rotate(45deg)}
.wiz-add[open] > summary,.wiz-more[open] > summary{margin-bottom:12px}

.wiz-packs{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-top:14px}
.wiz-packs .pack-card .btn{align-self:flex-start}

.wiz-wait{
  display:flex;gap:12px;align-items:flex-start;padding:12px 14px;border-radius:10px;
  border:1px solid rgba(var(--gold-rgb),.35);background:rgba(var(--gold-rgb),.06);
}
.wiz-wait strong{display:block;margin-bottom:2px}
.wiz-spinner{
  flex:none;width:18px;height:18px;margin-top:2px;border-radius:50%;
  border:2px solid rgba(var(--gold-rgb),.25);border-top-color:var(--gold);
  animation:spin .8s linear infinite;
}

.wiz-go{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.wiz-go .btn-go{margin-left:auto;min-height:44px;padding:10px 22px;font-size:14.5px}

@media (max-width:640px){
  .wiz-fields{grid-template-columns:minmax(0,1fr)}
  .wiz-summary{padding-left:0}
  .wiz-found,.wiz-notice,.wiz-step.is-done .helptext.mt-s{margin-left:0}
  .wiz-aside{margin-left:0}
  .wiz-go .btn-go{margin-left:0;width:100%}
  .wiz-step.is-current,.wiz-step.is-open{padding:16px 15px 18px}
  .wiz-step{padding:12px 15px}
}
@media (max-width:480px){
  /* Five labelled pills do not fit a phone. The finished and future ones keep
   * their number or tick; only the current step keeps its word. */
  .wiz-stepper li{padding:4px}
  .wiz-stepper li a{margin:-4px;padding:4px}
  .wiz-stepper li .l{display:none}
  .wiz-stepper li.is-current{padding-right:11px}
  .wiz-stepper li.is-current .l{display:inline}
}
[data-theme="light"] .wiz-stepper li.is-ticked .n,
[data-theme="light"] .wiz-step.is-done .wiz-n{border-color:rgba(44,122,68,.45);background:rgba(44,122,68,.08)}
