/* AMD Developer Program identity surfaces.
 *
 * Two surfaces, one visual language:
 *
 *   .amd-modal       the OAuth gate -- a <dialog> that opens over whatever page
 *                    the visitor started from, carrying the verify and confirm
 *                    steps. There is no OAuth PAGE; see amd_identity.js.
 *   .amd-connection  the connect/disconnect control embedded in Settings
 *                    (redesign) and Profile (classic).
 *
 * WHY EVERY COLOUR IS `var(--token, fallback)`. This file loads in two kinds of
 * place, and only one of them has tokens.css:
 *
 *   redesign  /, /profile, /settings ...  tokens.css present
 *   classic   /, /profile                 antd's light page, no tokens
 *
 * So the redesign inherits the real product tokens -- the modal follows the
 * light/dark switch and stays in step when a token changes -- and the classic
 * pages fall through to the fallbacks. Do not replace a `var(--x, y)` with a
 * bare hex: the variable is what keeps the redesign in sync, the fallback is
 * what makes the classic UI legible.
 *
 * The two surfaces take DIFFERENT fallbacks on purpose. The modal floats over a
 * scrim, so its fallbacks are the product's dark HUD values. The connection
 * widget is embedded inside a white antd card on classic /profile, so its
 * fallbacks are light -- a dark widget there would punch a hole in the page.
 *
 * THE DIRECTION: "machined checkpoint". The product's register is a HUD --
 * Chakra Petch caps, zero radii, one 10px chamfer per panel, cyan for what the
 * system is showing you. An OAuth handoff is a sequence of gates, so the rail
 * down the left is the load-bearing idea: numbered cells, hairline connectors,
 * a scan sweep on the leg you are currently traversing. Everything else is kept
 * quiet so the rail is the thing you read first.
 */

/* ---- the dialog ---------------------------------------------------------
   showModal() puts this in the top layer, which is what lets it sit above
   antd's own overlays without a z-index argument. The UA defaults have to go
   first: a dialog ships with a border, padding, a white background and an
   auto width that would box the panel inside a second, paler panel. */
