/* webv2's additions to the SPA theme (app.css). Only what server-rendered
   markup needs and the SPA gets from React components: native <dialog>
   modals, flash/live toasts, the SVG response-time chart and the uptime bar
   tooltips. Tokens are the theme's (web-app.md §16.2). */

/* Confirmation dialogs: a native <dialog> styled as a Bootstrap modal. */
dialog.jmi-dialog {
  border: 0;
  padding: 0;
  width: min(32rem, calc(100% - 2rem));
  background: transparent;
  /* Bootstrap defines these on .modal only; .modal-content reads them. */
  --bs-modal-padding: 1rem;
  --bs-modal-color: var(--bs-body-color);
  --bs-modal-bg: var(--bs-body-bg);
  --bs-modal-border-color: var(--bs-border-color-translucent);
  --bs-modal-border-width: var(--bs-border-width);
  --bs-modal-border-radius: var(--bs-border-radius-lg);
  --bs-modal-inner-border-radius: calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));
  --bs-modal-header-padding: 1rem 1rem;
  --bs-modal-header-border-color: var(--bs-border-color);
  --bs-modal-header-border-width: var(--bs-border-width);
  --bs-modal-title-line-height: 1.5;
  --bs-modal-footer-gap: 0.5rem;
  --bs-modal-footer-border-color: var(--bs-border-color);
  --bs-modal-footer-border-width: var(--bs-border-width);
}
dialog.jmi-dialog.jmi-dialog-wide {
  width: min(50rem, calc(100% - 2rem));
}
dialog.jmi-dialog::backdrop {
  background: rgba(0, 0, 0, 0.5);
}
dialog.jmi-dialog .modal-content {
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

/* Toasts (flash messages and live state changes), top right. */
.jmi-toasts {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 1080;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: min(24rem, calc(100% - 2rem));
}
.jmi-toast {
  background: var(--jmi-toast-bg);
  color: var(--bs-body-color);
  border-left: 4px solid var(--bs-success, #28a745);
  border-radius: 0.25rem;
  box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.15);
  padding: 0.75rem 1rem;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  animation: jmi-toast-in 0.2s ease-out;
}
.jmi-toast.toast-danger {
  border-left-color: #dc3545;
}
.jmi-toast.toast-warning {
  border-left-color: #ffc107;
}
.jmi-toast.toast-info {
  border-left-color: #17a2b8;
}
/* Live toasts (state changes) sit under the flash stack and fade out; the
   server drops them from the live region after 8 s. */
.jmi-live-toasts {
  top: 4.5rem;
}
.jmi-live-toasts .jmi-toast {
  animation:
    jmi-toast-in 0.2s ease-out,
    jmi-toast-out 0.4s ease-in 6s forwards;
}
@keyframes jmi-toast-out {
  to {
    opacity: 0;
    visibility: hidden;
  }
}
.jmi-toast[hidden] {
  display: none;
}
.jmi-toast .btn-close {
  margin-left: auto;
  font-size: 0.75rem;
}
@keyframes jmi-toast-in {
  from {
    opacity: 0;
    transform: translateY(-0.5rem);
  }
}

/* Navbar collapse and org dropdown driven by topcoat signals. */
.navbar .dropdown-menu.show {
  display: block;
}
/* The theme and mute menus are native <details> (work without JavaScript). */
.theme-menu > summary,
.mute-menu > summary {
  list-style: none;
  cursor: pointer;
}
.theme-menu > summary::-webkit-details-marker,
.mute-menu > summary::-webkit-details-marker {
  display: none;
}
.theme-menu[open] > .dropdown-menu,
.mute-menu[open] > .dropdown-menu {
  display: block;
}
.mute-menu > .dropdown-menu {
  min-width: 17rem;
}

/* Maintenance windows (notifications.md §8.17): violet, apart from the
   status colours, on the banner, the navbar's mute menu and badges. */
:root {
  --jmi-maint: #5b4bc4;
  --jmi-maint-bg: #efecfb;
  --jmi-maint-border: #c9c1f2;
}
[data-bs-theme="dark"] {
  --jmi-maint: #b3a8f5;
  --jmi-maint-bg: #26213f;
  --jmi-maint-border: #4a3f8a;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-bs-theme="light"]) {
    --jmi-maint: #b3a8f5;
    --jmi-maint-bg: #26213f;
    --jmi-maint-border: #4a3f8a;
  }
}
.maint-banner {
  background: var(--jmi-maint-bg);
  border-bottom: 1px solid var(--jmi-maint-border);
  color: var(--bs-body-color);
}
.text-maint {
  color: var(--jmi-maint) !important;
}
.badge.text-bg-maint {
  background: var(--jmi-maint) !important;
  color: var(--bs-body-bg) !important;
}
.btn-maint {
  --bs-btn-color: #fff;
  --bs-btn-bg: #5b4bc4;
  --bs-btn-border-color: #5b4bc4;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #4b3cb0;
  --bs-btn-hover-border-color: #4b3cb0;
  --bs-btn-active-bg: #4b3cb0;
}
.btn-outline-maint {
  --bs-btn-color: var(--jmi-maint);
  --bs-btn-border-color: var(--jmi-maint);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #5b4bc4;
  --bs-btn-hover-border-color: #5b4bc4;
  --bs-btn-active-bg: #4b3cb0;
}
/* Other <details> dropdowns (the probes' "More"): the menu hangs from the
   toggle's right edge. In a table's scroll box it would be clipped by the
   box, so the open menu is fixed to its toggle with anchor positioning and
   flips above it when there is no room below. Only one is open at a time
   (the menus share a `name`), so one anchor name serves them all. */
