diff --git a/peptide-news-plugin.php b/peptide-news-plugin.php index 7598d44..100ee26 100644 --- a/peptide-news-plugin.php +++ b/peptide-news-plugin.php @@ -3,7 +3,7 @@ * Plugin Name: Peptide News Aggregator * Plugin URI: https://github.com/peptiderepo/peptide-news-plugin * Description: Aggregates and displays the latest peptide research news from multiple sources with click analytics and trend reporting. - * Version: 2.1.0 + * Version: 2.2.0 * Author: Peptide News Team * Author URI: https://github.com/peptiderepo * License: GPL-2.0+ @@ -22,7 +22,7 @@ if ( ! defined( 'WPINC' ) ) { /** * Current plugin version — follows SemVer. */ -define( 'PEPTIDE_NEWS_VERSION', '2.1.0' ); +define( 'PEPTIDE_NEWS_VERSION', '2.2.0' ); define( 'PEPTIDE_NEWS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'PEPTIDE_NEWS_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'PEPTIDE_NEWS_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); diff --git a/peptide-news-plugin/peptide-news-plugin.php b/peptide-news-plugin/peptide-news-plugin.php index 7598d44..100ee26 100644 --- a/peptide-news-plugin/peptide-news-plugin.php +++ b/peptide-news-plugin/peptide-news-plugin.php @@ -3,7 +3,7 @@ * Plugin Name: Peptide News Aggregator * Plugin URI: https://github.com/peptiderepo/peptide-news-plugin * Description: Aggregates and displays the latest peptide research news from multiple sources with click analytics and trend reporting. - * Version: 2.1.0 + * Version: 2.2.0 * Author: Peptide News Team * Author URI: https://github.com/peptiderepo * License: GPL-2.0+ @@ -22,7 +22,7 @@ if ( ! defined( 'WPINC' ) ) { /** * Current plugin version — follows SemVer. */ -define( 'PEPTIDE_NEWS_VERSION', '2.1.0' ); +define( 'PEPTIDE_NEWS_VERSION', '2.2.0' ); define( 'PEPTIDE_NEWS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'PEPTIDE_NEWS_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'PEPTIDE_NEWS_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); diff --git a/peptide-news-plugin/public/css/public-style.css b/peptide-news-plugin/public/css/public-style.css index 841ed5b..e4c4079 100644 --- a/peptide-news-plugin/public/css/public-style.css +++ b/peptide-news-plugin/public/css/public-style.css @@ -1,17 +1,802 @@ -/* Peptide News – Public Styles */ +/** + * Peptide News Feed — Public Styles (Redesigned) + * + * Premium, Apple-inspired news feed with refined typography, + * generous spacing, and smooth micro-interactions. + * + * Design by: Senior Design Director + * Redesign Date: 2026-04-07 + * @since 2.2.0 + */ -.article-card { - background: white; - border: 1px solid #ddd; - padding: 15px; +/* Import Inter font from Google Fonts */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); + +/* ══════════════════════════════════════════════════════════════════ + CSS CUSTOM PROPERTIES (Variables) + ══════════════════════════════════════════════════════════════════ */ + +:root { + /* Neutral Scale — Light Mode */ + --pn-bg-primary: #ffffff; + --pn-bg-secondary: #f9fafb; + --pn-border-light: #e5e7eb; + --pn-border-subtle: #d1d5db; + + /* Text Colors */ + --pn-text-primary: #111827; + --pn-text-secondary: #4b5563; + --pn-text-tertiary: #9ca3af; + --pn-text-muted: #d1d5db; + + /* Accent Colors */ + --pn-accent-primary: #2563eb; + --pn-accent-hover: #1d4ed8; + --pn-source-color: #1f2937; + --pn-source-bg: #f3f4f6; + + /* Tag Colors */ + --pn-tag-bg: #eff6ff; + --pn-tag-color: #1e40af; + + /* Focus & System */ + --pn-focus-ring: #2563eb; + --pn-error: #dc2626; + --pn-error-bg: #fee2e2; + --pn-success: #16a34a; + --pn-loading: #6b7280; +} + +/* ──────────────────────────────────────────────────────────────── + DARK MODE OVERRIDE + ────────────────────────────────────────────────────────────── */ + +@media (prefers-color-scheme: dark) { + :root { + /* Neutral Scale — Dark Mode */ + --pn-bg-primary: #0f172a; + --pn-bg-secondary: #1e293b; + --pn-border-light: #334155; + --pn-border-subtle: #475569; + + /* Text Colors */ + --pn-text-primary: #f1f5f9; + --pn-text-secondary: #cbd5e1; + --pn-text-tertiary: #94a3b8; + --pn-text-muted: #64748b; + + /* Accent Colors */ + --pn-accent-primary: #60a5fa; + --pn-accent-hover: #93c5fd; + --pn-source-color: #e2e8f0; + --pn-source-bg: #1e293b; + + /* Tag Colors */ + --pn-tag-bg: #1e3a8a; + --pn-tag-color: #bfdbfe; + + /* Focus & System */ + --pn-focus-ring: #60a5fa; + --pn-error: #f87171; + --pn-error-bg: #7f1d1d; + --pn-success: #86efac; + --pn-loading: #64748b; + } +} + +/* ══════════════════════════════════════════════════════════════════ + BASE TYPOGRAPHY & LAYOUT + ══════════════════════════════════════════════════════════════════ */ + +.pn-news-feed { + max-width: 900px; + margin: 0 auto; + padding: 40px 20px; + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, 'Helvetica Neue', sans-serif; + font-size: 16px; + color: var(--pn-text-primary); + line-height: 1.6; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* ══════════════════════════════════════════════════════════════════ + ARTICLES LIST & CARD CONTAINER + ══════════════════════════════════════════════════════════════════ */ + +.pn-articles-list { + display: flex; + flex-direction: column; + gap: 0; + list-style: none; + padding: 0; + margin: 0; +} + +/* ──────────────────────────────────────────────────────────────── + ARTICLE CARD STRUCTURE + ────────────────────────────────────────────────────────────── */ + +.pn-article { + display: flex; + flex-direction: column; + padding: 24px; + margin-bottom: 24px; + gap: 12px; + background: var(--pn-bg-primary); + border: 1px solid var(--pn-border-light); + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); + transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1); +} + +.pn-article:hover { + transform: translateY(-3px); + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); + border-color: var(--pn-border-subtle); +} + +.pn-article:last-child { + margin-bottom: 0; +} + +/* ──────────────────────────────────────────────────────────────── + METADATA LINE (Source · Date) + ────────────────────────────────────────────────────────────── */ + +.pn-article-meta { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 12px; + font-size: 13px; + font-weight: 500; + color: var(--pn-text-tertiary); + line-height: 1.3; + letter-spacing: 0.2px; +} + +.pn-source { + display: inline-block; + padding: 4px 8px; + background: var(--pn-source-bg); + color: var(--pn-source-color); + font-size: 13px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03em; + border-radius: 4px; + transition: all 0.15s ease; +} + +.pn-source:hover { + background: color-mix(in srgb, var(--pn-source-bg) 80%, var(--pn-source-color) 20%); + cursor: pointer; +} + +.pn-separator { + display: inline-block; + font-size: 11px; + color: var(--pn-border-light); + margin: 0 2px; +} + +.pn-date { + font-size: 13px; + color: var(--pn-text-tertiary); +} + +/* ──────────────────────────────────────────────────────────────── + ARTICLE TITLE + ────────────────────────────────────────────────────────────── */ + +.pn-article-title { + margin: 0 0 14px 0; + font-size: 22px; + font-weight: 700; + line-height: 1.4; + letter-spacing: -0.3px; + color: var(--pn-text-primary); +} + +.pn-article-title a { + color: inherit; + text-decoration: none; + transition: color 0.2s ease, text-decoration 0.2s ease; +} + +.pn-article-title a:hover { + color: var(--pn-accent-primary); + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: 4px; +} + +.pn-article-title a:focus-visible { + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; +} + +@media (prefers-color-scheme: dark) { + .pn-article-title a:hover { + color: var(--pn-accent-hover); + } +} + +/* ──────────────────────────────────────────────────────────────── + EXCERPT / SUMMARY + ────────────────────────────────────────────────────────────── */ + +.pn-article-excerpt { + margin: 0 0 14px 0; + font-size: 15px; + font-weight: 400; + line-height: 1.7; + color: var(--pn-text-secondary); + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 4; + overflow: hidden; + flex: 1; +} + +/* ──────────────────────────────────────────────────────────────── + AUTHOR + ────────────────────────────────────────────────────────────── */ + +.pn-author { + margin: 0 0 10px 0; + font-size: 13px; + font-weight: 400; + color: var(--pn-text-tertiary); + line-height: 1.4; +} + +.pn-author::before { + content: ''; +} + +/* ──────────────────────────────────────────────────────────────── + TAGS + ────────────────────────────────────────────────────────────── */ + +.pn-tags { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: auto 0 0 0; +} + +.pn-tag { + display: inline-block; + padding: 4px 10px; + font-size: 12px; + font-weight: 500; + line-height: 1.3; + letter-spacing: 0.15px; + color: var(--pn-tag-color); + background: var(--pn-tag-bg); + border-radius: 20px; + cursor: pointer; + transition: all 0.15s ease; +} + +.pn-tag:hover { + background: color-mix(in srgb, var(--pn-tag-bg) 70%, var(--pn-tag-color) 30%); + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.15); +} + +.pn-tag:focus-visible { + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; +} + +/* ══════════════════════════════════════════════════════════════════ + LOADING STATES & SKELETON + ══════════════════════════════════════════════════════════════════ */ + +.pn-loading { + display: flex; + flex-direction: column; + gap: 0; + list-style: none; + padding: 0; + margin: 0; +} + +.pn-skeleton-card { + padding: 24px; + margin-bottom: 24px; + background: var(--pn-bg-primary); + border: 1px solid var(--pn-border-light); + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); +} + +.pn-skeleton-card:last-child { + margin-bottom: 0; +} + +.pn-skeleton-line { + height: 12px; + background: linear-gradient( + 90deg, + var(--pn-loading) 0%, + color-mix(in srgb, var(--pn-loading) 50%, transparent) 50%, + var(--pn-loading) 100% + ); + background-size: 200% 100%; + border-radius: 4px; + margin-bottom: 12px; + animation: pn-shimmer 2s infinite; +} + +/* Staggered animation delays for skeleton lines */ +.pn-skeleton-meta { + width: 40%; + height: 10px; + animation: pn-shimmer 2s infinite 0s; +} + +.pn-skeleton-title { + width: 85%; + height: 18px; + margin-bottom: 14px; + animation: pn-shimmer 2s infinite 0.1s; +} + +.pn-skeleton-excerpt { + width: 100%; + height: 14px; + animation: pn-shimmer 2s infinite 0.2s; +} + +.pn-skeleton-excerpt-short { + width: 70%; + height: 14px; + animation: pn-shimmer 2s infinite 0.3s; +} + +.pn-skeleton-author { + width: 30%; + height: 10px; + margin-top: 12px; + animation: pn-shimmer 2s infinite 0.4s; +} + +.pn-skeleton-tags { + display: flex; + gap: 8px; + margin-top: 16px; +} + +.pn-skeleton-tag { + height: 10px; + width: 60px; + border-radius: 20px; + animation: pn-shimmer 2s infinite 0.5s; +} + +@keyframes pn-shimmer { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} + +/* ══════════════════════════════════════════════════════════════════ + ERROR STATE + ══════════════════════════════════════════════════════════════════ */ + +.pn-error { + display: block; + padding: 20px; + text-align: center; + background: color-mix(in srgb, var(--pn-error-bg) 50%, transparent); + border: 1px solid var(--pn-border-light); + border-radius: 8px; + color: var(--pn-error); + font-size: 15px; + line-height: 1.6; +} + +.pn-error p { + margin: 0 0 16px 0; + font-size: 15px; + font-weight: 400; +} + +.pn-error p:last-child { + margin-bottom: 0; +} + +.pn-retry-btn { + display: inline-block; + padding: 10px 20px; + margin-top: 16px; + font-size: 14px; + font-weight: 600; + line-height: 1.4; + color: #ffffff; + background: var(--pn-error); + border: none; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s ease; +} + +.pn-retry-btn:hover { + opacity: 0.9; + transform: scale(1.01); +} + +.pn-retry-btn:active { + transform: scale(0.99); +} + +.pn-retry-btn:focus-visible { + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; +} + +/* ══════════════════════════════════════════════════════════════════ + EMPTY STATE + ══════════════════════════════════════════════════════════════════ */ + +.pn-empty { + display: block; + padding: 60px 20px; + text-align: center; + color: var(--pn-text-tertiary); + font-size: 16px; + font-weight: 400; + line-height: 1.6; +} + +.pn-empty p { + margin: 0; +} + +/* ══════════════════════════════════════════════════════════════════ + PAGINATION + ══════════════════════════════════════════════════════════════════ */ + +.pn-pagination { + display: flex; + align-items: center; + justify-content: center; + gap: 24px; + margin-top: 40px; + padding-top: 24px; + border-top: 1px solid var(--pn-border-light); +} + +.pn-page-btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 10px 16px; + font-size: 14px; + font-weight: 600; + line-height: 1.4; + color: var(--pn-text-primary); + background: var(--pn-bg-primary); + border: 1px solid var(--pn-border-light); + border-radius: 6px; + cursor: pointer; + transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1); +} + +.pn-page-btn:hover:enabled { + border-color: var(--pn-accent-primary); + color: var(--pn-accent-primary); + background: var(--pn-bg-secondary); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.15); +} + +.pn-page-btn:active:enabled { + transform: translateY(0); + box-shadow: 0 2px 4px rgba(37, 99, 235, 0.1); + background: var(--pn-bg-secondary); +} + +.pn-page-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.pn-page-btn:focus-visible { + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; +} + +.pn-page-info { + font-size: 14px; + font-weight: 500; + line-height: 1.4; + color: var(--pn-text-secondary); + white-space: nowrap; +} + +/* ══════════════════════════════════════════════════════════════════ + RESPONSIVE DESIGN — TABLET (768px - 1024px) + ══════════════════════════════════════════════════════════════════ */ + +@media (min-width: 768px) and (max-width: 1023px) { + .pn-news-feed { + max-width: 100%; + padding: 30px; + } + + .pn-article { + padding: 20px; + gap: 12px; margin-bottom: 20px; - border-radius: 4px; + } + + .pn-article-title { + font-size: 20px; + margin-bottom: 12px; + } + + .pn-article-excerpt { + margin-bottom: 12px; + } + + .pn-skeleton-card { + padding: 20px; + margin-bottom: 20px; + } } +/* ══════════════════════════════════════════════════════════════════ + RESPONSIVE DESIGN — MOBILE (< 768px) + ══════════════════════════════════════════════════════════════════ */ -.article-title { +@media (max-width: 767px) { + .pn-news-feed { + max-width: 100%; + padding: 20px 16px; + } + + .pn-article { + padding: 16px; + gap: 10px; + margin-bottom: 16px; + } + + .pn-article-title { font-size: 18px; - font-weight: bold; - color: #333; + margin-bottom: 12px; + line-height: 1.3; + letter-spacing: -0.2px; + } + + .pn-article-excerpt { + font-size: 14px; + line-height: 1.6; + margin-bottom: 12px; + -webkit-line-clamp: 3; + } + + .pn-article-meta { + gap: 6px; margin-bottom: 10px; + font-size: 12px; + } + + .pn-source { + padding: 3px 6px; + font-size: 12px; + } + + .pn-author { + margin-bottom: 8px; + font-size: 12px; + } + + .pn-tag { + padding: 3px 8px; + font-size: 11.5px; + } + + .pn-tags { + gap: 6px; + margin-top: 10px; + } + + .pn-skeleton-card { + padding: 16px; + margin-bottom: 16px; + } + + .pn-pagination { + flex-direction: column; + gap: 12px; + } + + .pn-page-btn { + width: 100%; + padding: 12px 16px; + } + + .pn-page-info { + width: 100%; + } +} + +/* ══════════════════════════════════════════════════════════════════ + SMALL MOBILE (< 480px) + ══════════════════════════════════════════════════════════════════ */ + +@media (max-width: 479px) { + .pn-news-feed { + padding: 16px 12px; + } + + .pn-article { + padding: 12px; + gap: 8px; + margin-bottom: 12px; + } + + .pn-article-title { + font-size: 18px; + margin-bottom: 10px; + } + + .pn-article-excerpt { + font-size: 14px; + -webkit-line-clamp: 3; + } + + .pn-article-meta { + font-size: 12px; + gap: 4px; + margin-bottom: 8px; + } + + .pn-skeleton-card { + padding: 12px; + margin-bottom: 12px; + } +} + +/* ══════════════════════════════════════════════════════════════════ + DARK MODE DARK MODE ENHANCEMENTS + ══════════════════════════════════════════════════════════════════ */ + +@media (prefers-color-scheme: dark) { + .pn-article { + background: var(--pn-bg-primary); + border-color: var(--pn-border-light); + } + + .pn-article-title { + color: var(--pn-text-primary); + } + + .pn-article-excerpt { + color: var(--pn-text-secondary); + } + + .pn-article-meta { + color: var(--pn-text-tertiary); + } + + .pn-source { + background: var(--pn-source-bg); + color: var(--pn-source-color); + } + + .pn-date { + color: var(--pn-text-tertiary); + } + + .pn-author { + color: var(--pn-text-tertiary); + } + + .pn-tag { + background: var(--pn-tag-bg); + color: var(--pn-tag-color); + } + + .pn-page-btn { + background: transparent; + border-color: var(--pn-border-light); + color: var(--pn-text-primary); + } + + .pn-page-btn:hover:enabled { + border-color: var(--pn-accent-primary); + color: var(--pn-accent-primary); + background: transparent; + } + + .pn-page-btn:disabled { + color: var(--pn-text-muted); + border-color: var(--pn-border-subtle); + } + + .pn-page-info { + color: var(--pn-text-secondary); + } + + .pn-pagination { + border-top-color: var(--pn-border-light); + } + + .pn-error { + background: color-mix(in srgb, var(--pn-error-bg) 40%, transparent); + border-color: var(--pn-border-light); + color: var(--pn-error); + } + + .pn-retry-btn { + background: var(--pn-error); + color: #ffffff; + } + + .pn-retry-btn:hover { + opacity: 0.8; + } + + .pn-empty { + color: var(--pn-text-tertiary); + } + + .pn-skeleton-line, + .pn-skeleton-tag { + background: linear-gradient( + 90deg, + var(--pn-loading) 0%, + color-mix(in srgb, var(--pn-loading) 50%, transparent) 50%, + var(--pn-loading) 100% + ); + background-size: 200% 100%; + } + + .pn-skeleton-card { + background: var(--pn-bg-primary); + border-color: var(--pn-border-light); + } +} + +/* ══════════════════════════════════════════════════════════════════ + ACCESSIBILITY + ══════════════════════════════════════════════════════════════════ */ + +/* High contrast mode support */ +@media (prefers-contrast: more) { + .pn-article { + border-width: 2px; + } + + .pn-page-btn { + border-width: 2px; + } + + .pn-article-title a:focus-visible, + .pn-page-btn:focus-visible, + .pn-retry-btn:focus-visible, + .pn-tag:focus-visible { + outline-width: 3px; + } +} + +/* Reduced motion support */ +@media (prefers-reduced-motion: reduce) { + .pn-article, + .pn-article-title a, + .pn-tag, + .pn-page-btn, + .pn-retry-btn, + .pn-skeleton-line, + .pn-skeleton-tag { + animation: none !important; + transition: none !important; + } } diff --git a/public/css/public-style.css b/public/css/public-style.css index b17d836..e4c4079 100644 --- a/public/css/public-style.css +++ b/public/css/public-style.css @@ -1,381 +1,802 @@ /** - * Peptide News Feed — Public Styles + * Peptide News Feed — Public Styles (Redesigned) * - * Clean, modern news feed layout without thumbnails. - * Focuses on readability and content hierarchy. + * Premium, Apple-inspired news feed with refined typography, + * generous spacing, and smooth micro-interactions. * - * @since 2.0.0 + * Design by: Senior Design Director + * Redesign Date: 2026-04-07 + * @since 2.2.0 */ -/* ── Feed container ────────────────────────────────────────────── */ +/* Import Inter font from Google Fonts */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); + +/* ══════════════════════════════════════════════════════════════════ + CSS CUSTOM PROPERTIES (Variables) + ══════════════════════════════════════════════════════════════════ */ + +:root { + /* Neutral Scale — Light Mode */ + --pn-bg-primary: #ffffff; + --pn-bg-secondary: #f9fafb; + --pn-border-light: #e5e7eb; + --pn-border-subtle: #d1d5db; + + /* Text Colors */ + --pn-text-primary: #111827; + --pn-text-secondary: #4b5563; + --pn-text-tertiary: #9ca3af; + --pn-text-muted: #d1d5db; + + /* Accent Colors */ + --pn-accent-primary: #2563eb; + --pn-accent-hover: #1d4ed8; + --pn-source-color: #1f2937; + --pn-source-bg: #f3f4f6; + + /* Tag Colors */ + --pn-tag-bg: #eff6ff; + --pn-tag-color: #1e40af; + + /* Focus & System */ + --pn-focus-ring: #2563eb; + --pn-error: #dc2626; + --pn-error-bg: #fee2e2; + --pn-success: #16a34a; + --pn-loading: #6b7280; +} + +/* ──────────────────────────────────────────────────────────────── + DARK MODE OVERRIDE + ────────────────────────────────────────────────────────────── */ + +@media (prefers-color-scheme: dark) { + :root { + /* Neutral Scale — Dark Mode */ + --pn-bg-primary: #0f172a; + --pn-bg-secondary: #1e293b; + --pn-border-light: #334155; + --pn-border-subtle: #475569; + + /* Text Colors */ + --pn-text-primary: #f1f5f9; + --pn-text-secondary: #cbd5e1; + --pn-text-tertiary: #94a3b8; + --pn-text-muted: #64748b; + + /* Accent Colors */ + --pn-accent-primary: #60a5fa; + --pn-accent-hover: #93c5fd; + --pn-source-color: #e2e8f0; + --pn-source-bg: #1e293b; + + /* Tag Colors */ + --pn-tag-bg: #1e3a8a; + --pn-tag-color: #bfdbfe; + + /* Focus & System */ + --pn-focus-ring: #60a5fa; + --pn-error: #f87171; + --pn-error-bg: #7f1d1d; + --pn-success: #86efac; + --pn-loading: #64748b; + } +} + +/* ══════════════════════════════════════════════════════════════════ + BASE TYPOGRAPHY & LAYOUT + ══════════════════════════════════════════════════════════════════ */ + .pn-news-feed { - max-width: 760px; - margin: 0 auto; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, - Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - color: #1a1a2e; - line-height: 1.6; - -webkit-font-smoothing: antialiased; + max-width: 900px; + margin: 0 auto; + padding: 40px 20px; + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, 'Helvetica Neue', sans-serif; + font-size: 16px; + color: var(--pn-text-primary); + line-height: 1.6; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } -/* ── Articles list ─────────────────────────────────────────────── */ +/* ══════════════════════════════════════════════════════════════════ + ARTICLES LIST & CARD CONTAINER + ══════════════════════════════════════════════════════════════════ */ + .pn-articles-list { - display: flex; - flex-direction: column; - gap: 0; + display: flex; + flex-direction: column; + gap: 0; + list-style: none; + padding: 0; + margin: 0; } -/* ── Individual article ────────────────────────────────────────── */ +/* ──────────────────────────────────────────────────────────────── + ARTICLE CARD STRUCTURE + ────────────────────────────────────────────────────────────── */ + .pn-article { - padding: 1.5rem 0; - border-bottom: 1px solid #e8eaed; - transition: background-color 0.15s ease; + display: flex; + flex-direction: column; + padding: 24px; + margin-bottom: 24px; + gap: 12px; + background: var(--pn-bg-primary); + border: 1px solid var(--pn-border-light); + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); + transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1); } -.pn-article:first-child { - padding-top: 0; +.pn-article:hover { + transform: translateY(-3px); + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); + border-color: var(--pn-border-subtle); } .pn-article:last-child { - border-bottom: none; + margin-bottom: 0; } -/* ── Meta line (source · date) ─────────────────────────────────── */ +/* ──────────────────────────────────────────────────────────────── + METADATA LINE (Source · Date) + ────────────────────────────────────────────────────────────── */ + .pn-article-meta { - display: flex; - align-items: center; - gap: 0.4rem; - margin-bottom: 0.375rem; - font-size: 0.8125rem; - color: #6b7280; - line-height: 1.4; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 12px; + font-size: 13px; + font-weight: 500; + color: var(--pn-text-tertiary); + line-height: 1.3; + letter-spacing: 0.2px; } .pn-source { - font-weight: 600; - color: #4b5563; - text-transform: uppercase; - letter-spacing: 0.03em; - font-size: 0.75rem; + display: inline-block; + padding: 4px 8px; + background: var(--pn-source-bg); + color: var(--pn-source-color); + font-size: 13px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03em; + border-radius: 4px; + transition: all 0.15s ease; +} + +.pn-source:hover { + background: color-mix(in srgb, var(--pn-source-bg) 80%, var(--pn-source-color) 20%); + cursor: pointer; } .pn-separator { - color: #d1d5db; + display: inline-block; + font-size: 11px; + color: var(--pn-border-light); + margin: 0 2px; } .pn-date { - color: #9ca3af; + font-size: 13px; + color: var(--pn-text-tertiary); } -/* ── Title ─────────────────────────────────────────────────────── */ +/* ──────────────────────────────────────────────────────────────── + ARTICLE TITLE + ────────────────────────────────────────────────────────────── */ + .pn-article-title { - font-size: 1.125rem; - font-weight: 600; - line-height: 1.4; - margin: 0 0 0.5rem; - color: #111827; + margin: 0 0 14px 0; + font-size: 22px; + font-weight: 700; + line-height: 1.4; + letter-spacing: -0.3px; + color: var(--pn-text-primary); } .pn-article-title a { - color: inherit; - text-decoration: none; - transition: color 0.15s ease; + color: inherit; + text-decoration: none; + transition: color 0.2s ease, text-decoration 0.2s ease; } .pn-article-title a:hover { - color: #2563eb; + color: var(--pn-accent-primary); + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: 4px; } .pn-article-title a:focus-visible { - outline: 2px solid #2563eb; - outline-offset: 2px; - border-radius: 2px; + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; } -/* ── Excerpt / AI summary ──────────────────────────────────────── */ +@media (prefers-color-scheme: dark) { + .pn-article-title a:hover { + color: var(--pn-accent-hover); + } +} + +/* ──────────────────────────────────────────────────────────────── + EXCERPT / SUMMARY + ────────────────────────────────────────────────────────────── */ + .pn-article-excerpt { - font-size: 0.9375rem; - line-height: 1.65; - color: #4b5563; - margin: 0 0 0.625rem; + margin: 0 0 14px 0; + font-size: 15px; + font-weight: 400; + line-height: 1.7; + color: var(--pn-text-secondary); + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 4; + overflow: hidden; + flex: 1; } -/* ── Author ────────────────────────────────────────────────────── */ +/* ──────────────────────────────────────────────────────────────── + AUTHOR + ────────────────────────────────────────────────────────────── */ + .pn-author { - display: inline-block; - font-size: 0.8125rem; - color: #9ca3af; - margin-bottom: 0.375rem; + margin: 0 0 10px 0; + font-size: 13px; + font-weight: 400; + color: var(--pn-text-tertiary); + line-height: 1.4; } .pn-author::before { - content: "By "; - font-style: italic; + content: ''; } -/* ── Tags ──────────────────────────────────────────────────────── */ +/* ──────────────────────────────────────────────────────────────── + TAGS + ────────────────────────────────────────────────────────────── */ + .pn-tags { - display: flex; - flex-wrap: wrap; - gap: 0.375rem; - margin-top: 0.375rem; + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: auto 0 0 0; } .pn-tag { - display: inline-block; - font-size: 0.6875rem; - background: #eff6ff; - color: #1d4ed8; - padding: 0.1875rem 0.625rem; - border-radius: 100px; - line-height: 1.5; - font-weight: 500; - letter-spacing: 0.01em; + display: inline-block; + padding: 4px 10px; + font-size: 12px; + font-weight: 500; + line-height: 1.3; + letter-spacing: 0.15px; + color: var(--pn-tag-color); + background: var(--pn-tag-bg); + border-radius: 20px; + cursor: pointer; + transition: all 0.15s ease; } -/* ── Loading skeleton ──────────────────────────────────────────── */ +.pn-tag:hover { + background: color-mix(in srgb, var(--pn-tag-bg) 70%, var(--pn-tag-color) 30%); + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.15); +} + +.pn-tag:focus-visible { + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; +} + +/* ══════════════════════════════════════════════════════════════════ + LOADING STATES & SKELETON + ══════════════════════════════════════════════════════════════════ */ + .pn-loading { - display: flex; - flex-direction: column; - gap: 0; + display: flex; + flex-direction: column; + gap: 0; + list-style: none; + padding: 0; + margin: 0; } .pn-skeleton-card { - padding: 1.5rem 0; - border-bottom: 1px solid #e8eaed; + padding: 24px; + margin-bottom: 24px; + background: var(--pn-bg-primary); + border: 1px solid var(--pn-border-light); + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); } -.pn-skeleton-card:first-child { - padding-top: 0; +.pn-skeleton-card:last-child { + margin-bottom: 0; } .pn-skeleton-line { - background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%); - background-size: 200% 100%; - animation: pn-shimmer 1.5s ease-in-out infinite; - border-radius: 4px; - margin-bottom: 0.5rem; + height: 12px; + background: linear-gradient( + 90deg, + var(--pn-loading) 0%, + color-mix(in srgb, var(--pn-loading) 50%, transparent) 50%, + var(--pn-loading) 100% + ); + background-size: 200% 100%; + border-radius: 4px; + margin-bottom: 12px; + animation: pn-shimmer 2s infinite; } +/* Staggered animation delays for skeleton lines */ .pn-skeleton-meta { - width: 140px; - height: 14px; + width: 40%; + height: 10px; + animation: pn-shimmer 2s infinite 0s; } .pn-skeleton-title { - width: 85%; - height: 20px; + width: 85%; + height: 18px; + margin-bottom: 14px; + animation: pn-shimmer 2s infinite 0.1s; } .pn-skeleton-excerpt { - width: 100%; - height: 14px; + width: 100%; + height: 14px; + animation: pn-shimmer 2s infinite 0.2s; } .pn-skeleton-excerpt-short { - width: 60%; - height: 14px; + width: 70%; + height: 14px; + animation: pn-shimmer 2s infinite 0.3s; +} + +.pn-skeleton-author { + width: 30%; + height: 10px; + margin-top: 12px; + animation: pn-shimmer 2s infinite 0.4s; } .pn-skeleton-tags { - display: flex; - gap: 0.375rem; - margin-top: 0.5rem; + display: flex; + gap: 8px; + margin-top: 16px; } .pn-skeleton-tag { - width: 64px; - height: 22px; - border-radius: 100px; - background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%); - background-size: 200% 100%; - animation: pn-shimmer 1.5s ease-in-out infinite; + height: 10px; + width: 60px; + border-radius: 20px; + animation: pn-shimmer 2s infinite 0.5s; } @keyframes pn-shimmer { - 0% { background-position: 200% 0; } - 100% { background-position: -200% 0; } + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } } -/* ── Error state ───────────────────────────────────────────────── */ +/* ══════════════════════════════════════════════════════════════════ + ERROR STATE + ══════════════════════════════════════════════════════════════════ */ + .pn-error { - text-align: center; - padding: 2.5rem 1rem; - color: #6b7280; + display: block; + padding: 20px; + text-align: center; + background: color-mix(in srgb, var(--pn-error-bg) 50%, transparent); + border: 1px solid var(--pn-border-light); + border-radius: 8px; + color: var(--pn-error); + font-size: 15px; + line-height: 1.6; } .pn-error p { - font-size: 0.9375rem; - margin: 0 0 1rem; + margin: 0 0 16px 0; + font-size: 15px; + font-weight: 400; +} + +.pn-error p:last-child { + margin-bottom: 0; } .pn-retry-btn { - display: inline-block; - padding: 0.5rem 1.25rem; - font-size: 0.875rem; - font-weight: 500; - color: #2563eb; - background: #eff6ff; - border: 1px solid #bfdbfe; - border-radius: 6px; - cursor: pointer; - transition: all 0.15s ease; + display: inline-block; + padding: 10px 20px; + margin-top: 16px; + font-size: 14px; + font-weight: 600; + line-height: 1.4; + color: #ffffff; + background: var(--pn-error); + border: none; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s ease; } .pn-retry-btn:hover { - background: #dbeafe; - border-color: #93c5fd; + opacity: 0.9; + transform: scale(1.01); +} + +.pn-retry-btn:active { + transform: scale(0.99); } .pn-retry-btn:focus-visible { - outline: 2px solid #2563eb; - outline-offset: 2px; + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; } -/* ── Empty state ───────────────────────────────────────────────── */ +/* ══════════════════════════════════════════════════════════════════ + EMPTY STATE + ══════════════════════════════════════════════════════════════════ */ + .pn-empty { - text-align: center; - padding: 2.5rem 1rem; + display: block; + padding: 60px 20px; + text-align: center; + color: var(--pn-text-tertiary); + font-size: 16px; + font-weight: 400; + line-height: 1.6; } .pn-empty p { - font-size: 0.9375rem; - color: #6b7280; - margin: 0; + margin: 0; } -/* ── Pagination ────────────────────────────────────────────────── */ +/* ══════════════════════════════════════════════════════════════════ + PAGINATION + ══════════════════════════════════════════════════════════════════ */ + .pn-pagination { - display: flex; - align-items: center; - justify-content: center; - gap: 1rem; - padding: 1.5rem 0 0.5rem; - margin-top: 0.5rem; - border-top: 1px solid #e8eaed; + display: flex; + align-items: center; + justify-content: center; + gap: 24px; + margin-top: 40px; + padding-top: 24px; + border-top: 1px solid var(--pn-border-light); } .pn-page-btn { - display: inline-flex; - align-items: center; - padding: 0.5rem 1rem; - font-size: 0.875rem; - font-weight: 500; - color: #374151; - background: #fff; - border: 1px solid #d1d5db; - border-radius: 6px; - cursor: pointer; - transition: all 0.15s ease; - line-height: 1; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 10px 16px; + font-size: 14px; + font-weight: 600; + line-height: 1.4; + color: var(--pn-text-primary); + background: var(--pn-bg-primary); + border: 1px solid var(--pn-border-light); + border-radius: 6px; + cursor: pointer; + transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1); } -.pn-page-btn:hover:not(:disabled) { - background: #f9fafb; - border-color: #9ca3af; +.pn-page-btn:hover:enabled { + border-color: var(--pn-accent-primary); + color: var(--pn-accent-primary); + background: var(--pn-bg-secondary); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.15); +} + +.pn-page-btn:active:enabled { + transform: translateY(0); + box-shadow: 0 2px 4px rgba(37, 99, 235, 0.1); + background: var(--pn-bg-secondary); } .pn-page-btn:disabled { - color: #d1d5db; - border-color: #e5e7eb; - cursor: not-allowed; + opacity: 0.5; + cursor: not-allowed; } .pn-page-btn:focus-visible { - outline: 2px solid #2563eb; - outline-offset: 2px; + outline: 2px solid var(--pn-focus-ring); + outline-offset: 2px; } .pn-page-info { - font-size: 0.8125rem; - color: #6b7280; - min-width: 100px; - text-align: center; + font-size: 14px; + font-weight: 500; + line-height: 1.4; + color: var(--pn-text-secondary); + white-space: nowrap; } -/* ── Responsive ────────────────────────────────────────────────── */ -@media (max-width: 600px) { - .pn-article-title { - font-size: 1rem; - } +/* ══════════════════════════════════════════════════════════════════ + RESPONSIVE DESIGN — TABLET (768px - 1024px) + ══════════════════════════════════════════════════════════════════ */ - .pn-article-excerpt { - font-size: 0.875rem; - } +@media (min-width: 768px) and (max-width: 1023px) { + .pn-news-feed { + max-width: 100%; + padding: 30px; + } - .pn-pagination { - gap: 0.5rem; - } + .pn-article { + padding: 20px; + gap: 12px; + margin-bottom: 20px; + } - .pn-page-btn { - padding: 0.375rem 0.75rem; - font-size: 0.8125rem; - } + .pn-article-title { + font-size: 20px; + margin-bottom: 12px; + } + + .pn-article-excerpt { + margin-bottom: 12px; + } + + .pn-skeleton-card { + padding: 20px; + margin-bottom: 20px; + } } -/* ── Dark mode support via prefers-color-scheme ────────────────── */ +/* ══════════════════════════════════════════════════════════════════ + RESPONSIVE DESIGN — MOBILE (< 768px) + ══════════════════════════════════════════════════════════════════ */ + +@media (max-width: 767px) { + .pn-news-feed { + max-width: 100%; + padding: 20px 16px; + } + + .pn-article { + padding: 16px; + gap: 10px; + margin-bottom: 16px; + } + + .pn-article-title { + font-size: 18px; + margin-bottom: 12px; + line-height: 1.3; + letter-spacing: -0.2px; + } + + .pn-article-excerpt { + font-size: 14px; + line-height: 1.6; + margin-bottom: 12px; + -webkit-line-clamp: 3; + } + + .pn-article-meta { + gap: 6px; + margin-bottom: 10px; + font-size: 12px; + } + + .pn-source { + padding: 3px 6px; + font-size: 12px; + } + + .pn-author { + margin-bottom: 8px; + font-size: 12px; + } + + .pn-tag { + padding: 3px 8px; + font-size: 11.5px; + } + + .pn-tags { + gap: 6px; + margin-top: 10px; + } + + .pn-skeleton-card { + padding: 16px; + margin-bottom: 16px; + } + + .pn-pagination { + flex-direction: column; + gap: 12px; + } + + .pn-page-btn { + width: 100%; + padding: 12px 16px; + } + + .pn-page-info { + width: 100%; + } +} + +/* ══════════════════════════════════════════════════════════════════ + SMALL MOBILE (< 480px) + ══════════════════════════════════════════════════════════════════ */ + +@media (max-width: 479px) { + .pn-news-feed { + padding: 16px 12px; + } + + .pn-article { + padding: 12px; + gap: 8px; + margin-bottom: 12px; + } + + .pn-article-title { + font-size: 18px; + margin-bottom: 10px; + } + + .pn-article-excerpt { + font-size: 14px; + -webkit-line-clamp: 3; + } + + .pn-article-meta { + font-size: 12px; + gap: 4px; + margin-bottom: 8px; + } + + .pn-skeleton-card { + padding: 12px; + margin-bottom: 12px; + } +} + +/* ══════════════════════════════════════════════════════════════════ + DARK MODE DARK MODE ENHANCEMENTS + ══════════════════════════════════════════════════════════════════ */ + @media (prefers-color-scheme: dark) { - .pn-news-feed { - color: #e5e7eb; - } + .pn-article { + background: var(--pn-bg-primary); + border-color: var(--pn-border-light); + } - .pn-article { - border-bottom-color: #374151; - } + .pn-article-title { + color: var(--pn-text-primary); + } - .pn-article-title { - color: #f3f4f6; - } + .pn-article-excerpt { + color: var(--pn-text-secondary); + } - .pn-article-title a:hover { - color: #60a5fa; - } + .pn-article-meta { + color: var(--pn-text-tertiary); + } - .pn-source { - color: #9ca3af; - } + .pn-source { + background: var(--pn-source-bg); + color: var(--pn-source-color); + } - .pn-article-excerpt { - color: #9ca3af; - } + .pn-date { + color: var(--pn-text-tertiary); + } - .pn-tag { - background: #1e3a5f; - color: #93c5fd; - } + .pn-author { + color: var(--pn-text-tertiary); + } - .pn-skeleton-line, - .pn-skeleton-tag { - background: linear-gradient(90deg, #1f2937 25%, #374151 50%, #1f2937 75%); - background-size: 200% 100%; - } + .pn-tag { + background: var(--pn-tag-bg); + color: var(--pn-tag-color); + } - .pn-page-btn { - color: #e5e7eb; - background: #1f2937; - border-color: #4b5563; - } + .pn-page-btn { + background: transparent; + border-color: var(--pn-border-light); + color: var(--pn-text-primary); + } - .pn-page-btn:hover:not(:disabled) { - background: #374151; - } + .pn-page-btn:hover:enabled { + border-color: var(--pn-accent-primary); + color: var(--pn-accent-primary); + background: transparent; + } - .pn-page-btn:disabled { - color: #4b5563; - border-color: #374151; - } + .pn-page-btn:disabled { + color: var(--pn-text-muted); + border-color: var(--pn-border-subtle); + } - .pn-retry-btn { - color: #60a5fa; - background: #1e3a5f; - border-color: #1d4ed8; - } + .pn-page-info { + color: var(--pn-text-secondary); + } - .pn-pagination { - border-top-color: #374151; - } + .pn-pagination { + border-top-color: var(--pn-border-light); + } - .pn-skeleton-card { - border-bottom-color: #374151; - } + .pn-error { + background: color-mix(in srgb, var(--pn-error-bg) 40%, transparent); + border-color: var(--pn-border-light); + color: var(--pn-error); + } + + .pn-retry-btn { + background: var(--pn-error); + color: #ffffff; + } + + .pn-retry-btn:hover { + opacity: 0.8; + } + + .pn-empty { + color: var(--pn-text-tertiary); + } + + .pn-skeleton-line, + .pn-skeleton-tag { + background: linear-gradient( + 90deg, + var(--pn-loading) 0%, + color-mix(in srgb, var(--pn-loading) 50%, transparent) 50%, + var(--pn-loading) 100% + ); + background-size: 200% 100%; + } + + .pn-skeleton-card { + background: var(--pn-bg-primary); + border-color: var(--pn-border-light); + } +} + +/* ══════════════════════════════════════════════════════════════════ + ACCESSIBILITY + ══════════════════════════════════════════════════════════════════ */ + +/* High contrast mode support */ +@media (prefers-contrast: more) { + .pn-article { + border-width: 2px; + } + + .pn-page-btn { + border-width: 2px; + } + + .pn-article-title a:focus-visible, + .pn-page-btn:focus-visible, + .pn-retry-btn:focus-visible, + .pn-tag:focus-visible { + outline-width: 3px; + } +} + +/* Reduced motion support */ +@media (prefers-reduced-motion: reduce) { + .pn-article, + .pn-article-title a, + .pn-tag, + .pn-page-btn, + .pn-retry-btn, + .pn-skeleton-line, + .pn-skeleton-tag { + animation: none !important; + transition: none !important; + } }