html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

a, .btn-link {
    color: #006bb7;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}
/* The build badge at the foot of the nav (R-48). Quiet by default — it is reference
   information, not something to read on every page — but always present, so "which
   version are you on?" never needs a server login to answer. */
.pgm-nav-build {
    padding: 0.75rem 1.5rem 1.25rem;
    opacity: 0.55;
    transition: opacity 0.15s ease-in-out;
}
.pgm-nav-build:hover { opacity: 1; }

/* "You're in a game" banner (R-52). Quiet but unmissable: a thin strip rather than an alert,
   because it is present for the whole length of a campaign and must not read as a warning. */
.pgm-rejoin {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.4rem 1rem;
    background: rgba(25, 135, 84, 0.14);
    border-bottom: 1px solid rgba(25, 135, 84, 0.35);
    font-size: 0.9rem;
}

/* The per-listener mixer in the play header (R-54). Three layers, three sliders: the table,
   the narrator and the music compete for the same ears and people want different things from
   each — a single master volume turns the voices down along with the score. */
.pgm-mixer {
    display: flex;
    gap: 1.25rem;
    flex-wrap: wrap;
    align-items: center;
    padding: 0.5rem 0.75rem;
    margin-top: 0.5rem;
    background: rgba(0, 0, 0, 0.18);
    border-radius: 6px;
    font-size: 0.85rem;
}
.pgm-mixer label { display: flex; align-items: center; gap: 0.5rem; margin: 0; white-space: nowrap; }
.pgm-mixer input[type="range"] { width: 7rem; }
.pgm-mixer span { min-width: 2.2rem; text-align: right; opacity: 0.7; font-variant-numeric: tabular-nums; }

/* ── Phone layout for the play view ──────────────────────────────────────────
   Below Bootstrap's lg breakpoint the two play columns become tabs rather than one
   long scroll. Purely structural — which pane is showing is a layout fact, and the
   visual pass that replaces these placeholder styles can leave it alone. */
@media (max-width: 991.98px) {
    .pgm-pane-hidden { display: none !important; }

    .pgm-pane-tabs {
        display: flex;
        gap: .5rem;
        margin: .25rem 0 .75rem;
    }
    .pgm-pane-tabs .btn { flex: 1 1 0; }

    /* Camera tiles get shorter: on a phone the transcript and the action bar matter more than
       seeing faces large, and every pixel the strip takes is a line of the story you cannot read. */
    .pgm-cam-slot { height: clamp(64px, 9vh, 88px); }
    .pgm-gm-slot  { height: clamp(80px, 12vh, 120px); }

    /* The mixer wraps rather than overflowing its row. */
    .pgm-mixer label { flex: 1 1 100%; }
    .pgm-mixer input[type="range"] { flex: 1 1 auto; width: auto; }
}

/* Touch: the on-screen push-to-talk button is the PRIMARY control on a phone, not a fallback for
   the Ctrl key — there is no Ctrl key. It gets a target you can hit without looking, because you
   are holding it while talking and watching the table rather than the screen. */
@media (pointer: coarse) {
    .pgm-ptt-button, .btn.pgm-ptt-button { min-height: 3rem; font-size: 1.05rem; }
}

/* ── Notifications: the bell and the fading overlay (ADR-115) ─────────────────────────────────
   Both themes are first-class per docs/DESIGN-BRIEF.md, so every colour here comes from an
   existing custom property rather than a literal. A hard-coded #fff in the top bar is invisible
   in light mode and nobody notices until a screenshot arrives. */

.pgm-bell-wrap { position: relative; display: inline-flex; }

.pgm-bell {
  position: relative;
  background: none;
  border: 0;
  padding: .25rem .5rem;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  opacity: .85;
}
.pgm-bell:hover { opacity: 1; }

/* Nothing waiting: the same bell, dimmed and desaturated. NOT a struck-through bell, which every
   other product uses to mean "notifications are switched off" — a person seeing that concludes
   theirs are broken and goes looking for the setting. */
.pgm-bell-quiet .pgm-bell-icon {
  opacity: .45;
  filter: grayscale(100%);
}
.pgm-bell-quiet:hover .pgm-bell-icon { opacity: .75; }

/* The dot, not a number. The top bar can only usefully answer "is there anything new?" */
.pgm-bell-dot {
  position: absolute;
  top: .15rem;
  right: .3rem;
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--bs-danger, #dc3545);
  /* A ring in the bar's own colour so the dot reads as separate from the glyph behind it. */
  box-shadow: 0 0 0 2px var(--pgm-topbar-bg, var(--bs-body-bg, #fff));
}

/* Covers the viewport under the panel so any click closes it — cheaper and more reliable than a
   document listener that has to be removed on dispose, navigation and circuit loss. */
.pgm-bell-scrim { position: fixed; inset: 0; z-index: 1040; }

.pgm-bell-panel {
  position: absolute;
  top: calc(100% + .4rem);
  right: 0;
  z-index: 1050;
  width: min(24rem, calc(100vw - 2rem));   /* never wider than a phone */
  max-height: min(28rem, 70vh);
  overflow-y: auto;
  background: var(--bs-body-bg, #fff);
  color: var(--bs-body-color, #212529);
  border: 1px solid var(--bs-border-color, rgba(0,0,0,.15));
  border-radius: .5rem;
  box-shadow: 0 .5rem 1.5rem rgba(0,0,0,.25);
}

.pgm-bell-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: .6rem .8rem;
  border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,.15));
}

.pgm-bell-empty { padding: 1.2rem .8rem; opacity: .7; font-size: .9rem; }

.pgm-bell-list { list-style: none; margin: 0; padding: 0; }

.pgm-bell-item {
  display: flex; gap: .6rem; align-items: flex-start;
  padding: .6rem .8rem;
  border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,.08));
  font-size: .9rem;
}
.pgm-bell-item:last-child { border-bottom: 0; }

