/* ============================================================================
   wy.css — design system: primitives and layout.
   Contract: design/DESIGN-SYSTEM.md section 4. Values live in tokens.css; this
   file uses var(--wy-…) only, and styles only .wy-* selectors (plus their
   descendants) and body.wy-root. Old pages are untouched until they opt in.
   Not used here: colour literals, gradients, backdrop filters, transform
   scale, card shadows, uppercase labels, the important flag.
   Lengths come from the space, type and radius tokens; the only raw lengths
   are 1 px borders and 2 px focus rings. Where a contract size is not a token
   it is a calc() of tokens with the intended value in a trailing comment.
   Breakpoints: 480 (dialog margins), 640 (phone to tablet), 1024 (sidebar).
   z-index scale: 1 sticky table header, 2 scroll cue, 10 topbar and sidebar,
   20 menus and tooltips, 30 toasts, 40 skip link. Dialogs use the top layer.
   ========================================================================== */

/* ----------------------------------------------------------------------------
   0. Base — typography for pages that opt in with body.wy-root
   -------------------------------------------------------------------------- */
body.wy-root {
  margin: 0;
  min-height: 100vh;
  color-scheme: var(--wy-color-scheme);
  background: var(--wy-bg);
  color: var(--wy-text);
  font-family: var(--wy-font-sans);
  font-size: var(--wy-text-md);
  font-weight: var(--wy-weight-normal);
  line-height: var(--wy-leading);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
.wy-root *, .wy-root *::before, .wy-root *::after { box-sizing: border-box; }
.wy-root [hidden] { display: none; }
/* Prose links. Wrapped in :where() so any .wy-* component (buttons, nav,
   breadcrumbs, menu items, logo) wins over these without extra specificity. */
:where(body.wy-root a) { color: var(--wy-accent); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
:where(body.wy-root a:hover) { color: var(--wy-accent-hover); }
:where(body.wy-root a:focus-visible) { outline: 2px solid var(--wy-focus); outline-offset: 2px; border-radius: var(--wy-radius-sm); }

/* ----------------------------------------------------------------------------
   4.1 Button — .wy-btn, .wy-btn-group, .wy-segmented
   -------------------------------------------------------------------------- */
.wy-btn {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--wy-space-2);
  min-height: var(--wy-space-8); /* 32 */
  margin: 0;
  padding: var(--wy-space-1) var(--wy-space-3);
  border: 1px solid var(--wy-border-control);
  border-radius: var(--wy-radius-md);
  background: var(--wy-surface);
  color: var(--wy-text);
  font-family: inherit;
  font-size: var(--wy-text-sm);
  font-weight: var(--wy-weight-medium);
  line-height: var(--wy-leading-tight);
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  appearance: none;
  user-select: none;
  transition: background-color var(--wy-motion-fast) var(--wy-ease), border-color var(--wy-motion-fast) var(--wy-ease), color var(--wy-motion-fast) var(--wy-ease);
}
.wy-btn:hover { background: var(--wy-surface-sunken); color: var(--wy-text); }
.wy-btn:active { background: var(--wy-border); }
.wy-btn:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; }

.wy-btn--primary { background: var(--wy-accent); border-color: var(--wy-accent); color: var(--wy-text-on-accent); }
.wy-btn--primary:hover, .wy-btn--primary:active { background: var(--wy-accent-hover); border-color: var(--wy-accent-hover); color: var(--wy-text-on-accent); }

.wy-btn--ghost { background: transparent; border-color: transparent; }
.wy-btn--ghost:hover { background: var(--wy-surface-sunken); }
.wy-btn--ghost:active { background: var(--wy-border); }

.wy-btn--danger { background: var(--wy-surface); border-color: var(--wy-danger-fg); color: var(--wy-danger-fg); }
/* Solid danger keeps white text in both themes (tokens.css verifies neutral-0
   on --wy-danger and on --wy-danger-hover); --wy-text-on-accent is dark in dark. */
.wy-btn--danger:hover { background: var(--wy-danger); border-color: var(--wy-danger); color: var(--wy-neutral-0); }
.wy-btn--danger:active { background: var(--wy-danger-hover); border-color: var(--wy-danger-hover); color: var(--wy-neutral-0); }
.wy-btn--danger.wy-btn--primary { background: var(--wy-danger); border-color: var(--wy-danger); color: var(--wy-neutral-0); }
.wy-btn--danger.wy-btn--primary:hover, .wy-btn--danger.wy-btn--primary:active { background: var(--wy-danger-hover); border-color: var(--wy-danger-hover); color: var(--wy-neutral-0); }

.wy-btn--sm { min-height: calc(var(--wy-space-6) + var(--wy-space-1)); /* 28 */ padding: var(--wy-space-1) var(--wy-space-2); font-size: var(--wy-text-xs); }
.wy-btn--icon { width: var(--wy-space-8); padding: 0; flex: none; }
.wy-btn--icon.wy-btn--sm { width: calc(var(--wy-space-6) + var(--wy-space-1)); }
.wy-btn--block { display: flex; width: 100%; }
.wy-btn > .wy-icon { flex: none; }

/* Loading: aria-busy shows the spinner next to the label, which stays in the DOM. */
.wy-btn__spinner { display: none; width: var(--wy-space-4); height: var(--wy-space-4); flex: none; animation: wy-spin 0.8s linear infinite; }
.wy-btn[aria-busy="true"] { pointer-events: none; }
.wy-btn[aria-busy="true"] .wy-btn__spinner { display: inline-block; }
.wy-btn[aria-busy="true"] > .wy-icon:not(.wy-btn__spinner) { display: none; }
@keyframes wy-spin { to { transform: rotate(1turn); } }

.wy-btn:disabled, .wy-btn[aria-disabled="true"] { background: var(--wy-surface-sunken); border-color: var(--wy-border); color: var(--wy-text-disabled); cursor: not-allowed; }
.wy-btn--ghost:disabled, .wy-btn--ghost[aria-disabled="true"] { background: transparent; border-color: transparent; }

.wy-btn-group { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wy-space-2); }

/* Segmented control: buttons with aria-pressed inside one bordered box. */
.wy-segmented { display: inline-flex; align-items: stretch; border: 1px solid var(--wy-border-control); border-radius: var(--wy-radius-md); background: var(--wy-surface); }
.wy-segmented > * {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: calc(var(--wy-space-8) - 2px); /* 30 inside the 1 px box = 32 */
  margin: 0;
  padding: 0 var(--wy-space-3);
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--wy-text-muted);
  font-family: inherit;
  font-size: var(--wy-text-sm);
  font-weight: var(--wy-weight-medium);
  line-height: var(--wy-leading-tight);
  white-space: nowrap;
  cursor: pointer;
  appearance: none;
}
.wy-segmented > * + * { border-left: 1px solid var(--wy-border); }
.wy-segmented > :first-child { border-radius: calc(var(--wy-radius-md) - 1px) 0 0 calc(var(--wy-radius-md) - 1px); }
.wy-segmented > :last-child { border-radius: 0 calc(var(--wy-radius-md) - 1px) calc(var(--wy-radius-md) - 1px) 0; }
.wy-segmented > :hover { color: var(--wy-text); background: var(--wy-surface-sunken); }
.wy-segmented > [aria-pressed="true"] { background: var(--wy-accent-subtle); color: var(--wy-accent); }
.wy-segmented > :focus-visible { position: relative; z-index: 1; outline: 2px solid var(--wy-focus); outline-offset: calc(var(--wy-space-1) * -0.5); }

/* ----------------------------------------------------------------------------
   4.2 Field — .wy-field, .wy-label, .wy-input, .wy-textarea, .wy-select,
       .wy-select-wrap, .wy-help, .wy-error, .wy-input-group, .wy-input-addon
   -------------------------------------------------------------------------- */
.wy-field { display: flex; flex-direction: column; gap: var(--wy-space-1); min-width: 0; }
.wy-label { display: block; color: var(--wy-text); font-size: var(--wy-text-sm); font-weight: var(--wy-weight-medium); line-height: var(--wy-leading); }
.wy-label__optional { margin-left: var(--wy-space-1); color: var(--wy-text-muted); font-weight: var(--wy-weight-normal); }
.wy-help { margin: 0; color: var(--wy-text-muted); font-size: var(--wy-text-xs); line-height: var(--wy-leading); }
.wy-error { margin: 0; color: var(--wy-danger-fg); font-size: var(--wy-text-xs); line-height: var(--wy-leading); }

