/* The manager's own stylesheet.

   Deliberately not the app's, for the reason the manual's is not
   either: this is three pages somebody sees once, before they have a
   team at all, and it cannot fetch a byte from an instance that may
   not exist yet. What it shares with the app is the world DESIGN.md
   sets out — white sheets on a cool grey page, strawberry as the one
   accent, Jelly's seven type sizes and Jelly's spacing scale — without
   sharing a layout. Sharing the colours and the type without sharing
   the chrome is what makes this feel like part of Jelly and not like
   Jelly.

   The palette and both scales below are a copy of jam.css's, under the
   manager's own names, and palette_test.go holds the two copies equal.
   The values that are the manager's own, and so are not held, are the
   three tone lines: a callout in prose wants a visible edge, and the
   app draws its tones as pills, which want none. Change one of those
   knowingly; change any other here and in jam.css together.

   No icon is drawn anywhere. The app's icons are a Font Awesome subset
   cut from Jelly's licensed files, and three pages do not earn a
   second copy of it — so a state says what it is in words, which is
   what "never colour alone" asks for anyway.

   No script runs on these pages. The team page refreshes itself with a
   meta tag, the form validates on the server, and there is nothing
   else here that moves. */

/* Source Sans 3 is the fallback, not the face: Jelly is set in the
   platform's own — San Francisco, Segoe UI, Roboto — and this is what
   draws it where none of those is installed, which is most Linux
   desktops and the test rig. Upright only; nothing here is italic. */
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/sourcesans3-normal.woff2") format("woff2");
}

:root {
  color-scheme: light;

  --mgr-page: hsl(240 5% 98.5%);        /* the page: barely off white, never beige */
  --mgr-sheet: #ffffff;
  --mgr-sheet-2: hsl(240 5% 95.5%);
  --mgr-line: hsl(240 5% 90%);
  --mgr-line-strong: hsl(240 5% 65%);
  --mgr-ink: hsl(240 5% 15%);
  --mgr-muted: hsl(240 5% 38%);
  --mgr-faint: hsl(240 5% 48%);

  --mgr-accent: hsl(342 75% 55%);        /* strawberry-600 */
  --mgr-accent-strong: hsl(342 70% 46%); /* strawberry-700 */
  --mgr-accent-soft: hsl(342 95% 95%);   /* strawberry-50 */
  --mgr-on-accent: #ffffff;

  --mgr-tone-positive-fg: hsl(135 88% 26%); --mgr-tone-positive-bg: hsl(135 90% 92%);
  --mgr-tone-warning-fg: hsl(45 88% 26%);   --mgr-tone-warning-bg: hsl(45 90% 92%);
  --mgr-tone-negative-fg: hsl(2 70% 46%);   --mgr-tone-negative-bg: hsl(2 90% 92%);
  /* The manager's own: see the header. */
  --mgr-tone-positive-line: hsl(135 55% 70%);
  --mgr-tone-warning-line: hsl(38 80% 70%);
  --mgr-tone-negative-line: hsl(2 75% 78%);

  /* Jelly's seven sizes, and no others. */
  --mgr-fs-2xs: 0.625rem;   /* 10px */
  --mgr-fs-xs: 0.75rem;     /* 12px — a hint, fine print */
  --mgr-fs-s: 0.875rem;     /* 14px — the chrome: a field's label, a button */
  --mgr-fs-m: 1rem;         /* 16px — the reading size */
  --mgr-fs-l: 1.125rem;     /* 18px */
  --mgr-fs-xl: 1.375rem;    /* 22px */
  --mgr-fs-2xl: 1.75rem;    /* 28px — a page's title */
  --mgr-track-tight: -0.01em;

  /* Jelly's spacing scale: every margin, padding and gap is a step. */
  --mgr-sp-3xs: 0.125rem;   /* 2px */
  --mgr-sp-2xs: 0.25rem;    /* 4px */
  --mgr-sp-xs: 0.5rem;      /* 8px */
  --mgr-sp-s: 0.75rem;      /* 12px */
  --mgr-sp-m: 1rem;         /* 16px */
  --mgr-sp-l: 1.5rem;       /* 24px */
  --mgr-sp-xl: 2rem;        /* 32px */
  --mgr-sp-2xl: 2.5rem;     /* 40px */
  --mgr-sp-3xl: 3rem;       /* 48px */
  --mgr-sp-4xl: 4rem;       /* 64px */

  /* Jam's corners: a sheet, a field, a chip. Buttons are pills. */
  --mgr-radius: 12px;
  --mgr-radius-md: 10px;
  --mgr-radius-sm: 8px;
  --mgr-radius-pill: 999px;

  /* A sheet is the long lift under a 1px ring of the same ink. */
  --mgr-shadow-card: 0 0 0 1px hsl(240 5% 12% / 0.075),
    0 4px 8px -2px hsl(240 5% 12% / 0.075),
    0 8px 20px -4px hsl(240 5% 12% / 0.075),
    0 24px 64px -8px hsl(240 5% 12% / 0.075);

  --mgr-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Source Sans 3", sans-serif;
  --mgr-measure: 28rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --mgr-page: hsl(240 5% 6%);
    --mgr-sheet: hsl(240 5% 12%);
    --mgr-sheet-2: hsl(240 5% 10%);
    --mgr-line: hsl(240 5% 19%);
    --mgr-line-strong: hsl(240 5% 40%);
    --mgr-ink: hsl(240 5% 95%);
    --mgr-muted: hsl(240 5% 72%);
    --mgr-faint: hsl(240 5% 62%);

    --mgr-accent: hsl(342 80% 65%);
    --mgr-accent-strong: hsl(342 80% 72%);
    --mgr-accent-soft: hsl(342 88% 17%);
    --mgr-on-accent: #ffffff;

    --mgr-tone-positive-fg: hsl(135 80% 72%); --mgr-tone-positive-bg: hsl(135 88% 14%);
    --mgr-tone-warning-fg: hsl(45 80% 72%);   --mgr-tone-warning-bg: hsl(45 88% 14%);
    --mgr-tone-negative-fg: hsl(2 80% 72%);   --mgr-tone-negative-bg: hsl(2 88% 17%);
    --mgr-tone-positive-line: hsl(135 40% 30%);
    --mgr-tone-warning-line: hsl(38 45% 32%);
    --mgr-tone-negative-line: hsl(2 45% 34%);

    --mgr-shadow-card: 0 0 0 1px hsl(240 5% 90% / 0.12),
      0 4px 8px -2px rgba(0, 0, 0, 0.5),
      0 8px 20px -4px rgba(0, 0, 0, 0.5),
      0 24px 64px -8px rgba(0, 0, 0, 0.5);
  }
}

