Feed

Continuously updated content stream.

Latest updates

Nothing here yet

New posts will appear here as they're published.

html

<section class="feed-demo feed-demo--loaded feed-demo--comfortable" style="--accent:#F5C2E0;">
  <h2 class="feed-demo__heading">Latest updates</h2>
  <ul class="feed-demo__list">
    <li class="feed-demo__item">
      <div class="feed-demo__item-head">
        <p class="feed-demo__item-title">New export formats are live</p>
        <span class="feed-demo__tag">Product</span>
      </div>
      <p class="feed-demo__item-body">Specimens can now be downloaded as HTML, Tailwind or React straight from the toolbar.</p>
      <time class="feed-demo__time" datetime="2026-08-18T08:00:00Z">18 Aug, 8:00am</time>
    </li>
    <li class="feed-demo__item">
      <div class="feed-demo__item-head">
        <p class="feed-demo__item-title">Glossary search is faster</p>
        <span class="feed-demo__tag">Performance</span>
      </div>
      <p class="feed-demo__item-body">Fuzzy search across every entry now returns results in under 50ms.</p>
      <time class="feed-demo__time" datetime="2026-08-16T13:20:00Z">16 Aug, 1:20pm</time>
    </li>
    <li class="feed-demo__item">
      <div class="feed-demo__item-head">
        <p class="feed-demo__item-title">New contributor: Maya Singh</p>
        <span class="feed-demo__tag">Community</span>
      </div>
      <p class="feed-demo__item-body">Maya joined the glossary team and shipped her first three entries this week.</p>
      <time class="feed-demo__time" datetime="2026-08-14T09:05:00Z">14 Aug, 9:05am</time>
    </li>
  </ul>
  <div class="feed-demo__skeleton" aria-hidden="true">
    <div class="feed-demo__skel-item"><span class="feed-demo__skel-line feed-demo__skel-line--title"></span><span class="feed-demo__skel-line"></span><span class="feed-demo__skel-line feed-demo__skel-line--short"></span></div>
    <div class="feed-demo__skel-item"><span class="feed-demo__skel-line feed-demo__skel-line--title"></span><span class="feed-demo__skel-line"></span><span class="feed-demo__skel-line feed-demo__skel-line--short"></span></div>
    <div class="feed-demo__skel-item"><span class="feed-demo__skel-line feed-demo__skel-line--title"></span><span class="feed-demo__skel-line"></span><span class="feed-demo__skel-line feed-demo__skel-line--short"></span></div>
  </div>
  <div class="feed-demo__empty">
    <svg viewBox="0 0 48 48" width="40" height="40" aria-hidden="true">
      <circle cx="24" cy="24" r="18" fill="none" stroke="#241430" stroke-width="2"/>
      <path d="M17 24h14M24 17v14" stroke="#241430" stroke-width="2" stroke-linecap="round" opacity=".35"/>
    </svg>
    <p class="feed-demo__empty-title">Nothing here yet</p>
    <p class="feed-demo__empty-sub">New posts will appear here as they're published.</p>
  </div>
