/*
 * SEBT documentation theme
 * ========================
 *
 * docfx's `modern` template ships an empty `public/main.css` as an override
 * hook. Because this template is listed after `modern` in docfx.json, this
 * file replaces it and is the last stylesheet the page loads.
 *
 * On the hardcoded hex values: the portal apps derive their colors from the
 * design tokens in `packages/design-system/design/states/*.json`, compiled
 * through the USWDS SCSS pipeline. This site is not part of that pipeline,
 * since docfx has no SCSS step, and it is state-neutral, so it cannot adopt
 * either state's theme layer. It uses the *system* layer both states share: the USWDS
 * base palette. Each value below is annotated with the token it came from. To
 * track a state rebrand, generate this file from the token JSON rather than
 * editing values here.
 */

:root {
  /* Teals, from the USWDS cyan family. The primary brand color for both
     states. */
  --sebt-teal-lightest: #e7f6f8; /* cyan-5 */
  --sebt-teal-lighter: #ccecf2; /* cyan-10 */
  --sebt-teal-light: #99deea; /* cyan-20 */
  --sebt-teal-bright: #00bde3; /* cyan-30v */
  --sebt-teal: #2a646d; /* cyan-60, DC theme-primary */
  --sebt-teal-vivid: #00687d; /* cyan-60v, DC theme-link-color */
  --sebt-teal-dark: #2c4a4e; /* cyan-70 */
  --sebt-teal-darker: #203133; /* cyan-80 */
  --sebt-teal-darkest: #111819; /* cyan-90 */

  /* Violet, from the USWDS violet vivid family. Used only to mark the code we
     ship on ownership diagrams, where it has to stay distinct from both the
     gold a state writes and the gray of a state's own resources. */
  --sebt-violet: #783cb9; /* violet-60v */

  /* Golds, from the USWDS gold vivid family. The accent, used sparingly. */
  --sebt-gold-light: #ffe396; /* gold-10v */
  --sebt-gold: #ffbe2e; /* gold-20v, DC theme-secondary */
  --sebt-gold-dark: #c2850c; /* gold-40v */

  /* Neutrals, from the USWDS gray-cool family, plus ink. */
  --sebt-gray-1: #fbfcfd; /* gray-cool-1 */
  --sebt-gray-2: #f7f9fa; /* gray-cool-2 */
  --sebt-gray-4: #f1f3f6; /* gray-cool-4 */
  --sebt-gray-5: #edeff0; /* gray-cool-5 */
  --sebt-gray-10: #dfe1e2; /* gray-cool-10 */
  --sebt-gray-20: #c6cace; /* gray-cool-20 */
  --sebt-gray-30: #a9aeb1; /* gray-cool-30 */
  --sebt-gray-50: #71767a; /* gray-cool-50 */
  --sebt-gray-60: #565c65; /* gray-cool-60 */
  --sebt-gray-70: #3d4551; /* gray-cool-70 */
  --sebt-gray-80: #2d2e2f; /* gray-cool-80 */
  --sebt-gray-90: #1c1d1f; /* gray-cool-90 */
  --sebt-ink: #1b1b1b; /* gray-90 */

  /* Semantic accents for callouts, from USWDS status colors. */
  --sebt-mint: #00a871; /* mint-40v */
  --sebt-red: #d83933; /* red-50 */
  --sebt-red-vivid: #b50909; /* red-60v, CO theme-secondary */

  /* USWDS focus ring, the same one the apps use. */
  --sebt-focus-color: #2491ff; /* blue-40v */
  --sebt-focus-width: 0.25rem;

  /* No webfont is loaded: the apps use Urbanist (DC) and Atkinson Hyperlegible
     (CO), neither of which is state-neutral. */
  --sebt-font-sans:
    system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;
  --sebt-font-mono:
    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    "Liberation Mono", monospace;
}

/* ---------------------------------------------------------------------------
 * Bootstrap variable mapping
 *
 * The modern template is Bootstrap 5.3. Remapping its variables themes
 * components this file never names, which is why little component-level CSS
 * follows.
 * ------------------------------------------------------------------------- */

