Files
shd.build/src/routes/agents/[id]/+page.svelte
T
jb d09b6220ee
Validate and deploy production / validate (push) Canceled after 0s
Validate and deploy production / deploy (push) Canceled after 0s
Validate and deploy staging / validate (push) Successful in 27s
Validate and deploy staging / deploy (push) Successful in 54s
feat: defer advanced build calculations
2026-08-02 03:07:12 -04:00

405 lines
32 KiB
Svelte

<script lang="ts">
import AgentIdentityLink from '$lib/components/AgentIdentityLink.svelte';
import AccountControl from '$lib/components/AccountControl.svelte';
import CommentComposer from '$lib/components/CommentComposer.svelte';
import ContentReport from '$lib/components/ContentReport.svelte';
import InfoPopover from '$lib/components/InfoPopover.svelte';
import MarkdownContent from '$lib/components/MarkdownContent.svelte';
import MarkdownEditor from '$lib/components/MarkdownEditor.svelte';
import ModerationDisclosure from '$lib/components/ModerationDisclosure.svelte';
import OverflowMenu from '$lib/components/OverflowMenu.svelte';
import PageBreadcrumb from '$lib/components/PageBreadcrumb.svelte';
import PendingForm from '$lib/components/PendingForm.svelte';
import { tick } from 'svelte';
type PublicAgent = {
id: string;
displayName: string;
publicSlug: string;
avatarUrl: string;
bioHtml: string;
bioMarkdown: string;
isPublic: boolean;
bioHidden: boolean;
bioModerationReason: string | null;
bioReviewPending: boolean;
bioReviewReason: string | null;
roles: string[];
};
type PublicContent = {
id: string;
slug: string;
title: string;
updatedAt: string;
};
type AuthoredComment = {
id: string;
createdAt: string;
targetType: string;
targetTitle: string;
targetHref: string;
};
type ProfileComment = {
id: string;
parentId: string | null;
status: 'visible' | 'removed';
bodyHtml: string;
removalReason: string | null;
createdAt: string;
author: { id: string; displayName: string; publicSlug: string | null; avatarUrl: string; roles: string[] };
canDelete: boolean;
canReport: boolean;
depth: number;
hasReplies: boolean;
rootId: string;
isFollowing: boolean;
isPinned: boolean;
};
type PageData = {
agent: PublicAgent;
counts: { builds: number; guides: number; authoredComments: number; profileComments: number };
builds: PublicContent[];
guides: PublicContent[];
authoredComments: AuthoredComment[];
profileComments: ProfileComment[];
viewer: { id: string | null; canComment: boolean; canReportProfile: boolean; isSelf: boolean };
accountControl: any | null;
};
let { data, form }: { data: PageData; form?: Record<string, any> | null } = $props();
let profileCommentDraft = $state('');
let activeComposerId = $state<string | null>(null);
let deletingCommentId = $state('');
let activeCommentMenuId = $state('');
let bioEditorOpen = $state(false);
let bioDraft = $state('');
let bioDraftInitialized = $state(false);
let handledBioToken = $state('');
let handledCommentToken = $state('');
const resultComposerId = $derived(String(form?.profileCommentParentId ?? '') || 'root');
const notificationIsIsac = (notification: any) =>
notification.category === 'isac' || String(notification.source).startsWith('ISAC');
const dateLabel = (value: string) => {
const date = new Date(value);
return Number.isNaN(date.valueOf())
? 'DATE UNKNOWN'
: date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }).toUpperCase();
};
$effect(() => {
const token = String(form?.profileCommentResultToken ?? form?.commentResultToken ?? '');
if (!token || token === handledCommentToken) return;
handledCommentToken = token;
if (form?.profileCommentSaved || form?.commentSaved) {
profileCommentDraft = '';
activeComposerId = null;
}
if (form?.profileCommentDeleted || form?.commentDeleted) deletingCommentId = '';
if (form?.profileCommentFollowSaved) activeCommentMenuId = '';
});
$effect(() => {
if (!bioDraftInitialized) {
bioDraft = data.agent.bioMarkdown;
bioDraftInitialized = true;
}
const token = String(form?.bioResultToken ?? '');
if (!token || token === handledBioToken) return;
handledBioToken = token;
if (form?.bioSaved) {
bioDraft = String(form.bioMarkdown ?? bioDraft);
bioEditorOpen = false;
}
if (form?.bioError) bioEditorOpen = true;
});
$effect(() => {
if (form?.profileCommentError) activeComposerId = resultComposerId;
});
async function openComposer(id: string) {
activeComposerId = activeComposerId === id ? null : id;
profileCommentDraft = '';
deletingCommentId = '';
activeCommentMenuId = '';
if (!activeComposerId) return;
await tick();
document.getElementById(`profile-comment-editor-${activeComposerId}`)?.focus();
}
</script>
{#snippet commentComposer(parentId: string | null, label: string)}
<PendingForm action="?/commentProfile" class="profile-comment-form">
<input type="hidden" name="agentId" value={data.agent.id}/>
{#if parentId}<input type="hidden" name="parentId" value={parentId}/>{/if}
<CommentComposer
id={`profile-comment-editor-${parentId ?? 'root'}`}
name="body"
{label}
maxLength={2000}
rows={4}
required
bind:value={profileCommentDraft}
/>
<ModerationDisclosure compact/>
{#if resultComposerId === (parentId ?? 'root') && (form?.profileCommentError || form?.commentError)}
<p class="error">{form?.profileCommentError ?? form?.commentError}</p>
{/if}
<div class="profile-comment-form-actions">
<button type="button" class="secondary" onclick={() => openComposer(parentId ?? 'root')}>CANCEL</button>
<button class="primary" disabled={!profileCommentDraft.trim()}>
{parentId ? 'POST REPLY →' : 'POST MESSAGE →'}
</button>
</div>
</PendingForm>
{/snippet}
<svelte:head>
<title>{data.agent.displayName} — Agent Profile — SHD.build</title>
<meta name="description" content={`View ${data.agent.displayName}'s public Agent profile, builds, Guides, and community activity on SHD.build.`}/>
</svelte:head>
<main class="page public-agent-page">
<PageBreadcrumb items={[{ label: 'AGENTS' }, { label: data.agent.displayName }]} />
<header class="agent-command">
<div class="agent-command-identity">
<AgentIdentityLink agent={data.agent} size="large" roles={data.agent.roles} />
</div>
<div class="agent-command-actions">
{#if data.viewer.isSelf}
<PendingForm action="?/setProfileVisibility" toast={false} class="profile-visibility-form">
<input type="hidden" name="isPublic" value={data.agent.isPublic ? '0' : '1'}/>
<button class="visibility-toggle" class:enabled={data.agent.isPublic} role="switch" aria-checked={data.agent.isPublic} aria-label={`Public profile ${data.agent.isPublic ? 'enabled' : 'hidden'}. Toggle visibility.`}><span aria-hidden="true"></span><b>{data.agent.isPublic ? 'PUBLIC' : 'HIDDEN'}</b></button>
</PendingForm>
<InfoPopover label="About profile visibility" title="PROFILE VISIBILITY" text="A hidden profile leaves your name and avatar on public Builds, Guides, and comments, but removes the profile from discovery and blocks new profile messages."/>
<a class="mobile-account-jump" href="#account-control">ACCOUNT CONTROL ↓</a>
{:else if data.viewer.canReportProfile}
<ContentReport contentType="avatar" contentId={data.agent.id} label="REPORT AVATAR" result={form}/>
{/if}
</div>
</header>
<section class="agent-telemetry" aria-label="Agent content totals">
<div><span>PUBLIC BUILDS</span><strong>{data.counts.builds}</strong></div>
<div><span>PUBLISHED GUIDES</span><strong>{data.counts.guides}</strong></div>
<div><span>CONTENT COMMENTS</span><strong>{data.counts.authoredComments}</strong></div>
<div><span>PROFILE MESSAGES</span><strong>{data.counts.profileComments}</strong></div>
</section>
<div class="agent-profile-grid">
<div class="agent-main-column">
<div class="agent-primary">
<section class="profile-section agent-bio">
<header>
<div><p class="eyebrow">FIELD DOSSIER</p><h1>ABOUT {data.agent.displayName.toUpperCase()}</h1></div>
<div class="profile-header-actions">
{#if data.viewer.isSelf}
<button type="button" class="bio-edit-trigger" aria-expanded={bioEditorOpen} onclick={() => bioEditorOpen = !bioEditorOpen}>{bioEditorOpen ? 'CLOSE EDITOR' : 'EDIT BIO'}</button>
{:else}
<span>PUBLIC BIO</span>
{#if data.viewer.canReportProfile && data.agent.bioHtml}<ContentReport contentType="profile_bio" contentId={data.agent.id} label="REPORT BIO" result={form}/>{/if}
{/if}
</div>
</header>
{#if data.viewer.isSelf && data.agent.bioHidden}
<div class="profile-owner-notice error" role="status"><strong>BIO HIDDEN BY OVERSIGHT</strong><span>{data.agent.bioModerationReason ?? 'Review your notification inbox for details.'}</span></div>
{/if}
{#if data.viewer.isSelf && data.agent.bioReviewPending}
<div class="profile-owner-notice" role="status"><strong>BIO REVISION AWAITING REVIEW</strong><span>{data.agent.bioReviewReason ?? 'Your last approved biography remains public during review.'}</span></div>
{/if}
{#if form?.profileVisibilityError}<p class="error owner-profile-result">{form.profileVisibilityError}</p>{/if}
{#if form?.profileVisibilitySaved}<p class="success owner-profile-result">Profile visibility updated.</p>{/if}
{#if data.viewer.isSelf && bioEditorOpen}
<PendingForm action="?/saveBio" class="profile-bio-form">
<MarkdownEditor name="bio" label="AGENT BIO" help="Describe your playstyle, preferred roles, community work, or current objectives. Links are allowed." maxLength={4000} rows={12} bind:value={bioDraft}/>
<ModerationDisclosure/>
{#if form?.bioError}<p class="error">{form.bioError}</p>{/if}
<div class="profile-bio-actions"><button type="button" class="secondary" onclick={() => bioEditorOpen = false}>CANCEL</button><button class="primary">SAVE PUBLIC BIO →</button></div>
</PendingForm>
{:else}
<div class="bio-content">
<MarkdownContent html={data.agent.bioHtml} emptyMessage="This Agent has not published a field bio yet." />
</div>
{/if}
</section>
<div class="agent-published-grid">
<section class="profile-section">
<header><div><p class="eyebrow">LOADOUT ARCHIVE</p><h2>PUBLIC BUILDS</h2></div><span>{data.counts.builds} TOTAL</span></header>
<div class="public-content-grid">
{#each data.builds as build}
<a class="public-content-card" href={`/builds/${encodeURIComponent(build.slug)}`}><span>LOADOUT</span><h3>{build.title}</h3><p>Open this loadout to inspect its equipment, known Attributes, and active set bonuses.</p><footer><small>UPDATED {dateLabel(build.updatedAt)}</small><b>VIEW BUILD →</b></footer></a>
{:else}<div class="public-empty"><span>◇</span><strong>NO PUBLIC BUILDS</strong><p>This Agent has not shared a public loadout.</p></div>{/each}
</div>
</section>
<section class="profile-section">
<header><div><p class="eyebrow">FIELD GUIDANCE</p><h2>PUBLISHED GUIDES</h2></div><span>{data.counts.guides} TOTAL</span></header>
<div class="public-content-grid">
{#each data.guides as guide}<a class="public-content-card" href={`/guides/${encodeURIComponent(guide.slug)}`}><span>GUIDE</span><h3>{guide.title}</h3><p>Open this Guide for the complete strategy, embedded Builds, and field notes.</p><footer><small>UPDATED {dateLabel(guide.updatedAt)}</small><b>READ GUIDE →</b></footer></a>
{:else}<div class="public-empty"><span>◇</span><strong>NO PUBLISHED GUIDES</strong><p>This Agent has not published a Guide.</p></div>{/each}
</div>
</section>
</div>
</div>
<section class="profile-comms" id="profile-comments">
<header class="profile-comms-heading">
<div><p class="eyebrow">AGENT COMMS</p><h2>PROFILE MESSAGES</h2></div>
<span>{data.counts.profileComments} {data.counts.profileComments === 1 ? 'MESSAGE' : 'MESSAGES'}</span>
</header>
{#if data.viewer.canComment}
<div class="profile-comment-start">
<button
type="button"
class="profile-comment-trigger"
aria-expanded={activeComposerId === 'root'}
aria-controls="profile-comment-composer-root"
onclick={() => openComposer('root')}
>{activeComposerId === 'root' ? 'CLOSE EDITOR' : 'LEAVE A MESSAGE'}</button>
</div>
{#if activeComposerId === 'root'}
<div id="profile-comment-composer-root">{@render commentComposer(null, 'NEW PROFILE MESSAGE')}</div>
{/if}
{:else if !data.viewer.id}
<div class="comment-access-note"><strong>SIGN-IN REQUIRED</strong><p>Sign in to leave a message on this Agent profile.</p><a class="secondary" href="/sign-in">SIGN IN →</a></div>
{:else}
<div class="comment-access-note"><strong>MESSAGING UNAVAILABLE</strong><p>Your account cannot post profile messages at this time.</p></div>
{/if}
<div class="profile-comment-list">
{#each data.profileComments as comment}
<article
id={`profile-comment-${comment.id}`}
class="profile-comment"
class:reply={comment.depth > 0}
class:removed={comment.status === 'removed'}
style={`--thread-depth:${Math.min(comment.depth, 4)}`}
>
{#if comment.status === 'visible'}
<header>
<AgentIdentityLink agent={comment.author} roles={comment.author.roles} meta={dateLabel(comment.createdAt)} />
{#if comment.isPinned}<b class="pinned-comment-label">PINNED COMMENT</b>{/if}
</header>
<MarkdownContent html={comment.bodyHtml} compact />
<div class="comment-actions">
{#if data.viewer.canComment}
<button
type="button"
class="comment-reply"
aria-expanded={activeComposerId === comment.id}
aria-controls={`profile-comment-composer-${comment.id}`}
onclick={() => openComposer(comment.id)}
>REPLY</button>
{/if}
{#if data.viewer.id}
<OverflowMenu label={`Actions for ${comment.author.displayName}'s message`} bind:open={() => activeCommentMenuId === comment.id, (open) => activeCommentMenuId = open ? comment.id : ''}>
{#snippet children(close)}
<PendingForm action="?/toggleProfileCommentFollow" successMessage={comment.isFollowing ? 'Conversation unfollowed.' : 'Conversation followed.'}>
<input type="hidden" name="commentId" value={comment.id}/>
<input type="hidden" name="intent" value={comment.isFollowing ? 'unfollow' : 'follow'}/>
<button>{comment.isFollowing ? 'UNFOLLOW THREAD' : 'FOLLOW THREAD'}</button>
</PendingForm>
{#if comment.canReport}<ContentReport contentType="comment" contentId={comment.id} result={form} plain menuItem/>{/if}
{#if data.viewer.isSelf && comment.depth === 0}
<PendingForm action="?/setPinnedProfileComment">
<input type="hidden" name="commentId" value={comment.id}/>
<input type="hidden" name="intent" value={comment.isPinned ? 'unpin' : 'pin'}/>
<button>{comment.isPinned ? 'UNPIN COMMENT' : 'PIN COMMENT'}</button>
</PendingForm>
{/if}
{#if comment.canDelete}
<button type="button" class="comment-remove danger" onclick={() => { deletingCommentId = comment.id; close(); }}>REMOVE MESSAGE</button>
{/if}
{/snippet}
</OverflowMenu>
{/if}
</div>
{:else}
<div class="removed-message">
<strong>{comment.removalReason === 'Removed by Community Oversight' ? 'MESSAGE REMOVED BY COMMUNITY OVERSIGHT' : 'MESSAGE REMOVED BY POSTER'}</strong>
<span>Replies remain visible to preserve the conversation.</span>
</div>
{/if}
{#if activeComposerId === comment.id}
<div id={`profile-comment-composer-${comment.id}`} class="reply-composer">
{@render commentComposer(comment.id, `REPLY TO ${comment.author.displayName.toUpperCase()}`)}
</div>
{/if}
{#if deletingCommentId === comment.id}
<div class="comment-delete-confirm" role="alert">
<p>Remove this message? It remains as a labeled placeholder only when replies depend on it.</p>
<div>
<button type="button" class="secondary" onclick={() => deletingCommentId = ''}>CANCEL</button>
<PendingForm action="?/deleteProfileComment">
<input type="hidden" name="commentId" value={comment.id}/>
<button class="primary">CONFIRM REMOVE</button>
</PendingForm>
</div>
</div>
{/if}
</article>
{:else}
<div class="public-empty compact">
<span>◇</span><strong>NO PROFILE MESSAGES</strong>
<p>Be the first Agent to leave a useful field message.</p>
</div>
{/each}
</div>
</section>
</div>
<aside class="agent-activity">
{#if data.viewer.isSelf && data.accountControl}
<div id="account-control"><AccountControl account={data.accountControl} displayName={data.agent.displayName} avatarUrl={data.agent.avatarUrl}/></div>
<section class="profile-section owner-notifications">
<header><div><p class="eyebrow">SHD COMMUNICATION NETWORK</p><h2>NOTIFICATIONS</h2></div><a href="/account/notifications">{data.accountControl.notificationUnread ? `${data.accountControl.notificationUnread} UNREAD` : 'VIEW INBOX'} →</a></header>
<div class="owner-notification-list">
{#each data.accountControl.notifications as notification}
<a class:unread={!notification.read_at} class:isac={notificationIsIsac(notification)} href="/account/notifications"><span><b>{notification.source}</b><small>{String(notification.category).toUpperCase()} · {dateLabel(String(notification.created_at))}</small></span><strong>{notification.title}</strong></a>
{:else}<div class="public-empty compact"><strong>INBOX CLEAR</strong><p>No unread notifications.</p></div>{/each}
</div>
</section>
{/if}
<section class="profile-section discussion-section">
<header><div><p class="eyebrow">COMMUNITY RECORD</p><h2>RECENT DISCUSSION</h2></div><span>{data.counts.authoredComments} COMMENTS</span></header>
<div class="authored-comment-list">
{#each data.authoredComments as comment}
<article>
<header><div><span>{comment.targetType.toUpperCase()}</span><strong>{comment.targetTitle}</strong></div><small>{dateLabel(comment.createdAt)}</small></header>
<a href={comment.targetHref}>OPEN DISCUSSION →</a>
</article>
{:else}
<div class="public-empty">
<span>◇</span><strong>NO PUBLIC DISCUSSION</strong>
<p>Comments this Agent leaves on builds will appear here.</p>
</div>
{/each}
</div>
</section>
</aside>
</div>
</main>
<style>
.public-agent-page{padding-top:28px}.agent-command{position:static;z-index:auto;width:auto;height:auto;min-height:96px;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:var(--shd-gap-lg);margin-top:12px;padding:14px 4px 16px;border:0;background:transparent}
.agent-command-identity{min-width:0}.agent-command :global(.agent-profile-identity){min-width:0}.agent-command-actions{display:flex;align-items:center;gap:8px}.agent-command-actions :global(.profile-visibility-form){margin:0}.agent-command-actions .visibility-toggle{min-height:40px}.mobile-account-jump{display:none}
.agent-telemetry{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));margin-top:8px;border:1px solid var(--shd-border);background:var(--shd-surface)}
.agent-telemetry>div{display:grid;gap:4px;padding:10px 12px;border-left:1px solid var(--shd-border)}.agent-telemetry>div:first-child{border-left:0}.agent-telemetry span{color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.8px}.agent-telemetry strong{color:var(--shd-orange);font-size:24px}
.agent-profile-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(360px,.42fr);align-items:start;gap:10px;margin-top:10px}.agent-main-column,.agent-primary,.agent-activity{display:grid;gap:10px;min-width:0}.agent-main-column{grid-column:1}.agent-activity{position:sticky;top:88px;grid-column:2}.agent-activity .public-empty{min-height:110px}#account-control{scroll-margin-top:88px}.agent-published-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.agent-published-grid .public-content-grid{grid-template-columns:1fr}
.profile-section{min-width:0;border:1px solid var(--shd-border);background:var(--shd-surface)}.profile-section>header{min-height:54px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 12px;border-bottom:1px solid var(--shd-border);background:var(--shd-surface-raised)}.profile-section>header>div{display:grid;gap:2px}.profile-section>header :is(h1,h2,p){margin:0}.profile-section>header h1,.profile-section>header h2{font-size:var(--shd-type-body);letter-spacing:.4px}.profile-section>header>span{color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.8px}
.bio-content{min-height:110px;padding:18px}:global(form.profile-bio-form){display:grid;gap:10px;padding:16px}.profile-bio-actions{display:flex;justify-content:flex-end;gap:7px}.profile-bio-actions button{min-height:40px}.profile-owner-notice{display:grid;gap:4px;margin:12px 16px 0;padding:10px;border:1px solid #745b2b;background:#1c170e;color:var(--shd-text-muted);font-size:var(--shd-type-supporting)}.profile-owner-notice strong{color:var(--shd-orange);font-size:var(--shd-type-telemetry);letter-spacing:.7px}.profile-owner-notice.error{border-color:#70423b;background:#211414}.profile-owner-notice.error strong{color:var(--shd-danger)}.owner-profile-result{margin:10px 16px 0}.public-content-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;padding:7px}
.public-content-card{min-width:0;display:grid;grid-template-rows:auto auto minmax(48px,1fr) auto;gap:6px;padding:12px;border:1px solid var(--shd-border);border-left:2px solid var(--shd-orange);background:#0d1011;color:var(--shd-text)}.public-content-card>span,.public-content-card footer{font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.7px}.public-content-card>span{color:var(--shd-orange)}.public-content-card h3,.public-content-card p{margin:0}.public-content-card h3{font-size:1.05rem}.public-content-card p{color:var(--shd-text-muted);font-family:var(--shd-font-editorial);font-size:var(--shd-type-supporting);line-height:1.45}.public-content-card footer{display:flex;justify-content:space-between;gap:8px;padding-top:8px;border-top:1px solid var(--shd-border-soft)}.public-content-card small{color:var(--shd-text-dim)}.public-content-card b{color:var(--shd-orange)}.public-content-card:hover,.public-content-card:focus-visible{border-color:var(--shd-orange);background:var(--shd-surface-active)}
.public-empty{grid-column:1/-1;min-height:150px;display:grid;place-content:center;gap:6px;padding:20px;text-align:center}.public-empty span{color:var(--shd-orange);font-size:28px}.public-empty strong{font-size:var(--shd-type-telemetry);letter-spacing:1px}.public-empty p{margin:0;color:var(--shd-text-muted);font-family:var(--shd-font-editorial);font-size:var(--shd-type-supporting)}.public-empty.compact{min-height:110px}
.authored-comment-list{display:grid;gap:7px;padding:7px}.authored-comment-list>article{display:grid;gap:10px;padding:11px;border:1px solid var(--shd-border);background:#0d1011}.authored-comment-list article>header{position:static;z-index:auto;width:auto;height:auto;min-height:0;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px;padding:0;border:0;background:transparent}.authored-comment-list article>header>div{min-width:0;display:grid;align-content:center;gap:2px}.authored-comment-list article header span,.authored-comment-list article header small,.authored-comment-list article>a{font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.7px}.authored-comment-list article header span,.authored-comment-list article>a{color:var(--shd-orange)}.authored-comment-list article header small{align-self:center;color:var(--shd-text-muted);text-align:right;white-space:nowrap}.authored-comment-list article>a{justify-self:end}
.profile-comms{margin-top:16px;padding:0;background:transparent}.profile-comms-heading{position:static;z-index:auto;width:auto;height:auto;min-height:0;display:flex;align-items:end;justify-content:space-between;gap:16px;padding:0 0 12px;border:0;border-bottom:1px solid var(--shd-border);background:transparent}.profile-comms-heading>div{display:grid;gap:3px}.profile-comms-heading :is(h2,p){margin:0}.profile-comms-heading h2{font-size:1.25rem}.profile-comms-heading>span{color:var(--shd-text-dim);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.7px}.profile-comment-start{width:min(920px,100%);padding-top:16px}.profile-comment-trigger{width:100%;min-height:48px;padding:0 14px;border:1px solid var(--shd-border-strong);background:transparent;color:var(--shd-text-muted);font-family:var(--shd-font-editorial);font-size:var(--shd-type-body);text-align:left;cursor:pointer}.profile-comment-trigger:hover,.profile-comment-trigger:focus-visible,.profile-comment-trigger[aria-expanded=true]{border-color:var(--shd-orange);color:var(--shd-text);background:var(--shd-surface-active)}:global(form.profile-comment-form){width:min(920px,100%);display:grid;gap:9px;padding:14px 0 0;border:0;background:transparent}.profile-comment-form-actions{display:flex;justify-content:flex-end;gap:7px}.profile-comment-form-actions button{min-height:38px}.profile-comment-list{width:min(980px,100%);display:grid;margin-top:26px;overflow:visible}.profile-comment-list>article{--thread-depth:0;position:relative;display:grid;gap:8px;margin:18px 0 0 calc(var(--thread-depth) * 22px);padding:0;scroll-margin-top:96px;background:transparent}.profile-comment-list>article:target{outline:1px solid var(--shd-orange);outline-offset:8px}.profile-comment-list>article.reply{padding-left:14px;border-left:1px solid var(--shd-border-strong)}.profile-comment-list article>header{position:static;z-index:auto;width:auto;height:auto;min-height:0;display:flex;align-items:center;justify-content:flex-start;gap:12px;padding:0;border:0;background:transparent}.profile-comment-list article>header :global(.agent-identity){flex:0 1 auto}.profile-comment-list article :global(.markdown-content){max-width:75ch;margin-left:47px}.comment-actions{display:flex;align-items:center;gap:14px;min-height:32px;margin-left:47px}.comment-reply{min-height:32px;padding:0;border:0;background:transparent;color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.6px;cursor:pointer}.comment-reply:hover,.comment-reply:focus-visible,.comment-reply[aria-expanded=true]{color:var(--shd-orange);text-decoration:underline;text-underline-offset:3px}.reply-composer{margin:6px 0 0 47px}.reply-composer :global(form.profile-comment-form){padding-top:0}.removed-message{display:grid;gap:3px;padding:4px 0}.removed-message strong{color:var(--shd-text-dim);font-size:var(--shd-type-telemetry);letter-spacing:.8px}.removed-message span{color:var(--shd-text-dim);font-size:var(--shd-type-supporting);font-style:italic}.comment-delete-confirm{width:min(520px,calc(100% - 47px));display:grid;gap:8px;margin-left:47px;padding:10px;border:1px solid var(--shd-danger);background:#1b1111}.comment-delete-confirm p{margin:0;color:var(--shd-text-muted);font-size:var(--shd-type-supporting)}.comment-delete-confirm>div{display:flex;justify-content:flex-end;gap:7px}.comment-delete-confirm button{min-height:38px;padding:0 10px}.comment-access-note{width:min(920px,100%);display:grid;gap:7px;padding:16px 0 0}.comment-access-note strong{color:var(--shd-orange);font-size:var(--shd-type-telemetry);letter-spacing:.8px}.comment-access-note p{margin:0;color:var(--shd-text-muted);font-size:var(--shd-type-supporting)}.comment-access-note a{justify-self:start}.profile-comms .public-empty{min-height:100px;place-content:start;padding:24px 0;text-align:left}.profile-comms .public-empty span{display:none}
.profile-header-actions{display:flex;align-items:center;gap:7px}.profile-header-actions>span{color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.7px}.bio-edit-trigger{min-height:32px;padding:0 9px;border:1px solid var(--shd-border);background:transparent;color:var(--shd-orange);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.7px;cursor:pointer}.bio-edit-trigger:hover,.bio-edit-trigger:focus-visible,.bio-edit-trigger[aria-expanded=true]{border-color:var(--shd-orange);background:var(--shd-surface-active)}.visibility-toggle{min-height:32px;display:flex;align-items:center;gap:7px;padding:0 8px;border:1px solid var(--shd-border-strong);background:#0d1011;color:var(--shd-text-muted);cursor:pointer}.visibility-toggle>span{position:relative;width:26px;height:14px;border:1px solid var(--shd-border-strong);background:#070909}.visibility-toggle>span::after{content:"";position:absolute;top:2px;left:2px;width:8px;height:8px;background:var(--shd-text-dim)}.visibility-toggle.enabled{border-color:#6b5128;color:var(--shd-orange)}.visibility-toggle.enabled>span::after{left:14px;background:var(--shd-orange)}.visibility-toggle b{font-size:var(--shd-type-telemetry);letter-spacing:.7px}.owner-notifications>header>a{color:var(--shd-orange);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.6px}.owner-notification-list{display:grid}.owner-notification-list>a{min-width:0;display:grid;gap:5px;padding:9px 10px;border-top:1px solid var(--shd-border);background:#0d1011;color:var(--shd-text-muted)}.owner-notification-list>a:first-child{border-top:0}.owner-notification-list>a.unread{box-shadow:inset 2px 0 var(--shd-orange)}.owner-notification-list>a.isac{box-shadow:inset 2px 0 var(--shd-info)}.owner-notification-list span{min-width:0;display:flex;justify-content:space-between;gap:8px}.owner-notification-list b,.owner-notification-list small{font-size:var(--shd-type-telemetry);letter-spacing:.5px}.owner-notification-list b{overflow:hidden;color:var(--shd-orange);text-overflow:ellipsis;white-space:nowrap}.owner-notification-list small{color:var(--shd-text-dim);white-space:nowrap}.owner-notification-list strong{overflow:hidden;font-size:var(--shd-type-supporting);text-overflow:ellipsis;white-space:nowrap}
.profile-comment-list article :global(.markdown-content),.comment-actions{margin-left:53px}.reply-composer{margin-left:53px}.comment-delete-confirm{width:min(520px,calc(100% - 53px));margin-left:53px}
.pinned-comment-label{margin-left:auto;color:var(--shd-orange);font-size:var(--shd-type-telemetry);letter-spacing:.7px}
@media(max-width:1000px){.agent-profile-grid{grid-template-columns:1fr}.agent-main-column{grid-column:1}.agent-activity{position:static;grid-column:1;grid-template-columns:repeat(2,minmax(0,1fr))}.agent-activity .profile-section:last-child{grid-column:1/-1}.agent-telemetry{grid-template-columns:repeat(2,minmax(0,1fr))}.agent-telemetry>div:nth-child(3){border-left:0}.agent-telemetry>div:nth-child(n+3){border-top:1px solid var(--shd-border)}}
@media(max-width:650px){.agent-command{grid-template-columns:1fr;align-items:stretch}.agent-command-actions{width:100%;display:grid;grid-template-columns:minmax(0,1fr) auto}.agent-command-actions :global(.profile-visibility-form),.agent-command-actions .visibility-toggle{width:100%}.agent-command-actions .visibility-toggle{min-height:44px;justify-content:center}.agent-command-actions :global(.content-report){grid-column:1/-1}.agent-command-actions :global(.content-report summary){width:100%;justify-content:center}.mobile-account-jump{grid-column:1/-1;min-height:44px;display:flex;align-items:center;justify-content:center;border:1px solid var(--shd-border-strong);color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.7px}.mobile-account-jump:hover,.mobile-account-jump:focus-visible{border-color:var(--shd-orange);color:var(--shd-orange);background:var(--shd-surface-active)}.agent-main-column{display:contents}.agent-primary{grid-column:1;grid-row:1}.agent-activity{grid-column:1;grid-row:2;grid-template-columns:1fr}.profile-comms{grid-column:1;grid-row:3;margin-top:16px}.agent-activity .profile-section:last-child{grid-column:auto}.agent-published-grid{grid-template-columns:1fr}.public-content-grid{grid-template-columns:1fr}.profile-section>header,.profile-comms-heading{align-items:flex-start;flex-direction:column}.agent-bio>header{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start}.agent-bio .profile-header-actions{width:auto}.bio-edit-trigger{min-height:44px;padding:0 5px;border-color:transparent}.bio-edit-trigger:hover,.bio-edit-trigger:focus-visible,.bio-edit-trigger[aria-expanded=true]{border-color:var(--shd-border-strong)}.profile-bio-actions{display:grid;grid-template-columns:1fr 1fr}.profile-bio-actions button{min-height:44px}.profile-comment-trigger,.profile-comment-form-actions button,.comment-reply,.comment-delete-confirm button{min-height:44px}.profile-comment-form-actions{display:grid;grid-template-columns:1fr 1fr}.profile-comment-list>article{margin-left:calc(var(--thread-depth) * 12px)}.comment-delete-confirm>div{display:grid;grid-template-columns:1fr 1fr}}
@media(prefers-reduced-motion:reduce){.public-content-card,.profile-comment-trigger,.comment-reply{transition:none}}
</style>