Files
fusion/packages/dashboard/app/components/SecretsView.css
gsxdsm e6aebdc316 feat(dashboard): full issue/PR preview, floating dock pop-out, header dedups, gm one-row, single-line quick entry
- GitHub import preview shows the full issue/PR body (markdown) + metadata (list already returned full bodies; removed client truncation).
- Task-detail main view: constrain width (no right cutoff); move 'Back to board' into the gray header far right.
- Dock pop-out: smoother touch drag (touch-action:none + captured-element listeners); popping out closes the dock but keeps the floating modal; modal survives dock dismiss.
- Remove duplicate inner headers in Git Manager / Activity Log / Dev Server / Secrets (dock + pop-out chrome already titles them); keep the title on mobile narrow; relocate gm Refresh into the section tab strip.
- Git Manager tabs: one scrollable row of compact icon-only tabs (max visible, scroll if needed).
- List quick entry is single-line (not tall) via singleLine prop; Board unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 04:37:28 -07:00

304 lines
6.9 KiB
CSS

/*
FNXC:SecretsView 2026-06-14-10:02:
The standalone Secrets page is mounted as a flex item inside the .project-content row on mobile and desktop. Grow and zero the min-width here so the page fills the viewport width instead of collapsing to intrinsic secret-card content (FN-6446); keep height behavior unchanged so the Settings modal section does not gain nested scrolling.
*/
.secrets-view {
display: flex;
flex: 1 1 auto;
flex-direction: column;
gap: var(--space-lg);
min-width: 0;
width: 100%;
padding-block: var(--space-md);
padding-inline: var(--space-xl);
}
.secrets-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-md);
}
/*
FNXC:RightDockEmbedded 2026-06-22-19:05:
SecretsView is a right-dock tool with no --embedded variant; it renders directly inside the dock body
(.right-dock__body) and inside the pop-out (.right-dock-expand-modal__body). In both, the chrome already labels the
view — the dock tab strip names it, and the pop-out's RightDockExpandModal supplies its own header — so the view's own
.secrets-header title row (the "Secrets" heading plus Refresh/Add actions) is redundant title chrome there. Hide it in
those two host contexts only; the header stays in the DOM (just display:none). The standalone full-page render and the
Settings-modal SecretsSection render are NOT inside these ancestors, so their header stays visible.
*/
.right-dock__body .secrets-view > .secrets-header,
.right-dock-expand-modal__body .secrets-view > .secrets-header {
display: none;
}
/*
FNXC:RightDockEmbedded 2026-06-22-19:05:
On real mobile-narrow the view goes full-screen with no dock tab strip or pop-out header, so it must own its title
again. The viewport @media (max-width:768px) fires only on a true narrow viewport (never in the desktop dock/pop-out,
where the @container right-dock-body query drives layout instead), so restoring the header here brings the title back
exactly when the surrounding chrome is gone.
*/
@media (max-width: 768px) {
.right-dock__body .secrets-view > .secrets-header,
.right-dock-expand-modal__body .secrets-view > .secrets-header {
display: flex;
}
}
.secrets-header h2 {
margin: 0;
}
.secrets-header-actions {
display: flex;
gap: var(--space-sm);
}
.secrets-loading,
.secrets-empty {
color: var(--text-muted);
display: flex;
align-items: center;
gap: var(--space-sm);
padding-block: var(--space-sm);
}
.secrets-sync-card {
display: flex;
flex-direction: column;
gap: var(--space-md);
}
.secrets-sync-header {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
justify-content: space-between;
gap: var(--space-md);
}
.secrets-sync-status {
display: inline-flex;
align-items: center;
gap: var(--space-xs);
margin: 0;
color: var(--text-muted);
}
.secrets-sync-copy {
margin: 0;
max-width: 60ch;
color: var(--text-muted);
line-height: 1.5;
}
.secrets-sync-actions {
display: flex;
gap: var(--space-sm);
}
.secrets-list {
display: flex;
flex-direction: column;
gap: var(--space-md);
}
.secrets-row {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: var(--space-md);
align-items: start;
}
.secrets-row-main {
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
.secrets-row-key {
font-family: var(--font-mono);
font-size: 1em;
overflow-wrap: anywhere;
}
.secrets-row-meta {
display: flex;
flex-wrap: wrap;
gap: var(--space-sm);
row-gap: var(--space-xs);
}
.secrets-chip {
border: var(--btn-border-width) solid var(--border);
border-radius: var(--radius-pill);
padding: var(--space-xs) var(--space-sm);
color: var(--text-muted);
}
.secrets-revealed {
margin: 0;
max-width: 100%;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-all;
font-family: var(--font-mono);
border: var(--btn-border-width) solid var(--border);
border-radius: var(--radius-sm);
padding: var(--space-sm);
background: var(--surface);
}
.secrets-row-side {
display: flex;
flex-direction: column;
gap: var(--space-sm);
align-items: flex-end;
}
.secrets-row-read {
color: var(--text-muted);
font-size: 0.95em;
font-weight: 400;
}
.secrets-row-actions,
.secrets-confirm,
.secrets-value-row,
.secrets-radio-row {
display: flex;
gap: var(--space-sm);
align-items: center;
}
.secrets-radio-row {
flex-wrap: wrap;
row-gap: var(--space-xs);
}
.secrets-modal-body {
display: flex;
flex-direction: column;
gap: var(--space-md);
padding: 0 var(--space-xl) var(--space-lg);
}
.secrets-modal-body .form-group {
margin: 0;
padding: 0;
}
.secrets-value-row .input {
flex: 1;
}
.secrets-action-icon {
width: 1em;
height: 1em;
min-width: 1em;
min-height: 1em;
flex-shrink: 0;
display: block;
stroke: currentColor;
font-size: var(--icon-size-sm);
}
.secrets-header-actions .btn,
.secrets-row-actions .btn,
.secrets-value-row .btn-icon {
color: var(--text);
}
.secrets-header-actions .btn-primary,
.secrets-row-actions .btn-danger {
color: var(--cta-text);
}
.secrets-row-actions .btn:disabled {
color: var(--text-muted);
}
@media (max-width: 768px) {
.secrets-view {
padding-inline: var(--space-md);
padding-bottom: calc(var(--space-md) + var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap, 0px));
}
.secrets-header,
.secrets-row,
.secrets-sync-header {
grid-template-columns: minmax(0, 1fr);
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--space-sm);
}
.secrets-sync-header {
flex-wrap: wrap;
}
.secrets-sync-copy {
max-width: none;
}
.secrets-sync-actions {
flex-direction: column;
}
.secrets-row-key {
font-size: 0.95em;
}
.secrets-row-side {
width: 100%;
align-items: flex-start;
gap: var(--space-sm);
}
}
/*
FNXC:RightDockEmbedded 2026-06-22-00:00:
SecretsView has no dedicated embedded variant; in the narrow right dock it renders directly under the dock body's
`right-dock-body` query container. The viewport stays desktop so its @media (max-width:768px) rules never fire.
Mirror the phone-width layout stacking off the DOCK width: the two-column .secrets-row grid collapses to a single
column, the header / sync-header stack, sync copy/actions go full-width, and the action side rail becomes full-width
so nothing overflows horizontally in the narrow dock.
*/
@container right-dock-body (max-width: 768px) {
.secrets-view {
padding-inline: var(--space-md);
}
.secrets-header,
.secrets-row,
.secrets-sync-header {
grid-template-columns: minmax(0, 1fr);
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--space-sm);
}
.secrets-sync-header {
flex-wrap: wrap;
}
.secrets-sync-copy {
max-width: none;
}
.secrets-sync-actions {
flex-direction: column;
}
.secrets-row-side {
width: 100%;
align-items: flex-start;
gap: var(--space-sm);
}
}