:root,
[data-bs-theme="light"] {
  --bs-body-font-family: var(--sebt-font-sans);
  --bs-font-monospace: var(--sebt-font-mono);
  --bs-body-color: var(--sebt-ink);
  --bs-body-bg: #fff;
  --bs-emphasis-color: #000;
  --bs-border-color: var(--sebt-gray-10);
  --bs-secondary-color: var(--sebt-gray-60);
  --bs-secondary-bg: var(--sebt-gray-5);
  --bs-tertiary-bg: var(--sebt-gray-2);

  --bs-primary: var(--sebt-teal);
  --bs-primary-rgb: 42, 100, 109;
  --bs-primary-bg-subtle: var(--sebt-teal-lightest);
  --bs-primary-border-subtle: var(--sebt-teal-light);
  --bs-primary-text-emphasis: var(--sebt-teal-dark);

  /* cyan-60v: 5.6:1 on white, so links clear WCAG AA as body text. */
  --bs-link-color: var(--sebt-teal-vivid);
  --bs-link-color-rgb: 0, 104, 125;
  --bs-link-hover-color: var(--sebt-teal-darker);
  --bs-link-hover-color-rgb: 32, 49, 51;

  --bs-code-color: #7a591a; /* gold-60v, 5.1:1 on the code background */
  --bs-highlight-bg: var(--sebt-gold-light);
}

[data-bs-theme="dark"] {
  --bs-body-color: #eef2f4;
  --bs-body-bg: var(--sebt-teal-darkest);
  --bs-emphasis-color: #fff;
  --bs-border-color: #33454a;
  --bs-secondary-color: var(--sebt-gray-30);
  --bs-secondary-bg: #1b2528;
  --bs-tertiary-bg: #162022;

  --bs-primary: var(--sebt-teal-bright);
  --bs-primary-rgb: 0, 189, 227;
  --bs-primary-bg-subtle: #16333a;
  --bs-primary-border-subtle: #2c5f6b;
  --bs-primary-text-emphasis: var(--sebt-teal-light);

  /* cyan-20 rather than cyan-60v: on a near-black background the vivid mid
     tone drops below AA, the light tint clears it comfortably. */
  --bs-link-color: var(--sebt-teal-light);
  --bs-link-color-rgb: 153, 222, 234;
  --bs-link-hover-color: #d8f2f7;
  --bs-link-hover-color-rgb: 216, 242, 247;

  --bs-code-color: var(--sebt-gold-light);
  --bs-highlight-bg: #4d3c14;
  --bs-highlight-color: #fff;
}

/* ---------------------------------------------------------------------------
 * Focus
 *
 * Bootstrap's default focus is a soft box-shadow that disappears against
 * tinted surfaces. Replaced with the USWDS focus ring the portal apps use.
 * ------------------------------------------------------------------------- */

:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
a:focus-visible {
  outline: var(--sebt-focus-width) solid var(--sebt-focus-color);
  outline-offset: 0;
  box-shadow: none;
}

/* Skip Bootstrap's focus ring when the element also gets ours. */
.form-control:focus {
  border-color: var(--sebt-teal);
  box-shadow: none;
}

/* ---------------------------------------------------------------------------
 * Header
 *
 * A solid teal bar in both color schemes, so the masthead looks the same
 * whichever setting the reader is on.
 * ------------------------------------------------------------------------- */

header.bg-body {
  background-color: var(--sebt-teal) !important;
  border-bottom: 0.25rem solid var(--sebt-gold) !important;
}

header .navbar {
  padding-block: 0.5rem;
}

header .navbar-brand,
header .navbar-brand:hover,
header .navbar-brand:focus {
  color: #fff;
  font-weight: 700;
  letter-spacing: -0.01em;
}

header .navbar-brand #logo {
  height: 2rem;
  width: 2rem;
  margin-right: 0.5rem;
}

/* Nav links inherit Bootstrap's body-emphasis color, which reads as muted gray
   against teal. The current page is marked by weight and a gold underline
   rather than by a dimmer color, so every link stays white. */
header .navbar-nav .nav-link,
header .navbar-nav .nav-link:hover,
header .navbar-nav .nav-link:focus,
header .navbar-nav .nav-link.active {
  color: #fff;
}

header .navbar-nav .nav-link.active {
  font-weight: 700;
  box-shadow: inset 0 -0.1875rem 0 var(--sebt-gold);
}

/* Children of a navbar dropdown sit on the menu's own surface rather than on teal,
   so the white above makes an open menu read as empty. They take the body color
   instead, which tracks the light and dark themes on its own. The active marker is
   dropped too: the gold underline is drawn for a teal bar, not for a white menu. */