.wy-input, .wy-textarea, .wy-select {
  box-sizing: border-box;
  display: block;
  width: 100%;
  min-height: var(--wy-space-8); /* 32 */
  margin: 0;
  padding: var(--wy-space-1) var(--wy-space-3);
  border: 1px solid var(--wy-border-control);
  border-radius: var(--wy-radius-md);
  background: var(--wy-surface);
  color: var(--wy-text);
  font-family: inherit;
  font-size: var(--wy-text-md);
  font-weight: var(--wy-weight-normal);
  line-height: var(--wy-leading-tight);
  appearance: none;
  transition: border-color var(--wy-motion-fast) var(--wy-ease);
}
.wy-input::placeholder, .wy-textarea::placeholder { color: var(--wy-text-muted); opacity: 1; } /* 4.5:1: placeholders are text */
.wy-input:hover, .wy-textarea:hover, .wy-select:hover { border-color: var(--wy-border-strong); }
.wy-input:focus-visible, .wy-textarea:focus-visible, .wy-select:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; border-color: var(--wy-border-control); }
.wy-input[aria-invalid="true"], .wy-textarea[aria-invalid="true"], .wy-select[aria-invalid="true"] { border-color: var(--wy-danger-fg); }
.wy-input[aria-invalid="true"]:focus-visible, .wy-textarea[aria-invalid="true"]:focus-visible, .wy-select[aria-invalid="true"]:focus-visible { outline-color: var(--wy-danger-fg); }
.wy-input:disabled, .wy-textarea:disabled, .wy-select:disabled { background: var(--wy-surface-sunken); border-color: var(--wy-border); color: var(--wy-text-disabled); cursor: not-allowed; }
.wy-input--mono, .wy-textarea--mono { font-family: var(--wy-font-mono); font-variant-numeric: tabular-nums; }
.wy-textarea { min-height: calc(var(--wy-space-16) + var(--wy-space-8)); /* 96 */ padding: var(--wy-space-2) var(--wy-space-3); line-height: var(--wy-leading); resize: vertical; }
/* iOS zooms into inputs under 16 px; --wy-text-lg is 1rem. */
@media (max-width: 639px) {
  .wy-input, .wy-textarea, .wy-select { font-size: var(--wy-text-lg); }
}

.wy-select-wrap { position: relative; }
.wy-select-wrap > .wy-select { padding-right: var(--wy-space-8); }
.wy-select-wrap > .wy-icon { position: absolute; top: 0; bottom: 0; right: var(--wy-space-3); margin: auto 0; color: var(--wy-text-muted); pointer-events: none; }
.wy-select-wrap > .wy-select:disabled ~ .wy-icon { color: var(--wy-text-disabled); }

.wy-input-group { display: flex; align-items: stretch; min-width: 0; }
.wy-input-group > .wy-input, .wy-input-group > .wy-select-wrap { flex: 1 1 auto; min-width: 0; }
.wy-input-group > .wy-input-addon { display: inline-flex; align-items: center; padding: 0 var(--wy-space-3); border: 1px solid var(--wy-border-control); background: var(--wy-surface-sunken); color: var(--wy-text-muted); font-size: var(--wy-text-sm); white-space: nowrap; }
.wy-input-group > * { border-radius: 0; }
.wy-input-group > * + * { border-left-width: 0; }
.wy-input-group > :first-child, .wy-input-group > :first-child > .wy-select { border-top-left-radius: var(--wy-radius-md); border-bottom-left-radius: var(--wy-radius-md); }
.wy-input-group > :last-child, .wy-input-group > :last-child > .wy-select { border-top-right-radius: var(--wy-radius-md); border-bottom-right-radius: var(--wy-radius-md); }
.wy-input-group > :focus-visible { position: relative; z-index: 1; }

/* ----------------------------------------------------------------------------
   4.3 Checkbox .wy-check, radio .wy-radio, switch .wy-switch
   Markup: <label class="wy-check"><input class="wy-check__input" type="checkbox">
   <span class="wy-check__box"><svg class="wy-icon">…</svg></span> Text</label>.
   The switch draws its track on .wy-switch__track and its knob on the
   .wy-switch__knob inside it. Inputs are clipped, never display none.
   -------------------------------------------------------------------------- */
.wy-check, .wy-radio, .wy-switch { position: relative; display: inline-flex; align-items: flex-start; gap: var(--wy-space-2); max-width: 100%; color: var(--wy-text); font-size: var(--wy-text-sm); line-height: var(--wy-leading); cursor: pointer; }
.wy-check__input, .wy-radio__input, .wy-switch__input, .wy-option__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  opacity: 0;
}
.wy-check__box, .wy-radio__box {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--wy-space-4);
  height: var(--wy-space-4);
  margin-top: calc((var(--wy-text-sm) * var(--wy-leading) - var(--wy-space-4)) / 2); /* centred on the first text line */
  border: 1px solid var(--wy-border-control);
  border-radius: var(--wy-radius-sm);
  background: var(--wy-surface);
  color: var(--wy-text-on-accent);
  transition: background-color var(--wy-motion-fast) var(--wy-ease), border-color var(--wy-motion-fast) var(--wy-ease);
}
.wy-radio__box { border-radius: 50%; }
.wy-check__box > .wy-icon { width: var(--wy-space-3); height: var(--wy-space-3); opacity: 0; }
.wy-radio__box::before { content: ""; width: calc(var(--wy-space-1) * 1.5); /* 6 */ height: calc(var(--wy-space-1) * 1.5); border-radius: 50%; background: currentColor; opacity: 0; }
.wy-check:hover .wy-check__box, .wy-radio:hover .wy-radio__box { border-color: var(--wy-border-strong); }
.wy-check__input:checked ~ .wy-check__box, .wy-radio__input:checked ~ .wy-radio__box { background: var(--wy-accent); border-color: var(--wy-accent); }
.wy-check__input:checked ~ .wy-check__box > .wy-icon, .wy-radio__input:checked ~ .wy-radio__box::before { opacity: 1; }
.wy-check__input:focus-visible ~ .wy-check__box, .wy-radio__input:focus-visible ~ .wy-radio__box, .wy-switch__input:focus-visible ~ .wy-switch__track { outline: 2px solid var(--wy-focus); outline-offset: 2px; }
.wy-check__input:disabled ~ *, .wy-radio__input:disabled ~ *, .wy-switch__input:disabled ~ * { color: var(--wy-text-disabled); cursor: not-allowed; }
.wy-check__input:disabled ~ .wy-check__box, .wy-radio__input:disabled ~ .wy-radio__box { background: var(--wy-surface-sunken); border-color: var(--wy-border); color: var(--wy-text-disabled); }
.wy-check .wy-help, .wy-radio .wy-help, .wy-switch .wy-help { display: block; margin-top: var(--wy-space-1); }

/* Switch: track 36 x 20, knob 16 (.wy-switch__knob), accent when on. */
.wy-switch__track {
  box-sizing: border-box;
  position: relative;
  display: inline-block;
  flex: none;
  width: calc(var(--wy-space-8) + var(--wy-space-1)); /* 36 */
  height: calc(var(--wy-space-4) + var(--wy-space-1)); /* 20 */
  border: 1px solid var(--wy-border-control);
  border-radius: var(--wy-radius-pill);
  background: var(--wy-surface-sunken);
  transition: background-color var(--wy-motion-fast) var(--wy-ease), border-color var(--wy-motion-fast) var(--wy-ease);
}
.wy-switch__knob {
  box-sizing: border-box;
  position: absolute;
  top: 1px;
  left: 1px;
  width: var(--wy-space-4);
  height: var(--wy-space-4);
  border: 1px solid var(--wy-surface); /* invisible ring; keeps the knob visible in forced colours */
  border-radius: 50%;
  background: var(--wy-border-control);
  transition: translate var(--wy-motion-fast) var(--wy-ease), background-color var(--wy-motion-fast) var(--wy-ease);
}
.wy-switch:hover .wy-switch__track { border-color: var(--wy-border-strong); }
.wy-switch__input:checked ~ .wy-switch__track { background: var(--wy-accent); border-color: var(--wy-accent); }
.wy-switch__input:checked ~ .wy-switch__track > .wy-switch__knob { translate: var(--wy-space-4) 0; background: var(--wy-text-on-accent); }
.wy-switch__input:disabled ~ .wy-switch__track { background: var(--wy-surface-sunken); border-color: var(--wy-border); }
.wy-switch__input:disabled ~ .wy-switch__track > .wy-switch__knob { background: var(--wy-border-strong); }

