diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ff303a3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,129 @@ +# RealBrain Design System — instructions for coding agents + +Copy this file into a RealBrain repository as `AGENTS.md` (or append it to `CLAUDE.md`). It tells an agent how to apply the design system without being reminded each time. Adjust the one path in "Source of truth" to wherever the repository vendors `tokens.css`. + +## Source of truth + +- In this repository: `src/tokens.css` — a vendored copy of https://realbrain.cc/design-system/tokens.css. Never edit it by hand; refresh it with `curl -o src/tokens.css https://realbrain.cc/design-system/tokens.css`. +- Full guide: https://realbrain.cc/design-system/design-system.md +- Short reference for agents: https://realbrain.cc/design-system/llms.txt +- Tokens as JSON (DTCG): https://realbrain.cc/design-system/tokens.json + +Read the guide's §2 (non-negotiables) and §6 (components) before writing or editing any CSS, component, or UI copy. + +## Rules + +1. **Tokens only.** Every colour, size, radius, shadow, duration, and easing in component code is a `var(--token)` from `tokens.css`. No raw hex, no raw px, no `rgba()`. +2. **One accent per screen.** Exactly one `.btn-primary` (or one accent-coloured action). Everything else is `.btn-secondary`, `.btn-ghost`, or neutral text. +3. **Weight ≤ 600.** Never `font-weight: 700` or `bold`. The font import does not even load 700. +4. **Flat.** No `linear-gradient`, `radial-gradient`, `backdrop-filter`, `text-shadow`, glow, or decorative `box-shadow`. `--shadow-*` is only for surfaces that are actually elevated (menus, modals, toasts). +5. **Never white on accent.** Text and icons on `--accent` use `--accent-fg`. +6. **Semantic colour is never the only signal.** Use `.status.ok|warn|err|info` (dot plus text) or an icon plus text. +7. **Copy:** sentence case everywhere. Buttons are verbs ("Sign in", "Create project"). "Sign in", never "Log in" or "Login". Errors say what happened and what to do next. +8. **One density per product.** `.density-comfortable` (default, 44px controls) or `.density-compact` (32px) on a container. Never both. +9. **Use the existing component classes** (`.btn`, `.field`, `.input`, `.select`, `.checkbox`, `.radio`, `.toggle`, `.card`, `dialog.modal`, `.toast`, `.tabs`, `.table`, `.status`, `.scaffold`, `.empty`, `.skeleton`). Do not re-style them locally. Do not build a div-based fake of a native control. +10. **Motion goes through `--dur-1/2/3` and `--ease`.** Nothing else. Reduced motion is handled globally by `tokens.css`. + +## When the system doesn't have what you need + +Do not invent a value. Build the piece from existing tokens if you can. If you genuinely need a new token or component, ship the work with a clearly marked proposal in your final message: + +``` +⚑ NEW TOKEN --{category}-{name}: {value} + why nothing existing fits: … +``` + +Do the same for drift you notice in existing code (`⚑ DRIFT file:line #3b82f6 → --accent`) rather than silently patching it. + +## Self-check before you finish + +Run these from the repository root (adjust `src` and the excluded path). Every command should print nothing: + +```sh +# raw colours or px outside the token file +grep -rnE --include=*.css --include=*.vue --include=*.jsx --include=*.tsx --include=*.svelte \ + --exclude=tokens.css '#[0-9a-fA-F]{3,8}\b|rgba?\(|\b[0-9]+px\b' src + +# forbidden weight and effects +grep -rnE --include=*.css --include=*.vue --include=*.jsx --include=*.tsx --include=*.svelte \ + --exclude=tokens.css 'font-weight:\s*(700|800|900|bold)|linear-gradient|radial-gradient|backdrop-filter|text-shadow' src + +# copy rules +grep -rniE --exclude-dir=node_modules 'log ?in|Sign In\b|Log In\b' src +``` + +Then check by eye: one `.btn-primary` per screen, focus rings visible when tabbing, and every status or badge has text next to its colour. + +## Quick reference + + +``` +--bg #080808 light: #F7F7F9 +--surface #121216 light: #FFFFFF +--elevated #1A1A20 light: #FFFFFF +--text-1 #F4F4F6 light: #16161C +--text-2 #A9A9B4 light: #4C4C58 +--text-3 #83838F light: #6E6E7A +--accent #8FA8FF light: #3450C8 +--accent-fg #080808 light: #FFFFFF +--accent-hover #9EB5FF light: #4C6BD2 +--accent-pressed #6173B1 light: #21358A +--success #3ECF8E light: #177A4E +--warning #E8B23D light: #8A5A00 +--error #F26D6D light: #C2373C +--info #62B0F5 light: #1D62A8 +--border #26262E light: #E3E3E9 +--border-strong #3A3A46 light: #C6C6D0 +--font-ui 'IBM Plex Sans', system-ui, sans-serif +--font-mono 'IBM Plex Mono', ui-monospace, monospace +type steps display:60/64 8:40/48 7:30/38 6:24/32 5:20/28 4:17/26 3:15/24 2:13/20 1:12/16 +weights 400 · 500 · 600 (never 700) +space 4px 8px 12px 16px 24px 32px 48px 64px 96px +radius sm 6px · md 10px · lg 16px · full 999px +motion 120ms · 200ms · 360ms · ease cubic-bezier(.22,.61,.36,1) +layout marketing 1200px · app 1440px · control-h 44px (compact 32px) +``` + + +Light theme: `document.documentElement.setAttribute('data-theme', 'light')`. Dark: remove the attribute. + +--- + +## Untrace specifics + +Applied to this repository on 2026-09-05, design system v2.0.0. + +- `src/tokens.css` is the vendored copy. `src/app.css` imports it and adds only + app-level composition (layout, dropzone, stepper, disclosure, tiles, the + mobile action bar). No component from `tokens.css` is restyled locally. +- Density is **comfortable** throughout — this is a consumer surface. +- Dark is the default. `src/lib/theme.js` reads a saved choice first and falls + back to the operating system, and `index.html` applies the result before + first paint so the page never flashes the wrong surface. +- One `.btn-primary` per step of the tool: the dropzone step has none, review + has "Clean image", download has "Download clean image". +- There is no Tailwind and no PostCSS. The design system is plain CSS and the + app needs nothing on top of it. + +### Open token proposals + +``` +NEW TOKEN --border-w: 1px + why nothing existing fits: every surface in the system draws a 1px + hairline, but the width itself is only ever written literally inside + tokens.css. Defined locally in src/app.css until the system adopts it. + +NEW TOKEN --topbar-h: 56px + why nothing existing fits: no layout token covers a sticky product bar. + Derived locally as calc(var(--space-7) + var(--space-2)). + +NEW TOKEN breakpoints — 560px / 768px / 900px + why nothing existing fits: the system documents container maximums + (--max-marketing, --max-app) but no breakpoint scale. Custom properties + cannot be used in a media query, so a literal is unavoidable; this app + pins itself to exactly these three widths. +``` + +`src/lib/clean.js` contains one literal hex, `JPEG_MATTE = "#FFFFFF"`. That is +image data written to a canvas, not interface styling, so it is intentionally +not a token. diff --git a/README.md b/README.md index 93fbb3f..31ebb4e 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,80 @@ -# Untrace - Advanced EXIF Metadata & AI Content Credential Remover +# Untrace -**Remove all metadata from images. Keep your privacy.** +**Remove content credentials from an image.** -Clean your photos from location data, AI signatures, C2PA content credentials, and other tracking information. Works 100% in your browser - no uploads, no tracking. +Untrace strips C2PA content credentials, AI generation tags, GPS coordinates +and EXIF metadata from a photo. It runs entirely in the browser — the file is +read and rewritten in the tab, never uploaded. -## Features + -**[•] Complete Privacy Protection** +## What it removes -- Removes GPS location data -- Strips camera information -- Cleans AI generation tags (ChatGPT, DALL-E, Midjourney, Stable Diffusion) -- Eliminates C2PA content credentials and provenance data -- Removes JUMBF metadata containers -- Clears Adobe Firefly and Google Imagen signatures -- Eliminates timestamps and device info +| | | +|---|---| +| C2PA content credentials | Manifests, claims, assertions and signatures from the Content Authenticity Initiative | +| AI generation tags | ChatGPT, DALL·E, Midjourney, Stable Diffusion, Adobe Firefly, Google Imagen | +| JUMBF containers | The APP11 and APP2 boxes that carry provenance inside a JPEG | +| GPS location | Latitude, longitude, altitude, bearing and their timestamp | +| Camera and device | Make, model, lens, serial numbers, exposure and shooting settings | +| Timestamps | When the photo was taken, digitised and last modified | +| XMP and IPTC | Creator names, captions, keywords, copyright, editing history | +| Comments and thumbnails | User comments, maker notes, embedded previews | +| PNG text chunks | tEXt, iTXt and zTXt blocks, including generation prompts | -**[✓] Enhanced AI Content Credential Removal** +Supported input: JPEG, PNG, TIFF, HEIC, AVIF. Output is JPEG, or PNG when the +original was a small PNG. -- Advanced detection of AI generation markers -- C2PA (Content Authenticity Initiative) signature removal -- DALL-E and OpenAI watermark stripping -- Midjourney metadata cleaning -- Stable Diffusion tag removal -- Adobe Content Authenticity removal -- JUMBF (JPEG Universal Metadata Box Format) cleaning +## How it works -**[✓] Secure & Private** +Detection and removal are two separate passes. -- No server uploads - everything happens in your browser -- No tracking or data collection -- Supports JPEG, PNG, TIFF, HEIC, AVIF +**Detection** (`src/lib/metadata.js`) reads the file twice: once through +[exifr](https://github.com/MikeKovarik/exifr) for structured segments, and once +as raw bytes to find C2PA strings and JUMBF boxes that exifr does not surface. +The results are merged and bucketed into named sections, then turned into the +findings list the review step renders. -**[↕] Easy to Use** +**Removal** (`src/lib/clean.js`) decodes the image to pixels on a canvas and +re-encodes it. Nothing carries over, so every metadata container is dropped at +once rather than deleting known tags one by one and leaving the rest behind. +The output is then re-read to confirm it is clean; if anything survived, a +second pass forces JPEG on a white matte. -- Drag & drop interface -- Instant preview of what data will be removed -- One-click cleaning -- Mobile-friendly design +If the browser cannot decode or re-encode the file, the original bytes are +returned and the interface says so — it never reports a clean that did not +happen. -## Quick Start +## Design -1. **Upload** - Drag your image to the page -2. **Review** - See what metadata was found -3. **Clean** - Click "Remove Metadata" -4. **Download** - Save your privacy-safe image +The interface follows the +[RealBrain Design System](https://realbrain.cc/design-system/) v2.0. Tokens are +vendored at `src/tokens.css`; refresh with: -## For Developers +```bash +curl -o src/tokens.css https://realbrain.cc/design-system/tokens.css +``` + +`AGENTS.md` carries the rules, the self-check commands, and this repository's +open token proposals. Read it before touching any CSS. + +## Development ```bash npm install -npm run dev - -npm run build +npm run dev # vite dev server +npm run build # production build to dist/ +npm run preview # serve the build ``` -**Built with:** Svelte + Vite + exifr +Stack: Svelte 4, Vite 5, exifr. No CSS framework — the design system is plain +CSS. -## Why Use Untrace? +## Who it is for -Modern images contain hidden data that can compromise your privacy: - -- **Location data** reveals where photos were taken -- **AI signatures** show which tools generated images (DALL-E, Midjourney, ChatGPT, Stable Diffusion) -- **C2PA content credentials** track the entire creation and editing history -- **Device info** identifies your camera/phone -- **Timestamps** reveal when images were created -- **JUMBF containers** store complex metadata structures -- **Content Authenticity** markers link images to specific AI tools -- **Provenance data** creates a digital paper trail - -Untrace removes all this data while keeping your images looking exactly the same. - -## Supported AI Tools & Formats - -**AI Generation Platforms:** - -- OpenAI DALL-E & ChatGPT -- Midjourney -- Stable Diffusion -- Adobe Firefly -- Google Imagen -- Runway ML -- NightCafe -- Artbreeder - -**Content Credential Standards:** - -- C2PA (Content Provenance and Authenticity) -- Content Authenticity Initiative (CAI) -- JUMBF (JPEG Universal Metadata Box Format) -- Adobe Content Credentials -- Project Origin signatures +Journalists protecting sources, activists maintaining anonymity, photographers +selling stock, and anyone who would rather a photo not carry its own history. ## License -MIT License - Free for personal and commercial use. +MIT. diff --git a/index.html b/index.html index 7aa146e..052869d 100644 --- a/index.html +++ b/index.html @@ -1,132 +1,268 @@ - + + - - - - - - - - - - - Untrace - Remove EXIF Metadata & AI Credentials from Images Online | - Privacy Tool - + Remove content credentials from an image – free online remover | Untrace - - - + - - - - + + + + + + + + + + + + + + + + + + + + - + - + - - - + + - - + - - - - - + - -
- + + + diff --git a/package-lock.json b/package-lock.json index bcad250..ccb4ede 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,30 +12,12 @@ }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", - "@tailwindcss/postcss": "^4.1.10", - "@tailwindcss/typography": "^0.5.16", - "@tailwindcss/vite": "^4.1.10", - "autoprefixer": "^10.4.21", "gh-pages": "^6.1.0", - "postcss": "^8.5.6", + "lightningcss": "^1.30.1", "svelte": "^4.2.0", - "tailwindcss": "^4.1.10", "vite": "^5.0.0" } }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -441,19 +423,6 @@ "node": ">=12" } }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", @@ -866,313 +835,6 @@ "vite": "^5.0.0" } }, - "node_modules/@tailwindcss/node": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.10.tgz", - "integrity": "sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.30.1", - "magic-string": "^0.30.17", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.10" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.10.tgz", - "integrity": "sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.10", - "@tailwindcss/oxide-darwin-arm64": "4.1.10", - "@tailwindcss/oxide-darwin-x64": "4.1.10", - "@tailwindcss/oxide-freebsd-x64": "4.1.10", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.10", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.10", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.10", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.10", - "@tailwindcss/oxide-linux-x64-musl": "4.1.10", - "@tailwindcss/oxide-wasm32-wasi": "4.1.10", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.10", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.10" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.10.tgz", - "integrity": "sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.10.tgz", - "integrity": "sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.10.tgz", - "integrity": "sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.10.tgz", - "integrity": "sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.10.tgz", - "integrity": "sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.10.tgz", - "integrity": "sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.10.tgz", - "integrity": "sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.10.tgz", - "integrity": "sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.10.tgz", - "integrity": "sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.10.tgz", - "integrity": "sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.10", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.10.tgz", - "integrity": "sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.10.tgz", - "integrity": "sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/postcss": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.10.tgz", - "integrity": "sha512-B+7r7ABZbkXJwpvt2VMnS6ujcDoR2OOcFaqrLIo1xbcdxje4Vf+VgJdBzNNbrAjBj/rLZ66/tlQ1knIGNLKOBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.10", - "@tailwindcss/oxide": "4.1.10", - "postcss": "^8.4.41", - "tailwindcss": "4.1.10" - } - }, - "node_modules/@tailwindcss/typography": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", - "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.castarray": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "postcss-selector-parser": "6.0.10" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.10.tgz", - "integrity": "sha512-QWnD5HDY2IADv+vYR82lOhqOlS1jSCUUAmfem52cXAhRTKxpDh3ARX8TTXJTCCO7Rv7cD2Nlekabv02bwP3a2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.1.10", - "@tailwindcss/oxide": "4.1.10", - "tailwindcss": "4.1.10" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6" - } - }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1220,44 +882,6 @@ "dev": true, "license": "MIT" }, - "node_modules/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -1281,70 +905,6 @@ "node": ">=8" } }, - "node_modules/browserslist": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", - "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001724", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz", - "integrity": "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/code-red": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", @@ -1390,19 +950,6 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -1454,13 +1001,6 @@ "node": ">=8" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.171", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.171.tgz", - "integrity": "sha512-scWpzXEJEMrGJa4Y6m/tVotb0WuvNmasv3wWVzUAeCgKU0ToFOhUW6Z+xWnRQANMYGxN4ngJXIThgBJOqzVPCQ==", - "dev": true, - "license": "ISC" - }, "node_modules/email-addresses": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", @@ -1468,20 +1008,6 @@ "dev": true, "license": "MIT" }, - "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -1521,16 +1047,6 @@ "@esbuild/win32-x64": "0.21.5" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1657,20 +1173,6 @@ "node": ">=8" } }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, "node_modules/fs-extra": { "version": "11.3.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", @@ -1818,16 +1320,6 @@ "@types/estree": "^1.0.6" } }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -2110,27 +1602,6 @@ "node": ">=8" } }, - "node_modules/lodash.castarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", - "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", @@ -2188,45 +1659,6 @@ "node": ">=8.6" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2253,23 +1685,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2403,27 +1818,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -2602,41 +1996,6 @@ "svelte": "^3.19.0 || ^4.0.0" } }, - "node_modules/tailwindcss": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz", - "integrity": "sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==", - "dev": true, - "license": "MIT" - }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2673,44 +2032,6 @@ "node": ">= 10.0.0" } }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, "node_modules/vite": { "version": "5.4.19", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", @@ -2785,16 +2106,6 @@ "optional": true } } - }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } } } } diff --git a/package.json b/package.json index a74a943..65f5e53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "untrace", - "description": "Clean your images. Keep your identity.", + "description": "Remove C2PA content credentials, AI generation tags and EXIF metadata from images, entirely in the browser.", "version": "1.0.0", "type": "module", "scripts": { @@ -11,18 +11,13 @@ }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", - "@tailwindcss/postcss": "^4.1.10", - "@tailwindcss/typography": "^0.5.16", - "@tailwindcss/vite": "^4.1.10", - "autoprefixer": "^10.4.21", "gh-pages": "^6.1.0", - "postcss": "^8.5.6", "svelte": "^4.2.0", - "tailwindcss": "^4.1.10", - "vite": "^5.0.0" + "vite": "^5.0.0", + "lightningcss": "^1.30.1" }, "dependencies": { "exifr": "^7.1.3" }, - "homepage": "https://developersharif.github.io/untrace" + "homepage": "https://untrace.realbrain.cc/" } diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index 1c87846..0000000 --- a/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - '@tailwindcss/postcss': {}, - autoprefixer: {}, - }, -} diff --git a/public/favicon-16x16.svg b/public/favicon-16x16.svg index b23c985..2b45932 100644 --- a/public/favicon-16x16.svg +++ b/public/favicon-16x16.svg @@ -1,23 +1,5 @@ - - - - - - - - - - - - - - - - - - - - - - + + + U diff --git a/public/favicon-32x32.svg b/public/favicon-32x32.svg index 2aacbef..2b45932 100644 --- a/public/favicon-32x32.svg +++ b/public/favicon-32x32.svg @@ -1,27 +1,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + U diff --git a/public/favicon-maskable.svg b/public/favicon-maskable.svg new file mode 100644 index 0000000..f7f6def --- /dev/null +++ b/public/favicon-maskable.svg @@ -0,0 +1,5 @@ + + + U + diff --git a/public/favicon.svg b/public/favicon.svg index 2ff2704..2b45932 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,32 +1,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + U diff --git a/public/manifest.json b/public/manifest.json index 56626e8..bb59c0d 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,19 +1,29 @@ { - "name": "Untrace", + "id": "/", + "name": "Untrace — content credentials and metadata remover", "short_name": "Untrace", - "description": "EXIF Metadata & AI Content Credential Remover", + "description": "Remove C2PA content credentials, AI generation tags and EXIF metadata from images, entirely in your browser.", "start_url": "/", + "scope": "/", "display": "standalone", - "background_color": "#ffffff", - "theme_color": "#3b82f6", + "background_color": "#080808", + "theme_color": "#080808", "icons": [ { - "src": "vite.svg", + "src": "/favicon.svg", "sizes": "any", - "type": "image/svg+xml" + "type": "image/svg+xml", + "purpose": "any" + }, + { + "src": "/favicon-maskable.svg", + "sizes": "any", + "type": "image/svg+xml", + "purpose": "maskable" } ], "categories": ["productivity", "utilities", "photo"], "lang": "en", + "dir": "ltr", "orientation": "any" } diff --git a/public/sitemap.xml b/public/sitemap.xml index 08a1a86..f711bfc 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -1,8 +1,8 @@ - https://untrace.realbrain.cc/untrace/ - 2025-06-23 + https://untrace.realbrain.cc/ + 2026-09-05 weekly 1.0 diff --git a/public/thumb.jpg b/public/thumb.jpg index 9b5e26e..b10c8d1 100644 Binary files a/public/thumb.jpg and b/public/thumb.jpg differ diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index a41de18..0000000 --- a/public/vite.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/App.svelte b/src/App.svelte index 68e1cf3..f46a467 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -1,335 +1,126 @@ - + -
-
- -
-
-
-