header .navbar-nav .dropdown-menu .nav-link,
header .navbar-nav .dropdown-menu .nav-link:hover,
header .navbar-nav .dropdown-menu .nav-link:focus,
header .navbar-nav .dropdown-menu .nav-link.active,
header .navbar-nav .dropdown-menu a {
  color: var(--bs-body-color);
}

header .navbar-nav .dropdown-menu .nav-link.active {
  box-shadow: none;
}

header .navbar-nav .dropdown-menu .nav-link:hover,
header .navbar-nav .dropdown-menu .nav-link:focus {
  background-color: var(--bs-primary-bg-subtle);
}

/* The mobile TOC/nav toggles and the search icon are Bootstrap icon buttons
   that inherit body color, which is invisible on teal. */
header .btn,
header .bi {
  color: #fff;
}

header .search .form-control {
  background-color: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.35);
  color: #fff;
}

header .search .form-control::placeholder {
  color: rgba(255, 255, 255, 0.75);
  opacity: 1;
}

/* On focus the field flips to a light surface: white-on-translucent-teal is
   hard to read while typing, and the focus ring needs a stable backdrop. */
header .search .form-control:focus {
  background-color: #fff;
  border-color: #fff;
  color: var(--sebt-ink);
}

/* ---------------------------------------------------------------------------
 * Article typography
 * ------------------------------------------------------------------------- */

/* Measure.
 *
 * The article column is wide enough for about 100 characters per line, and
 * comfortable reading runs 60 to 75. Capping the running text fixes that
 * without narrowing the column, so tables, code, and diagrams keep the full
 * width they need. */
article p,
article li,
article blockquote,
article > .NOTE,
article > .TIP,
article > .IMPORTANT,
article > .WARNING,
article > .CAUTION {
  max-width: 72ch;
}

/* A table cell holds its own short strings, so the cap would only add ragged
   wrapping inside the cell. */
article table p,
article table li {
  max-width: none;
}

article h1,
article h2,
article h3,
article h4,
article h5 {
  letter-spacing: -0.015em;
  font-weight: 700;
  max-width: 60ch;
}

/* 40px at weight 700 with a full-width gold rule reads as a banner on every
   page. Smaller, with the rule only under the text, leaves the emphasis for
   the content. */
article > h1 {
  font-size: 2rem;
  padding-bottom: 0.375rem;
  border-bottom: 0.1875rem solid var(--sebt-gold);
  margin-bottom: 1.25rem;
  width: fit-content;
  max-width: 100%;
}

article > h2 {
  margin-top: 2rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--bs-border-color);
}

article h3 {
  margin-top: 1.75rem;
}

article p,
article li {
  line-height: 1.6;
}

/* ---------------------------------------------------------------------------
 * Code
 * ------------------------------------------------------------------------- */

code:not(pre code) {
  background-color: var(--bs-secondary-bg);
  padding: 0.125rem 0.25rem;
  border-radius: 0.125rem; /* USWDS radius-sm */
  font-size: 0.9375em;
}

pre {
  background-color: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-left: 0.25rem solid var(--sebt-teal-light);
  border-radius: 0.25rem; /* USWDS radius-md */
  padding: 1rem;
}

[data-bs-theme="dark"] pre {
  border-left-color: var(--sebt-teal-dark);
}

pre code {
  background: none;
  padding: 0;
}

/* ---------------------------------------------------------------------------
 * Tables, the bulk of the API reference
 * ------------------------------------------------------------------------- */

article table {
  --bs-table-border-color: var(--bs-border-color);
  --bs-table-striped-bg: var(--sebt-gray-2);
  width: 100%;
}

[data-bs-theme="dark"] article table {
  --bs-table-striped-bg: #162022;
}

article table > thead {
  background-color: var(--bs-secondary-bg);
}

article table > thead th {
  border-bottom: 2px solid var(--sebt-teal);
  font-weight: 700;
}

article table th,
article table td {
  padding: 0.5rem 0.75rem;
  vertical-align: top;
}

/* ---------------------------------------------------------------------------
 * Callouts
 *
 * docfx renders `> [!NOTE]` and friends as either a classed div or a Bootstrap
 * alert depending on content type, so both are styled. The left-bar treatment
 * mirrors the USWDS alert component the apps use.
 * ------------------------------------------------------------------------- */