/* Forced colours: fills vanish, so state comes from system colours on the
   drawn parts (the only place system colour keywords are used). */
@media (forced-colors: active) {
  .wy-check__box, .wy-radio__box, .wy-switch__track { forced-color-adjust: none; background: Canvas; border-color: CanvasText; color: CanvasText; }
  .wy-check__input:checked ~ .wy-check__box, .wy-radio__input:checked ~ .wy-radio__box, .wy-switch__input:checked ~ .wy-switch__track { background: Highlight; border-color: Highlight; color: HighlightText; }
  .wy-switch__knob { forced-color-adjust: none; background: CanvasText; border-color: Canvas; }
  .wy-switch__input:checked ~ .wy-switch__track > .wy-switch__knob { background: HighlightText; border-color: Highlight; }
  .wy-check__input:disabled ~ .wy-check__box, .wy-radio__input:disabled ~ .wy-radio__box, .wy-switch__input:disabled ~ .wy-switch__track { border-color: GrayText; color: GrayText; }
}

/* ----------------------------------------------------------------------------
   4.4 Option card — .wy-option in a .wy-option-grid
   The radio is clipped; ::before draws the indicator so the checked state is
   a shape, not only a colour.
   -------------------------------------------------------------------------- */
.wy-option-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--wy-space-16) * 3 - var(--wy-space-3))), 1fr)); /* min 180 */ gap: var(--wy-space-3); }
.wy-option {
  box-sizing: border-box;
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--wy-space-3);
  row-gap: var(--wy-space-1);
  align-items: start;
  min-width: 0;
  padding: var(--wy-space-3) var(--wy-space-4);
  border: 1px solid var(--wy-border-control);
  border-radius: var(--wy-radius-lg);
  background: var(--wy-surface);
  color: var(--wy-text);
  cursor: pointer;
  transition: background-color var(--wy-motion-fast) var(--wy-ease), border-color var(--wy-motion-fast) var(--wy-ease);
}
.wy-option::before {
  content: "";
  grid-row: 1 / span 2;
  box-sizing: border-box;
  width: var(--wy-space-4);
  height: var(--wy-space-4);
  margin-top: calc((var(--wy-text-md) * var(--wy-leading) - var(--wy-space-4)) / 2);
  border: 1px solid var(--wy-border-control);
  border-radius: 50%;
  background: var(--wy-surface);
}
.wy-option__title { display: block; font-size: var(--wy-text-md); font-weight: var(--wy-weight-medium); line-height: var(--wy-leading); overflow-wrap: anywhere; }
.wy-option__meta { display: block; grid-column: 2; color: var(--wy-text-muted); font-size: var(--wy-text-sm); line-height: var(--wy-leading); }
.wy-option__tag { display: inline-block; grid-column: 2; justify-self: start; padding: 0 var(--wy-space-2); border: 1px solid var(--wy-border-strong); border-radius: var(--wy-radius-pill); color: var(--wy-text-muted); font-size: var(--wy-text-xs); font-weight: var(--wy-weight-medium); line-height: calc(var(--wy-space-4) + var(--wy-space-1) - 2px); /* 18 inside the border = 20 */ }
.wy-option:hover { border-color: var(--wy-border-strong); }
.wy-option:has(.wy-option__input:checked) { border-color: var(--wy-accent-border); background: var(--wy-accent-subtle); }
.wy-option:has(.wy-option__input:checked)::before { border-color: var(--wy-accent); background: var(--wy-accent); box-shadow: inset 0 0 0 calc(var(--wy-space-1) - 1px) var(--wy-surface); /* 3 px ring leaves the dot */ }
.wy-option:has(.wy-option__input:focus-visible) { outline: 2px solid var(--wy-focus); outline-offset: 2px; }
.wy-option--disabled, .wy-option:has(.wy-option__input:disabled) { background: var(--wy-surface-sunken); border-color: var(--wy-border); color: var(--wy-text-disabled); cursor: not-allowed; }
.wy-option--disabled .wy-option__meta, .wy-option:has(.wy-option__input:disabled) .wy-option__meta { color: var(--wy-text-disabled); }
.wy-option--disabled::before, .wy-option:has(.wy-option__input:disabled)::before { border-color: var(--wy-border); background: var(--wy-surface-sunken); }
@media (forced-colors: active) {
  .wy-option::before { forced-color-adjust: none; background: Canvas; border-color: CanvasText; }
  .wy-option:has(.wy-option__input:checked) { border-color: Highlight; }
  .wy-option:has(.wy-option__input:checked)::before { background: Highlight; border-color: Highlight; box-shadow: inset 0 0 0 calc(var(--wy-space-1) - 1px) Canvas; }
}

/* ----------------------------------------------------------------------------
   4.5 Dropdown menu — .wy-menu (JS toggles [hidden]; .is-open and .is-up on the root)
   -------------------------------------------------------------------------- */
.wy-menu { position: relative; display: inline-block; }
.wy-menu__list {
  position: absolute;
  top: calc(100% + var(--wy-space-1));
  right: 0;
  z-index: 20;
  min-width: calc(var(--wy-space-16) * 3 - var(--wy-space-3)); /* 180 */
  margin: 0;
  padding: var(--wy-space-1);
  border-radius: var(--wy-radius-lg);
  background: var(--wy-surface-raised);
  box-shadow: var(--wy-shadow);
  animation: wy-fade-in var(--wy-motion-fast) var(--wy-ease);
}
.wy-menu__list[hidden] { display: none; }
.wy-menu--left .wy-menu__list, .wy-menu__list--left { right: auto; left: 0; }
.wy-menu.is-up > .wy-menu__list { top: auto; bottom: calc(100% + var(--wy-space-1)); }
.wy-menu.is-open > .wy-btn { background: var(--wy-surface-sunken); }
.wy-menu__list form { margin: 0; }
.wy-menu__item {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--wy-space-2);
  width: 100%;
  min-height: var(--wy-space-8);
  margin: 0;
  padding: var(--wy-space-1) var(--wy-space-3);
  border: 0;
  border-radius: var(--wy-radius-md);
  background: transparent;
  color: var(--wy-text);
  font-family: inherit;
  font-size: var(--wy-text-sm);
  font-weight: var(--wy-weight-normal);
  line-height: var(--wy-leading-tight);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  appearance: none;
}
.wy-menu__item:hover, .wy-menu__item:focus-visible { background: var(--wy-surface-sunken); color: var(--wy-text); }
.wy-menu__item:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: calc(var(--wy-space-1) * -0.5); }
.wy-menu__item:active { background: var(--wy-border); }
.wy-menu__item > .wy-icon { color: var(--wy-text-muted); }
.wy-menu__item--danger, .wy-menu__item--danger > .wy-icon { color: var(--wy-danger-fg); }
.wy-menu__item--danger:hover, .wy-menu__item--danger:focus-visible { background: var(--wy-danger-bg); color: var(--wy-danger-fg); }
.wy-menu__item:disabled, .wy-menu__item[aria-disabled="true"] { background: transparent; color: var(--wy-text-disabled); cursor: not-allowed; }
.wy-menu__sep { height: 0; margin: var(--wy-space-1) 0; border: 0; border-top: 1px solid var(--wy-border); }
/* Non-interactive first line (the signed-in email in the account menu). */
.wy-menu__heading { max-width: calc(var(--wy-space-16) * 4); /* 256 */ padding: var(--wy-space-2) var(--wy-space-3) var(--wy-space-1); color: var(--wy-text-muted); font-size: var(--wy-text-xs); font-weight: var(--wy-weight-medium); line-height: var(--wy-leading); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@keyframes wy-fade-in { from { opacity: 0; } }

/* ----------------------------------------------------------------------------
   4.6 Page header — .wy-page-header
   -------------------------------------------------------------------------- */
.wy-page-header { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--wy-space-3) var(--wy-space-4); margin: 0 0 var(--wy-space-6); }
.wy-page-header__text { flex: 1 1 auto; min-width: 0; }
.wy-page-header__title { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wy-space-2); margin: 0; color: var(--wy-text); font-size: var(--wy-text-2xl); font-weight: var(--wy-weight-semibold); line-height: var(--wy-leading-tight); overflow-wrap: anywhere; }
.wy-page-header__desc { margin: var(--wy-space-1) 0 0; color: var(--wy-text-muted); font-size: var(--wy-text-md); line-height: var(--wy-leading); }
.wy-page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wy-space-2); }
@media (max-width: 639px) {
  .wy-page-header__actions { width: 100%; }
}

