/* The desk's own look, on top of site.css, as on aprsthursday: one bar to move between a net's
   desk pages, solid buttons with a clear order of importance, fields with labels above and a
   ring when in use, badges for roles and states, and settings laid out as a title and its
   controls. Written for a phone first: a button and a field are at least 44 pixels high and a
   field's text is 16 pixels. The colours it uses are set in site.css, so these parts work on
   any page. */

/* ── The bar ─────────────────────────────────────────────────────────────── */
.adm-nav { display: flex; align-items: center; justify-content: space-between; gap: 6px 12px; flex-wrap: wrap; padding: 6px 8px; margin-bottom: 18px; background: var(--adm-surface); border: 1px solid var(--adm-border); border-radius: 14px; }
.adm-nav-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; padding: 4px 6px; }
.adm-nav-title b { font-size: 16px; font-weight: 650; }
.adm-nav-tag { color: var(--faint); font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
/* The links go on to a second line when they do not fit one (on a phone: Dashboard, Settings,
   Members, then Import and Public page); the page never scrolls sideways. */
.adm-nav-links { display: flex; gap: 2px; align-items: center; flex: 1 1 100%; flex-wrap: wrap; overflow-x: auto; scrollbar-width: none; }
.adm-nav-links::-webkit-scrollbar { display: none; }
.adm-nav-links a { flex: none; display: flex; align-items: center; min-height: var(--tap); padding: 0 14px; border-radius: 9px; color: var(--muted); font-weight: 500; text-decoration: none; white-space: nowrap; }
.adm-nav-links a:hover { color: var(--text); background: rgba(var(--tint), 0.05); text-decoration: none; }
.adm-nav-links a.on { color: var(--text); background: rgba(var(--tint), 0.09); }
.adm-nav-links .push { margin-left: auto; }
.adm-nav-user { display: flex; align-items: center; gap: 6px; }
.adm-me { display: flex; align-items: center; gap: 9px; min-height: var(--tap); padding: 0 12px 0 6px; border-radius: 999px; color: var(--text); font-weight: 500; text-decoration: none; }
.adm-me:hover, .adm-me.on { background: rgba(var(--tint), 0.07); text-decoration: none; }
.adm-nav-user form { margin: 0; }

/* ── Round badges with initials ──────────────────────────────────────────── */
.adm-avatar { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(135deg, var(--adm-avatar-a), var(--adm-avatar-b)); border: 1px solid var(--adm-border-strong); color: var(--text); font-size: 13px; font-weight: 600; letter-spacing: 0.02em; }
.adm-avatar.sm { width: 28px; height: 28px; font-size: 11px; }
.adm-avatar.lg { width: 56px; height: 56px; font-size: 19px; }

/* ── Page heads ──────────────────────────────────────────────────────────── */
.adm-head { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; margin-bottom: 18px; }
.adm-head h1 { margin: 0; font-size: 24px; letter-spacing: -0.01em; }
.adm-head p { margin: 4px 0 0; color: var(--muted); }
.adm-crumb { margin: 0 0 12px; font-size: 13px; color: var(--faint); }
.adm-crumb a { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--muted); text-decoration: none; }
.adm-crumb a:hover { color: var(--text); }
.adm-who { display: flex; align-items: center; gap: 14px; }
.adm-badges { display: flex; gap: 6px; flex-wrap: wrap; }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.adm-btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: var(--tap); padding: 0 14px; border-radius: 9px; border: 1px solid var(--adm-border-strong); background: var(--adm-surface-2); color: var(--text); font: inherit; font-size: 15px; font-weight: 500; line-height: 1.2; cursor: pointer; text-decoration: none; white-space: nowrap; transition: background 0.12s, border-color 0.12s, box-shadow 0.12s; }
.adm-btn:hover { background: var(--adm-surface-3); border-color: rgba(var(--tint), 0.3); color: var(--text); text-decoration: none; }
.adm-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--adm-ring); }
.adm-btn.primary { background: var(--amber-fill); border-color: var(--amber-fill); color: var(--on-amber); font-weight: 600; }
.adm-btn.primary:hover { background: var(--amber-fill-hi); border-color: var(--amber-fill-hi); color: var(--on-amber); }
.adm-btn.ghost { background: none; border-color: transparent; color: var(--muted); }
.adm-btn.ghost:hover { background: rgba(var(--tint), 0.06); border-color: transparent; color: var(--text); }
.adm-btn.danger { background: none; border-color: rgba(var(--bad-rgb), 0.45); color: var(--bad); }
.adm-btn.danger:hover { background: var(--bad-fill); border-color: var(--bad-fill); color: var(--on-bad); }
/* Smaller in look only: a small button is still as tall as a finger needs. */
.adm-btn.sm { padding: 0 11px; font-size: 14px; }
.adm-btn:disabled { opacity: 0.45; cursor: default; }
.adm-btn svg { width: 15px; height: 15px; flex: none; }
.adm-linkbtn { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0; border: 0; background: none; color: var(--blue); font: inherit; cursor: pointer; }
.adm-linkbtn:hover { text-decoration: underline; }