/* ── Browser surfaces: selection in the accent's wash, the caret and
      every focus ring in the accent, scrollbars thin. ─────────────── */
* { box-sizing: border-box; }
::selection { background: var(--mgr-accent-soft); color: var(--mgr-ink); }
* { scrollbar-width: thin; scrollbar-color: var(--mgr-line-strong) transparent; }
input, button { font-family: inherit; caret-color: var(--mgr-accent); }
:focus-visible { outline: 2px solid var(--mgr-accent); outline-offset: 2px; border-radius: var(--mgr-radius-sm); }

body {
  margin: 0;
  background: var(--mgr-page);
  color: var(--mgr-ink);
  font-family: var(--mgr-font);
  font-size: var(--mgr-fs-m);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ── The page: the brand, then one sheet. ──────────────────────────── */
.mgr-page {
  max-width: calc(var(--mgr-measure) + 2 * var(--mgr-sp-xl));
  margin: 0 auto;
  padding: var(--mgr-sp-3xl) var(--mgr-sp-m) var(--mgr-sp-4xl);
}

/* The brand, drawn the way the app's header draws it: the mascot keeps
   its own colours and is an <img>; the logotype is one colour, so it is
   a mask over currentColor and reads on either theme. Everything is a
   multiple of one unit taken from the mascot's height, so the two
   halves stay in proportion at any size. */
.mgr-brand {
  --mgr-brand-u: calc(2.25rem / 585);
  display: inline-flex;
  align-items: center;
  gap: calc(98 * var(--mgr-brand-u));
  margin: 0 0 var(--mgr-sp-l);
  color: var(--mgr-ink);
}
.mgr-brand__mascot { display: block; width: auto; height: calc(585 * var(--mgr-brand-u)); }
.mgr-brand__word {
  display: block;
  width: calc(1410 * var(--mgr-brand-u));
  height: calc(564 * var(--mgr-brand-u));
  transform: translateY(calc(78.5 * var(--mgr-brand-u)));
  background: currentColor;
  mask: url("brand/jelly-wordmark.svg") center / contain no-repeat;
}

.mgr-sheet {
  background: var(--mgr-sheet);
  border-radius: var(--mgr-radius);
  box-shadow: var(--mgr-shadow-card);
  padding: var(--mgr-sp-xl);
}

/* ── Type ──────────────────────────────────────────────────────────── */
h1 {
  font-weight: 600;
  font-size: var(--mgr-fs-2xl);
  line-height: 1.2;
  letter-spacing: var(--mgr-track-tight);
  text-wrap: balance;
  overflow-wrap: anywhere;
  margin: 0 0 var(--mgr-sp-s);
}
.mgr-lede { color: var(--mgr-muted); margin: 0 0 var(--mgr-sp-l); }
/* A paragraph of the page's own prose. The classed ones below carry
   their own air, and :not([class]) is what keeps this from reaching
   over them — the lede and the hints are not this. */
.mgr-sheet > p:not([class]) { margin: var(--mgr-sp-m) 0 0; }
.mgr-sheet > *:first-child { margin-top: 0; }
a { color: var(--mgr-accent); }

/* ── The form ──────────────────────────────────────────────────────── */
.mgr-form { display: grid; gap: var(--mgr-sp-l); }
.mgr-field { display: grid; gap: var(--mgr-sp-2xs); }
.mgr-field label { font-size: var(--mgr-fs-s); font-weight: 600; color: var(--mgr-muted); }
.mgr-field input {
  font: inherit;
  color: inherit;
  background: var(--mgr-sheet);
  border: 1px solid var(--mgr-line-strong);
  border-radius: var(--mgr-radius-md);
  padding: var(--mgr-sp-xs) var(--mgr-sp-s);
  min-height: 2.75rem;
  width: 100%;
  min-width: 0;
}
.mgr-field input::placeholder { color: var(--mgr-faint); }
.mgr-field input[aria-invalid="true"] { border-color: var(--mgr-tone-negative-fg); }

/* Where they heard of Jelly: the one question on the form about the
   person rather than the team, so it reads as an aside after the
   account's facts — a dashed rule, then a question at the reading size
   in ink, where the fields above have labels in the chrome's size.
   The answers are cards rather than a menu, so every one can be read
   without opening anything: two to a row where the sheet has room and
   one on a phone, the last ("Something else") across the whole row. A
   chosen card is strawberry, its edge doubled inward so nothing beside
   it shifts, and says so with its radio's dot as well as its colour.
   The detail under the cards is the question's follow-up, close to the
   answers it asks after. Colour changes ease; nothing moves. */
.mgr-choices {
  border: 0;
  border-top: 1px dashed var(--mgr-line-strong);
  margin: 0;
  padding: var(--mgr-sp-l) 0 0;
  min-width: 0;
}
/* Floated, a legend is an ordinary block under the rule instead of a
   gap cut into it. */
.mgr-choices legend {
  float: left;
  width: 100%;
  padding: 0;
  margin-bottom: var(--mgr-sp-s);
  font-size: var(--mgr-fs-m);
  font-weight: 600;
  color: var(--mgr-ink);
}
.mgr-choices legend + * { clear: both; }
.mgr-choices > .mgr-error { margin: 0 0 var(--mgr-sp-xs); }
.mgr-choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 12rem), 1fr));
  gap: var(--mgr-sp-xs);
}
.mgr-choice {
  display: flex;
  align-items: center;
  gap: var(--mgr-sp-xs);
  min-height: 2.75rem;
  padding: var(--mgr-sp-xs) var(--mgr-sp-s);
  border: 1px solid var(--mgr-line-strong);
  border-radius: var(--mgr-radius-md);
  background: var(--mgr-sheet);
  font-size: var(--mgr-fs-s);
  line-height: 1.3;
  cursor: pointer;
  transition: background-color 120ms ease-out, border-color 120ms ease-out, box-shadow 120ms ease-out;
}
.mgr-choice:last-child { grid-column: 1 / -1; }
.mgr-choice input { flex: none; margin: 0; accent-color: var(--mgr-accent); }
.mgr-choice:hover { background: var(--mgr-sheet-2); }
.mgr-choice:has(input:checked) {
  border-color: var(--mgr-accent);
  background: var(--mgr-accent-soft);
  box-shadow: inset 0 0 0 1px var(--mgr-accent);
}
.mgr-choice:has(input:focus-visible) { outline: 2px solid var(--mgr-accent); outline-offset: 2px; }
.mgr-choice:has(input[aria-invalid="true"]) { border-color: var(--mgr-tone-negative-fg); }
.mgr-choices > .mgr-field { margin-top: var(--mgr-sp-m); }
.mgr-optional { font-weight: 400; }
/* A box that is a choice of its own, not one of a set: the sign-up's
   "email me" (#973), ticked unless somebody unticks it. */
