/* Tasks (design v9 boards Tasks and TaskDetail): the page head with the one
   primary action, then one card with the table toolbar (search, the filter
   chips, the page-only note, 更新于 and a refresh), the task table and its
   cursor footer. A row opens the task's details in a sheet on the right:
   from 1440px the list narrows beside it, below 1440px it floats over the
   list, which keeps its width, and on phones it fills the screen. Cards,
   buttons, chips, badges, tables, tabs, code blocks, dialogs, the progress
   bar and the sheet come from the shared stylesheet; this file places them
   and draws the task-only pieces. */
.tasks-workspace { min-width: 0; max-width: 100%; }
/* The task list is a list page: its column widens to 1600px (design v9). */
main.tasks-workspace { --page-max: 1600px; }
.tasks { display: flex; flex-direction: column; min-width: 0; }
.tasks > .page-head { margin-bottom: 24px; }
/* The heading takes the focus when a sheet the address opened closes with
   no row of its task on the page (FE-TASK-LINK); its ring hugs the word. */
#tasks-heading { width: fit-content; max-width: 100%; }
.tasks-card { min-width: 0; }

/* Toolbar: a 280px search with the / key cap, the four chips, 清除筛选 only
   while filtered, and at the end the page-only note, 更新于 N 秒前 (刷新中
   while the rows are read again) and the refresh. */
.tasks-search { flex: 0 1 280px; width: 280px; max-width: 100%; }
.tasks-search input::-webkit-search-cancel-button { cursor: pointer; }
.tasks-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.tasks-clear { margin-left: 4px; }
.tasks-scope { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--r-6); background: var(--gray-100); color: var(--text-2); font-size: 12px; line-height: 16px; white-space: nowrap; }
.tasks-updating, .tasks-updated { padding: 0 4px; }
/* The 2px bar under the toolbar while the rows on screen are read again. */
.tasks-bar { margin-top: -1px; }
.tasks-bar > span { animation: tasks-bar 1.2s var(--ease) infinite; }
@keyframes tasks-bar { from { transform: translateX(-100%); } to { transform: translateX(170%); } }
/* 有 N 个新任务: newer tasks wait above the rows until the reader asks. */
.tasks-new { display: flex; justify-content: center; padding: 4px 16px; border-bottom: 1px solid var(--line-soft); background: var(--accent-tint); }
.tasks-new .btn { font-size: 13px; }
.tasks-new-up { transform: rotate(-90deg); }

/* Table: fixed columns as the board measures them; the task column takes
   the rest. The wrap does not scroll sideways from 768px up, so a row's
   menu is never cut off by it. */
.tasks-wrap { overflow: visible; }
.tasks-table { table-layout: fixed; }
.tasks-table .c-status { width: 120px; }
.tasks-table .c-id { width: 168px; }
.tasks-table .c-key { width: 136px; }
.tasks-table .c-elapsed { width: 96px; }
.tasks-table .c-charge { width: 104px; }
.tasks-table .c-created { width: 112px; }
.tasks-table .c-more { width: 56px; text-align: right; }
/* 预览 (OF1, owner S-414): a succeeded row's way to its result, beside the
   ⋯. From 1440px it is a labelled button in an 88px column; below, the
   play icon alone in a 40px column, quiet as the ⋯, and every other
   column stays as it was (see the widths below). */