/* ── Cards and settings rows ─────────────────────────────────────────────── */
.adm-card { background: var(--adm-surface); border: 1px solid var(--adm-border); border-radius: 14px; margin-bottom: 16px; overflow: hidden; }
.adm-card-pad { padding: 16px; }
.adm-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px 14px; flex-wrap: wrap; padding: 14px 16px; border-bottom: 1px solid var(--adm-border); }
.adm-card-head h2 { margin: 0 0 2px; font-size: 15px; font-weight: 600; color: var(--text); text-transform: none; letter-spacing: 0; }
.adm-card-head p { margin: 0; color: var(--muted); font-size: 14px; }
/* A title and what it explains above its controls; side by side on a wide screen. */
.adm-section { display: grid; grid-template-columns: 1fr; gap: 12px; padding: 16px; border-top: 1px solid var(--adm-border); }
.adm-section:first-child { border-top: 0; }
.adm-section > header h2 { margin: 0 0 4px; font-size: 15px; font-weight: 600; color: var(--text); text-transform: none; letter-spacing: 0; }
.adm-section > header p { margin: 0; color: var(--muted); font-size: 14px; line-height: 1.5; }
/* The box behind an i button keeps its own look wherever it is written: this file loads after
   site.css, and the three rules above would reach a box inside a head. */
.info-pop p { margin: 0 0 10px; color: var(--text); font-size: 16px; line-height: 1.5; }
.adm-section.danger > header h2 { color: var(--bad); }
.adm-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.adm-foot form { margin: 0; }
/* Two buttons in a page's head (People: New person, Invite a person): no space above them. */
.adm-head .adm-head-acts { margin-top: 0; }

/* ── Fields ──────────────────────────────────────────────────────────────── */
.adm-grid { display: grid; grid-template-columns: 1fr; gap: 14px 16px; margin: 0 0 14px; }
.adm-grid .wide { grid-column: 1 / -1; }
.adm-field { display: block; margin: 0 0 14px; }
.adm-grid .adm-field { margin: 0; }
.adm-field > span, .adm-label { display: block; margin-bottom: 6px; color: var(--text); font-size: 14px; font-weight: 500; }
.adm-field small, .adm-hint { display: block; margin-top: 6px; color: var(--muted); font-size: 13px; line-height: 1.45; }
.adm-field small.adm-error, .adm-error { color: var(--bad); }
.adm-field.has-error input, .adm-field.has-error select, .adm-field.has-error textarea { border-color: rgba(var(--bad-rgb), 0.6); }
/* :where keeps the "not a tick" test from outweighing the rules for a field in capitals and a
   field with a problem, which come after and must win. */