.NOTE,
.TIP,
.IMPORTANT,
.WARNING,
.CAUTION,
article .alert {
  border: 1px solid var(--bs-border-color);
  border-left-width: 0.5rem;
  border-radius: 0.25rem;
  padding: 1rem 1.25rem;
  margin-block: 1.25rem;
  background-color: var(--bs-tertiary-bg);
}

.NOTE,
.TIP,
article .alert-info {
  border-left-color: var(--sebt-teal);
}

.IMPORTANT,
article .alert-primary {
  border-left-color: var(--sebt-mint);
}

.WARNING,
article .alert-warning {
  border-left-color: var(--sebt-gold-dark);
}

.CAUTION,
article .alert-danger {
  border-left-color: var(--sebt-red);
}

.NOTE > h5,
.TIP > h5,
.IMPORTANT > h5,
.WARNING > h5,
.CAUTION > h5 {
  text-transform: uppercase;
  font-size: 0.8125rem;
  letter-spacing: 0.05em;
  margin-bottom: 0.5rem;
}

article blockquote {
  border-left: 0.25rem solid var(--sebt-gray-20);
  padding-left: 1rem;
  color: var(--bs-secondary-color);
}

/* ---------------------------------------------------------------------------
 * Navigation: left TOC and right in-page affix
 * ------------------------------------------------------------------------- */

.toc li > a {
  border-radius: 0.125rem;
}

.toc li > a:hover,
.toc li > a:focus {
  color: var(--bs-link-hover-color);
}

/* docfx marks the current node on the anchor in some layouts and on the list
   item in others; both are covered so the accent never goes missing. */
.toc li.active > a,
.toc li > a.active {
  color: var(--bs-primary);
  font-weight: 700;
  box-shadow: inset 0.1875rem 0 0 var(--sebt-gold);
  padding-left: 0.5rem;
}

.toc form.filter > input:focus {
  border-color: var(--sebt-teal);
}

/* The API reference has 500-plus entries and needs the filter. A short TOC does
   not: the box costs more attention than it saves. The test is whether the list
   runs past 12 entries, which the guides do not and the ADRs do. */
.toc:not(:has(li:nth-child(12))) form.filter {
  display: none;
}

/* Group labels in a multi-guide sidebar. The nested children carry the detail,
   so the parent reads as a heading rather than as another link. */
.toc > ul > li > a {
  font-weight: 600;
}

.toc > ul > li > ul {
  margin-bottom: 0.75rem;
}

.affix h5 {
  text-transform: uppercase;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--bs-secondary-color);
}

