/* 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); }

/* 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; }

/* 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 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); }

/* 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 sits
   beside the label, not in place of it: the label is what says which
   state this is, 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-state[data-state="pending"] > strong { display: flex; align-items: center; gap: var(--mgr-sp-2xs); }
.mgr-state[data-state="pending"] > strong::after {
  content: "";
  box-sizing: border-box;
  width: 0.85em;
  height: 0.85em;
  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-state[data-state="pending"] > strong::after { animation: none; border-style: dotted; border-top-color: var(--mgr-accent); }
}

/* 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); }

/* ── 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); }
}
