/* The admin layer.
 *
 * Every colour is a token from tokens.css (guardrail 10) — there is not a raw
 * value in this file and `scripts/check.js` fails the build if one appears.
 *
 * Two things drive the layout: the design's slim `--ink` band at the top, and
 * the fact that an organiser reads this on a phone in a dust storm as often as
 * on a laptop. Every control clears the `--tap-min` floor, the two-column split
 * collapses to one below the phone breakpoint, and nothing scrolls sideways.
 */

/* --- the band ------------------------------------------------------------- */

.aband {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-4);
  margin-bottom: var(--space-4);
}

.aband-who {
  font-size: var(--size-small);
  font-weight: var(--weight-semibold);
  min-width: 0;
}

.aband-out {
  min-height: var(--tap-min);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-slot);
  background: none;
  color: var(--bg);
  font: inherit;
  font-size: var(--size-small);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}
.aband-out:hover { background: var(--soft); }

/* --- tabs ----------------------------------------------------------------- */

.atabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--space-5);
}

.atab {
  min-height: var(--tap-min);
  padding: var(--space-2) var(--space-4);
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--soft);
  font: inherit;
  font-size: var(--size-small);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}
.atab.is-on { color: var(--ink); border-bottom-color: var(--ink); }

/* Five tabs on a 390px phone.
 *
 * At the desktop padding they wrap, and the second row is one tab wide — a
 * whole 44px band of nothing above the fold, on the screen with the least of it
 * to spare. Narrowing the horizontal padding brings all five back onto one line
 * (measured at 390px: 330 of 360 available). The vertical padding and the
 * `min-height` are untouched, so the tap target keeps its full height. */
@media (max-width: 480px) {
  /* `gap: 0` here, once. Five 48px targets touching edge to edge is the thing
   * the owner reported as "buttons too close together on mobile", and it is
   * worse than the band of whitespace the comment above was avoiding: at zero
   * separation the boundary between two tabs is invisible and a mis-tap costs a
   * screen change.
   *
   * 4px keeps all five on one line — measured at 390px they occupied 330 of 360
   * available, so four gaps of 4px lands at 346 — while restoring a visible
   * edge. It is still below the 8px used everywhere else, which is a deliberate
   * trade on the one bar that must not wrap, and it is recorded as such. */
  .atabs { gap: var(--space-1); }
  .atab { padding: var(--space-2); }
}

/* --- signing in ----------------------------------------------------------- */

.asignin { max-width: 460px; }
.asignin .display { margin: 0 0 var(--space-2); }
.asignin-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--space-4);
  margin: var(--space-4) 0;
}

.aerror {
  margin: 0;
  padding: var(--space-3);
  border-radius: var(--radius-slot);
  background: var(--gap-bg);
  color: var(--gap);
  font-size: var(--size-small);
  font-weight: var(--weight-semibold);
}

/* --- the shared vocabulary ------------------------------------------------- */

/* `.akicker` used to live here as admin's own copy of a kicker — the very
 * duplication that once made this file and `live.css` both define a global
 * `.kicker`, with admin linked last and every one of Live's eight section
 * headings silently gaining a border and margins `live.css` had explicitly
 * zeroed. That bug is what `scripts/check-ui.js`'s "one selector, one home"
 * rule exists to catch.
 *
 * `components/ui.js#sectionHead` now draws the identical hairline-kicker —
 * `rule: true` is that exact option — so `admin-ui.js#kicker` delegates to it
 * and every place in this app that drew the raw class has moved onto the
 * function instead. The one thing left here is spacing: a kicker straight
 * inside a panel loses its top margin, because `.apanel` already supplies the
 * air above it. */
.apanel > .ui-head:first-child { margin-top: 0; }

.apanel { margin-bottom: var(--space-6); }
.ahead { margin-bottom: var(--space-4); }
.ahead .display { margin: 0 0 var(--space-2); }

