/* The Hub's OWN pages: sign-in, home, admin, error. Everything else on a Hub
   page — the type, the palette, the topbar menus, the Appearance control, the
   six themes and light/dark — comes from the shared chrome package
   (packages/hub-chrome: pico.min.css, chrome.css, themes/*.css), loaded by
   views/partials/header.ejs BEFORE this file, with the theme files AFTER it.

   Rules this file lives by (2026-09-02, when the Hub was re-based onto the
   Asset Manager's Pico tokens so the themes mean something here):

   - NO colour literals. Every colour is a --pico-* token (or one of the SCP
     tokens chrome.css defines), so a theme that re-pitches the palette
     re-pitches the Hub with it. The one exception is the Google sign-in
     button, whose colours are Google's brand rules, not ours.
   - No component rules that belong to every app — those are chrome.css's.
   - The Hub is chrome, not content, so it stays quiet. The one place it has a
     face is the app tiles on Home (and the wordmark on sign-in): Outfit at
     display size, the SCP teal on hover, nothing else competing. */

/* Layout ------------------------------------------------------------------ */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 1.25rem;
  background: var(--pico-card-background-color);
  border-bottom: 1px solid var(--pico-muted-border-color);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar-brand {
  font-family: var(--heading-font-family);
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--pico-color);
  text-decoration: none;
  letter-spacing: 0.01em;
}
.topbar-brand:hover { color: var(--pico-primary); text-decoration: none; }

/* The Appearance control was designed for the foot of the Asset Manager's
   sidebar (default variant) and for a pre-auth strip (page variant). In the
   Hub's topbar it sits in the flex row with the menus, so it must not float
   out of flow, and its panel opens under the topbar at the right. */
.topbar .appearance-page { position: static; }
.topbar .appearance-panel { position: fixed; top: 3.75rem; right: 1rem; left: auto; bottom: auto; }

.main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
}

/* Flash ------------------------------------------------------------------- */

.flash {
  padding: 0.7rem 1rem;
  border-radius: var(--pico-border-radius);
  margin-bottom: 1rem;
  font-weight: 500;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-left-width: 4px;
}
.flash-ok { border-left-color: var(--pico-ins-color); }
.flash-error { border-left-color: var(--pico-del-color); }

/* Sign-in ------------------------------------------------------------------ */

.login {
  display: flex;
  justify-content: center;
  padding: clamp(2rem, 9vh, 5rem) 1rem;
}
.login-card { width: 100%; max-width: 26rem; text-align: center; }
.login-wordmark {
  font-family: var(--heading-font-family);
  font-size: 2.6rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.1;
  color: var(--pico-color);
}
.login-tagline { margin: 0.35rem 0 0; color: var(--pico-muted-color); }
.login-signed-out {
  margin: 1.5rem 0 0;
  padding: 0.6rem 0.9rem;
  border-radius: var(--pico-border-radius);
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-left: 4px solid var(--pico-ins-color);
  font-weight: 600;
}
.login-hint { margin-top: 1.25rem; color: var(--pico-muted-color); font-size: 0.9rem; }

/* Google's sign-in button follows Google's brand guidance, not the theme:
   white face, its own grey ink and hairline, the four-colour G. Pico styles
   [role=button] as a primary button through per-element custom properties, so
   those are what get overridden here. */
.google-button {
  --pico-background-color: #fff;
  --pico-border-color: #dadce0;
  --pico-color: #3c4043;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  margin-top: 2rem;
  font-weight: 600;
}
.google-button:hover,
.google-button:focus-visible {
  --pico-background-color: #f7f8f8;
  --pico-border-color: #c6c9cc;
  --pico-color: #3c4043;
}

.dev-users { list-style: none; padding: 0; margin: 1.5rem 0 0; display: grid; gap: 0.5rem; }
.dev-users li { list-style: none; margin: 0; padding: 0; }
.dev-user-button {
  --pico-background-color: var(--pico-card-background-color);
  --pico-border-color: var(--pico-muted-border-color);
  --pico-color: var(--pico-color);
  width: 100%;
  margin: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 500;
}
.dev-user-button:hover,
.dev-user-button:focus-visible { --pico-border-color: var(--pico-primary); --pico-background-color: var(--pico-card-background-color); }
.dev-role { font-size: 0.8rem; color: var(--pico-muted-color); }

/* Home -------------------------------------------------------------------- */

