diff --git a/internal/generator/html.go b/internal/generator/html.go index fdfcecf..9d2b4fc 100644 --- a/internal/generator/html.go +++ b/internal/generator/html.go @@ -33,6 +33,12 @@ func getTemplateFuncs() template.FuncMap { "shortenPubkey": func(pubkey string) string { return nostr.ShortenPubkey(pubkey) }, + "truncate": func(s string, maxLen int) string { + if len(s) <= maxLen { + return s + } + return s[:maxLen] + "..." + }, "icon": func(name string) template.HTML { // Read icon file from static/icons directory iconPath := filepath.Join("static", "icons", name+".svg") diff --git a/internal/nostr/ebooks.go b/internal/nostr/ebooks.go index 62d0900..c5748cc 100644 --- a/internal/nostr/ebooks.go +++ b/internal/nostr/ebooks.go @@ -4,8 +4,9 @@ import ( "context" "fmt" - "github.com/nbd-wtf/go-nostr" "gitcitadel-online/internal/logger" + + "github.com/nbd-wtf/go-nostr" ) // EBooksService handles fetching top-level 30040 events @@ -46,10 +47,10 @@ func (es *EBooksService) FetchTopLevelIndexEvents(ctx context.Context) ([]EBookI } defer relay.Close() - // Fetch all 30040 events (limit 10k) + // Fetch all 30040 events (limit 1000 for e-books) filter := nostr.Filter{ Kinds: []int{es.indexKind}, - Limit: 10000, + Limit: 1000, } logFilter(filter, fmt.Sprintf("all index events (kind %d) from %s", es.indexKind, es.relayURL)) diff --git a/internal/nostr/feed.go b/internal/nostr/feed.go index e24462f..45b8ec3 100644 --- a/internal/nostr/feed.go +++ b/internal/nostr/feed.go @@ -32,7 +32,7 @@ func (fs *FeedService) FetchFeedItems(ctx context.Context, feedRelay string, max filter := nostr.Filter{ Kinds: []int{fs.feedKind}, - Limit: maxEvents, + Limit: 50, } logFilter(filter, fmt.Sprintf("feed (kind %d)", fs.feedKind)) @@ -43,7 +43,7 @@ func (fs *FeedService) FetchFeedItems(ctx context.Context, feedRelay string, max logger.WithFields(map[string]interface{}{ "relay": feedRelay, "kind": fs.feedKind, - "limit": maxEvents, + "limit": 50, }).Debug("Fetching feed items using SimplePool") // Use the client's pool to query the feed relay @@ -51,7 +51,7 @@ func (fs *FeedService) FetchFeedItems(ctx context.Context, feedRelay string, max eventChan := fs.client.GetPool().SubManyEose(queryCtx, []string{feedRelay}, nostr.Filters{filter}) // Collect events and convert to feed items - items := make([]FeedItem, 0, maxEvents) + items := make([]FeedItem, 0, 50) for incomingEvent := range eventChan { if incomingEvent.Event != nil { item := FeedItem{ diff --git a/internal/nostr/wiki.go b/internal/nostr/wiki.go index d8c1145..487fd61 100644 --- a/internal/nostr/wiki.go +++ b/internal/nostr/wiki.go @@ -91,7 +91,7 @@ func (ws *WikiService) FetchWikiEvents(ctx context.Context, index *IndexEvent) ( // Query ALL events of this kind - simple query by kind only filter := nostr.Filter{ Kinds: []int{ws.wikiKind}, - Limit: 10000, // Reasonable limit + Limit: 50, } logger.WithFields(map[string]interface{}{ @@ -181,7 +181,7 @@ func (ws *WikiService) GetLongformKind() int { } // FetchLongformArticles fetches the newest longform articles (kind 30023) from a specific relay -// Queries by kind only, sorted by newest first, limit 1000 +// Queries by kind only, sorted by newest first, limit 50 func (ws *WikiService) FetchLongformArticles(ctx context.Context, relayURL string, longformKind int, limit int) ([]*nostr.Event, error) { // Connect to the specific relay relay, err := ws.client.ConnectToRelay(ctx, relayURL) @@ -254,7 +254,7 @@ func (ws *WikiService) FetchIndexEvents(ctx context.Context, index *IndexEvent, // Query ALL events of this kind - simple query by kind only filter := nostr.Filter{ Kinds: []int{targetKind}, - Limit: 10000, // Reasonable limit + Limit: 50, } logger.WithFields(map[string]interface{}{ diff --git a/static/css/main.css b/static/css/main.css index 107646c..9662533 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -99,6 +99,7 @@ header { color: var(--text-primary); font-weight: 600; font-size: 1.25rem; + margin-right: 3rem; } .logo-icon { @@ -348,27 +349,29 @@ a:focus { outline-offset: 2px; } -/* Buttons */ +/* Buttons - Consolidated styles */ .btn { - display: inline-block; + display: inline-flex; + align-items: center; + gap: 0.5rem; padding: 0.75rem 1.5rem; background: var(--accent-color); - color: #ffffff; + color: #1a1a1a; border: none; border-radius: 4px; + font-size: 1rem; + font-weight: 600; cursor: pointer; text-decoration: none; - font-weight: 600; - transition: background 0.2s; + transition: background-color 0.2s, transform 0.1s; } .btn:hover { background: var(--link-hover); } -.btn:focus { - outline: var(--focus-outline); - outline-offset: var(--focus-offset); +.btn:active { + transform: scale(0.98); } .btn:focus:not(:focus-visible) { @@ -449,7 +452,7 @@ a:focus { gap: 0.5rem; } -.feature-card p { +.feature-card > p { margin-bottom: 1.5rem; color: var(--text-secondary); flex-grow: 1; @@ -527,7 +530,7 @@ a:focus { .feature-image-wrapper { position: relative; width: 100%; - aspect-ratio: 16 / 9; + aspect-ratio: 1 / 1; overflow: hidden; border-radius: 8px; background: var(--bg-primary); @@ -545,13 +548,13 @@ a:focus { bottom: 0; left: 0; right: 0; - background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.4) 50%, transparent 100%); + background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.5) 50%, transparent 100%); padding: 1.5rem 1rem 1rem; color: #ffffff; } .feature-image-title { - margin: 0; + margin: 0 0 0.5rem 0; font-size: 1.1rem; font-weight: 600; color: #ffffff; @@ -559,6 +562,30 @@ a:focus { line-height: 1.3; } +.feature-image-summary { + margin: 0; + font-size: 0.9rem; + color: rgba(255, 255, 255, 0.95); + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); + line-height: 1.4; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.feature-card-content { + margin-top: auto; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.feature-card-content p { + margin: 0; + color: var(--text-secondary); +} + /* Articles and Pages */ article { background: var(--bg-secondary); @@ -1015,7 +1042,7 @@ textarea:focus-visible { } .contact-links li { - margin-bottom: 0.5rem; + margin-bottom: 1rem; } .contact-links a { @@ -1185,23 +1212,11 @@ textarea:focus-visible { margin-top: 2rem; } -.btn { - padding: 0.75rem 1.5rem; - border: none; - border-radius: 4px; - font-size: 1rem; - font-weight: 600; - cursor: pointer; - transition: background-color 0.2s, transform 0.1s; -} - -.btn:active { - transform: scale(0.98); -} +/* .btn styles are defined above - consolidated */ .btn-primary { background: var(--accent-color); - color: #ffffff; + color: #1a1a1a; } .btn-primary:hover { diff --git a/static/css/responsive.css b/static/css/responsive.css index e27e8ce..f1245ea 100644 --- a/static/css/responsive.css +++ b/static/css/responsive.css @@ -81,6 +81,43 @@ .nav-container { padding: 0.5rem 1rem; } + + /* E-books table: show only avatar on mobile, narrow author column */ + .ebooks-table th[data-sort="author"], + .ebooks-table td:nth-child(2) { + width: 60px; + min-width: 60px; + max-width: 60px; + padding: 0.5rem; + text-align: center; + } + + .ebooks-table td .user-badge { + display: flex; + justify-content: center; + align-items: center; + padding: 0; + background: transparent; + border: none; + width: 100%; + } + + .ebooks-table td .user-badge-name, + .ebooks-table td .user-badge-handle { + display: none !important; + } + + .ebooks-table td .user-badge-avatar, + .ebooks-table td .user-badge-avatar-placeholder { + width: 40px; + height: 40px; + margin: 0; + } + + .ebooks-table td .user-badge-avatar-placeholder .icon-inline { + width: 20px; + height: 20px; + } } /* Tablet styles (768px - 1024px) */ diff --git a/templates/landing.html b/templates/landing.html index 8348578..d4fea55 100644 --- a/templates/landing.html +++ b/templates/landing.html @@ -34,6 +34,9 @@ {{$item.Title}}

{{$item.Title}}

+ {{if $item.Summary}} +

{{truncate $item.Summary 250}}

+ {{end}}
{{else}} @@ -43,14 +46,19 @@ {{$item.Title}}

{{$item.Title}}

+ {{if $item.Summary}} +

{{truncate $item.Summary 250}}

+ {{end}}
{{end}} {{end}} {{end}} -

Read the latest articles and updates from the GitCitadel project blog.

- {{icon "arrow-right"}} View Blog +
+

Read the latest articles and updates from the GitCitadel project blog.

+ {{icon "arrow-right"}} View Blog +
@@ -63,6 +71,9 @@ {{$item.Title}}

{{$item.Title}}

+ {{if $item.Summary}} +

{{truncate $item.Summary 250}}

+ {{end}}
{{else}} @@ -72,14 +83,19 @@ {{$item.Title}}

{{$item.Title}}

+ {{if $item.Summary}} +

{{truncate $item.Summary 250}}

+ {{end}}
{{end}} {{end}} {{end}} -

Longform markdown articles from the TheForest relay.

- {{icon "arrow-right"}} View Articles +
+

Longform markdown articles from the TheForest relay.

+ {{icon "arrow-right"}} View Articles +