:root {
  /* let native controls (buttons, scrollbars) follow the OS light/dark scheme */
  color-scheme: light dark;

  /* page gutter: margins, cell padding, and the gap between panels */
  --gap: 1rem;
  /* vertical separation between blocks */
  --space: .6rem;
  /* hairline rules and panel dividers */
  --line: .7px;
  --radius: 3px;

  --bg: #fff;
  --fg: #111;
  --accent: #C33;
  --accent-strong: #A22;
  --muted: #666;
  --strong: #333;
  --border: #AAA;
  --border-light: #DDD;
  --pre-bg: #F8F8F8;
  --info: #090;
  --warning: #999;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1e1e1e;
    --fg: #ddd;
    --accent: #f77;
    --accent-strong: #e66;
    --muted: #aaa;
    --strong: #ccc;
    --border: #555;
    --border-light: #444;
    --pre-bg: #2a2a2a;
    --info: #6c6;
  }
}

body {
  font-family: Calibri, Helvetica, sans-serif;
  font-size: 16px;
  /* no top margin: the sticky header supplies its own top spacing (via padding),
     so it starts flush at the viewport top and pins without any travel */
  margin: 0 var(--gap) var(--gap) var(--gap);
  background-color: var(--bg);
  color: var(--fg);
  /* the page is at least as tall as the viewport, so that the footer stays at the
     bottom of short pages and is pushed down by longer content */
  min-height: calc(100vh - var(--gap));
  display: flex;
  flex-direction: column;
}

/* the content takes the height that the header and the footer leave */
main {
  flex: 1;
}
/* the rule and the footer are flex items here: they must not be shrunk away, and
   'float' would be ignored, so the footer is aligned by its text */
body > hr, body > footer {
  flex: none;
}
/* the default 'margin: .5em auto' of a rule centres it at zero width in a flex column, which
   makes the line above the footer disappear: only the vertical margins are wanted here */
body > hr {
  margin-inline: 0;
}
body > footer {
  text-align: right;
}

p {
  margin: 0 0 var(--space) 0;
}

h1 {
  font-size: 220%;
  color: var(--accent-strong);
  margin: -2px 0 0 0;
}

h2 {
  font-size: 150%;
  color: var(--accent);
  margin: 0 0 .2rem 0;
}

h3 {
  font-size: 120%;
  color: var(--muted);
  /* the top margin also separates a heading from the block above it */
  margin: var(--space) 0 .2rem 0;
}

table {
  table-layout: fixed;
}

th {
  vertical-align: top;
  text-align: left;
  padding: 0 var(--gap) 0 0;
}

/* right-aligned numeric table columns (was the deprecated align='right' attribute) */
.num {
  text-align: right;
}

td {
  vertical-align: top;
  padding: 0 var(--gap) 0 0;
  border: 0;
}

ol, ul, dd {
  padding-left: 1.2rem;
  margin-left: 0;
}

dl {
  margin: 0;
}

dt {
  margin: var(--space) 0;
  font-weight: bold;
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  text-decoration:underline;
}

/* a control that acts on the server but reads as a link */
button.link {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
}

button.link:hover {
  text-decoration: underline;
}

b {
  color: var(--strong);
}

code {
  font-family: SFMono-Regular, Consolas, Menlo, monospace;
  font-size: 90%;
  border: 1px solid var(--border-light);
  border-radius: var(--radius);
  padding: 0 4px;
  margin: 0 2px;
}

pre {
  font-family: SFMono-Regular, Consolas, Menlo, monospace;
  font-size: 90%;
  border: 1px solid var(--border-light);
  border-radius: var(--radius);
  background-color: var(--pre-bg);
  padding: .5rem;
  margin: .2rem 0 .5rem 0;
}

textarea {
  font-family: SFMono-Regular, Consolas, Menlo, monospace;
  width: 100%;
  /* the border must not add to the width, or the panel scrolls sideways */
  box-sizing: border-box;
  resize: vertical;
  background-color: var(--bg);
  color: var(--fg);
}

textarea, input[type=text], input[type=password], input[type=number],
input[type=submit], select, button {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  outline: none;
}

input[type=text], input[type=password], input[type=number], select {
  padding: 4px;
  width: 200px;
  /* entry fields keep themed colours; buttons stay native so disabled greys out */
  background-color: var(--bg);
  color: var(--fg);
}

input[type=submit], button {
  padding: 4px 8px;
}

