/* sitekit admin styles. Plain CSS, no build step.

   PART 1: THE VARIABLES. Every colour, font, text size, icon setting and
   corner the admin uses is a variable, set below; the rest of this file
   only uses them.

   There are three modes: light, medium (a soft dark grey) and dark. Each
   person picks one in their own menu, kept with their account: or "Auto"
   (light, or medium when the device is set to dark), or the site's
   brand when it has one. The page is marked with the choice
   (data-theme="medium") before it is drawn.

   A site gives the admin its own look in two ways, both through CSS:
     - Its brand, offered as a choice next to the modes: app.Admin.Brand
       names a stylesheet that sets these variables under
       :root[data-theme="brand"] (variables it leaves out keep the light
       values):
         :root[data-theme="brand"] { --accent: #b4532a; --font-title: Georgia, serif; }
     - For everyone, whatever they chose: its own CSS file loaded through
       the head.html slot, setting variables for each mode:
         :root { --text-md: 1rem; }
         :root[data-theme="medium"] { --accent: #367c60; }

   Its logo is added in Go, with app.Admin.Logo; --logo-h sets its size.

   A font the device doesn't have is added with @font-face in the site's
   file (the font file in its web/static/ folder), then named in --font.

   PART 2: THE PARTS. Classes admin screens (built-in, or added with
   admin.Page) can use:
     .card            a box; .card-head is a row with its h2 and a link
     .settings        a .card in parts: each .setting has a title and
                      note on the left and its form on the right
     .split           two columns on wide screens: content, then a narrow
                      column of settings
     .stack           a form whose fields sit one under the other
     .row             a form whose fields sit side by side
     .field           a label (.label), an optional .hint, the input, and
                      a .mistake (admin.Field draws one); .field.wide for
                      long text
     .check, .choices tick boxes and round choices; .choices puts each in
                      a box, with a .hint under its name
     .switch          an on/off switch (a checkbox)
     .buttons         a row of buttons
     button, .button  the main button; add .secondary, .ghost, .danger,
                      .danger-quiet (red text), .link or .small
     .icon-button     a square button holding only an icon
     .notice          a message: .ok, .problem, .warn or .info, with an
                      icon first and a <p> (and an optional <strong>)
     .table-wrap      a box around a table; a wide table scrolls inside
                      it. table.list turns each row into a block on phones
                      (give each <td> a data-label); table.wide keeps its
                      first column in place while it scrolls; th.num and
                      td.num line up numbers on the right (a box in a
                      td.num is narrow, for a number), td.end holds a
                      row's buttons
     .tag             a small label: .ok, .problem, .warn, .accent
     .status          a coloured dot and a word: .ok, .problem, .warn
     .facts           a <dl> of label/value pairs; .boxed in a box,
                      .across side by side (each pair in a <div>)
     .rows            a list of rows: an icon, a .main line, a .note
     .toolbar         a row above a list (.end pushes an item right)
     .empty           "nothing here yet", with an optional .mark icon
     .widgets         the dashboard's grid of .card boxes (a box with a
                      table in it takes the whole row)
     .tabs            links as tabs (the current one has aria-current)
     .note, .lead     quieter text; a line under the title
     .visually-hidden text only screen readers read
   Icons: {{icon "name"}} in a template draws <svg class="icon">.
   Helpers in admin.js, switched on by attributes:
     data-copy="text"            on a <button type="button">: copies the text
     data-fill-password="a,b"    on a <button type="button"> in a form: fills
                                 fields a and b with a strong random password,
                                 shows it and copies it
     data-busy-label="..."       on a form's button: what it says while the
                                 form is sent (default "Saving…")
     data-confirm="Question?"    on a form: asks first (with
                                 data-confirm-detail and data-confirm-yes)
     data-submit-on-change       on a form: sent as soon as a box in it (or
                                 tied to it with form="...") changes
     data-add-row="id"           on a <button type="button">: adds a copy of
                                 <template id="id" data-to="tbody-id"> to
                                 that tbody, "__N__" in names made unique;
                                 tr.when-empty shows while it has no row
     data-remove-row             on a <button type="button">: removes its row
     details.list-group  a part of a list that folds away: its <summary>
                         holds an h2 and a .note (such as a count)
     .toggles / .toggle / .when-on   in a .toggles (such as a <tr>), .when-on
                                 shows only while its .toggle box is ticked
     data-warn-unsaved           on a form: the browser asks before leaving
                                 the page with changes in it not saved
                                 (="sent" on a form shown again with a
                                 problem: its text counts as not saved)
   Every password field gets a button to show what was typed.
   The standard pieces (admin.Field, Filter, PageLinks, Empty) use these
   too, plus .filter and .pages.

   The site's own slots sit in .slot-above-top-bar, .slot-top-bar-links,
   .slot-above-title, .slot-below-login-form and .slot-footer.

   The page has three parts: .nav (the top bar), .menu (on the left; the
   button at the top left opens and closes it) and main. On a laptop the
   menu starts open and pushes the page over; closed, the page takes the
   whole width. On a phone it starts closed and slides over the page.
   Without JavaScript it is always shown. The page scrolls, never
   sideways: a wide table scrolls inside its own box. */

/* ===================== PART 1: THE VARIABLES ===================== */