.adm-input, .adm-field input:where(:not([type=checkbox]):not([type=radio])), .adm-field select, .adm-field textarea { display: block; width: 100%; min-height: var(--tap); padding: 0 12px; background: var(--adm-well); color: var(--text); border: 1px solid var(--adm-border-strong); border-radius: 9px; font: inherit; font-size: 16px; transition: border-color 0.12s, box-shadow 0.12s; }
.adm-field textarea, textarea.adm-input { padding: 10px 12px; line-height: 1.45; resize: vertical; }
.adm-input:hover, .adm-field input:hover, .adm-field select:hover, .adm-field textarea:hover { border-color: rgba(var(--tint), 0.3); }
.adm-input:focus, .adm-field input:focus, .adm-field select:focus, .adm-field textarea:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 3px var(--adm-ring); }
.adm-input::placeholder, .adm-field input::placeholder, .adm-field textarea::placeholder { color: var(--faint); }
.adm-input:disabled, .adm-field input:disabled, .adm-field select:disabled, .adm-field textarea:disabled { opacity: 0.55; }
.adm-field input.caps, input.adm-input.caps { font-family: var(--mono); text-transform: uppercase; }
.adm-field input.caps::placeholder { text-transform: none; font-family: var(--font); }
.adm-pw { display: flex; gap: 8px; }
.adm-pw .adm-pw-box { position: relative; flex: 1; }
.adm-pw .adm-pw-box input { padding-right: 70px; font-family: var(--mono); }
.adm-pw .adm-pw-box button { position: absolute; top: 2px; right: 2px; height: calc(var(--tap) - 4px); padding: 0 12px; border: 0; border-radius: 7px; background: none; color: var(--muted); font: inherit; font-size: 14px; cursor: pointer; }
.adm-pw .adm-pw-box button:hover { color: var(--text); background: rgba(var(--tint), 0.07); }
/* A tick with its words: the whole line is the target. */
.adm-check { display: flex; align-items: flex-start; gap: 12px; min-height: var(--tap); margin: 0 0 6px; padding: 10px 0; color: var(--text); cursor: pointer; }
.adm-check input { width: 22px; height: 22px; margin: 1px 0 0; accent-color: var(--amber-mark); flex: none; }
.adm-check small { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; }
.adm-check:has(input:disabled) { opacity: 0.55; cursor: default; }

/* A choice drawn as cards. */
.adm-choice { display: grid; grid-template-columns: 1fr; gap: 10px; }
.adm-choice label { position: relative; display: block; min-height: var(--tap); padding: 13px 14px 13px 44px; border: 1px solid var(--adm-border-strong); border-radius: 10px; background: var(--adm-well); cursor: pointer; transition: border-color 0.12s, background 0.12s; }
.adm-choice label:hover { border-color: rgba(var(--tint), 0.3); }
.adm-choice input { position: absolute; top: 14px; left: 14px; width: 20px; height: 20px; margin: 0; accent-color: var(--amber-mark); }
.adm-choice b { display: block; font-weight: 600; }
.adm-choice small { display: block; margin-top: 3px; color: var(--muted); font-size: 13px; line-height: 1.45; }
.adm-choice label:has(input:checked) { border-color: var(--amber); background: rgba(var(--amber-rgb), 0.07); }
.adm-choice label:has(input:disabled) { opacity: 0.55; cursor: default; }

/* ── Badges ──────────────────────────────────────────────────────────────── */
.adm-badge { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: 999px; font-size: 12.5px; font-weight: 500; background: rgba(var(--tint), 0.07); color: var(--muted); white-space: nowrap; }
.adm-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.adm-badge.plain::before { display: none; }
.adm-badge.ok { background: rgba(var(--ok-rgb), 0.13); color: var(--ok); }
.adm-badge.warn { background: rgba(var(--amber-rgb), 0.14); color: var(--amber); }
.adm-badge.bad { background: rgba(var(--bad-rgb), 0.14); color: var(--bad); }
.adm-badge.blue { background: rgba(var(--blue-rgb), 0.14); color: var(--blue); }

/* ── Notes at the top of a page: saved, refused, take care ───────────────── */
.adm-alert { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; margin: 0 0 16px; border-radius: 10px; border: 1px solid var(--adm-border); background: var(--adm-surface); line-height: 1.5; }
.adm-alert::before { content: ""; flex: none; width: 8px; height: 8px; margin-top: 8px; border-radius: 50%; background: var(--muted); }
.adm-alert.ok { border-color: rgba(var(--ok-rgb), 0.4); background: rgba(var(--ok-rgb), 0.07); }
.adm-alert.ok::before { background: var(--ok-mark); }
.adm-alert.bad { border-color: rgba(var(--bad-rgb), 0.45); background: rgba(var(--bad-rgb), 0.07); }
.adm-alert.bad::before { background: var(--bad); }
.adm-alert.warn { border-color: var(--amber-dim); background: rgba(var(--amber-rgb), 0.07); }
.adm-alert.warn::before { background: var(--amber-mark); }