/* ----------------------------------------------------------------------------
   4.7 Card — .wy-card, .wy-card-grid
   -------------------------------------------------------------------------- */
.wy-card { display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--wy-border); border-radius: var(--wy-radius-lg); background: var(--wy-surface); color: var(--wy-text); }
.wy-card > :first-child { border-top-left-radius: inherit; border-top-right-radius: inherit; }
.wy-card > :last-child { border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; }
.wy-card__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--wy-space-2) var(--wy-space-3); padding: var(--wy-space-3) var(--wy-space-4); border-bottom: 1px solid var(--wy-border); }
.wy-card__title { margin: 0; color: var(--wy-text); font-size: var(--wy-text-lg); font-weight: var(--wy-weight-semibold); line-height: var(--wy-leading-tight); }
.wy-card__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wy-space-2); margin-left: auto; }
.wy-card__body { flex: 1 1 auto; min-width: 0; padding: var(--wy-space-4); }
.wy-card__body > :first-child { margin-top: 0; }
.wy-card__body > :last-child { margin-bottom: 0; }
.wy-card__footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--wy-space-2); padding: var(--wy-space-3) var(--wy-space-4); border-top: 1px solid var(--wy-border); }
.wy-card--flush > .wy-card__body { padding: 0; }
.wy-card--flush > .wy-card__body > .wy-table-wrap { border-radius: inherit; }
.wy-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--wy-space-16) * 4 + var(--wy-space-6))), 1fr)); /* min 280 */ gap: var(--wy-space-4); }
@media (min-width: 640px) {
  .wy-card__header, .wy-card__footer { padding-left: var(--wy-space-6); padding-right: var(--wy-space-6); }
  .wy-card__body { padding: var(--wy-space-6); }
  .wy-card--flush > .wy-card__body { padding: 0; }
}

/* ----------------------------------------------------------------------------
   4.8 Tabs — .wy-tabs, .wy-tab, .wy-tabpanel
   The list scrolls sideways without a scrollbar; JS sets [data-more] while
   tabs are hidden past the right edge and the fade cue shows (see 4.11).
   -------------------------------------------------------------------------- */
.wy-tabs { border-bottom: 1px solid var(--wy-border); margin: 0 0 var(--wy-space-4); }
.wy-tabs__list { position: relative; top: 1px; display: flex; align-items: stretch; gap: var(--wy-space-1); overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.wy-tabs__list::-webkit-scrollbar { display: none; }
.wy-tab {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  gap: var(--wy-space-2);
  flex: none;
  min-height: calc(var(--wy-space-8) + var(--wy-space-2)); /* 40 */
  margin: 0;
  padding: var(--wy-space-2) var(--wy-space-3);
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--wy-text-muted);
  font-family: inherit;
  font-size: var(--wy-text-sm);
  font-weight: var(--wy-weight-medium);
  line-height: var(--wy-leading-tight);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  appearance: none;
  transition: color var(--wy-motion-fast) var(--wy-ease), border-color var(--wy-motion-fast) var(--wy-ease);
}
.wy-tab:hover { color: var(--wy-text); }
.wy-tab[aria-selected="true"] { color: var(--wy-text); border-bottom-color: var(--wy-accent); }
.wy-tab:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: calc(var(--wy-space-1) * -0.5); border-radius: var(--wy-radius-sm); }
.wy-tab:disabled { color: var(--wy-text-disabled); cursor: not-allowed; }
.wy-tab__count, .wy-page-header__count { display: inline-flex; align-items: center; justify-content: center; min-width: calc(var(--wy-space-4) + var(--wy-space-1)); padding: 0 var(--wy-space-2); border-radius: var(--wy-radius-pill); font-size: var(--wy-text-xs); font-weight: var(--wy-weight-medium); line-height: calc(var(--wy-space-4) + var(--wy-space-1)); /* 20 */ font-variant-numeric: tabular-nums; }
.wy-tabpanel { min-width: 0; }
.wy-tabpanel[hidden] { display: none; }
.wy-tabpanel:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; border-radius: var(--wy-radius-sm); }
@media (forced-colors: active) {
  .wy-tab[aria-selected="true"] { border-bottom-color: Highlight; }
}

/* ----------------------------------------------------------------------------
   4.9 Breadcrumbs — .wy-breadcrumbs (template inserts .wy-breadcrumbs__sep icons)
   -------------------------------------------------------------------------- */
.wy-breadcrumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wy-space-1); margin: 0; padding: 0; list-style: none; font-size: var(--wy-text-sm); line-height: var(--wy-leading); }
.wy-breadcrumbs li { display: inline-flex; align-items: center; gap: var(--wy-space-1); min-width: 0; color: var(--wy-text-muted); }
.wy-breadcrumbs a { color: var(--wy-text-muted); text-decoration: none; border-radius: var(--wy-radius-sm); }
.wy-breadcrumbs a:hover { color: var(--wy-text); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.wy-breadcrumbs a:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; }
.wy-breadcrumbs [aria-current="page"] { color: var(--wy-text); font-weight: var(--wy-weight-medium); overflow: hidden; white-space: nowrap; }
/* The current label is its own (blockified) flex item so text-overflow can draw the ellipsis. */
.wy-breadcrumbs__current { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wy-breadcrumbs__sep { color: var(--wy-text-disabled); }

/* ----------------------------------------------------------------------------
   4.10 Dialog and sheet — .wy-dialog (native dialog), --lg, --sheet,
        --sheet-left, --confirm. JS: [data-wy-open] calls showModal(),
        [data-wy-close] closes; html.wy-scroll-lock while one is open.
   -------------------------------------------------------------------------- */
.wy-dialog {
  box-sizing: border-box;
  width: min(calc(var(--wy-space-16) * 7.5), calc(100% - var(--wy-space-8))); /* 480, else 16 margins */
  max-width: 100%;
  max-height: calc(100% - var(--wy-space-8));
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--wy-radius-lg);
  background: var(--wy-surface-raised);
  color: var(--wy-text);
  box-shadow: var(--wy-shadow);
  font-size: var(--wy-text-md);
  line-height: var(--wy-leading);
}
.wy-dialog[open] { display: flex; flex-direction: column; animation: wy-fade-in var(--wy-motion-fast) var(--wy-ease); }
.wy-dialog::backdrop { background: var(--wy-overlay); }
.wy-dialog--lg { width: min(calc(var(--wy-space-16) * 10), calc(100% - var(--wy-space-8))); /* 640 */ }
.wy-dialog__header { display: flex; align-items: center; justify-content: space-between; gap: var(--wy-space-3); padding: var(--wy-space-4) var(--wy-space-4) var(--wy-space-3); border-bottom: 1px solid var(--wy-border); }
.wy-dialog__title { min-width: 0; margin: 0; color: var(--wy-text); font-size: var(--wy-text-lg); font-weight: var(--wy-weight-semibold); line-height: var(--wy-leading-tight); overflow-wrap: anywhere; }
.wy-dialog__body { flex: 1 1 auto; min-height: 0; padding: var(--wy-space-4); overflow-y: auto; overscroll-behavior: contain; }
.wy-dialog__body > :first-child { margin-top: 0; }
.wy-dialog__body > :last-child { margin-bottom: 0; }
.wy-dialog__footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--wy-space-2); padding: var(--wy-space-3) var(--wy-space-4) var(--wy-space-4); border-top: 1px solid var(--wy-border); }
@media (min-width: 640px) {
  .wy-dialog__header, .wy-dialog__body, .wy-dialog__footer { padding-left: var(--wy-space-6); padding-right: var(--wy-space-6); }
}
/* Sheet: docked to the right edge, full height, slides in over --wy-motion.
   --sheet-left docks to the left edge (the sidebar drawer below 1024). */
.wy-dialog--sheet { width: min(calc(var(--wy-space-12) * 7.5), 100%); /* 360 */ height: 100%; max-height: 100%; margin: 0 0 0 auto; border-radius: 0; }
.wy-dialog--sheet[open] { animation: wy-sheet-in var(--wy-motion) var(--wy-ease); }
.wy-dialog--sheet.wy-dialog--sheet-left { margin: 0 auto 0 0; }
.wy-dialog--sheet.wy-dialog--sheet-left[open] { animation-name: wy-sheet-in-left; }
.wy-dialog--sheet > .wy-dialog__body { flex: 1 1 auto; }
.wy-scroll-lock { overflow: hidden; }
@media (max-width: 479px) {
  .wy-dialog--sheet { width: 100%; }
}
@keyframes wy-sheet-in { from { translate: 100% 0; } }
@keyframes wy-sheet-in-left { from { translate: -100% 0; } }
/* Type-the-name confirm: JS keeps [data-wy-confirm-submit] disabled until the
   input matches; the field just needs room under the body copy. */
