/* Fonts and colors follow moin-website/src/styles/site.css. danger, warning and
   surface are not there; they are the app palette's, which site.css names as its
   source: moin-flutter/lib/shared/theme/palettes/moin.dart. */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/manrope-400-700.woff2') format('woff2');
}

@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/dm-mono-400.woff2') format('woff2');
}

@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/dm-mono-500.woff2') format('woff2');
}

/* Each color is written once, light then dark, and the system picks. */
:root {
  color-scheme: light dark;
  --page: light-dark(#f2f5fa, #080c12);
  --ink: light-dark(#202c40, #f3f6fb);
  --muted-bright: light-dark(#58677e, #aab4c3);
  --muted: light-dark(#58677e, #8693a6);
  --line: light-dark(#cdd6e6, #263241);
  --line-soft: light-dark(#e3e8f0, rgba(112, 131, 155, 0.18));
  --periwinkle: light-dark(#4561b8, #7da2ff);
  --periwinkle-bright: light-dark(#4561b8, #a7bcff);
  --sea-glass: light-dark(#277657, #48d5aa);
  --danger: light-dark(#b3344b, #f08a96);
  --warning: light-dark(#8b5b09, #ffc66d);
  --nav-surface: light-dark(#e8edf5, #080c12);
  --menu-surface: light-dark(#fdfeff, #171d26);
  --surface: light-dark(#fffffff2, #111822f2);
  --shadow: light-dark(#0d244518, #0006);
  --button-background: light-dark(#4561b8, #dde3ed);
  --button-ink: light-dark(#fff, #080c12);
  --button-hover: light-dark(#3a529c, #cbd8ff);
  --font-body: 'Manrope', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --font-utility: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

/* The header's appearance button sets these, and the gallery, to show a page in the theme
   the system is not in. */
:root[data-theme='light'] {
  color-scheme: light;
}
:root[data-theme='dark'] {
  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--page);
}

/* Operators read these pages all day: mono and tight. */
body {
  min-height: 100vh;
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font: 400 13px/1.5 var(--font-utility);
}

/* Customers read theirs once: running text in the website's face, with room. #page
   holds the frame, so that htmx swapping the body's content brings who reads it too. */
.customers {
  font: 400 14px/1.6 var(--font-body);
}

a {
  color: var(--periwinkle-bright);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

::selection {
  background: color-mix(in srgb, var(--periwinkle) 38%, transparent);
  color: var(--ink);
}

:focus-visible {
  outline: 2px solid var(--periwinkle-bright);
  outline-offset: 2px;
}

/* The frame. */

header {
  position: sticky;
  z-index: 10;
  top: 0;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: 40px;
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--line-soft);
  background: var(--nav-surface);
  font: 400 13px/1.5 var(--font-utility);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ink);
  font-weight: 500;
  white-space: nowrap;
}
.brand:hover {
  text-decoration: none;
}
.brand img {
  width: 20px;
  height: 20px;
}
.brand span {
  padding: 1px 6px;
  border: 1px solid var(--line);
  border-radius: 3px;
  color: var(--muted-bright);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

header nav {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 0.25rem;
}
header nav a {
  display: flex;
  align-items: center;
  height: 26px;
  padding: 0 0.6rem;
  border-radius: 3px;
  color: var(--muted-bright);
  white-space: nowrap;
}
header nav a:hover {
  color: var(--ink);
  text-decoration: none;
}
header nav a[aria-current] {
  background: color-mix(in srgb, var(--periwinkle) 16%, transparent);
  color: var(--ink);
}
header nav .split {
  width: 1px;
  height: 14px;
  margin: 0 0.5rem;
  background: var(--line);
}
header .who {
  color: var(--muted);
  white-space: nowrap;
}
/* The appearance button, which names the theme: as wide as its longest name, so the
   header holds still as it changes. It keeps the header's far end when nobody is signed
   in and no links push it there. */
header .theme {
  min-width: 5ch;
  margin-left: auto;
  text-align: right;
}
header .theme[hidden] {
  display: none;
}

/* What is too wide and has no sheet to scroll in scrolls here, not the page. */
main {
  max-width: 88rem;
  margin: 0 auto;
  padding: 0 1.25rem 5rem;
  overflow-x: auto;
}
.customers main {
  max-width: 52rem;
}
/* A community's page is set as operators' are, as wide as what it holds needs, and as
   high as the window, so a form that opens from its command bar has the room. */
.owner main {
  max-width: 60rem;
  min-height: calc(100vh - 41px);
}
/* One thing to do, in the middle of the window. */
.alone main {
  max-width: 26rem;
  padding-top: 3rem;
}
.alone form.stack {
  max-width: none;
}

/* What heads a page: its title, and beside it what the page puts there. */
.title {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
  align-items: center;
  padding: 1.1rem 0 0.8rem;
}
.customers .title {
  padding: 2rem 0 1rem;
}
h1 {
  margin: 0;
  font: 500 15px/1.4 var(--font-utility);
}
.customers h1 {
  font: 600 22px/1.3 var(--font-body);
  letter-spacing: -0.03em;
}

/* The way back, over the title. */
.crumb {
  flex-basis: 100%;
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}
.crumb a {
  color: inherit;
}
.crumb a:hover {
  color: var(--ink);
}

/* Where a thing is, in a few words each, at the title's far end. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-left: auto;
}
.chips span,
.chips button.copy {
  padding: 2px 8px;
  border: 1px solid var(--line-soft);
  border-radius: 3px;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
}
.chips b {
  margin-left: 0.2rem;
  color: var(--ink);
  font-weight: 400;
}
/* A chip that copies what it holds. */
.chips button.copy {
  height: auto;
  background: none;
  font: inherit;
  font-size: 12px;
  line-height: inherit;
}
.chips button.copy::after {
  margin-left: 0.5rem;
  color: var(--periwinkle-bright);
  content: 'copy';
}
.chips button.copy.copied::after {
  color: var(--sea-glass);
  content: 'copied';
}
.chips button.copy:hover {
  border-color: color-mix(in srgb, var(--periwinkle) 55%, var(--line));
}

h2 {
  margin: 1.6rem 0 0.4rem;
  color: var(--muted);
  font: 400 11px/1.5 var(--font-utility);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
h2 small {
  margin-left: 0.6rem;
  font-size: 10px;
  letter-spacing: 0;
  text-transform: none;
}

p {
  margin: 0.5rem 0;
}

.muted {
  color: var(--muted);
}

/* Tables and sheets. A sheet is the bordered surface a table sits on, and scrolls
   sideways when the table is too wide; a table with no sheet around it draws its own
   border. */

.sheet {
  overflow-x: auto;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  background: var(--surface);
}

table {
  width: 100%;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  border-spacing: 0;
  background: var(--surface);
}
/* A problem report's description, as the person wrote it. */
.sheet > .description {
  margin: 0;
  padding: 0.75rem 1rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.sheet > table {
  border: 0;
  border-radius: 0;
  background: none;
}
table:empty {
  display: none;
}

/* A feed says "None." until it has a row; a live feed's first row can arrive. */
.feed:has(tbody > tr) > .none,
.feed:not(:has(tbody > tr)) > .sheet {
  display: none;
}

th,
td {
  padding: 5px 0.8rem;
  border-bottom: 1px solid var(--line-soft);
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
}
tbody > tr:last-child > * {
  border-bottom: 0;
}
td {
  font: 400 13px/1.5 var(--font-utility);
}
tr:hover > td {
  background: color-mix(in srgb, var(--periwinkle) 6%, transparent);
}

/* A column's head. */
th {
  color: var(--muted);
  font: 400 11px/1.7 var(--font-utility);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
tr:has(> th + th) > th {
  background: color-mix(in srgb, var(--page) 50%, transparent);
}

/* A row's label, and the value beside it. */
th:has(+ td) {
  width: 13rem;
  color: var(--muted-bright);
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
}

/* Text and JSON are what a table has room for: their column takes the width the others
   leave, wraps at its spaces, and inside a string only when one alone is wider than the
   cell. With no such column the last one takes what is left, so the others stay as wide
   as what is in them. */
td.text {
  width: 100%;
  min-width: 14rem;
  white-space: normal;
  overflow-wrap: anywhere;
}
.sheet > table:not(.state, :has(.text)) :is(th, td):last-child {
  width: 100%;
}

/* A table with no sheet still reads: a value beside its label wraps, and the last
   column takes what is left. */
table:not(.sheet > *) th + td {
  white-space: normal;
  overflow-wrap: anywhere;
}
table:not(.sheet > *) :is(th, td):last-child {
  width: 100%;
}

pre,
code {
  color: var(--muted-bright);
  font: inherit;
  font-family: var(--font-utility);
}
pre {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
details summary {
  color: var(--muted-bright);
  cursor: pointer;
}

/* What is shown once: an administrator link, a registration token. */
.secret {
  padding: 0.75rem;
  border: 1px solid var(--periwinkle);
  border-radius: 4px;
  background: var(--surface);
  font: 400 13px/1.5 var(--font-utility);
  overflow-wrap: anywhere;
}

td.soft {
  color: var(--muted-bright);
}
.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Desired beside observed: the subject, then a column each, sharing the width. */
table.state {
  min-width: 40rem;
  table-layout: fixed;
}
table.state :is(th, td) {
  width: auto;
  min-width: 0;
  white-space: normal;
}
table.state th:first-child {
  width: 10rem;
}
tr.differs > * {
  background: color-mix(in srgb, var(--warning) 7%, transparent);
}

/* What went wrong the last time something was asked for. */
p.failed {
  color: var(--warning);
}

/* What to know about the value it follows. */
.note {
  display: inline-block;
  margin-left: 0.75rem;
  color: var(--warning);
  font-size: 12px;
}

/* What is beside a value and matters less: the slots left after a meter. */
.aside {
  margin-left: 0.7rem;
  color: var(--muted);
}

/* A thing's facts, three to a row; the gaps draw the lines, so any number of columns
   closes. */
.facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin: 0;
  background: var(--line-soft);
}
.facts div {
  padding: 0.45rem 0.8rem;
  background: var(--surface);
}
.facts dt {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.facts dd {
  margin: 0;
  overflow: hidden;
  font: 400 13px/1.5 var(--font-utility);
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Facts whose values are lists or say what went wrong wrap, not end in an ellipsis. */
.facts.wraps dd {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Two blocks side by side, the first taking the room. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 1rem;
  align-items: start;
}

/* Blocks side by side, sharing the width; in a rail, a column of lists beside the rest. */
.cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 1rem;
  align-items: start;
}
.cols.rail {
  grid-template-columns: 24rem minmax(0, 1fr);
}
.cols > div {
  min-width: 0;
}
/* A rail's labels are as wide as the longest, and its values start in one line: a
   meter's numbers are set left, as the plain values under and over it are. */
.rail th:has(+ td) {
  width: auto;
}
.rail .meter {
  grid-template-columns: 5.5rem 5rem;
}
.rail .meter > span {
  text-align: left;
}

/* What is used of what there is: the numbers, and a bar that warns from four fifths. */
.meter {
  display: inline-grid;
  grid-template-columns: 4.5rem 5rem;
  gap: 0.6rem;
  align-items: center;
  white-space: nowrap;
}
.meter > span {
  text-align: right;
}
.meter em {
  color: var(--muted);
  font-style: normal;
}
.meter i {
  height: 4px;
  overflow: hidden;
  border-radius: 2px;
  background: var(--line-soft);
}
.meter i::after {
  display: block;
  width: var(--filled);
  height: 100%;
  border-radius: inherit;
  background: var(--periwinkle);
  content: '';
}
.meter i.high::after {
  background: var(--warning);
}
/* One meter on its own has no column of numbers to line up with. */
:is(table.state, .facts) .meter {
  grid-template-columns: auto 5rem;
}

/* A count's share of the largest in its table: the meter's bar, in the color of the
   status it counts. */
td.bar {
  width: 100%;
  min-width: 5rem;
  vertical-align: middle;
}
td.bar i {
  display: block;
  width: var(--filled);
  min-width: 2px;
  height: 4px;
  border-radius: 2px;
  background: var(--status, var(--periwinkle));
}

/* A count by week: the drawing stretches to the width, so its line keeps its stroke, and
   the numbers at its left and the dates beneath it are text beside it. Bars take the
   color of the status they count, as a share's bar does. */
.plot {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: 0 0.4rem;
  padding: 0.5rem 0.8rem 0.3rem;
  color: var(--muted);
  font-size: 11px;
}
.plot svg {
  display: block;
  width: 100%;
  height: 72px;
  overflow: visible;
  border-bottom: 1px solid var(--line);
}
.plot rect {
  fill: var(--status, var(--periwinkle));
}
.plot rect.hit {
  fill: transparent;
}
.plot polyline {
  fill: none;
  stroke: var(--periwinkle);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}
/* The drawing, and over it a column for each week, which says its week while pointed at:
   beside the column, at its right, or at its left in the later half. */
.plot .drawing {
  position: relative;
}
.plot .weeks {
  position: absolute;
  inset: 0;
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
}
.plot .weeks span {
  position: relative;
}
.plot .weeks span:hover {
  background: color-mix(in srgb, var(--periwinkle) 12%, transparent);
}
.plot .weeks span:hover::after {
  position: absolute;
  z-index: 1;
  top: 0;
  left: calc(100% + 4px);
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--menu-surface);
  color: var(--ink);
  line-height: 1.4;
  white-space: pre;
  content: attr(data-says);
  pointer-events: none;
}
.plot .weeks span.late:hover::after {
  right: calc(100% + 4px);
  left: auto;
}
.plot line {
  stroke: var(--line);
  vector-effect: non-scaling-stroke;
}
.plot .y {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: right;
}
/* The baseline's number, where counts go both ways from it. */
.plot .y .zero {
  position: absolute;
  right: 0;
  translate: 0 -50%;
}
.plot .x {
  display: flex;
  grid-column: 2;
  justify-content: space-between;
}
/* A heading's figure, at its far end; where two are counted, each after a mark in its
   bars' color. */
h2 b {
  float: right;
  color: var(--ink);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}
h2 b i {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 0.4rem;
  background: var(--status, var(--periwinkle));
}
h2 b .aside {
  color: var(--muted);
}

/* What a page waits for, under the line that names it: the meter's bar, running across
   as the website's does. A reader who asked for less motion has the line alone, since
   a bar standing still would read as a meter. */
.loader {
  width: 8rem;
  height: 4px;
  margin: 0.9rem 0 1.1rem;
  overflow: hidden;
  border-radius: 2px;
  background: var(--line-soft);
}
.loader::after {
  display: block;
  width: 40%;
  height: 100%;
  border-radius: inherit;
  background: var(--periwinkle);
  animation: loader 1.8s ease-in-out infinite;
  content: '';
}
@keyframes loader {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(350%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .loader {
    display: none;
  }
}

/* The version a tenant runs, after the one it is to run. */
.was {
  margin-left: 0.5rem;
  color: var(--warning);
}

/* A list's filter: links in one bar, at the title's far end. */
nav.filter {
  display: flex;
  flex-wrap: wrap;
  width: fit-content;
  padding: 2px;
  border: 1px solid var(--line-soft);
  margin-left: auto;
  border-radius: 4px;
  background: var(--surface);
}
nav.filter a {
  padding: 2px 10px;
  border-radius: 3px;
  color: var(--muted-bright);
  font-size: 12px;
  text-transform: capitalize;
  white-space: nowrap;
}
nav.filter a span {
  margin-left: 0.1rem;
  color: var(--muted);
}
nav.filter a:hover {
  color: var(--ink);
  text-decoration: none;
}
nav.filter a[aria-current] {
  background: color-mix(in srgb, var(--periwinkle) 18%, transparent);
  color: var(--ink);
}

/* Statuses. status-<word> alone colors its text; with status it marks the word. */

[class*='status-'] {
  --status: var(--muted);
  color: var(--status);
}
.status-active,
.status-ready,
.status-done,
.status-current {
  --status: var(--sea-glass);
}
.status-provisioning,
.status-creating,
.status-bootstrapping,
.status-queued,
.status-running,
.status-upgrading {
  --status: var(--periwinkle);
}
.status-suspended,
.status-draining,
.status-behind {
  --status: var(--warning);
}
.status-failed,
.status-deleted {
  --status: var(--danger);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: inherit;
  white-space: nowrap;
}
.status::before {
  width: 6px;
  height: 6px;
  border-radius: 1px;
  background: var(--status);
  content: '';
}

/* Controls. */

button,
input,
select {
  height: 26px;
  padding: 0 0.65rem;
  border: 1px solid var(--line);
  border-radius: 3px;
  color: inherit;
  font: 400 12px/1 var(--font-utility);
}
button {
  background: color-mix(in srgb, var(--menu-surface) 60%, transparent);
  white-space: nowrap;
  cursor: pointer;
}
button:hover {
  border-color: color-mix(in srgb, var(--periwinkle) 55%, var(--line));
  background: color-mix(in srgb, var(--periwinkle) 12%, transparent);
}
input,
select {
  background: var(--page);
  font-size: 13px;
}
input:focus,
select:focus {
  border-color: var(--periwinkle);
  outline: none;
}
input::placeholder {
  color: var(--muted);
  opacity: 0.6;
}
input[type='checkbox'] {
  width: 14px;
  height: 14px;
  padding: 0;
  accent-color: var(--periwinkle);
}
td button {
  height: 20px;
  padding: 0 0.5rem;
}

/* Customers' controls have the room their pages do. */
.customers :is(button, input, select) {
  height: 32px;
  font-size: 13px;
}
.customers main button {
  padding: 0 0.9rem;
  font: 600 13px/1 var(--font-body);
}

/* A link that is the thing to do: New community. */
a.button {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 0.9rem;
  border-radius: 3px;
  background: var(--button-background);
  color: var(--button-ink);
  font: 600 13px/1 var(--font-body);
  white-space: nowrap;
}
a.button:hover {
  background: var(--button-hover);
  text-decoration: none;
}
.title a.button {
  margin-left: auto;
}

/* A button that reads as a link: Sign out. */
button.link {
  height: auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted-bright);
  font-size: 13px;
}
button.link:hover {
  background: none;
  color: var(--ink);
}

/* Forms. */

label {
  display: block;
  color: var(--muted);
  font: 400 11px/1.5 var(--font-utility);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
label input,
label select {
  display: block;
  width: 100%;
  margin-top: 0.2rem;
  color: var(--ink);
  letter-spacing: 0;
}
label code {
  color: var(--ink);
  letter-spacing: 0;
  text-transform: none;
}

/* A checkbox and what it means, and a field with words after it, sit in a line. */
label:has(> input[type='checkbox']),
label > span {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--muted-bright);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
}
label:has(> input[type='checkbox']) {
  min-height: 26px;
}
label:has(> input[type='checkbox']) input,
label > span input {
  margin-top: 0;
}
label > span input {
  flex: 1;
  width: auto;
}

form.inline,
.actions form {
  display: inline-flex;
  gap: 0.4rem;
  align-items: end;
}
main > form.inline,
main > section > form.inline {
  margin-bottom: 0.6rem;
}

/* One form under another, its button the thing to do. */
form.stack {
  display: grid;
  gap: 0.6rem;
  max-width: 28rem;
  padding: 0.8rem;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  background: var(--surface);
}
/* The plans to buy, side by side, the chosen one marked. */
fieldset.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.5rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
fieldset.plans legend {
  float: left;
  grid-column: 1 / -1;
  margin-bottom: 0.2rem;
  padding: 0;
  color: var(--muted);
  font: 400 11px/1.5 var(--font-utility);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
fieldset.plans label {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.1rem 0.5rem;
  align-items: baseline;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--ink);
  font: 400 13px/1.4 var(--font-body);
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
}
fieldset.plans label:hover {
  border-color: color-mix(in srgb, var(--periwinkle) 55%, var(--line));
}
fieldset.plans label:has(input:checked) {
  border-color: var(--periwinkle);
  background: color-mix(in srgb, var(--periwinkle) 10%, transparent);
}
fieldset.plans label:has(input:focus-visible) {
  outline: 2px solid var(--periwinkle-bright);
  outline-offset: 1px;
}
fieldset.plans input[type='radio'] {
  width: 14px;
  height: 14px;
  margin: 0;
  padding: 0;
  accent-color: var(--periwinkle);
  align-self: center;
}
fieldset.plans label > span {
  display: block;
  font-size: 13px;
}
fieldset.plans .price {
  font-family: var(--font-utility);
  white-space: nowrap;
}
fieldset.plans .slots {
  grid-column: 2 / -1;
  color: var(--muted-bright);
  font-size: 12px;
}
fieldset.plans p {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 12px;
}

/* The privacy policy, under a form that asks for personal data. */
.privacy {
  color: var(--muted);
  font-size: 12px;
}
.privacy a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.privacy a:hover {
  color: var(--ink);
}

/* Its fields in one row, in a sheet, going to further rows as the window slims. */
form.row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: end;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  background: var(--surface);
}
form.row > label {
  flex: 1 1 12rem;
}
form.row > button {
  min-width: 6rem;
}

/* A link beside the button, such as a filter's Clear. */
form.row > a {
  line-height: 26px;
  white-space: nowrap;
}

:is(form.stack, form.row) > button {
  border-color: transparent;
  background: var(--button-background);
  color: var(--button-ink);
}
:is(form.stack, form.row) > button:hover {
  background: var(--button-hover);
}

/* A page's actions in one bar. One with nothing to fill in is a button; one with
   fields opens its form under its name, and naming the <details> alike keeps one open
   at a time. */
.cmd {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  padding: 0.4rem;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  background: var(--surface);
}
.cmd > form {
  display: contents;
}
.cmd .rule {
  width: 1px;
  height: 18px;
  margin: 0 0.25rem;
  background: var(--line);
}
.cmd details {
  position: relative;
}
.cmd details:last-child {
  margin-left: auto;
}
.cmd summary {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  height: 26px;
  padding: 0 0.65rem;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: color-mix(in srgb, var(--menu-surface) 60%, transparent);
  font-size: 12px;
  list-style: none;
  white-space: nowrap;
  cursor: pointer;
}
.cmd summary::-webkit-details-marker {
  display: none;
}
.cmd summary::after {
  width: 5px;
  height: 5px;
  margin-top: -3px;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(45deg);
  content: '';
}
.cmd summary:hover {
  border-color: color-mix(in srgb, var(--periwinkle) 55%, var(--line));
  background: color-mix(in srgb, var(--periwinkle) 12%, transparent);
}
.cmd details[open] summary {
  border-color: var(--periwinkle);
}
.cmd details form {
  position: absolute;
  z-index: 5;
  top: calc(100% + 6px);
  left: 0;
  width: 19rem;
  border-color: var(--line);
  background: var(--menu-surface);
  box-shadow: 0 12px 32px var(--shadow);
}
.cmd details:last-child form {
  right: 0;
  left: auto;
}
.cmd details p {
  margin: 0;
  color: var(--muted-bright);
  font-size: 12px;
}

/* In a form that opens, the link it is about, and the thing to do that is not the first. */
.cmd details p.secret {
  padding: 0.5rem 0.6rem;
  color: var(--ink);
}
/* What the choices under it are of, and what belongs to a choice: there while it is
   ticked. */
.cmd details p.legend {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.cmd .under {
  display: grid;
  gap: 0.6rem;
  margin-left: 6px;
  padding-left: 14px;
  border-left: 1px solid var(--line);
}
.cmd form:has(#with-password:not(:checked)) .under {
  display: none;
}
.cmd form.stack > button.plain {
  border-color: var(--line);
  background: none;
  color: inherit;
}
.cmd form.stack > button.plain:hover {
  background: color-mix(in srgb, var(--periwinkle) 12%, transparent);
}

/* What cannot be undone. */
button.danger,
.danger summary,
.danger form.stack > button {
  border-color: color-mix(in srgb, var(--danger) 45%, var(--line));
  color: var(--danger);
}
.danger form.stack > button {
  background: none;
}
button.danger:hover,
.danger form.stack > button:hover {
  background: color-mix(in srgb, var(--danger) 14%, transparent);
}

/* What is wrong now, in a line. */
.failing {
  color: var(--danger);
}

/* A filter form over the table it filters. */
form.filters {
  margin-bottom: 0.6rem;
}

/* Links between a long list's pages, under it. */
nav.pages {
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
  margin-top: 0.6rem;
  font: 400 12px/1.5 var(--font-utility);
  white-space: nowrap;
}

/* A page's actions, in a bar that wraps. */
div.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  align-items: end;
  padding: 0.5rem;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  background: var(--surface);
}
td.actions {
  white-space: nowrap;
}
td.actions > :not(:first-child) {
  margin-left: 0.3rem;
}

/* Slim windows. The header's one row needs about 75rem when it has the operators'
   links, and about 40rem without them; under that the links take a second row and the
   header scrolls away with the page. */

/* Jobs beside Backups needs about 86rem; under that they stack. */
@media (max-width: 86rem) {
  .split {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 75rem) {
  header:has(.split) {
    position: static;
    flex-wrap: wrap;
    gap: 0 1rem;
    height: auto;
    padding-top: 7px;
  }
  header:has(.split) nav {
    flex: 1 0 100%;
    flex-wrap: wrap;
    order: 3;
    margin: 0 -0.6rem;
    padding: 4px 0;
  }
  header:has(.split) .who {
    margin-left: auto;
  }
  header .split {
    display: none;
  }
}

@media (max-width: 66rem) {
  .cols,
  .cols.rail {
    grid-template-columns: minmax(0, 1fr);
  }
  nav.filter,
  .chips {
    flex-basis: 100%;
    margin-left: 0;
  }
  nav.filter {
    flex-basis: auto;
  }
  .title {
    row-gap: 0.5rem;
  }
  .facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 40rem) {
  header {
    position: static;
    flex-wrap: wrap;
    gap: 0 0.75rem;
    height: auto;
    padding-top: 7px;
  }
  header nav {
    flex: 1 0 100%;
    flex-wrap: wrap;
    order: 3;
    margin: 0 -0.6rem;
    padding: 4px 0;
  }
  header,
  main {
    padding-inline: 0.75rem;
  }
  header .who {
    display: none;
  }
  header form {
    margin-left: auto;
  }
  header .theme:not([hidden]) ~ form {
    margin-left: 0;
  }
  header:not(:has(form)) nav {
    display: none;
  }
  .facts {
    grid-template-columns: minmax(0, 1fr);
  }
  /* A form opens across the bar, not from its own name, so it cannot hang off the
     screen. */
  .cmd {
    position: relative;
  }
  .cmd details {
    position: static;
  }
  .cmd details:last-child {
    margin-left: 0;
  }
  .cmd details form,
  .cmd details:last-child form {
    right: 0;
    left: 0;
    width: auto;
  }
  .cmd .rule {
    display: none;
  }
}