.affix ul li.active > a {
  color: var(--bs-primary);
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
 * Footer and page furniture
 * ------------------------------------------------------------------------- */

/* `padding-block` matches the `gap` in `.site-footer`, so the badge carries the
   same amount of space above it, below it, and to its right. Its left edge is
   left to the container gutter, which is what keeps it aligned with the header
   logo and the page content above. */
footer {
  background-color: var(--bs-tertiary-bg);
  padding-block: 1.5rem;
  font-size: 0.875rem;
}

.contribution a.edit-link {
  color: var(--bs-link-color);
}

/* Print: the teal masthead wastes toner and the nav is meaningless on paper. */
@media print {
  header.bg-body {
    background-color: transparent !important;
    border-bottom-color: var(--sebt-gray-30) !important;
  }

  header .navbar-brand,
  header .btn,
  header .bi {
    color: var(--sebt-ink);
  }
}

/* ---------------------------------------------------------------------------
   Page provenance
   --------------------------------------------------------------------------- */

/*
  The "last updated" line the section generator writes under each page's H1.
  It is a sibling of the heading rather than part of it, so the gold rule under
  the H1 stays tight to the title.
*/
.doc-meta {
  margin-top: -0.5rem;
  margin-bottom: 1.5rem;
  font-size: 0.8125rem;
  color: var(--bs-secondary-color);
}

.doc-meta time {
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   Footer

   The Summer EBT Potatoes seal sits beside the attribution, with the badge
   drawn as a background image rather than an `<img>`. The footer comes from
   the `_appFooter` metadata string, which the template inserts raw and does
   not prefix with `{{_rel}}` the way it does the header logo, so a relative
   `src` there would resolve correctly only on pages at the site root. A
   stylesheet always loads from `public/`, so a path relative to this file is
   right at every depth.

   The seal repeats the wording of the attribution next to it, so it is
   decorative and carries no alternative text.
   --------------------------------------------------------------------------- */

.site-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
}

.site-footer-badge {
  flex: none;
  width: 10rem;
  height: 10rem;
  background-image: url("../img/potato-sebt.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

.site-footer p {
  margin-bottom: 0;
}

/* Stacked rather than in a row. `align-items` keeps each link's target to the
   width of its own text, since a stretched column item would otherwise make
   the whole line clickable. */
.site-footer-links {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  margin-top: 0.5rem;
}

/* ---------------------------------------------------------------------------
   Path cards

   Used on the Docs overview to route a reader to the section that fits what
   they came to do. Each card is one link, so the target is the whole block
   rather than the title alone.
   --------------------------------------------------------------------------- */

.cta-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin: 1.5rem 0 2rem;
}

/* Two columns rather than auto-fit: with four cards, auto-fit lands on three
   across and orphans the fourth on its own row. */
@media (min-width: 36rem) {
  .cta-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* The gold edge repeats the masthead rule and gives the grid an anchor on the
   left of each card. */
.cta {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1.25rem;
  border: 1px solid var(--bs-border-color);
  border-left: 0.25rem solid var(--sebt-gold);
  border-radius: 0.25rem;
  background-color: var(--bs-body-bg);
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.cta:hover,
.cta:focus {
  border-color: var(--sebt-teal);
  border-left-color: var(--sebt-gold);
  box-shadow: 0 0.125rem 0.5rem rgb(0 0 0 / 10%);
  text-decoration: none;
}

/*
  A tinted disc rather than a bare glyph: at this size a lone icon reads as
  decoration, while the disc gives each card a consistent visual anchor and
  survives the switch to dark mode with the rest of the primary scale.
*/
.cta-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: 0.5rem;
  border-radius: 50%;
  background-color: var(--bs-primary-bg-subtle);
  color: var(--bs-primary);
  font-size: 1.25rem;
  line-height: 1;
}

.cta:hover .cta-icon,
.cta:focus .cta-icon {
  background-color: var(--bs-primary);
  color: var(--bs-body-bg);
}

.cta-title {
  font-weight: 700;
  color: var(--bs-link-color);
}

.cta:hover .cta-title,
.cta:focus .cta-title {
  text-decoration: underline;
}

.cta-text {
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--bs-secondary-color);
}

/*
  The template marks external links with a pseudo-element. Inside a card the
  card is a column flex container, so the marker takes a row of its own and
  reads as a stray glyph. Pinning it to the corner keeps the signal without the
  extra line.
*/
.cta::after {
  position: absolute;
  top: 1.15rem;
  right: 1.15rem;
  color: var(--bs-secondary-color);
}

/* A card for a path that is not written yet. Muted and not a link, so it sets
   expectations without offering a dead end. */
.cta-pending {
  border-left-color: var(--sebt-gray-20);
  cursor: default;
}

.cta-pending .cta-icon {
  background-color: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
}

.cta-pending .cta-title {
  color: var(--bs-secondary-color);
}

/* ---------------------------------------------------------------------------
   Decision records

   The Architecture Decisions landing page. One full-width card per record,
   stacked, grouped by status. Markup is generated by
   `scripts/docs/adr-index.ts`, so the class names here are that script's
   contract: change one and change the other.

   Full width rather than a grid of columns because the longest ADR title runs
   87 characters and wraps to two lines in half a column.
   --------------------------------------------------------------------------- */

.adr-group {
  margin-top: 2rem;
  font-size: 1.25rem;
}

/* The count answers "how many are still open" without counting rows. Lighter
   than the heading so it reads as an annotation on it.

   Drawn from an attribute rather than sitting in the heading, because docfx
   builds its in-page outline from heading text and a count inside one rendered
   there as "Proposed2". Being decorative and redundant next to the cards it
   counts, a pseudo-element is the right home for it. */
.adr-group::after {
  content: attr(data-count);
  margin-left: 0.5rem;
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--bs-secondary-color);
}

.adr-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

/* Narrow first: the status sits beside the number, with title and date across
   the full width below. The wide layout pulls it into one row further down.

   The narrow rules do not render today. This site's layout viewport stays at
   1280px however narrow the window gets, so the page scrolls sideways instead
   of reflowing and the breakpoint below always matches. That is template-wide
   rather than anything here, and it is kept as a fallback for when the template
   does reflow. */
.adr-card {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    'id     status'
    'title  title'
    'meta   meta';
  gap: 0.125rem 1rem;
  padding: 0.875rem 1.125rem;
  border: 1px solid var(--bs-border-color);
  border-left: 0.25rem solid var(--bs-border-color);
  border-radius: 0.25rem;
  background-color: var(--bs-body-bg);
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

@media (min-width: 48rem) {
  .adr-card {
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      'id title status'
      'id meta  status';
    align-items: center;
  }
}

.adr-card:hover,
.adr-card:focus {
  border-color: var(--sebt-teal);
  box-shadow: 0 0.125rem 0.5rem rgb(0 0 0 / 10%);
  text-decoration: none;
}

/* The left edge repeats the badge's color, so status is legible while scanning
   the column of edges without reading every badge. Keyed off the badge class
   with `:has()` rather than a second class on the card, which keeps the
   generated markup to one place per record. */
.adr-card:has(.adr-status-proposed) {
  border-left-color: var(--sebt-gold);
}

.adr-card:has(.adr-status-accepted) {
  border-left-color: var(--sebt-teal);
}

.adr-id {
  grid-area: id;
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--bs-secondary-color);
  white-space: nowrap;
}

.adr-title {
  grid-area: title;
  font-weight: 700;
  color: var(--bs-link-color);
}

.adr-card:hover .adr-title,
.adr-card:focus .adr-title {
  text-decoration: underline;
}

.adr-meta {
  grid-area: meta;
  font-size: 0.875rem;
  color: var(--bs-secondary-color);
}

/* A pill with its own background, so it keeps its meaning against either
   theme's page color without a dark-mode override. */
.adr-status {
  grid-area: status;
  justify-self: end;
  padding: 0.125rem 0.625rem;
  border-radius: 1rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.adr-status-accepted {
  background-color: var(--sebt-teal-lighter);
  color: var(--sebt-teal-dark);
}

.adr-status-proposed {
  background-color: var(--sebt-gold-light);
  color: var(--sebt-ink);
}

/* No record uses these yet. Muted on purpose: a decision that no longer holds
   should not compete with one that does. */
.adr-status-superseded,
.adr-status-deprecated,
.adr-status-rejected {
  background-color: var(--sebt-gray-10);
  color: var(--sebt-gray-70);
}

/* ---------------------------------------------------------------------------
   Diagram legend

   Sits under an architecture diagram and names what each color means. A panel
   rather than a bullet list, because a legend read after the diagram is a
   reference the eye comes back to, not prose read once.

   The swatch is decorative and marked `aria-hidden`. Every entry names its
   meaning in words, so the legend survives a reader who cannot use the color.
   --------------------------------------------------------------------------- */

.legend {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem 2rem;
  /* Pulled up to sit against the diagram it explains. */
  margin: -0.5rem 0 1.75rem;
  padding: 1.25rem;
  border: 1px solid var(--bs-border-color);
  border-left: 0.25rem solid var(--sebt-gold);
  border-radius: 0.25rem;
  background-color: var(--bs-tertiary-bg);
}

@media (min-width: 48rem) {
  .legend {
    grid-template-columns: repeat(2, 1fr);
  }
}

.legend-caption {
  grid-column: 1 / -1;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
}

.legend-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem;
  align-items: start;
}

/* The inset ring, rather than a border, keeps the swatch a fixed size and gives
   each color an edge against the panel behind it. It has to invert with the
   theme: a black ring is invisible on the dark panel, which is where a swatch
   needs the edge most. */
.legend-swatch {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.15rem;
  border-radius: 0.1875rem;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 25%);
}