.wy-dialog--confirm .wy-dialog__body > .wy-field { margin-top: var(--wy-space-4); }
.wy-dialog--confirm [data-wy-confirm-name] { font-family: var(--wy-font-mono); }

/* ----------------------------------------------------------------------------
   4.11 Table — .wy-table-wrap, .wy-table, --stack, __sort, __num, __actions,
        __empty, __loading, .is-selected
   -------------------------------------------------------------------------- */
.wy-table-wrap { position: relative; display: flex; align-items: flex-start; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; background: var(--wy-surface); }
/* While a row menu is open the wrap stops being a scroll container (x is
   clipped, y visible) so the menu can hang below the last rows unclipped. */
.wy-table-wrap:has(.wy-menu.is-open) { overflow-x: clip; overflow-y: visible; }
/* Scroll fade cue for the table wrap and the tab list: a zero-width sticky
   pseudo at the right edge whose blurred shadow, in the background colour,
   softens the last visible column while JS keeps [data-more] set. */
.wy-table-wrap[data-more]::after, .wy-tabs__list[data-more]::after { content: ""; position: sticky; right: 0; z-index: 2; flex: none; align-self: stretch; width: 0; box-shadow: 0 0 var(--wy-space-6) var(--wy-space-3) var(--wy-surface); pointer-events: none; }
.wy-tabs__list[data-more]::after { box-shadow: 0 0 var(--wy-space-6) var(--wy-space-3) var(--wy-bg); }
.wy-table { width: 100%; flex: none; margin: 0; border-collapse: collapse; border-spacing: 0; color: var(--wy-text); font-size: var(--wy-text-sm); line-height: var(--wy-leading); }
.wy-table caption { padding: var(--wy-space-3) var(--wy-space-4); color: var(--wy-text-muted); font-size: var(--wy-text-sm); text-align: left; caption-side: top; }
.wy-table th, .wy-table td { box-sizing: border-box; padding: var(--wy-space-1) var(--wy-space-2); border-bottom: 1px solid var(--wy-border); text-align: left; vertical-align: middle; }
.wy-table th:first-child, .wy-table td:first-child { padding-left: var(--wy-space-4); }
.wy-table th:last-child, .wy-table td:last-child { padding-right: var(--wy-space-4); }
.wy-table thead th { position: sticky; top: 0; z-index: 1; height: var(--wy-space-8); background: var(--wy-surface-sunken); border-bottom: 1px solid var(--wy-border-strong); color: var(--wy-text-muted); font-size: var(--wy-text-xs); font-weight: var(--wy-weight-medium); line-height: var(--wy-leading-tight); white-space: nowrap; }
.wy-table td { height: calc(var(--wy-space-8) + var(--wy-space-2)); /* 40 */ }
.wy-table--comfortable td { height: var(--wy-space-12); /* 48 */ padding-top: var(--wy-space-2); padding-bottom: var(--wy-space-2); }
.wy-table tbody tr { transition: background-color var(--wy-motion-fast) var(--wy-ease); }
.wy-table tbody tr:hover { background: var(--wy-surface-sunken); }
.wy-table tbody tr.is-selected { background: var(--wy-accent-subtle); }
.wy-card--flush .wy-table tbody tr:last-child td { border-bottom: 0; }
/* Identifiers (mono values) and relative times never break inside a cell, and a value
   that sits in a .wy-row with its copy button stays on one line; the stacked layout
   below lifts both. Cells keep 8 px sides (16 at the table edges) so a nine-column
   list fits beside the sidebar at 1440. */
.wy-table td.wy-mono, .wy-table td .wy-mono, .wy-table td > time { white-space: nowrap; }
.wy-table td > .wy-row { flex-wrap: nowrap; }
.wy-table__num { text-align: right; font-variant-numeric: tabular-nums; }
.wy-table__actions { text-align: right; white-space: nowrap; }
.wy-table__actions > .wy-row, .wy-table__actions > .wy-btn-group { justify-content: flex-end; flex-wrap: nowrap; }
/* Sortable headers: the icon is arrow-up-down muted, arrow-up or arrow-down in text colour. */
.wy-table__sort { display: inline-flex; align-items: center; gap: var(--wy-space-1); margin: 0; padding: 0; border: 0; border-radius: var(--wy-radius-sm); background: transparent; color: inherit; font: inherit; text-decoration: none; cursor: pointer; appearance: none; }
.wy-table__sort:hover { color: var(--wy-text); }
.wy-table__sort:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; }
.wy-table th[aria-sort] .wy-icon { color: var(--wy-text-muted); }
.wy-table th[aria-sort="ascending"] .wy-table__sort, .wy-table th[aria-sort="descending"] .wy-table__sort, .wy-table th[aria-sort="ascending"] .wy-icon, .wy-table th[aria-sort="descending"] .wy-icon { color: var(--wy-text); }
/* Empty and loading rows span all columns. */
.wy-table__empty td, .wy-table__loading td { height: auto; padding: 0; }
.wy-table__loading td { padding: var(--wy-space-4); }
.wy-table__loading .wy-skeleton + .wy-skeleton { margin-top: var(--wy-space-3); }
.wy-table tbody tr.wy-table__empty:hover, .wy-table tbody tr.wy-table__loading:hover { background: transparent; }
/* Stacked rows below 640: each cell shows its data-label. */
@media (max-width: 639px) {
  .wy-table--stack, .wy-table--stack tbody, .wy-table--stack tr { display: block; }
  .wy-table--stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .wy-table--stack tr { padding: var(--wy-space-2) 0; border-bottom: 1px solid var(--wy-border); }
  .wy-table--stack td { display: flex; align-items: baseline; justify-content: space-between; gap: var(--wy-space-3); height: auto; padding: var(--wy-space-1) var(--wy-space-4); border: 0; text-align: right; }
  .wy-table--stack td[data-label]::before { content: attr(data-label); flex: none; min-width: calc(var(--wy-space-16) + var(--wy-space-8)); /* 96 */ color: var(--wy-text-muted); font-size: var(--wy-text-xs); font-weight: var(--wy-weight-medium); text-align: left; }
  .wy-table--stack td:not([data-label]) { justify-content: flex-end; }
  .wy-table--stack td.wy-mono, .wy-table--stack td .wy-mono, .wy-table--stack td > time { white-space: normal; }
  .wy-table--stack td > .wy-row { flex-wrap: wrap; justify-content: flex-end; }
  .wy-table--stack .wy-table__empty td, .wy-table--stack .wy-table__loading td { display: block; padding: 0; text-align: left; }
  .wy-table--stack .wy-table__loading td { padding: var(--wy-space-4); }
  .wy-table--stack .wy-table__empty::before, .wy-table--stack .wy-table__loading::before { content: none; }
}

/* ----------------------------------------------------------------------------
   4.12 Status badge — .wy-badge with --success, --warning, --danger, --info,
        --neutral. A dot and a label, never colour alone.
   -------------------------------------------------------------------------- */
.wy-badge {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  gap: calc(var(--wy-space-1) * 1.5); /* 6 */
  min-height: calc(var(--wy-space-4) + var(--wy-space-1)); /* 20 */
  padding: 0 var(--wy-space-2);
  border: 1px solid var(--wy-neutral-border);
  border-radius: var(--wy-radius-pill);
  background: var(--wy-neutral-bg);
  color: var(--wy-neutral-fg);
  font-family: var(--wy-font-sans);
  font-size: var(--wy-text-xs);
  font-weight: var(--wy-weight-medium);
  line-height: var(--wy-leading-tight);
  white-space: nowrap;
  vertical-align: middle;
}
.wy-badge__dot { flex: none; width: calc(var(--wy-space-1) * 1.5); /* 6 */ height: calc(var(--wy-space-1) * 1.5); border-radius: 50%; background: currentColor; }
.wy-badge__dot--pulse { animation: wy-pulse 2.4s var(--wy-ease) infinite; }
.wy-badge > .wy-icon { width: var(--wy-space-3); height: var(--wy-space-3); }
.wy-badge--success { background: var(--wy-success-bg); border-color: var(--wy-success-border); color: var(--wy-success-fg); }
.wy-badge--warning { background: var(--wy-warning-bg); border-color: var(--wy-warning-border); color: var(--wy-warning-fg); }
.wy-badge--danger { background: var(--wy-danger-bg); border-color: var(--wy-danger-border); color: var(--wy-danger-fg); }
.wy-badge--info { background: var(--wy-info-bg); border-color: var(--wy-info-border); color: var(--wy-info-fg); }
/* Neutral tone (also the tab and page header counts) from the neutral triple
   in tokens.css: neutral-100 on text-muted in light, neutral-800 on
   neutral-300 in dark. */