:root {
  color-scheme: light;

  /* Typefaces: the device's own, so nothing is downloaded. */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-title: var(--font);  /* page titles and the site's name */
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Text sizes, smallest to largest. In rem, so a person who sets their
     browser's text larger gets a larger admin. */
  --text-xs: .75rem;     /* small labels, counts */
  --text-sm: .84rem;     /* notes under fields, second lines */
  --text-md: .9375rem;   /* normal text: 15px */
  --text-lg: 1.05rem;    /* box titles */
  --text-xl: 1.35rem;    /* the login title */
  --text-2xl: 1.6rem;    /* page titles */
  --text-3xl: 1.9rem;    /* big numbers */

  --weight-normal: 400;
  --weight-medium: 500;  /* menu entries */
  --weight-strong: 600;  /* labels, buttons */
  --weight-title: 650;   /* titles */

  --leading: 1.55;       /* space between lines of text */
  --leading-tight: 1.25; /* ... of titles */
  --title-tracking: -.015em; /* titles sit a touch tighter */

  /* Icons: drawn with lines, in the text's colour. */
  --icon-size: 1.1rem;
  --icon-stroke: 1.75;   /* line thickness, on a 24-unit square */

  /* Corners. */
  --radius-sm: 6px;
  --radius: 8px;
  --radius-lg: 12px;

  /* Sizes of the frame and the controls. */
  --control-h: 2.375rem;     /* buttons and fields: 38px */
  --nav-h: 3.5rem;           /* the top bar */
  --logo-h: 1.75rem;         /* the site's logo in the top bar (half again above the login form) */
  --menu-width: 15.5rem;
  --field-width: 28rem;      /* most fields */
  --field-width-wide: 44rem; /* long text */

  /* Colours, light mode. */
  --bg: #f7f6f3;            /* the page behind the boxes */
  --surface: #ffffff;       /* boxes */
  --surface-2: #f3f1ed;     /* a quiet fill: table headers, hover */
  --surface-3: #e9e6e0;     /* a stronger fill */
  --raised: #ffffff;        /* drop-downs and the "are you sure?" box */
  --text: #2d2b27;
  --text-strong: #1a1916;
  --muted: #6b675f;         /* notes and labels */
  --faint: #9a958b;         /* the quietest text, icons */
  --line: #e8e5df;
  --line-strong: #d6d2ca;
  --input-bg: #ffffff;
  --input-line: #cfcac1;

  --accent: #2d2b27;        /* main buttons */
  --on-accent: #ffffff;     /* text on a main button */
  --accent-text: #1a1916;   /* links, the current tab, small marks */
  --link-underline: var(--faint);

  --nav-bg: #ffffff;
  --menu-bg: #f2f0eb;
  --menu-hover: #e8e5df;
  --menu-current: #ffffff;

  --ok: #1f7a45;       --ok-soft: #eaf5ee;
  --problem: #be3a2e;  --problem-soft: #fcefed;  --on-problem: #ffffff;
  --warn: #946000;     --warn-soft: #fcf3df;

  --shadow-sm: 0 1px 2px rgb(40 30 10 / .06);
  --shadow: 0 1px 2px rgb(40 30 10 / .05), 0 1px 3px rgb(40 30 10 / .04);
  --shadow-pop: 0 12px 32px rgb(40 30 10 / .14), 0 2px 6px rgb(40 30 10 / .06);
  --backdrop: rgb(30 25 15 / .35);
}

/* Colours, medium mode: a soft dark grey. "Auto" picks it when the
   device is set to dark. */
:root[data-theme="medium"] {
  color-scheme: dark;

  --bg: #282725;
  --surface: #31302d;
  --surface-2: #393835;
  --surface-3: #43413d;
  --raised: #3a3936;
  --text: #e4e1db;
  --text-strong: #f5f3ef;
  --muted: #aaa59c;
  --faint: #827d74;
  --line: #3f3d39;
  --line-strong: #534f49;
  --input-bg: #2b2a28;
  --input-line: #5a564f;

  --accent: #ebe8e2;
  --on-accent: #22211f;
  --accent-text: #f5f3ef;

  --nav-bg: #2e2d2a;
  --menu-bg: #2b2a28;
  --menu-hover: #36352f;
  --menu-current: #3d3b37;

  --ok: #7dd3a0;       --ok-soft: #313f35;
  --problem: #ff9f93;  --problem-soft: #4a3330;  --on-problem: #2b0d09;
  --warn: #efc56f;     --warn-soft: #463f2d;

  --shadow-sm: 0 1px 2px rgb(0 0 0 / .2);
  --shadow: 0 1px 2px rgb(0 0 0 / .2);
  --shadow-pop: 0 14px 36px rgb(0 0 0 / .4), 0 2px 6px rgb(0 0 0 / .25);
  --backdrop: rgb(0 0 0 / .45);
}

