44 changed files with 1613 additions and 703 deletions
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
/** |
||||
* Base Reset |
||||
* Minimal reset and base element styles |
||||
*/ |
||||
|
||||
* { |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
body { |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
||||
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
/** |
||||
* Spacing System |
||||
* Define consistent spacing variables based on an 8px base unit |
||||
* This creates a predictable rhythm across the entire application |
||||
*/ |
||||
|
||||
:root { |
||||
/* Base spacing unit: 8px */ |
||||
--spacing-base: 0.5rem; /* 8px */ |
||||
|
||||
/* Spacing scale (multiples of base unit) */ |
||||
--spacing-0: 0; |
||||
--spacing-1: 0.25rem; /* 4px - micro spacing */ |
||||
--spacing-2: 0.5rem; /* 8px - small spacing */ |
||||
--spacing-3: 1rem; /* 16px - medium spacing */ |
||||
--spacing-4: 1.5rem; /* 24px - large spacing */ |
||||
--spacing-5: 2rem; /* 32px - xl spacing */ |
||||
--spacing-6: 3rem; /* 48px - xxl spacing */ |
||||
--spacing-7: 4rem; /* 64px - huge spacing */ |
||||
--spacing-8: 6rem; /* 96px - massive spacing */ |
||||
|
||||
/* Common use-case aliases */ |
||||
--spacing-xs: var(--spacing-1); |
||||
--spacing-sm: var(--spacing-2); |
||||
--spacing-md: var(--spacing-3); |
||||
--spacing-lg: var(--spacing-4); |
||||
--spacing-xl: var(--spacing-5); |
||||
--spacing-2xl: var(--spacing-6); |
||||
--spacing-3xl: var(--spacing-7); |
||||
--spacing-4xl: var(--spacing-8); |
||||
|
||||
/* Component-specific spacing */ |
||||
--button-padding-y: var(--spacing-2); |
||||
--button-padding-x: var(--spacing-4); |
||||
--card-padding: var(--spacing-4); |
||||
--input-padding: var(--spacing-2); |
||||
--section-spacing: var(--spacing-6); |
||||
} |
||||
|
||||
@ -0,0 +1,145 @@
@@ -0,0 +1,145 @@
|
||||
/** |
||||
* Typography Styles |
||||
* Base typography including headings, paragraphs, links, and text utilities |
||||
*/ |
||||
|
||||
body { |
||||
display: flex; |
||||
flex-direction: column; |
||||
min-height: 100vh; |
||||
max-width: 100%; |
||||
background-color: var(--color-bg); |
||||
color: var(--color-text); |
||||
font-family: var(--font-family), sans-serif; |
||||
margin: 0; |
||||
padding: 0; |
||||
line-height: 1.6; |
||||
} |
||||
|
||||
/* Headings */ |
||||
h1, h2, h3, h4, h5, h6 { |
||||
font-family: var(--heading-font), serif; |
||||
font-weight: 600; |
||||
line-height: 1.1; |
||||
color: var(--color-primary); |
||||
margin: 30px 0 10px; |
||||
} |
||||
|
||||
h1 { |
||||
font-size: 3.2rem; |
||||
margin-top: 0.25em; |
||||
font-weight: 300; |
||||
} |
||||
|
||||
h1.brand { |
||||
font-family: var(--brand-font), serif; |
||||
color: var(--color-primary); |
||||
font-size: 3.2rem; |
||||
} |
||||
|
||||
h1.brand a { |
||||
color: var(--brand-color); |
||||
text-decoration: none; |
||||
} |
||||
|
||||
h1.brand a:hover { |
||||
text-decoration: none; |
||||
} |
||||
|
||||
h1:not(.brand) > a:hover { |
||||
text-decoration: none; |
||||
font-weight: 500; |
||||
} |
||||
|
||||
h2 { |
||||
font-size: 2.2rem; |
||||
} |
||||
|
||||
h2.brand { |
||||
font-family: var(--brand-font), serif; |
||||
color: var(--color-primary); |
||||
} |
||||
|
||||
h3 { |
||||
font-size: 2rem; |
||||
} |
||||
|
||||
h4 { |
||||
font-size: 1.9rem; |
||||
} |
||||
|
||||
h5 { |
||||
font-size: 1.75rem; |
||||
} |
||||
|
||||
h6 { |
||||
font-size: 1.5rem; |
||||
} |
||||
|
||||
/* Sidebar heading overrides */ |
||||
aside h1 { |
||||
font-size: 1.2rem; |
||||
} |
||||
|
||||
aside h2 { |
||||
font-size: 1.1rem; |
||||
} |
||||
|
||||
aside p.lede { |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
/* Paragraphs and text */ |
||||
p { |
||||
margin: 0 0 15px; |
||||
} |
||||
|
||||
.lede { |
||||
font-family: var(--main-body-font), serif; |
||||
font-size: 1.6rem; |
||||
word-wrap: break-word; |
||||
font-weight: 300; |
||||
} |
||||
|
||||
strong:not(>h2), .strong { |
||||
color: var(--color-primary); |
||||
} |
||||
|
||||
/* Links */ |
||||
a { |
||||
color: var(--color-secondary); |
||||
text-decoration: none; |
||||
} |
||||
|
||||
a:hover { |
||||
text-decoration: underline; |
||||
} |
||||
|
||||
/* Images and icons */ |
||||
img { |
||||
max-width: 100%; |
||||
height: auto; |
||||
} |
||||
|
||||
svg.icon { |
||||
width: 2em; |
||||
height: 2em; |
||||
} |
||||
|
||||
/* Utility classes */ |
||||
.hidden { |
||||
display: none; |
||||
} |
||||
|
||||
.divider { |
||||
border: 2px solid var(--color-primary); |
||||
margin: 20px 0; |
||||
} |
||||
|
||||
.truncate { |
||||
display: -webkit-box; |
||||
-webkit-line-clamp: 3; |
||||
-webkit-box-orient: vertical; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
} |
||||
@ -0,0 +1,175 @@
@@ -0,0 +1,175 @@
|
||||
/** |
||||
* Header Component |
||||
* Main site header with navigation categories |
||||
*/ |
||||
|
||||
.header { |
||||
text-align: center; |
||||
z-index: 1000; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
background-color: var(--color-bg); |
||||
border-bottom: 1px solid var(--color-border); |
||||
} |
||||
|
||||
.header .container { |
||||
display: flex; |
||||
flex-direction: column; |
||||
} |
||||
|
||||
.header__categories ul { |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
justify-content: center; |
||||
gap: 20px; |
||||
padding: 0; |
||||
} |
||||
|
||||
.header__categories li { |
||||
list-style: none; |
||||
} |
||||
|
||||
.header__categories li a:hover { |
||||
text-decoration: none; |
||||
} |
||||
/** |
||||
* Shared Card Styles |
||||
* Styles that are used across different card types in the app |
||||
*/ |
||||
|
||||
.card { |
||||
background-color: var(--color-bg); |
||||
color: var(--color-text); |
||||
padding: 0; |
||||
margin: 0 0 2rem 0; |
||||
border-radius: 0; /* Sharp edges */ |
||||
} |
||||
|
||||
.card a:hover { |
||||
text-decoration: none; |
||||
color: var(--color-text); |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.card a:hover h2 { |
||||
color: var(--color-text); |
||||
} |
||||
|
||||
.card.bordered { |
||||
border: 2px solid var(--color-border); |
||||
} |
||||
|
||||
.card-header { |
||||
margin: 10px 0; |
||||
} |
||||
|
||||
.header__image { |
||||
position: relative; |
||||
width: 100%; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
.header__image::before { |
||||
content: ""; |
||||
display: block; |
||||
padding-top: 56.25%; /* 16:9 aspect ratio */ |
||||
} |
||||
|
||||
.header__image img { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
object-fit: cover; |
||||
} |
||||
|
||||
.card-body { |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
.card-footer { |
||||
border-top: 1px solid var(--color-border); |
||||
margin: 20px 0; |
||||
} |
||||
|
||||
/* Featured cards layout */ |
||||
.featured-cat { |
||||
border-bottom: 2px solid var(--color-border); |
||||
padding-left: 10px; |
||||
} |
||||
|
||||
.featured-list { |
||||
display: flex; |
||||
flex-direction: row; |
||||
flex-wrap: wrap; |
||||
} |
||||
|
||||
.featured-list > * { |
||||
box-sizing: border-box; |
||||
margin-bottom: 10px; |
||||
padding: 10px; |
||||
} |
||||
|
||||
div:nth-child(odd) .featured-list { |
||||
flex-direction: row-reverse; |
||||
} |
||||
|
||||
.featured-list div:first-child { |
||||
flex: 0 0 66%; |
||||
} |
||||
|
||||
.featured-list div:last-child { |
||||
flex: 0 0 34%; |
||||
} |
||||
|
||||
.featured-list h2.card-title { |
||||
font-size: 1.5rem; |
||||
} |
||||
|
||||
.featured-list p.lede { |
||||
font-size: 1.4rem; |
||||
} |
||||
|
||||
.featured-list .card { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.featured-list .card:not(:last-child) { |
||||
border-bottom: 1px solid var(--color-border); |
||||
} |
||||
|
||||
/* Article list cards */ |
||||
.article-list .metadata { |
||||
display: flex; |
||||
flex-direction: row; |
||||
justify-content: space-between; |
||||
align-items: baseline; |
||||
} |
||||
|
||||
.article-list .metadata p { |
||||
margin: 0; |
||||
} |
||||
|
||||
/* Responsive adjustments */ |
||||
@media (max-width: 1024px) { |
||||
.featured-list { |
||||
flex-direction: column !important; |
||||
} |
||||
|
||||
.featured-list .card-header { |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
.featured-list .card { |
||||
border-bottom: 1px solid var(--color-border) !important; |
||||
} |
||||
|
||||
.featured-list > * { |
||||
margin-bottom: 10px; |
||||
padding: 0; |
||||
} |
||||
} |
||||
|
||||
@ -1,9 +1,13 @@
@@ -1,9 +1,13 @@
|
||||
/** |
||||
* Button Component |
||||
* Primary button styles and variants |
||||
*/ |
||||
|
||||
button, .btn, a.btn { |
||||
background-color: var(--color-primary); |
||||
color: var(--color-text-contrast); |
||||
border: 2px solid var(--color-primary); |
||||
padding: 10px 20px; |
||||
padding: var(--button-padding-y) var(--button-padding-x); |
||||
text-transform: uppercase; |
||||
font-weight: bold; |
||||
cursor: pointer; |
||||
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
/* Image Upload Dialog Styles */ |
||||
.iu-dialog { |
||||
display: none; |
||||
} |
||||
|
||||
.iu-dialog.active { |
||||
display: block; |
||||
} |
||||
|
||||
.iu-backdrop { |
||||
position: fixed; |
||||
top: 0; |
||||
left: 0; |
||||
right: 0; |
||||
bottom: 0; |
||||
background-color: rgba(0, 0, 0, 0.5); |
||||
z-index: 1000; |
||||
} |
||||
|
||||
.iu-modal { |
||||
position: fixed; |
||||
top: 50%; |
||||
left: 50%; |
||||
transform: translate(-50%, -50%); |
||||
background-color: var(--color-bg, #fff); |
||||
border-radius: 0.5rem; |
||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.3); |
||||
max-width: 90%; |
||||
width: 500px; |
||||
max-height: 90vh; |
||||
overflow-y: auto; |
||||
z-index: 1001; |
||||
} |
||||
|
||||
.iu-modal .modal-header { |
||||
padding: var(--spacing-3); |
||||
border-bottom: 1px solid var(--color-border, #dee2e6); |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
} |
||||
|
||||
.iu-modal .modal-header h5 { |
||||
margin: 0; |
||||
} |
||||
|
||||
.iu-modal .modal-header .close { |
||||
background: none; |
||||
border: none; |
||||
font-size: 1.5rem; |
||||
cursor: pointer; |
||||
color: var(--color-text); |
||||
} |
||||
|
||||
.iu-modal .modal-body { |
||||
padding: var(--spacing-3); |
||||
} |
||||
|
||||
.iu-modal .modal-body > div { |
||||
margin-bottom: var(--spacing-3); |
||||
} |
||||
|
||||
.upload-area { |
||||
border: 2px dashed #ccc; |
||||
padding: var(--spacing-5); |
||||
text-align: center; |
||||
cursor: pointer; |
||||
min-height: 4em; |
||||
border-radius: 0.25rem; |
||||
transition: border-color 0.2s; |
||||
} |
||||
|
||||
.upload-area:hover { |
||||
border-color: var(--color-primary, #007bff); |
||||
} |
||||
|
||||
.upload-area input[type="file"] { |
||||
display: none; |
||||
} |
||||
|
||||
.upload-progress { |
||||
display: none; |
||||
margin-top: 1em; |
||||
} |
||||
|
||||
.upload-progress.active { |
||||
display: block; |
||||
} |
||||
|
||||
.upload-error { |
||||
color: red; |
||||
margin-top: 1em; |
||||
display: none; |
||||
} |
||||
|
||||
.upload-error.active { |
||||
display: block; |
||||
} |
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
/** |
||||
* Nostr Previews Component |
||||
* Styles for Nostr event and profile preview cards |
||||
* Converted from SCSS to plain CSS |
||||
*/ |
||||
|
||||
.nostr-preview { |
||||
margin-top: var(--spacing-2); |
||||
} |
||||
|
||||
.nostr-preview .nostr-event-preview, |
||||
.nostr-preview .nostr-profile-preview { |
||||
border-left: 3px solid #6c5ce7; |
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
||||
} |
||||
|
||||
.nostr-preview .nostr-profile-preview { |
||||
border-left-color: #00b894; |
||||
} |
||||
|
||||
.nostr-preview .card-title { |
||||
margin-bottom: var(--spacing-2); |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
.nostr-preview .card-text { |
||||
font-size: 0.9rem; |
||||
} |
||||
|
||||
.nostr-preview .card-footer { |
||||
padding: var(--spacing-2) var(--spacing-3); |
||||
} |
||||
|
||||
.nostr-previews h6 { |
||||
font-size: 0.9rem; |
||||
margin-bottom: var(--spacing-3); |
||||
} |
||||
|
||||
.nostr-previews .preview-container { |
||||
max-height: 500px; |
||||
overflow-y: auto; |
||||
padding-right: var(--spacing-2); |
||||
} |
||||
|
||||
/* Style for nostr links in text */ |
||||
.nostr-link { |
||||
color: #6c5ce7; |
||||
background-color: rgba(108, 92, 231, 0.1); |
||||
padding: 0 var(--spacing-1); |
||||
border-radius: 3px; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
.nostr-link:hover { |
||||
background-color: rgba(108, 92, 231, 0.2); |
||||
} |
||||
@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
|
||||
.notice { |
||||
padding: 10px; /* Padding around the content */ |
||||
padding: var(--spacing-2); /* Padding around the content */ |
||||
border-radius: 5px; /* Rounded corners */ |
||||
margin: 10px 0; /* Margin above and below the notice */ |
||||
margin: var(--spacing-2) 0; /* Margin above and below the notice */ |
||||
} |
||||
|
||||
.notice p { |
||||
@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
|
||||
.og-preview-card { |
||||
max-width: 100%; |
||||
padding: 20px; |
||||
margin: 10px 0; |
||||
padding: var(--spacing-4); |
||||
margin: var(--spacing-2) 0; |
||||
background-color: var(--color-bg); |
||||
} |
||||
|
||||
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
/* Search Component Styles */ |
||||
.search-component { |
||||
margin-bottom: 1rem; |
||||
} |
||||
|
||||
.search-credits { |
||||
text-align: right; |
||||
} |
||||
|
||||
.search-credits .help-text { |
||||
font-size: 0.875rem; |
||||
} |
||||
|
||||
.search-loading { |
||||
text-align: center; |
||||
} |
||||
|
||||
.search form { |
||||
margin-bottom: 1rem; |
||||
} |
||||
|
||||
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
/* Admin Panel Styles */ |
||||
|
||||
/* Analytics */ |
||||
.analytics-container { |
||||
padding: var(--spacing-3); |
||||
} |
||||
|
||||
.analytics-card { |
||||
margin-bottom: var(--spacing-5); |
||||
padding: var(--spacing-3); |
||||
background-color: var(--color-card-bg, #f8f9fa); |
||||
border-radius: 0.5rem; |
||||
} |
||||
|
||||
.analytics-stats { |
||||
list-style: none; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.analytics-stats li { |
||||
padding: var(--spacing-2) 0; |
||||
} |
||||
|
||||
.analytics-table { |
||||
width: 100%; |
||||
border-collapse: collapse; |
||||
} |
||||
|
||||
.analytics-table th { |
||||
padding: var(--spacing-3); |
||||
text-align: left; |
||||
border-bottom: 2px solid var(--color-border, #dee2e6); |
||||
} |
||||
|
||||
.analytics-table th.text-right, |
||||
.analytics-table th[style*="text-align: right"] { |
||||
min-width: 100px; |
||||
text-align: right; |
||||
} |
||||
|
||||
.analytics-table td { |
||||
padding: var(--spacing-3); |
||||
border-bottom: 1px solid var(--color-border, #dee2e6); |
||||
} |
||||
|
||||
.analytics-table td.text-right { |
||||
text-align: right; |
||||
} |
||||
|
||||
.analytics-info { |
||||
padding: var(--spacing-3); |
||||
background-color: var(--color-info-bg, #e9f5ff); |
||||
border-radius: 0.25rem; |
||||
} |
||||
|
||||
/* Articles Table */ |
||||
.admin-articles-table { |
||||
width: 100%; |
||||
border-collapse: collapse; |
||||
} |
||||
|
||||
.admin-articles-table tr { |
||||
padding-bottom: var(--spacing-1); |
||||
} |
||||
|
||||
.admin-articles-table td { |
||||
padding: var(--spacing-2); |
||||
vertical-align: top; |
||||
} |
||||
|
||||
.admin-articles-table button { |
||||
margin-left: var(--spacing-2); |
||||
} |
||||
|
||||
.admin-articles-table form { |
||||
display: inline; |
||||
} |
||||
|
||||
/* Magazine Editor */ |
||||
.magazine-editor-layout { |
||||
display: flex; |
||||
gap: var(--spacing-4); |
||||
} |
||||
|
||||
.magazine-editor-section { |
||||
flex: 1; |
||||
min-width: 320px; |
||||
} |
||||
|
||||
.magazine-search-form { |
||||
margin-bottom: var(--spacing-3); |
||||
display: flex; |
||||
gap: var(--spacing-2); |
||||
} |
||||
|
||||
.magazine-search-form input[type="text"] { |
||||
flex: 1; |
||||
} |
||||
|
||||
.magazine-table { |
||||
width: 100%; |
||||
border-collapse: collapse; |
||||
} |
||||
|
||||
.magazine-table th { |
||||
padding: 0.25rem 0.5rem; |
||||
text-align: left; |
||||
border-bottom: 1px solid var(--color-border, #dee2e6); |
||||
} |
||||
|
||||
.magazine-table td { |
||||
padding: 0.25rem 0.5rem; |
||||
vertical-align: top; |
||||
} |
||||
|
||||
.magazine-table td.actions { |
||||
text-align: right; |
||||
} |
||||
|
||||
.magazine-table td.author { |
||||
white-space: nowrap; |
||||
} |
||||
/* NIP-68 Picture Event Styles */ |
||||
.picture-event { |
||||
margin: 1rem 0; |
||||
} |
||||
|
||||
.picture-title { |
||||
font-size: 1.5rem; |
||||
margin-bottom: 1rem; |
||||
} |
||||
|
||||
.content-warning { |
||||
padding: 1rem; |
||||
background-color: var(--color-warning-bg, #fff3cd); |
||||
border: 1px solid var(--color-warning-border, #ffc107); |
||||
border-radius: 0.25rem; |
||||
margin-bottom: 1rem; |
||||
} |
||||
|
||||
.btn-show-nsfw { |
||||
margin-left: 0.5rem; |
||||
padding: 0.25rem 0.5rem; |
||||
background-color: var(--color-primary); |
||||
color: white; |
||||
border: none; |
||||
border-radius: 0.25rem; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.btn-show-nsfw:hover { |
||||
opacity: 0.9; |
||||
} |
||||
|
||||
.picture-gallery { |
||||
display: block; |
||||
} |
||||
|
||||
.picture-gallery.hidden { |
||||
display: none; |
||||
} |
||||
|
||||
.picture-item { |
||||
position: relative; |
||||
margin-bottom: 1rem; |
||||
} |
||||
|
||||
.picture-image { |
||||
max-width: 100%; |
||||
height: auto; |
||||
display: block; |
||||
} |
||||
|
||||
.annotated-users { |
||||
position: relative; |
||||
} |
||||
|
||||
.user-tag { |
||||
position: absolute; |
||||
background-color: rgba(0, 0, 0, 0.7); |
||||
color: white; |
||||
padding: 0.25rem 0.5rem; |
||||
border-radius: 0.25rem; |
||||
font-size: 0.875rem; |
||||
white-space: nowrap; |
||||
} |
||||
|
||||
.picture-alt { |
||||
margin-top: 0.5rem; |
||||
font-style: italic; |
||||
color: var(--color-text-muted, #6c757d); |
||||
} |
||||
@ -0,0 +1,123 @@
@@ -0,0 +1,123 @@
|
||||
.profile-tabs { |
||||
display: flex; |
||||
gap: 1rem; |
||||
margin: 1.5rem 0; |
||||
border-bottom: 2px solid #e0e0e0; |
||||
} |
||||
|
||||
.tab-link { |
||||
padding: 0.75rem 1.5rem; |
||||
text-decoration: none; |
||||
color: #666; |
||||
border-bottom: 3px solid transparent; |
||||
margin-bottom: -2px; |
||||
transition: all 0.3s ease; |
||||
} |
||||
|
||||
.tab-link:hover { |
||||
color: #333; |
||||
border-bottom-color: #ccc; |
||||
} |
||||
|
||||
.tab-link.active { |
||||
color: #0066cc; |
||||
border-bottom-color: #0066cc; |
||||
font-weight: 600; |
||||
} |
||||
|
||||
.masonry-grid { |
||||
column-count: 3; |
||||
column-gap: 1.5rem; |
||||
margin: 2rem 0; |
||||
} |
||||
|
||||
@media (max-width: 1200px) { |
||||
.masonry-grid { |
||||
column-count: 2; |
||||
} |
||||
} |
||||
|
||||
@media (max-width: 768px) { |
||||
.masonry-grid { |
||||
column-count: 1; |
||||
} |
||||
} |
||||
|
||||
.masonry-item { |
||||
break-inside: avoid; |
||||
margin-bottom: 1.5rem; |
||||
background: #fff; |
||||
border-radius: 8px; |
||||
overflow: hidden; |
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
||||
transition: transform 0.2s ease, box-shadow 0.2s ease; |
||||
} |
||||
|
||||
.masonry-item:hover { |
||||
transform: translateY(-4px); |
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); |
||||
} |
||||
|
||||
.masonry-link, .masonry-link:hover { |
||||
display: block; |
||||
text-decoration: none; |
||||
color: inherit; |
||||
} |
||||
|
||||
.masonry-image-container { |
||||
width: 100%; |
||||
overflow: hidden; |
||||
background-color: #f5f5f5; |
||||
} |
||||
|
||||
.masonry-image { |
||||
width: 100%; |
||||
height: auto; |
||||
display: block; |
||||
transition: transform 0.3s ease; |
||||
} |
||||
|
||||
.masonry-item:hover .masonry-image { |
||||
transform: scale(1.05); |
||||
} |
||||
|
||||
.masonry-caption { |
||||
padding: 1rem 1rem 0.5rem; |
||||
} |
||||
|
||||
.masonry-caption h3 { |
||||
margin: 0; |
||||
font-size: 1.1rem; |
||||
font-weight: 600; |
||||
color: #333; |
||||
line-height: 1.4; |
||||
} |
||||
|
||||
.masonry-description { |
||||
padding: 0 1rem; |
||||
font-size: 0.9rem; |
||||
color: #666; |
||||
line-height: 1.5; |
||||
} |
||||
|
||||
.masonry-meta { |
||||
padding: 0.75rem 1rem; |
||||
border-top: 1px solid #f0f0f0; |
||||
margin-top: 0.5rem; |
||||
} |
||||
|
||||
.event-date { |
||||
font-size: 0.85rem; |
||||
color: #999; |
||||
} |
||||
|
||||
.no-media { |
||||
text-align: center; |
||||
padding: 3rem 1rem; |
||||
color: #666; |
||||
} |
||||
|
||||
.no-media p { |
||||
font-size: 1.1rem; |
||||
} |
||||
|
||||
@ -1,520 +0,0 @@
@@ -1,520 +0,0 @@
|
||||
body { |
||||
display: flex; |
||||
flex-direction: column; |
||||
min-height: 100vh; |
||||
max-width: 100%; |
||||
background-color: var(--color-bg); |
||||
color: var(--color-text); |
||||
font-family: var(--font-family), sans-serif; |
||||
margin: 0; |
||||
padding: 0; |
||||
line-height: 1.6; |
||||
} |
||||
|
||||
h1, h2, h3, h4, h5, h6 { |
||||
font-family: var(--heading-font), serif; |
||||
font-weight: 600; |
||||
line-height: 1.1; |
||||
color: var(--color-primary); |
||||
margin: 30px 0 10px; |
||||
} |
||||
|
||||
h1 { |
||||
font-size: 3.2rem; |
||||
margin-top: 0.25em; |
||||
font-weight: 300; |
||||
} |
||||
|
||||
h1.brand { |
||||
font-family: var(--brand-font), serif; |
||||
color: var(--color-primary); |
||||
font-size: 3.2rem; |
||||
} |
||||
|
||||
@media screen and (max-width: 600px) { |
||||
h1.brand { |
||||
font-size: 2.3rem; |
||||
} |
||||
} |
||||
|
||||
h1.brand a { |
||||
color: var(--brand-color); |
||||
} |
||||
|
||||
h1:not(.brand) > a:hover { |
||||
text-decoration: none; |
||||
font-weight: 500; |
||||
} |
||||
|
||||
h2 { |
||||
font-size: 2.2rem; |
||||
} |
||||
|
||||
h2.brand { |
||||
font-family: var(--brand-font), serif; |
||||
color: var(--color-primary); |
||||
} |
||||
|
||||
h3 { |
||||
font-size: 2rem; |
||||
} |
||||
|
||||
h4 { |
||||
font-size: 1.9rem; |
||||
} |
||||
|
||||
h5 { |
||||
font-size: 1.75rem; |
||||
} |
||||
|
||||
h6 { |
||||
font-size: 1.5rem; |
||||
} |
||||
|
||||
p { |
||||
margin: 0 0 15px; |
||||
} |
||||
|
||||
aside h1 { |
||||
font-size: 1.2rem; |
||||
} |
||||
|
||||
aside h2 { |
||||
font-size: 1.1rem; |
||||
} |
||||
|
||||
aside p.lede { |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
.lede { |
||||
font-family: var(--main-body-font), serif; |
||||
font-size: 1.6rem; |
||||
word-wrap: break-word; |
||||
font-weight: 300; |
||||
} |
||||
|
||||
strong:not(>h2), .strong { |
||||
color: var(--color-primary); |
||||
} |
||||
|
||||
.hidden { |
||||
display: none; |
||||
} |
||||
|
||||
a { |
||||
color: var(--color-secondary); |
||||
text-decoration: none; |
||||
} |
||||
|
||||
a:hover { |
||||
text-decoration: underline; |
||||
} |
||||
|
||||
.card a:hover { |
||||
text-decoration: none; |
||||
color: var(--color-text); |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.card a:hover h2 { |
||||
color: var(--color-text); |
||||
} |
||||
|
||||
img { |
||||
max-width: 100%; |
||||
height: auto; |
||||
} |
||||
|
||||
svg.icon { |
||||
width: 2em; |
||||
height: 2em; |
||||
} |
||||
|
||||
.divider { |
||||
border: 2px solid var(--color-primary); |
||||
margin: 20px 0; |
||||
} |
||||
|
||||
.hashtag { |
||||
color: var(--color-secondary); |
||||
} |
||||
|
||||
.card { |
||||
background-color: var(--color-bg); |
||||
color: var(--color-text); |
||||
padding: 0; |
||||
margin: 0 0 2rem 0; |
||||
border-radius: 0; /* Sharp edges */ |
||||
} |
||||
|
||||
.featured-cat { |
||||
border-bottom: 2px solid var(--color-border); |
||||
padding-left: 10px; |
||||
} |
||||
|
||||
.featured-list { |
||||
display: flex; |
||||
flex-direction: row; |
||||
flex-wrap: wrap; |
||||
} |
||||
|
||||
|
||||
.featured-list > * { |
||||
box-sizing: border-box; /* so padding/border don't break the layout */ |
||||
margin-bottom: 10px; |
||||
padding: 10px; |
||||
} |
||||
|
||||
@media (max-width: 1024px) { |
||||
.featured-list { |
||||
flex-direction: column !important; |
||||
} |
||||
|
||||
.featured-list .card-header { |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
.featured-list .card { |
||||
border-bottom: 1px solid var(--color-border) !important; |
||||
} |
||||
|
||||
.featured-list > * { |
||||
margin-bottom: 10px; |
||||
padding: 0; |
||||
} |
||||
} |
||||
div:nth-child(odd) .featured-list { |
||||
flex-direction: row-reverse; |
||||
} |
||||
|
||||
.featured-list div:first-child { |
||||
flex: 0 0 66%; /* each item takes up 50% width = 2 columns */ |
||||
} |
||||
|
||||
.featured-list div:last-child { |
||||
flex: 0 0 34%; /* each item takes up 50% width = 2 columns */ |
||||
} |
||||
|
||||
.featured-list h2.card-title { |
||||
font-size: 1.5rem; |
||||
} |
||||
|
||||
.featured-list p.lede { |
||||
font-size: 1.4rem; |
||||
} |
||||
|
||||
.featured-list .card { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.featured-list .card:not(:last-child) { |
||||
border-bottom: 1px solid var(--color-border); |
||||
} |
||||
|
||||
.article-list .metadata { |
||||
display: flex; |
||||
flex-direction: row; |
||||
justify-content: space-between; |
||||
align-items: baseline; |
||||
} |
||||
|
||||
.article-list .metadata p { |
||||
margin: 0; |
||||
} |
||||
|
||||
.truncate { |
||||
display: -webkit-box; |
||||
-webkit-line-clamp: 3; /* limit to 3 lines */ |
||||
-webkit-box-orient: vertical; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
} |
||||
|
||||
.card.bordered { |
||||
border: 2px solid var(--color-border); |
||||
} |
||||
|
||||
.card-header { |
||||
margin: 10px 0; |
||||
} |
||||
|
||||
.header__image { |
||||
position: relative; |
||||
width: 100%; |
||||
overflow: hidden; /* Ensures any overflow is hidden */ |
||||
} |
||||
|
||||
.header__image::before { |
||||
content: ""; |
||||
display: block; |
||||
padding-top: 56.25%; /* 16:9 aspect ratio (9 / 16 * 100 = 56.25%) */ |
||||
} |
||||
|
||||
.header__image img { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
object-fit: cover; /* Ensures the image covers the entire area while maintaining its aspect ratio */ |
||||
} |
||||
|
||||
.card-body { |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
.card-footer { |
||||
border-top: 1px solid var(--color-border); |
||||
margin: 20px 0; |
||||
} |
||||
|
||||
.header { |
||||
text-align: center; |
||||
z-index: 1000; /* Ensure it stays on top */ |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
background-color: var(--color-bg); /* Black background */ |
||||
border-bottom: 1px solid var(--color-border); |
||||
} |
||||
|
||||
.header .container { |
||||
display: flex; |
||||
flex-direction: column; |
||||
} |
||||
|
||||
.header__categories ul { |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
justify-content: center; |
||||
gap: 20px; |
||||
padding: 0; |
||||
} |
||||
|
||||
.header__categories li { |
||||
list-style: none; |
||||
} |
||||
|
||||
.header__categories li a:hover { |
||||
text-decoration: none; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.header__categories a.active { |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.header__logo h1 { |
||||
font-weight: normal; |
||||
} |
||||
|
||||
.header__logo img { |
||||
height: 40px; /* Adjust the height as needed */ |
||||
} |
||||
|
||||
.header__logo a:hover { |
||||
text-decoration: none; |
||||
} |
||||
|
||||
.header__user { |
||||
position: relative; |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
|
||||
.header__avatar img { |
||||
height: 40px; /* Adjust the avatar size as needed */ |
||||
width: 40px; |
||||
border-radius: 50%; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.header__dropdown { |
||||
display: none; |
||||
position: absolute; |
||||
top: 50px; /* Adjust this depending on the header.html.twig height */ |
||||
right: 0; |
||||
background-color: var(--color-text); /* White dropdown */ |
||||
border: 2px solid var(--color-bg); /* Black border */ |
||||
list-style: none; |
||||
padding: 10px 0; |
||||
z-index: 1000; |
||||
border-radius: 0; /* Sharp edges */ |
||||
} |
||||
|
||||
.header__dropdown ul { |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
||||
|
||||
.header__dropdown li { |
||||
padding: 10px 20px; |
||||
} |
||||
|
||||
.header__dropdown li a { |
||||
color: var(--color-bg); /* Black text */ |
||||
text-decoration: none; |
||||
} |
||||
|
||||
.header__dropdown li a:hover { |
||||
background-color: var(--color-bg); /* Black background on hover */ |
||||
color: var(--color-text); /* White text on hover */ |
||||
display: block; |
||||
} |
||||
|
||||
footer p { |
||||
margin: 0; |
||||
} |
||||
|
||||
footer a { |
||||
color: var(--color-text-contrast); |
||||
} |
||||
|
||||
/* Tags container */ |
||||
.tags { |
||||
margin: 10px 0; |
||||
display: flex; |
||||
flex-wrap: wrap; /* Allows tags to wrap to the next line if needed */ |
||||
gap: 10px; /* Adds spacing between individual tags */ |
||||
} |
||||
|
||||
/* Individual tag */ |
||||
.tag { |
||||
background-color: var(--color-bg-light); |
||||
color: var(--color-text-mid); |
||||
padding: 3px 6px; /* Padding around the tag text */ |
||||
border-radius: 20px; /* Rounded corners (pill-shaped) */ |
||||
font-size: 0.75em; /* Slightly smaller text */ |
||||
cursor: pointer; /* Cursor turns to pointer for clickable tags */ |
||||
text-decoration: none; /* Removes any text decoration (e.g., underline) */ |
||||
display: inline-block; /* Makes sure each tag behaves like a block with padding */ |
||||
transition: background-color 0.3s ease; /* Smooth hover effect */ |
||||
} |
||||
|
||||
/*!* Hover effect for tags *!*/ |
||||
/*.tag:hover {*/ |
||||
/* color: var(--color-text-contrast);*/ |
||||
/*}*/ |
||||
|
||||
/* Optional: Responsive adjustments for smaller screens */ |
||||
@media (max-width: 768px) { |
||||
.tag { |
||||
font-size: 0.8em; /* Slightly smaller text for mobile */ |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
.card.card__horizontal { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
|
||||
h1 { |
||||
font-size: 2rem; |
||||
} |
||||
|
||||
.card-content { |
||||
flex: 1; |
||||
margin-right: 30px; |
||||
padding: 0 8px; |
||||
} |
||||
|
||||
.card-image img { |
||||
width: 220px; |
||||
max-height: 220px; |
||||
object-fit: contain; |
||||
} |
||||
} |
||||
|
||||
.article__image img { |
||||
margin: 1rem 0; |
||||
width: 100%; |
||||
} |
||||
|
||||
.badge { |
||||
background-color: var(--color-primary); |
||||
color: var(--color-bg); |
||||
padding: 3px 8px; |
||||
border-radius: 20px; |
||||
font-family: var(--font-family), sans-serif; |
||||
font-weight: bold; |
||||
font-size: 0.65em; |
||||
text-transform: uppercase; |
||||
margin-right: 5px; |
||||
vertical-align: super; |
||||
} |
||||
|
||||
.badge.badge__secondary { |
||||
background-color: var(--color-secondary); |
||||
} |
||||
|
||||
.avatar { |
||||
width: 24px; /* Adjust the size as needed */ |
||||
height: 24px; /* Adjust the size as needed */ |
||||
border-radius: 50%; /* Makes the image circular */ |
||||
object-fit: cover; /* Ensures the image scales correctly */ |
||||
display: inline-block; |
||||
vertical-align: middle; |
||||
} |
||||
|
||||
.alert { |
||||
padding: 10px 20px; /* Padding around the text */ |
||||
border-radius: 5px; /* Rounded corners */ |
||||
margin: 20px 0; /* Spacing around the alert */ |
||||
} |
||||
|
||||
.alert.alert-success { |
||||
background-color: var(--color-secondary); |
||||
color: var(--color-text-contrast); |
||||
} |
||||
|
||||
/* Tabs Container */ |
||||
.nav-tabs { |
||||
display: flex; /* Arrange items in a row */ |
||||
justify-content: center; |
||||
padding: 0; /* Remove padding */ |
||||
margin: 0; /* Remove margin */ |
||||
list-style: none; /* Remove list item styling */ |
||||
} |
||||
|
||||
/* Individual Tab Item */ |
||||
.nav-tabs .nav-item { |
||||
margin: 0; /* No margin around list items */ |
||||
} |
||||
|
||||
/* NON-Active Tab */ |
||||
.nav-tabs .nav-link { |
||||
color: var(--color-text); |
||||
background-color: transparent; |
||||
border: none; |
||||
} |
||||
|
||||
|
||||
/* Active Tab */ |
||||
.nav-tabs .nav-link.active { |
||||
color: var(--color-text-contrast); |
||||
background-color: var(--color-primary); |
||||
font-weight: bold; |
||||
} |
||||
|
||||
/* Content Container */ |
||||
.tab-content { |
||||
padding: 15px; /* Spacing inside the content */ |
||||
border-top: none; /* Remove border overlap with active tab */ |
||||
} |
||||
|
||||
/* Quill editor */ |
||||
#editor { |
||||
height: 400px; |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
/* Search */ |
||||
label.search { |
||||
width: 100%; |
||||
justify-content: center; |
||||
margin-bottom: 15px; |
||||
} |
||||
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
// ...existing code... |
||||
@import "components/nostr_previews"; |
||||
// ...existing code... |
||||
@ -1,52 +0,0 @@
@@ -1,52 +0,0 @@
|
||||
.nostr-preview { |
||||
margin-top: 0.5rem; |
||||
|
||||
.nostr-event-preview, .nostr-profile-preview { |
||||
border-left: 3px solid #6c5ce7; |
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
||||
} |
||||
|
||||
.nostr-profile-preview { |
||||
border-left-color: #00b894; |
||||
} |
||||
|
||||
.card-title { |
||||
margin-bottom: 0.5rem; |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
.card-text { |
||||
font-size: 0.9rem; |
||||
} |
||||
|
||||
.card-footer { |
||||
padding: 0.5rem 1rem; |
||||
} |
||||
} |
||||
|
||||
.nostr-previews { |
||||
h6 { |
||||
font-size: 0.9rem; |
||||
margin-bottom: 1rem; |
||||
} |
||||
|
||||
.preview-container { |
||||
// For multiple previews |
||||
max-height: 500px; |
||||
overflow-y: auto; |
||||
padding-right: 10px; |
||||
} |
||||
} |
||||
|
||||
// Style for nostr links in text |
||||
.nostr-link { |
||||
color: #6c5ce7; |
||||
background-color: rgba(108, 92, 231, 0.1); |
||||
padding: 0 3px; |
||||
border-radius: 3px; |
||||
text-decoration: none; |
||||
|
||||
&:hover { |
||||
background-color: rgba(108, 92, 231, 0.2); |
||||
} |
||||
} |
||||
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
{% extends 'layout.html.twig' %} |
||||
|
||||
{% block body %} |
||||
|
||||
{% if author.image is defined %} |
||||
<img src="{{ author.image }}" class="avatar" alt="{{ author.name }}" onerror="this.style.display = 'none'" /> |
||||
{% endif %} |
||||
|
||||
<h1><twig:Atoms:NameOrNpub :author="author" :npub="npub"></twig:Atoms:NameOrNpub></h1> |
||||
<div> |
||||
{% if author.about is defined %} |
||||
{{ author.about|markdown_to_html|mentionify|linkify }} |
||||
{% endif %} |
||||
</div> |
||||
|
||||
<div class="profile-tabs"> |
||||
<a href="{{ path('author-profile', {'npub': npub}) }}" class="tab-link">Articles</a> |
||||
<a href="{{ path('author-media', {'npub': npub}) }}" class="tab-link active">Media</a> |
||||
</div> |
||||
|
||||
<hr /> |
||||
|
||||
<div class="w-container"> |
||||
{% if pictureEvents|length > 0 %} |
||||
<div class="masonry-grid"> |
||||
{% for event in pictureEvents %} |
||||
<div class="masonry-item"> |
||||
{# Extract title #} |
||||
{% set title = null %} |
||||
{% for tag in event.tags %} |
||||
{% if tag[0] == 'title' %} |
||||
{% set title = tag[1] %} |
||||
{% endif %} |
||||
{% endfor %} |
||||
|
||||
{# Extract first image from imeta tags #} |
||||
{% set firstImageUrl = null %} |
||||
{% set imageAlt = null %} |
||||
{% for tag in event.tags %} |
||||
{% if tag[0] == 'imeta' and firstImageUrl is null %} |
||||
{% for i in 1..(tag|length - 1) %} |
||||
{% set param = tag[i] %} |
||||
{% if param starts with 'url ' and firstImageUrl is null %} |
||||
{% set firstImageUrl = param[4:] %} |
||||
{% elseif param starts with 'alt ' %} |
||||
{% set imageAlt = param[4:] %} |
||||
{% endif %} |
||||
{% endfor %} |
||||
{% endif %} |
||||
{% endfor %} |
||||
|
||||
{# Generate nevent for linking #} |
||||
{% set eventId = event.id %} |
||||
{% set noteId = event.noteId %} |
||||
|
||||
<a href="/e/{{ noteId }}" class="masonry-link"> |
||||
{% if firstImageUrl %} |
||||
<div class="masonry-image-container"> |
||||
<img src="{{ firstImageUrl }}" |
||||
alt="{{ imageAlt|default(title|default('Picture')) }}" |
||||
class="masonry-image" |
||||
loading="lazy" /> |
||||
</div> |
||||
{% endif %} |
||||
|
||||
{% if title %} |
||||
<div class="masonry-caption"> |
||||
<h3>{{ title }}</h3> |
||||
</div> |
||||
{% endif %} |
||||
|
||||
{% if event.content %} |
||||
<div class="masonry-description mt-1"> |
||||
{{ event.content|length > 100 ? event.content[:100] ~ '...' : event.content }} |
||||
</div> |
||||
{% endif %} |
||||
|
||||
<div class="masonry-meta"> |
||||
<span class="event-date">{{ event.created_at|date('M j, Y') }}</span> |
||||
</div> |
||||
</a> |
||||
</div> |
||||
{% endfor %} |
||||
</div> |
||||
{% else %} |
||||
<div class="no-media"> |
||||
<p>No media found for this author.</p> |
||||
</div> |
||||
{% endif %} |
||||
</div> |
||||
{% endblock %} |
||||
|
||||
Loading…
Reference in new issue