.wy-badge--neutral, .wy-tab__count, .wy-page-header__count { background: var(--wy-neutral-bg); color: var(--wy-neutral-fg); }
.wy-badge--neutral { border-color: var(--wy-neutral-border); }
@keyframes wy-pulse { 50% { opacity: 0.4; } }

/* ----------------------------------------------------------------------------
   4.13 Key-value — .wy-kv (dl), .wy-kv__row (dt + dd), .wy-kv__note
   -------------------------------------------------------------------------- */
.wy-kv { margin: 0; container-type: inline-size; } /* rows go two-column by the list's own width, not the viewport */
.wy-kv__row { display: grid; grid-template-columns: 1fr; gap: var(--wy-space-1) var(--wy-space-4); padding: var(--wy-space-3) 0; border-bottom: 1px solid var(--wy-border); }
.wy-kv__row:last-child { border-bottom: 0; }
.wy-kv__row > dt { margin: 0; color: var(--wy-text-muted); line-height: var(--wy-leading); }
.wy-kv__row > dd { min-width: 0; margin: 0; color: var(--wy-text); line-height: var(--wy-leading); overflow-wrap: anywhere; }
.wy-kv__note { display: block; margin-top: var(--wy-space-1); color: var(--wy-text-muted); font-size: var(--wy-text-xs); }
@container (min-width: 480px) {
  .wy-kv__row { grid-template-columns: calc(var(--wy-space-16) * 2.5) 1fr; /* 160 */ }
}

/* ----------------------------------------------------------------------------
   4.14 Stat — .wy-stat in a .wy-stat-row; delta tone carries an arrow icon
   -------------------------------------------------------------------------- */
.wy-stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--wy-space-16) * 2 + var(--wy-space-3))), 1fr)); /* min 140 */ gap: var(--wy-space-4); }
.wy-stat { display: flex; flex-direction: column; gap: var(--wy-space-1); min-width: 0; }
.wy-stat__label { color: var(--wy-text-muted); font-size: var(--wy-text-sm); line-height: var(--wy-leading); }
.wy-stat__value { color: var(--wy-text); font-size: var(--wy-text-2xl); font-weight: var(--wy-weight-semibold); line-height: var(--wy-leading-tight); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.wy-stat__delta { display: inline-flex; align-items: center; gap: var(--wy-space-1); color: var(--wy-text-muted); font-size: var(--wy-text-xs); line-height: var(--wy-leading); }
.wy-stat__delta--up { color: var(--wy-success-fg); }
.wy-stat__delta--down { color: var(--wy-danger-fg); }

/* ----------------------------------------------------------------------------
   4.15 Quota bar — .wy-quota; --warn from 80 percent, --over from 100
   -------------------------------------------------------------------------- */
.wy-quota { display: flex; flex-direction: column; gap: var(--wy-space-2); min-width: 0; }
.wy-quota__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--wy-space-3); font-size: var(--wy-text-sm); line-height: var(--wy-leading); }
.wy-quota__label { color: var(--wy-text); font-weight: var(--wy-weight-medium); }
.wy-quota__value { color: var(--wy-text-muted); font-variant-numeric: tabular-nums; }
.wy-quota__bar { height: calc(var(--wy-space-3) / 2); /* 6 */ border-radius: var(--wy-radius-pill); background: var(--wy-border); /* neutral-200 light, neutral-800 dark */ overflow: hidden; }
.wy-quota__fill { height: 100%; max-width: 100%; border-radius: var(--wy-radius-pill); background: var(--wy-accent); transition: width var(--wy-motion) var(--wy-ease); }
.wy-quota--warn .wy-quota__fill { background: var(--wy-warning-fg); }
.wy-quota--over .wy-quota__fill { background: var(--wy-danger-fg); }
.wy-quota--over .wy-quota__value { color: var(--wy-danger-fg); }
@media (forced-colors: active) {
  .wy-quota__bar { border: 1px solid CanvasText; }
  .wy-quota__fill { forced-color-adjust: none; background: Highlight; }
}

/* ----------------------------------------------------------------------------
   4.16 Code block .wy-code, command .wy-cmd, kbd .wy-kbd
   -------------------------------------------------------------------------- */
.wy-code { display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--wy-border); border-radius: var(--wy-radius-lg); background: var(--wy-surface-sunken); color: var(--wy-text); font-family: var(--wy-font-mono); font-size: var(--wy-text-sm); line-height: var(--wy-leading); }
.wy-code__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--wy-space-2); padding: var(--wy-space-1) var(--wy-space-1) var(--wy-space-1) var(--wy-space-4); border-bottom: 1px solid var(--wy-border); }
.wy-code__lang { color: var(--wy-text-muted); font-size: var(--wy-text-xs); }
.wy-code pre { margin: 0; padding: var(--wy-space-4); overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; font: inherit; tab-size: 2; }
.wy-code pre:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: calc(var(--wy-space-1) * -0.5); }
.wy-code code, .wy-cmd code { font-family: inherit; font-size: inherit; }
.wy-cmd { display: inline-flex; align-items: center; gap: var(--wy-space-1); max-width: 100%; padding: 0 var(--wy-space-1) 0 var(--wy-space-2); border: 1px solid var(--wy-border); border-radius: var(--wy-radius-md); background: var(--wy-surface-sunken); color: var(--wy-text); font-family: var(--wy-font-mono); font-size: var(--wy-text-sm); line-height: var(--wy-leading); vertical-align: middle; }
.wy-cmd code { min-width: 0; padding: var(--wy-space-1) 0; overflow-x: auto; scrollbar-width: none; white-space: nowrap; }
/* Small icon-only buttons inside a command or a toast. */
.wy-cmd__copy, .wy-toast__close { display: inline-flex; align-items: center; justify-content: center; flex: none; width: var(--wy-space-6); height: var(--wy-space-6); margin: 0; padding: 0; border: 0; border-radius: var(--wy-radius-sm); background: transparent; color: var(--wy-text-muted); cursor: pointer; appearance: none; }
.wy-cmd__copy:hover, .wy-toast__close:hover { background: var(--wy-border); color: var(--wy-text); }
.wy-cmd__copy:focus-visible, .wy-toast__close:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; }
.wy-cmd__copy[data-copied], .wy-btn[data-copied] { color: var(--wy-success-fg); }
.wy-kbd { display: inline-block; min-width: calc(var(--wy-space-4) + var(--wy-space-1)); padding: 0 var(--wy-space-1); border: 1px solid var(--wy-border-strong); border-bottom-width: 2px; border-radius: var(--wy-radius-sm); background: var(--wy-surface); color: var(--wy-text); font-family: var(--wy-font-mono); font-size: var(--wy-text-xs); line-height: calc(var(--wy-space-4) + var(--wy-space-1) - 2px); /* 18 */ text-align: center; vertical-align: middle; }

/* ----------------------------------------------------------------------------
   4.17 Toast — .wy-toasts region (one per page; bottom right, top on phones)
        and .wy-toast with the badge tones on the icon
   -------------------------------------------------------------------------- */
