/* Callbacks (design v9, FE9-CB): the page head with its one primary
   (添加回调地址), then page tabs in the address with 「更新于」 and refresh at
   their right for both lists. 回调地址 is one table card (地址, 签名密钥 with
   查看 and 复制, 状态, 添加时间, 验证 and a ⋯ menu per row) and the signature
   guide beside a light Node.js sample, as the access card of the API keys
   board. 投递记录 is a list card: a toolbar (the shared task select, which
   takes a pasted ID, the endpoint filter chip and 清除筛选), the deliveries
   and a cursor foot. Adding, the new secret and revoking are modal v9
   dialogs; a finished action is a v9 toast, a row's own problem reads under
   its endpoint, and the banner is only for a blocking state. Cards,
   buttons, fields, menus, badges, tables, toasts, code and the shared
   controls are the v9 classes of the shared stylesheet; this file places
   them. */
.callbacks-workspace { min-width: 0; max-width: 100%; }
.callbacks { display: flex; flex-direction: column; gap: 16px; }
.callbacks .card { margin: 0; padding: 0; }
.callbacks > .page-head { margin-bottom: 0; }
.callbacks-head-action { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.callbacks-limit { max-width: 280px; margin: 0; text-align: right; }
.callbacks-tabs .count { margin-left: 2px; }
/* 「更新于」 and refresh sit at the right of the tab row and serve both
   tabs; the tabs keep their own hairline under them. */
.callbacks-tabbar { position: relative; }
.callbacks-tabbar-end { position: absolute; top: 4px; right: 0; display: flex; align-items: center; gap: 4px; }
.callbacks-refresh { color: var(--text-3); }
.callbacks-refresh:hover { color: var(--text-1); }
.callbacks-panel { display: flex; flex-direction: column; gap: 16px; container-type: inline-size; }
/* A blocking problem (the sign-in could not be confirmed) is the v9
   warning banner over the panels, its icon on the first line. */
.callbacks-status-bar { flex-wrap: nowrap; align-items: flex-start; }
.callbacks-status-bar > .glyph { margin-top: 1px; }
.callbacks-status { margin: 0; }
.callbacks-error { margin: 0; color: var(--danger-fg); font-size: 12px; line-height: 16px; }
.callbacks-error:empty { display: none; }
/* A row's own problem (a verification that did not pass, a secret that
   could not be read or copied) reads under its endpoint until the next
   action, as a field error does under its field. */
.callbacks-row-note { display: flex; align-items: flex-start; gap: 4px; margin: 4px 0 0; color: var(--danger-fg); font-size: 12px; line-height: 16px; text-wrap: pretty; }
.callbacks-row-note > .glyph { margin-top: 1px; }

/* A control at work: the shared spinner before its label (验证中), or over
   the icon of 刷新, ⋯, 查看 and 复制, which it replaces; it shows after
   200 ms (design v9, R8), so a quick answer never flashes it. */
.callbacks .btn > .spinner, .callbacks-row-menu > summary > .spinner { opacity: 0; animation: v9-spin .8s linear infinite, callbacks-appear 1ms linear 200ms forwards; }
.callbacks-refresh > .spinner { position: absolute; top: 8px; left: 8px; display: none; }
.callbacks-secret > .btn > .spinner { position: absolute; top: 50%; left: 50%; display: none; margin: -7px 0 0 -7px; }
.callbacks-refresh[aria-busy="true"] > .spinner, .callbacks-secret > .btn[aria-busy="true"] > .spinner { display: block; }
.callbacks-row-menu > summary > * { grid-area: 1 / 1; }
:is(.callbacks-refresh, .callbacks-secret > .btn, .callbacks-row-menu > summary)[aria-busy="true"] > .glyph { animation: callbacks-vanish 1ms linear 200ms forwards; }
.callbacks .btn[aria-busy="true"], .callbacks-row-menu > summary[aria-busy="true"] { opacity: 1; cursor: progress; }
@keyframes callbacks-vanish { to { opacity: 0; } }

/* Tables: rows of 56 (two-line cells breathe 10 over and under), the
   endpoint in mono and breakable, times in tabular figures. The endpoint
   table never scrolls sideways (its cells wrap), so a row menu can open
   over the rows and the card below it. */
.callbacks-card { container-type: inline-size; }
.callbacks-table td { height: 56px; padding-top: 10px; padding-bottom: 10px; }
.callbacks-targets-card .callbacks-scroll { overflow: visible; }
.callbacks-url-cell { min-width: 200px; }
.callbacks-url { color: var(--text-1); font: 400 13px/20px var(--font-mono); overflow-wrap: anywhere; }
.callbacks-table tr.is-revoked .callbacks-url { color: var(--text-3); }
.callbacks-table time { color: var(--text-2); font-size: 13px; line-height: 20px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.callbacks-created-cell, .callbacks-time-cell, .callbacks-delivered-cell { white-space: nowrap; }
.callbacks-cell-label { display: none; }
th.callbacks-actions-head, td.callbacks-actions { width: 1%; text-align: right; white-space: nowrap; }
td.callbacks-actions > .callbacks-verify { vertical-align: middle; }
td.callbacks-actions > .callbacks-row-menu { margin-left: 8px; vertical-align: middle; }
.callbacks .badge > .glyph { width: 12px; height: 12px; }

/* The signing secret: masked, then 查看 (an eye; pressed while shown, the
   eye struck) and 复制. Its column keeps the width of a shown secret, which
   wraps in a light box no wider than the column, so showing one never moves
   the other columns. */
.callbacks-secret-cell { width: 320px; min-width: 176px; }
.callbacks-secret { display: inline-flex; align-items: center; gap: 2px; max-width: 100%; }
.callbacks-secret > code { color: var(--text-1); font: 400 13px/20px var(--font-mono); letter-spacing: .02em; white-space: nowrap; }
.callbacks-secret > .callbacks-eye { margin-left: 6px; }
.callbacks-secret > .btn.btn-icon { flex: none; color: var(--text-3); }
.callbacks-secret > .btn.btn-icon:hover { color: var(--text-1); }
.callbacks-secret > .btn.btn-icon[aria-pressed="true"] { background: var(--accent-tint); color: var(--violet-700); }
.callbacks-secret.is-shown { display: flex; align-items: flex-start; width: 100%; max-width: 320px; padding: 6px 4px 6px 10px; border-radius: var(--r-8); background: var(--gray-25); box-shadow: inset 0 0 0 1px var(--line-soft); }
.callbacks-secret.is-shown > code { flex: 1 1 auto; min-width: 0; white-space: normal; overflow-wrap: anywhere; user-select: all; }
.callbacks-secret.is-shown > .btn.btn-icon { margin-top: -2px; }

/* A copy control that just copied shows a check, and an icon control
   「已复制」 over itself, for 1.6 seconds. */
.callbacks-copied { display: none; }
.callbacks-copy { position: relative; }
.btn.callbacks-copy.is-copied, .btn.callbacks-copy.is-copied:hover { color: var(--success-fg); }
.btn.btn-icon.callbacks-copy.is-copied > .glyph { display: none; }
.btn.btn-icon.callbacks-copy.is-copied::after { content: ""; width: 12px; height: 12px; background: currentColor; clip-path: path("M1.4 6.4L2.9 4.9L4.9 6.9L9.1 2.7L10.6 4.2L4.9 9.9Z"); }
.btn.btn-icon.callbacks-copy.is-copied > .callbacks-copied { position: absolute; bottom: calc(100% + 6px); left: 50%; z-index: 2; display: block; padding: 2px 8px; border-radius: var(--r-6); background: var(--gray-900); color: #fff; font: 500 12px/16px var(--font-sans); white-space: nowrap; transform: translateX(-50%); pointer-events: none; }
.btn.callbacks-copy:not(.btn-icon).is-copied > :is(.glyph, .callbacks-copy-label) { display: none; }
.btn.callbacks-copy:not(.btn-icon).is-copied::before { content: ""; width: 12px; height: 12px; background: currentColor; clip-path: path("M1.4 6.4L2.9 4.9L4.9 6.9L9.1 2.7L10.6 4.2L4.9 9.9Z"); }
.btn.callbacks-copy:not(.btn-icon).is-copied > .callbacks-copied { display: inline; }
.btn.btn-primary.callbacks-copy.is-copied, .btn.btn-primary.callbacks-copy.is-copied:hover { color: #fff; }

/* Row menu: a native disclosure (⋯) with the v9 menu under it, floating
   over the rows below; the danger item is red under a hairline. */
.callbacks-row-menu { position: relative; display: inline-block; text-align: left; }
.callbacks-row-menu > summary { position: relative; display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: var(--r-6); color: var(--gray-400); list-style: none; cursor: pointer; transition: background-color var(--t-hover) var(--ease), color var(--t-hover) var(--ease); }
.callbacks-row-menu > summary::-webkit-details-marker { display: none; }
.callbacks-row-menu > summary::after { content: ""; position: absolute; inset: -8px; }
.callbacks-table tbody tr:hover .callbacks-row-menu > summary, .callbacks-row-menu[open] > summary, .callbacks-row-menu > summary[aria-busy="true"] { color: var(--gray-700); }
.callbacks-row-menu > summary:hover, .callbacks-row-menu[open] > summary { background: var(--wash-1); }
.callbacks-row-menu > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.callbacks-row-menu > .callbacks-menu { position: absolute; top: calc(100% + 4px); right: 0; z-index: var(--z-menu); min-width: 168px; }
.callbacks-menu > .menu-item:disabled { color: var(--gray-400); cursor: not-allowed; }
.callbacks-menu > .menu-item > .glyph { width: 16px; height: 16px; }
.callbacks-menu > .menu-item > .glyph.glyph-copy-14 { width: 14px; height: 14px; margin: 0 1px; }
.callbacks-menu > .menu-item:disabled > .glyph { color: var(--gray-400); }
/* 撤销地址: a ring with a bar across it, drawn like the shared glyphs. */
.glyph.callbacks-glyph-revoke { width: 16px; height: 16px; clip-path: path("M8 1.5A6.5 6.5 0 1 1 8 14.5A6.5 6.5 0 1 1 8 1.5ZM8 3A5 5 0 1 0 8 13A5 5 0 1 0 8 3ZM4.4 3.34L12.66 11.6L11.6 12.66L3.34 4.4Z"); }
.callbacks-menu > .menu-item.is-danger { position: relative; margin-top: 6px; }
.callbacks-menu > .menu-item.is-danger::before { content: ""; position: absolute; top: -4px; right: -6px; left: -6px; height: 1px; background: var(--line-soft); }

/* Empty, failed and loading states fill the table; an empty or failed
   table drops its head, so the state is the card's only content.
   Placeholder rows fade in after 200 ms, so a quick answer never flashes
   them. */
.callbacks-table.is-empty > thead { display: none; }
.callbacks-table tr.callbacks-state-row td { height: auto; padding: 0; }
.callbacks-table tbody tr.callbacks-state-row:hover, .callbacks-table tbody tr.callbacks-skel-row:hover { background: transparent; }
.callbacks-state-row .empty { padding: 48px 16px; }
.callbacks-skel-row .skel { width: 72%; max-width: 168px; opacity: 0; animation: callbacks-appear 1ms linear 200ms forwards; }
@keyframes callbacks-appear { to { opacity: 1; } }

/* The signature guide: steps on the left, the light sample on the right
   with its copy control; they stack in a narrow column. */
.callbacks-guide { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
.callbacks-guide-text { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; min-width: 0; padding: 20px; }
.callbacks-guide-intro, .callbacks-guide-note { margin: 0; color: var(--text-2); font-size: 13px; line-height: 20px; }
.callbacks-steps { margin: 0; padding-left: 20px; color: var(--text-1); font-size: 13px; line-height: 20px; }
.callbacks-steps > li + li { margin-top: 4px; }
.callbacks-steps > li::marker { color: var(--text-3); font-variant-numeric: tabular-nums; }
.callbacks-docs { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 4px; }
.callbacks .btn.btn-link.callbacks-docs-link { font-size: 13px; line-height: 20px; }
.callbacks-code { min-width: 0; border: 0; border-left: 1px solid var(--line-soft); border-radius: 0 var(--r-12) var(--r-12) 0; }
.callbacks-code .code-head { padding-left: 4px; }
.callbacks-code pre.callbacks-example { max-height: none; }
/* A sample the clipboard refused says so beside its copy control. */
.callbacks-code-status { min-width: 0; margin-left: auto; overflow: hidden; color: var(--danger-fg); font-size: 12px; line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
.callbacks-code-status:empty { display: none; }
.callbacks-code-status:not(:empty) + .code-copy { margin-left: 8px; }
@container (max-width: 879px) {
  .callbacks-guide { grid-template-columns: minmax(0, 1fr); }
  .callbacks-code { border-left: 0; border-top: 1px solid var(--line-soft); border-radius: 0 0 var(--r-12) var(--r-12); }
}

/* Deliveries: the toolbar of the v9 list: the task select (32 high, 280
   wide, as the board's list search) and the endpoint filter chip on the
   left, then 清除筛选 while a filter is on. */
.callbacks-task-slot { flex: 0 1 280px; width: 280px; min-width: 200px; }
.callbacks-target-slot { display: flex; min-width: 0; max-width: 100%; }
.callbacks-target-slot > .ctl-chip { max-width: 100%; }
/* A recent task lists its ID, model and time on one line, so its menu is
   wider than the select (a phone keeps the shared sheet at the foot). */
@media (min-width: 768px) {
  .callbacks-task-slot .ctl-select > .ctl-menu { width: max(100%, 380px); max-width: calc(100vw - 32px); }
}

/* Delivery cells: the event over its type, the task as a mono link, the
   endpoint as host and path, the receiver's last HTTP status, the result
   badge over its attempts or until when it stops; the foot holds the range
   and the pager. */
.callbacks-event-name { display: block; color: var(--text-1); white-space: nowrap; }
.callbacks .cell-sub.callbacks-event-type { font: 400 12px/16px var(--font-mono); white-space: nowrap; }
.callbacks-task-link { color: var(--text-1); font: 400 13px/20px var(--font-mono); text-decoration: none; white-space: nowrap; }
.callbacks-task-link:hover { color: var(--violet-700); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.callbacks-target-url { color: var(--text-2); font: 400 13px/20px var(--font-mono); overflow-wrap: anywhere; }
th.callbacks-http-head, td.callbacks-http-cell { text-align: right; white-space: nowrap; }
.callbacks-http { color: var(--text-1); font: 400 13px/20px var(--font-mono); font-variant-numeric: tabular-nums; }
.callbacks-result-cell { min-width: 150px; }
.callbacks-result-cell > .cell-sub { margin-top: 2px; font-size: 12px; line-height: 16px; }
.callbacks-foot .pager .glyph { color: currentColor; }
.callbacks-foot > span { font-variant-numeric: tabular-nums; }

/* Dialogs: a fixed layer over the page; on phones the dialog is the v9
   bottom sheet. */
.callbacks-dialog { position: relative; }
.callbacks-dialog-close { position: absolute; top: 16px; right: 16px; color: var(--text-3); }
.callbacks-create { display: flex; flex-direction: column; gap: 24px; margin: 4px 0 0; }
.callbacks-create > div { margin: 0; }
.callbacks-create .field > p { margin: 0; }
.callbacks-url-control { padding: 0 12px; gap: 0; }
.callbacks-url-control > .callbacks-scheme { color: var(--text-3); font: 400 14px/20px var(--font-mono); }
.callbacks-url-control > input, .callbacks-url-control > input:is(:hover, :focus, :focus-visible) { font: 400 14px/20px var(--font-mono); }
.callbacks-created-title { display: flex; align-items: center; gap: 10px; }
.callbacks-created-mark { display: grid; flex: none; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--success-tint); color: var(--success-fg); }
.callbacks-secret-box { padding: 12px; border: 1px solid var(--line); border-radius: var(--r-8); background: var(--gray-25); }
.callbacks-secret-url { margin: 0 0 6px; color: var(--text-3); font: 400 12px/16px var(--font-mono); overflow-wrap: anywhere; }
.callbacks-secret-full { display: block; color: var(--text-1); font: 400 13px/20px var(--font-mono); overflow-wrap: anywhere; user-select: all; }
.callbacks-dialog-status { margin: 0; color: var(--text-2); font-size: 13px; line-height: 20px; }
.callbacks-dialog-status:empty { display: none; }
.callbacks-confirm-url { margin: 0; padding: 8px 12px; border-radius: var(--r-8); background: var(--gray-25); color: var(--text-1); font: 400 13px/20px var(--font-mono); overflow-wrap: anywhere; }

/* A narrow card (under 880px: tablets at the rail width and phones) shows
   each endpoint as one block, so every action, status and time stays in
   view without scrolling sideways; a cell label names the values the block
   would otherwise leave unexplained. */
@container (max-width: 879px) {
  .callbacks-scroll { overflow: visible; }
  .callbacks-table, .callbacks-table tbody { display: block; width: 100%; min-width: 0; }
  .callbacks-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .callbacks-table tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 6px 12px; padding: 14px 16px; border-bottom: 1px solid var(--line-soft); }
  .callbacks-table tbody tr:last-child { border-bottom: 0; }
  .callbacks-table td, .callbacks-table tr > :first-child, .callbacks-table tr > :last-child { display: block; height: auto; min-width: 0; padding: 0; border: 0; white-space: normal; text-align: left; }
  .callbacks-cell-label { display: inline; margin-right: 6px; color: var(--text-3); font-size: 12px; }
  #callbacks-rows > tr { grid-template-areas: "url actions" "state state" "secret secret" "created created"; }
  #callbacks-rows td:nth-child(1) { grid-area: url; }
  #callbacks-rows td:nth-child(2) { grid-area: secret; }
  #callbacks-rows td:nth-child(3) { grid-area: state; }
  #callbacks-rows td:nth-child(4) { grid-area: created; }
  #callbacks-rows td:nth-child(5) { grid-area: actions; align-self: start; }
  #callbacks-rows td.callbacks-actions { width: auto; white-space: nowrap; }
  #callbacks-rows td.callbacks-secret-cell { width: auto; }
  #callbacks-rows td.callbacks-secret-cell > .callbacks-cell-label { display: none; }
  #callbacks-rows tr.is-revoked > td.callbacks-secret-cell { display: none; }
  .callbacks-table tr.callbacks-state-row, .callbacks-table tr.callbacks-skel-row { display: block; padding: 0; }
  .callbacks-table tr.callbacks-skel-row { padding: 14px 16px; }
  .callbacks-table tr.callbacks-skel-row td + td { display: none; }
  .callbacks-table tr.callbacks-state-row td, .callbacks-table tr.callbacks-skel-row td { grid-area: auto; }
  .callbacks-result-cell { min-width: 0; }
  .callbacks-secret.is-shown { max-width: none; }
}
/* A delivery in a narrow card is a short row of at most three lines (the
   v9 lists below 768: two-line rows): the event and its result badge; the
   endpoint's host and path, the task and the time; then the attempts, the
   receiver's last HTTP status and when it was delivered, where there is
   one. The type, the cell labels of the task and the endpoint and an empty
   value drop out. Each part is its own flex item, ordered into the lines
   that the two full-width breaks start; the result cell lends its badge
   and its attempts to two of them. The parts that shrink start from 1px,
   never 0, so none of them fits on a break's own line. */
@container (max-width: 879px) {
  #callbacks-events > tr:not(.callbacks-state-row, .callbacks-skel-row) { display: flex; flex-wrap: wrap; align-items: center; gap: 0; padding: 12px 16px; }
  #callbacks-events > tr:not(.callbacks-state-row, .callbacks-skel-row)::before { content: ""; order: 3; flex: 0 0 100%; height: 4px; }
  #callbacks-events > tr:not(.callbacks-state-row, .callbacks-skel-row)::after { content: ""; order: 7; flex: 0 0 100%; height: 2px; }
  #callbacks-events td:nth-child(2) { order: 1; flex: 1 1 1px; min-width: 0; }
  #callbacks-events td:nth-child(2) > .callbacks-event-name { overflow: hidden; text-overflow: ellipsis; }
  #callbacks-events td:nth-child(2) > .callbacks-event-type { display: none; }
  #callbacks-events td.callbacks-result-cell { display: contents; }
  #callbacks-events td.callbacks-result-cell > .badge { order: 2; flex: none; margin-left: 12px; }
  #callbacks-events td:nth-child(4) { order: 4; flex: 1 1 1px; min-width: 0; max-width: max-content; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--text-2); font-size: 13px; line-height: 20px; }
  #callbacks-events td:nth-child(4) > .callbacks-target-url { overflow-wrap: normal; }
  #callbacks-events td:nth-child(3) { order: 5; flex: none; }
  #callbacks-events td:nth-child(1) { order: 6; flex: none; }
  #callbacks-events td:is(:nth-child(3), :nth-child(1))::before { content: "·"; margin: 0 6px; color: var(--text-3); font-size: 13px; line-height: 20px; }
  #callbacks-events td:is(:nth-child(3), :nth-child(4)) > .callbacks-cell-label { display: none; }
  #callbacks-events td.callbacks-result-cell > .cell-sub { order: 8; flex: none; margin: 0 12px 0 0; }
  #callbacks-events td:nth-child(5) { order: 9; flex: none; margin-right: 12px; }
  #callbacks-events td:nth-child(7) { order: 10; flex: none; }
  #callbacks-events td:is(:nth-child(5), :nth-child(7)) { color: var(--text-3); font-size: 12px; line-height: 16px; }
  #callbacks-events td:is(:nth-child(5), :nth-child(7)) > .callbacks-cell-label { margin-right: 4px; }
  #callbacks-events td:is(:nth-child(5), :nth-child(7)) :is(.callbacks-http, time) { color: var(--text-2); font-size: 12px; line-height: 16px; }
  #callbacks-events td.is-none { display: none; }
}
@media (max-width: 767px) {
  .callbacks-head-action { align-items: flex-start; }
  .callbacks-limit { text-align: left; }
  /* The task select takes the toolbar's first line; the chip and 清除筛选
     share the second. */
  .callbacks-task-slot { flex: 1 1 100%; width: auto; }
  /* 查看 and 复制 are the board's 36px icon buttons, each answering a 44px
     square; 8px apart, the two squares never overlap, shown or masked. */
  .callbacks-secret { gap: 8px; }
  .callbacks-secret > .callbacks-eye { margin-left: 0; }
  .callbacks-secret > .btn.btn-icon.btn-xs { width: 36px; height: 36px; border-radius: var(--r-8); }
  .callbacks-secret > .btn.btn-icon.btn-xs::before { inset: -4px; }
  .callbacks-secret.is-shown { align-items: center; padding: 4px 4px 4px 10px; }
  .callbacks-secret.is-shown > .btn.btn-icon { margin-top: 0; }
  .callbacks-url-control > .callbacks-scheme, .callbacks-url-control > input, .callbacks-url-control > input:is(:hover, :focus, :focus-visible) { font-size: 16px; }
  .callbacks-dialog .dialog-foot { flex-direction: column-reverse; align-items: stretch; }
}