/* Unread is a left bar and weight, not a background wash: a tinted row is hard to keep legible in
   both themes, and the bar survives any background. */
.pgm-bell-unread {
  border-left: 3px solid var(--bs-primary, #0d6efd);
  font-weight: 500;
}

.pgm-bell-item-icon { font-size: 1.1rem; line-height: 1.2; }
.pgm-bell-item-text { flex: 1; min-width: 0; }   /* min-width:0 so long words wrap instead of overflowing */
.pgm-bell-item-body { opacity: .8; font-weight: 400; }
.pgm-bell-item-when { opacity: .55; font-size: .78rem; margin-top: .15rem; }

/* ── The overlay ──────────────────────────────────────────────────────────────────────────── */

.pgm-toasts {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1080;              /* above the play page's panels */
  display: flex;
  flex-direction: column;
  gap: .5rem;
  max-width: min(26rem, calc(100vw - 2rem));
  pointer-events: none;       /* the container never eats clicks meant for the page */
}

.pgm-toast {
  pointer-events: auto;       /* ...but the toasts themselves are clickable */
  display: flex; gap: .6rem; align-items: center;
  padding: .7rem .8rem;
  background: var(--bs-body-bg, #fff);
  color: var(--bs-body-color, #212529);
  border: 1px solid var(--bs-border-color, rgba(0,0,0,.15));
  border-left: 3px solid var(--bs-primary, #0d6efd);
  border-radius: .5rem;
  box-shadow: 0 .5rem 1.5rem rgba(0,0,0,.3);
  transition: opacity .4s ease, transform .4s ease;
}

.pgm-toast-in  { opacity: 1; transform: translateY(0); }
.pgm-toast-out { opacity: 0; transform: translateY(.5rem); }

/* Respect a stated preference for less motion: the fade becomes an instant change rather than a
   slide. https://developer.mozilla.org/docs/Web/CSS/@media/prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .pgm-toast { transition: opacity .01s linear; }
  .pgm-toast-in, .pgm-toast-out { transform: none; }
}

.pgm-toast-icon { font-size: 1.2rem; }
.pgm-toast-text { flex: 1; min-width: 0; }
.pgm-toast-title { font-weight: 600; font-size: .92rem; }
.pgm-toast-body { opacity: .8; font-size: .85rem; }

.pgm-toast-close {
  background: none; border: 0; cursor: pointer;
  opacity: .5; font-size: .8rem; line-height: 1;
  padding: .2rem;
}
.pgm-toast-close:hover { opacity: 1; }

/* ── The table id, for naming one game in a bug report (ADR-119) ───────────────────────────── */

.pgm-table-id {
  display: inline-flex;
  align-items: baseline;
  gap: .3rem;
  margin-left: .5rem;
  padding: .1rem .4rem;
  border-radius: .25rem;
  font-size: .72rem;
  opacity: .45;                      /* present, not competing with the game */
  cursor: pointer;
  user-select: none;
  transition: opacity .15s ease, background-color .15s ease;
}
.pgm-table-id:hover,
.pgm-table-id:focus-visible {
  opacity: .95;
  background: var(--bs-secondary-bg, rgba(128,128,128,.15));
}

.pgm-table-id-label { text-transform: uppercase; letter-spacing: .04em; }
.pgm-table-id code { font-size: inherit; color: inherit; }
.pgm-table-id-copied { color: var(--bs-success, #198754); font-weight: 600; }

/* ── Avatars (ADR-132) ─────────────────────────────────────────────────────────────────────── */

.pgm-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;                 /* never squashed by a long name beside it */
  border-radius: 50%;
  overflow: hidden;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .02em;
  /* The initials sit on a generated tint, so the text colour is fixed light rather than themed:
     the background is chosen at 38% lightness precisely so this reads in both themes. */
  color: #fff;
  user-select: none;
}

.pgm-avatar img { width: 100%; height: 100%; object-fit: cover; }

.pgm-avatar-lg {
  width: 4.5rem;
  height: 4.5rem;
  font-size: 1.5rem;
}