</section>
<style>
.feed-demo { font: 14px/1.5 system-ui, sans-serif; color: #241430; background: #FAF7F2; border: 1.5px solid #24143022; border-radius: 12px; padding: 18px; box-sizing: border-box; }
.feed-demo__heading { margin: 0 0 12px; font-size: 16px; font-weight: 600; }
.feed-demo__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.feed-demo--compact .feed-demo__list { gap: 8px; }
.feed-demo__item { border-left: 3px solid var(--accent); padding: 4px 0 4px 12px; }
.feed-demo--compact .feed-demo__item { padding: 2px 0 2px 10px; }
.feed-demo__item-head { display: flex; align-items: center; gap: 8px; }
.feed-demo__item-title { margin: 0; font-weight: 600; font-size: 14px; }
.feed-demo__tag { font-size: 10px; font-weight: 600; text-transform: uppercase; background: #24143012; padding: 2px 7px; border-radius: 999px; }
.feed-demo__item-body { margin: 4px 0; font-size: 13px; color: #241430cc; }
.feed-demo--compact .feed-demo__item-body { display: none; }
.feed-demo__time { font-size: 11px; color: #24143099; }
.feed-demo__skeleton, .feed-demo__empty { display: none; }
.feed-demo__skel-item { display: flex; flex-direction: column; gap: 6px; padding: 6px 0 6px 12px; border-left: 3px solid #24143014; margin-bottom: 12px; }
.feed-demo__skel-line { display: block; height: 9px; border-radius: 4px; background: linear-gradient(90deg, #24143012 25%, #24143024 37%, #24143012 63%); background-size: 400% 100%; width: 90%; }
@media (prefers-reduced-motion: no-preference) {
.feed-demo__skel-line { animation: feed-shimmer .22s ease infinite; }
}
.feed-demo__skel-line--title { width: 55%; height: 11px; }
.feed-demo__skel-line--short { width: 35%; }
@keyframes feed-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
.feed-demo__empty { text-align: center; padding: 24px 0; }
.feed-demo__empty-title { margin: 8px 0 4px; font-weight: 600; }
.feed-demo__empty-sub { margin: 0; font-size: 13px; color: #241430aa; }
.feed-demo--loading .feed-demo__list { display: none; }
.feed-demo--loading .feed-demo__skeleton { display: block; }
.feed-demo--empty .feed-demo__list { display: none; }
.feed-demo--empty .feed-demo__empty { display: block; }
</style>

tailwind

<section class="feed-tw feed-tw--loaded feed-tw--comfortable font-sans text-sm text-[#241430] bg-[#FAF7F2] border-[1.5px] border-[#24143022] rounded-xl p-[18px] box-border" style="--accent:#F5C2E0;">
  <h2 class="m-0 mb-3 text-base font-semibold">Latest updates</h2>
  <ul class="feed-tw__list list-none m-0 p-0 flex flex-col gap-3.5">
    <li class="feed-tw__item pl-3 py-1" style="border-left: 3px solid #F5C2E0;">
      <div class="flex items-center gap-2">
        <p class="m-0 font-semibold text-sm">New export formats are live</p>
        <span class="text-[10px] font-semibold uppercase bg-[#24143012] px-1.5 py-0.5 rounded-full">Product</span>
      </div>
      <p class="feed-tw__body my-1 text-[13px] text-[#241430]/80">Specimens can now be downloaded as HTML, Tailwind or React straight from the toolbar.</p>
      <time class="text-[11px] text-[#241430]/60" datetime="2026-08-18T08:00:00Z">18 Aug, 8:00am</time>
    </li>
    <li class="feed-tw__item pl-3 py-1" style="border-left: 3px solid #F5C2E0;">
      <div class="flex items-center gap-2">
        <p class="m-0 font-semibold text-sm">Glossary search is faster</p>
        <span class="text-[10px] font-semibold uppercase bg-[#24143012] px-1.5 py-0.5 rounded-full">Performance</span>
      </div>
      <p class="feed-tw__body my-1 text-[13px] text-[#241430]/80">Fuzzy search across every entry now returns results in under 50ms.</p>
      <time class="text-[11px] text-[#241430]/60" datetime="2026-08-16T13:20:00Z">16 Aug, 1:20pm</time>
    </li>
    <li class="feed-tw__item pl-3 py-1" style="border-left: 3px solid #F5C2E0;">
      <div class="flex items-center gap-2">
        <p class="m-0 font-semibold text-sm">New contributor: Maya Singh</p>
        <span class="text-[10px] font-semibold uppercase bg-[#24143012] px-1.5 py-0.5 rounded-full">Community</span>
      </div>
      <p class="feed-tw__body my-1 text-[13px] text-[#241430]/80">Maya joined the glossary team and shipped her first three entries this week.</p>
      <time class="text-[11px] text-[#241430]/60" datetime="2026-08-14T09:05:00Z">14 Aug, 9:05am</time>
    </li>
  </ul>
  <div class="feed-tw__skeleton" aria-hidden="true">
    <div class="feed-tw__skel-item"><span class="feed-tw__skel-line feed-tw__skel-line--title"></span><span class="feed-tw__skel-line"></span><span class="feed-tw__skel-line feed-tw__skel-line--short"></span></div>
    <div class="feed-tw__skel-item"><span class="feed-tw__skel-line feed-tw__skel-line--title"></span><span class="feed-tw__skel-line"></span><span class="feed-tw__skel-line feed-tw__skel-line--short"></span></div>
    <div class="feed-tw__skel-item"><span class="feed-tw__skel-line feed-tw__skel-line--title"></span><span class="feed-tw__skel-line"></span><span class="feed-tw__skel-line feed-tw__skel-line--short"></span></div>
  </div>
  <div class="feed-tw__empty text-center py-6">
    <svg viewBox="0 0 48 48" width="40" height="40" aria-hidden="true">
      <circle cx="24" cy="24" r="18" fill="none" stroke="#241430" stroke-width="2"/>
      <path d="M17 24h14M24 17v14" stroke="#241430" stroke-width="2" stroke-linecap="round" opacity=".35"/>
    </svg>
    <p class="mt-2 mb-1 font-semibold">Nothing here yet</p>
    <p class="m-0 text-[13px] text-[#241430]/70">New posts will appear here as they're published.</p>
  </div>
</section>
<style>
.feed-tw--compact .feed-tw__list { gap: 8px; }
.feed-tw--compact .feed-tw__item { padding: 2px 0 2px 10px; }
.feed-tw--compact .feed-tw__body { display: none; }
.feed-tw__skeleton, .feed-tw__empty { display: none; }
.feed-tw__skel-item { display: flex; flex-direction: column; gap: 6px; padding: 6px 0 6px 12px; border-left: 3px solid #24143014; margin-bottom: 12px; }
.feed-tw__skel-line { display: block; height: 9px; border-radius: 4px; background: linear-gradient(90deg, #24143012 25%, #24143024 37%, #24143012 63%); background-size: 400% 100%; width: 90%; }
@media (prefers-reduced-motion: no-preference) {
.feed-tw__skel-line { animation: feed-tw-shimmer .22s ease infinite; }
}
.feed-tw__skel-line--title { width: 55%; height: 11px; }
.feed-tw__skel-line--short { width: 35%; }
@keyframes feed-tw-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
.feed-tw--loading .feed-tw__list { display: none; }
.feed-tw--loading .feed-tw__skeleton { display: block; }
.feed-tw--empty .feed-tw__list { display: none; }
.feed-tw--empty .feed-tw__empty { display: block; }
</style>

react

export function Feed({
  title = "Latest updates",
  state = "loaded",
  density = "comfortable",
  accent = "#F5C2E0",
  showTags = true,
}) {
  const posts = [
    { title: "New export formats are live", tag: "Product", body: "Specimens can now be downloaded as HTML, Tailwind or React straight from the toolbar.", iso: "2026-08-18T08:00:00Z", when: "18 Aug, 8:00am" },
    { title: "Glossary search is faster", tag: "Performance", body: "Fuzzy search across every entry now returns results in under 50ms.", iso: "2026-08-16T13:20:00Z", when: "16 Aug, 1:20pm" },
    { title: "New contributor: Maya Singh", tag: "Community", body: "Maya joined the glossary team and shipped her first three entries this week.", iso: "2026-08-14T09:05:00Z", when: "14 Aug, 9:05am" },
  ];
  const wrap = { fontFamily: "system-ui, sans-serif", fontSize: 14, lineHeight: 1.5, color: "#241430", background: "#FAF7F2", border: "1.5px solid #24143022", borderRadius: 12, padding: 18, boxSizing: "border-box" };
  if (state === "loading") {
    return (
      <div style={wrap}>
        <h2 style={{ margin: "0 0 12px", fontSize: 16, fontWeight: 600 }}>{title}</h2>
        {[0, 1, 2].map((i) => (
          <div key={i} style={{ display: "flex", flexDirection: "column", gap: 6, padding: "6px 0 6px 12px", borderLeft: "3px solid #24143014", marginBottom: 12 }}>
            <span style={{ display: "block", height: 11, width: "55%", borderRadius: 4, background: "#24143020" }} />
            <span style={{ display: "block", height: 9, width: "90%", borderRadius: 4, background: "#24143016" }} />
            <span style={{ display: "block", height: 9, width: "35%", borderRadius: 4, background: "#24143016" }} />
          </div>
        ))}
      </div>
    );
  }
  if (state === "empty") {
    return (
      <div style={{ ...wrap, textAlign: "center", padding: "24px 18px" }}>
        <p style={{ margin: "8px 0 4px", fontWeight: 600 }}>Nothing here yet</p>
        <p style={{ margin: 0, fontSize: 13, color: "#241430aa" }}>New posts will appear here as they're published.</p>
      </div>
    );
  }
  const gap = density === "compact" ? 8 : 14;
  const compact = density === "compact";
  return (
    <div style={wrap}>
      <h2 style={{ margin: "0 0 12px", fontSize: 16, fontWeight: 600 }}>{title}</h2>
      <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap }}>
        {posts.map((p) => (
          <li key={p.title} style={{ borderLeft: `3px solid ${accent}`, padding: compact ? "2px 0 2px 10px" : "4px 0 4px 12px" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <p style={{ margin: 0, fontWeight: 600, fontSize: 14 }}>{p.title}</p>
              {showTags && (
                <span style={{ fontSize: 10, fontWeight: 600, textTransform: "uppercase", background: "#24143012", padding: "2px 7px", borderRadius: 999 }}>{p.tag}</span>
              )}
            </div>
            {!compact && (
              <p style={{ margin: "4px 0", fontSize: 13, color: "#241430cc" }}>{p.body}</p>
            )}
            <time style={{ fontSize: 11, color: "#24143099" }} dateTime={p.iso}>{p.when}</time>
          </li>
        ))}
      </ul>
    </div>
  );
}