Upload Your Image

+
+
+
+

C2PA · AI credentials · EXIF

+

Remove content credentials from an image

+

+ Untrace strips C2PA content credentials, AI generation tags, GPS + coordinates and EXIF metadata from a photo — free, and without the file + ever leaving your device. +

+
+ Free + No sign-in + Open source
- -
- - {#if selectedFile} -
-
-
-

Original

- {#if metadata} - - {/if} -
+ -
- Original -
+
    + {#each assurances as item} +
  • +

    {item.title}

    +

    {item.detail}

    +
  • + {/each} +
-
-

- {selectedFile.name} • {(selectedFile.size / 1024).toFixed(1)} KB -

- {#if metadata && metadata.message && !metadata.hasMetadata} -

✓ No metadata detected

- {:else if metadata} -

- ⚠️ {Object.keys(metadata).filter( - (key) => !["fileType", "hasMetadata", "message"].includes(key) - ).length} metadata entries found -

- {/if} -
- - {#if showMetadata && metadata} -
- -
- {/if} -
- -
-

Clean Metadata

- - - {#if isProcessing} -
-
-
-
-

Processing...

-
- {/if} - - {#if processedImage} -
-

✅ Clean Image

-
- Cleaned -
- -
-

- {(processedImage.size / 1024).toFixed(1)} KB • - {processedImage.compressionRatio - ? `${processedImage.compressionRatio > 0 ? "-" : "+"}${Math.abs(processedImage.compressionRatio)}% size` - : "Processed"} -

- {#if processedImage.wasSecondPass} -

- ⚠️ Used enhanced cleaning (second pass) -

- {/if} -

✓ All EXIF metadata removed

-

✓ GPS location data cleared

-

✓ AI content credentials stripped

-

✓ C2PA provenance data removed

-

✓ Camera & device info cleared

-
- - - - - - Download Cleaned Image - -
- {/if} -
-
- {/if} - -
-
-

🔐 Privacy & Security

- -
- -
-

- ✓ 100% client-side - processing - • - ✓ No data collection - • - ✓ Open source -

-
- - {#if showPrivacyInfo} - - {/if} -
+
+ + + +