.tasks-table .c-preview { width: 88px; }
.tasks-preview-button .glyph { margin-left: -1px; }
.tasks-table td.c-key, .tasks-table td.c-created { white-space: nowrap; }
.tasks-table td.c-key > .ellipsis { display: block; }
.tasks-status-cell { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.tasks-task { display: flex; align-items: center; gap: 12px; min-width: 0; }
.tasks-text { display: flex; flex-direction: column; min-width: 0; }
.tasks-open { color: var(--text-1); font-weight: 400; }
.tasks-table tbody tr:hover .tasks-open { color: var(--text-1); }
.thumb.is-glyph { background: var(--gray-50); color: var(--gray-600); font: 500 12px/16px var(--font-sans); letter-spacing: .01em; }
.table tbody tr:hover .thumb.is-glyph, .table tbody tr.is-open .thumb.is-glyph { background: var(--gray-100); }
.tasks-id { display: flex; align-items: center; gap: 4px; min-width: 0; }
.tasks-id .cell-id { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tasks-copy { opacity: 0; transition: opacity var(--t-hover) var(--ease); }
.table tbody tr:hover .tasks-copy, .table tbody tr.is-open .tasks-copy, .tasks-copy:focus-visible, .tasks-copy.is-copied { opacity: 1; }
.tasks-meta-sm { display: none; }
.tasks-more { position: relative; display: inline-flex; }
.tasks-row-menu { position: absolute; top: calc(100% + 4px); right: 0; z-index: var(--z-menu); min-width: 180px; text-align: left; }
/* A row whose status changed while on screen flashes once (board: 任务完成). */
.tasks-table tbody tr.is-changed > td { animation: tasks-flash 1.2s var(--ease); }
@keyframes tasks-flash { from { background: var(--success-tint); } to { background: transparent; } }
.tasks-empty-row td, .table tbody tr.tasks-empty-row:hover { height: auto; background: transparent; }
.tasks-empty-row td { padding: 0; }
.tasks-empty .btn-primary { margin-top: 20px; }
.tasks-empty .tasks-empty-link { margin-top: 12px; }
.tasks-range { color: var(--text-2); font-variant-numeric: tabular-nums; }
.tasks-pager { flex-wrap: wrap; }
.tasks-size .ctl-per-page-select { width: auto; }
.tasks-turn .glyph { flex: none; }
/* Skeleton rows: a page being read for 200ms or more shows the table's own
   columns in gray bars, the toolbar and the table head kept on screen. */
.tasks-skel-tr td { height: 56px; }
.table tbody tr.tasks-skel-tr:hover { background: transparent; }
.tasks-skel-tr .tasks-skel-badge { width: 56px; height: 22px; border-radius: var(--r-6); }
.tasks-skel-tr .tasks-skel-cell { width: 72%; max-width: 120px; }
.tasks-skel-tr .tasks-skel-num { width: 48px; margin-left: auto; }

/* With the sheet open from 1440px the list narrows beside it to the board's
   three columns (状态 · 任务 · 费用), without the model tile and the ⋯, so
   the task keeps the room for its name; below 1440px the narrowed card
   would fall under about 480px, so the sheet floats over the list instead
   and the list keeps its width and columns. Below 1280px the ID column
   gives way to the task column. */
@media (min-width: 1440px) {
  .tasks.has-sheet .tasks-card { margin-right: 648px; }
  /* The head narrows with the card and keeps one row, so 生成视频 stays
     beside the list (TaskDetail board) instead of under the sheet: the
     line under the title ends in an ellipsis (its title holds it all). */
  .tasks.has-sheet > .page-head { flex-wrap: nowrap; margin-right: 648px; }
  .tasks.has-sheet > .page-head > div { flex: 1 1 auto; min-width: 0; }
  .tasks.has-sheet > .page-head > .btn { flex: none; }
  .tasks.has-sheet .tasks-intro { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tasks.has-sheet .tasks-table :is(.c-id, .c-key, .c-elapsed, .c-created, .c-more) { display: none; }
  .tasks.has-sheet .tasks-table .thumb { display: none; }
  .tasks.has-sheet .tasks-table .c-preview { display: none; }
  .tasks.has-sheet .tasks-search { flex: 1 1 200px; }
  /* The chips flow beside the search, so 更新于 and the refresh end the
     second line (board) instead of taking a line of their own. */
  .tasks.has-sheet .tasks-filters { display: contents; }
}
/* Below 1440px 预览 is its play icon alone in a 40px column (the 32px
   icon and 4px each side); the other columns give way as before. */
@media (max-width: 1439px) {
  .tasks-table .c-preview { width: 40px; padding-right: 4px; padding-left: 4px; }
  .tasks-preview-button.btn { width: 32px; height: 32px; gap: 0; padding: 0; border-color: transparent; border-radius: var(--r-6); background: transparent; box-shadow: none; color: var(--gray-700); }
  .tasks-preview-button.btn:hover { border-color: transparent; background: var(--wash-1); color: var(--text-1); }
  .tasks-preview-button.btn:active { background: var(--wash-2); color: var(--text-1); }
  .tasks-preview-button.btn:disabled, .tasks-preview-button.btn:disabled:hover { border-color: transparent; background: transparent; color: var(--gray-400); }
  .tasks-preview-button .glyph { margin-left: 1px; }
  .tasks-preview-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@media (max-width: 1279px) {
  .tasks-table .c-id { display: none; }
}
@media (max-width: 1023px) {
  .tasks-table .c-elapsed, .tasks-table .c-key { display: none; }
}

/* The sheet: under the 56px top bar, 640 wide (560 below 1280), the whole
   screen on phones; its header holds the title, the copyable ID, the
   previous and next task and the close button. */
.tasks-sheet { top: 64px; }
.tasks-sheet-head { gap: 8px; }
.tasks-sheet-id { gap: 6px; color: var(--text-2); }
.tasks-sheet-id .mono { font-size: 13px; line-height: 20px; }
.tasks-sheet-end { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.glyph-pub-chev-down.is-up { transform: rotate(180deg); }
.tasks-sheet-head .btn[aria-disabled="true"] { color: var(--gray-400); cursor: default; }
.tasks-sheet-body { padding: 0; }
.tasks-summary { padding: 16px 20px 0; }
.tasks-summary:empty { display: none; }
.tasks-statusrow { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.tasks-prompt { display: -webkit-box; margin: 8px 0 0; overflow: hidden; color: var(--text-1); font: 600 16px/24px var(--font-sans); overflow-wrap: anywhere; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
.tasks-banner { margin: 12px 0 0; }
.tasks-dl { grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) minmax(0, 1fr); margin-top: 16px; padding: 16px 0; border-top: 1px solid var(--line-soft); }
.tasks-dl dd { overflow-wrap: anywhere; }
.tasks-tabs { position: sticky; top: 0; z-index: 2; padding: 0 20px; background: var(--gray-0); }
.tasks-panel { padding: 20px 20px 24px; }
.tasks-panel:empty { display: none; }
/* Section headings in the sheet are CJK at 14px, so 500 (SHELL 1.4: 600
   only from 16px). */
.tasks-panel-title { margin: 0 0 8px; color: var(--text-1); font: 500 14px/20px var(--font-sans); }
.tasks-panel-intro { margin: 0 0 12px; color: var(--text-3); font-size: 13px; line-height: 20px; }
.tasks-panel-notice { margin: 0; color: var(--text-2); font-size: 13px; line-height: 20px; }
.tasks-panel-notice:empty { display: none; }
.tasks-panel-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.tasks-panel-actions:not(:has(> :not([hidden]))) { display: none; }
.tasks-section { margin-top: 24px; }
.tasks-section:first-child { margin-top: 0; }

/* 结果: a tile by status (running, failed, cancelled, expired or
   unavailable, or a task the address named that is not there or not read),
   the result playing with its facts and until when it can be
   downloaded (shared/preview.js), any other file, why a task failed and
   the cancellation record. */
.tasks-tile { position: relative; display: grid; place-items: center; min-height: 216px; overflow: hidden; border-radius: var(--r-12); background: var(--gray-100); text-align: center; }
.tasks-tile.is-live::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .6), rgba(255, 255, 255, 0)); transform: translateX(-100%); animation: tasks-shimmer 1.4s var(--ease) infinite; }
@keyframes tasks-shimmer { to { transform: translateX(100%); } }
.tasks-tile-in { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 24px; }
.tasks-tile-icon { display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 12px; border-radius: var(--r-8); background: var(--gray-0); color: var(--gray-700); box-shadow: 0 0 0 1px var(--line), var(--e1); }
.tasks-tile-icon .glyph-video-32 { width: 20px; height: 20px; }
.tasks-tile-icon.is-danger { background: var(--danger-tint); color: var(--danger-fg); box-shadow: none; }
.tasks-tile-icon.is-live { background: var(--accent-tint); color: var(--violet-700); box-shadow: none; }
.tasks-tile-title { margin: 0; color: var(--text-1); font: 600 16px/24px var(--font-sans); }
.tasks-tile-sub { max-width: 400px; margin: 0; color: var(--text-2); font-size: 13px; line-height: 20px; text-wrap: pretty; }
/* A task the address named that is not there, or a read of it not
   confirmed (FE-TASK-LINK), says so in this tile; 重新读取 sits under it. */
.tasks-tile-in > .btn { margin-top: 16px; }
.tasks-tile + .tasks-section, .tasks-tile + .task-output { margin-top: 24px; }
.tasks-steps { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 20px; margin: 20px 0 0; padding: 0; color: var(--text-3); font-size: 12px; line-height: 16px; list-style: none; }
.tasks-steps li { position: relative; display: inline-flex; align-items: center; gap: 4px; }
.tasks-steps li + li::before { content: ""; position: absolute; top: 50%; left: -16px; width: 12px; height: 1px; background: var(--gray-300); }
.tasks-steps li.is-done { color: var(--text-2); }
.tasks-steps li.is-now { color: var(--accent-fg); font-weight: 500; }
.tasks-steps .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gray-300); }
.tasks-steps .is-now .dot { background: var(--violet-500); }
.task-output { display: flex; flex-direction: column; gap: 8px; }
.tasks-player { flex: none; }
.tasks-player-meta { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; margin: 4px 0 4px; color: var(--text-2); font-size: 13px; line-height: 20px; font-variant-numeric: tabular-nums; }
.tasks-player-meta .task-result-until { margin-left: auto; white-space: nowrap; }
.tasks-player-meta .task-result-until:empty { display: none; }
.task-result { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 16px; align-items: center; padding: 12px 16px; border: 1px solid var(--line); border-radius: var(--r-8); background: var(--gray-0); }
.task-result > p { margin: 0; }
.task-result-name { color: var(--text-1); font-size: 14px; font-weight: 500; line-height: 20px; }
.task-result-state, .task-result-until { grid-column: 1; color: var(--text-2); font-size: 13px; line-height: 20px; }
.task-result-open { grid-column: 2; grid-row: 1 / span 3; }
/* A note that wraps on phones reads at 13/20 (C10). */
.tasks-link-note { margin: 4px 0 0; color: var(--text-3); font-size: 13px; line-height: 20px; }
.tasks-kv { display: flex; flex-direction: column; margin: 0; }
.tasks-kv > div { display: grid; grid-template-columns: 152px minmax(0, 1fr); gap: 12px; align-items: center; min-height: 40px; padding: 8px 0; border-bottom: 1px solid var(--line-soft); }
.tasks-kv > div:first-child { border-top: 1px solid var(--line-soft); }
.tasks-kv dt { color: var(--text-2); font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }
.tasks-kv dd { display: flex; align-items: center; gap: 4px; min-width: 0; margin: 0; color: var(--text-1); font-size: 14px; line-height: 20px; }
.tasks-kv dd .btn { margin: -4px 0; }
.tasks-kv dd .mono { font: 400 13px/20px var(--font-mono); }
.tasks-kv-mono dt, .tasks-kv-mono dd { font: 400 13px/20px var(--font-mono); }
.tasks-kv-mono .tasks-sans { font-family: var(--font-sans); font-size: 14px; }
.tasks-kv-money dd { justify-content: flex-end; font-variant-numeric: tabular-nums; }
.tasks-kv-copy { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }

/* 时间线: the customer's own states, each with its time and a line of what
   it meant. */
.tasks-timeline { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.tasks-tl-item { position: relative; display: grid; grid-template-columns: 10px minmax(0, 1fr) auto; gap: 14px; padding-bottom: 20px; }
.tasks-tl-item::before { content: ""; position: absolute; top: 16px; bottom: -4px; left: 5px; width: 1px; background: var(--gray-200); }
.tasks-tl-item:last-child { padding-bottom: 0; }
.tasks-tl-item:last-child::before { display: none; }
.tasks-tl-dot { position: relative; z-index: 1; width: 10px; height: 10px; margin-top: 5px; border-radius: 50%; background: var(--gray-400); box-shadow: 0 0 0 3px var(--gray-0); }
.tasks-tl-dot.is-ok { background: var(--success-dot); }
.tasks-tl-dot.is-fail { background: var(--danger-solid); }
.tasks-tl-dot.is-ink { background: var(--gray-900); }
.tasks-tl-title { color: var(--text-1); font-size: 14px; line-height: 20px; }
.tasks-tl-note { color: var(--text-3); font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }
.tasks-tl-time { color: var(--text-3); font-size: 13px; line-height: 20px; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* 请求 and 响应: the request line, the allowlisted headers and the JSON in
   the code colours, clamped at 420px with its own scroll. The path never
   breaks inside a word; on phones the time takes its own line. */
.tasks-reqline { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; min-width: 0; margin: 0 0 12px; }
.tasks-method { flex: none; color: var(--text-1); font: 500 12px/16px var(--font-mono); }
.tasks-path { min-width: 0; color: var(--text-1); font: 400 13px/20px var(--font-mono); overflow-wrap: normal; }
.tasks-when { flex: none; margin-left: auto; color: var(--text-3); font-size: 13px; line-height: 20px; white-space: nowrap; }
.tasks-code { margin-top: 16px; }
.tasks-panel-intro + .tasks-code { margin-top: 0; }
.tasks-code .code-head { padding: 0 6px 0 12px; }
.tasks-code .code-label { margin-right: 8px; padding: 0; }
.tasks-code-status { height: 20px; }
.tasks-code pre { max-height: 420px; white-space: pre; }
.tasks-code pre:empty { display: none; }
.tasks-request-view .tasks-panel-intro { margin-top: 12px; }

/* Callbacks and charge details: tables bleeding to the sheet's edges. */
.tasks-bleed { margin: 0 -20px; }
.tasks-cb, .tasks-ledger { table-layout: fixed; }
.tasks-cb thead th, .tasks-ledger thead th { border-top: 1px solid var(--line-soft); }
.tasks-cb tr > :first-child, .tasks-ledger tr > :first-child { padding-left: 20px; }
.tasks-cb tr > :last-child, .tasks-ledger tr > :last-child { padding-right: 20px; }
.tasks-cb td { height: 64px; padding-top: 8px; padding-bottom: 8px; }
.tasks-cb .c-res { width: 168px; }
.tasks-cb .c-last { width: 160px; }
.tasks-cb-target { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin: 0 0 12px; }
.tasks-cb-k { color: var(--text-3); font-size: 13px; line-height: 20px; }
.tasks-cb-url { min-width: 0; color: var(--text-1); font: 400 13px/20px var(--font-mono); overflow-wrap: anywhere; }
.tasks-evtype { overflow: hidden; color: var(--text-3); font: 400 12px/16px var(--font-mono); text-overflow: ellipsis; white-space: nowrap; }
.tasks-attempts-n { margin-top: 2px; color: var(--text-3); font-size: 12px; line-height: 16px; }
.task-callback-more { margin: 12px 0 0; color: var(--text-2); font-size: 13px; line-height: 20px; }
.tasks-charge-hero { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.tasks-formula { margin-top: 4px; color: var(--text-2); font-size: 13px; line-height: 20px; }
.tasks-facts { margin-top: 20px; }
.tasks-facts > summary { color: var(--text-2); font: 500 13px/20px var(--font-sans); cursor: pointer; }
.tasks-facts[open] > summary { margin-bottom: 8px; }
.tasks-sheet:focus { outline: none; }
.tasks-billing-events .tasks-kv { margin-bottom: 16px; }
.tasks-ledger .c-time { width: 136px; }
.tasks-ledger td.c-time { text-align: left; }
.tasks-ledger .c-type { width: 120px; }
.tasks-ledger .c-amt { width: 128px; text-align: right; }
.tasks-ledger .c-amt.c-3 { color: var(--text-3); }
.tasks-ledger tbody tr:last-child td { border-bottom: 1px solid var(--line-soft); }
/* The way to the full bill sits under the details, at the start (board). */
.tasks-billing-link { order: -1; margin-right: auto; }

/* The sheet's footer: the keys at the start, then the cancel and the
   result link as its one primary action. */
.tasks-sheet-foot { align-items: center; }
.tasks-shortcuts { display: inline-flex; align-items: center; gap: 6px; margin: 0 auto 0 0; color: var(--text-3); font-size: 12px; line-height: 16px; }
.tasks-shortcuts .kbd + span + .kbd { margin-left: 8px; }
.tasks-cancel-notice { flex: 1 1 100%; order: -1; margin: 0; color: var(--text-2); font-size: 13px; line-height: 20px; }
.tasks-cancel-notice:empty { display: none; }
.tasks-download .glyph, .tasks-copy-link .glyph { margin-left: -2px; }
/* A sheet with no task confirmed in it (a task the address named that is
   not there, or a read of it that was not confirmed, FE-TASK-LINK) shows
   the tile of 结果 alone: the tabs, their other panels and the keys go, and
   a footer left with nothing to offer goes with them. */
.tasks-sheet.is-unconfirmed :is(.tasks-tabs, .tasks-shortcuts), .tasks-sheet.is-unconfirmed .tasks-panel:not(.tasks-detail) { display: none; }
.tasks-sheet.is-unconfirmed .tasks-sheet-foot:not(:has(> .btn:not([hidden]), > .tasks-cancel-notice:not(:empty))) { display: none; }

/* The cancel dialog: the safe answer focused, Esc keeps the task. */
.tasks-dialog-task { margin: 0; color: var(--text-3); font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }

/* Loading: the skeleton of the page in the console's place, 200ms into the
   first read of this account; the status line is then read aloud only. A
   failure shows the line with the way back to the first page; a line said
   while the page is on screen keeps that way back beside it. */
.tasks-skeleton { display: none; }
main:has(#tasks-status.is-loading) .tasks-skeleton { display: block; animation: tasks-appear 1ms linear 200ms both; }
@keyframes tasks-appear { from { opacity: 0; } to { opacity: 1; } }
#tasks-page:not([hidden]) ~ .tasks-skeleton { display: none; }
.tasks-skeleton .page-head > div { display: flex; flex-direction: column; gap: 10px; }
.tasks-skel-title { width: 72px; height: 20px; }
.tasks-skel-desc { width: 280px; max-width: 70vw; }
.tasks-skel-card { overflow: hidden; }
.tasks-skel-search { width: 280px; height: 32px; border-radius: var(--r-6); }
.tasks-skel-chip { width: 64px; height: 28px; border-radius: var(--r-6); }
.tasks-skel-row { display: flex; align-items: center; gap: 16px; height: 56px; padding: 0 var(--table-edge); border-bottom: 1px solid var(--line-soft); }
.tasks-skel-row:last-child { border-bottom: 0; }
.tasks-skel-badge { width: 56px; height: 22px; border-radius: var(--r-6); }
.tasks-skel-thumb { flex: none; width: 64px; height: 36px; border-radius: var(--r-8); }
.tasks-skel-lines { display: flex; flex: 1 1 auto; flex-direction: column; gap: 8px; max-width: 320px; }
.tasks-skel-line { width: 100%; }
.tasks-skel-sub { width: 60%; }
.tasks-skel-cell { width: 96px; margin-left: auto; }
.tasks-trouble { display: flex; flex-direction: column; align-items: center; gap: 12px; margin-top: 24px; padding: 48px 16px; border: 1px solid var(--line); border-radius: var(--r-12); background: var(--gray-0); text-align: center; }
.tasks-trouble:has(#tasks-status:empty) { display: none; }
.tasks-trouble-icon { margin: 0; color: var(--danger-fg); background: var(--danger-tint); }
.tasks-status { max-width: 400px; margin: 0; color: var(--text-2); font-size: 14px; line-height: 22px; }
.session-tools { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
/* While the first page loads only the skeleton shows; once the page shows,
   a status line that remains (a check that failed later) is a plain line
   with 刷新第一页 beside it. */
main:has(#tasks-status.is-loading) .tasks-trouble, #tasks-page:not([hidden]) ~ .tasks-trouble { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 12px 0 0; padding: 0; border: 0; background: none; text-align: left; }
main:has(#tasks-status.is-loading) .tasks-trouble > :not(#tasks-status), #tasks-page:not([hidden]) ~ .tasks-trouble > .tasks-trouble-icon, #tasks-page:not([hidden]) ~ .tasks-trouble #tasks-sign-out { display: none; }
main:has(#tasks-status.is-loading) #tasks-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Phones: two-line rows (the task over its status, charge and time), the
   sheet fills the screen, the toolbar search takes the row. */
@media (max-width: 767px) {
  .tasks > .page-head { margin-bottom: 16px; }
  .tasks-search { flex: 1 1 100%; width: 100%; }
  /* The chips flow on the toolbar's own lines, so the refresh ends the
     last chip line instead of a line of its own. */
  .tasks-filters { display: contents; }
  .tasks-table { display: block; }
  .tasks-table thead { display: none; }
  .tasks-table tbody { display: block; }
  .tasks-table tbody tr { display: flex; align-items: center; gap: 4px; padding: 12px 8px 12px 16px; border-bottom: 1px solid var(--line-soft); }
  .tasks-table tbody tr:last-child { border-bottom: 0; }
  .table.tasks-table td { display: block; height: auto; padding: 0; border: 0; }
  .tasks-table td:is(.c-status, .c-id, .c-key, .c-elapsed, .c-charge, .c-created) { display: none; }
  .tasks-table td.c-task { flex: 1 1 auto; min-width: 0; }
  .tasks-table td.c-more { flex: none; width: auto; }
  /* 预览 keeps its place beside the ⋯ as the 32px play icon: it answers
     taps over 44px (7px around its 30px inside its border) and stands
     12px from the ⋯, so neither hit area covers the other. */
  .tasks-table td.c-preview { flex: none; width: auto; margin-right: 8px; }
  .tasks-table td.c-preview:empty { display: none; }
  .tasks-preview-button.btn::before { content: ""; position: absolute; inset: -7px; }
  .tasks-table tr.tasks-empty-row { display: block; padding: 0; }
  .tasks-table tr.tasks-empty-row td { display: block; }
  .tasks-table tr.tasks-skel-tr { height: 72px; }
  .tasks-sub-lg { display: none; }
  .tasks-meta-sm { display: flex; align-items: center; gap: 8px; min-width: 0; margin-top: 4px; color: var(--text-3); font-size: 13px; line-height: 20px; }
  .tasks-meta-sm .stage-line { flex: none; }
  .tasks-foot { justify-content: flex-start; }
  .tasks-pager { flex-wrap: nowrap; width: 100%; }
  .tasks-size { flex: 0 1 auto; min-width: 0; margin-right: auto; }
  .tasks-sheet-head .sheet-title { display: none; }
  .tasks-sheet { top: 0; right: 0; bottom: 0; left: 0; width: auto; max-width: none; border-radius: 0; }
  .tasks-sheet-head { padding: 0 8px 0 16px; }
  .tasks-summary { padding: 16px 16px 0; }
  .tasks-tabs { padding: 0 16px; }
  .tasks-panel { padding: 20px 16px 24px; }
  .tasks-bleed { margin: 0 -16px; }
  .tasks-cb tr > :first-child, .tasks-ledger tr > :first-child { padding-left: 16px; }
  .tasks-cb tr > :last-child, .tasks-ledger tr > :last-child { padding-right: 16px; }
  .tasks-cb .c-last, .tasks-ledger .c-desc { display: none; }
  .tasks-dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tasks-kv > div { grid-template-columns: minmax(0, 1fr); gap: 2px; align-items: start; }
  .tasks-when { flex: 1 1 100%; margin-left: 0; }
  .tasks-shortcuts { display: none; }
  .tasks-sheet-foot { justify-content: flex-end; }
  /* Without its keys, a footer with no action and no line to say (a task
     the address named that is not there, one still running) goes. */
  .tasks-sheet-foot:not(:has(> .btn:not([hidden]), > .tasks-cancel-notice:not(:empty))) { display: none; }
  .tasks-skel-search { width: 100%; }
  .tasks-skel-chip { display: none; }
}
/* From 768px to 1439px the sheet floats over the list without dimming it,
   and the list keeps its width; Esc and × close the sheet. */
@media (min-width: 768px) and (max-width: 1279px) {
  .tasks-sheet { width: 560px; }
}
@media (prefers-reduced-motion: reduce) {
  .tasks-tile.is-live::after, .tasks-bar > span, .tasks-table tbody tr.is-changed > td { animation: none; }
}