/* Colours, dark mode: a deep grey, never pure black. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #151514;
  --surface: #1d1d1b;
  --surface-2: #252523;
  --surface-3: #2f2e2b;
  --raised: #252523;
  --text: #e6e4df;
  --text-strong: #f6f4f0;
  --muted: #9e9a91;
  --faint: #716d66;
  --line: #2c2b28;
  --line-strong: #403e3a;
  --input-bg: #191918;
  --input-line: #48453f;

  --accent: #ecebe7;
  --on-accent: #151514;
  --accent-text: #f6f4f0;

  --nav-bg: #1a1a18;
  --menu-bg: #181817;
  --menu-hover: #242422;
  --menu-current: #2a2a27;

  --ok: #66c98f;       --ok-soft: #18271e;
  --problem: #ff8d80;  --problem-soft: #351b1a;  --on-problem: #260806;
  --warn: #e9bb5e;     --warn-soft: #2f2716;

  --shadow-sm: 0 0 0 transparent;
  --shadow: 0 0 0 transparent;
  --shadow-pop: 0 14px 40px rgb(0 0 0 / .6), 0 0 0 1px rgb(255 255 255 / .04);
  --backdrop: rgb(0 0 0 / .6);
}

/* Worked out from the ones above. */
:root {
  --accent-soft: color-mix(in srgb, var(--accent-text) 11%, var(--surface));
  --accent-hover: color-mix(in srgb, var(--accent) 86%, var(--surface));
  --focus: color-mix(in srgb, var(--accent-text) 40%, transparent);
}

/* ===================== PART 2: THE PARTS ===================== */

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

/* Pages fade into each other instead of flashing (in browsers that
   support it; others just load the page). */
@view-transition { navigation: auto; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--text-md);
  font-weight: var(--weight-normal);
  line-height: var(--leading);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: grid;
  grid-template:
    "above above" auto
    "nav   nav"   auto
    "menu  main"  1fr
    "foot  foot"  auto
    / var(--menu-col, var(--menu-width)) minmax(0, 1fr);
  transition: grid-template-columns .22s ease;
}
html.menu-closed { --menu-col: 0px; }

a { color: var(--accent-text); text-underline-offset: .18em; text-decoration-thickness: 1px; text-decoration-color: var(--link-underline); }
a:hover { text-decoration-thickness: 2px; text-decoration-color: currentColor; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
::selection { background: var(--accent-soft); }
button, input, select, textarea { font-family: inherit; }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* --- Icons: each a few lines on a 24-unit square, in the text's colour --- */

.icon {
  display: inline-block;
  width: var(--icon-size);
  height: var(--icon-size);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -.2em;
}

/* --- Slots the site fills --- */

.slot-above-top-bar { grid-area: above; }
.slot-footer { grid-area: foot; }
.slot-top-bar-links { display: flex; align-items: center; gap: 1rem; }

/* --- Top bar --- */

.nav {
  grid-area: nav;
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: .5rem;
  height: var(--nav-h);
  padding: 0 .75rem;
  background: var(--nav-bg);
  border-bottom: 1px solid var(--line);
}
.nav .site {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  min-width: 0;
  margin-right: auto;
  padding: .25rem .4rem;
  border-radius: var(--radius-sm);
  color: var(--text-strong);
  font-family: var(--font-title);
  font-size: var(--text-lg);
  font-weight: var(--weight-title);
  text-decoration: none;
  white-space: nowrap;
}
.nav .site span { overflow: hidden; text-overflow: ellipsis; }
.nav .site small { color: var(--faint); font-family: var(--font); font-size: var(--text-sm); font-weight: var(--weight-medium); }

/* The site's logo (app.Admin.Logo), before its name. With a version for
   dark colours, the medium and dark modes show that one instead. */
.site-logo { display: block; flex: none; align-self: center; width: auto; height: var(--logo-h); max-width: 10rem; object-fit: contain; }
.site-logo-dark,
:root[data-theme="medium"] .site-logo-light,
:root[data-theme="dark"] .site-logo-light { display: none; }
:root[data-theme="medium"] .site-logo-dark,
:root[data-theme="dark"] .site-logo-dark { display: block; }

/* A square button with only an icon in it. Give it a name for screen
   readers (a .visually-hidden span) and a title for the mouse. */
.icon-button {
  display: inline-grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  box-shadow: none;
  color: var(--muted);
  cursor: pointer;
  flex: none;
}
.icon-button:hover { background: var(--surface-2); color: var(--text-strong); }
.icon-button .icon { --icon-size: 1.2rem; margin: 0; }
.icon-button.small { width: 2rem; height: 2rem; padding: 0; }
.icon-button.small .icon { --icon-size: 1.05rem; }
.icon-button.problem:hover { background: var(--problem-soft); color: var(--problem); }

/* The person's button at the right: their initial and name. */
.me {
  display: flex;
  align-items: center;
  gap: .55rem;
  height: var(--control-h);
  padding: 0 .55rem 0 .3rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  box-shadow: none;
  color: var(--text);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  cursor: pointer;
}
.me:hover { background: var(--surface-2); }
.me .name { max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.me .icon { --icon-size: .95rem; margin: 0; color: var(--faint); }
.avatar {
  display: grid;
  place-items: center;
  width: 1.85rem;
  height: 1.85rem;
  border-radius: 50%;
  background: var(--surface-3);
  color: var(--text-strong);
  font-size: var(--text-xs);
  font-weight: var(--weight-title);
  flex: none;
}
/* Phones: room for the site's name; the person shows as their initial. */
@media (max-width: 40rem) {
  .nav .site small, .me .icon { display: none; }
  /* The name is still read out by screen readers, just not shown. */
  .me .name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .me { padding: 0 .2rem; }
}

/* --- Menu --- */

.menu {
  grid-area: menu;
  min-width: 0;
  overflow: clip; /* "clip", not "hidden", or the list inside can't stay in place */
  background: var(--menu-bg);
  border-right: 1px solid var(--line);
}
.menu-inner {
  position: sticky;
  top: var(--nav-h);
  width: var(--menu-width);
  max-height: calc(100dvh - var(--nav-h));
  overflow-y: auto;
  padding: .9rem .75rem 2rem;
}
@media (min-width: 60.01rem) {
  html.menu-closed .menu { visibility: hidden; transition: visibility 0s .22s; }
}
/* Without JavaScript the menu is always shown, so its button is left out. */
html:not(.js) .menu-button { display: none; }

.menu ul { margin: 0; padding: 0; list-style: none; }
.menu li + li { margin-top: 1px; }
.menu li > a, .menu li > .label, .menu summary {
  display: flex;
  align-items: center;
  gap: .65rem;
  min-height: 2.25rem;
  padding: .3rem .7rem;
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
.menu .icon { color: var(--faint); }
.menu li > a:hover, .menu summary:hover { background: var(--menu-hover); color: var(--text-strong); }
.menu li > a:hover .icon, .menu summary:hover .icon { color: var(--text-strong); }
.menu a[aria-current="page"] {
  background: var(--menu-current);
  color: var(--text-strong);
  font-weight: var(--weight-strong);
  box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--line);
}
.menu a[aria-current="page"] .icon { color: var(--text-strong); }
/* A heading that opens to its sub-options (a section, such as SEO). */
.menu summary { list-style: none; cursor: pointer; }
.menu summary::-webkit-details-marker { display: none; }
.menu summary::after {
  content: "";
  margin-left: auto;
  width: .38rem;
  height: .38rem;
  border: solid var(--faint);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(-45deg);
  transition: transform .15s;
  flex: none;
}
.menu details[open] > summary::after { transform: rotate(45deg) translate(-2px, -1px); }
/* A heading that is also a link: the link takes the row, the arrow opens. */
.menu summary > a { display: flex; align-items: center; gap: .65rem; flex: 1; color: inherit; text-decoration: none; border-radius: var(--radius-sm); }
/* Sub-options sit under their heading's text, past the icon, with none
   of their own. */
.menu details ul { margin: 1px 0 .35rem 1.25rem; padding-left: .7rem; border-left: 1px solid var(--line-strong); }
.menu details ul .icon { display: none; }
/* A heading with no link and nothing under it: a quiet group label. */
.menu li > .label {
  min-height: 0;
  margin: 1.1rem 0 .2rem;
  color: var(--faint);
  font-size: var(--text-xs);
  font-weight: var(--weight-title);
  letter-spacing: .07em;
  text-transform: uppercase;
}
/* Phones only: the menu's own close button. */
.menu-head { display: none; }

/* Phones and small tablets: the menu slides over the page. */
@media (max-width: 60rem) {
  body { grid-template: "above" auto "nav" auto "menu" auto "main" 1fr "foot" auto / 100%; }
  .menu-inner { position: static; width: auto; max-height: none; }

  .js .menu {
    position: fixed;
    z-index: 50;
    inset: 0 auto 0 0;
    width: min(18rem, 86vw);
    border-right: 1px solid var(--line);
    box-shadow: var(--shadow-pop);
    overflow-y: auto;
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform .22s ease, visibility 0s .22s;
  }
  .js.menu-open .menu { transform: none; visibility: visible; transition: transform .22s ease; }
  .js .menu-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--nav-h);
    padding: 0 .75rem 0 1.1rem;
    border-bottom: 1px solid var(--line);
    color: var(--text-strong);
    font-weight: var(--weight-title);
  }
  .scrim { position: fixed; inset: 0; z-index: 40; background: var(--backdrop); opacity: 0; visibility: hidden; transition: opacity .22s, visibility 0s .22s; }
  .js.menu-open .scrim { opacity: 1; visibility: visible; transition: opacity .22s; }
  .js.menu-open body { overflow: hidden; }
}
@media (min-width: 60.01rem) { .scrim { display: none; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0s !important; }
}