/* ── Tables ──────────────────────────────────────────────────────────────── */
.adm-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 14px; border-bottom: 1px solid var(--adm-border); }
.adm-tools .adm-input { width: auto; flex: 1 1 180px; min-width: 0; }
.adm-tools .adm-count { margin-left: auto; color: var(--muted); font-size: 13px; }
/* Wider than the screen, it scrolls inside its card: wrap it in .table-scroll. */
.adm-table { width: 100%; border-collapse: collapse; }
.adm-table th { text-align: left; padding: 10px 14px; color: var(--muted); font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; border-bottom: 1px solid var(--adm-border); background: rgba(var(--tint), 0.02); white-space: nowrap; }
.adm-table td { padding: 12px 14px; border-bottom: 1px solid var(--adm-border); vertical-align: middle; }
.adm-table tbody tr:last-child td { border-bottom: 0; }
.adm-table tbody tr[data-href] { cursor: pointer; }
.adm-table tbody tr[data-href]:hover { background: rgba(var(--tint), 0.035); }
.adm-table .adm-right { text-align: right; }
.adm-person { display: flex; align-items: center; gap: 12px; }
.adm-person b { display: block; font-weight: 600; color: var(--text); }
.adm-person span span { display: block; color: var(--muted); font-size: 13px; }
.adm-person a { color: inherit; text-decoration: none; }
.adm-empty { padding: 36px 16px; text-align: center; color: var(--muted); }
.adm-empty b { display: block; color: var(--text); font-size: 16px; margin-bottom: 4px; }
.adm-facts { display: grid; grid-template-columns: max-content 1fr; gap: 8px 16px; margin: 0; }
.adm-facts dt { color: var(--muted); }
.adm-facts dd { margin: 0; }
/* A short value beside its name (a number, a build) is never broken in two: the name takes
   the wrap. Health marks its values (HealthModel.ValueClass). */
td.whole { white-space: nowrap; }
.adm-pager { display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; padding: 12px; border-top: 1px solid var(--adm-border); color: var(--muted); font-size: 13px; }

/* ── Signing in ──────────────────────────────────────────────────────────── */
.adm-auth { width: min(400px, 100%); margin: 4vh auto 0; }
.adm-auth h1 { margin: 0 0 6px; font-size: 24px; text-align: center; }
.adm-auth > p { margin: 0 0 20px; color: var(--muted); text-align: center; }
.adm-auth .adm-btn { width: 100%; margin-top: 6px; }
.adm-auth .adm-auth-foot { margin-top: 18px; text-align: center; color: var(--muted); font-size: 14px; }
/* "Sign in with APRS Connect" under the form: the button as wide as the form's, its i beside it. */
.adm-auth > p.adm-auth-alt { display: flex; align-items: center; gap: 8px; margin: 14px 0 0; }
.adm-auth .adm-auth-alt .adm-btn { flex: 1; margin-top: 0; }
/* The APRS Connect icon in its buttons, as aprs.now draws it: 20 pixels, its corners rounded. */
.adm-btn.connect img { flex: none; border-radius: 5px; }
.adm-or { display: flex; align-items: center; gap: 12px; margin: 14px 0 8px; color: var(--faint); font-size: 13px; }
.adm-or::before, .adm-or::after { content: ""; flex: 1; height: 1px; background: var(--adm-border); }