.home-title { margin: 0.5rem 0 0.25rem; }
.home-sub { color: var(--pico-muted-color); margin-top: 0; }
.home-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}
.home-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  padding: 1.75rem 1rem 1.5rem;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  text-decoration: none;
  color: var(--pico-color);
  text-align: center;
  transition: border-color 0.15s, transform 0.15s;
}
.home-card:hover,
.home-card:focus-visible {
  border-color: var(--pico-primary);
  color: var(--pico-color);
  text-decoration: none;
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  .home-card { transition: none; }
  .home-card:hover, .home-card:focus-visible { transform: none; }
}
.home-card-icon { font-size: 2.6rem; line-height: 1; }
.home-card-name { font-family: var(--heading-font-family); font-weight: 600; font-size: 1.05rem; }
.home-empty {
  background: var(--pico-card-background-color);
  border: 1px dashed var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  padding: 2rem;
  text-align: center;
  color: var(--pico-muted-color);
}

/* Admin ------------------------------------------------------------------- */

.admin-sub { color: var(--pico-muted-color); max-width: 60ch; }
.admin h2 { margin-top: 2rem; }
.admin-table td, .admin-table th { vertical-align: top; }
.admin-table tr.is-inactive { opacity: 0.55; }
.tag {
  display: inline-block;
  background: var(--pico-primary-background);
  color: var(--pico-primary-inverse);
  font-size: 0.7rem;
  padding: 0.05rem 0.45rem;
  border-radius: 6px;
  margin-left: 0.35rem;
  vertical-align: middle;
}
.muted { color: var(--pico-muted-color); }
.grant-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
  font-size: 0.8rem;
  margin: 0 0.25rem 0.25rem 0;
}
/* Buttons that are not buttons: Pico paints every <button> as a primary
   button, so the two "quiet" kinds on this page reset its per-element tokens
   and box. */
.chip-x,
.linklike {
  --pico-background-color: transparent;
  --pico-border-color: transparent;
  --pico-color: var(--pico-muted-color);
  width: auto;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  font: inherit;
  line-height: 1;
  cursor: pointer;
}
.chip-x { font-size: 1rem; }
.chip-x:hover, .chip-x:focus-visible { --pico-color: var(--pico-del-color); }
.linklike { --pico-color: var(--pico-primary); text-decoration: underline; }
.linklike:hover, .linklike:focus-visible { --pico-color: var(--pico-primary-hover); }
.grant-form { display: flex; gap: 0.35rem; margin-top: 0.4rem; flex-wrap: wrap; align-items: center; }
.grant-form select, .grant-form button { width: auto; margin: 0; padding: 0.3rem 0.6rem; font-size: 0.85rem; }
.inline { display: inline; margin: 0; }
.admin-add {
  margin-top: 1rem;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  padding: 0.75rem 1rem;
}
.admin-add summary { cursor: pointer; font-weight: 600; }
.stack { display: grid; gap: 0.6rem; margin-top: 0.75rem; max-width: 30rem; }
.stack label { display: grid; gap: 0.25rem; font-size: 0.9rem; color: var(--pico-muted-color); }
.stack button { width: auto; justify-self: start; }

/* The admin REPORTS (N1: /admin/preferences; N2: /admin/feedback). One line of
   links under the admin heading, a crumb back from each report, and a compact
   two-column count table whose figures right-align so the column reads as
   numbers rather than as text that happens to be digits. */
.admin-reports { margin: -0.25rem 0 0.75rem; color: var(--pico-muted-color); }
.admin-crumb { margin: 0 0 0.25rem; font-size: 0.9rem; }
.prefs-table { max-width: 28rem; }
.prefs-table th[scope="row"] { font-weight: 500; }
.admin-table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* N2: the no-JS feedback page and the admin list. The form's own shape
   (.feedback-form and friends) is chrome.css's, shared with the dialog; this
   is only where the Hub PUTS it and how the list reads. The message cell keeps
   the person's line breaks through pre-wrap — never by injecting markup — and
   wraps a pasted URL or stack line rather than widening the table. */
.feedback-page { max-width: 40rem; }
.feedback-page .feedback-form { padding: 0; }
/* The WRAPPER scrolls, never the page (the Asset Manager's rule for every wide
   table): seven columns carrying a message and a URL outgrew the 1100px main
   column on the first screenshot and gave the page a horizontal scrollbar. */
.table-wrap { overflow-x: auto; }
.feedback-table { font-size: 0.92rem; }
.feedback-table .nowrap { white-space: nowrap; }
.feedback-when { min-width: 7rem; }
.feedback-body { white-space: pre-wrap; overflow-wrap: anywhere; min-width: 14rem; }
/* min-width, not max-width: with overflow-wrap:anywhere a cell's min-content
   width is one character, and the auto table layout gave the column exactly
   that — "/assets/checkouts?sort=due" rendered as seven lines of four letters
   on the first screenshot. A floor keeps a typical page on one or two lines;
   a 2,000-character path still wraps instead of widening the table. */
.feedback-page-cell { overflow-wrap: anywhere; min-width: 11rem; }
.feedback-table tr.is-done { opacity: 0.55; }
.feedback-table .inline { display: block; margin-top: 0.2rem; }

.error-page { text-align: center; padding: 4rem 1rem; }

[hidden] { display: none !important; }