/* --- The page --- */

main {
  grid-area: main;
  min-width: 0;
  padding: 1.75rem 2.25rem 5rem;
}
@media (max-width: 40rem) { main { padding: 1.25rem 1rem 4rem; } }

/* The top of a page: a way back (to the menu entry it is under), then the
   title. A .lead right after it sits close under the title. */
.page-head { margin: 0 0 1.5rem; }
.page-head h1 { margin: 0; }
.page-head + .lead { margin: -1.1rem 0 1.5rem; }
.back { display: inline-flex; align-items: center; gap: .35rem; margin-bottom: .5rem; color: var(--muted); font-size: var(--text-sm); font-weight: var(--weight-medium); text-decoration: none; }
.back:hover { color: var(--text-strong); }
.back .icon { --icon-size: 1rem; }

/* --- Text --- */

h1, h2, h3 { color: var(--text-strong); line-height: var(--leading-tight); overflow-wrap: anywhere; }
h1 { font-family: var(--font-title); font-size: var(--text-2xl); font-weight: var(--weight-title); letter-spacing: var(--title-tracking); margin: 0 0 1rem; }
h2 { font-size: var(--text-lg); font-weight: var(--weight-title); margin: 0 0 .75rem; }
h3 { font-size: var(--text-md); font-weight: var(--weight-title); margin: 0 0 .5rem; }
p { margin: 0 0 1rem; max-width: 68ch; }
.lead { color: var(--muted); font-size: var(--text-md); }
.note { color: var(--muted); font-size: var(--text-sm); }
strong { font-weight: var(--weight-strong); color: var(--text-strong); }
code, kbd { font-family: var(--font-mono); font-size: .85em; padding: .12em .38em; border-radius: 5px; background: var(--surface-2); border: 1px solid var(--line); }
kbd { border-bottom-width: 2px; }

