Add Prettier and ESLint tooling (Refs #77)
This commit is contained in:
@@ -1,86 +1,245 @@
|
||||
<script lang="ts">
|
||||
import OperationTime from '$ui/components/OperationTime.svelte';
|
||||
import type { ProvisioningDetail } from '$lib/provisioning-detail.js';
|
||||
import { activeProvisioningStates, provisioningCheckValue, provisioningGroups, progressIcons, progressStateLabels } from '$ui/provisioning-presentation.js';
|
||||
import {
|
||||
activeProvisioningStates,
|
||||
provisioningCheckValue,
|
||||
provisioningGroups,
|
||||
progressIcons,
|
||||
progressStateLabels
|
||||
} from '$ui/provisioning-presentation.js';
|
||||
|
||||
let { detail, hostHistoryHref }: { detail: ProvisioningDetail; hostHistoryHref?: string } = $props();
|
||||
let { detail, hostHistoryHref }: { detail: ProvisioningDetail; hostHistoryHref?: string } =
|
||||
$props();
|
||||
const groups = $derived(provisioningGroups(detail));
|
||||
const progress = $derived(detail.progress);
|
||||
const active = $derived(activeProvisioningStates.includes(detail.deployment.state));
|
||||
let expanded = $state<Record<string, boolean>>({});
|
||||
const evidenceLabels = { pass: 'Passed', waiting: 'Waiting', fail: 'Failed', unknown: 'Unknown' };
|
||||
const sources = { agent: 'Host agent', rcon: 'RCON', telemetry: 'Telemetry', combined: 'RCON and telemetry', manifest: 'Plutonium manifest' };
|
||||
const evidenceLabels = {
|
||||
pass: 'Passed',
|
||||
waiting: 'Waiting',
|
||||
fail: 'Failed',
|
||||
unknown: 'Unknown'
|
||||
};
|
||||
const sources = {
|
||||
agent: 'Host agent',
|
||||
rcon: 'RCON',
|
||||
telemetry: 'Telemetry',
|
||||
combined: 'RCON and telemetry',
|
||||
manifest: 'Plutonium manifest'
|
||||
};
|
||||
</script>
|
||||
|
||||
<section class="execution" aria-labelledby="execution-title">
|
||||
<div class="section-heading"><div><span class="eyebrow">Execution</span><h2 id="execution-title">Progress and evidence</h2></div></div>
|
||||
<div class="section-heading">
|
||||
<div>
|
||||
<span class="eyebrow">Execution</span>
|
||||
<h2 id="execution-title">Progress and evidence</h2>
|
||||
</div>
|
||||
</div>
|
||||
{#if !progress}
|
||||
<div class="legacy"><h3>{detail.deployment.stage}</h3><p>Detailed checkpoints were not recorded for this operation. Its recorded outcome and original activity remain available below.</p></div>
|
||||
<div class="legacy">
|
||||
<h3>{detail.deployment.stage}</h3>
|
||||
<p>
|
||||
Detailed checkpoints were not recorded for this operation. Its recorded outcome and
|
||||
original activity remain available below.
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
{#if groups.length}
|
||||
<ol class="phases">
|
||||
{#each groups as group (group.key)}
|
||||
{@const defaultOpen = detail.deployment.state !== 'done' || group.steps.some(step => step.state === 'failed' || step.checks.some(check => check.result !== 'pass'))}
|
||||
<li class:current={active && (group.state === 'current' || group.state === 'waiting')} class:failed={group.state === 'failed'}>
|
||||
{@const defaultOpen =
|
||||
detail.deployment.state !== 'done' ||
|
||||
group.steps.some(
|
||||
(step) =>
|
||||
step.state === 'failed' ||
|
||||
step.checks.some((check) => check.result !== 'pass')
|
||||
)}
|
||||
<li
|
||||
class:current={active &&
|
||||
(group.state === 'current' || group.state === 'waiting')}
|
||||
class:failed={group.state === 'failed'}
|
||||
>
|
||||
<details open={expanded[group.key] ?? defaultOpen}>
|
||||
<summary
|
||||
onclick={event => { event.preventDefault(); expanded[group.key] = !(expanded[group.key] ?? defaultOpen); }}
|
||||
onkeydown={event => {
|
||||
onclick={(event) => {
|
||||
event.preventDefault();
|
||||
expanded[group.key] = !(expanded[group.key] ?? defaultOpen);
|
||||
}}
|
||||
onkeydown={(event) => {
|
||||
if (event.key !== 'Enter' && event.key !== ' ') return;
|
||||
event.preventDefault();
|
||||
if (!event.repeat) expanded[group.key] = !(expanded[group.key] ?? defaultOpen);
|
||||
if (!event.repeat)
|
||||
expanded[group.key] = !(expanded[group.key] ?? defaultOpen);
|
||||
}}
|
||||
>
|
||||
<span class="phase-icon state-{group.state}" aria-hidden="true">{progressIcons[group.state]}</span>
|
||||
<span class="phase-icon state-{group.state}" aria-hidden="true"
|
||||
>{progressIcons[group.state]}</span
|
||||
>
|
||||
<span class="phase-title">{group.label}</span>
|
||||
<span class="phase-state state-{group.state}">{progressStateLabels[group.state]}</span>
|
||||
<span class="phase-state state-{group.state}"
|
||||
>{progressStateLabels[group.state]}</span
|
||||
>
|
||||
</summary>
|
||||
<ol class="steps">
|
||||
{#each group.steps as step (step.key)}
|
||||
<li aria-current={active && (step.state === 'current' || step.state === 'waiting') ? 'step' : undefined}>
|
||||
<span class="step-icon state-{step.state}" aria-hidden="true">{progressIcons[step.state]}</span>
|
||||
<li
|
||||
aria-current={active &&
|
||||
(step.state === 'current' || step.state === 'waiting')
|
||||
? 'step'
|
||||
: undefined}
|
||||
>
|
||||
<span class="step-icon state-{step.state}" aria-hidden="true"
|
||||
>{progressIcons[step.state]}</span
|
||||
>
|
||||
<div class="step-content">
|
||||
<strong>{step.label}</strong>
|
||||
<span class="step-meta state-{step.state}">{progressStateLabels[step.state]}{#if step.at}{' · '}<span class="time"><OperationTime start={detail.deployment.started_at} value={step.at} /></span>{/if}</span>
|
||||
<span class="step-meta state-{step.state}"
|
||||
>{progressStateLabels[
|
||||
step.state
|
||||
]}{#if step.at}{' · '}<span class="time"
|
||||
><OperationTime
|
||||
start={detail.deployment.started_at}
|
||||
value={step.at}
|
||||
/></span
|
||||
>{/if}</span
|
||||
>
|
||||
{#each step.checks as check (check.key)}
|
||||
<div class="evidence">
|
||||
{#if step.checks.length > 1 || check.key === 'plutonium-release'}<p class="check-label">{check.label}{' · '}{evidenceLabels[check.result]}</p>{/if}
|
||||
{#if step.checks.length > 1 || check.key === 'plutonium-release'}<p
|
||||
class="check-label"
|
||||
>
|
||||
{check.label}{' · '}{evidenceLabels[
|
||||
check.result
|
||||
]}
|
||||
</p>{/if}
|
||||
<dl class="values">
|
||||
{#if check.expected !== null}<div><dt>Expected</dt><dd>{provisioningCheckValue(check.key, check.expected)}</dd></div>{/if}
|
||||
<div><dt>Observed</dt><dd>{provisioningCheckValue(check.key, check.actual)}</dd></div>
|
||||
{#if check.expected !== null}<div>
|
||||
<dt>Expected</dt>
|
||||
<dd>
|
||||
{provisioningCheckValue(
|
||||
check.key,
|
||||
check.expected
|
||||
)}
|
||||
</dd>
|
||||
</div>{/if}
|
||||
<div>
|
||||
<dt>Observed</dt>
|
||||
<dd>
|
||||
{provisioningCheckValue(
|
||||
check.key,
|
||||
check.actual
|
||||
)}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
{#if check.message}<p>{check.message}</p>{/if}
|
||||
<div class="evidence-meta">
|
||||
<span>{check.source ? sources[check.source] : 'Source not recorded'}</span>
|
||||
{#if check.checkedAt !== step.at}<span>Checked <OperationTime start={detail.deployment.started_at} value={check.checkedAt} /></span>{/if}
|
||||
{#if check.receivedAt}<span>Evidence received <OperationTime start={detail.deployment.started_at} value={check.receivedAt} /></span>{/if}
|
||||
<span
|
||||
>{check.source
|
||||
? sources[check.source]
|
||||
: 'Source not recorded'}</span
|
||||
>
|
||||
{#if check.checkedAt !== step.at}<span
|
||||
>Checked <OperationTime
|
||||
start={detail.deployment.started_at}
|
||||
value={check.checkedAt}
|
||||
/></span
|
||||
>{/if}
|
||||
{#if check.receivedAt}<span
|
||||
>Evidence received <OperationTime
|
||||
start={detail.deployment.started_at}
|
||||
value={check.receivedAt}
|
||||
/></span
|
||||
>{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{#if step.key === 'verify-map' && detail.deployment.expected_map}<p class="map-note">Engine-map verification does not independently verify a variant or start location.</p>{/if}
|
||||
{#if step.key === 'verify-map' && detail.deployment.expected_map}<p
|
||||
class="map-note"
|
||||
>
|
||||
Engine-map verification does not independently
|
||||
verify a variant or start location.
|
||||
</p>{/if}
|
||||
{#if step.command}
|
||||
<div class="evidence" class:uncertain={step.command.state === 'uncertain'}>
|
||||
<p class="command-label">{step.command.state === 'attempted' ? 'Command submission attempted' : step.command.state === 'accepted' ? 'Remote request accepted' : step.command.state === 'rejected' ? 'Remote request rejected' : 'Remote response uncertain'}</p>
|
||||
<div
|
||||
class="evidence"
|
||||
class:uncertain={step.command.state === 'uncertain'}
|
||||
>
|
||||
<p class="command-label">
|
||||
{step.command.state === 'attempted'
|
||||
? 'Command submission attempted'
|
||||
: step.command.state === 'accepted'
|
||||
? 'Remote request accepted'
|
||||
: step.command.state === 'rejected'
|
||||
? 'Remote request rejected'
|
||||
: 'Remote response uncertain'}
|
||||
</p>
|
||||
<p>{step.command.message}</p>
|
||||
<span class="time"><OperationTime start={detail.deployment.started_at} value={step.command.at} /></span>
|
||||
<span class="time"
|
||||
><OperationTime
|
||||
start={detail.deployment.started_at}
|
||||
value={step.command.at}
|
||||
/></span
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
{#if step.agentOperation}
|
||||
<div class="evidence">
|
||||
<dl class="agent-details">
|
||||
<div><dt>Agent state</dt><dd>{step.agentOperation.state}</dd></div>
|
||||
<div><dt>Command queued</dt><dd><OperationTime start={detail.deployment.started_at} value={step.agentOperation.createdAt} missing="Not recorded" /></dd></div>
|
||||
<div><dt>Latest agent report</dt><dd><OperationTime start={detail.deployment.started_at} value={step.agentOperation.updatedAt} missing="Not recorded" /></dd></div>
|
||||
<div>
|
||||
<dt>Agent state</dt>
|
||||
<dd>{step.agentOperation.state}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Command queued</dt>
|
||||
<dd>
|
||||
<OperationTime
|
||||
start={detail.deployment.started_at}
|
||||
value={step.agentOperation
|
||||
.createdAt}
|
||||
missing="Not recorded"
|
||||
/>
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Latest agent report</dt>
|
||||
<dd>
|
||||
<OperationTime
|
||||
start={detail.deployment.started_at}
|
||||
value={step.agentOperation
|
||||
.updatedAt}
|
||||
missing="Not recorded"
|
||||
/>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
{#if step.agentOperation.error}<p class="agent-error">{step.agentOperation.error}</p>{/if}
|
||||
<a href={hostHistoryHref ?? `/hosts/operations?server=${encodeURIComponent(detail.deployment.server)}`}>View host operation history</a>
|
||||
{#if step.agentOperation.error}<p
|
||||
class="agent-error"
|
||||
>
|
||||
{step.agentOperation.error}
|
||||
</p>{/if}
|
||||
<a
|
||||
href={hostHistoryHref ??
|
||||
`/hosts/operations?server=${encodeURIComponent(detail.deployment.server)}`}
|
||||
>View host operation history</a
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
{#if step.checkpoints.length}<ul class="checkpoints">
|
||||
{#each step.checkpoints as checkpoint (checkpoint.key)}
|
||||
<li><span>{checkpoint.label}</span><span class="time"><OperationTime start={detail.deployment.started_at} value={checkpoint.at} /></span></li>
|
||||
{/each}
|
||||
</ul>{/if}
|
||||
{#each step.checkpoints as checkpoint (checkpoint.key)}
|
||||
<li>
|
||||
<span>{checkpoint.label}</span><span
|
||||
class="time"
|
||||
><OperationTime
|
||||
start={detail.deployment.started_at}
|
||||
value={checkpoint.at}
|
||||
/></span
|
||||
>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>{/if}
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
@@ -93,50 +252,262 @@
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.execution { display: grid; gap: var(--space-5); min-width: 0; }
|
||||
h2, h3, p { margin: 0; }
|
||||
h2 { font-size: var(--text-lg); letter-spacing: var(--tracking-tight); }
|
||||
h3 { font-size: var(--text-sm); font-weight: var(--weight-semibold); }
|
||||
.eyebrow { display: block; margin-bottom: var(--space-2); font-size: var(--text-xs); color: var(--text-tertiary); }
|
||||
.phases, .steps, .checkpoints { list-style: none; padding: 0; margin: 0; }
|
||||
.phases { display: grid; gap: var(--space-3); }
|
||||
.phases > li { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface); overflow: hidden; }
|
||||
.phases > li.current { border-color: color-mix(in srgb, var(--accent-primary) 60%, var(--border-subtle)); }
|
||||
.phases > li.failed { border-color: color-mix(in srgb, var(--state-danger) 60%, var(--border-subtle)); }
|
||||
summary { cursor: pointer; }
|
||||
.phases summary { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-5); list-style: none; }
|
||||
.phases summary::-webkit-details-marker { display: none; }
|
||||
.phases summary::after { content: '+'; color: var(--text-tertiary); font-size: var(--text-md); }
|
||||
.phases details[open] > summary::after { content: '−'; }
|
||||
summary:focus-visible { outline: 2px solid var(--border-focus); outline-offset: -3px; border-radius: var(--radius-sm); }
|
||||
.phase-icon { flex: 0 0 26px; display: grid; place-items: center; width: 26px; height: 26px; border: 1px solid var(--border-strong); border-radius: var(--radius-pill); font-size: var(--text-sm); }
|
||||
.phase-title { flex: 1; font-size: var(--text-sm); font-weight: var(--weight-semibold); }
|
||||
.phase-state { font-size: var(--text-xs); }
|
||||
.steps { border-top: 1px solid var(--border-subtle); padding: var(--space-4) var(--space-5); display: grid; gap: var(--space-4); }
|
||||
.steps > li { display: flex; align-items: flex-start; gap: var(--space-3); }
|
||||
.step-icon { flex: 0 0 26px; text-align: center; line-height: 1.5; }
|
||||
.steps strong { display: block; font-size: var(--text-sm); font-weight: var(--weight-medium); line-height: 1.5; }
|
||||
.step-meta { display: block; font-size: var(--text-xs); margin-top: var(--space-1); line-height: 1.6; }
|
||||
.state-current { color: var(--accent-primary-hover); }.state-waiting { color: var(--state-warning); }.state-failed { color: var(--state-danger); }.state-done { color: var(--state-online); }
|
||||
.state-unknown, .state-pending, .state-cancelled, .time { color: var(--text-secondary); }
|
||||
.legacy { display: grid; gap: var(--space-2); padding: var(--space-4); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); }
|
||||
p { color: var(--text-secondary); font-size: var(--text-xs); line-height: 1.65; overflow-wrap: anywhere; }
|
||||
.legacy p { font-size: var(--text-sm); }
|
||||
.step-content { min-width: 0; flex: 1; overflow-wrap: anywhere; }
|
||||
.evidence { display: grid; gap: var(--space-1); margin-top: var(--space-2); font-size: var(--text-xs); }
|
||||
.check-label, .command-label { color: var(--text-primary); font-weight: var(--weight-medium); }
|
||||
.uncertain .command-label { color: var(--state-warning); }
|
||||
.agent-error { color: var(--state-danger); }
|
||||
dl { display: flex; gap: var(--space-2) var(--space-4); margin: 0; flex-wrap: wrap; line-height: 1.6; }
|
||||
dt { color: var(--text-tertiary); }dd { margin: 0; color: var(--text-secondary); overflow-wrap: anywhere; }
|
||||
.values > div { display: flex; flex-wrap: wrap; gap: 0 var(--space-1); }
|
||||
.agent-details { margin-block: var(--space-1); }.agent-details > div { min-width: 0; }
|
||||
.time, .evidence-meta, .checkpoints { font-size: var(--text-xs); }
|
||||
.evidence-meta { display: flex; gap: var(--space-1) var(--space-4); flex-wrap: wrap; color: var(--text-tertiary); line-height: 1.6; }
|
||||
.checkpoints { display: grid; gap: var(--space-2); margin-top: var(--space-3); color: var(--text-secondary); line-height: 1.6; }
|
||||
.checkpoints li { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); }
|
||||
.map-note { margin-top: var(--space-2); }
|
||||
a { color: var(--accent-primary-hover); text-underline-offset: 3px; }
|
||||
a:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 3px; border-radius: 2px; }
|
||||
@media (max-width: 600px) { .phases summary { padding: var(--space-4); gap: var(--space-2); flex-wrap: wrap; }.phase-title { flex-basis: calc(100% - 70px); }.phase-state { padding-left: 34px; order: 1; flex-basis: 100%; }.phases summary::after { order: 0; }.steps { padding: var(--space-4); } }
|
||||
.execution {
|
||||
display: grid;
|
||||
gap: var(--space-5);
|
||||
min-width: 0;
|
||||
}
|
||||
h2,
|
||||
h3,
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
h2 {
|
||||
font-size: var(--text-lg);
|
||||
letter-spacing: var(--tracking-tight);
|
||||
}
|
||||
h3 {
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--weight-semibold);
|
||||
}
|
||||
.eyebrow {
|
||||
display: block;
|
||||
margin-bottom: var(--space-2);
|
||||
font-size: var(--text-xs);
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
.phases,
|
||||
.steps,
|
||||
.checkpoints {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.phases {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.phases > li {
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--surface);
|
||||
overflow: hidden;
|
||||
}
|
||||
.phases > li.current {
|
||||
border-color: color-mix(in srgb, var(--accent-primary) 60%, var(--border-subtle));
|
||||
}
|
||||
.phases > li.failed {
|
||||
border-color: color-mix(in srgb, var(--state-danger) 60%, var(--border-subtle));
|
||||
}
|
||||
summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
.phases summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-5);
|
||||
list-style: none;
|
||||
}
|
||||
.phases summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
.phases summary::after {
|
||||
content: '+';
|
||||
color: var(--text-tertiary);
|
||||
font-size: var(--text-md);
|
||||
}
|
||||
.phases details[open] > summary::after {
|
||||
content: '−';
|
||||
}
|
||||
summary:focus-visible {
|
||||
outline: 2px solid var(--border-focus);
|
||||
outline-offset: -3px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
.phase-icon {
|
||||
flex: 0 0 26px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border: 1px solid var(--border-strong);
|
||||
border-radius: var(--radius-pill);
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
.phase-title {
|
||||
flex: 1;
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--weight-semibold);
|
||||
}
|
||||
.phase-state {
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
.steps {
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
padding: var(--space-4) var(--space-5);
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
.steps > li {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.step-icon {
|
||||
flex: 0 0 26px;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.steps strong {
|
||||
display: block;
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--weight-medium);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.step-meta {
|
||||
display: block;
|
||||
font-size: var(--text-xs);
|
||||
margin-top: var(--space-1);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.state-current {
|
||||
color: var(--accent-primary-hover);
|
||||
}
|
||||
.state-waiting {
|
||||
color: var(--state-warning);
|
||||
}
|
||||
.state-failed {
|
||||
color: var(--state-danger);
|
||||
}
|
||||
.state-done {
|
||||
color: var(--state-online);
|
||||
}
|
||||
.state-unknown,
|
||||
.state-pending,
|
||||
.state-cancelled,
|
||||
.time {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.legacy {
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-4);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
p {
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--text-xs);
|
||||
line-height: 1.65;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.legacy p {
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
.step-content {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.evidence {
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
margin-top: var(--space-2);
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
.check-label,
|
||||
.command-label {
|
||||
color: var(--text-primary);
|
||||
font-weight: var(--weight-medium);
|
||||
}
|
||||
.uncertain .command-label {
|
||||
color: var(--state-warning);
|
||||
}
|
||||
.agent-error {
|
||||
color: var(--state-danger);
|
||||
}
|
||||
dl {
|
||||
display: flex;
|
||||
gap: var(--space-2) var(--space-4);
|
||||
margin: 0;
|
||||
flex-wrap: wrap;
|
||||
line-height: 1.6;
|
||||
}
|
||||
dt {
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
dd {
|
||||
margin: 0;
|
||||
color: var(--text-secondary);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.values > div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0 var(--space-1);
|
||||
}
|
||||
.agent-details {
|
||||
margin-block: var(--space-1);
|
||||
}
|
||||
.agent-details > div {
|
||||
min-width: 0;
|
||||
}
|
||||
.time,
|
||||
.evidence-meta,
|
||||
.checkpoints {
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
.evidence-meta {
|
||||
display: flex;
|
||||
gap: var(--space-1) var(--space-4);
|
||||
flex-wrap: wrap;
|
||||
color: var(--text-tertiary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.checkpoints {
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
margin-top: var(--space-3);
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.checkpoints li {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-1) var(--space-3);
|
||||
}
|
||||
.map-note {
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
a {
|
||||
color: var(--accent-primary-hover);
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
a:focus-visible {
|
||||
outline: 2px solid var(--border-focus);
|
||||
outline-offset: 3px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.phases summary {
|
||||
padding: var(--space-4);
|
||||
gap: var(--space-2);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.phase-title {
|
||||
flex-basis: calc(100% - 70px);
|
||||
}
|
||||
.phase-state {
|
||||
padding-left: 34px;
|
||||
order: 1;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
.phases summary::after {
|
||||
order: 0;
|
||||
}
|
||||
.steps {
|
||||
padding: var(--space-4);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user