.wy-toasts { position: fixed; top: var(--wy-space-2); right: var(--wy-space-2); left: var(--wy-space-2); z-index: 30; display: flex; flex-direction: column; gap: var(--wy-space-2); pointer-events: none; }
@media (min-width: 640px) {
  .wy-toasts { top: auto; left: auto; right: var(--wy-space-4); bottom: var(--wy-space-4); width: min(calc(var(--wy-space-12) * 7.5), calc(100% - var(--wy-space-8))); /* 360 */ }
}
.wy-toast {
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  gap: var(--wy-space-2);
  width: 100%;
  padding: var(--wy-space-3) var(--wy-space-3) var(--wy-space-3) var(--wy-space-4);
  border-radius: var(--wy-radius-lg);
  background: var(--wy-surface-raised);
  color: var(--wy-text);
  box-shadow: var(--wy-shadow);
  font-size: var(--wy-text-sm);
  line-height: var(--wy-leading);
  pointer-events: auto;
  animation: wy-toast-in var(--wy-motion) var(--wy-ease);
}
.wy-toast[hidden] { display: none; }
.wy-toast > .wy-icon { flex: none; margin-top: calc((var(--wy-text-sm) * var(--wy-leading) - var(--wy-space-4)) / 2); color: var(--wy-text-muted); }
.wy-toast__text, .wy-toast > span { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.wy-toast__close { flex: none; }
.wy-toast--success > .wy-icon { color: var(--wy-success-fg); }
.wy-toast--warning > .wy-icon { color: var(--wy-warning-fg); }
.wy-toast--danger > .wy-icon { color: var(--wy-danger-fg); }
.wy-toast--info > .wy-icon { color: var(--wy-info-fg); }
@keyframes wy-toast-in { from { opacity: 0; translate: 0 var(--wy-space-2); } }

/* ----------------------------------------------------------------------------
   4.18 Tooltip — [data-wy-tip] inside .wy-root, CSS only; above by default,
        .wy-tip--below flips it. The trigger keeps its own accessible name;
        the slash alternative text keeps the pseudo out of it. Hidden tips are
        display: none (a visibility-hidden box would still widen a scrolling
        table wrap); the fade uses a discrete display transition and
        @starting-style, so older browsers show and hide them instantly.
   -------------------------------------------------------------------------- */
.wy-root [data-wy-tip] { position: relative; }
.wy-root [data-wy-tip]::after {
  content: attr(data-wy-tip) / "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  z-index: 20;
  display: none;
  width: max-content;
  max-width: calc(var(--wy-space-16) * 4); /* 256 */
  margin-bottom: var(--wy-space-1);
  padding: var(--wy-space-1) var(--wy-space-2);
  border-radius: var(--wy-radius-sm);
  background: var(--wy-text); /* inverse surface: reverses with the theme */
  color: var(--wy-bg);
  font-family: var(--wy-font-sans);
  font-size: var(--wy-text-xs);
  font-weight: var(--wy-weight-normal);
  line-height: var(--wy-leading);
  text-align: center;
  white-space: normal;
  translate: -50% 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--wy-motion-fast) var(--wy-ease), display var(--wy-motion-fast) allow-discrete;
}
.wy-root [data-wy-tip]:hover::after, .wy-root [data-wy-tip]:focus-visible::after { display: block; opacity: 1; }
@starting-style {
  .wy-root [data-wy-tip]:hover::after, .wy-root [data-wy-tip]:focus-visible::after { opacity: 0; }
}
.wy-root .wy-tip--below::after { top: 100%; bottom: auto; margin-top: var(--wy-space-1); margin-bottom: 0; }

/* ----------------------------------------------------------------------------
   4.19 Empty state — .wy-empty: one sentence, one action
   -------------------------------------------------------------------------- */
.wy-empty { display: flex; flex-direction: column; align-items: center; gap: var(--wy-space-3); padding: var(--wy-space-12) var(--wy-space-4); color: var(--wy-text-muted); text-align: center; }
.wy-empty__icon { color: var(--wy-text-disabled); }
.wy-empty__text { max-width: calc(var(--wy-space-16) * 6); /* 384 */ margin: 0; color: var(--wy-text-muted); font-size: var(--wy-text-md); line-height: var(--wy-leading); }
.wy-empty > .wy-btn { margin-top: var(--wy-space-1); }

/* ----------------------------------------------------------------------------
   4.20 Skeleton — .wy-skeleton; the container sets aria-busy while it shows
   -------------------------------------------------------------------------- */
.wy-skeleton { display: block; width: 60%; height: var(--wy-text-md); /* 14 */ border-radius: var(--wy-radius-sm); background: var(--wy-border); /* neutral-200 light, neutral-800 dark */ animation: wy-pulse 1.8s var(--wy-ease) infinite; }
.wy-skeleton--w-40 { width: 40%; }
.wy-skeleton--w-80 { width: 80%; }
.wy-skeleton--block { width: 100%; height: 100%; min-height: var(--wy-space-12); }
.wy-skeleton + .wy-skeleton { margin-top: var(--wy-space-2); }

/* ----------------------------------------------------------------------------
   4.21 Icon — .wy-icon from the sprite; --sm 12, default 16, --lg 20, --xl 24
   -------------------------------------------------------------------------- */
.wy-icon { display: inline-block; flex: none; width: var(--wy-space-4); height: var(--wy-space-4); vertical-align: middle; }
.wy-icon--sm { width: var(--wy-space-3); height: var(--wy-space-3); }
.wy-icon--lg { width: calc(var(--wy-space-4) + var(--wy-space-1)); height: calc(var(--wy-space-4) + var(--wy-space-1)); }
.wy-icon--xl { width: var(--wy-space-6); height: var(--wy-space-6); }

/* ----------------------------------------------------------------------------
   4.22 Logo — .wy-logo from the logo() macro: .wy-logo__mark + .wy-logo__text
   -------------------------------------------------------------------------- */
.wy-logo { display: inline-flex; align-items: center; gap: var(--wy-space-2); color: var(--wy-text); font-size: var(--wy-text-md); font-weight: var(--wy-weight-semibold); line-height: var(--wy-leading-tight); text-decoration: none; white-space: nowrap; }
.wy-logo:hover { color: var(--wy-text); }
.wy-logo:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; border-radius: var(--wy-radius-sm); }
.wy-logo__mark { flex: none; color: var(--wy-accent); }
.wy-logo__text { color: inherit; }

/* ----------------------------------------------------------------------------
   4.23 Utilities — the only ones; layout belongs to components
   -------------------------------------------------------------------------- */
.wy-mono { font-family: var(--wy-font-mono); font-variant-numeric: tabular-nums; }
.wy-muted { color: var(--wy-text-muted); }
.wy-visually-hidden { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.wy-stack { display: flex; flex-direction: column; gap: var(--wy-space-4); }
.wy-stack--tight { gap: var(--wy-space-2); }
.wy-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wy-space-2); min-width: 0; }
.wy-spacer { margin-left: auto; }
.wy-text-sm { font-size: var(--wy-text-sm); }
.wy-text-xs { font-size: var(--wy-text-xs); }

/* ----------------------------------------------------------------------------
   4.24 Notice — .wy-notice, block-level inline message with --info (default),
        --success, --warning, --danger from the semantic pairs. Icon slot first,
        then .wy-notice__body, then the optional .wy-notice__actions, which wrap
        under the body when there is no room. Toasts are for transient feedback;
        a notice stays in the page (the maintenance banner, form-level errors).
   -------------------------------------------------------------------------- */
.wy-notice { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--wy-space-3); padding: var(--wy-space-3) var(--wy-space-4); border: 1px solid var(--wy-info-border); border-radius: var(--wy-radius-lg); background: var(--wy-info-bg); color: var(--wy-text); font-size: var(--wy-text-sm); line-height: var(--wy-leading); }
.wy-notice > .wy-icon { flex: none; margin-top: calc((var(--wy-text-sm) * var(--wy-leading) - var(--wy-space-4)) / 2); color: var(--wy-info-fg); }
.wy-notice__body { flex: 1 1 calc(var(--wy-space-16) * 3); /* 192: below this the actions wrap */ min-width: 0; overflow-wrap: anywhere; }
.wy-notice__body > :first-child { margin-top: 0; }
.wy-notice__body > :last-child { margin-bottom: 0; }
.wy-notice__actions { display: flex; flex: none; flex-wrap: wrap; align-items: center; gap: var(--wy-space-2); }
.wy-notice--success { background: var(--wy-success-bg); border-color: var(--wy-success-border); }
.wy-notice--success > .wy-icon { color: var(--wy-success-fg); }
.wy-notice--warning { background: var(--wy-warning-bg); border-color: var(--wy-warning-border); }
.wy-notice--warning > .wy-icon { color: var(--wy-warning-fg); }
.wy-notice--danger { background: var(--wy-danger-bg); border-color: var(--wy-danger-border); }
.wy-notice--danger > .wy-icon { color: var(--wy-danger-fg); }