/* ── The desk: a net's numbers, its tabs, its lists ──────────────────────── */
.desk-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.desk-title { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.desk-title h1 { margin: 0; font-size: 22px; }
.desk-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.desk-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 12px; }
.desk-stats > div { background: var(--adm-surface); border: 1px solid var(--adm-border); border-radius: 14px; padding: 10px 14px; }
.desk-stats b { display: block; font-size: 24px; font-family: var(--mono); color: var(--text); }
.desk-stats span { color: var(--muted); font-size: 12px; }
/* The tabs scroll sideways inside their own box when they do not fit. */
.desk-tabs { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.desk-tabs::-webkit-scrollbar { display: none; }
/* While more tabs are hidden to the right, the edge fades (desk.js marks the box). */
.desk-tabs.more { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent); }
.desk-tabs a { flex: none; display: flex; align-items: center; gap: 6px; min-height: var(--tap); padding: 0 14px; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; }
.desk-tabs a:hover { color: var(--text); }
.desk-tabs a.on { color: var(--text); border-bottom-color: var(--amber-mark); }
.count { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 999px; background: rgba(var(--tint), 0.07); color: var(--muted); font-size: 12px; font-family: var(--mono); text-align: center; }
.count.warn { background: var(--amber-dim); color: var(--text); }
.desk-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
.desk-grid .adm-card { margin: 0; }
.desk-act { white-space: nowrap; text-align: right; }
.desk-act form { display: inline; }

@media (min-width: 761px) {
    .adm-nav-links { flex: 0 1 auto; }
    .adm-card-pad { padding: 20px 22px; }
    .adm-section { grid-template-columns: minmax(200px, 280px) 1fr; gap: 12px 32px; padding: 22px; }
    .adm-grid { grid-template-columns: 1fr 1fr; }
    .adm-choice { grid-template-columns: 1fr 1fr; }
    .adm-auth { margin-top: 6vh; }
    .desk-stats { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
    .desk-grid { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
    .adm-check input { width: 18px; height: 18px; margin-top: 2px; }
    .adm-check { padding: 6px 0; }
}

/* ---- The form a net is set up with (NetForm/_NetForm.cshtml, on /manage/new and a net's settings). ---- */
/* On a narrow screen: the questions, then Save, then the panel. Save two screens below the last
   question, after the panel and "Try a message", was where nobody looked for it. */
.nf-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 20px; grid-template-areas: "ask" "save" "see"; }
.nf-ask { grid-area: ask; min-width: 0; }
.nf-see { grid-area: see; min-width: 0; }
.nf-save { grid-area: save; min-width: 0; margin-bottom: 20px; }
.nf-missing { margin: 0 0 8px; }
/* "Not saved", at the top of a page that answers a refused save. */
.nf-notsaved ul { margin: 6px 0 0; padding-left: 18px; }
.nf-notsaved li a { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--text); text-decoration: underline; }
.nf-notsaved p { margin: 4px 0 0; }
.nf-notsaved:focus { outline: none; }
/* A problem longer than one block of text, as short lines cut between its sentences: beside
   its field and in the "Not saved" list. */
.nf-lines, .nf-line { display: block; }
.nf-line + .nf-line { margin-top: 4px; }
/* What stations will send, and the next session, under the answers they come from. On a wide
   screen the panel beside the questions says both, so these are not shown there. */
.nf-inline { margin: 0 0 14px; padding: 9px 12px; border-radius: 9px; border: 1px dashed var(--adm-border-strong); color: var(--text); font-size: 14px; line-height: 1.45; }
.nf-zone + .nf-inline { margin: 4px 0 0; }
.nf-save .adm-foot { margin-top: 0; }
.nf-save .adm-btn.primary { flex: 1 1 100%; }
.nf .nf-q { margin: 0 0 12px; font-size: 16px; font-weight: 600; color: var(--text); text-transform: none; letter-spacing: 0; }
.nf .adm-card-pad > :last-child { margin-bottom: 0; }
.nf-under { margin: 0 0 12px; }
.nf-gap { margin-top: 18px; }
.nf-or { margin: 14px 0 6px; color: var(--muted); }
.nf-when { margin: 12px 0; }
.nf-wait { margin: 0 0 12px; color: var(--muted); }
.nf-ok { margin: 0; color: var(--ok); }

/* The web address under the name, with its Change link. */
.nf-address { margin: -4px 0 16px; color: var(--muted); font-size: 14px; }
.nf-address b { color: var(--text); font-family: var(--mono); font-weight: 500; }
.nf-address details { margin-top: 2px; }
.nf-address summary { display: inline-flex; list-style: none; }
.nf-address summary::-webkit-details-marker { display: none; }
.nf-address details[open] summary { margin-bottom: 4px; }
.nf-address .adm-field { margin-bottom: 6px; }