details.dropdown > .dropdown-menu-end {
  right: 0;
  left: auto;
}
@supports (anchor-name: --a) {
  .table-responsive details.dropdown[open] > summary {
    anchor-name: --jmi-dropdown;
  }
  .table-responsive details.dropdown[open] > .dropdown-menu {
    position: fixed;
    position-anchor: --jmi-dropdown;
    top: anchor(bottom);
    right: anchor(right);
    left: auto;
    margin-top: 0.125rem;
    position-try-fallbacks: flip-block;
    position-visibility: anchors-visible;
  }
}

/* SVG response-time chart (server rendered). */
.svg-chart {
  width: 100%;
  height: auto;
  display: block;
  font-size: 11px;
}
.svg-chart .grid line {
  stroke: var(--bs-secondary-bg);
}
.svg-chart .axis text {
  fill: var(--jmi-chart-label);
}
.svg-chart .series {
  fill: none;
  stroke-width: 1.5;
  stroke-linejoin: round;
}
.svg-chart .band {
  opacity: 0.25;
}
.svg-chart .hover-point {
  fill: transparent;
}
.svg-chart .hover-point:hover {
  fill: currentColor;
}
.chart-legend label {
  cursor: pointer;
}
.chart-legend .legend-line {
  display: inline-block;
  width: 1.5rem;
  border-top-width: 2px;
  vertical-align: middle;
}

/* Live dot connecting state (before the WebSocket render). */
.live-dot.connecting .dot {
  background: #adb5bd;
}

/* Path traces: a summary line that opens the hop table. */
details.trace > summary {
  cursor: pointer;
}
details.trace[open] > summary {
  border-bottom: 1px solid var(--bs-border-color);
  margin-bottom: 0.75rem;
}
.trace-hops td.num,
.trace-hops th {
  white-space: nowrap;
}

/* Inline forms inside tables and button rows. */
form.d-inline {
  display: inline;
}

@media (prefers-reduced-motion: reduce) {
  .jmi-toast,
  .jmi-live-toasts .jmi-toast {
    animation: none;
  }
}