/* --- Boxes --- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.35rem 1.5rem;
  margin: 0 0 1.25rem;
}
.card > :last-child { margin-bottom: 0; }
.card-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; margin: 0 0 1rem; }
.card-head h2 { margin: 0; }
.card-head .note { margin: .2rem 0 0; }

/* Two columns on wide screens: the content, then a narrow column of its
   settings. One under the other on smaller screens. */
.split { display: grid; gap: 1.25rem; align-items: start; }
.split > * { min-width: 0; }
@media (min-width: 72rem) { .split { grid-template-columns: minmax(0, 1fr) 20rem; } }

/* A box in parts: each part's title and note on the left, its form on the
   right; one under the other on a phone. */
.settings { padding: 0; }
.setting { display: grid; gap: .75rem 2.5rem; padding: 1.5rem; border-top: 1px solid var(--line); }
.setting:first-child { border-top: 0; }
.setting h2 { margin: 0 0 .3rem; font-size: var(--text-md); }
.setting .note { margin: 0; }
.setting form { margin: 0; }
.setting .notice { margin-bottom: 1rem; }
@media (min-width: 56rem) { .setting { grid-template-columns: 16rem minmax(0, 1fr); } }

/* Label / value pairs. */
.facts { display: grid; grid-template-columns: max-content 1fr; gap: .55rem 2rem; margin: 0 0 1.5rem; }
.facts dt { color: var(--muted); }
.facts dd { margin: 0; overflow-wrap: anywhere; color: var(--text-strong); }
.facts.boxed { padding: 1.1rem 1.5rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); }
.facts.across { display: flex; flex-wrap: wrap; gap: 1rem 3rem; }
.facts.across dt { font-size: var(--text-sm); margin-bottom: .15rem; }

/* --- Messages --- */

.notice {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .15rem .75rem;
  padding: .85rem 1rem;
  margin: 0 0 1.25rem;
  border: 1px solid color-mix(in srgb, var(--tone) 28%, transparent);
  border-radius: var(--radius);
  background: var(--tone-soft);
  color: var(--text);
}
.notice > .icon { margin-top: .15rem; color: var(--tone); grid-row: span 2; }
.notice strong { color: var(--text-strong); }
.notice p { margin: 0; max-width: none; }
.notice, .notice.info { --tone: var(--muted); --tone-soft: var(--surface-2); }
.notice.ok      { --tone: var(--ok);      --tone-soft: var(--ok-soft); }
.notice.problem { --tone: var(--problem); --tone-soft: var(--problem-soft); }
.notice.warn    { --tone: var(--warn);    --tone-soft: var(--warn-soft); }

/* --- Buttons --- */

button, .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  height: var(--control-h);
  padding: 0 1rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: var(--shadow-sm), inset 0 1px 0 rgb(255 255 255 / .1);
  transition: background-color .12s, border-color .12s, box-shadow .12s, color .12s;
}
button:hover, .button:hover { background: var(--accent-hover); }
button:active, .button:active { transform: translateY(.5px); }
button .icon, .button .icon { --icon-size: 1rem; margin-left: -.15rem; }
.button .icon:last-child:not(:first-child) { margin: 0 -.15rem 0 0; }

button.secondary, .button.secondary {
  background: var(--surface);
  color: var(--text-strong);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-sm);
}
button.secondary:hover, .button.secondary:hover { background: var(--surface-2); border-color: var(--input-line); }

button.ghost, .button.ghost { background: transparent; color: var(--text); box-shadow: none; }
button.ghost:hover, .button.ghost:hover { background: var(--surface-2); color: var(--text-strong); }

button.danger, .button.danger { background: var(--problem); color: var(--on-problem); }
button.danger:hover, .button.danger:hover { background: color-mix(in srgb, var(--problem) 86%, var(--text-strong)); }
button.danger-quiet, .button.danger-quiet { background: var(--surface); color: var(--problem); border-color: color-mix(in srgb, var(--problem) 40%, var(--line-strong)); box-shadow: var(--shadow-sm); }
button.danger-quiet:hover, .button.danger-quiet:hover { background: var(--problem-soft); }

button.link { height: auto; padding: 0; border: 0; background: none; box-shadow: none; color: var(--accent-text); font-size: inherit; font-weight: var(--weight-medium); text-decoration: underline; text-decoration-color: var(--link-underline); text-underline-offset: .18em; }

button.small, .button.small { height: 2rem; padding: 0 .75rem; font-size: var(--text-xs); border-radius: var(--radius-sm); }

button:disabled, button:disabled:hover {
  background: var(--surface-2);
  color: var(--faint);
  border-color: var(--line);
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}
.buttons { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: 0 0 1rem; }

/* --- Drop-downs: the browser's own pop-up (popover), so it opens, closes
   on a click outside and closes with Escape without script; admin.js
   only places it under its button --- */

[popover].pop {
  position: fixed;
  inset: auto;
  margin: 0;
  min-width: 16.5rem;
  max-width: calc(100vw - 1rem);
  padding: .35rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--raised);
  color: var(--text);
  box-shadow: var(--shadow-pop);
}
/* Without JavaScript nothing places it: it opens under the top bar, at the
   right, where the person's own menu is. Browsers that can tie it to its
   button in CSS (anchor positioning) put it right under the button, even
   with a site's banner above the top bar. */
