Spaces:
Running
Running
| class PaperCard extends HTMLElement { | |
| constructor() { | |
| super(); | |
| this.attachShadow({ mode: 'open' }); | |
| } | |
| connectedCallback() { | |
| this.render(); | |
| } | |
| static get observedAttributes() { | |
| return ['title', 'summary', 'authors', 'date', 'pdf-link', 'abs-link']; | |
| } | |
| attributeChangedCallback(name, oldValue, newValue) { | |
| if (oldValue !== newValue) { | |
| this.render(); | |
| } | |
| } | |
| render() { | |
| const title = this.getAttribute('title') || 'No Title'; | |
| const summary = this.getAttribute('summary') || 'No summary available.'; | |
| const authors = this.getAttribute('authors') || 'Unknown'; | |
| const date = this.getAttribute('date') || ''; | |
| const pdfLink = this.getAttribute('pdf-link') || '#'; | |
| const absLink = this.getAttribute('abs-link') || '#'; | |
| // Truncate summary if too long | |
| const shortSummary = summary.length > 200 ? summary.substring(0, 200) + '...' : summary; | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| } | |
| .card { | |
| background-color: rgba(30, 41, 59, 0.6); | |
| border: 1px solid rgba(148, 163, 184, 0.1); | |
| border-radius: 1rem; | |
| padding: 1.5rem; | |
| transition: all 0.3s ease; | |
| position: relative; | |
| overflow: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| height: 100%; | |
| } | |
| .card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 25px -5px rgba(6, 182, 212, 0.15); | |
| border-color: rgba(6, 182, 212, 0.3); | |
| background-color: rgba(30, 41, 59, 0.9); | |
| } | |
| .card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 4px; | |
| height: 100%; | |
| background: linear-gradient(to bottom, #06b6d4, #8b5cf6); | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| } | |
| .card:hover::before { | |
| opacity: 1; | |
| } | |
| .badge { | |
| display: inline-block; | |
| background-color: rgba(139, 92, 246, 0.1); | |
| color: #a78bfa; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 9999px; | |
| margin-bottom: 0.75rem; | |
| border: 1px solid rgba(139, 92, 246, 0.2); | |
| } | |
| h3 { | |
| font-size: 1.125rem; | |
| font-weight: 700; | |
| color: #f1f5f9; | |
| margin-bottom: 0.75rem; | |
| line-height: 1.4; | |
| display: -webkit-box; | |
| -webkit-line-clamp: 2; | |
| -webkit-box-orient: vertical; | |
| overflow: hidden; | |
| } | |
| .authors { | |
| font-size: 0.8rem; | |
| color: #94a3b8; | |
| margin-bottom: 0.75rem; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.35rem; | |
| } | |
| p { | |
| font-size: 0.875rem; | |
| color: #cbd5e1; | |
| line-height: 1.6; | |
| margin-bottom: 1.5rem; | |
| flex-grow: 1; | |
| } | |
| .actions { | |
| display: flex; | |
| gap: 0.75rem; | |
| margin-top: auto; | |
| } | |
| .btn { | |
| flex: 1; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 0.5rem; | |
| padding: 0.5rem 1rem; | |
| border-radius: 0.5rem; | |
| font-size: 0.875rem; | |
| font-weight: 500; | |
| text-decoration: none; | |
| transition: all 0.2s; | |
| } | |
| .btn-primary { | |
| background-color: #0e7490; | |
| color: white; | |
| } | |
| .btn-primary:hover { | |
| background-color: #06b6d4; | |
| } | |
| .btn-outline { | |
| background-color: transparent; | |
| border: 1px solid #475569; | |
| color: #94a3b8; | |
| } | |
| .btn-outline:hover { | |
| border-color: #94a3b8; | |
| color: #e2e8f0; | |
| } | |
| </style> | |
| <article class="card"> | |
| <span class="badge">${date}</span> | |
| <h3 title="${title}">${title}</h3> | |
| <div class="authors"> | |
| <i data-feather="users" width="12" height="12"></i> | |
| <span>${authors}</span> | |
| </div> | |
| <p>${shortSummary}</p> | |
| <div class="actions"> | |
| <a href="${pdfLink}" target="_blank" class="btn btn-primary"> | |
| <i data-feather="file-text" width="16" height="16"></i> PDF | |
| </a> | |
| <a href="${absLink}" target="_blank" class="btn btn-outline"> | |
| <i data-feather="external-link" width="16" height="16"></i> Abstract | |
| </a> | |
| </div> | |
| </article> | |
| `; | |
| // Re-initialize icons inside Shadow DOM | |
| if(window.feather) { | |
| feather.replace(); | |
| } | |
| } | |
| } | |
| customElements.define('paper-card', PaperCard); |