/* The public API documentation (/docs/api, crate::docs): a page list
   beside Markdown rendered on the server. */
.docs-shell > .docs-body {
  flex: 1 0 auto;
}
.docs-nav .nav-link {
  padding: 0.3rem 0.75rem;
  border-radius: var(--bs-border-radius);
  color: var(--bs-body-color);
}
.docs-nav .nav-link.active {
  background: var(--bs-secondary-bg);
  font-weight: 600;
}
.docs-content {
  min-width: 0;
}
.docs-content h2 {
  margin-top: 2rem;
}
.docs-content h3 {
  margin-top: 1.5rem;
}
.docs-content pre {
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  padding: 0.75rem 1rem;
}
.docs-content td code {
  word-break: break-word;
}
.docs-toc summary {
  cursor: pointer;
}

/* The public changelog (/changelog, crate::changelog): dates on the left
   (above the entries on small screens), each entry a badge, a title that
   links to its anchor, and Markdown text. */
.changelog-shell > .changelog-body {
  flex: 1 0 auto;
  max-width: 60rem;
}
.changelog-nav-link {
  font-size: 0.875rem;
  color: var(--bs-secondary-color);
}
@media (max-width: 575.98px) {
  .changelog-nav-link {
    display: none;
  }
}
.changelog-header {
  padding-bottom: 1.5rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--bs-border-color);
}
.changelog-header h1 {
  font-weight: 700;
}
.changelog-day {
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--bs-border-color);
}
.changelog-day:last-child {
  border-bottom: 0;
}
.changelog-date {
  font-size: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--bs-secondary-color);
  margin-bottom: 1rem;
}
.changelog-entry + .changelog-entry {
  margin-top: 2rem;
}
.changelog-entry {
  scroll-margin-top: 1rem;
}
.changelog-kind {
  font-weight: 600;
  margin-bottom: 0.5rem;
  color: var(--changelog-ink);
  background: var(--changelog-bg);
  border: 1px solid var(--changelog-border);
}
.changelog-kind-new {
  --changelog-ink: var(--bs-success-text-emphasis);
  --changelog-bg: var(--bs-success-bg-subtle);
  --changelog-border: var(--bs-success-border-subtle);
}
.changelog-kind-improved {
  --changelog-ink: var(--bs-primary-text-emphasis);
  --changelog-bg: var(--bs-primary-bg-subtle);
  --changelog-border: var(--bs-primary-border-subtle);
}
.changelog-kind-fixed {
  --changelog-ink: var(--bs-warning-text-emphasis);
  --changelog-bg: var(--bs-warning-bg-subtle);
  --changelog-border: var(--bs-warning-border-subtle);
}
.changelog-kind-security {
  --changelog-ink: var(--bs-danger-text-emphasis);
  --changelog-bg: var(--bs-danger-bg-subtle);
  --changelog-border: var(--bs-danger-border-subtle);
}
.changelog-kind-removed {
  --changelog-ink: var(--bs-secondary-text-emphasis);
  --changelog-bg: var(--bs-secondary-bg-subtle);
  --changelog-border: var(--bs-secondary-border-subtle);
}
.changelog-entry h3 {
  font-size: 1.35rem;
  font-weight: 600;
  margin-bottom: 0.75rem;
}
.changelog-entry h3 a {
  color: inherit;
  text-decoration: none;
}
.changelog-entry h3 a:hover {
  text-decoration: underline;
}
.changelog-entry:target h3 a {
  text-decoration: underline;
  text-decoration-color: var(--bs-primary);
}
.changelog-text {
  max-width: 42rem;
}
.changelog-text > :last-child {
  margin-bottom: 0;
}
@media (min-width: 768px) {
  .changelog-day {
    display: grid;
    grid-template-columns: 11rem 1fr;
    gap: 2rem;
  }
  .changelog-date {
    position: sticky;
    top: 1rem;
    align-self: start;
    margin: 0.2rem 0 0;
  }
}