html:not(.js) [popover].pop { top: var(--nav-h); right: .5rem; }
.me { anchor-name: --account-menu; }
@supports (anchor-name: --x) {
  html:not(.js) #account-menu { position-anchor: --account-menu; top: calc(anchor(bottom) + 6px); right: anchor(right); }
}
.pop .who { padding: .55rem .65rem .7rem; margin-bottom: .3rem; border-bottom: 1px solid var(--line); font-size: var(--text-sm); }
.pop .who strong { display: block; }
.pop .who span { color: var(--muted); overflow-wrap: anywhere; }
.pop hr { border: 0; border-top: 1px solid var(--line); margin: .3rem 0; }
.pop form { margin: 0; }
.pop .item {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: .6rem;
  width: 100%;
  height: auto;
  padding: .5rem .65rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  box-shadow: none;
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: 1.3;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.pop .item:hover { background: var(--surface-2); color: var(--text-strong); }
.pop .item .icon { --icon-size: 1rem; margin: 0; color: var(--faint); }
.pop .item.problem, .pop .item.problem .icon { color: var(--problem); }
.pop .item.problem:hover { background: var(--problem-soft); }
/* The person's choice of colours, in their own menu: a form of buttons in
   a row, the chosen one raised. */
.modes { padding: .45rem .65rem .6rem; margin: 0 0 .3rem; border-bottom: 1px solid var(--line); }
.modes > span { display: block; margin-bottom: .35rem; color: var(--muted); font-size: var(--text-xs); font-weight: var(--weight-strong); }
.modes > div { display: flex; gap: 2px; padding: 2px; border-radius: var(--radius); background: var(--bg); border: 1px solid var(--line); }
.modes button { flex: 1; height: 1.9rem; padding: 0 .4rem; border: 0; border-radius: var(--radius-sm); background: transparent; box-shadow: none; color: var(--muted); font-size: var(--text-xs); font-weight: var(--weight-medium); }
.modes button:hover { background: var(--surface-3); color: var(--text-strong); }
.modes button[aria-pressed="true"] { background: var(--raised); color: var(--text-strong); box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--line); }

/* --- Forms --- */

form { margin: 0 0 1rem; }
.stack { display: grid; gap: 1.15rem; }
.stack > .buttons { margin: .25rem 0 0; }
.row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem; }
.row .field { flex: 1 1 14rem; }

.field { display: grid; gap: .35rem; max-width: var(--field-width); }
.field.wide { max-width: var(--field-width-wide); }
.field > .label { color: var(--text-strong); font-size: var(--text-sm); font-weight: var(--weight-strong); }
.field .optional { font-weight: var(--weight-normal); color: var(--faint); }
.field .hint { color: var(--muted); font-size: var(--text-sm); margin-top: -.1rem; }
.field .mistake { display: flex; gap: .4rem; align-items: flex-start; color: var(--problem); font-size: var(--text-sm); font-weight: var(--weight-medium); }
.field .mistake .icon { --icon-size: 1rem; margin-top: .05rem; }

input:not([type=checkbox], [type=radio], [type=file], [type=hidden]), select, textarea {
  width: 100%;
  min-height: var(--control-h);
  padding: .4rem .75rem;
  border: 1px solid var(--input-line);
  border-radius: var(--radius);
  background: var(--input-bg);
  color: var(--text-strong);
  font-size: var(--text-md);
  box-shadow: inset 0 1px 1px rgb(0 0 0 / .03);
  transition: border-color .12s, box-shadow .12s;
}
textarea { min-height: 7.5rem; resize: vertical; line-height: var(--leading); padding-block: .55rem; }
input:hover, select:hover, textarea:hover { border-color: var(--faint); }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; border-color: var(--accent-text); box-shadow: 0 0 0 3px var(--focus); }
[aria-invalid="true"], [aria-invalid="true"]:hover { border-color: var(--problem) !important; }
[aria-invalid="true"]:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--problem) 30%, transparent) !important; }
input:disabled, select:disabled, textarea:disabled { background: var(--surface-2); color: var(--muted); border-color: var(--line); cursor: not-allowed; box-shadow: none; }
::placeholder { color: var(--faint); opacity: 1; }

/* A password field with its eye button (admin.js adds it) inside, at the
   right. */
.password { position: relative; display: block; }
.password input { padding-right: 2.6rem; }
.password .icon-button { position: absolute; right: .2rem; top: 50%; transform: translateY(-50%); }

/* A button whose form is being sent ("Saving…"). */
button[aria-busy="true"], .button[aria-busy="true"] { opacity: .7; cursor: progress; }

/* A drop-down list with a drawn arrow, the same in every browser. */
select {
  appearance: none;
  padding-right: 2.25rem;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: right 1.05rem center, right .75rem center;
  background-size: .3rem .3rem;
  background-repeat: no-repeat;
}

/* Dates and times: the browser's own calendar and clock. */
input[type=date], input[type=time] { max-width: 12rem; }
input::-webkit-calendar-picker-indicator { opacity: .6; cursor: pointer; }