.mgr-consent { display: grid; gap: var(--mgr-sp-2xs); }
.mgr-consent .mgr-hint { margin: 0; padding-left: calc(1.25rem + var(--mgr-sp-xs)); }
.mgr-check { display: flex; align-items: center; gap: var(--mgr-sp-xs); min-height: 1.5rem; cursor: pointer; }
.mgr-check input { flex: none; width: 1.25rem; height: 1.25rem; margin: 0; accent-color: var(--mgr-accent); }
/* signup.js hides the detail until an answer is chosen; the field's
   own display would otherwise win over the attribute. */
.mgr-field[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .mgr-choice { transition: none; }
}

/* The subdomain and the domain it sits under read as one control: the
   suffix is the same height and the same edge, joined to the field. */
.mgr-host { display: flex; align-items: stretch; min-width: 0; }
.mgr-host input { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.mgr-host-suffix {
  display: flex;
  align-items: center;
  flex: none;
  padding: 0 var(--mgr-sp-s);
  border: 1px solid var(--mgr-line-strong);
  border-left: 0;
  border-radius: 0 var(--mgr-radius-md) var(--mgr-radius-md) 0;
  background: var(--mgr-sheet-2);
  color: var(--mgr-muted);
  white-space: nowrap;
}

.mgr-hint { color: var(--mgr-muted); font-size: var(--mgr-fs-xs); margin: var(--mgr-sp-m) 0 0; }
.mgr-error { color: var(--mgr-tone-negative-fg); font-size: var(--mgr-fs-xs); font-weight: 600; margin: var(--mgr-sp-m) 0 0; }
/* Inside a field a hint or an error belongs to the control above it,
   not to the next field: 4px of grid gap and 4px of its own sits it
   under the box and still inside that field's own air. */
.mgr-field > .mgr-hint, .mgr-field > .mgr-error { margin: var(--mgr-sp-2xs) 0 0; }

/* A button that sits in a hint's sentence (signup.js's "Use acme-2")
   reads as the link it acts like. */
.mgr-inline-button {
  font: inherit;
  color: var(--mgr-accent);
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  cursor: pointer;
}

/* Buttons are pills, as they are everywhere in the app. This is the
   one action on its page, so it fills the width it is given. */
.mgr-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  font: inherit;
  font-weight: 600;
  line-height: 1.4;
  color: var(--mgr-on-accent);
  background: var(--mgr-accent);
  border: 1px solid var(--mgr-accent);
  border-radius: var(--mgr-radius-pill);
  padding: var(--mgr-sp-s) var(--mgr-sp-m);
  min-height: 2.75rem;
  cursor: pointer;
  text-decoration: none;
}
.mgr-button:hover { background: var(--mgr-accent-strong); border-color: var(--mgr-accent-strong); color: var(--mgr-on-accent); }