input:focus, select:focus, button:focus {
  outline: .5px solid var(--fg);
}

hr {
  height: var(--line);
  border: 0;
  background-color: var(--border);
}

/* page content: one grid column per panel, separated by the gap rather than by
   panel padding, so that a track width is the width of the content */
.content {
  display: grid;
  grid-template-columns: var(--columns);
  /* a gutter on either side of the divider that sits in the middle */
  column-gap: calc(var(--gap) * 2);
  /* keeps a focus ring at the panel top clear of the sticky header */
  padding-top: 2px;
}
.content > .panel {
  /* anchors the divider */
  position: relative;
  /* lets a long value scroll inside the panel instead of widening the track */
  min-width: 0;
}
/* a panel that spans the whole row: it has no divider, and neither has the panel that
   starts the row below it */
.content > .full {
  grid-column: 1 / -1;
}
/* divider, centered in the gap before every panel but the first of a row */
.content > .panel:not(.full) ~ .panel:not(.full)::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--gap) * -1);
  border-left: var(--line) solid var(--border);
}

.error {
  color: var(--accent);
  font-weight: bold;
}

.info {
  color: var(--info);
  font-weight: bold;
}

.warning {
  color: var(--warning);
  font-weight: bold;
}

.ellipsis {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

/* a group of fields: a form, or one column of a form that spreads its fields over columns.
   The group is the grid, so its label column is as wide as its longest label asks for */
form:has(> .field) {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: var(--gap);
}

/* what is not a field spans both columns */
form:has(> .field) > :not(.field) {
  grid-column: 1 / -1;
}

/* labeled form field: label column, control column. A field outside a group is its own grid,
   and its label takes the width it asks for */
.field {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: var(--gap);
  align-items: baseline;
  /* fields belong together, so they sit closer than blocks do; the margin separates them from
     each other and from the block above */
  margin: calc(var(--space) / 2) 0;
}

/* a field of a group adopts the columns of its group, which lines up the controls */
form:has(> .field) > .field:not(.stacked) {
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
}

/* label above its control, for labels too long for a label column */
.field.stacked {
  grid-column: 1 / -1;
  grid-template-columns: 1fr;
}

.note {
  color: var(--muted);
  margin-bottom: var(--space);
}
.header-nav .note {
  /* the header nav is a single row: no spacing before the rule below it */
  margin-bottom: 0;
}

.footnote {
  font-size: 70%;
  color: var(--muted);
}

/* the root of a breadcrumb: bold, and a link like the others */
a.root {
  font-weight: bold;
}

/* page header: pinned to the top while scrolling */
header {
  display: flex;
  align-items: flex-start;
  gap: var(--gap);
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: var(--bg);
  padding-top: .5rem;
}

.header-main {
  flex: 1;
  /* allow the nav line to shrink and truncate instead of pushing the logo away */
  min-width: 0;
  /* the rule that closes the header, kept clear of the nav line above it and of the
     content below it */
  padding-bottom: .5rem;
  border-bottom: var(--line) solid var(--border);
  margin-bottom: .5rem;
}

.header-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--gap);
  flex-wrap: wrap;
}

/* a logout submits instead of following a link, and is shown as one */
.header-top form {
  display: inline;
}

/* the navigation and the status message share one line, separated by a gap of their own */
.header-nav {
  display: flex;
  align-items: baseline;
  column-gap: 1.5rem;
  /* fixed height so the status glyph (fallback font) can't shift the layout */
  line-height: 1.4;
}

.header-nav ul {
  display: flex;
  column-gap: .25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* the separator belongs to the line, not to the entries: it is neither read out nor clickable */
.header-nav li + li::before {
  content: '\B7';
  margin-right: .25rem;
  color: var(--muted);
}

/* the entry of the current view, marked by the same attribute the client is given */
.header-nav a[aria-current] {
  font-weight: bold;
  color: var(--accent-strong);
}

/* a long message truncates instead of pushing the navigation out of the line */
#info {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.header-logo {
  flex: none;
}

/* short page title, shown on narrow screens instead of the full one */
.title-short {
  display: none;
}

/* narrow screens */
@media (max-width: 800px) {
  /* shorten the page title */
  .title-full { display: none; }
  .title-short { display: inline; }
  /* labels above their controls, so the fields keep the full width */
  .field,
  form:has(> .field) > .field {
    grid-template-columns: 1fr;
  }
}