/* Tick boxes and round choices. */
.check { display: flex; align-items: flex-start; gap: .65rem; color: var(--text); cursor: pointer; }
.check input { width: 1.1rem; height: 1.1rem; margin: .18rem 0 0; accent-color: var(--accent); flex: none; cursor: pointer; }
.check .hint { display: block; color: var(--muted); font-size: var(--text-sm); }
fieldset { border: 0; padding: 0; margin: 0; display: grid; gap: .6rem; min-width: 0; }
legend { color: var(--text-strong); font-size: var(--text-sm); font-weight: var(--weight-strong); padding: 0; margin-bottom: .5rem; }
.choices { display: grid; gap: .5rem; max-width: var(--field-width-wide); }
.choices .check { padding: .75rem .9rem; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--surface); }
.choices .check:hover { border-color: var(--faint); }
.choices .check:has(input:checked) { border-color: var(--accent-text); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-text); }
.choices strong { display: block; font-weight: var(--weight-strong); }

/* An on/off switch, for a setting that applies at once. */
.switch { display: flex; align-items: flex-start; gap: .75rem; cursor: pointer; }
.switch input { appearance: none; flex: none; width: 2.2rem; height: 1.3rem; margin: .1rem 0 0; border-radius: 999px; background: var(--line-strong); position: relative; cursor: pointer; transition: background-color .15s; }
.switch input::after { content: ""; position: absolute; top: 2px; left: 2px; width: calc(1.3rem - 4px); height: calc(1.3rem - 4px); border-radius: 50%; background: var(--surface); box-shadow: 0 1px 2px rgb(0 0 0 / .25); transition: transform .15s; }
.switch input:checked { background: var(--accent); }
.switch input:checked::after { transform: translateX(.9rem); background: var(--on-accent); }
.switch .hint { display: block; color: var(--muted); font-size: var(--text-sm); }

/* Choosing a file (a photo). */
input[type=file] { font-size: var(--text-sm); color: var(--muted); max-width: 100%; }
input[type=file]::file-selector-button {
  margin-right: .75rem;
  height: 2.125rem;
  padding: 0 .9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text-strong);
  font-family: var(--font);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
  cursor: pointer;
}
input[type=file]::file-selector-button:hover { background: var(--surface-2); }

/* --- Tabs (languages) --- */

.tabs { display: flex; gap: .25rem; margin: 0 0 1.25rem; border-bottom: 1px solid var(--line); overflow-x: auto; }
.tabs a { display: inline-flex; align-items: center; gap: .4rem; padding: .55rem .2rem; margin: 0 .6rem -1px 0; border-bottom: 2px solid transparent; color: var(--muted); font-weight: var(--weight-medium); text-decoration: none; white-space: nowrap; }
.tabs a:hover { color: var(--text-strong); }
.tabs a[aria-current] { color: var(--text-strong); border-bottom-color: var(--accent-text); }

/* --- Tables --- */

.table-wrap {
  position: relative; /* keeps hidden labels inside, so they can't widen the page */
  overflow-x: auto;
  margin: 0 0 1.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
table { border-collapse: separate; border-spacing: 0; width: 100%; }
th, td { text-align: left; padding: .7rem 1rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
th { background: var(--surface-2); color: var(--muted); font-size: var(--text-sm); font-weight: var(--weight-strong); white-space: nowrap; }
thead th:first-child { border-top-left-radius: calc(var(--radius-lg) - 1px); }
thead th:last-child { border-top-right-radius: calc(var(--radius-lg) - 1px); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
td { color: var(--text); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.num { width: 1%; }
tbody:has(> tr:not(.when-empty)) > tr.when-empty { display: none; }
details.list-group { margin: 0 0 1rem; }
details.list-group > summary { display: flex; align-items: center; gap: .5rem; padding: .4rem 0; cursor: pointer; list-style: none; }
details.list-group > summary::-webkit-details-marker { display: none; }
/* An arrow that points down while open, right while folded. */
details.list-group > summary::before { content: ""; width: .45rem; height: .45rem; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); margin: 0 .2rem .2rem 0; transition: transform .15s; }
details.list-group:not([open]) > summary::before { transform: rotate(-45deg); margin-bottom: 0; }
details.list-group > summary h2 { display: inline; margin: 0; font-size: var(--text-md); }
/* Each part is its own table: fixed widths keep their columns lined up. */
details.list-group table.list { table-layout: fixed; }
details.list-group table.list .num { width: 6rem; }
details.list-group table.list .end { width: 7.5rem; }
.toggles:has(.toggle:not(:checked)) .when-on { display: none; }
.times { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; }
.times input[type="time"] { width: auto; }
td.num input { width: 4.5rem; text-align: right; }
td.end, th.end { text-align: right; width: 1%; white-space: nowrap; }
td .sub { display: block; color: var(--muted); font-size: var(--text-sm); }
td a.title { color: var(--text-strong); font-weight: var(--weight-strong); text-decoration: none; }
td a.title:hover { text-decoration: underline; }
table.wide td { white-space: nowrap; }
table.wide th:first-child, table.wide td:first-child { position: sticky; left: 0; z-index: 1; background: var(--surface); box-shadow: inset -1px 0 var(--line); }
table.wide th:first-child { background: var(--surface-2); }

@media (max-width: 40rem) {
  table.list thead { display: none; }
  table.list, table.list tbody, table.list tr, table.list td { display: block; }
  table.list tr { padding: .85rem 1rem; border-bottom: 1px solid var(--line); }
  table.list tbody tr:last-child { border-bottom: 0; }
  table.list td { display: flex; gap: .75rem; padding: .12rem 0; border: 0; text-align: left; } /* numbers too, so each label lines up */
  table.list td[data-label]::before { content: attr(data-label); flex: 0 0 5.5rem; color: var(--muted); font-size: var(--text-sm); }
  table.list td:first-child { display: block; padding-bottom: .4rem; }
  table.list td.end { width: auto; padding-top: .4rem; }
  table.list tbody tr:hover td { background: none; }
}

/* --- Small labels --- */

.tag {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .05rem .45rem;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--muted);
  border: 1px solid var(--line);
  font-size: var(--text-xs);
  font-weight: var(--weight-strong);
  line-height: 1.5;
  white-space: nowrap;
  vertical-align: .08em;
}
.tag .icon { --icon-size: .8rem; }
.tag.ok      { background: var(--ok-soft);      color: var(--ok);          border-color: color-mix(in srgb, var(--ok) 22%, transparent); }
.tag.problem { background: var(--problem-soft); color: var(--problem);     border-color: color-mix(in srgb, var(--problem) 22%, transparent); }
.tag.warn    { background: var(--warn-soft);    color: var(--warn);        border-color: color-mix(in srgb, var(--warn) 22%, transparent); }
.tag.accent  { background: var(--accent-soft);  color: var(--accent-text); border-color: color-mix(in srgb, var(--accent-text) 22%, transparent); }
.status { display: inline-flex; align-items: baseline; gap: .5rem; }
.status::before { content: ""; flex: none; width: .5rem; height: .5rem; border-radius: 50%; background: var(--faint); transform: translateY(-.05em); }
.status.ok::before { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); }
.status.problem::before { background: var(--problem); box-shadow: 0 0 0 3px var(--problem-soft); }
.status.warn::before { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-soft); }