[data-bs-theme='dark'] .legend-swatch {
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 30%);
}

/* These four match the id-prefix convention used by the architecture diagram
   rules further down this file. Change one and change the other. */
.legend-swatch-person {
  background-color: var(--sebt-teal-vivid);
}

.legend-swatch-ours {
  background-color: var(--sebt-violet);
}

.legend-swatch-yours {
  background-color: var(--sebt-gold-dark);
}

.legend-swatch-res {
  background-color: var(--sebt-gray-50);
}

.legend-title {
  display: block;
}

.legend-text {
  display: block;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--bs-secondary-color);
}

/* ---------------------------------------------------------------------------
   Mermaid diagrams

   Mermaid's stock palette is lavender and pale yellow, which belongs to no
   part of this site. It writes its own styles into a `<style>` block inside
   each SVG, scoped by the diagram's generated id, so those rules carry an id's
   specificity and `!important` is what overrides them.

   Every value here is a Bootstrap variable this file already remaps per color
   scheme, so the diagrams follow the light and dark themes instead of being
   pinned to one. That is why this is CSS rather than a Mermaid `themeVariables`
   directive, which would be static.
   --------------------------------------------------------------------------- */

pre.mermaid .node rect,
pre.mermaid .node polygon,
pre.mermaid .node circle,
pre.mermaid .node path,
pre.mermaid .node .label-container {
  fill: var(--bs-primary-bg-subtle) !important;
  stroke: var(--bs-primary) !important;
}