/* --- the key metrics band --------------------------------------------------
 *
 * The six numbers an admin opens the Dashboard for, directly under the heading.
 * The tiles are the shared `statTile()` (`components/ui.js`), which owns the
 * padding, the type and the tone stripe; the only thing that belongs to this
 * screen is how they are arranged, which is this rule and nothing else.
 *
 * The same auto-fit grid as the Tally's `.ty-stats`, at a narrower minimum
 * because there are six tiles here rather than five and they carry shorter
 * numbers: two columns at 390px, six across a 1280px laptop, and no width in
 * between where a tile drops off the side. Nothing here is tappable, so there
 * is no tap floor to clear — a stat tile is something you read.
 *
 * `.ahead` gives up a little of its margin above, because a heading with a
 * bar under it and tiles under that is one block, not three.
 */
.astats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

.anote { color: var(--soft); font-size: var(--size-micro); margin: 0; }
/* A note that explains the buttons above it has to be clear of them, or it
 * reads as part of the last button's box. */
.sheet-actions + .anote { margin-top: var(--space-2); }

/* Scoped, not global — `me.css` states the rule this used to break: this file
 * is linked last, so a bare `.is-live` wins the cascade wherever the class
 * name turns up, and it turns up on `me.js`, `pick.js`, `train.js`, `live.js`
 * and two screens in this very directory. `.atab-body` is what every admin
 * tab is mounted into (`admin.js#render`), so this still reaches everywhere
 * admin actually uses the class and nowhere else does. */
.atab-body .is-gap { color: var(--gap); font-weight: var(--weight-semibold); }
.atab-body .is-live { color: var(--live); font-weight: var(--weight-semibold); }
.atab-body .is-soon { color: var(--soon); font-weight: var(--weight-semibold); }

.ameter {
  height: 11px;
  border-radius: var(--radius-pill);
  background: var(--card);
  overflow: hidden;
}
.ameter-fill { height: 100%; border-radius: var(--radius-pill); }

.afield { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.afield-label { font-size: var(--size-micro); color: var(--soft); }

.ainput {
  min-height: var(--tap-min);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  /* 16px so iOS does not zoom the page when a field takes focus. */
  font-size: var(--size-body);
}

/* A control that sits inside a row rather than owning a line of its own — the
 * pod picker beside each person who has not got one. Still a full tap target
 * top to bottom; it just stops being 100% wide next to the name it belongs to. */
.ainput--slim { width: auto; max-width: 100%; flex: 0 1 200px; }

.aform {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: flex-end;
  margin-top: var(--space-3);
}
.aform .afield { flex: 1 1 170px; }
.aform-row { align-items: center; }

.achips { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }

/* Rows of chips that stand on their own — the territory and day pickers — need
 * air under them, which chips inside a person row do not. */
.astack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.aspaced { margin-bottom: var(--space-5); }

.asetting {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) minmax(120px, 1fr) auto;
  gap: var(--space-2) var(--space-3);
  align-items: center;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--size-small);
}
.asetting-name { display: flex; flex-direction: column; min-width: 0; }

@media (max-width: 560px) {
  .asetting { grid-template-columns: 1fr auto; }
  .asetting-name { grid-column: 1 / -1; }
}

.achip {
  min-height: var(--tap-min);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--panel);
  color: var(--soft);
  font: inherit;
  font-size: var(--size-small);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  white-space: nowrap;
}
.achip.is-on { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.achip.is-premium { background: var(--t-prem-t); color: var(--t-prem-deep); border-color: var(--t-prem); }
.achip.is-off { opacity: 0.5; text-decoration: line-through; }

/* The chip that opens a sheet rather than toggling something itself — "seats…"
 * beside each shift. Quieter and narrower than the chip it follows, because it
 * is the same block's second gesture and not a second block. It was used with
 * no rule to its name at all, so it drew as a full-weight chip that looked
 * exactly as loud as the 2× toggle next to it. */
/* Quieter, not smaller. It kept its dashed border, its micro type and its
 * narrow padding — but `min-height` is a tap target, not a visual weight, and
 * at 34px this was the smallest thing an organiser had to hit on a phone. The
 * two are independent: the padding still makes it read as a secondary gesture. */
.achip--slim {
  min-height: var(--tap-min);
  padding: var(--space-1) var(--space-2);
  border-style: dashed;
  font-size: var(--size-micro);
  font-weight: var(--weight-medium);
}

.askeleton {
  padding: var(--space-5);
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--soft);
  animation: breathe 1.6s ease-in-out infinite;
}

/* --- lists ---------------------------------------------------------------- */