/* --- Lists of things --- */

.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem; margin: 0 0 1rem; }
.toolbar > p { margin: 0; }
.toolbar .end { margin-left: auto; }

.filter { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem; margin: 0 0 1rem; }
.filter .field { flex: 1 1 12rem; max-width: 18rem; }
.filter .clear { line-height: var(--control-h); padding: 0 .25rem; font-size: var(--text-sm); }

.pages { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin: 0 0 1.25rem; color: var(--muted); font-size: var(--text-sm); }

.empty { display: grid; justify-items: center; gap: .35rem; padding: 3rem 1.5rem; margin: 0 0 1.25rem; text-align: center; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); }
.empty h2 { margin: .4rem 0 0; font-size: var(--text-md); }
.empty p { margin: 0 0 .75rem; color: var(--muted); }
.empty .mark { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: 50%; background: var(--surface-2); border: 1px solid var(--line); color: var(--muted); }
.empty .mark .icon { --icon-size: 1.3rem; }

.rows { list-style: none; margin: 0 0 1rem; padding: 0; }
.rows li { display: flex; align-items: center; gap: .9rem; padding: .8rem 0; border-top: 1px solid var(--line); }
.rows li:first-child { border-top: 0; padding-top: 0; }
.rows li > div { flex: 1 1 auto; min-width: 0; }
.rows li > .icon { color: var(--faint); --icon-size: 1.25rem; }
.rows .main { display: flex; flex-wrap: wrap; gap: .25rem .5rem; align-items: center; color: var(--text-strong); font-weight: var(--weight-strong); }
.rows .note { display: block; margin-top: .1rem; overflow-wrap: anywhere; }

/* --- Dashboard --- */

.widgets { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); margin: 0 0 1.25rem; }
.widgets .card { margin: 0; min-width: 0; }
/* A box with a table in it (such as System) takes the whole row, so its
   columns have room. */
.widgets .card:has(table) { grid-column: 1 / -1; }
.widgets .table-wrap { margin: 0; box-shadow: none; }

/* --- "Are you sure?" box (admin.js) --- */

dialog {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  width: min(27rem, calc(100vw - 2rem));
  background: var(--raised);
  color: var(--text);
  box-shadow: var(--shadow-pop);
}
dialog::backdrop { background: var(--backdrop); }
dialog h2 { font-size: var(--text-lg); margin: 0 0 .45rem; }
dialog p { margin: 0 0 1.5rem; color: var(--muted); }
dialog form { margin: 0; }
dialog menu { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .6rem; margin: 0; padding: 0; }

/* --- The login screen: no menu, a narrow column in the middle --- */

body.bare { grid-template: "above" auto "main" 1fr "foot" auto / 100%; }
main.login { display: grid; align-content: center; justify-items: center; padding: 3rem 1rem 6rem; }
.login .site { display: flex; align-items: center; gap: .6rem; margin: 0 0 1.5rem; color: var(--text-strong); font-family: var(--font-title); font-size: var(--text-lg); font-weight: var(--weight-title); }
.login .site-logo { height: calc(var(--logo-h) * 1.5); max-width: 15rem; }
.login .card { width: 100%; max-width: 24rem; padding: 2rem; }
.login h1 { font-size: var(--text-xl); margin: 0 0 .3rem; }
.login .card > .note:first-of-type { margin: 0 0 1.5rem; }
.login .card > .note:last-child { margin: 1.25rem 0 0; }
.login .field { max-width: none; }
.login .stack > button { width: 100%; height: 2.6rem; }
.login .slot-below-login-form { width: 100%; max-width: 24rem; margin: 1.25rem 0 0; text-align: center; color: var(--muted); font-size: var(--text-sm); }
.login .slot-below-login-form > :last-child { margin-bottom: 0; }
