@charset "UTF-8";
/* ── Vendored web fonts ───────────────────────────────────────────────────
   `bootstrap-overrides.css` names Funnel Sans and Volkhov in --font-body and
   --font-display, and used to reach for them with a Google Fonts @import. That
   request was blocked by this host's own CSP for as long as it existed, so the
   whole file rendered in system-ui. The faces are now restored by `libman restore`
   from `libman.json` into wwwroot/lib and served from this origin, which is what
   `font-src 'self'` will accept.

   Funnel Sans is the variable cut: one file carries 300-700, which is every weight
   the overrides ask for. Volkhov is static, so 400 and 700 are separate files.

   Italics are deliberately not vendored - 46 KB for `<em>`, which appears nowhere on
   these pages. The browser synthesizes an oblique if one ever does.

   The unicode-range split is Google's own: latin-ext is fetched only by a page that
   actually renders a character in it, which for this host means an accented name. */
@font-face {
  font-family: "Funnel Sans";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../lib/funnel-sans/files/funnel-sans-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Funnel Sans";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../lib/funnel-sans/files/funnel-sans-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Volkhov";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../lib/volkhov/files/volkhov-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Volkhov";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../lib/volkhov/files/volkhov-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
:root {
  --brand-color: var(--duende-charcoal);
}

.sidebar {
  background-color: var(--duende-sand-soft) !important;
}

.sidebar a, .sidebar .link-body-emphasis {
  text-decoration: none;
  background-image: none;
  transition: none;
}

.sidebar .nav-link.active {
  background-color: var(--duende-green) !important;
  color: var(--duende-charcoal) !important;
}

.text-brand {
  color: var(--brand-color) !important;
}

.text-bg-brand {
  background-color: var(--brand-color) !important;
  color: #FFF !important;
}

.card .table {
  --bs-table-bg: var(--duende-white);
  --bs-table-color: var(--duende-charcoal);
  --bs-table-border-color: rgba(36,32,32,0.12);
}

.card .list-group-item {
  background-color: var(--duende-sand-soft) !important;
}

.welcome-page .logo {
  width: 64px;
}

.dashboard a i.bi {
  --bs-btn-color: var(--brand-color);
  color: var(--brand-color) !important;
}

textarea.disco-doc,
code.language-csharp {
  /* cross-platform monospace stack */
  font-family: Consolas, "Liberation Mono", Menlo, "Courier New", Courier, monospace; /* ultimate fallback */
  font-size: 0.9rem;
  line-height: 1.4;
  padding: 0.5rem;
  overflow-x: auto;
  white-space: pre;
  word-wrap: normal;
  font-size: small;
}

code.language-csharp {
  font-size: smaller;
}

@media (max-width: 576px) {
  .sidebar {
    max-width: 80px !important;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
  .sidebar .nav-link {
    justify-content: center;
  }
}
@media (min-width: 577px) {
  .sidebar {
    max-width: 280px !important;
  }
}
.icon-banner {
  width: 32px;
}

.body-container {
  margin-top: 60px;
  padding-bottom: 40px;
}

.welcome-page li {
  list-style: none;
  padding: 4px;
}

.logged-out-page iframe {
  display: none;
  width: 0;
  height: 0;
}

.grants-page .card {
  margin-top: 20px;
  border-bottom: 1px solid lightgray;
}

.grants-page .card .card-title {
  font-size: 120%;
  font-weight: bold;
}

.grants-page .card .card-title img {
  width: 100px;
  height: 100px;
}

.grants-page .card label {
  font-weight: bold;
}

.page-consent div.client-logo > img {
  max-height: 48px;
}

.discovery-document {
  height: 700px;
}

.discovery-document pre {
  max-height: fit-content;
}

.discovery-document pre code {
  font-size: 0.9em;
  padding: 0;
  margin: 0;
}

/* "Sign in with Google".

   These values are Google's published specification for the dark, pill-shaped variant of
   their button - not Mokuo's palette, and deliberately not --brand-color. Recoloring the
   mark or the surround is what fails Google's brand review, so this block is the one place
   in this stylesheet that is exempt from the single-brand-token rule. Do not theme it.

   The pill radius is one of Google's own approved shapes, chosen because it matches the
   Duende buttons beside it. Their spec also asks for Roboto Medium; loading it would mean a
   Google Fonts request from a login page, so the page's own stack is used at weight 500,
   which their guidance allows where Roboto is unavailable. */
.btn-google {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 40px;
  padding: 0 12px;
  border: 1px solid #8E918F;
  border-radius: 20px;
  background-color: #131314;
  color: #E3E3E3;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.25px;
  line-height: 20px;
  text-decoration: none;
  white-space: nowrap;
}

.btn-google svg {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}

/* Google's state layer: white over the background at 8% hovered and 12% pressed, flattened
   here so the mark and label need no stacking context of their own. */
.btn-google:hover {
  background-color: #262627;
  color: #E3E3E3;
}

.btn-google:active {
  background-color: #2F2F30;
  color: #E3E3E3;
}

.btn-google:focus-visible {
  color: #E3E3E3;
  outline: 2px solid #8E918F;
  outline-offset: 2px;
}

/* ── The sign-in shell ────────────────────────────────────────────────────
   `_LayoutLogin` is the shared shell for Login, Register, ForgotPassword,
   ResetPassword, ConfirmEmail, Consent, Logout, LoggedOut and Passkeys. It used to be
   Bootstrap's `container-fluid vh-100` with a `row` and a `col-md-8` inside it, which is
   the scaffold's answer to "put something on a page" and reads as one.

   Two things that shape everything below.

   `vh-100` with an `overflow-auto` main is replaced by a document that simply scrolls.
   The old arrangement made an inner scroll region, and an inner scroll region is what
   makes a mobile keyboard shove a focused field under itself with nowhere to go. This is
   the page an Android Custom Tab opens onto, so that is not a hypothetical.

   The column is capped rather than proportional. A sign-in form has one job and a
   measure to match; `col-md-8` on a laptop gave it a text line long enough to read as an
   admin screen. Everything here is one column at every width, which also means no page
   needs a breakpoint of its own.

   Nothing in this block names a product - see ClientBranding. The single thing that
   varies is `--brand-color`, which the layout binds per client, and which reaches the
   primary action through `.sign-in-shell .btn-primary` below. */
.sign-in-body {
  background-color: var(--duende-sand);
  min-height: 100dvh;
  display: flex;
  justify-content: center;
  /* Not `center`: a form that grows past the viewport - Register, or Login carrying a
     validation summary - would center by overflowing equally off the top, putting the
     first field out of reach above the scroll origin. */
  align-items: flex-start;
  padding: clamp(1.5rem, 6vh, 4rem) 1rem;
}

.sign-in-shell {
  width: 100%;
  max-width: 26rem;
}

.sign-in-masthead {
  text-align: center;
  margin-bottom: 1.75rem;
}

.sign-in-wordmark {
  display: block;
  font-family: var(--font-display);
  font-size: 1.75rem;
  line-height: 1.1;
  font-weight: 700;
  letter-spacing: -0.01em;
  /* Deliberately the neutral foreground and not --brand-color: the wordmark is Mokuo's
     and must not take a product's color. The accent belongs to the sentence below it
     and to the action inside the card. */
  color: var(--d-fg-1);
}

.sign-in-continue {
  margin: 0.4rem 0 0;
  font-size: 0.875rem;
  color: var(--d-fg-3);
}

/* The panel. `.card` from the palette already carries the radius, border and shadow, so
   this only adds the padding a bare card does not have and drops the header bar these
   pages no longer use. */
.sign-in-card {
  background-color: var(--duende-white);
  border: 1px solid var(--d-border-subtle);
  border-radius: 12px;
  box-shadow: var(--shadow-card);
  padding: 1.75rem 1.5rem;
}

.sign-in-title {
  font-family: var(--font-body);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--d-fg-1);
  margin: 0 0 1.25rem;
}

/* The sentence under a title, where a page has one. Titles that carry a lead sit
   closer to it than to the form, so the pair reads as one block rather than two. */
.sign-in-title:has(+ .sign-in-lead) {
  margin-bottom: 0.35rem;
}

.sign-in-lead {
  margin: 0 0 1.5rem;
  font-size: 0.9375rem;
  color: var(--d-fg-3);
}

/* The accent, on the one control it should be on. Scoped to the shell so the admin
   pages keep the charcoal `.btn-primary` the palette gives them. */
.sign-in-shell .btn-primary {
  --bs-btn-bg: var(--brand-color);
  --bs-btn-border-color: var(--brand-color);
  --bs-btn-hover-bg: color-mix(in srgb, var(--brand-color) 88%, #000);
  --bs-btn-hover-border-color: color-mix(in srgb, var(--brand-color) 88%, #000);
  --bs-btn-active-bg: color-mix(in srgb, var(--brand-color) 78%, #000);
  --bs-btn-active-border-color: color-mix(in srgb, var(--brand-color) 78%, #000);
}

.sign-in-shell .form-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--d-fg-2);
  margin-bottom: 0.35rem;
}

/* A "or" rule between the password form and the credentials that are not passwords.

   Drawn only when there is in fact something below it. The login page cannot decide
   that on the server: the passkey button ships hidden and reveals itself only where
   the browser can do WebAuthn, so a rule emitted unconditionally would dangle above
   an empty stack in a browser that cannot. Hence display:none by default and a :has()
   that looks for a Google button or a revealed passkey button in the next sibling. */
.sign-in-divider {
  display: none;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--d-fg-3);
}

.sign-in-divider:has(+ .sign-in-alternatives :is(.btn-google, [data-passkey-button]:not(.d-none))) {
  display: flex;
}

.sign-in-divider::before,
.sign-in-divider::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background-color: var(--d-border-subtle);
}

/* The alternatives stack, one per row and all the same width, so no one of them reads as
   the afterthought. The Google button sizes itself from its own spec, so it is stretched
   here rather than restyled - see `.btn-google`, which must not be themed. */
.sign-in-alternatives {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.sign-in-alternatives > .btn,
.sign-in-alternatives > .btn-google,
.sign-in-alternatives form > .btn {
  width: 100%;
}

.sign-in-alternatives .btn-google {
  justify-content: center;
}

.sign-in-footer {
  margin-top: 1.5rem;
  text-align: center;
  font-size: 0.875rem;
  color: var(--d-fg-3);
}

.sign-in-meta {
  margin-top: 1rem;
  font-size: 0.875rem;
}

/* An action that belongs to the page rather than to the form inside the card - the "Sign in"
   on a password-changed or email-confirmed page, where the card is only a sentence and the
   button is the one thing left to do. Same offset as .sign-in-footer so the two are
   interchangeable without the card appearing to move. */
.sign-in-after-card {
  margin-top: 1.5rem;
}

/* Two cards in a column, on the pages that genuinely have two things to say - Passkeys lists
   what you have and then offers to add one. */
.sign-in-card + .sign-in-card {
  margin-top: 1rem;
}

/* A heading inside a card, below .sign-in-title - the scope groups on the consent page. */
.sign-in-subhead {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--d-fg-3);
  margin: 0 0 0.5rem;
}

/* The passkey list, inside a .sign-in-card rather than a Bootstrap .card. The palette fills
   `.card .list-group-item` with sand, which inside a white sign-in card reads as a highlighted
   band rather than as a row. Flush rows separated by a rule is what `list-group-flush` means. */
.sign-in-card .list-group-item {
  background-color: transparent;
  border-color: var(--d-border-subtle);
}

.sign-in-card .list-group-flush > .list-group-item:last-child {
  border-bottom: 0;
}