/* ----------------------------------------------------------------------------
   5. Reduced motion — durations collapse through the motion tokens; the
      pulses, the spinner and the entrance animations stop outright.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .wy-root *, .wy-root *::before, .wy-root *::after { transition-duration: 0s; animation-duration: 0s; }
  .wy-badge__dot--pulse, .wy-skeleton, .wy-btn__spinner, .wy-dialog[open], .wy-dialog--sheet[open], .wy-menu__list, .wy-toast { animation: none; }
}

/* ----------------------------------------------------------------------------
   6. Shell (components/shell.html; base.html wraps every signed-in page in it)
   <div class="wy-shell"><aside class="wy-sidebar" id="wy-sidebar">…</aside>
   <div class="wy-shell__main"><header class="wy-topbar">…</header>
   <main class="wy-content" id="main">…</main></div></div>
   Nav: .wy-nav > .wy-nav__group + ul.wy-nav__list > li > a.wy-nav__item
   (icon + .wy-nav__label). Below 1024 the static sidebar is hidden and the
   same nav renders inside <dialog class="wy-dialog wy-dialog--sheet
   wy-dialog--sheet-left"> opened by .wy-topbar__menu. .wy-skip comes first.
   Topbar: menu button, breadcrumbs (the current crumb shrinks with an
   ellipsis), spacer, .wy-topbar__docs (label hidden below 640), account menu.
   Anonymous and chromeless pages use .wy-auth instead (section 6.1).
   -------------------------------------------------------------------------- */
.wy-skip { position: absolute; top: 0; left: 0; z-index: 40; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.wy-skip:focus, .wy-skip:focus-visible { position: fixed; top: var(--wy-space-2); left: var(--wy-space-2); width: auto; height: auto; padding: var(--wy-space-2) var(--wy-space-3); clip: auto; clip-path: none; border-radius: var(--wy-radius-md); background: var(--wy-surface-raised); color: var(--wy-text); box-shadow: var(--wy-shadow); font-size: var(--wy-text-sm); font-weight: var(--wy-weight-medium); text-decoration: none; outline: 2px solid var(--wy-focus); outline-offset: 2px; }

.wy-shell { display: flex; min-height: 100vh; }
.wy-sidebar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: none;
  flex: none;
  flex-direction: column;
  width: var(--wy-sidebar);
  height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-right: 1px solid var(--wy-border);
  background: var(--wy-surface);
  transition: width var(--wy-motion) var(--wy-ease);
}
.wy-sidebar__header { display: flex; align-items: center; flex: none; height: var(--wy-topbar); padding: 0 var(--wy-space-4); border-bottom: 1px solid var(--wy-border); }
.wy-sidebar__brand { display: inline-flex; border-radius: var(--wy-radius-sm); color: inherit; text-decoration: none; }
.wy-sidebar__brand:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: 2px; }
.wy-sidebar__footer { margin-top: auto; padding: var(--wy-space-2); border-top: 1px solid var(--wy-border); }
.wy-nav { display: flex; flex-direction: column; padding: var(--wy-space-2); }
.wy-nav__list { margin: 0; padding: 0; list-style: none; }
.wy-nav__list > li + li { margin-top: var(--wy-space-1); }
.wy-dialog .wy-nav { padding: 0; }
.wy-nav__group { margin: var(--wy-space-4) 0 var(--wy-space-1); padding: 0 var(--wy-space-3); color: var(--wy-text-muted); font-size: var(--wy-text-xs); font-weight: var(--wy-weight-medium); line-height: var(--wy-leading); white-space: nowrap; }
.wy-nav__group:first-child { margin-top: var(--wy-space-1); }
.wy-nav__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--wy-space-2);
  min-height: var(--wy-space-8); /* 32 */
  padding: var(--wy-space-1) var(--wy-space-3);
  border-radius: var(--wy-radius-md);
  color: var(--wy-text-muted);
  font-size: var(--wy-text-sm);
  font-weight: var(--wy-weight-medium);
  line-height: var(--wy-leading-tight);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--wy-motion-fast) var(--wy-ease), color var(--wy-motion-fast) var(--wy-ease);
}
.wy-nav__item:hover { background: var(--wy-surface-sunken); color: var(--wy-text); }
.wy-nav__item:focus-visible { outline: 2px solid var(--wy-focus); outline-offset: calc(var(--wy-space-1) * -0.5); }
.wy-nav__item[aria-current="page"] { background: var(--wy-accent-subtle); color: var(--wy-accent); }
.wy-nav__item[aria-current="page"]::before { content: ""; position: absolute; top: var(--wy-space-1); bottom: var(--wy-space-1); left: 0; width: 2px; border-radius: var(--wy-radius-pill); background: var(--wy-accent); }
.wy-nav__item > .wy-icon { flex: none; }
.wy-nav__item[data-wy-tip]::after { content: none; } /* the label is visible; only the rail needs the tip */
/* Rail: icons only; labels stay in the tree for screen readers and the tips
   show to the right (overflow stays visible so they are not clipped). */
.wy-sidebar--rail { width: var(--wy-sidebar-rail); overflow: visible; }
.wy-sidebar--rail .wy-nav__item[data-wy-tip]::after { content: attr(data-wy-tip) / ""; top: 50%; bottom: auto; left: 100%; margin: 0 0 0 var(--wy-space-2); translate: 0 -50%; }
.wy-sidebar--rail .wy-nav__group, .wy-sidebar--rail .wy-nav__label, .wy-sidebar--rail .wy-logo__text { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.wy-sidebar--rail .wy-nav__item { justify-content: center; padding: 0; }
.wy-sidebar--rail .wy-nav__group + .wy-nav__list { margin-top: var(--wy-space-2); padding-top: var(--wy-space-2); border-top: 1px solid var(--wy-border); } /* the hidden group label leaves a hairline */
.wy-sidebar--rail .wy-sidebar__header { justify-content: center; padding: 0; }
.wy-sidebar--rail .wy-sidebar__footer { display: flex; justify-content: center; }
.wy-sidebar--rail .wy-sidebar__toggle > .wy-icon { rotate: 180deg; } /* the panel icon points back out */

.wy-shell__main { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.wy-topbar { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; gap: var(--wy-space-3); flex: none; height: var(--wy-topbar); padding: 0 var(--wy-space-4); border-bottom: 1px solid var(--wy-border); background: var(--wy-surface); }
.wy-topbar .wy-breadcrumbs { flex: 1 1 auto; min-width: 0; }
.wy-topbar .wy-breadcrumbs ol { flex-wrap: nowrap; overflow: hidden; }
.wy-topbar .wy-breadcrumbs li { flex: none; }
.wy-topbar .wy-breadcrumbs li:last-child { flex: 0 1 auto; }
.wy-topbar > .wy-spacer { flex: none; }
.wy-topbar__docs { flex: none; }
.wy-content { flex: 1 1 auto; width: 100%; min-width: 0; max-width: var(--wy-content-max); margin: 0 auto; padding: var(--wy-space-6); }
/* The maintenance banner: base.html keeps the literal class="maint" (tests
   pin it) on a wrapper around the .wy-notice, so the page-level spacing hangs
   off the wrapper rather than off the notice primitive. */
.wy-content > .maint { margin-bottom: var(--wy-space-6); }
@media (max-width: 639px) {
  .wy-topbar__docs { width: var(--wy-space-8); padding: 0; }
  .wy-topbar__docs-label { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
}
@media (min-width: 1024px) {
  .wy-shell { position: relative; }
  .wy-shell::before { content: ""; position: absolute; inset: 0 auto 0 0; width: var(--wy-sidebar); border-right: 1px solid var(--wy-border); background: var(--wy-surface); transition: width var(--wy-motion) var(--wy-ease); }
  .wy-shell:has(.wy-sidebar--rail)::before { width: var(--wy-sidebar-rail); }
  .wy-sidebar { display: flex; }
  .wy-topbar__menu { display: none; }
  .wy-topbar { padding: 0 var(--wy-space-6); }
  .wy-content { padding: var(--wy-space-8); }
}
@media (forced-colors: active) {
  .wy-nav__item[aria-current="page"] { outline: 2px solid Highlight; outline-offset: calc(var(--wy-space-1) * -0.5); }
  .wy-nav__item[aria-current="page"]::before { background: Highlight; }
}

/* ----------------------------------------------------------------------------
   6.1 Auth frame — .wy-auth for anonymous pages and pages that set
       {% set chromeless = true %}: one centred column, 400 wide (content-box,
       so the phone gutters come on top), the brand centred above the card.
       .wy-auth__card is a width container only; the card look is Phase 3.
   -------------------------------------------------------------------------- */
.wy-auth { box-sizing: content-box; max-width: calc(var(--wy-space-16) * 6.25); /* 400 */ margin: 0 auto; padding: var(--wy-space-8) var(--wy-space-4) var(--wy-space-12); }
.wy-auth__brand { display: flex; justify-content: center; margin-bottom: var(--wy-space-6); }
.wy-auth__card { width: 100%; min-width: 0; }