dialog.amd-modal {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text, #F5F5F6);
  width: min(920px, calc(100vw - 24px));
  max-width: min(920px, calc(100vw - 24px));
  max-height: calc(100dvh - 24px);
  overflow: visible;
  font-family: "IBM Plex Sans", "IBM Plex Sans SC", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
dialog.amd-modal, dialog.amd-modal *, dialog.amd-modal *::before, dialog.amd-modal *::after {
  box-sizing: border-box;
}

/* Atmosphere, not a flat scrim: a cyan bloom high and centre where the panel's
   head sits, over a technical grid, over a blur that pushes the origin page
   back without hiding it. Hardcoded rather than tokenised -- ::backdrop does not
   reliably inherit custom properties from its originating element, and a scrim
   is dark in both themes anyway. */
dialog.amd-modal::backdrop {
  background:
    radial-gradient(70ch 40ch at 50% -6ch, rgba(0, 194, 222, 0.16) 0%, transparent 70%),
    linear-gradient(rgba(0, 194, 222, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 194, 222, 0.05) 1px, transparent 1px),
    rgba(6, 8, 10, 0.82);
  background-size: 100% 100%, 56px 56px, 56px 56px, 100% 100%;
  backdrop-filter: blur(6px) saturate(120%);
}

dialog.amd-modal[open] { animation: amd-pop 260ms cubic-bezier(0.34, 1.4, 0.5, 1) none; }
dialog.amd-modal[open]::backdrop { animation: amd-fade 220ms cubic-bezier(0.2, 0.7, 0.3, 1) none; }

/* ---- the panel ----------------------------------------------------------
   One chamfer, bottom-right, --notch. The rail is a real column on a wide
   viewport and a header strip on a narrow one; the divider between them is
   drawn by the rail's own border, so there is nothing to keep in sync. */
.amd-shell {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 244px) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  max-height: calc(100dvh - 24px);
  background: var(--surface, #141416);
  border: 1px solid var(--border, #26262A);
  box-shadow: 0 28px 72px rgba(0, 0, 0, 0.55);
  clip-path: polygon(
    0 0, 100% 0,
    100% calc(100% - var(--notch, 10px)), calc(100% - var(--notch, 10px)) 100%,
    0 100%
  );
}
/* The lit top edge: a 2px cyan rule across the panel's head, brightest at the
   left where the rail starts. It points at the sequence. */
.amd-shell::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg,
    var(--graph, #00C2DE) 0%,
    color-mix(in srgb, var(--graph, #00C2DE) 40%, transparent) 34%,
    transparent 78%);
  z-index: 2;
}

/* ---- the rail -----------------------------------------------------------
   The one thing to remember about this modal. Each gate is a square index cell
   in mono, a display-face label, and a connector down to the next. State is
   decided from the flow's phase when the modal renders; nothing here polls. */
.amd-rail {
  padding: clamp(20px, 3vw, 30px);
  background: var(--surface-inset, #08080A);
  border-right: 1px solid var(--border, #26262A);
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-height: 0;
  overflow: hidden;
}

.amd-provider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border, #26262A);
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted, #A1A1A8);
  line-height: 1.3;
}
/* A filled square, not a circle and not an icon: the same mark the rail's index
   cells use, so the provider reads as the origin of the sequence below it. */
.amd-provider-mark {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  background: var(--graph, #00C2DE);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--graph, #00C2DE) 20%, transparent);
}

.amd-steps { list-style: none; margin: 0; padding: 0; }

.amd-step {
  position: relative;
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 12px;
  padding-bottom: 26px;
  animation: amd-rise 420ms cubic-bezier(0.2, 0.7, 0.3, 1) none;
  animation-delay: calc(var(--amd-i, 0) * 70ms);
}
.amd-step:last-child { padding-bottom: 0; }

/* The connector is owned by the step ABOVE the gap it spans, which is why
   :last-child drops it -- there is no leg after the final gate. */
.amd-step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 13px;
  top: 32px;
  bottom: 6px;
  width: 2px;
  background: repeating-linear-gradient(
    to bottom,
    var(--border-emphasis, #3D3D42) 0 3px,
    transparent 3px 7px);
}
.amd-step.is-done:not(:last-child)::before {
  background: color-mix(in srgb, var(--graph, #00C2DE) 55%, transparent);
}
/* The leg you are on carries a slow scan. Deliberately unhurried: this modal can
   sit for a minute waiting on an email, and a fast pulse next to that reads as
   an error rather than as progress. */
.amd-step.is-active:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 13px;
  top: 32px;
  bottom: 6px;
  width: 2px;
  background: linear-gradient(to bottom, transparent, var(--graph-strong, #4FDCF2), transparent);
  animation: amd-scan 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.amd-step-cell {
  grid-column: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border-control, #686873);
  background: var(--surface, #141416);
  color: var(--text-subtle, #7E7E86);
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.amd-step-label {
  grid-column: 2;
  align-self: center;
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-subtle, #7E7E86);
  overflow-wrap: anywhere;
}

.amd-step.is-done .amd-step-cell {
  border-color: color-mix(in srgb, var(--graph, #00C2DE) 55%, transparent);
  background: color-mix(in srgb, var(--graph, #00C2DE) 16%, transparent);
  color: var(--graph-strong, #4FDCF2);
}
.amd-step.is-done .amd-step-label { color: var(--text-muted, #A1A1A8); }
/* The index is replaced by a tick once the gate is behind you. Done in CSS off
   the state class so the script emits the number unconditionally and the two
   can never disagree about which gates are cleared. */
.amd-step.is-done .amd-step-n { display: none; }
.amd-step.is-done .amd-step-cell::after { content: "✓"; font-size: 13px; }

.amd-step.is-active .amd-step-cell {
  border-color: var(--graph, #00C2DE);
  background: var(--action-soft, #00C2DE1F);
  color: var(--graph-strong, #4FDCF2);
  animation: amd-breathe 2.8s ease-in-out infinite;
}
.amd-step.is-active .amd-step-label { color: var(--text, #F5F5F6); }

.amd-step.is-error .amd-step-cell {
  border-color: var(--danger, #FF6B62);
  background: color-mix(in srgb, var(--danger, #FF6B62) 14%, transparent);
  color: var(--danger, #FF6B62);
  animation: none;
}
.amd-step.is-error .amd-step-n { display: none; }
.amd-step.is-error .amd-step-cell::after { content: "!"; font-size: 14px; font-weight: 700; }
.amd-step.is-error .amd-step-label { color: var(--danger, #FF6B62); }

/* ---- the body ----------------------------------------------------------- */
.amd-body {
  position: relative;
  min-width: 0;
  /* min-height:0 is what makes overflow-y actually engage: a grid item defaults
     to min-height:auto and refuses to shrink below its content, so without this
     a tall panel grows past the shell's max-height instead of scrolling. */
  min-height: 0;
  overflow-y: auto;
  padding: clamp(24px, 3vw, 36px);
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.amd-body > * { animation: amd-rise 420ms cubic-bezier(0.2, 0.7, 0.3, 1) none; }

/* The dismiss control. Ghost-weight and in the corner, because leaving is not
   one of the things this panel is asking you to do -- but it posts the same
   cancel the named Cancel button does, so the flow is released either way. */
.amd-close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-subtle, #7E7E86);
  cursor: pointer;
  transition: color 120ms cubic-bezier(0.2, 0.7, 0.3, 1),
              border-color 120ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
.amd-close:hover:not(:disabled) {
  color: var(--text, #F5F5F6);
  border-color: var(--border-emphasis, #3D3D42);
}
.amd-close svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 1.6; }

.amd-eyebrow {
  margin: 0;
  padding-right: 34px;
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--graph-strong, #4FDCF2);
}

.amd-shell h1 {
  margin: 0;
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: clamp(22px, 3vw, 32px);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--text, #F5F5F6);
  overflow-wrap: anywhere;
}

.amd-shell p { margin: 0; overflow-wrap: anywhere; }
.amd-note {
  color: var(--text-muted, #A1A1A8);
  font-size: 15px;
  line-height: 1.6;
  max-width: 56ch;
}

/* Alert and status share a geometry -- a keyline in the margin, a reserved
   line-box -- so a message appearing never shifts the controls under it. They
   differ only in hue, which is the whole vocabulary: red is what went wrong,
   cyan is what the system is telling you. */
.amd-shell [role="alert"],
.amd-shell [role="status"] {
  min-height: 1.5em;
  padding-left: 12px;
  border-left: 2px solid transparent;
  font-size: 14px;
  line-height: 1.5;
}
.amd-shell [role="alert"] { color: var(--danger, #FF6B62); }
.amd-shell [role="alert"]:not(:empty) { border-left-color: var(--danger, #FF6B62); }
.amd-shell [role="status"] { color: var(--graph-strong, #4FDCF2); }
.amd-shell [role="status"]:not(:empty) { border-left-color: var(--graph, #00C2DE); }

/* ---- fields -------------------------------------------------------------
   The code field is the moment this modal is actually FOR, so it gets the only
   type on the panel that is neither the display face nor body copy: mono,
   tracked wide, tabular, centred. It should feel like keying a number into
   hardware. */
.amd-field { display: block; }
.amd-field + .amd-field { margin-top: 18px; }

.amd-label {
  display: block;
  margin-bottom: 8px;
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted, #A1A1A8);
}

.amd-input {
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  background: var(--control, #1C1C1F);
  border: 1px solid var(--border-control, #686873);
  border-radius: 0;
  color: var(--text, #F5F5F6);
  font: inherit;
  caret-color: var(--graph, #00C2DE);
  transition: border-color 120ms cubic-bezier(0.2, 0.7, 0.3, 1),
              box-shadow 120ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
.amd-input::placeholder { color: var(--text-subtle, #7E7E86); }
.amd-input:hover:not([readonly]) { border-color: var(--text-muted, #A1A1A8); }
.amd-input:focus {
  outline: none;
  border-color: var(--graph, #00C2DE);
  box-shadow: inset 0 -2px 0 0 var(--graph, #00C2DE);
}
/* A readonly address is not an input the visitor can act on -- it is the
   identity the flow is bound to. Rendering it as a locked mono plate says so
   without needing a sentence to explain it. */
.amd-input[readonly] {
  background: var(--surface-inset, #08080A);
  border-color: var(--border, #26262A);
  border-left: 2px solid var(--graph-dim, #0A6E80);
  color: var(--text-muted, #A1A1A8);
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px;
  cursor: default;
}

.amd-input-code {
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: clamp(18px, 4vw, 22px);
  font-variant-numeric: tabular-nums;
  /* Tracking is what makes six digits read as six slots. Clamped rather than
     fixed because letter-spacing adds to the content box: a fixed 0.5em pushed
     a full-width field past a 390px viewport. text-indent cancels the trailing
     space the last character's tracking leaves, so the digits stay centred. */
  letter-spacing: clamp(0.16em, 2.2vw, 0.4em);
  text-indent: clamp(0.16em, 2.2vw, 0.4em);
  text-align: center;
  padding-inline: 8px;
}

/* The verified address on the confirm gate. Same mono plate as a readonly
   field, but it is output rather than input, so it is not one. */
.amd-value {
  display: block;
  padding: 12px 14px;
  background: var(--surface-inset, #08080A);
  border: 1px solid var(--border, #26262A);
  border-left: 2px solid var(--graph, #00C2DE);
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px;
  color: var(--text, #F5F5F6);
  overflow-wrap: anywhere;
}

/* No separate signup surface: an address with no account behind it is the SAME
   gate with this chip on it. The chip is the entire difference, and it is
   outlined rather than filled so it reads as an annotation on the flow, not as
   a second thing to press. */
.amd-badge {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  padding: 3px 9px;
  border: 1px solid color-mix(in srgb, var(--graph, #00C2DE) 55%, transparent);
  background: var(--action-soft, #00C2DE1F);
  color: var(--graph-strong, #4FDCF2);
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* ---- controls -----------------------------------------------------------
   Same three ranks and the same recipe as redesign/chrome.css, re-declared
   because the classic pages have no chrome.css. Scoped at (0,2,0) so this one
   definition also outranks the redesign's global `.btn` -- both variants are
   governed by the same block and cannot drift apart. */
.amd-shell .btn, .amd-connection .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 16px;
  border: 1px solid transparent;
  border-radius: 0;
  background: none;
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.15;
  white-space: normal;
  text-decoration: none;
  cursor: pointer;
  transition: background 120ms cubic-bezier(0.2, 0.7, 0.3, 1),
              border-color 120ms cubic-bezier(0.2, 0.7, 0.3, 1),
              color 120ms cubic-bezier(0.2, 0.7, 0.3, 1),
              transform 120ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
.amd-shell .btn:active, .amd-connection .btn:active { transform: translateY(1px); }
.amd-shell .btn:disabled, .amd-connection .btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}
.amd-shell .btn-block { width: 100%; }
.amd-shell .btn-primary, .amd-connection .btn-primary {
  background: var(--action, #00C2DE);
  color: var(--on-action, #06181C);
}
.amd-shell .btn-primary:hover:not(:disabled),
.amd-connection .btn-primary:hover:not(:disabled) { background: var(--action-hover, #33D2E8); }
.amd-shell .btn-secondary, .amd-connection .btn-secondary {
  background: var(--control, #1C1C1F);
  color: var(--text, #F5F5F6);
  border-color: var(--border-control, #686873);
}
.amd-shell .btn-secondary:hover:not(:disabled),
.amd-connection .btn-secondary:hover:not(:disabled) {
  border-color: var(--text-muted, #A1A1A8);
  background: var(--surface-inset, #08080A);
}
/* The resend control. A quiet third rank -- it belongs to the field above it,
   not to the row of decisions at the bottom. */
.amd-shell .btn-ghost {
  min-height: 32px;
  padding: 0 10px;
  color: var(--text-muted, #A1A1A8);
  font-size: 12px;
}
.amd-shell .btn-ghost:hover:not(:disabled) {
  background: var(--surface-inset, #08080A);
  color: var(--text, #F5F5F6);
}
.amd-shell .btn-cancel { min-height: 32px; padding: 0 12px; font-size: 12px; }

.amd-submit { margin-top: 18px; }
.amd-send-row { display: flex; justify-content: flex-end; margin-top: 8px; }

/* ---- meta strip ---------------------------------------------------------
   Everything that is true about the flow rather than part of it: how long it
   lives, the way out, the way back to the start. Below the rule, in the quiet
   register, so it never competes with the gate's own action. */
.amd-meta {
  margin-top: auto;
  padding-top: 18px;
  border-top: 1px solid var(--border, #26262A);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.amd-ttl {
  flex: 1 1 20ch;
  min-width: 0;
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--text-subtle, #7E7E86);
}
.amd-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.amd-retry {
  color: var(--action-text, #4FDCF2);
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--action-text, #4FDCF2) 40%, transparent);
  padding-bottom: 1px;
}
.amd-retry:hover { border-bottom-color: var(--action-text, #4FDCF2); }

/* ---- busy ---------------------------------------------------------------
   The script sets aria-busy on the panel around every request. Reading it back
   as a hairline sweep across the panel's head means the feedback is already
   correct for a screen reader and free for everyone else. */
.amd-shell[aria-busy="true"]::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 3;
  background: linear-gradient(90deg, transparent, var(--graph-strong, #4FDCF2), transparent);
  animation: amd-sweep 1.1s linear infinite;
}

/* ---- the connection control --------------------------------------------
   Settings (redesign) and Profile (classic). Same language, but it sits INSIDE
   whatever card it is given, so the palette is inherited and the fallbacks here
   are LIGHT -- classic /profile is a white antd page. */
.amd-connection {
  position: relative;
  margin-bottom: 24px;
  padding: 20px;
  background: var(--surface, #ffffff);
  border: 1px solid var(--border, #e3e3e6);
  clip-path: polygon(
    0 0, 100% 0,
    100% calc(100% - var(--notch, 10px)), calc(100% - var(--notch, 10px)) 100%,
    0 100%
  );
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-start;
}
.amd-connection h2 {
  margin: 0;
  font-family: "Chakra Petch", system-ui, sans-serif;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text, #16161A);
}
.amd-connection p { margin: 0; overflow-wrap: anywhere; }
/* The status LED. A dot is the one place a pill radius survives in this
   language, because a circle is the shape's meaning rather than a softening. */
.amd-connection [role="status"] {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--text, #16161A);
}
.amd-connection [role="status"]::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--text-subtle, #6E6E78);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--text-subtle, #6E6E78) 18%, transparent);
  transition: background 220ms cubic-bezier(0.2, 0.7, 0.3, 1),
              box-shadow 220ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
/* Connected is the only state that lights. The attribute is written by the
   component beside the label it describes, so the dot and the word can never
   disagree. */
.amd-connection [role="status"][data-connected="true"]::before {
  background: var(--success, #1A7F37);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success, #1A7F37) 22%, transparent);
}
.amd-connection > p:not([role]) {
  color: var(--text-muted, #5A5A63);
  font-size: 13px;
  line-height: 1.6;
  max-width: 62ch;
}
.amd-connection [role="alert"] {
  color: var(--danger, #C4141C);
  font-size: 13px;
  padding-left: 10px;
  border-left: 2px solid var(--danger, #C4141C);
}

/* ---- focus --------------------------------------------------------------
   The classic pages have no motion.css, so the product's one focus treatment is
   restated here. Scoped, so it does not reach antd's controls on /profile. */
.amd-shell :focus-visible,
.amd-connection :focus-visible {
  outline: 2px solid var(--focus-ring, #4FDCF2);
  outline-offset: 2px;
}

/* ---- motion -------------------------------------------------------------
   Every keyframe settles to the correct STATIC state, and every animated
   element's RESTING state is the finished one -- `animation-fill-mode` is
   `none` throughout, so a frozen background tab or a privacy mode that
   suppresses animation leaves content visible rather than stuck at opacity 0. */
@keyframes amd-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes amd-pop {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes amd-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes amd-scan {
  from { transform: translateY(-100%); }
  to   { transform: translateY(100%); }
}
@keyframes amd-sweep {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}
@keyframes amd-breathe {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--graph, #00C2DE) 34%, transparent); }
  50%      { box-shadow: 0 0 0 5px transparent; }
}

@media (prefers-reduced-motion: reduce) {
  dialog.amd-modal, dialog.amd-modal *, .amd-connection * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .amd-step.is-active:not(:last-child)::after,
  .amd-shell[aria-busy="true"]::after { display: none; }
}

/* ---- responsive ---------------------------------------------------------
   Below 760px the rail turns from a column into a header strip. The gates run
   horizontally there, so the vertical connector becomes a horizontal one and
   the labels sit UNDER their cells -- three uppercase words in a row on a 390px
   screen would wrap into six lines and bury the field below them. */
@media (max-width: 760px) {
  .amd-shell { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .amd-rail {
    border-right: 0;
    border-bottom: 1px solid var(--border, #26262A);
    gap: 16px;
  }
  .amd-provider { padding-bottom: 14px; }
  .amd-steps { display: flex; align-items: flex-start; }
  .amd-step {
    flex: 1 1 0;
    min-width: 0;
    grid-template-columns: minmax(0, 1fr);
    justify-items: start;
    gap: 8px;
    padding-bottom: 0;
  }
  .amd-step-label {
    grid-column: 1;
    font-size: 11px;
    letter-spacing: 0.03em;
    line-height: 1.25;
  }
  .amd-step:not(:last-child)::before,
  .amd-step.is-active:not(:last-child)::after {
    left: 34px;
    right: 8px;
    top: 13px;
    bottom: auto;
    width: auto;
    height: 2px;
  }
  .amd-step:not(:last-child)::before {
    background: repeating-linear-gradient(
      to right,
      var(--border-emphasis, #3D3D42) 0 3px,
      transparent 3px 7px);
  }
  .amd-step.is-done:not(:last-child)::before {
    background: color-mix(in srgb, var(--graph, #00C2DE) 55%, transparent);
  }
  .amd-step.is-active:not(:last-child)::after {
    background: linear-gradient(90deg, transparent, var(--graph-strong, #4FDCF2), transparent);
    animation-name: amd-sweep;
  }
  .amd-meta { flex-direction: column; align-items: stretch; }
  .amd-actions { justify-content: space-between; }
}
@media (max-width: 420px) {
  dialog.amd-modal { width: calc(100vw - 16px); max-width: calc(100vw - 16px); }
  .amd-rail, .amd-body { padding: 18px; }
  .amd-close { top: 8px; right: 8px; }
}