pre.mermaid .cluster rect {
  fill: var(--bs-tertiary-bg) !important;
  stroke: var(--bs-border-color) !important;
}

pre.mermaid .nodeLabel,
pre.mermaid .cluster-label,
pre.mermaid .edgeLabel {
  color: var(--bs-body-color) !important;
  fill: var(--bs-body-color) !important;
}

/* Edge labels sit on top of the connector they annotate and need to mask it. */
pre.mermaid .edgeLabel .labelBkg,
pre.mermaid .edgeLabel rect {
  background-color: var(--bs-body-bg) !important;
  fill: var(--bs-body-bg) !important;
}

pre.mermaid .flowchart-link,
pre.mermaid .edgePath .path {
  stroke: var(--bs-primary) !important;
}

pre.mermaid .marker,
pre.mermaid .arrowMarkerPath {
  fill: var(--bs-primary) !important;
  stroke: var(--bs-primary) !important;
}

/* Ownership colors on architecture diagrams: default blue is the shared
   application, gold is the connector a state writes, gray is the state's own
   systems. These rules are the only place the colors are set. A diagram's
   `classDef` cannot do it, because mermaid's classDef parser rejects
   parentheses and so cannot take a `var(--token)` value; it declares the class
   and the dashed outline, and the color comes from here.

   So a diagram should declare the class without naming a property set here. Any
   property it does name becomes an id-scoped `!important` rule inside the SVG,
   which outranks these selectors and wins. `classDef stateBuilt fill:...` is
   the way to silently lose the fill below; `classDef stateBuilt stroke-width:2px`
   attaches the class and leaves the color alone.

   The extra class in each selector is what beats the generic `.node` rule
   above, and the shape list mirrors it because a cylinder renders as a path
   rather than a rect. Color only reinforces: every node is labelled, and the
   state-owned nodes are dashed, so the distinction survives without it. */
pre.mermaid .node.stateBuilt rect,
pre.mermaid .node.stateBuilt polygon,
pre.mermaid .node.stateBuilt circle,
pre.mermaid .node.stateBuilt path,
pre.mermaid .node.stateBuilt .label-container {
  fill: var(--sebt-gold-light) !important;
  stroke: var(--sebt-gold-dark) !important;
  stroke-width: 2px !important;
}

/* The gold fill is a fixed light tone, so the label cannot follow the body
   color into dark mode without losing contrast against it. */
pre.mermaid .node.stateBuilt .nodeLabel {
  color: var(--sebt-ink) !important;
  fill: var(--sebt-ink) !important;
}

pre.mermaid .node.stateOwned rect,
pre.mermaid .node.stateOwned polygon,
pre.mermaid .node.stateOwned circle,
pre.mermaid .node.stateOwned path,
pre.mermaid .node.stateOwned .label-container {
  fill: var(--bs-secondary-bg) !important;
  stroke: var(--bs-secondary-color) !important;
  stroke-width: 2px !important;
  stroke-dasharray: 5 4 !important;
}

/* Architecture diagrams (`architecture-beta`) build a different tree from
   flowcharts, so none of the rules above reach them: groups are `rect.node-bkg`
   inside `.architecture-groups`, and services are `g.architecture-service`.
   The ownership colors for this diagram type are set further down, keyed off
   the service id rather than a class. */

/* Outline only, never a fill. Mermaid paints `.architecture-groups` after
   `.architecture-services`, so an opaque group background covers every service
   inside it and the diagram renders as a set of empty boxes. */
pre.mermaid .architecture-groups rect.node-bkg {
  fill: none !important;
  stroke: var(--bs-border-color) !important;
}

