@byline/admin 4.15.0 → 4.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abilities.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/modules/analytics/abilities.d.ts +14 -0
- package/dist/modules/analytics/abilities.js +21 -0
- package/dist/modules/analytics/components/dashboard.d.ts +20 -0
- package/dist/modules/analytics/components/dashboard.js +308 -0
- package/dist/modules/analytics/components/dashboard.module.js +29 -0
- package/dist/modules/analytics/components/dashboard.test.node.d.ts +8 -0
- package/dist/modules/analytics/components/dashboard_module.css +268 -0
- package/dist/modules/analytics/components/timeseries.d.ts +59 -0
- package/dist/modules/analytics/components/timeseries.js +253 -0
- package/dist/modules/analytics/components/timeseries.module.js +17 -0
- package/dist/modules/analytics/components/timeseries_module.css +126 -0
- package/dist/modules/analytics/index.d.ts +9 -0
- package/dist/modules/analytics/index.js +1 -0
- package/dist/modules/analytics/types.d.ts +20 -0
- package/dist/modules/analytics/types.js +1 -0
- package/package.json +17 -5
- package/src/abilities.ts +2 -0
- package/src/index.ts +1 -0
- package/src/modules/analytics/abilities.ts +33 -0
- package/src/modules/analytics/components/dashboard.module.css +330 -0
- package/src/modules/analytics/components/dashboard.test.node.ts +193 -0
- package/src/modules/analytics/components/dashboard.tsx +371 -0
- package/src/modules/analytics/components/timeseries.module.css +151 -0
- package/src/modules/analytics/components/timeseries.tsx +332 -0
- package/src/modules/analytics/index.ts +14 -0
- package/src/modules/analytics/types.ts +31 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
.root-L2qL4D {
|
|
2
|
+
border-radius: .25rem;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: .5rem;
|
|
5
|
+
display: flex;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.root-L2qL4D:focus-visible {
|
|
9
|
+
outline: 2px solid var(--primary-500);
|
|
10
|
+
outline-offset: 4px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:is(.chart-giYTrx, .byline-analytics-chart) {
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 11rem;
|
|
16
|
+
display: block;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.gridline-R_wAwP {
|
|
20
|
+
stroke: var(--gray-200);
|
|
21
|
+
stroke-width: 1px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.column-_Cw2Ua {
|
|
25
|
+
transition: opacity .12s;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.views-WHbm44 {
|
|
29
|
+
fill: #38bdf8;
|
|
30
|
+
opacity: .38;
|
|
31
|
+
transition: opacity .12s;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.columnActive-CwHwbo .views-WHbm44 {
|
|
35
|
+
opacity: .62;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.visitors-n6IL4B {
|
|
39
|
+
fill: #7c3aed;
|
|
40
|
+
opacity: .95;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.hit-ZxDHvk {
|
|
44
|
+
fill: #0000;
|
|
45
|
+
cursor: crosshair;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:is(.axis-fBshTw, .byline-analytics-axis) {
|
|
49
|
+
font-variant-numeric: tabular-nums;
|
|
50
|
+
letter-spacing: .04em;
|
|
51
|
+
color: var(--gray-500);
|
|
52
|
+
justify-content: space-between;
|
|
53
|
+
font-size: .6875rem;
|
|
54
|
+
display: flex;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
:is(.readout-L9jEpz, .byline-analytics-readout) {
|
|
58
|
+
font-variant-numeric: tabular-nums;
|
|
59
|
+
min-height: 1.25rem;
|
|
60
|
+
color: var(--gray-500);
|
|
61
|
+
flex-wrap: wrap;
|
|
62
|
+
align-items: center;
|
|
63
|
+
gap: .35rem .75rem;
|
|
64
|
+
margin: 0;
|
|
65
|
+
font-size: .75rem;
|
|
66
|
+
display: flex;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.readout-L9jEpz strong {
|
|
70
|
+
color: inherit;
|
|
71
|
+
font-weight: 600;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.swatchViews-OCeKNe, .swatchVisitors-O3BWz6, .swatchDownloads-SVo9mN {
|
|
75
|
+
border-radius: 1px;
|
|
76
|
+
width: .5rem;
|
|
77
|
+
height: .5rem;
|
|
78
|
+
margin-inline: .4rem -.4rem;
|
|
79
|
+
display: inline-block;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.swatchViews-OCeKNe {
|
|
83
|
+
opacity: .55;
|
|
84
|
+
background-color: #38bdf8;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.swatchVisitors-O3BWz6 {
|
|
88
|
+
background-color: #7c3aed;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.swatchDownloads-SVo9mN {
|
|
92
|
+
background-color: #10b981;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
:is([data-theme="dark"], .dark) .gridline-R_wAwP {
|
|
96
|
+
stroke: var(--gray-700);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
:is(:is([data-theme="dark"], .dark) .axis-fBshTw, :is([data-theme="dark"], .dark) .byline-analytics-axis, :is([data-theme="dark"], .dark) .readout-L9jEpz, :is([data-theme="dark"], .dark) .byline-analytics-readout) {
|
|
100
|
+
color: var(--gray-400);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
:is([data-theme="dark"], .dark) .visitors-n6IL4B {
|
|
104
|
+
fill: #a78bfa;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
:is([data-theme="dark"], .dark) .swatchVisitors-O3BWz6 {
|
|
108
|
+
background-color: #a78bfa;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
:is([data-theme="dark"], .dark) .swatchDownloads-SVo9mN {
|
|
112
|
+
background-color: #34d399;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
.column-_Cw2Ua, .views-WHbm44 {
|
|
117
|
+
transition: none;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@media (max-width: 720px) {
|
|
122
|
+
:is(.chart-giYTrx, .byline-analytics-chart) {
|
|
123
|
+
height: 9rem;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
export { ANALYTICS_ABILITIES, type AnalyticsAbilityKey, registerAnalyticsAbilities, } from './abilities.js';
|
|
9
|
+
export type { AnalyticsDashboardData, AnalyticsDashboardPeriod } from './types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ANALYTICS_ABILITIES, registerAnalyticsAbilities } from "./abilities.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
import type { AnalyticsCountryTotal, AnalyticsDateRange, AnalyticsPathTotal, AnalyticsRankedTotals, AnalyticsReferrerTotal, AnalyticsReportCoverage, AnalyticsSummary } from '@byline/analytics';
|
|
9
|
+
import type { AnalyticsDashboardPeriod as PortableAnalyticsDashboardPeriod } from '@byline/analytics/config';
|
|
10
|
+
export type AnalyticsDashboardPeriod = PortableAnalyticsDashboardPeriod;
|
|
11
|
+
export interface AnalyticsDashboardData {
|
|
12
|
+
range: AnalyticsDateRange;
|
|
13
|
+
coverage: AnalyticsReportCoverage;
|
|
14
|
+
summary: AnalyticsSummary;
|
|
15
|
+
pages: AnalyticsRankedTotals<AnalyticsPathTotal>;
|
|
16
|
+
downloads: AnalyticsRankedTotals<AnalyticsPathTotal>;
|
|
17
|
+
referrers: AnalyticsRankedTotals<AnalyticsReferrerTotal>;
|
|
18
|
+
/** Countries are unbounded by a top-N limit, so there is nothing to truncate. */
|
|
19
|
+
countries: AnalyticsCountryTotal[];
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/admin",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.16.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -77,6 +77,16 @@
|
|
|
77
77
|
"import": "./dist/modules/admin-preferences/index.js",
|
|
78
78
|
"require": "./dist/modules/admin-preferences/index.js"
|
|
79
79
|
},
|
|
80
|
+
"./analytics": {
|
|
81
|
+
"types": "./dist/modules/analytics/index.d.ts",
|
|
82
|
+
"import": "./dist/modules/analytics/index.js",
|
|
83
|
+
"require": "./dist/modules/analytics/index.js"
|
|
84
|
+
},
|
|
85
|
+
"./analytics/components/dashboard": {
|
|
86
|
+
"types": "./dist/modules/analytics/components/dashboard.d.ts",
|
|
87
|
+
"import": "./dist/modules/analytics/components/dashboard.js",
|
|
88
|
+
"require": "./dist/modules/analytics/components/dashboard.js"
|
|
89
|
+
},
|
|
80
90
|
"./services": {
|
|
81
91
|
"types": "./dist/services/admin-services-context.d.ts",
|
|
82
92
|
"import": "./dist/services/admin-services-context.js",
|
|
@@ -173,10 +183,12 @@
|
|
|
173
183
|
"react-diff-viewer-continued": "^4.4.0",
|
|
174
184
|
"uuid": "^14.0.2",
|
|
175
185
|
"zod": "^4.4.3",
|
|
176
|
-
"@byline/
|
|
177
|
-
"@byline/
|
|
178
|
-
"@byline/
|
|
179
|
-
"@byline/
|
|
186
|
+
"@byline/analytics": "4.16.0",
|
|
187
|
+
"@byline/i18n": "4.16.0",
|
|
188
|
+
"@byline/core": "4.16.0",
|
|
189
|
+
"@byline/ui": "4.16.0",
|
|
190
|
+
"@byline/auth": "4.16.0",
|
|
191
|
+
"@byline/analytics-agent": "4.16.0"
|
|
180
192
|
},
|
|
181
193
|
"peerDependencies": {
|
|
182
194
|
"react": "^19.0.0",
|
package/src/abilities.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { registerAdminActivityAbilities } from './modules/admin-activity/abiliti
|
|
|
12
12
|
import { registerAdminPermissionsAbilities } from './modules/admin-permissions/abilities.js'
|
|
13
13
|
import { registerAdminRolesAbilities } from './modules/admin-roles/abilities.js'
|
|
14
14
|
import { registerAdminUsersAbilities } from './modules/admin-users/abilities.js'
|
|
15
|
+
import { registerAnalyticsAbilities } from './modules/analytics/abilities.js'
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Register every ability contributed by the admin subsystem.
|
|
@@ -30,5 +31,6 @@ export function registerAdminAbilities(registry: AbilityRegistry): void {
|
|
|
30
31
|
registerAdminRolesAbilities(registry)
|
|
31
32
|
registerAdminPermissionsAbilities(registry)
|
|
32
33
|
registerAdminActivityAbilities(registry)
|
|
34
|
+
registerAnalyticsAbilities(registry)
|
|
33
35
|
// registerAccountAbilities(registry) — added when that module lands
|
|
34
36
|
}
|
package/src/index.ts
CHANGED
|
@@ -36,5 +36,6 @@ export * from './modules/admin-activity/index.js'
|
|
|
36
36
|
export * from './modules/admin-permissions/index.js'
|
|
37
37
|
export * from './modules/admin-roles/index.js'
|
|
38
38
|
export * from './modules/admin-users/index.js'
|
|
39
|
+
export * from './modules/analytics/index.js'
|
|
39
40
|
export * from './modules/auth/index.js'
|
|
40
41
|
export type { AdminStore } from './store.js'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { AbilityRegistry } from '@byline/auth'
|
|
10
|
+
|
|
11
|
+
export const ANALYTICS_ABILITIES = {
|
|
12
|
+
read: 'analytics.read',
|
|
13
|
+
maintain: 'analytics.maintain',
|
|
14
|
+
} as const
|
|
15
|
+
|
|
16
|
+
export type AnalyticsAbilityKey = (typeof ANALYTICS_ABILITIES)[keyof typeof ANALYTICS_ABILITIES]
|
|
17
|
+
|
|
18
|
+
export function registerAnalyticsAbilities(registry: AbilityRegistry): void {
|
|
19
|
+
registry.register({
|
|
20
|
+
key: ANALYTICS_ABILITIES.read,
|
|
21
|
+
label: 'Read analytics',
|
|
22
|
+
description: 'View installation-level page, visitor, download, referrer, and country totals.',
|
|
23
|
+
group: 'analytics',
|
|
24
|
+
source: 'admin',
|
|
25
|
+
})
|
|
26
|
+
registry.register({
|
|
27
|
+
key: ANALYTICS_ABILITIES.maintain,
|
|
28
|
+
label: 'Maintain analytics',
|
|
29
|
+
description: 'Delete retained analytics events and rebuild affected daily aggregates.',
|
|
30
|
+
group: 'analytics',
|
|
31
|
+
source: 'admin',
|
|
32
|
+
})
|
|
33
|
+
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnalyticsDashboard — the installation-level analytics page.
|
|
3
|
+
*
|
|
4
|
+
* Override handles:
|
|
5
|
+
* .byline-analytics-header — title block and period/exclusion controls
|
|
6
|
+
* .byline-analytics-title — page heading
|
|
7
|
+
* .byline-analytics-help — the daily-uniques qualification
|
|
8
|
+
* .byline-analytics-controls — period picker + exclusion toggle
|
|
9
|
+
* .byline-analytics-stats — the three metric tiles
|
|
10
|
+
* .byline-analytics-stat — one tile
|
|
11
|
+
* .byline-analytics-stat-label — tracked uppercase metric name
|
|
12
|
+
* .byline-analytics-stat-value — the figure
|
|
13
|
+
* .byline-analytics-stat-foot — the figure's qualification
|
|
14
|
+
* .byline-analytics-chart-card — card wrapping the timeseries
|
|
15
|
+
* .byline-analytics-lists — top-pages / referrers+countries band
|
|
16
|
+
* .byline-analytics-list — one ranked-list card
|
|
17
|
+
* .byline-analytics-ranking — the ordered list
|
|
18
|
+
* .byline-analytics-ranking-row — one row, carrying its share bar
|
|
19
|
+
*
|
|
20
|
+
* The tile hues are the collection dashboard's status-tile values
|
|
21
|
+
* (`byline-dashboard-stat-tile`), so the two surfaces read as one system.
|
|
22
|
+
* Amber is deliberately unused here: it already means "draft".
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
.header,
|
|
26
|
+
:global(.byline-analytics-header) {
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: flex-end;
|
|
29
|
+
justify-content: space-between;
|
|
30
|
+
gap: 1rem 1.5rem;
|
|
31
|
+
flex-wrap: wrap;
|
|
32
|
+
margin-bottom: 1.25rem;
|
|
33
|
+
padding-bottom: 1rem;
|
|
34
|
+
border-bottom: var(--border-width-thin) var(--border-style-solid) var(--gray-200);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.title,
|
|
38
|
+
:global(.byline-analytics-title) {
|
|
39
|
+
margin: 0;
|
|
40
|
+
font-size: 1.875rem;
|
|
41
|
+
font-weight: 650;
|
|
42
|
+
letter-spacing: -0.02em;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.help,
|
|
46
|
+
:global(.byline-analytics-help) {
|
|
47
|
+
max-width: 48ch;
|
|
48
|
+
margin: 0.35rem 0 0;
|
|
49
|
+
font-size: 0.8125rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* `Card.Title` defaults to 1.8rem bold — larger than this page's own heading,
|
|
53
|
+
which inverted the hierarchy. Bring the section titles below the h1 while
|
|
54
|
+
keeping them clearly headings. Scoped to the analytics cards so no other
|
|
55
|
+
Card consumer shifts. */
|
|
56
|
+
.chartCard :global(.byline-card-title),
|
|
57
|
+
.list :global(.byline-card-title) {
|
|
58
|
+
font-size: 1.25rem;
|
|
59
|
+
font-weight: 600;
|
|
60
|
+
letter-spacing: normal;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.chartCard :global(.byline-card-description),
|
|
64
|
+
.list :global(.byline-card-description) {
|
|
65
|
+
font-size: 0.75rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.controls,
|
|
69
|
+
:global(.byline-analytics-controls) {
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
gap: 0.75rem;
|
|
73
|
+
flex-wrap: wrap;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ── Metric tiles ──────────────────────────────────────────────────── */
|
|
77
|
+
|
|
78
|
+
.stats,
|
|
79
|
+
:global(.byline-analytics-stats) {
|
|
80
|
+
display: grid;
|
|
81
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
82
|
+
gap: 0.75rem;
|
|
83
|
+
margin-bottom: 0.75rem;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.stat,
|
|
87
|
+
:global(.byline-analytics-stat) {
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
gap: 0.5rem;
|
|
91
|
+
min-width: 0;
|
|
92
|
+
padding: 1rem 1.125rem 1.125rem;
|
|
93
|
+
border-radius: 0.375rem;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.statLabel,
|
|
97
|
+
:global(.byline-analytics-stat-label) {
|
|
98
|
+
font-size: 0.625rem;
|
|
99
|
+
font-weight: 600;
|
|
100
|
+
text-transform: uppercase;
|
|
101
|
+
letter-spacing: 0.1em;
|
|
102
|
+
line-height: 1;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.statValue,
|
|
106
|
+
:global(.byline-analytics-stat-value) {
|
|
107
|
+
font-size: clamp(1.75rem, 4.5vw, 2.5rem);
|
|
108
|
+
font-weight: 700;
|
|
109
|
+
font-variant-numeric: tabular-nums;
|
|
110
|
+
line-height: 1;
|
|
111
|
+
letter-spacing: -0.02em;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.statFoot,
|
|
115
|
+
:global(.byline-analytics-stat-foot) {
|
|
116
|
+
font-size: 0.6875rem;
|
|
117
|
+
font-variant-numeric: tabular-nums;
|
|
118
|
+
color: var(--gray-600);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.toneViews {
|
|
122
|
+
background-color: #f0f9ff;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.toneViews .statLabel,
|
|
126
|
+
.toneViews .statValue {
|
|
127
|
+
color: #0369a1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.toneVisitors {
|
|
131
|
+
background-color: #f5f3ff;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.toneVisitors .statLabel,
|
|
135
|
+
.toneVisitors .statValue {
|
|
136
|
+
color: #6d28d9;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.toneDownloads {
|
|
140
|
+
background-color: #ecfdf5;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.toneDownloads .statLabel,
|
|
144
|
+
.toneDownloads .statValue {
|
|
145
|
+
color: #047857;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:is([data-theme="dark"], :global(.dark)) .statFoot,
|
|
149
|
+
:is([data-theme="dark"], :global(.dark)) :global(.byline-analytics-stat-foot) {
|
|
150
|
+
color: var(--gray-400);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
:is([data-theme="dark"], :global(.dark)) .toneViews {
|
|
154
|
+
background-color: rgba(12, 74, 110, 0.28);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
:is([data-theme="dark"], :global(.dark)) .toneViews .statLabel,
|
|
158
|
+
:is([data-theme="dark"], :global(.dark)) .toneViews .statValue {
|
|
159
|
+
color: #7dd3fc;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
:is([data-theme="dark"], :global(.dark)) .toneVisitors {
|
|
163
|
+
background-color: rgba(76, 29, 149, 0.3);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
:is([data-theme="dark"], :global(.dark)) .toneVisitors .statLabel,
|
|
167
|
+
:is([data-theme="dark"], :global(.dark)) .toneVisitors .statValue {
|
|
168
|
+
color: #c4b5fd;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
:is([data-theme="dark"], :global(.dark)) .toneDownloads {
|
|
172
|
+
background-color: rgba(6, 78, 59, 0.28);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
:is([data-theme="dark"], :global(.dark)) .toneDownloads .statLabel,
|
|
176
|
+
:is([data-theme="dark"], :global(.dark)) .toneDownloads .statValue {
|
|
177
|
+
color: #6ee7b7;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* ── Lists ─────────────────────────────────────────────────────────── */
|
|
181
|
+
|
|
182
|
+
.chartCard,
|
|
183
|
+
:global(.byline-analytics-chart-card) {
|
|
184
|
+
margin-bottom: 0.75rem;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Top pages is the list people actually read, so it takes the wide track. */
|
|
188
|
+
.lists,
|
|
189
|
+
:global(.byline-analytics-lists) {
|
|
190
|
+
display: grid;
|
|
191
|
+
grid-template-columns: 1.55fr 1fr;
|
|
192
|
+
align-items: start;
|
|
193
|
+
gap: 0.75rem;
|
|
194
|
+
margin-bottom: 0.75rem;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.stack {
|
|
198
|
+
display: flex;
|
|
199
|
+
flex-direction: column;
|
|
200
|
+
gap: 0.75rem;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.ranking,
|
|
204
|
+
:global(.byline-analytics-ranking) {
|
|
205
|
+
display: flex;
|
|
206
|
+
flex-direction: column;
|
|
207
|
+
gap: 1px;
|
|
208
|
+
padding: 0;
|
|
209
|
+
margin: 0;
|
|
210
|
+
list-style: none;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.rankingRow,
|
|
214
|
+
:global(.byline-analytics-ranking-row) {
|
|
215
|
+
position: relative;
|
|
216
|
+
display: grid;
|
|
217
|
+
grid-template-columns: minmax(0, 1fr) auto auto;
|
|
218
|
+
align-items: center;
|
|
219
|
+
gap: 0.75rem;
|
|
220
|
+
padding: 0.45rem 0.625rem;
|
|
221
|
+
border-radius: 0.25rem;
|
|
222
|
+
/* The row paints its own stacking context so the share bar can sit behind
|
|
223
|
+
the text without escaping to the card background. */
|
|
224
|
+
isolation: isolate;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.rankingRow::before {
|
|
228
|
+
content: "";
|
|
229
|
+
position: absolute;
|
|
230
|
+
inset: 0 auto 0 0;
|
|
231
|
+
z-index: -1;
|
|
232
|
+
width: var(--byline-analytics-share, 0%);
|
|
233
|
+
border-radius: 0.25rem;
|
|
234
|
+
background-color: var(--byline-analytics-bar, transparent);
|
|
235
|
+
opacity: 0.16;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.barViews {
|
|
239
|
+
--byline-analytics-bar: #38bdf8;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.barVisitors {
|
|
243
|
+
--byline-analytics-bar: #7c3aed;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.barDownloads {
|
|
247
|
+
--byline-analytics-bar: #10b981;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* The reserved overflow bucket is an aggregate, not a page — a dashed rule
|
|
251
|
+
and muted label keep it from reading as traffic to a real path. */
|
|
252
|
+
.rankingOverflow {
|
|
253
|
+
border: var(--border-width-thin) dashed var(--gray-300);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.rankingOverflow::before {
|
|
257
|
+
opacity: 0.07;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.rankingOverflow .rankingLabel {
|
|
261
|
+
font-style: italic;
|
|
262
|
+
color: var(--gray-600);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.rankingLabel {
|
|
266
|
+
overflow: hidden;
|
|
267
|
+
min-width: 0;
|
|
268
|
+
font-size: 0.8125rem;
|
|
269
|
+
text-overflow: ellipsis;
|
|
270
|
+
white-space: nowrap;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.rankingValue {
|
|
274
|
+
font-size: 0.8125rem;
|
|
275
|
+
font-weight: 600;
|
|
276
|
+
font-variant-numeric: tabular-nums;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.rankingVisitors {
|
|
280
|
+
min-width: 3ch;
|
|
281
|
+
font-size: 0.6875rem;
|
|
282
|
+
font-variant-numeric: tabular-nums;
|
|
283
|
+
text-align: end;
|
|
284
|
+
color: var(--gray-500);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
:is([data-theme="dark"], :global(.dark)) .header,
|
|
288
|
+
:is([data-theme="dark"], :global(.dark)) :global(.byline-analytics-header) {
|
|
289
|
+
border-bottom-color: var(--gray-700);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
:is([data-theme="dark"], :global(.dark)) .rankingVisitors {
|
|
293
|
+
color: var(--gray-400);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
:is([data-theme="dark"], :global(.dark)) .rankingOverflow {
|
|
297
|
+
border-color: var(--gray-600);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
:is([data-theme="dark"], :global(.dark)) .rankingOverflow .rankingLabel {
|
|
301
|
+
color: var(--gray-400);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
:is([data-theme="dark"], :global(.dark)) .barVisitors {
|
|
305
|
+
--byline-analytics-bar: #a78bfa;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
:is([data-theme="dark"], :global(.dark)) .barDownloads {
|
|
309
|
+
--byline-analytics-bar: #34d399;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
@media (max-width: 900px) {
|
|
313
|
+
.lists,
|
|
314
|
+
:global(.byline-analytics-lists) {
|
|
315
|
+
grid-template-columns: 1fr;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
@media (max-width: 720px) {
|
|
320
|
+
.header,
|
|
321
|
+
:global(.byline-analytics-header) {
|
|
322
|
+
align-items: stretch;
|
|
323
|
+
flex-direction: column;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.stats,
|
|
327
|
+
:global(.byline-analytics-stats) {
|
|
328
|
+
grid-template-columns: 1fr;
|
|
329
|
+
}
|
|
330
|
+
}
|