diff --git a/CLAUDE.md b/CLAUDE.md
index bfe381d..eff0e13 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -485,6 +485,11 @@ section.
what the columns below show, the breakdowns are ranked bars, the devices
one bar of shares; every chart has its values as a table one click away.
It does not poll - it reads again when the page is looked at again.
+- **The breakdowns are grouped by what they count - decided by the owner.**
+ Page views (pages, sites, countries, devices, browsers, systems) under one
+ heading, requests (what was requested, crawlers) under another: the two can
+ be far apart, and a card counting one beside a card counting the other
+ read as figures that did not add up.
- This is said in the README (Analytics), `/docs` (Who visits it),
`platform_guide` (`analytics`), the tool's description and the privacy
page - keep them the same.
diff --git a/README.md b/README.md
index 66642ae..850b811 100644
--- a/README.md
+++ b/README.md
@@ -839,6 +839,13 @@ feature's preview.
believed from an agent that is Chromium's, and only where they name a
browser or system that is known, so nobody writes words of their own into
an owner's figures (`VisitorClassifier`).
+- **Two groups in the editor, by what they count.** The pages, the referring
+ sites, the countries, the devices, the browsers and the systems are counted
+ in page views, under that heading; what was requested by path and the
+ crawlers in requests, under theirs. The two can be far apart - a crawler
+ asks for a hundred things that are no page - so a card never leaves the
+ reader to guess which it is. A lambda without pages people open has the
+ requests group only.
- **Crawlers, hardened.** A program is told from a person by
[crawler-user-agents](https://github.com/monperrus/crawler-user-agents)
(MIT, `Resources/Crawlers`), a maintained list of about 1,500 crawlers with a
diff --git a/src/Frontend/src/control/AnalyticsTab.tsx b/src/Frontend/src/control/AnalyticsTab.tsx
index ff76a0d..e269f9f 100644
--- a/src/Frontend/src/control/AnalyticsTab.tsx
+++ b/src/Frontend/src/control/AnalyticsTab.tsx
@@ -190,35 +190,64 @@ export function AnalyticsTab({ control }: { control: Control }) {
-
-
- p[by] > 0)}
- by={by}
- mono
- name={(value) => (value === '(other)' ? said.other : value)}
- />
-
+ {/*
+ * In two groups by what their numbers count, since the two can be far
+ * apart: a person opens a page and it loads a dozen things, a crawler
+ * asks for a hundred that are no page at all. An app that has no pages
+ * people open is described by its requests alone.
+ */}
+ {by === 'views' && (
+
+
+ p.views > 0)}
+ by="views"
+ mono
+ name={(value) => (value === '(other)' ? said.other : value)}
+ />
+
+
+
+ r.views > 0)}
+ by="views"
+ name={(value) => (value === '(other)' ? said.other : value)}
+ icon={}
+ rest={{ label: said.direct, value: Math.max(0, state.totals.views - sum(state.referrers, 'views')) }}
+ />
+
-
- r[by] > 0)}
- by={by}
- name={(value) => (value === '(other)' ? said.other : value)}
- icon={}
- rest={by === 'views' ? { label: said.direct, value: Math.max(0, state.totals.views - sum(state.referrers, 'views')) } : undefined}
- />
-
+
+ c.views > 0)} by="views" tag={tag} />
+
-
- c[by] > 0)} by={by} tag={tag} />
-
+
+
+ )}
-
-
+
+
+ (value === '(other)' ? said.other : value)} />
-
+ {by === 'hits' && (
+ <>
+
+ (value === '(other)' ? said.other : value)}
+ icon={}
+ />
+
+
+
+
+
+
+
+ >
+ )}
{(state.crawlers ?? []).length === 0 ? (
@@ -227,7 +256,7 @@ export function AnalyticsTab({ control }: { control: Control }) {
} />
)}
-