Reader read-aloud now streams neural WAV audio from a new POST /api/tts endpoint that shells out to Piper, instead of the browser's Web Speech voice. Each paragraph is synthesized on demand with the next one prefetched during playback, keeping the existing highlight/scroll sync. Voices are configured under [web.tts] (piper binary + voices_dir + a labelled voice list) and exposed to the client as window.PETE_TTS; the reader gets a Voice selector in the Aa menu, persisted per-device. Still a signed-in-only perk and gated on auth.
525 lines
19 KiB
CSS
525 lines
19 KiB
CSS
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
Day/night palette. JS sets data-phase={dawn|day|dusk|night} on <html>.
|
|
Each phase drives a small set of CSS vars; the page transitions smoothly
|
|
thanks to the `transition-colors duration-1000` on <body>.
|
|
---------------------------------------------------------------------------- */
|
|
|
|
:root,
|
|
html[data-phase="day"] {
|
|
--bg: #fff7e4; /* warm cream */
|
|
--bg-grad: #ffeec2; /* soft sun wash */
|
|
--card: #ffffff;
|
|
--ink: #3a2e1f;
|
|
--accent: #f2a541; /* sunshine yellow */
|
|
}
|
|
|
|
html[data-phase="dawn"] {
|
|
--bg: #ffe7d6;
|
|
--bg-grad: #ffc9c9;
|
|
--card: #fff4ea;
|
|
--ink: #4a2e2a;
|
|
--accent: #ff8a65;
|
|
}
|
|
|
|
html[data-phase="dusk"] {
|
|
--bg: #ffd6a8;
|
|
--bg-grad: #f7a07e;
|
|
--card: #fff1de;
|
|
--ink: #3d2417;
|
|
--accent: #e6553a;
|
|
}
|
|
|
|
html[data-phase="night"] {
|
|
--bg: #1a1f3a;
|
|
--bg-grad: #2a3358;
|
|
--card: #2d365a;
|
|
--ink: #f1ecd8; /* moonlight */
|
|
--accent: #f9d976; /* lantern */
|
|
}
|
|
|
|
@layer base {
|
|
body { font-family: "Nunito", system-ui, sans-serif; }
|
|
html { scroll-behavior: smooth; }
|
|
/* Belt-and-braces: never let stray wide content push horizontal scroll on
|
|
the whole page (the channel nav scrolls inside itself instead). */
|
|
html, body { overflow-x: hidden; }
|
|
}
|
|
|
|
@layer components {
|
|
/* Channel pill row may exceed viewport on mobile once enough channels are
|
|
configured. Let it scroll inside its own rounded container and hide the
|
|
scrollbar chrome so it still reads as a clean pill. */
|
|
.pete-channel-nav {
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
}
|
|
.pete-channel-nav::-webkit-scrollbar { display: none; }
|
|
}
|
|
|
|
@layer utilities {
|
|
.font-display { font-family: "Fredoka", "Nunito", system-ui, sans-serif; letter-spacing: -0.01em; }
|
|
|
|
/* Soft signage shadow — Animal Crossing wooden plank vibe. */
|
|
.shadow-pete { box-shadow: 0 4px 0 rgba(60,40,20,0.10), 0 8px 24px rgba(60,40,20,0.08); }
|
|
.shadow-pete-lg { box-shadow: 0 6px 0 rgba(60,40,20,0.12), 0 16px 32px rgba(60,40,20,0.12); }
|
|
|
|
/* Per-channel theme colors. Kept as plain utilities so Tailwind doesn't
|
|
need to know to safelist them. */
|
|
.bg-theme-gaming { background-color: #4caf7d; }
|
|
.bg-theme-tech { background-color: #5aa9e6; }
|
|
.bg-theme-politics { background-color: #e07a5f; }
|
|
.bg-theme-eu { background-color: #003399; }
|
|
.bg-theme-music { background-color: #b079d6; }
|
|
.bg-theme-anime { background-color: #ec5e8a; }
|
|
.bg-theme-foss { background-color: #d97706; }
|
|
.bg-theme-kids { background-color: #14b8a6; }
|
|
.bg-theme-finance { background-color: #10b981; }
|
|
.bg-theme-lego { background-color: #d01012; }
|
|
|
|
.text-theme-gaming { color: #2d8a5a; }
|
|
.text-theme-tech { color: #2f7fb8; }
|
|
.text-theme-politics { color: #b8523a; }
|
|
.text-theme-eu { color: #003399; }
|
|
.text-theme-music { color: #8a4fb8; }
|
|
.text-theme-anime { color: #c33a6a; }
|
|
.text-theme-foss { color: #b8530a; }
|
|
.text-theme-kids { color: #0f766e; }
|
|
.text-theme-finance { color: #059669; }
|
|
.text-theme-lego { color: #b00d0e; }
|
|
|
|
.decoration-theme-gaming { text-decoration-color: #4caf7d; }
|
|
.decoration-theme-tech { text-decoration-color: #5aa9e6; }
|
|
.decoration-theme-politics { text-decoration-color: #e07a5f; }
|
|
.decoration-theme-eu { text-decoration-color: #003399; }
|
|
.decoration-theme-music { text-decoration-color: #b079d6; }
|
|
.decoration-theme-anime { text-decoration-color: #ec5e8a; }
|
|
.decoration-theme-foss { text-decoration-color: #d97706; }
|
|
.decoration-theme-kids { text-decoration-color: #14b8a6; }
|
|
.decoration-theme-finance { text-decoration-color: #10b981; }
|
|
.decoration-theme-lego { text-decoration-color: #d01012; }
|
|
|
|
.border-theme-gaming { border-color: #4caf7d; }
|
|
.border-theme-tech { border-color: #5aa9e6; }
|
|
.border-theme-politics { border-color: #e07a5f; }
|
|
.border-theme-eu { border-color: #003399; }
|
|
.border-theme-music { border-color: #b079d6; }
|
|
.border-theme-anime { border-color: #ec5e8a; }
|
|
.border-theme-foss { border-color: #d97706; }
|
|
.border-theme-kids { border-color: #14b8a6; }
|
|
.border-theme-finance { border-color: #10b981; }
|
|
.border-theme-lego { border-color: #d01012; }
|
|
|
|
/* "Posted to Matrix" glow — soft pulsing aura in the channel's theme color. */
|
|
.glow-theme-gaming { box-shadow: 0 0 0 2px rgba(76,175,125,0.35), 0 0 24px 4px rgba(76,175,125,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-tech { box-shadow: 0 0 0 2px rgba(90,169,230,0.35), 0 0 24px 4px rgba(90,169,230,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-politics { box-shadow: 0 0 0 2px rgba(224,122,95,0.35), 0 0 24px 4px rgba(224,122,95,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-eu { box-shadow: 0 0 0 2px rgba(0,51,153,0.35), 0 0 24px 4px rgba(0,51,153,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-music { box-shadow: 0 0 0 2px rgba(176,121,214,0.35), 0 0 24px 4px rgba(176,121,214,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-anime { box-shadow: 0 0 0 2px rgba(236,94,138,0.35), 0 0 24px 4px rgba(236,94,138,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-foss { box-shadow: 0 0 0 2px rgba(217,119,6,0.35), 0 0 24px 4px rgba(217,119,6,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-kids { box-shadow: 0 0 0 2px rgba(20,184,166,0.35), 0 0 24px 4px rgba(20,184,166,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-finance { box-shadow: 0 0 0 2px rgba(16,185,129,0.35), 0 0 24px 4px rgba(16,185,129,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
.glow-theme-lego { box-shadow: 0 0 0 2px rgba(208,16,18,0.35), 0 0 24px 4px rgba(208,16,18,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
|
|
|
@keyframes pete-glow-pulse {
|
|
0%, 100% { filter: brightness(1); }
|
|
50% { filter: brightness(1.08); }
|
|
}
|
|
|
|
.line-clamp-3 {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* "PAYWALLED" diagonal rubber stamp overlay — slapped across the whole
|
|
card when the source is gated and no archive snapshot worked. The card
|
|
stays clickable (link still goes to the original); the stamp is just
|
|
visual warning. pointer-events:none keeps it from eating clicks. */
|
|
.paywall-stamp {
|
|
position: absolute;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 5;
|
|
background: rgba(255, 250, 240, 0.18);
|
|
}
|
|
.paywall-stamp::before {
|
|
content: "PAYWALLED";
|
|
font-family: var(--font-display, ui-sans-serif), system-ui, sans-serif;
|
|
font-weight: 900;
|
|
font-size: clamp(1rem, 3.2vw, 1.75rem);
|
|
letter-spacing: 0.12em;
|
|
color: rgba(180, 30, 30, 0.85);
|
|
border: 0.28rem double rgba(180, 30, 30, 0.85);
|
|
padding: 0.3rem 0.9rem;
|
|
transform: rotate(-15deg);
|
|
text-shadow: 0 1px 0 rgba(255,255,255,0.4);
|
|
box-shadow: inset 0 0 0 2px rgba(255,255,255,0.15);
|
|
background: rgba(255, 240, 230, 0.55);
|
|
border-radius: 0.25rem;
|
|
/* slight roughness to mimic a real ink stamp */
|
|
filter: contrast(1.05);
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
Feed / reader mode. A focused, one-story-at-a-time overlay driven by
|
|
reader.js. Left/right arrows page through the stories currently on screen,
|
|
marking each read as it's shown. Styling leans on the phase palette vars so
|
|
it recolours with day/night like everything else.
|
|
---------------------------------------------------------------------------- */
|
|
@layer components {
|
|
.pete-reader-backdrop {
|
|
position: absolute;
|
|
inset: 0;
|
|
background: rgba(20, 14, 6, 0.55);
|
|
backdrop-filter: blur(6px);
|
|
}
|
|
html[data-phase="night"] .pete-reader-backdrop { background: rgba(6, 8, 20, 0.65); }
|
|
|
|
.pete-reader-shell {
|
|
position: relative;
|
|
height: 100%;
|
|
width: 100%;
|
|
max-width: 44rem;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: max(env(safe-area-inset-top), 0.75rem) 1rem 0.75rem;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.pete-reader-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.75rem;
|
|
color: #fff;
|
|
}
|
|
.pete-reader-progress {
|
|
font-family: "Fredoka", "Nunito", system-ui, sans-serif;
|
|
font-weight: 600;
|
|
font-size: 0.85rem;
|
|
letter-spacing: 0.02em;
|
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
}
|
|
.pete-reader-nav { display: flex; align-items: center; gap: 0.4rem; }
|
|
.pete-reader-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 2.25rem;
|
|
height: 2.25rem;
|
|
padding: 0 0.7rem;
|
|
border-radius: 9999px;
|
|
background: rgba(255, 255, 255, 0.14);
|
|
color: #fff;
|
|
font-weight: 700;
|
|
font-size: 0.95rem;
|
|
border: 2px solid rgba(255, 255, 255, 0.18);
|
|
cursor: pointer;
|
|
transition: background 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
|
|
}
|
|
.pete-reader-btn:hover { background: rgba(255, 255, 255, 0.28); transform: translateY(-1px); }
|
|
.pete-reader-btn:disabled { opacity: 0.35; cursor: default; transform: none; }
|
|
.pete-reader-btn-open { background: var(--accent); border-color: transparent; color: #1c1305; text-decoration: none; }
|
|
.pete-reader-btn-open:hover { background: var(--accent); filter: brightness(1.08); }
|
|
/* Active/pressed toolbar toggle (Listen while speaking, Aa while menu open). */
|
|
.pete-reader-btn[aria-pressed="true"],
|
|
.pete-reader-btn[aria-expanded="true"] {
|
|
background: var(--accent);
|
|
border-color: transparent;
|
|
color: #1c1305;
|
|
}
|
|
|
|
/* Text-options popover, anchored under the Aa button in the reader bar. */
|
|
.pete-reader-type { position: relative; display: inline-flex; }
|
|
.pete-reader-typemenu[hidden] { display: none; }
|
|
.pete-reader-typemenu {
|
|
position: absolute;
|
|
top: calc(100% + 0.5rem);
|
|
right: 0;
|
|
z-index: 10;
|
|
width: 15rem;
|
|
padding: 0.75rem;
|
|
border-radius: 1rem;
|
|
background: var(--card);
|
|
color: var(--ink);
|
|
border: 2px solid rgba(0, 0, 0, 0.08);
|
|
box-shadow: 0 10px 30px rgba(20, 14, 6, 0.28);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.6rem;
|
|
}
|
|
html[data-phase="night"] .pete-reader-typemenu { border-color: rgba(255, 255, 255, 0.12); }
|
|
.pete-reader-typerow { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
|
|
.pete-reader-typelabel { font-size: 0.8rem; font-weight: 700; opacity: 0.7; }
|
|
.pete-reader-typebtns { display: inline-flex; gap: 0.25rem; }
|
|
.pete-reader-typebtns button {
|
|
min-width: 2rem;
|
|
height: 2rem;
|
|
padding: 0 0.55rem;
|
|
border-radius: 0.6rem;
|
|
background: rgba(20, 14, 6, 0.06);
|
|
color: var(--ink);
|
|
font-weight: 700;
|
|
font-size: 0.82rem;
|
|
border: 2px solid transparent;
|
|
cursor: pointer;
|
|
transition: background 0.15s ease;
|
|
}
|
|
html[data-phase="night"] .pete-reader-typebtns button { background: rgba(255, 255, 255, 0.08); }
|
|
.pete-reader-typebtns button:hover { background: rgba(20, 14, 6, 0.12); }
|
|
.pete-reader-typebtns button.is-active {
|
|
background: var(--accent);
|
|
color: #1c1305;
|
|
border-color: transparent;
|
|
}
|
|
.pete-reader-voicerow[hidden] { display: none; }
|
|
.pete-reader-voice {
|
|
font: inherit;
|
|
font-size: 0.8rem;
|
|
font-weight: 600;
|
|
padding: 0.25rem 0.4rem;
|
|
border-radius: 0.55rem;
|
|
border: 1px solid rgba(20, 14, 6, 0.18);
|
|
background: rgba(20, 14, 6, 0.06);
|
|
color: inherit;
|
|
max-width: 11rem;
|
|
cursor: pointer;
|
|
}
|
|
html[data-phase="night"] .pete-reader-voice {
|
|
border-color: rgba(255, 255, 255, 0.14);
|
|
background: rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
.pete-reader-scroll {
|
|
flex: 1 1 auto;
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
border-radius: 1.75rem;
|
|
}
|
|
|
|
.pete-reader-article {
|
|
background: var(--card);
|
|
color: var(--ink);
|
|
border-radius: 1.75rem;
|
|
border: 2px solid rgba(0, 0, 0, 0.06);
|
|
box-shadow: 0 6px 0 rgba(60, 40, 20, 0.12), 0 16px 32px rgba(60, 40, 20, 0.18);
|
|
padding: clamp(1.25rem, 4vw, 2.5rem);
|
|
}
|
|
html[data-phase="night"] .pete-reader-article { border-color: rgba(255, 255, 255, 0.08); }
|
|
|
|
.pete-reader-eyebrow {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 0.5rem;
|
|
font-size: 0.75rem;
|
|
margin-bottom: 0.85rem;
|
|
}
|
|
.pete-reader-chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
border-radius: 9999px;
|
|
padding: 0.15rem 0.65rem;
|
|
color: #fff;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
}
|
|
.pete-reader-source { font-weight: 700; opacity: 0.75; }
|
|
.pete-reader-time { opacity: 0.55; }
|
|
|
|
.pete-reader-title {
|
|
font-family: "Fredoka", "Nunito", system-ui, sans-serif;
|
|
font-weight: 700;
|
|
line-height: 1.15;
|
|
letter-spacing: -0.01em;
|
|
font-size: clamp(1.6rem, 4.5vw, 2.4rem);
|
|
margin-bottom: 1rem;
|
|
}
|
|
.pete-reader-hero {
|
|
width: 100%;
|
|
border-radius: 1.1rem;
|
|
margin-bottom: 1.25rem;
|
|
background: rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
/* Reader typography, driven by the Aa popover and persisted per-device. The
|
|
size lives as a CSS var on the scroll container; font + paper are classes. */
|
|
.pete-reader-scroll { --reader-fs: 1.08rem; }
|
|
.pete-reader-body { font-size: var(--reader-fs); line-height: 1.75; }
|
|
.pete-reader-body p { margin-bottom: 1.05em; }
|
|
.pete-reader-body p:last-child { margin-bottom: 0; }
|
|
.pete-reader-scroll.is-size-s { --reader-fs: 0.98rem; }
|
|
.pete-reader-scroll.is-size-m { --reader-fs: 1.08rem; }
|
|
.pete-reader-scroll.is-size-l { --reader-fs: 1.22rem; }
|
|
.pete-reader-scroll.is-size-xl { --reader-fs: 1.4rem; }
|
|
.pete-reader-scroll.is-serif .pete-reader-body {
|
|
font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
|
|
}
|
|
/* Sepia paper: warm background + ink regardless of day/night phase. */
|
|
.pete-reader-scroll.is-sepia .pete-reader-article {
|
|
background: #f6ecd6;
|
|
color: #4a3a28;
|
|
border-color: rgba(74, 58, 40, 0.16);
|
|
}
|
|
.pete-reader-scroll.is-sepia .pete-reader-note { border-top-color: rgba(74, 58, 40, 0.18); opacity: 0.8; }
|
|
.pete-reader-scroll.is-sepia .pete-reader-hero { background: rgba(74, 58, 40, 0.08); }
|
|
/* Currently-spoken paragraph highlight while reading aloud. */
|
|
.pete-reader-body p.is-speaking {
|
|
background: color-mix(in srgb, var(--accent) 32%, transparent);
|
|
border-radius: 0.4rem;
|
|
box-shadow: 0 0 0 0.35rem color-mix(in srgb, var(--accent) 32%, transparent);
|
|
}
|
|
|
|
.pete-reader-note {
|
|
margin-top: 1.25rem;
|
|
padding-top: 1rem;
|
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
|
font-size: 0.85rem;
|
|
opacity: 0.7;
|
|
}
|
|
html[data-phase="night"] .pete-reader-note { border-color: rgba(255, 255, 255, 0.12); }
|
|
.pete-reader-note a { color: var(--accent); font-weight: 700; }
|
|
|
|
.pete-reader-empty {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
text-align: center;
|
|
gap: 0.75rem;
|
|
padding: clamp(2rem, 8vw, 4rem) 1rem;
|
|
color: var(--ink);
|
|
}
|
|
.pete-reader-empty-emoji { font-size: 2.5rem; }
|
|
|
|
/* Transient confirmation toast (e.g. "Link copied") shown over the reader. */
|
|
.pete-reader-toast {
|
|
position: absolute;
|
|
left: 50%;
|
|
bottom: 4.5rem;
|
|
transform: translate(-50%, 0.5rem);
|
|
z-index: 20;
|
|
padding: 0.5rem 0.9rem;
|
|
border-radius: 9999px;
|
|
background: rgba(20, 14, 6, 0.9);
|
|
color: #fff;
|
|
font-weight: 700;
|
|
font-size: 0.85rem;
|
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
}
|
|
.pete-reader-toast.is-shown { opacity: 1; transform: translate(-50%, 0); }
|
|
|
|
.pete-reader-hint {
|
|
text-align: center;
|
|
color: rgba(255, 255, 255, 0.85);
|
|
font-size: 0.75rem;
|
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
}
|
|
.pete-reader-hint kbd {
|
|
font-family: ui-monospace, monospace;
|
|
background: rgba(255, 255, 255, 0.16);
|
|
border-radius: 0.3rem;
|
|
padding: 0.05rem 0.3rem;
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.pete-reader-hint { display: none; }
|
|
/* With Listen/Share/Aa added, let the toolbar wrap instead of overflowing. */
|
|
.pete-reader-bar { flex-wrap: wrap; }
|
|
.pete-reader-nav { flex-wrap: wrap; justify-content: flex-end; row-gap: 0.4rem; }
|
|
}
|
|
|
|
/* "You might also like" rail, shown under the article in feed mode. Lives
|
|
inside the reader's scroll area, below the article card. */
|
|
.pete-reader-related { width: 100%; margin: 0.85rem auto 0; }
|
|
.pete-reader-related-title {
|
|
font-family: "Fredoka", "Nunito", system-ui, sans-serif;
|
|
font-weight: 700;
|
|
font-size: 0.95rem;
|
|
color: #fff;
|
|
margin: 0 0 0.6rem;
|
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
}
|
|
.pete-reader-related-grid { display: grid; gap: 0.6rem; }
|
|
.pete-reader-related-card {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
background: var(--card);
|
|
color: var(--ink);
|
|
border-radius: 1rem;
|
|
border: 2px solid rgba(0, 0, 0, 0.06);
|
|
padding: 0.6rem;
|
|
text-decoration: none;
|
|
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
|
}
|
|
.pete-reader-related-card:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 6px 16px rgba(60, 40, 20, 0.16);
|
|
}
|
|
html[data-phase="night"] .pete-reader-related-card { border-color: rgba(255, 255, 255, 0.08); }
|
|
.pete-reader-related-thumb {
|
|
width: 4.5rem;
|
|
height: 3.25rem;
|
|
flex-shrink: 0;
|
|
object-fit: cover;
|
|
border-radius: 0.6rem;
|
|
background: rgba(0, 0, 0, 0.06);
|
|
}
|
|
.pete-reader-related-meta { min-width: 0; display: flex; flex-direction: column; gap: 0.25rem; }
|
|
.pete-reader-related-eyebrow {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 0.4rem;
|
|
font-size: 0.7rem;
|
|
}
|
|
.pete-reader-related-source { font-weight: 700; opacity: 0.7; }
|
|
.pete-reader-related-headline {
|
|
font-weight: 700;
|
|
line-height: 1.25;
|
|
font-size: 0.92rem;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Grid treatment for stories already read in feed mode: dimmed, with a small
|
|
corner check. Hovering restores full opacity so nothing feels lost. */
|
|
[data-story-card][data-read="1"] { opacity: 0.5; transition: opacity 0.2s ease; }
|
|
[data-story-card][data-read="1"]:hover { opacity: 1; }
|
|
[data-story-card][data-read="1"]::after {
|
|
content: "✓";
|
|
position: absolute;
|
|
top: 0.6rem;
|
|
right: 0.6rem;
|
|
z-index: 6;
|
|
display: grid;
|
|
place-items: center;
|
|
height: 1.5rem;
|
|
width: 1.5rem;
|
|
border-radius: 9999px;
|
|
background: rgba(20, 14, 6, 0.72);
|
|
color: #fff;
|
|
font-size: 0.8rem;
|
|
font-weight: 700;
|
|
}
|
|
}
|