/* A group is a boundary, not a thing anyone owns, so its label icon is drawn as
   line art while owned components keep a solid tile. That also clears mermaid's
   stock blue off the diagram, which would otherwise read as a fifth ownership
   color alongside the four below.

   `.architecture-groups svg` only matches the nested icon SVG: the group frames
   are `rect.node-bkg` children of the group layer itself, with no SVG in
   between, so they keep the rule above. The 80x80 tile is the icon background;
   every other shape is a detail stroke, inlined as `#fff` for a colored tile it
   no longer has. */
pre.mermaid .architecture-groups svg rect[width="80"] {
  fill: none !important;
}

pre.mermaid .architecture-groups svg path,
pre.mermaid .architecture-groups svg line,
pre.mermaid .architecture-groups svg circle,
pre.mermaid .architecture-groups svg polyline,
pre.mermaid .architecture-groups svg rect:not([width="80"]) {
  stroke: var(--bs-secondary-color) !important;
}

pre.mermaid .architecture-edges .edge {
  stroke: var(--bs-primary) !important;
}

pre.mermaid .architecture-edges .arrow {
  fill: var(--bs-primary) !important;
}

pre.mermaid .architecture-groups text,
pre.mermaid .architecture-service .text-inner-tspan {
  fill: var(--bs-body-color) !important;
}

/* Architecture diagrams put each service label below its icon, and a vertical
   edge into that icon runs straight through the text. The label is painted
   after the edges, so it is already on top; it just has no background, and the
   line shows through the gaps between letters as a strikethrough.

   `paint-order` draws the stroke first and the glyph over it, turning the
   stroke into a halo in the page color that masks the edge behind the word. */
pre.mermaid .architecture-service .text-inner-tspan {
  paint-order: stroke fill;
  stroke: var(--bs-body-bg) !important;
  stroke-width: 5px;
  stroke-linejoin: round;
}

/* Ownership colors on architecture diagrams.
 *
 * `classDef` is a syntax error in `architecture-beta`, so the only hook is the
 * id mermaid derives from each service's name. Naming a node `oursPortal` or
 * `yoursConnector` therefore carries meaning: the prefix selects the color, and
 * any diagram that follows the convention gets it for free.
 *
 *   person* -> someone using the portal
 *   ours*   -> code we ship and a state adopts
 *   yours*  -> code the state writes
 *   res*    -> a resource the state runs, rather than code
 *
 * The 80x80 rect is the icon tile. The white detail shapes drawn on top of it
 * are separate elements and keep their own fill, so only the tile recolors.
 *
 * Every value has to hold the white detail strokes in light mode and stay
 * visible against the near-black page in dark mode, which rules out the ends of
 * the scale: a near-black tile disappears on the dark page, and a pale one
 * loses the glyph drawn on it. These are all mid-tones for that reason.
 */
pre.mermaid [id^="service-person"] svg rect[width="80"] {
  fill: var(--sebt-teal-vivid) !important;
}

pre.mermaid [id^="service-ours"] svg rect[width="80"] {
  fill: var(--sebt-violet) !important;
}

pre.mermaid [id^="service-yours"] svg rect[width="80"] {
  fill: var(--sebt-gold-dark) !important;
}

pre.mermaid [id^="service-res"] svg rect[width="80"] {
  fill: var(--sebt-gray-50) !important;
}

/* Mermaid renders at the size its layout engine picks, which in an article
   column reads as zoomed in. The viewBox lets it scale down cleanly, so cap the
   height and let width follow.

   Capping the height means the diagram is usually narrower than its column, so
   it needs centering. An SVG is inline by default and would ignore the auto
   margins, hence `display: block`. */
/* The child combinator is load-bearing. `architecture-beta` draws every service
   icon as a nested <svg>, so a descendant selector here also sizes those, which
   collapses them and leaves the diagram as a set of empty group outlines. Only
   the root svg should be constrained. */
pre.mermaid > svg {
  display: block;
  margin-inline: auto;
  max-width: 100%;
  max-height: 24rem;
  height: auto;
}

/* Architecture diagrams carry an icon and a wrapped label per node, so the
   24rem cap that suits a flowchart shrinks their text past reading size. Let
   them take their natural height, and scroll sideways rather than shrink when
   the column is too narrow. */
pre.mermaid:has(> svg[aria-roledescription="architecture"]) {
  overflow-x: auto;
}

pre.mermaid > svg[aria-roledescription="architecture"] {
  max-height: none;
  width: 100%;
  min-width: 34rem;
}