/* Chips that are ticks: days of the week, weeks of the month, apps and radios. */
.nf-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.nf-chip { position: relative; display: inline-flex; }
.nf-chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.nf-chip span { display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--adm-border-strong); background: var(--adm-well); color: var(--text); font-size: 15px; white-space: nowrap; }
.nf-chip input:checked + span { border-color: var(--amber); background: rgba(var(--amber-rgb), 0.12); color: var(--amber); font-weight: 600; }
.nf-chip input:focus-visible + span { box-shadow: 0 0 0 3px var(--adm-ring); }
.nf-times { grid-template-columns: 1fr 1fr; }
.nf .adm-choice.nf-one { grid-template-columns: 1fr; }

/* A row under "More options": closed, it shows its value in words. */
.nf-row { border-top: 1px solid var(--adm-border); }
.nf-row > summary { position: relative; display: flex; flex-direction: column; gap: 2px; min-height: 44px; padding: 12px 44px 12px 16px; cursor: pointer; list-style: none; }
.nf-row > summary::-webkit-details-marker { display: none; }
.nf-row > summary::after { content: ""; position: absolute; right: 20px; top: 20px; width: 8px; height: 8px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); }
.nf-row[open] > summary::after { top: 24px; transform: rotate(-135deg); }
.nf-row > summary:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--adm-ring); }
.nf-row-name { font-weight: 600; }
.nf-row-val { color: var(--muted); font-size: 14px; line-height: 1.45; }
.nf-row.has-error .nf-row-name { color: var(--bad); }
.nf-row-body { padding: 4px 16px 16px; }
.nf-row-body > :last-child { margin-bottom: 0; }
/* The box behind an i button is centred by its own margin, also when it is the last thing in a row. */
.nf-row-body > .info-pop:last-child { margin: auto; }

/* Something a controller must know before choosing. */
.nf-note { margin: 12px 0 14px; padding: 10px 12px; border-left: 3px solid var(--amber); border-radius: 0 9px 9px 0; background: rgba(var(--amber-rgb), 0.07); font-size: 14px; line-height: 1.5; }
.nf-note ul { margin: 6px 0 0; padding-left: 18px; }
.nf-note li { margin-bottom: 4px; }

/* The panel. */
.nf-sessions { margin: 0 0 12px; padding-left: 22px; }
.nf-sessions li { margin-bottom: 8px; }
.nf-sessions .adm-hint { margin-top: 0; }
.nf-problems { margin: 0; padding-left: 18px; }
.nf-problems li { margin-bottom: 6px; }
.nf-problems a { display: flex; align-items: center; min-height: var(--tap); color: var(--text); }
.nf-try-foot { margin: 0 0 12px; }
.nf .check-result { margin-bottom: 0; }
.nf .send-line code { font-size: 15px; }

/* A list that can be searched (wwwroot/js/combo.js): the field that is typed into, the arrow
   that opens it, and the list under it. The list is in the flow of the page and scrolls inside
   itself, so it is never cut off by the card it is in and never traps the page. Every row is
   a finger tall and its text is 16 pixels, like the field's. */
