diff --git a/src/content/blog/agent-memory-provenance-audit-trails.mdx b/src/content/blog/agent-memory-provenance-audit-trails.mdx
index 42d8604..3d0be75 100644
--- a/src/content/blog/agent-memory-provenance-audit-trails.mdx
+++ b/src/content/blog/agent-memory-provenance-audit-trails.mdx
@@ -36,9 +36,15 @@ When the agent answers "your pipeline timed out at 9am UTC on April 14", you can
Honest accounting. Storing `source_episode_ids` per memory adds:
-- **Storage**: a small array of UUIDs per memory. For a million memories averaging three source episodes each, that's ~3M UUIDs — call it 50 MB. Trivial relative to the embeddings.
-- **Compute**: zero at retrieval time — the IDs are already on the memory row, no extra lookup unless you want to fetch the source episodes themselves.
-- **API surface**: one extra field on the memory shape, one optional `expand=episodes` parameter on the context endpoint for callers who want the raw events alongside the compiled facts.
+
The honest cost
+
+
+
+- Storage — a small array of UUIDs per memory. For a million memories averaging three source episodes each, that's ~3M UUIDs — call it 50 MB. Trivial relative to the embeddings.
+- Compute — zero at retrieval time. The IDs are already on the memory row, no extra lookup unless you want to fetch the source episodes themselves.
+- API surface — one extra field on the memory shape, one optional `expand=episodes` parameter on the context endpoint for callers who want the raw events alongside the compiled facts.
+
+
That's it. No separate audit-log service. No log shipping pipeline to keep alive. No retention conflict between the operational data and the audit data — they're the same data, in the same Postgres, with the same lifecycle.
@@ -58,7 +64,9 @@ This isn't a feature you bolt on for an enterprise tier. It's the data model. Th
### 3. Trust
-The thing that breaks user trust in AI agents isn't being wrong sometimes — it's being wrong *and unable to explain why*. A support agent that says "your subscription is on the Pro plan because that's what you told us on April 12" is qualitatively different from one that says "your subscription is on the Pro plan" full stop. The first is auditable. The second is confidence theater.
+> The thing that breaks user trust in AI agents isn't being wrong sometimes — it's being wrong *and unable to explain why*.
+
+A support agent that says "your subscription is on the Pro plan because that's what you told us on April 12" is qualitatively different from one that says "your subscription is on the Pro plan" full stop. The first is auditable. The second is confidence theater.
Provenance gives the agent the language to be honest about where its knowledge came from — and gives the human reviewer the language to verify it.
@@ -70,7 +78,7 @@ There's a school of thought that says provenance is an enterprise feature: ship
2. **The auditing audience is the same as the technical audience.** Engineers debugging the agent in dev want the same chain a compliance officer wants in prod. Building two paths to the same answer (a dev "trace" and a prod "audit log") doubles the surface area for bugs.
3. **It's a forcing function for honest storage.** If every memory has to carry its sources, you can't sneak a "memory" in that isn't backed by an episode. The compiler can't hallucinate. The agent's "knowledge" is bounded by what actually happened.
-Provenance ends up being a constraint that makes the whole system easier to reason about, not a tax you pay for compliance theater.
+> Provenance ends up being a constraint that makes the whole system easier to reason about, not a tax you pay for compliance theater.
## What this looks like in the API
diff --git a/src/content/blog/ai-agent-memory-vs-rag.mdx b/src/content/blog/ai-agent-memory-vs-rag.mdx
index 62bd881..5c37271 100644
--- a/src/content/blog/ai-agent-memory-vs-rag.mdx
+++ b/src/content/blog/ai-agent-memory-vs-rag.mdx
@@ -12,7 +12,9 @@ tags:
Most teams building on LLMs end up with two patterns in the same codebase: **RAG** for looking things up in a corpus, and some hand-rolled **memory** for remembering what the agent has done or what the user has said. The two are often confused, and the confusion costs real engineering time when one is used in place of the other.
-A short, accurate version: RAG retrieves *content the agent doesn't already know*; memory retrieves *context the agent has already participated in*. They share a vector store but they answer different questions, store different shapes of data, and have different correctness requirements.
+> RAG retrieves *content the agent doesn't already know*. Memory retrieves *context the agent has already participated in*.
+
+They share a vector store but they answer different questions, store different shapes of data, and have different correctness requirements.
## The shared substrate
@@ -37,9 +39,15 @@ You can paper over each of these in your application code. Teams that do end up
A memory runtime adds three things on top of the vector store:
-- **Compilation**: a pass over raw episodes that produces typed memories — profile facts, preferences, procedures, episode summaries — with confidence scores and validity windows. This is what shrinks 200 turns into one fact.
-- **Deterministic ranking**: scoring that mixes similarity with kind priority (a procedure beats a casual mention), recency, temporal validity, and an explicit token budget. Same query → same bundle. No silent re-ordering.
-- **Provenance**: every compiled memory carries the IDs of the episodes it was derived from. When an agent answers from memory, the answer is auditable back to the raw event that produced it.
+What memory adds
+
+
+
+- Compilation — a pass over raw episodes that produces typed memories — profile facts, preferences, procedures, episode summaries — with confidence scores and validity windows. This is what shrinks 200 turns into one fact.
+- Deterministic ranking — scoring that mixes similarity with kind priority (a procedure beats a casual mention), recency, temporal validity, and an explicit token budget. Same query → same bundle. No silent re-ordering.
+- Provenance — every compiled memory carries the IDs of the episodes it was derived from. When an agent answers from memory, the answer is auditable back to the raw event that produced it.
+
+
None of those are properties of "RAG" in the literature sense. They're what makes memory infrastructure rather than retrieval over chat logs.
@@ -53,7 +61,9 @@ None of those are properties of "RAG" in the literature sense. They're what make
| Mutability | Append-only chunks; reindex on doc update | Episodes append-only; memories supersede; compaction is idempotent |
| Output | Top-K chunks | Token-bounded bundle ready to drop into a prompt |
-Most production agents need both. The grounding corpus (docs, knowledge base) lives in RAG. The user / account / project context lives in memory. Trying to make either pattern do the other's job is the common architecture mistake — and it's the one we built Statewave to stop people from making.
+Most production agents need both. The grounding corpus (docs, knowledge base) lives in RAG. The user / account / project context lives in memory.
+
+> Trying to make either pattern do the other's job is the common architecture mistake — and it's the one we built Statewave to stop people from making.
## What Statewave is in this picture
diff --git a/src/content/blog/episodic-vs-semantic-memory.mdx b/src/content/blog/episodic-vs-semantic-memory.mdx
new file mode 100644
index 0000000..b7c8d13
--- /dev/null
+++ b/src/content/blog/episodic-vs-semantic-memory.mdx
@@ -0,0 +1,245 @@
+---
+title: "Episodic vs Semantic Memory in AI Agents: What to Store and When"
+slug: episodic-vs-semantic-memory
+date: "2026-08-07T09:00:00+02:00"
+description: Episodic memory stores what happened; semantic memory stores what's true. Here's how AI agents use each, when to convert one to the other, and how to store it.
+author: Statewave team
+tags:
+ - memory
+ - episodic-memory
+ - semantic-memory
+ - agent-memory
+---
+
+Episodic memory stores what happened. Semantic memory stores what is true. An AI agent uses episodic memory to recall a specific past interaction, and semantic memory to hold general facts it can reuse across many of them.
+
+The split comes from psychologist Endel Tulving in 1972, and it now decides whether your agent remembers a user or forgets them the moment a session closes. In one 2025 enterprise benchmark, leading agents scored about 58% on single-turn tasks but only 35% on multi-turn ones, and lost context was a leading cause.
+
+This post is for engineers and technical founders building agents that need a past. You'll get a clear definition of each memory type, a rule for deciding what to store where, and the parts most guides skip: consolidation, invalidation, and retrieval that doesn't rely on similarity alone.
+
+## What is the difference between episodic and semantic memory?
+
+The cleanest definition still comes from Tulving's 1972 chapter "Episodic and Semantic Memory," in the book *Organization of Memory*. He proposed splitting long-term memory into two systems with different jobs.
+
+Semantic memory holds facts and meanings, which he described as functioning like a "mental thesaurus."
+
+Episodic memory holds personal experience tied to a specific time and place, or as he put it, "temporally dated episodes or events, and the temporal-spatial relations" among them.
+
+A short version you can carry into a design review: knowing what a cat is sits in semantic memory. Remembering the cat that walked across your keyboard last Tuesday sits in episodic memory. One is general and reusable. The other is specific, timestamped, and personal.
+
+Tulving himself called the distinction "an orienting attitude," not a hard wall, and argued the two systems depend on each other. That caveat matters for agents, because the line blurs the moment code has to decide what to write down. More on that below.
+
+## How do episodic and semantic memory work in AI agents?
+
+The mapping was formalized for language agents by the [CoALA paper](https://arxiv.org/abs/2309.02427) (Cognitive Architectures for Language Agents, 2023), which most memory frameworks now use as their taxonomy. It defines three long-term stores: semantic memory as facts about the world, episodic memory as sequences of the agent's past actions and experiences, and procedural memory as skills and rules.
+
+In practice, teams use each store differently. [LangChain's memory docs](https://docs.langchain.com/oss/python/concepts/memory) note that semantic memory is most often used to personalize an app: an LLM extracts facts from a conversation, and those facts are retrieved later and inserted into the system prompt. Episodic memory is often implemented as few-shot examples, showing the agent how a similar task was handled before rather than telling it.
+
+Here's the part most people don't know. The base model already holds an enormous semantic memory of the world from its training data. It knows what a fintech is and what Python is. What it doesn't know is anything about this user, this team, or this codebase, because none of that was in training. The real gap you're filling is *personal* semantic memory, not world knowledge.
+
+| | Episodic memory | Semantic memory |
+|---|---|---|
+| Stores | Specific events, turns, tool calls, decisions | General facts and preferences |
+| Time | Timestamped and contextual | Timeless once accepted |
+| Example | "User canceled on March 4 after a price increase" | "User prefers terse answers" |
+| Typical use | Few-shot examples, incident recall | System-prompt personalization |
+| Source in an agent | Written at interaction time | Derived from episodes |
+
+## Why does the episodic vs semantic difference matter in production?
+
+Because getting it wrong is why agents forget people. LLMs are stateless. Every session starts from zero unless you build a store outside the context window.
+
+The failure is not subtle. A support agent asks a returning customer for the order number they already gave twice that week. An assistant forgets that a user said "I'm allergic to shellfish," which is the kind of fact that has to survive across every future session.
+
+The numbers back up how common this is. Salesforce AI Research's [CRMArena-Pro benchmark](https://www.salesforce.com/blog/crmarena-pro/) found generic LLM agents dropped from about 58% success on single-turn tasks to about 35% on multi-turn ones.
+
+> "A 35% success rate in multi-step workflows is a non-starter for enterprises."
+>
+> — Umang Thakur, QKS Group, [speaking to CIO](https://www.cio.com/article/4008228/salesforce-study-warns-against-rushing-llms-into-crm-workflows-without-guardrails.html)
+
+Multi-turn is exactly where memory has to do its job.
+
+Our practitioners describe three distinct ways this shows up:
+
+
+
Where it shows up
+
+- Session death — the agent starts fresh every time.
+- Compaction loss — it forgets what you told it at the start of a long session once the context window fills.
+- Cross-agent amnesia — a researcher agent and a coder agent share nothing at all.
+
+
+
+If your agent needs to remember users across sessions, this is the layer to get right. A durable store of episodes plus compiled facts is what Statewave was built to provide, so an agent stops re-asking what it already learned.
+
+## When should an agent store something as episodic vs semantic?
+
+> Store the raw event as episodic. Derive the reusable fact as semantic. Keep both.
+
+That order matters. If a user says "I prefer Python," you could write the semantic fact "user prefers Python." But if you only keep that, you lose the ability to check when it was said, what prompted it, and whether it still holds.
+
+The episodic record — "user said they prefer Python on March 4 while setting up a data pipeline" — is what lets you audit and revise the fact later. The semantic version is what you actually inject at prompt time because it's compact.
+
+So the working rule is: write episodes at interaction time with full context, and treat semantic facts as a compiled output of those episodes, each carrying a confidence score and a validity window. This keeps you out of the common trap of storing loose facts with no way to trace or expire them.
+
+## How does an agent turn episodes into semantic memory?
+
+Through consolidation, a background pass that reads raw episodes and produces typed, durable facts. In [Atlan's analysis](https://atlan.com/know/episodic-memory-ai-agents/), consolidation is called the most impactful and the least implemented stage of agent memory. It's what shrinks 200 conversation turns into a single line like "user is a senior engineer at a fintech who prefers terse responses."
+
+```
+EPISODE (raw, timestamped) SEMANTIC MEMORY (compiled)
+─────────────────────────── ──────────────────────────
+{ {
+ "at": "2026-03-04T14:02:00Z", "kind": "profile_fact",
+ "subject": "user_492", "subject": "user_492",
+ "text": "I prefer Python "fact": "prefers_language: python",
+ for data pipelines" "confidence": 0.92,
+} "valid_since": "2026-03-04",
+ "source_episode": "ep_8831"
+ }
+ └──────────────── consolidation ────────────┘
+```
+
+Two things separate a real consolidation step from a naive one.
+
+First, compaction with meaning, not truncation: you summarize into typed facts rather than dropping the oldest tokens.
+
+Second, supersession: when a user's job changes, the old "works at a fintech" fact is marked superseded, not left to be retrieved next to the new one. An append-only store with no validity model will happily serve both and let the agent contradict itself.
+
+This is the exact shape of Statewave's compile step: episodes go in, and a compilation pass produces typed memories — profile facts, preferences, and episode summaries — each with provenance back to the episodes it came from. It's the episodic-to-semantic conversion, done as infrastructure instead of ad hoc application code.
+
+## Why isn't similarity search enough to retrieve the right memory?
+
+Because the most relevant memory is often not the most similar one. Consider a user who said "I'm allergic to peanuts," then later asks "what should I order for lunch?" Those two messages don't have close embeddings, so pure cosine similarity will surface every restaurant note before the allergy. Similarity is one signal, and on its own it ranks the wrong things first.
+
+The retrieval problem is measurable. On the [Episodic Memory Benchmark](https://openreview.net/forum?id=6ycX677p2l) (ICLR 2025), which tests whether models can track how entities change over time, the best model reached only 0.290 on Chronological Awareness — under 30% on temporal sequencing. Models are weak exactly where episodic memory is supposed to be strong: knowing what happened and in what order.
+
+Good memory retrieval mixes several signals: semantic similarity, kind priority so a standing preference or procedure outranks a casual mention, recency, temporal validity so superseded facts are excluded, and a token budget so the result fits the prompt.
+
+Statewave applies these as deterministic ranking, which also means the same query returns the same context bundle every time, with no silent re-ordering between runs. If retrieval quality is where your agent breaks, that ranking model is the specific fix.
+
+## How do you keep memory trustworthy?
+
+Track where each fact came from. When an agent answers "you told me you prefer Python," you should be able to trace that claim to the exact episode that produced it.
+
+Statewave carries this as provenance: every compiled memory stores the IDs of the episodes it was derived from, so any answer is auditable back to the raw event. For anything touching support, compliance, or user data, this is the difference between a memory you can defend and one you have to trust blindly.
+
+## How should you actually build episodic and semantic memory?
+
+Match the effort to the need, and add layers only when you hit their limits.
+
+For simple cases, a disciplined file or a small facts table covers a large share of what people reach for vector databases to do. Bigger context windows aren't the answer either. Stuffing an entire history into every call raises cost and latency without solving recall, which is why the useful move is compaction, not accumulation.
+
+You need a real memory runtime once your agent has to remember users across sessions, resolve conflicting facts over time, prove where an answer came from, or share memory across several agents. At that point, the parts to build are consistent: durable episodes, a consolidation pass, ranked retrieval, invalidation, and provenance.
+
+That's the shape of Statewave. It's an open-source, Apache 2.0 memory runtime that takes in episodes and returns ranked, token-bounded context bundles with provenance, self-hosted on Postgres with pgvector so there's no separate vector database to run.
+
+One command, `npx @statewavedev/statewave`, boots the API, an admin console, and Postgres locally.
+
+Statewave, by the numbers
+
+
+
+If you want to see how the storage decisions map to Postgres, the [self-hosted Postgres and pgvector write-up](/blog/self-hosted-memory-postgres-pgvector) goes deeper.
+
+## Conclusion
+
+Episodic memory is what happened. Semantic memory is what is true. Agents need both, and the hard work is not naming them — it's the wiring between them: storing raw episodes, compiling them into typed facts, expiring facts that no longer hold, ranking retrieval by more than similarity, and keeping a trace of where each fact came from.
+
+Get that wiring right, and your agent stops re-asking for the order number, stops contradicting last week's answer, and starts behaving like it remembers people.
+
+That's the difference between a demo and a product. If you'd rather run that layer than rebuild it, read [how it compares to RAG](/blog/ai-agent-memory-vs-rag) before you commit, or:
+
+
+
+## FAQ
+
+
+
+
+
+1. What is the difference between episodic and semantic memory in AI agents?
+
+
+
+
+
Episodic memory stores specific events with time and context, like "user canceled on March 4 after a price increase." Semantic memory stores general, reusable facts, like "user prefers terse answers." Agents write episodes at interaction time and derive semantic facts from them.
+
+
+
+
+
+2. Is episodic or semantic memory better for AI agents?
+
+
+
+
+
Neither. They do different jobs, and most production agents need both. Episodic memory handles recall of past interactions and few-shot examples. Semantic memory handles personalization by injecting compact facts into the prompt. The skill is deciding what to store as which, then converting between them.
+
+
+
+
+
+3. What is memory consolidation in AI agents?
+
+
+
+
+
Consolidation is a background pass that reads raw episodes and produces durable semantic facts, shrinking 200 conversation turns into one line like "senior engineer at a fintech, prefers terse responses." Atlan calls it the most impactful and least implemented stage of agent memory.
+
+
+
+
+
+4. Where does procedural memory fit alongside episodic and semantic?
+
+
+
+
+
Procedural memory holds skills and rules for how to do a task, separate from facts (semantic) and events (episodic). The CoALA framework defines all three as long-term stores. In agents, procedural memory often lives in reusable instructions or guidelines the agent follows.
+
+
+
+
+
+5. Why do AI agents forget things between sessions?
+
+
+
+
+
LLMs are stateless, so every session starts from zero unless you store memory outside the context window. On Salesforce's CRMArena-Pro benchmark, agent success dropped from about 58% on single-turn tasks to about 35% on multi-turn ones, with lost context a leading cause.
+
+
+
+
+
+6. Isn't a bigger context window enough to replace agent memory?
+
+
+
+
+
No. Putting an entire history into every call raises cost and latency without fixing recall, and models still struggle with order and time. The better approach is compaction: store episodes, compile them into typed facts, and retrieve only what fits the prompt.
+
+
+
+
diff --git a/src/content/blog/persistent-memory-for-ai-support-agents.mdx b/src/content/blog/persistent-memory-for-ai-support-agents.mdx
index affd1ef..a484a0f 100644
--- a/src/content/blog/persistent-memory-for-ai-support-agents.mdx
+++ b/src/content/blog/persistent-memory-for-ai-support-agents.mdx
@@ -10,7 +10,9 @@ tags:
- memory
---
-Support is the workload where missing memory hurts most. A customer who told you yesterday that their pipeline runs on Snowflake shouldn't have to say it again today. A subscription user shouldn't have to re-explain their plan tier to every new agent. And the agent shouldn't be guessing — it should be able to *cite* where it learned each fact.
+Support is the workload where missing memory hurts most. A customer who told you yesterday that their pipeline runs on Snowflake shouldn't have to say it again today. A subscription user shouldn't have to re-explain their plan tier to every new agent.
+
+> The agent shouldn't be guessing — it should be able to *cite* where it learned each fact.
This post walks through giving a support agent persistent customer memory with Statewave. It's about 30 minutes of work end-to-end, and the result is an agent that remembers across sessions with the same audit trail a human support engineer would leave.
@@ -94,7 +96,7 @@ about this customer when relevant:
Cite the source episode IDs above when you reference a remembered fact.
```
-That `Cite the source episode IDs` instruction is what turns the agent from "AI that confidently makes things up" into one that points at receipts.
+> That `Cite the source episode IDs` instruction is what turns the agent from "AI that confidently makes things up" into one that points at receipts.
## What the benchmark measures
@@ -115,8 +117,14 @@ A naive prompt-stuffing baseline (concatenate the last N turns) scores 2/8. A St
A few things the memory layer deliberately doesn't do:
-- **It doesn't replace your knowledge base.** Product docs, runbooks, troubleshooting articles still belong in your RAG stack. Statewave handles the *who you're talking to* layer, not the *what does the documentation say* layer.
-- **It doesn't make personally identifying information safe by itself.** Storage encryption, access control, retention policies, GDPR / CCPA flows are your platform's job. Statewave gives you the substrate; the policy is yours.
-- **It doesn't ship a routing engine.** Statewave returns ranked context. Deciding whether to escalate, hand off to a human, or close the ticket is your application logic.
+What this doesn't solve
+
+
+
+- It doesn't replace your knowledge base. Product docs, runbooks, troubleshooting articles still belong in your RAG stack. Statewave handles the *who you're talking to* layer, not the *what does the documentation say* layer.
+- It doesn't make personally identifying information safe by itself. Storage encryption, access control, retention policies, GDPR / CCPA flows are your platform's job. Statewave gives you the substrate; the policy is yours.
+- It doesn't ship a routing engine. Statewave returns ranked context. Deciding whether to escalate, hand off to a human, or close the ticket is your application logic.
+
+
What it does ship is a memory layer that doesn't forget, with an audit trail you can show to a human reviewer or a compliance auditor. For a support agent, that's the difference between a demo and a deployment.
diff --git a/src/content/blog/self-hosted-memory-postgres-pgvector.mdx b/src/content/blog/self-hosted-memory-postgres-pgvector.mdx
index 1e9aeea..7aab251 100644
--- a/src/content/blog/self-hosted-memory-postgres-pgvector.mdx
+++ b/src/content/blog/self-hosted-memory-postgres-pgvector.mdx
@@ -21,10 +21,20 @@ pgvector is a Postgres extension that adds a `vector(N)` column type, ANN indexe
The honest tradeoff with pgvector versus a purpose-built vector DB (Pinecone, Weaviate, Milvus, Qdrant):
-- **You give up**: marginal recall-vs-latency on extreme corpora (>50M vectors / sub-millisecond p99 SLAs), some advanced filtering optimizations, the vendor's prebuilt management UI.
-- **You get**: one durable substrate, transactional consistency between embeddings and the rows they describe, the entire Postgres operational toolkit (PITR, replicas, pgbouncer, observability), no second source of truth to keep in sync.
+The honest tradeoff
-For a memory runtime, the transactional consistency is the win. When a compiled memory references its source episodes, you want that reference to be enforceable as a foreign key, not a "best-effort soft pointer maintained by application code." With pgvector, it just is.
+
+
+- You give up — marginal recall-vs-latency on extreme corpora (>50M vectors / sub-millisecond p99 SLAs), some advanced filtering optimizations, the vendor's prebuilt management UI.
+- You get — one durable substrate, transactional consistency between embeddings and the rows they describe, the entire Postgres operational toolkit (PITR, replicas, pgbouncer, observability), no second source of truth to keep in sync.
+
+
+
+For a memory runtime, the transactional consistency is the win.
+
+> When a compiled memory references its source episodes, you want that reference to be enforceable as a foreign key, not a "best-effort soft pointer maintained by application code."
+
+With pgvector, it just is.
## Why one database
@@ -68,4 +78,6 @@ Apache-2.0 server, Apache-2.0 SDKs, Apache-2.0 connectors. No "community edition
What we offer commercially, separate from the code: SLA, indemnity, architecture review, managed hosting if you want us to operate Postgres-plus-Statewave for you. None of that gates features in the open source. If you can run Postgres, you can run Statewave forever, for free, with the same code we'd run for an enterprise customer.
-That's the deal — Postgres-only, transactional consistency, no managed-cloud lock-in. The trade is real (we're not the world's fastest vector recall) and we think it's the right one for a memory layer where the audit trail matters more than the marginal millisecond.
+> That's the deal — Postgres-only, transactional consistency, no managed-cloud lock-in.
+
+The trade is real (we're not the world's fastest vector recall) and we think it's the right one for a memory layer where the audit trail matters more than the marginal millisecond.
diff --git a/src/index.css b/src/index.css
index b5eae98..6e99659 100644
--- a/src/index.css
+++ b/src/index.css
@@ -784,6 +784,24 @@ html[data-theme="dark"] .connector-logo-black {
border: 0;
}
+/* Collapsible FAQ entries inside blog post MDX content — mirrors the
+ home page's / FAQ (HomePage.tsx FAQSection), but that
+ one uses Tailwind's `group-open:` variant, which needs a literal
+ `group` class on the ancestor. Blog posts are hand-authored MDX, so a
+ plain CSS rule keyed off :where([open]) is more robust than asking every
+ post author to remember the `group` class. */
+.blog-faq summary::-webkit-details-marker {
+ display: none;
+}
+
+.blog-faq-chevron {
+ transition: transform 0.2s ease;
+}
+
+.blog-faq:where([open]) .blog-faq-chevron {
+ transform: rotate(180deg);
+}
+
/* ==========================================================================
Product page
========================================================================== */