.alist { display: flex; flex-direction: column; gap: var(--space-1); }

.arow {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  align-items: center;
  min-height: var(--tap-min);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-size: var(--size-small);
  text-decoration: none;
}
.arow-main { display: flex; flex-direction: column; flex: 1 1 200px; min-width: 0; }
.arow-right { font-variant-numeric: tabular-nums; font-weight: var(--weight-semibold); }

/* A row whose name is a link to that person's page. Every admin list that names
 * somebody is one of these now, so a dues chase can go from "who is short" to
 * the person in one tap. It has to look like the text it replaced until it is
 * hovered, or twelve blue underlines in a column read as an error state. */
a.arow-main { color: inherit; text-decoration: none; }
a.arow-main:hover, a.arow-main:focus-visible { text-decoration: underline; }

.agap {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  align-items: center;
  min-height: var(--tap-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-slot);
  background: var(--gap-bg);
  color: var(--ink);
  font-size: var(--size-small);
  text-decoration: none;
  line-height: 1.35;
}
.agap-label { flex: 1 1 60%; min-width: 0; }
.agap-flag { font-size: var(--size-micro); font-weight: var(--weight-semibold); color: var(--gap); }

.abadge {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--t-prem-t);
  color: var(--t-prem-deep);
  font-size: var(--size-micro);
  font-weight: var(--weight-bold);
}

/* --- territory boxes ------------------------------------------------------- */

.aterr-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
  gap: var(--space-3);
}

.aterr {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 112px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--panel);
  color: var(--ink);
  text-decoration: none;
}
.aterr-head { display: flex; align-items: center; gap: var(--space-2); }
.aterr-emoji { font-size: 18px; }
.aterr-name { font-family: var(--font-display); font-size: var(--size-h2); }
.aterr-times { flex: 1; font-size: var(--size-micro); color: var(--soft); line-height: 1.35; }
.aterr-foot {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--size-micro);
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
}

/* --- people --------------------------------------------------------------- */

.acols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-6);
}

.aperson { border-bottom: 1px solid var(--line); }

.aperson-head {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  width: 100%;
  min-height: var(--tap-min);
  padding: var(--space-2) 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--size-small);
  text-align: left;
  cursor: pointer;
}
.aperson-caret { color: var(--soft); width: 12px; flex: none; }
.aperson-body { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.aperson-name { font-weight: var(--weight-medium); }
.aperson-right { display: flex; flex-direction: column; align-items: flex-end; flex: none; }
.aperson-weight { font-variant-numeric: tabular-nums; font-weight: var(--weight-semibold); }
.aperson-dues { font-size: var(--size-micro); font-weight: var(--weight-semibold); }

.aperson-more {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  margin: 0 0 var(--space-3);
  border-radius: var(--radius-slot);
  background: var(--card);
}

/* --- the two passwords ------------------------------------------------------
 *
 * Two forms in one panel, and they must not read as one form with four fields.
 * The rule under each is what separates them; the space is what stops somebody
 * typing the admin password into the pod-lead form's second box. */
.apassword + .apassword {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.afilters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--space-3);
  max-width: 560px;
  margin-bottom: var(--space-5);
}

/* --- the week of shifts, on the Shifts tab ---------------------------------
 *
 * What used to be here was the Sign-ups tab's own seat grid — `.ashift`,
 * `.ashift-head`, `.aseats`, `.aseat` and `.ashift-more`, a bespoke seat layout
 * used on exactly one screen, which was a worse copy of the Schedule next to it.
 * The tab is gone (screens/admin-signups.js says why) and so are its rules.
 * `.ashift-more` had already outlived its markup and was styling nothing at all. */

.ashift-days { display: flex; flex-direction: column; gap: var(--space-3); }
.ashift-day { display: flex; flex-direction: column; gap: var(--space-1); }

/* 767, not 768. Every other stylesheet and `app.js`'s own matchMedia use 767,
 * so at exactly 768px admin switched to its phone layout while the shell was
 * still in desktop mode — no tab bar, no bottom padding. One pixel wide, and
 * the kind of thing nobody reproduces on purpose. */
@media (max-width: 767px) {
  .acols { grid-template-columns: 1fr; gap: var(--space-5); }
  .aterr-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