.combo { position: relative; }
.combo-input { display: block; width: 100%; min-height: var(--tap); padding: 0 48px 0 12px; background: var(--adm-well); color: var(--text); border: 1px solid var(--adm-border-strong); border-radius: 9px; font: inherit; font-size: 16px; text-overflow: ellipsis; transition: border-color 0.12s, box-shadow 0.12s; }
.adm-field input.combo-input { padding-right: 48px; }
.combo-input:hover { border-color: rgba(var(--tint), 0.3); }
.combo-input:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 3px var(--adm-ring); }
.combo-input::placeholder { color: var(--faint); }
.combo-toggle { position: absolute; top: 0; right: 0; width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: 9px; background: transparent; color: var(--muted); cursor: pointer; }
.combo-toggle::before { content: ""; position: absolute; top: 50%; left: 50%; width: 8px; height: 8px; margin: -7px 0 0 -5px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); }
.combo.open .combo-toggle::before { margin-top: -2px; transform: rotate(-135deg); }
.combo-list { list-style: none; margin: 6px 0 0; padding: 4px; max-height: 308px; overflow-y: auto; border: 1px solid var(--adm-border-strong); border-radius: 9px; background: var(--adm-well); }
.combo-option { display: flex; align-items: center; min-height: var(--tap); padding: 6px 10px; border-radius: 7px; font-size: 16px; line-height: 1.3; cursor: pointer; }
.combo-option:hover { background: rgba(var(--tint), 0.06); }
.combo-option.active { background: rgba(var(--amber-rgb), 0.14); box-shadow: inset 0 0 0 2px var(--amber); }
.combo-option.chosen { color: var(--amber); font-weight: 600; }
.combo-group { padding: 10px 10px 4px; color: var(--muted); font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.combo-none { margin: 6px 0 0; padding: 12px; border: 1px dashed var(--adm-border-strong); border-radius: 9px; color: var(--muted); font-size: 14px; line-height: 1.45; }
.combo-count { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Several choices: the ticks the list is laid over. Only the ticked ones show under the field,
   each still a tick that a tap takes off; with none ticked they take no room. */
.combo-picked label:not(:has(input:checked)) { display: none; }
.combo-picked:not(:has(input:checked)) { margin: 0; }

@media (min-width: 981px) {
    .nf-cols { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); grid-template-areas: "ask see" "save see"; align-items: start; }
    .nf-see { position: sticky; top: 12px; max-height: calc(100vh - 24px); overflow-y: auto; scrollbar-width: thin; }
    .nf-save .adm-btn.primary { flex: 0 1 auto; }
    .nf-inline, .nf-missing { display: none; }
}
/* The checks beside the Publish button, on a net's settings. */
.nf-checks { margin: 0; padding: 0; list-style: none; }
.nf-checks li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 12px; align-items: start; padding: 12px 16px; border-top: 1px solid var(--adm-border); }
.nf-checks li:first-child { border-top: 0; }
.nf-checks b { font-weight: 600; }
.nf-checks span.nf-detail { grid-column: 2; color: var(--muted); font-size: 14px; line-height: 1.45; }
.nf-state form { margin: 0; }
/* Pause, on the site admins' list of nets: its own line, the tick above the button. */
.cards td.act .pause-form { display: block; margin-top: 4px; }
.cards td.act .pause-form .adm-check { margin: 0; white-space: normal; text-align: left; }
.nf-flush { margin: 0; }

/* ---- My nets (Pages/Manage/Index.cshtml). ---- */
.my-nets { display: grid; grid-template-columns: 1fr; gap: 14px; margin: 0; padding: 0; list-style: none; }
.my-nets .adm-card { margin: 0; height: 100%; }
.my-net-name { display: flex; align-items: center; gap: 6px 10px; flex-wrap: wrap; margin: 0 0 10px; }
.my-net-name h2 { margin: 0; font-size: 18px; }
.my-net-name h2 a { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--text); }
.my-net .facts { grid-template-columns: 1fr; margin: 0 0 4px; }
.my-net .facts dd { color: var(--text); }
.my-net .facts dd small { display: block; color: var(--muted); font-size: 13px; }
.my-net .net-state { margin: 0; }
@media (min-width: 761px) { .my-nets { grid-template-columns: 1fr 1fr; } }

