PageSourceSearch

https://cssradar.com/privacy.html

html cssradar.com collected 2026-10-08 13:22:42 UTC 15,236 bytes, 380 lines download raw bytes

1<!doctype html>
2<html lang="en">
3	<head>
4		<meta charset="utf-8" />
5		<meta name="viewport" content="width=device-width, initial-scale=1" />
6		<title>Privacy and data use | CSS Radar</title>
7		<meta
8			name="description"
9			content="How CSS Radar handles submitted URLs, report email addresses, temporary audit records, public report links, and landing-page analytics."
10		/>
11		<link rel="icon" type="image/svg+xml" href="favicon.svg" />
12		<link rel="canonical" href="https://cssradar.com/privacy.html" />
13		<link rel="alternate" type="application/rss+xml" title="CSS Radar articles" href="https://cssradar.com/feed.xml" />
14
15		<!-- Open Graph -->
16		<meta property="og:type" content="article" />
17		<meta property="og:site_name" content="Modern CSS Radar" />
18		<meta property="og:title" content="Privacy and data use | CSS Radar" />
19		<meta
20			property="og:description"
21			content="How CSS Radar handles submitted URLs, report email addresses, temporary audit records, public report links, and landing-page analytics."
22		/>
23		<meta property="og:url" content="https://cssradar.com/privacy.html" />
24		<meta property="og:image" content="https://cssradar.com/assets/og.png" />
25		<meta property="og:image:width" content="1200" />
26		<meta property="og:image:height" content="630" />
27		<meta property="og:image:alt" content="Modern CSS Radar: audit one page, ship less custom code." />
28		<meta property="og:locale" content="en_US" />
29
30		<!-- X / Twitter card -->
31		<meta name="twitter:card" content="summary_large_image" />
32		<meta name="twitter:title" content="Privacy and data use | CSS Radar" />
33		<meta
34			name="twitter:description"
35			content="How CSS Radar handles submitted URLs, report email addresses, temporary audit records, public report links, and landing-page analytics."
36		/>
37		<meta name="twitter:image" content="https://cssradar.com/assets/og.png" />
38		<meta name="twitter:image:alt" content="Modern CSS Radar: audit one page, ship less custom code." />
39
40		
40<script>
41			try {
42				const requestedTheme = new URLSearchParams(window.location.search).get('theme');
43				const storedTheme = window.localStorage.getItem('css-radar-theme');
44				const initialTheme = ['light', 'dark'].includes(requestedTheme)
45					? requestedTheme
46					: ['light', 'dark'].includes(storedTheme)
47						? storedTheme
48						: null;
49
50				if (initialTheme) document.documentElement.style.colorScheme = initialTheme;
51			} catch {}
52		</script>
52
53		<link rel="stylesheet" href="/styles.css?v=303c7bd6d52a" />
54	</head>
55	<body>
56		<header class="site-header" id="top">
57			<a class="skip-link" href="#main">Skip to content</a>
58			<div class="wrap site-header__row">
59				<a class="site-header__brand" href="/">
60					<svg class="radar-mark" viewBox="0 0 32 32" width="28" height="28" aria-hidden="true">
61						<circle cx="16" cy="16" r="14" fill="none" stroke="currentColor" stroke-width="1.5" />
62						<circle cx="16" cy="16" r="8" fill="none" stroke="currentColor" stroke-width="1" opacity="0.45" />
63						<line
64							class="radar-mark__sweep"
65							x1="16"
66							y1="16"
67							x2="16"
68							y2="3"
69							stroke="var(--accent)"
70							stroke-width="2"
71							stroke-linecap="round"
72						/>
73						<circle cx="22" cy="10" r="2" fill="var(--accent)" />
74					</svg>
75					<span class="site-header__brand-text">CSS Radar</span>
76				</a>
77				<div class="site-header__actions">
78					<div class="theme-toggle">
79						<input
80							class="theme-toggle__input"
81							id="theme-toggle"
82							type="checkbox"
83							role="switch"
84							aria-label="Switch to dark mode"
85						/>
86						<label class="theme-toggle__label" for="theme-toggle" title="Switch to dark mode">
87							<span class="theme-toggle__icon" aria-hidden="true">
88								<svg
89									class="theme-toggle__moon"
90									xmlns="http://www.w3.org/2000/svg"
91									width="100%"
92									height="100%"
93									viewBox="0 0 100 100"
94									preserveAspectRatio="xMidYMid meet"
95								>
96									<path
97										d="M82.1,61.2a31.9,31.9,0,0,1-12.4,2.4A33.3,33.3,0,0,1,36.4,30.3a31.9,31.9,0,0,1,2.4-12.4A33.3,33.3,0,1,0,82.1,61.2Z"
98										fill="none"
99										stroke="currentColor"
100										stroke-linecap="round"
101										stroke-linejoin="round"
102										stroke-width="5"
103									/>
104								</svg>
105								<svg
106									class="theme-toggle__sun"
107									xmlns="http://www.w3.org/2000/svg"
108									width="100%"
109									height="100%"
110									viewBox="0 0 100 100"
111									preserveAspectRatio="xMidYMid meet"
112								>
113									<path
114										d="M50,18v3.6m0,56.8V82M82,50H78.4M21.6,50H18M72.6,72.6l-2.5-2.5M29.9,29.9l-2.5-2.5m45.2,0-2.5,2.5M29.9,70.1l-2.5,2.5M64.2,50A14.2,14.2,0,1,1,50,35.8,14.3,14.3,0,0,1,64.2,50Z"
115										fill="none"
116										stroke="currentColor"
117										stroke-linecap="round"
118										stroke-linejoin="round"
119										stroke-width="5"
120									/>
121								</svg>
122							</span>
123						</label>
124					</div>
125					<nav class="site-header__nav" aria-label="Main">
126						<a class="site-header__link" href="/blog/" aria-current="false">Blog</a>
127						<a class="site-header__link site-header__link--cta" href="/">Audit my page</a>
128					</nav>
129				</div>
130			</div>
131		</header>
132
133		<main class="privacy-page wrap" id="main">
134			<header class="privacy-page__header">
135				<p class="privacy-page__eyebrow">Privacy</p>
136				<h1>What CSS Radar handles.</h1>
137				<p class="privacy-page__intro">
138					CSS Radar audits public pages without an account. This page explains how the submitted URL and required
139					report email are used, who can open a report, and when CSS Radar's temporary records expire.
140				</p>
141				<p class="privacy-page__updated">Last updated August 13, 2026</p>
142			</header>
143
144			<div class="privacy-page__content">
145				<section class="privacy-section" aria-labelledby="privacy-audit">
146					<h2 id="privacy-audit">When you start an audit</h2>
147					<p>
148						Your browser sends the submitted public URL and email address to <code>api.cssradar.com</code>. The audit
149						service opens that URL in Chrome, inspects the rendered page and relevant
150						HTML, CSS, and JavaScript, observes safe interactions, and builds the report. It does not sign in or try to
151						bypass access controls.
152					</p>
153					<p class="privacy-section__note">
154						Do not submit private URLs, signed links, or URLs containing passwords, access tokens, or other secrets.
155					</p>
156				</section>
157
158				<section class="privacy-section" aria-labelledby="privacy-storage">
159					<h2 id="privacy-storage">What is stored</h2>
160					<ul>
161						<li>
162							<strong>Private audit record:</strong> the submitted URL, report email address, audit status,
163							timestamps, and technical result references are stored in Google Cloud Firestore. This record is scheduled
164							to expire 31 days after the audit finishes, fails, or is canceled.
165						</li>
166						<li>
167							<strong>Report file:</strong> a completed report is stored as an HTML file in Google Cloud Storage. It is
168							scheduled for automatic deletion after 30 days.
169						</li>
170						<li>
171							<strong>Kit subscriber:</strong> the email address is added to Kit with the
172							<code>radar</code> tag for occasional CSS Radar and modern CSS emails. Kit keeps that subscriber record until
173							the person unsubscribes or asks CSS Radar to delete it.
174						</li>
175						<li>
176							<strong>Daily limit:</strong> CSS Radar derives a pseudonymous identifier from the visitor's IP address with
177							a keyed hash. The raw IP address is not stored in the application's rate-limit record. That record 
177is
178							scheduled to expire within 48 hours.
179						</li>
180					</ul>
181					<p>
182						The 30-day deletion rule covers the generated report file. Standard infrastructure logs kept by the
183						service providers below are separate and follow each provider's own retention terms.
184					</p>
185				</section>
186
187				<section class="privacy-section" aria-labelledby="privacy-access">
188					<h2 id="privacy-access">Who can open a report</h2>
189					<p>
190						Anyone with the report URL can open it without an account. CSS Radar does not list reports on the site or
191						include them in its sitemap, but the link is not an access-control mechanism. Do not share it with people
192						who should not see the report.
193					</p>
194					<p>
195						To request deletion before the automatic deadline, email
196						<a href="mailto:[email protected]?subject=Delete%20a%20CSS%20Radar%20report">[email protected]</a> and include
197						the report URL.
198					</p>
199				</section>
200
201				<section class="privacy-section" aria-labelledby="privacy-email">
202					<h2 id="privacy-email">How the email address is used</h2>
203					<p>
204						CSS Radar uses the submitted email address to send the requested report or to say when the audit could not
205						be completed. It also adds the address to Kit with the <code>radar</code> tag for occasional CSS
206						Radar and modern CSS emails. Marketing emails include an unsubscribe option. The address does not appear
207						in the generated report.
208					</p>
209					<p>
210						Mailjet, a Sinch brand, receives the address and message content to deliver the
211						report or failure notice. Its delivery records are separate from CSS Radar's 30-day report file and follow
212						Mailjet's own retention terms.
213					</p>
214					<p>
215						Kit receives the email address to maintain the subscriber list and apply the
216						<code>radar</code> tag. To request complete deletion instead of unsubscribing, email
217						<a href="mailto:[email protected]">[email protected]</a>.
218					</p>
219				</section>
220
221				<section class="privacy-section" aria-labelledby="privacy-analytics">
222					<h2 id="privacy-analytics">Landing-page analytics</h2>
223					<p>
224						The public landing page loads Fairlytics to count visits and understand which pages are used. According to
225						Fairlytics, its hosted service uses no cookies. It receives the current CSS Radar page URL, the referrer,
226						and request data such as the IP address, browser, and operating system. Fairlytics says it uses the IP
227						address to derive approximate location and a daily hashed visitor identifier, then discards the raw IP.
228					</p>
229					<p>
230						The URL and email address typed into the audit form are not sent to Fairlytics as analytics events, and
231						generated reports do not load Fairlytics. Fairlytics stores its audience records separately. Its public
232						documentation does not state a fixed retention period, so the 30-day report rule does not cover those
233						analytics records.
234					</p>
235					<p>
236						Read Fairlytics'
237						<a href="https://fairlytics.tech/doc/fonctionnement" target="_blank" rel="noopener">data explanation</a>
238						and <a href="https://fairlytics.tech/doc/cgu" target="_blank" rel="noopener">terms</a>.
239					</p>
240				</section>
241
242				<section class="privacy-section" aria-labelledby="privacy-providers">
243					<h2 id="privacy-providers">Service providers and contact</h2>
244					<ul>
245						<li>
246							<a href="https://www.netlify.com/privacy/" target="_blank" rel="noopener">Netlify</a> serves the public
247							website.
248						</li>
249						<li>
250							<a href="https://cloud.google.com/terms/cloud-privacy-notice" target="_blank" rel="noopener">Google Cloud</a>
251							runs the audit service and stores temporary audit records and reports.
252						</li>
253						<li>
254							<a href="https://fairlytics.tech/" target="_blank" rel="noopener">Fairlytics</a> provides the
255							landing-page audience measurement described above.
256						</li>
257						<li>
258							<a href="https://www.mailjet.com/legal/privacy-policy/" target="_blank" rel="noopener">Mailjet</a>
259							delivers report emails and audit failure notices.
260						</li>
261						<li>
262							<a href="https://kit.com/privacy" target="_blank" rel="noopener">Kit</a> stores report recipients as
263							subscribers and manages later email updates and unsubscribes.
264						</li>
265					</ul>
266					<p>
267						CSS Radar is operated by Theo Soti. For a privacy question, subscriber-deletion request, or an early
268						report-deletion request, email
269						<a href="mailto:[email protected]">[email protected]</a>.
270					</p>
271				</section>
272			</div>
273		</main>
274
275		<footer class="site-footer">
276			<div class="wrap site-footer__row">
277				<p>Modern CSS Radar. Audit one page, ship less custom code.</p>
278				<div class="site-footer__meta">
279					<p class="site-footer__credit">
280						Created by <a href="https://theosoti.com/">Theo Soti</a> ·
281						<a href="/blog/">Blog</a> ·
282						<a href="/privacy.html">Privacy and data use</a>
283					</p>
284					<div class="site-footer__badges">
285						<a
286							class="site-footer__badge"
287							href="https://codetrendy.com/?utm_source=cssradar.com&amp;utm_medium=badge"
288							target="_blank"
289							rel="nofollow noopener noreferrer"
290						>
291							<img
292								src="https://codetrendy.com/api/badge?style=classic"
293								alt="codetrendy.com listing"
294								width="220"
295								height="56"
296								loading="lazy"
297								decoding="async"
298								referrerpolicy="no-referrer"
299							/>
300						</a>
301						<a
302							class="site-footer__badge"
303							href="https://sitepatent.com/?utm_source=cssradar.com&amp;utm_medium=badge"
304							target="_blank"
305							rel="nofollow noopener noreferrer"
306						>
307							<img
308								src="https://sitepatent.com/api/badge?style=classic"
309								alt="sitepatent.com listing"
310								width="220"
311								height="56"
312								loading="lazy"
313								decoding="async"
314								referrerpolicy="no-referrer"
315							/>
316						</a>
317					</div>
318				</div>
319			</div>
320		</footer>
321
322		
322<script>
323			(() => {
324				const themeToggle = document.querySelector('#theme-toggle');
325				const themeLabel = document.querySelector('.theme-toggle__label');
326				const requestedTheme = new URLSearchParams(window.location.search).get('theme');
327				const systemTheme = window.matchMedia('(prefers-color-scheme: dark)');
328				let storedTheme = null;
329
330				try {
331					storedTheme = window.localStorage.getItem('css-radar-theme');
332				} catch {}
333
334				const hasRequestedTheme = requestedTheme === 'light' || requestedTheme === 'dark';
335				let hasManualTheme = storedTheme === 'light' || storedTheme === 'dark';
336
337				const applyTheme = (theme, persist = false) => {
338					const nextTheme = theme === 'dark' ? 'light' : 'dark';
339					document.documentElement.style.colorScheme = theme;
340
341					if (themeToggle) {
342						themeToggle.checked = theme === 'dark';
343						themeToggle.setAttribute('aria-label', `Switch to ${nextTheme} mode`);
344					}
345
346					if (themeLabel) themeLabel.title = `Switch to ${nextTheme} mode`;
347
348					if (persist) {
349						hasManualTheme = true;
350						try {
351							window.localStorage.setItem('css-radar-theme', theme);
352						} catch {}
353					}
354				};
355
356				const initialTheme = hasRequestedTheme
357					? requestedTheme
358					: hasManualTheme
359						? storedTheme
360						: systemTheme.matches
361							? 'dark'
362							: 'light';
363
364				applyTheme(initialTheme);
365
366				themeToggle?.addEventListener('change', (event) => {
367					applyTheme(event.currentTarget.checked ? 'dark' : 'light', true);
368				});
369
370				systemTheme.addEventListener?.('change', (event) => {
371					if (!hasRequestedTheme && !hasManualTheme) applyTheme(event.matches ? 'dark' : 'light');
372				});
373
374				if (hasRequestedTheme) {
375					document.documentElement.style.colorScheme = requestedTheme;
376				}
377			})();
378		</script>
378
379	</body>
380</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.