/* ── The sign-in front door ────────────────────────────────────────── */
/* One page, one primary action (#939). .mgr-door stacks the page's
   groups with one gap between them, and owns every margin between
   groups so that no group has to: a group's own children keep the
   form's gap inside it. Nothing here touches the one it sits beside. */
.mgr-door > * { margin: 0; }
.mgr-door > * + * { margin-top: var(--mgr-sp-xl); }
/* A notice is as far below the title as it is above the forms. */
.mgr-door > .mgr-notice:first-child { margin-top: var(--mgr-sp-xl); }
/* The teams this browser remembers come first, one pill each: the
   returning visit is what the page is for. Forgetting them reads as a
   link under the pills. */
.mgr-continue__heading, .mgr-step__heading {
  font-size: var(--mgr-fs-s);
  font-weight: 600;
  color: var(--mgr-muted);
  margin: 0 0 var(--mgr-sp-xs);
}
.mgr-step__heading { font-size: var(--mgr-fs-xl); color: var(--mgr-ink); margin-bottom: var(--mgr-sp-s); }
.mgr-step .mgr-lede { margin-bottom: var(--mgr-sp-l); }
.mgr-continue__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--mgr-sp-xs); }
.mgr-continue .mgr-button, .mgr-door .mgr-button { overflow-wrap: anywhere; }
/* Forgetting is a link to its own confirm page, centred and held well
   off the buttons so a stray tap does not land on it. */
