Implements animated modal open/close with accessibility support: - Add closing state with 200ms exit animation before unmount - Refactor to React hooks-compliant structure (guards after hooks) - Add CSS keyframes for backdrop fade and panel scale+translate - Include prefers-reduced-motion media query to disable animations for users with vestibular sensitivities - Use handleClose callback wrapper for consistent animation behavior across Escape key, backdrop click, and close button The animations provide visual continuity without being distracting, and gracefully degrade to instant transitions when reduced motion is preferred. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
397 lines
6.9 KiB
CSS
397 lines
6.9 KiB
CSS
/* AMC Dashboard Styles */
|
|
|
|
html {
|
|
font-size: 16px;
|
|
}
|
|
|
|
:root {
|
|
--bg-flat: #01040b;
|
|
--glass-border: rgba(116, 154, 214, 0.22);
|
|
}
|
|
|
|
* {
|
|
scrollbar-width: thin;
|
|
scrollbar-color: #445f8e #0a1222;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
font-family: 'IBM Plex Sans', system-ui, sans-serif;
|
|
background: var(--bg-flat);
|
|
min-height: 100vh;
|
|
color: #e0ebff;
|
|
letter-spacing: 0.01em;
|
|
}
|
|
|
|
#app {
|
|
position: relative;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
#app > *:not(.fixed) {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: #0a1222;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: #445f8e;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: #5574aa;
|
|
}
|
|
|
|
/* Animations */
|
|
@keyframes pulse-attention {
|
|
0%, 100% {
|
|
opacity: 1;
|
|
transform: scale(1) translateY(0);
|
|
}
|
|
50% {
|
|
opacity: 0.62;
|
|
transform: scale(1.04) translateY(-1px);
|
|
}
|
|
}
|
|
|
|
.pulse-attention {
|
|
animation: pulse-attention 2s ease-in-out infinite;
|
|
}
|
|
|
|
/* Active session spinner */
|
|
@keyframes spin-ring {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
.spinner-dot {
|
|
position: relative;
|
|
display: inline-block;
|
|
}
|
|
|
|
.spinner-dot::after {
|
|
content: '';
|
|
position: absolute;
|
|
inset: -2px;
|
|
border-radius: 50%;
|
|
border: 1.5px solid transparent;
|
|
border-top-color: currentColor;
|
|
will-change: transform;
|
|
animation: spin-ring 0.9s cubic-bezier(0.645, 0.045, 0.355, 1) infinite;
|
|
}
|
|
|
|
/* Working indicator at bottom of chat */
|
|
@keyframes bounce-dot {
|
|
0%, 80%, 100% { transform: translateY(0); }
|
|
40% { transform: translateY(-4px); }
|
|
}
|
|
|
|
.working-dots span {
|
|
display: inline-block;
|
|
will-change: transform;
|
|
}
|
|
|
|
.working-dots span:nth-child(1) { animation: bounce-dot 1.2s ease-out infinite; }
|
|
.working-dots span:nth-child(2) { animation: bounce-dot 1.2s ease-out 0.15s infinite; }
|
|
.working-dots span:nth-child(3) { animation: bounce-dot 1.2s ease-out 0.3s infinite; }
|
|
|
|
/* Modal entrance/exit animations */
|
|
@keyframes modalBackdropIn {
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
}
|
|
@keyframes modalBackdropOut {
|
|
from { opacity: 1; }
|
|
to { opacity: 0; }
|
|
}
|
|
@keyframes modalPanelIn {
|
|
from { opacity: 0; transform: scale(0.96) translateY(8px); }
|
|
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
}
|
|
@keyframes modalPanelOut {
|
|
from { opacity: 1; transform: scale(1) translateY(0); }
|
|
to { opacity: 0; transform: scale(0.96) translateY(8px); }
|
|
}
|
|
|
|
.modal-backdrop-in {
|
|
animation: modalBackdropIn 200ms ease-out;
|
|
}
|
|
.modal-backdrop-out {
|
|
animation: modalBackdropOut 200ms ease-in forwards;
|
|
}
|
|
.modal-panel-in {
|
|
animation: modalPanelIn 200ms ease-out;
|
|
}
|
|
.modal-panel-out {
|
|
animation: modalPanelOut 200ms ease-in forwards;
|
|
}
|
|
|
|
/* Accessibility: disable continuous animations for motion-sensitive users */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.spinner-dot::after {
|
|
animation: none;
|
|
}
|
|
.working-dots span {
|
|
animation: none;
|
|
}
|
|
.pulse-attention {
|
|
animation: none;
|
|
}
|
|
.modal-backdrop-in,
|
|
.modal-backdrop-out,
|
|
.modal-panel-in,
|
|
.modal-panel-out {
|
|
animation: none;
|
|
}
|
|
.animate-float,
|
|
.animate-fade-in-up {
|
|
animation: none !important;
|
|
}
|
|
}
|
|
|
|
/* Glass panel effect */
|
|
.glass-panel {
|
|
backdrop-filter: blur(10px);
|
|
border: 1px solid var(--glass-border);
|
|
background: rgba(7, 13, 24, 0.95);
|
|
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.36), inset 0 1px 0 rgba(151, 185, 245, 0.05);
|
|
}
|
|
|
|
/* Agent header variants */
|
|
.agent-header-codex {
|
|
background: rgba(20, 60, 54, 0.4);
|
|
border-bottom-color: rgba(116, 227, 196, 0.34);
|
|
}
|
|
|
|
.agent-header-claude {
|
|
background: rgba(45, 36, 78, 0.42);
|
|
border-bottom-color: rgba(179, 154, 255, 0.36);
|
|
}
|
|
|
|
/* Markdown content styling */
|
|
.md-content {
|
|
line-height: 1.45;
|
|
}
|
|
|
|
.md-content > *:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.md-content > *:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.md-content h1, .md-content h2, .md-content h3,
|
|
.md-content h4, .md-content h5, .md-content h6 {
|
|
font-family: 'Space Grotesk', 'IBM Plex Sans', sans-serif;
|
|
font-weight: 600;
|
|
color: #fbfdff;
|
|
margin: 0.6em 0 0.25em;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.md-content h1 { font-size: 1.4em; }
|
|
.md-content h2 { font-size: 1.25em; }
|
|
.md-content h3 { font-size: 1.1em; }
|
|
.md-content h4, .md-content h5, .md-content h6 { font-size: 1em; }
|
|
|
|
.md-content p {
|
|
margin: 0.25em 0;
|
|
}
|
|
|
|
.md-content p:empty {
|
|
display: none;
|
|
}
|
|
|
|
.md-content strong {
|
|
color: #fbfdff;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.md-content em {
|
|
color: #c8d8f0;
|
|
}
|
|
|
|
.md-content a {
|
|
color: #7cb2ff;
|
|
text-decoration: underline;
|
|
text-underline-offset: 2px;
|
|
}
|
|
|
|
.md-content a:hover {
|
|
color: #a8ccff;
|
|
}
|
|
|
|
.md-content code {
|
|
font-family: 'IBM Plex Mono', monospace;
|
|
font-size: 0.9em;
|
|
background: rgba(1, 4, 11, 0.55);
|
|
border: 1px solid rgba(34, 52, 84, 0.8);
|
|
border-radius: 4px;
|
|
padding: 0.15em 0.4em;
|
|
}
|
|
|
|
.md-content pre {
|
|
margin: 0.4em 0;
|
|
padding: 0.6rem 0.8rem;
|
|
background: rgba(1, 4, 11, 0.65);
|
|
border: 1px solid rgba(34, 52, 84, 0.75);
|
|
border-radius: 0.75rem;
|
|
overflow-x: auto;
|
|
font-size: 0.85em;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.md-content pre code {
|
|
background: none;
|
|
border: none;
|
|
padding: 0;
|
|
font-size: inherit;
|
|
}
|
|
|
|
.md-content ul, .md-content ol {
|
|
margin: 0.35em 0;
|
|
padding-left: 1.5em;
|
|
white-space: normal;
|
|
}
|
|
|
|
.md-content li {
|
|
margin: 0;
|
|
}
|
|
|
|
.md-content li p {
|
|
margin: 0;
|
|
display: inline;
|
|
}
|
|
|
|
.md-content li > ul, .md-content li > ol {
|
|
margin: 0.1em 0;
|
|
}
|
|
|
|
.md-content blockquote {
|
|
margin: 0.4em 0;
|
|
padding: 0.4em 0.8em;
|
|
border-left: 3px solid rgba(124, 178, 255, 0.5);
|
|
background: rgba(34, 52, 84, 0.25);
|
|
border-radius: 0 0.5rem 0.5rem 0;
|
|
color: #c8d8f0;
|
|
}
|
|
|
|
.md-content hr {
|
|
border: none;
|
|
border-top: 1px solid rgba(34, 52, 84, 0.6);
|
|
margin: 0.6em 0;
|
|
}
|
|
|
|
.md-content table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 0.75em 0;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.md-content th, .md-content td {
|
|
border: 1px solid rgba(34, 52, 84, 0.6);
|
|
padding: 0.5em 0.75em;
|
|
text-align: left;
|
|
}
|
|
|
|
.md-content th {
|
|
background: rgba(34, 52, 84, 0.35);
|
|
font-weight: 600;
|
|
color: #fbfdff;
|
|
}
|
|
|
|
.md-content tr:nth-child(even) {
|
|
background: rgba(34, 52, 84, 0.15);
|
|
}
|
|
|
|
/* Highlight.js syntax theme (dark) */
|
|
.hljs {
|
|
color: #e0ebff;
|
|
}
|
|
|
|
.hljs-keyword,
|
|
.hljs-selector-tag,
|
|
.hljs-built_in,
|
|
.hljs-name,
|
|
.hljs-tag {
|
|
color: #c792ea;
|
|
}
|
|
|
|
.hljs-string,
|
|
.hljs-title,
|
|
.hljs-section,
|
|
.hljs-attribute,
|
|
.hljs-literal,
|
|
.hljs-template-tag,
|
|
.hljs-template-variable,
|
|
.hljs-type,
|
|
.hljs-addition {
|
|
color: #c3e88d;
|
|
}
|
|
|
|
.hljs-comment,
|
|
.hljs-quote,
|
|
.hljs-deletion,
|
|
.hljs-meta {
|
|
color: #697098;
|
|
}
|
|
|
|
.hljs-keyword,
|
|
.hljs-selector-tag,
|
|
.hljs-literal,
|
|
.hljs-title,
|
|
.hljs-section,
|
|
.hljs-doctag,
|
|
.hljs-type,
|
|
.hljs-name,
|
|
.hljs-strong {
|
|
font-weight: 500;
|
|
}
|
|
|
|
.hljs-number,
|
|
.hljs-selector-id,
|
|
.hljs-selector-class,
|
|
.hljs-quote,
|
|
.hljs-template-tag,
|
|
.hljs-deletion {
|
|
color: #f78c6c;
|
|
}
|
|
|
|
.hljs-title.function_,
|
|
.hljs-subst,
|
|
.hljs-symbol,
|
|
.hljs-bullet,
|
|
.hljs-link {
|
|
color: #82aaff;
|
|
}
|
|
|
|
.hljs-selector-attr,
|
|
.hljs-selector-pseudo,
|
|
.hljs-variable,
|
|
.hljs-template-variable {
|
|
color: #ffcb6b;
|
|
}
|
|
|
|
.hljs-attr {
|
|
color: #89ddff;
|
|
}
|
|
|
|
.hljs-regexp,
|
|
.hljs-link {
|
|
color: #89ddff;
|
|
}
|
|
|
|
.hljs-emphasis {
|
|
font-style: italic;
|
|
}
|