diff --git a/app.css b/app.css index fbd4233..6705096 100644 --- a/app.css +++ b/app.css @@ -3603,6 +3603,100 @@ footer a:hover { color: var(--accent-2); } .trk-info-label { color: #666; } } + +/* ── Per-type bespoke: Question — Stack Overflow Q&A card ── */ + +.card.qa-card { background: #fff; border-color: rgba(0,0,0,.08); } +.card.qa-card .hd.hidden { display: none; } +.card.qa-card .bd { padding: 1.4rem; background: #fff; } +.card.qa-card .bd::before { display: none; } + +/* Stat chips */ +.qa-stats { display: flex; gap: .6rem; margin-bottom: 1rem; } +.qa-chip { + display: flex; + align-items: center; + gap: .35rem; + padding: .3rem .7rem; + border-radius: 6px; + background: #f0f0f0; + font-size: .78rem; +} +.qa-chip-num { font-weight: 700; color: #555; font-size: .85rem; } +.qa-chip-label { color: #888; } +.qa-chip-accepted { background: #dcfce7; } +.qa-chip-accepted .qa-chip-num { color: #15803d; } +.qa-chip-accepted .qa-chip-label { color: #15803d; } + +/* Question title */ +.qa-title { + font-size: 1.25rem; + font-weight: 700; + color: #1a1a1a; + line-height: 1.35; + margin: 0 0 .8rem; +} + +/* Question body */ +.qa-body { + font-size: .88rem; + line-height: 1.6; + color: #444; + margin-bottom: .8rem; + white-space: pre-wrap; +} + +/* Meta line */ +.qa-meta { + font-size: .75rem; + color: #999; + margin-bottom: 1.2rem; + padding-bottom: .8rem; + border-bottom: 1px solid #eee; +} +.qa-meta strong { color: #0891b2; font-weight: 600; } + +/* Accepted answer */ +.qa-accepted { + background: #f0fdf4; + border: 1px solid #bbf7d0; + border-radius: 8px; + padding: 1rem 1.1rem; +} +.qa-accepted-head { + font-size: .75rem; + font-weight: 700; + color: #15803d; + margin-bottom: .5rem; + text-transform: uppercase; + letter-spacing: .03em; +} +.qa-accepted-body { + font-size: .85rem; + line-height: 1.6; + color: #333; + white-space: pre-wrap; +} + +/* Dark mode Q&A */ +@media (prefers-color-scheme: dark) { + .card.qa-card { background: #1c1c1e; border-color: rgba(255,255,255,.06); } + .card.qa-card .bd { background: #1c1c1e; } + .qa-chip { background: #2a2a2e; } + .qa-chip-num { color: #ccc; } + .qa-chip-label { color: #666; } + .qa-chip-accepted { background: #052e16; } + .qa-chip-accepted .qa-chip-num { color: #6ee7b7; } + .qa-chip-accepted .qa-chip-label { color: #6ee7b7; } + .qa-title { color: #e8e8e8; } + .qa-body { color: #bbb; } + .qa-meta { color: #555; border-bottom-color: #333; } + .qa-meta strong { color: #22d3ee; } + .qa-accepted { background: #052e16; border-color: #064e3b; } + .qa-accepted-head { color: #6ee7b7; } + .qa-accepted-body { color: #ccc; } +} + /* ────────────────────────────────────────────── Responsive / Mobile — small-screen polish. Stacks label/value grid, scales header, diff --git a/app.js b/app.js index adfc543..727fd0e 100644 --- a/app.js +++ b/app.js @@ -2426,6 +2426,68 @@ handled.add("expectedArrivalUntil"); handled.add("itemShipped"); handled.add("deliveryAddress"); } + // ── QUESTION (Stack Overflow Q&A card) ── + if (cfg.type === "Question") { + const card = document.querySelector(".card"); + if (card) card.classList.add("qa-card"); + + // Hide normal header + const hd = document.querySelector(".hd"); + if (hd) hd.classList.add("hidden"); + + // Remove generic hero if present + const heroMount = document.getElementById("hero-mount"); + if (heroMount) heroMount.querySelector(".hero")?.remove(); + + // Stat chips row + const stats = document.createElement("div"); stats.className = "qa-stats"; + const answers = data["answerCount"] || "0"; + const hasAccepted = !!data["acceptedAnswer"]; + stats.innerHTML = "
" + answers + "answers
" + (hasAccepted ? "
\u2713accepted
" : ""); + view.appendChild(stats); + + // Question title + const qTitle = data["name"]; + if (qTitle) { + const h = document.createElement("h2"); h.className = "qa-title"; + h.textContent = qTitle; + view.appendChild(h); + } + + // Question body + const qBody = data["text"]; + if (qBody) { + const body = document.createElement("div"); body.className = "qa-body"; + body.textContent = qBody; + view.appendChild(body); + } + + // Author + date meta line + const authorRaw = data["author"]; + const authorName = (typeof authorRaw === "object" && authorRaw !== null) ? (authorRaw.name || "") : (authorRaw || ""); + const dateCreated = data["dateCreated"]; + let dateStr = ""; + if (dateCreated) { + const d = new Date(dateCreated); + dateStr = isNaN(d.getTime()) ? dateCreated : d.toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" }); + } + const meta = document.createElement("div"); meta.className = "qa-meta"; + meta.innerHTML = (authorName ? "asked by " + authorName + "" : "") + (dateStr ? " on " + dateStr : ""); + view.appendChild(meta); + + // Accepted answer panel + const accepted = data["acceptedAnswer"]; + if (accepted) { + const panel = document.createElement("div"); panel.className = "qa-accepted"; + panel.innerHTML = "
\u2705 Accepted Answer
" + accepted + "
"; + view.appendChild(panel); + } + + handled.add("name"); handled.add("image"); handled.add("description"); + handled.add("text"); handled.add("author"); handled.add("dateCreated"); + handled.add("answerCount"); handled.add("acceptedAnswer"); + } + return handled; }