.mgr-forget { margin: var(--mgr-sp-xl) 0 0; font-size: var(--mgr-fs-xs); text-align: center; }
.mgr-forget__actions { display: grid; gap: var(--mgr-sp-m); }
/* On the chooser, a team that signs in without Google says so under
   its button, inside that button's own air; the button is a form, and
   a letter asked for takes the button's place as a notice. Each team
   is its own block, with air between. */
.mgr-door > .mgr-continue__list { gap: var(--mgr-sp-l); }
.mgr-continue__list .mgr-hint { margin: var(--mgr-sp-xs) 0 0; text-align: center; }
.mgr-choose-letter { margin: 0; }
.mgr-continue__list .mgr-notice { margin: 0; }
/* What just happened, over the forms: the app's callout shape with no
   tone, because the words say what it is and the ways on are below. */
.mgr-notice {
  border: 1px solid var(--mgr-line);
  border-radius: var(--mgr-radius);
  background: var(--mgr-sheet-2);
  padding: var(--mgr-sp-s) var(--mgr-sp-m);
  margin: 0 0 var(--mgr-sp-l);
  overflow-wrap: anywhere;
}
/* A button that is not the page's one action: the same pill, outlined
   and in ink. */
.mgr-button--quiet {
  color: var(--mgr-ink);
  background: var(--mgr-sheet);
  border-color: var(--mgr-line-strong);
}
.mgr-button--quiet:hover { color: var(--mgr-ink); background: var(--mgr-sheet-2); border-color: var(--mgr-line-strong); }
/* Continue with Google is Google's own button, as it is on an
   instance's sign-in page: white, with the mark, in both themes,
   because the mark's colours are Google's and not ours. */