/* ---- A net's desk (Pages/Manage/Net.cshtml). ---- */
.desk-pick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0; }
.desk-pick .adm-input { width: auto; flex: 1 1 200px; min-width: 0; max-width: 100%; }
.desk-title h1 small { display: block; color: var(--muted); font-size: 14px; font-weight: 400; }
.desk-stats.three { grid-template-columns: repeat(3, 1fr); gap: 8px; }
.desk-stats.three > a { display: block; background: var(--adm-surface); border: 1px solid var(--adm-border); border-radius: 14px; padding: 10px 12px; color: inherit; text-decoration: none; min-height: var(--tap); }
.desk-stats.three > a:hover { border-color: var(--amber-dim); }
.desk-stats.three b { display: block; font-size: 24px; font-family: var(--mono); color: var(--text); }
.desk-stats.three span { display: block; color: var(--muted); font-size: 12px; line-height: 1.3; }
.desk-stats.three small { display: block; margin-top: 2px; color: var(--muted); font-size: 12px; line-height: 1.3; }
.desk-list { list-style: none; margin: 0; padding: 0; }
.desk-list > li { padding: 12px 14px; border-top: 1px solid var(--adm-border); }
.desk-list > li:first-child { border-top: 0; }
.desk-row-head { display: flex; align-items: center; justify-content: space-between; gap: 6px 12px; flex-wrap: wrap; }
.desk-row-head .call { font-size: 16px; }
/* The callsign of a line to review, its tags and its Raw button (site.css, .raw-btn). */
.desk-who { min-width: 0; }
.desk-who .raw-btn { margin-left: 4px; }
.desk-row-head b { font-weight: 600; }
.desk-said { margin: 4px 0 0; color: var(--text); }
.desk-why { margin: 6px 0 0; color: var(--muted); font-size: 14px; }
.desk-reasons { margin: 4px 0 0; padding-left: 18px; color: var(--muted); font-size: 14px; }
.desk-reasons li { margin: 2px 0; }
.desk-meta { margin: 4px 0 0; color: var(--faint); font-size: 13px; }
.desk-quiet { margin: 0; padding: 20px 4px; color: var(--muted); }
.adm-card > .desk-quiet { padding: 16px 14px; }
.adm-card > .desk-meta { margin: 0; padding: 0 14px 12px; }
.desk-list > li > .desk-said:first-child { margin-top: 0; }
.desk-form { margin: 0; }
.adm-card-head h2 .count { margin-left: 4px; }
.adm-tools .adm-btn { flex: none; }
/* What was just done stays in view while the list under it is scrolled: the page comes back to
   where the change was made, not to its top. */
.adm-alert.stick { position: sticky; top: 8px; z-index: 4; background-color: var(--adm-surface); box-shadow: 0 6px 18px rgba(0, 0, 0, calc(0.45 * var(--shade))); }
.adm-alert.ok.stick { background: linear-gradient(rgba(var(--ok-rgb), 0.09), rgba(var(--ok-rgb), 0.09)), var(--adm-surface); }
.adm-alert.bad.stick { background: linear-gradient(rgba(var(--bad-rgb), 0.09), rgba(var(--bad-rgb), 0.09)), var(--adm-surface); }
/* A section a change comes back to sits a little below the top of the screen, under that line. */
#roster, #not-checked, #outside-rules, #outside-hours, #wrong-way, #counted-wrong-way, #changes, #sessions, #runs { scroll-margin-top: 72px; }
.desk-order { margin: 0 0 8px; color: var(--muted); }
.desk-sub { margin: 0; padding: 14px 14px 0; font-size: 14px; font-weight: 600; color: var(--text); }
.desk-sub + .desk-meta { padding: 2px 14px 0; }
.desk-list .desk-meta { padding: 0; }
.adm-card > .desk-form + .desk-meta { padding-top: 10px; }
/* "Add them all": the tick, then the button, on their own lines. */
.desk-all { padding: 12px 14px; border-bottom: 1px solid var(--adm-border); }
.desk-all .desk-why { margin: 0 0 4px; }
.desk-all .adm-check { margin: 0 0 8px; }

/* ---- A net that closes when its time runs out, on its dashboard (Desk/RunDesk.cs). ---- */
/* The four numbers over a session's roster: two across on a phone, each label on its own line. */
.run-tiles { margin-bottom: 8px; }
.run-tiles span { display: block; line-height: 1.3; }
.run-takes { margin: 0 0 12px; }
/* Close the net: what it does, the tick on its own line, then the button. */
.run-ends { margin: 0 0 4px; }
/* A past run: its button goes under its name when the two do not fit one line. */
.desk-row-head .desk-form { flex: none; }
/* Open this run again, under a past run: its help line, its tick, its button. */
.run-again { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--adm-border); }
.run-again .desk-why { margin: 0 0 4px; }
.run-again .adm-check { margin: 0 0 8px; }
/* What an operator added to the time left, on a line of the roster. */
.roster-table td.added { color: var(--muted); font-size: 13px; }
