-
-
Notifications
You must be signed in to change notification settings - Fork 13
Version 0.1.1 alpha #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThe changes remove outdated HTML files and a simple server setup, and modernize the proxy server to use Express with CORS support. New dependencies and TypeScript types were added, and the code now features improved client IP detection. Enhancements include a comprehensive confidence scoring mechanism, bot detection functions, and an updated geolocation endpoint. Additionally, the test interface was overhauled with improved semantics, dynamic code copying, loading indicators, and responsive styling. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ExpressServer
participant SystemInfo
participant GeoService
Client->>ExpressServer: GET /userInfo with API key
ExpressServer->>ExpressServer: getClientIp()
ExpressServer->>SystemInfo: getSystemInfo() (detectBot, calculateConfidenceScore)
SystemInfo-->>ExpressServer: systemInfo data
ExpressServer->>GeoService: Fetch geolocation info (via GEOIP_URL)
GeoService-->>ExpressServer: geolocation info
ExpressServer->>ExpressServer: calculateCombinedConfidence(systemInfo, geoInfo)
ExpressServer->>ExpressServer: generateJSON(geoInfo, systemInfo, combinedConfidence)
ExpressServer-->>Client: Return JSON response
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Here's the code health analysis summary for commits Analysis Summary
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (2)
src/types.ts (2)
106-115:⚠️ Potential issueDuplicate interface definition:
MathInfoThe
MathInfointerface is defined twice in the file - once at lines 80-89 and again at lines 106-115. Both definitions are identical, which introduces unnecessary duplication.Remove the duplicate interface definition:
-export interface MathInfo { - acos: number; - acosh: number; - asinh: number; - atanh: number; - expm1: number; - sinh: number; - cosh: number; - tanh: number; -}
117-122:⚠️ Potential issueDuplicate interface definition:
FontInfoSimilar to
MathInfo, theFontInfointerface is also defined twice - once at lines 91-96 and again at lines 117-122. This creates unnecessary duplication and could cause confusion.Remove the duplicate interface definition:
-export interface FontInfo { - fonts: Array<{ - name: string; - width: number; - }>; -}
🧹 Nitpick comments (14)
src/geo-ip.ts (1)
2-2: Hard-coded production URL could complicate local developmentThe URL has been changed from a localhost reference to a production URL. While this works for production, it might complicate local development and testing.
Consider using an environment variable to make the URL configurable:
-const GEOIP_URL = 'https://proxy-server-deploy.onrender.com'; +const GEOIP_URL = process.env.GEOIP_URL || 'https://proxy-server-deploy.onrender.com';This would allow developers to override the URL for local testing while keeping the production URL as a default.
proxy_server/src/index.ts (2)
60-63: Unnecessaryfinallyblock withres.end()Express automatically ends the response when methods like
res.json()orres.send()are called. The explicit call tores.end()is redundant and could potentially cause issues if the response has already been sent.Consider removing the
finallyblock or use it only for cleanup operations that don't involve the response:- finally{ - // db.insert({ip: req.ip, date: new Date()}); - res.end(); - }
37-51: API key validation can be simplified into middlewareThe API key validation logic is duplicated across multiple conditionals. This would be more maintainable and reusable as Express middleware.
Consider refactoring to use Express middleware for API key validation:
+// Middleware for API key validation +const validateApiKey = (req, res, next) => { + if (!req.headers || !req.headers['x-api-key']) { + console.log('API key not found'); + return res.status(403).send('Forbidden'); + } + + if (req.headers['x-api-key'] !== API_KEY) { + console.log('API key does not match'); + return res.status(403).send('Forbidden'); + } + + next(); +}; + +// Apply the middleware to routes that need it +server.get('/', validateApiKey, async (req, res) => { + const ip = getClientIp(req); + + try { + const response = await getIpInfo(ip); + res.json(response); + } catch (e) { + console.error('Error processing geolocation request:', e); + res.status(500).json({error: 'Failed to retrieve geolocation information'}); + } +});src/json.ts (1)
4-51: Add a clamp for out-of-range inputs
The function’s JSDoc states that the score parameter is between 0.1 and 0.9. However, the code does not clamp or validate the input, which could lead to inconsistent interpretation if an out-of-range score is passed. Consider enforcing that range to avoid unexpected results.Here's one way to implement a clamp:
function interpretConfidenceScore(score: number) { + // Clamp the input to [0.1, 0.9] + score = Math.max(0.1, Math.min(0.9, score)); if (score >= 0.8) { ... } }src/index.ts (4)
11-258: Refactor large function for maintainability
While the scoring logic is comprehensive, the function is quite large and hard to maintain. Consider extracting the different weighting sections (bot detection, geolocation, data coherence, final adjustments) into smaller helper functions for better readability and testability.function calculateCombinedConfidence(systemInfo: any, geoInfo: any): number { let score = 0.5; - // Bot detection logic - ... - // Geolocation verification - ... - // Data coherence - ... + score = applyBotDetectionAdjustment(score, systemInfo); + score = applyGeolocationAdjustment(score, geoInfo, systemInfo); + score = applyDataCoherenceAdjustment(score, systemInfo); + score = applyFinalTweaks(score, systemInfo, geoInfo); return Math.max(0.1, Math.min(0.9, score)); }🧰 Tools
🪛 Biome (1.9.4)
[error] 21-21: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 67-67: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 109-109: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
21-21: Use optional chaining for clarity
Instead ofif (systemInfo && systemInfo.bot), considerif (systemInfo?.bot). It simplifies the conditional logic and avoids potential undefined checks.🧰 Tools
🪛 Biome (1.9.4)
[error] 21-21: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
67-67: Adopt optional chaining
Likewise, replaceif (systemInfo && systemInfo.timezone)withif (systemInfo?.timezone)to streamline null checks.🧰 Tools
🪛 Biome (1.9.4)
[error] 67-67: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
109-109: Optional chain for multi-property checks
The condition could be shortened withsystemInfo?.languages?.lengthif that suits your style and does not conflict with existing coding conventions.🧰 Tools
🪛 Biome (1.9.4)
[error] 109-109: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/systemInfo.ts (2)
112-226: Consider extracting sub-checks
This function packs multiple checks (incognito, bot signals, platform consistency) into one routine, which can be hard to maintain or extend. Splitting out each major check into helper functions would improve clarity and testability.
473-476: Avoid 'any' for MIME type mapping
Using(mime: any)can lead to type-safety issues. Declare a dedicated interface or inline type to ensure consistent usage and reduce potential runtime errors.interface PluginMimeType { type: string; suffixes: string; } ... mimeTypes: Array.from(plugin.mimeTypes).map((mime: PluginMimeType) => ({ type: mime.type, suffixes: mime.suffixes }))test/src/main.js (1)
31-67: Well-implemented dynamic stylingThe new
addDisplayStyles()function is a good approach to programmatically adding styles. This keeps the styling concerns together with the related functionality.Some suggestions for improvement:
- Consider moving these styles to your CSS file instead of injecting them via JavaScript, which would:
- Improve separation of concerns
- Allow styles to load earlier with the page
- Make styles easier to maintain with the rest of your CSS
- function addDisplayStyles() { - const style = document.createElement('style'); - style.textContent = ` - pre#result { - font-weight: 500; - font-size: 14px; - line-height: 1.5; - background-color: var(--bg-secondary); - color: var(--text-primary); - padding: var(--spacing-md); - border-radius: var(--border-radius); - box-shadow: 0 2px 8px var(--shadow-color); - overflow: auto; - max-height: 80vh; - font-family: 'Fira Code', 'Roboto Mono', monospace; - } - - .key-highlight { - color: var(--accent-color); - font-weight: 700; - } - - .value-string { - color: #2e7d32; - } - - .value-number { - color: #d32f2f; - } - - .value-boolean { - color: #1976d2; - } - `; - document.head.appendChild(style); - }
- If you need to keep the dynamic styling (for example, if you're adding syntax highlighting), consider adding a class to the result element instead of injecting styles:
async function runTest() { try { // Get user information const result = await userInfo(); // Format the result for display with nice indentation const formattedResult = JSON.stringify(result, null, 2); // Update the result display with just the raw data resultElement.textContent = formattedResult; - // Apply styles for clear reading - addDisplayStyles(); + // Apply styling class + resultElement.classList.add('formatted-result'); } catch (error) { resultElement.classList.add('error'); resultElement.textContent = `Error: ${error.message}`; console.error('Fingerprinting error:', error); } }test/src/style.css (1)
116-237: Well-structured component stylingThe layout and component styles are well-organized and use consistent spacing and styling patterns.
One suggestion regarding the GitHub button:
The GitHub button uses hardcoded colors rather than CSS variables:
.github-button { display: inline-flex; align-items: center; - background-color: var(--github-black); + background-color: var(--github-black); color: white; padding: var(--spacing-xs) var(--spacing-sm); border-radius: var(--border-radius); font-size: var(--font-size-sm); transition: background-color 0.2s; } .github-button:hover { - background-color: #2c3136; + background-color: var(--github-black-hover); color: white; }Add a new variable to the :root section:
--github-black-hover: #2c3136;test/index.html (2)
57-60: Image loading optimization neededThe image references could be improved for better loading performance and reliability.
- Add width and height attributes to prevent layout shifts during loading
- Consider adding loading="lazy" for images below the fold
- Consider using local copies of all images instead of loading from external sources
-<img src="./public/freejs.png" alt="FreeJS Logo" class="logo"> -<img src="./public/goss.png" alt="GOSS Logo" class="logo"> -<img src="https://upload.wikimedia.org/wikipedia/commons/d/db/Npm-logo.svg" alt="npm" class="logo"> +<img src="./public/freejs.png" alt="FreeJS Logo" class="logo" width="40" height="40" loading="lazy"> +<img src="./public/goss.png" alt="GOSS Logo" class="logo" width="40" height="40" loading="lazy"> +<img src="./public/npm-logo.svg" alt="npm" class="logo" width="40" height="40" loading="lazy">Download the npm logo to your local assets for better reliability and control:
curl -o ./public/npm-logo.svg https://upload.wikimedia.org/wikipedia/commons/d/db/Npm-logo.svg
70-80: Improve clipboard functionality with error handlingThe clipboard functionality works well but could be improved with error handling.
function copyCode(button) { const codeBlock = button.parentElement.querySelector('code'); - navigator.clipboard.writeText(codeBlock.textContent); - - button.innerHTML = '<i class="fas fa-check"></i>'; - setTimeout(() => { - button.innerHTML = '<i class="far fa-copy"></i>'; - }, 2000); + navigator.clipboard.writeText(codeBlock.textContent) + .then(() => { + button.innerHTML = '<i class="fas fa-check"></i>'; + setTimeout(() => { + button.innerHTML = '<i class="far fa-copy"></i>'; + }, 2000); + }) + .catch(err => { + console.error('Failed to copy: ', err); + button.innerHTML = '<i class="fas fa-times"></i>'; + setTimeout(() => { + button.innerHTML = '<i class="far fa-copy"></i>'; + }, 2000); + }); }This improves the function by:
- Adding proper promise handling for the clipboard API
- Adding error handling to show a failure icon
- Logging errors to the console for debugging
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
test/public/freejs.pngis excluded by!**/*.pngtest/public/goss.pngis excluded by!**/*.pngtest/public/vite.svgis excluded by!**/*.svg
📒 Files selected for processing (13)
index.html(0 hunks)proxy_server/package.json(1 hunks)proxy_server/src/index.ts(2 hunks)src/geo-ip.ts(1 hunks)src/index.ts(1 hunks)src/json.ts(2 hunks)src/server.ts(0 hunks)src/systemInfo.ts(4 hunks)src/types.ts(1 hunks)test/index.html(1 hunks)test/src/main.js(1 hunks)test/src/style.css(1 hunks)test/test.html(0 hunks)
💤 Files with no reviewable changes (3)
- src/server.ts
- test/test.html
- index.html
🧰 Additional context used
🪛 Biome (1.9.4)
src/index.ts
[error] 21-21: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 67-67: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 109-109: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (20)
src/types.ts (1)
52-57: Good addition of bot detection and confidence scoring propertiesThe addition of
confidenceScoreand thebotobject with detailed properties enhances the system's capability to detect and report on automated clients.proxy_server/package.json (2)
15-16: Express dependencies added appropriately for server migrationThe addition of express, body-parser, and cors packages aligns well with the server implementation changes seen in the index.ts file.
Also applies to: 18-18
22-23: Type definitions added for new dependenciesGood practice to include the TypeScript type definitions for the new dependencies.
proxy_server/src/index.ts (3)
1-11: Server framework migration to ExpressGood refactoring from Hasty to Express, which is more widely used and has better community support. The CORS middleware is correctly configured.
20-33: Well-implemented client IP detection functionThe
getClientIpfunction correctly handles both direct connections and requests through proxies by checking for thex-forwarded-forheader. This is a good practice for accurate client IP detection.
34-35: Improved route handler with IP detectionThe refactored GET route handler now properly uses the new
getClientIpfunction to determine the client's IP address.src/json.ts (1)
53-118: Well-structured returned object
The function effectively consolidates geolocation, system, and optional combinedConfidenceScore data into a coherent JSON. The fallback logic for the combined interpretation is clear, and the usage of optional chaining for geolocation traits is good. No major concerns.src/index.ts (2)
5-10: Documentation is consistent
The JSDoc block thoroughly explains the function's intent and parameter ranges. Looks good.
267-272: Proper utilization of combined confidence
CallingcalculateCombinedConfidenceand passing the result togenerateJSONneatly integrates the new scoring logic. No issues noted.src/systemInfo.ts (3)
4-110: Verify isBot assumption for non-browser environments
By returningisBot: trueifwindowornavigatoris undefined, certain non-browser contexts (e.g., server-side rendering) are classified as bots. Confirm that this strict approach is intentional; if you prefer a fallback instead, you can revise the logic to avoid false positives.
235-243: Integration logic looks sound
Fetching bot info, incognito mode, and then computing confidence all fit together properly. No issues here.
309-342: Mock data usage
Providing mock bot and confidence data is a good approach for non-browser contexts. The structure aligns with the real data format. No concerns.test/src/main.js (3)
6-8: Good UX enhancement with loading indicatorAdding a loading indicator improves the user experience by providing immediate feedback that the test is running.
12-23: Well-structured code with clear commentsThe added comments enhance code readability by clearly identifying each step in the process. The formatted JSON with indentation (using
null, 2) makes the output much more readable for users.
27-27: Improved error handlingAdding console.error with a descriptive prefix makes debugging issues easier by clearly identifying fingerprinting-related errors in the console.
test/src/style.css (2)
75-114: Clean base styling with consistent variable usageGood use of CSS variables for consistent styling. The typography choices are clean and the responsive defaults are well set.
304-328: Good responsive design implementationThe responsive breakpoints and adjustments are well thought out. Using flexbox direction changes for mobile layouts is an effective approach.
test/index.html (3)
2-9: Improved HTML document structure and metadataAdding the lang attribute, proper meta tags, and Font Awesome integration improves accessibility and functionality.
12-25: Well-structured header with good call-to-actionThe header layout with GitHub link and star request creates a clear call-to-action for users.
27-52: Comprehensive installation and usage guideThe installation guide with copyable code snippets provides excellent user experience. The "Live Demo" section with the result container gives users immediate value.
| "cors": "^2.8.5", | ||
| "dotenv": "^16.4.7", | ||
| "express": "^4.21.2", | ||
| "hasty-server": "^0.9.52" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify if hasty-server dependency is still needed
Since the code has been migrated from Hasty to Express (as seen in proxy_server/src/index.ts), the hasty-server dependency might no longer be needed.
🏁 Script executed:
#!/bin/bash
# Check if hasty-server is still being used elsewhere in the codebase
echo "Searching for hasty-server imports in the codebase:"
grep -r --include="*.ts" --include="*.js" "import.*hasty" .Length of output: 238
Action Required: Remove Obsolete hasty-server Dependency
- The grep search confirms that the only mention of
hasty-serverin the codebase is a commented-out import inproxy_server/src/index.ts. - Since the code now uses Express and no active references to
hasty-serverwere found, it appears that the dependency is no longer necessary. - Please remove the
"hasty-server": "^0.9.52"entry fromproxy_server/package.jsonand consider cleaning up the commented-out import inproxy_server/src/index.tsif it’s no longer relevant.
| } | ||
| catch(e){ | ||
| res.json({error: null}); | ||
| res.json({error: null}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Error response returns misleading information
When an error occurs, the response returns {error: null} which is misleading as it suggests no error occurred.
Improve error handling to provide more useful information to the client:
- res.json({error: null})
+ console.error('Error processing geolocation request:', e);
+ res.status(500).json({error: 'Failed to retrieve geolocation information'})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| res.json({error: null}) | |
| console.error('Error processing geolocation request:', e); | |
| res.status(500).json({error: 'Failed to retrieve geolocation information'}); |
| #result { | ||
| background-color: var(--bg-secondary); | ||
| padding: var(--spacing-md); | ||
| border-radius: var(--border-radius); | ||
| border: 1px solid var(--border-color); | ||
| overflow: auto; | ||
| max-height: 70vh; | ||
| font-family: 'Fira Code', 'Roboto Mono', monospace; | ||
| font-size: var(--font-size-sm); | ||
| margin: 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Duplicate styling between CSS and JavaScript
There's duplicate styling for the #result element between this CSS file and the addDisplayStyles() function in main.js.
Either:
- Remove this CSS block and keep the styling in JavaScript, or
- Remove the JavaScript styling function and rely on this CSS (preferred)
If you keep the CSS here, you should remove the addDisplayStyles() function from main.js to avoid conflicts and maintain a single source of truth for styling.
| /* | ||
| * FINGERPRINT TEST STYLES | ||
| * A clean, organized stylesheet for the browser fingerprint test UI | ||
| */ | ||
|
|
||
| /* ============================== | ||
| * 1. VARIABLES | ||
| * ============================== */ | ||
| :root { | ||
| font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; | ||
| /* Colors */ | ||
| --text-primary: #213547; | ||
| --text-secondary: #666; | ||
| --bg-primary: #ffffff; | ||
| --bg-secondary: #f8f9fa; | ||
| --accent-color: #646cff; | ||
| --accent-hover: #535bf2; | ||
| --border-color: #eaeaea; | ||
| --shadow-color: rgba(0, 0, 0, 0.1); | ||
| --github-black: #24292e; | ||
| --success-color: #28a745; | ||
|
|
||
| /* Confidence score colors */ | ||
| --high-confidence-bg: #d4edda; | ||
| --high-confidence-text: #155724; | ||
| --medium-high-bg: #d1ecf1; | ||
| --medium-high-text: #0c5460; | ||
| --medium-bg: #fff3cd; | ||
| --medium-text: #856404; | ||
| --medium-low-bg: #ffe5d0; | ||
| --medium-low-text: #7d5a00; | ||
| --low-bg: #f8d7da; | ||
| --low-text: #721c24; | ||
|
|
||
| /* Error colors */ | ||
| --error-color: #dc3545; | ||
|
|
||
| /* Spacing */ | ||
| --spacing-xs: 0.5rem; | ||
| --spacing-sm: 1rem; | ||
| --spacing-md: 1.5rem; | ||
| --spacing-lg: 2rem; | ||
|
|
||
| /* Font sizes */ | ||
| --font-size-sm: 0.9rem; | ||
| --font-size-md: 1rem; | ||
| --font-size-lg: 1.2rem; | ||
| --font-size-xl: 2.5rem; | ||
|
|
||
| /* Border radius */ | ||
| --border-radius: 8px; | ||
| } | ||
|
|
||
| /* Dark mode overrides */ | ||
| @media (prefers-color-scheme: dark) { | ||
| :root { | ||
| --text-primary: rgba(255, 255, 255, 0.87); | ||
| --text-secondary: #a0a0a0; | ||
| --bg-primary: #242424; | ||
| --bg-secondary: #2a2a2a; | ||
| --border-color: #333; | ||
| --shadow-color: rgba(0, 0, 0, 0.3); | ||
| } | ||
| } | ||
|
|
||
| /* Force light mode - overriding dark mode */ | ||
| :root { | ||
| --text-primary: #213547; | ||
| --text-secondary: #666; | ||
| --bg-primary: #ffffff; | ||
| --bg-secondary: #f8f9fa; | ||
| --border-color: #eaeaea; | ||
| --shadow-color: rgba(0, 0, 0, 0.1); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Well-organized CSS with variables and theme support
Excellent organization of CSS with clear comments, sectioning, and comprehensive variable definitions. The CSS variables approach makes the stylesheet more maintainable.
However, there's an issue with your theme implementation:
Lines 53-73 define both dark mode support and then immediately override it with light mode variables. This creates confusion as the dark mode media query will never take effect. Either:
- Remove the forced light mode section (lines 65-73) to allow the dark mode to work properly, or
- Add a class-based theme toggle system instead of relying solely on the media query
/* Dark mode overrides */
@media (prefers-color-scheme: dark) {
:root {
--text-primary: rgba(255, 255, 255, 0.87);
--text-secondary: #a0a0a0;
--bg-primary: #242424;
--bg-secondary: #2a2a2a;
--border-color: #333;
--shadow-color: rgba(0, 0, 0, 0.3);
}
}
-/* Force light mode - overriding dark mode */
-:root {
- --text-primary: #213547;
- --text-secondary: #666;
- --bg-primary: #ffffff;
- --bg-secondary: #f8f9fa;
- --border-color: #eaeaea;
- --shadow-color: rgba(0, 0, 0, 0.1);
-}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /* | |
| * FINGERPRINT TEST STYLES | |
| * A clean, organized stylesheet for the browser fingerprint test UI | |
| */ | |
| /* ============================== | |
| * 1. VARIABLES | |
| * ============================== */ | |
| :root { | |
| font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; | |
| /* Colors */ | |
| --text-primary: #213547; | |
| --text-secondary: #666; | |
| --bg-primary: #ffffff; | |
| --bg-secondary: #f8f9fa; | |
| --accent-color: #646cff; | |
| --accent-hover: #535bf2; | |
| --border-color: #eaeaea; | |
| --shadow-color: rgba(0, 0, 0, 0.1); | |
| --github-black: #24292e; | |
| --success-color: #28a745; | |
| /* Confidence score colors */ | |
| --high-confidence-bg: #d4edda; | |
| --high-confidence-text: #155724; | |
| --medium-high-bg: #d1ecf1; | |
| --medium-high-text: #0c5460; | |
| --medium-bg: #fff3cd; | |
| --medium-text: #856404; | |
| --medium-low-bg: #ffe5d0; | |
| --medium-low-text: #7d5a00; | |
| --low-bg: #f8d7da; | |
| --low-text: #721c24; | |
| /* Error colors */ | |
| --error-color: #dc3545; | |
| /* Spacing */ | |
| --spacing-xs: 0.5rem; | |
| --spacing-sm: 1rem; | |
| --spacing-md: 1.5rem; | |
| --spacing-lg: 2rem; | |
| /* Font sizes */ | |
| --font-size-sm: 0.9rem; | |
| --font-size-md: 1rem; | |
| --font-size-lg: 1.2rem; | |
| --font-size-xl: 2.5rem; | |
| /* Border radius */ | |
| --border-radius: 8px; | |
| } | |
| /* Dark mode overrides */ | |
| @media (prefers-color-scheme: dark) { | |
| :root { | |
| --text-primary: rgba(255, 255, 255, 0.87); | |
| --text-secondary: #a0a0a0; | |
| --bg-primary: #242424; | |
| --bg-secondary: #2a2a2a; | |
| --border-color: #333; | |
| --shadow-color: rgba(0, 0, 0, 0.3); | |
| } | |
| } | |
| /* Force light mode - overriding dark mode */ | |
| :root { | |
| --text-primary: #213547; | |
| --text-secondary: #666; | |
| --bg-primary: #ffffff; | |
| --bg-secondary: #f8f9fa; | |
| --border-color: #eaeaea; | |
| --shadow-color: rgba(0, 0, 0, 0.1); | |
| } | |
| /* | |
| * FINGERPRINT TEST STYLES | |
| * A clean, organized stylesheet for the browser fingerprint test UI | |
| */ | |
| /* ============================== | |
| * 1. VARIABLES | |
| * ============================== */ | |
| :root { | |
| /* Colors */ | |
| --text-primary: #213547; | |
| --text-secondary: #666; | |
| --bg-primary: #ffffff; | |
| --bg-secondary: #f8f9fa; | |
| --accent-color: #646cff; | |
| --accent-hover: #535bf2; | |
| --border-color: #eaeaea; | |
| --shadow-color: rgba(0, 0, 0, 0.1); | |
| --github-black: #24292e; | |
| --success-color: #28a745; | |
| /* Confidence score colors */ | |
| --high-confidence-bg: #d4edda; | |
| --high-confidence-text: #155724; | |
| --medium-high-bg: #d1ecf1; | |
| --medium-high-text: #0c5460; | |
| --medium-bg: #fff3cd; | |
| --medium-text: #856404; | |
| --medium-low-bg: #ffe5d0; | |
| --medium-low-text: #7d5a00; | |
| --low-bg: #f8d7da; | |
| --low-text: #721c24; | |
| /* Error colors */ | |
| --error-color: #dc3545; | |
| /* Spacing */ | |
| --spacing-xs: 0.5rem; | |
| --spacing-sm: 1rem; | |
| --spacing-md: 1.5rem; | |
| --spacing-lg: 2rem; | |
| /* Font sizes */ | |
| --font-size-sm: 0.9rem; | |
| --font-size-md: 1rem; | |
| --font-size-lg: 1.2rem; | |
| --font-size-xl: 2.5rem; | |
| /* Border radius */ | |
| --border-radius: 8px; | |
| } | |
| /* Dark mode overrides */ | |
| @media (prefers-color-scheme: dark) { | |
| :root { | |
| --text-primary: rgba(255, 255, 255, 0.87); | |
| --text-secondary: #a0a0a0; | |
| --bg-primary: #242424; | |
| --bg-secondary: #2a2a2a; | |
| --border-color: #333; | |
| --shadow-color: rgba(0, 0, 0, 0.3); | |
| } | |
| } |
Summary by CodeRabbit
New Features
Refactor
Style
Chores