.mgr-google { margin: 0; }
.mgr-button--google {
  gap: var(--mgr-sp-s);
  color: #1f1f1f;
  background: #fff;
  border-color: #dadce0;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.mgr-button--google:hover { color: #1f1f1f; background: #f8f9fa; border-color: #dadce0; }
.mgr-button--google > svg { flex: none; width: 18px; height: 18px; }
/* "or", between the page's one action and the doors beside it: a rule
   with the word on it. The rule is decoration; the order says the rest. */
.mgr-or {
  display: flex;
  align-items: center;
  gap: var(--mgr-sp-s);
  color: var(--mgr-muted);
  font-size: var(--mgr-fs-s);
}
.mgr-or::before, .mgr-or::after { content: ""; flex: 1; border-top: 1px solid var(--mgr-line); }
/* A fold: the doors a visitor rarely needs, closed until asked for
   (and open whenever something inside has to be read). A <details>,
   so it needs no script. The summary is the link-coloured line. */
.mgr-more { border-block: 1px solid var(--mgr-line); padding-block: var(--mgr-sp-m); }
/* A fold sits above the footer's rule, so the footer lends it its own:
   the summary has the same air above and below. */
.mgr-door:has(.mgr-more) > .mgr-foot { margin-top: 0; border-top: 0; }
.mgr-more > summary {
  cursor: pointer;
  color: var(--mgr-accent);
  font-weight: 600;
  min-height: 1.5rem;
}
.mgr-more > summary:hover { color: var(--mgr-accent-strong); }
.mgr-more[open] > summary { margin-bottom: var(--mgr-sp-l); }
.mgr-more__body, .mgr-ways { display: grid; gap: var(--mgr-sp-l); }
.mgr-more__body > *, .mgr-ways > * { margin: 0; }
/* The way back, on the page that is only a confirmation. */
.mgr-back { color: var(--mgr-muted); font-size: var(--mgr-fs-s); }
/* The ways out and the small print, the same on every state, under a
   rule: Rails' door at the reading size, the rest as fine print. */
.mgr-foot {
  border-top: 1px solid var(--mgr-line);
  padding-top: var(--mgr-sp-l);
  display: grid;
  gap: var(--mgr-sp-s);
}
.mgr-foot > p { margin: 0; }
.mgr-foot__small { color: var(--mgr-muted); font-size: var(--mgr-fs-xs); }

/* Ways out beside a form, at the reading size, and the fine print
   (the error page's, errorpage.go). */
.mgr-aside { margin: var(--mgr-sp-l) 0 0; }
.mgr-aside--small { color: var(--mgr-muted); font-size: var(--mgr-fs-xs); margin-top: var(--mgr-sp-m); }

/* ── The team page ─────────────────────────────────────────────────── */
/* A state is the app's callout: a label on its own line over the
   sentence that explains it, in the tone's own wash. The label is
   what says which state this is; the colour only agrees with it. */
.mgr-state {
  border: 1px solid var(--mgr-line);
  border-radius: var(--mgr-radius);
  background: var(--mgr-sheet-2);
  padding: var(--mgr-sp-s) var(--mgr-sp-m);
  margin: var(--mgr-sp-m) 0;
  overflow-wrap: anywhere;
}
/* The label is the state's own child; a <strong> inside the sentence
   is a host or an address, and stays in the line it is part of. */
.mgr-state > strong { display: block; font-weight: 600; }
.mgr-state p { margin: var(--mgr-sp-3xs) 0 0; color: var(--mgr-muted); }
.mgr-state p strong { color: var(--mgr-ink); }
.mgr-state[data-state="live"] { background: var(--mgr-tone-positive-bg); border-color: var(--mgr-tone-positive-line); }
.mgr-state[data-state="live"] > strong { color: var(--mgr-tone-positive-fg); }
.mgr-state[data-state="failed"] { background: var(--mgr-tone-negative-bg); border-color: var(--mgr-tone-negative-line); }
.mgr-state[data-state="failed"] > strong { color: var(--mgr-tone-negative-fg); }

/* The steps: what is done is in ink, what is not is quiet. The marker
   carries no meaning of its own — the words do. */
.mgr-steps { margin: var(--mgr-sp-m) 0 0; padding-left: var(--mgr-sp-l); color: var(--mgr-faint); }
.mgr-steps li { margin: 0 0 var(--mgr-sp-xs); }
.mgr-steps li[data-done="true"] { color: var(--mgr-ink); }
.mgr-steps li[data-done="true"]::marker { color: var(--mgr-accent); }

/* Waiting has a spinner, because the page's own words say it is still
   going and nothing else on a still page agrees with them. It turns
   on the step that is happening — the first not done, which has no
   unfinished step before it — rather than on the heading, so that as
   the page refreshes the motion walks down the list and the wait reads
   as progress rather than as one stuck line. The steps after it have
   not begun, and stay quiet. The step is in ink, as a done one is,
   because it is the line being read; its words already say it is not
   finished ("Setting up…"), and a reader who sees no motion has lost
   nothing. Under reduced motion it stops and goes dotted — the ring is
   still the mark of something unfinished, it simply does not turn. */
.mgr-steps li[data-done="false"]:not(li[data-done="false"] ~ li) { color: var(--mgr-ink); }
.mgr-steps li[data-done="false"]:not(li[data-done="false"] ~ li)::after {
  content: "";
  display: inline-block;
  vertical-align: -0.1em;
  box-sizing: border-box;
  width: 0.85em;
  height: 0.85em;
  margin-left: var(--mgr-sp-2xs);
  border: 2px solid var(--mgr-line);
  border-top-color: var(--mgr-accent);
  border-radius: 50%;
  animation: mgr-spin 0.7s linear infinite;
}
@keyframes mgr-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .mgr-steps li[data-done="false"]:not(li[data-done="false"] ~ li)::after { animation: none; border-style: dotted; border-top-color: var(--mgr-accent); }
}

/* ── The demo banner ───────────────────────────────────────────────── */
.mgr-demo {
  margin: 0;
  padding: var(--mgr-sp-xs) var(--mgr-sp-m);
  background: var(--mgr-tone-warning-bg);
  color: var(--mgr-tone-warning-fg);
  border-bottom: 1px solid var(--mgr-tone-warning-line);
  text-align: center;
  font-size: var(--mgr-fs-s);
  text-wrap: balance;
}

/* ── The phone. The sheet keeps its corners but loses the air it has
      no room for; below that it is the same page. ─────────────────── */
@media (max-width: 30rem) {
  .mgr-page { padding: var(--mgr-sp-l) var(--mgr-sp-s) var(--mgr-sp-2xl); }
  .mgr-sheet { padding: var(--mgr-sp-l) var(--mgr-sp-m); }
}

/* ── Error pages ───────────────────────────────────────────────────── */
.mgr-error__code { margin: 0 0 var(--mgr-sp-xs); color: var(--mgr-faint); font-size: var(--mgr-fs-s); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.mgr-error__detail { color: var(--mgr-ink); }
