diff --git a/.github/workflows/indexnow.yml b/.github/workflows/indexnow.yml new file mode 100644 index 0000000..eabcc8f --- /dev/null +++ b/.github/workflows/indexnow.yml @@ -0,0 +1,108 @@ +name: IndexNow ping + +# Notify Bing/Yandex/Naver of changed URLs after a successful main-branch +# deploy. Uses the IndexNow open protocol with a key file hosted at +# https://gemmology.dev/.txt — the key value is stored as a +# repo secret and the public file is generated as part of the build (see +# `public/.txt` placeholder; replace with the real key on first setup). +# +# Diffs the sitemap between the previous main commit and the current commit +# to keep the submission list under IndexNow's 10k-URL limit and avoid +# spam-pinging the entire 600+ mineral catalogue on cosmetic changes. + +on: + workflow_run: + workflows: ["Deploy to Cloudflare Pages"] + types: [completed] + branches: [main] + workflow_dispatch: + inputs: + full_resubmit: + description: 'Resubmit every URL in the sitemap (use sparingly)' + type: boolean + default: false + +jobs: + ping: + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 50 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Determine changed URLs + id: urls + env: + FULL: ${{ github.event.inputs.full_resubmit || 'false' }} + run: | + set -euo pipefail + mkdir -p .indexnow + if [ "$FULL" = "true" ]; then + echo "Submitting full sitemap" + curl -fsSL https://gemmology.dev/sitemap-0.xml \ + | grep -oE 'https://gemmology\.dev/[^<]*' \ + | sort -u > .indexnow/urls.txt + else + # Diff content/page paths since the previous commit on main. + git diff --name-only "${{ github.event.before || 'HEAD~1' }}"...HEAD \ + | grep -E '^(src/pages|src/content|public/crystals)/' \ + | sort -u > .indexnow/changed.txt || true + : > .indexnow/urls.txt + while IFS= read -r path; do + case "$path" in + src/pages/index.astro) echo 'https://gemmology.dev/' >> .indexnow/urls.txt ;; + src/pages/about.astro) echo 'https://gemmology.dev/about/' >> .indexnow/urls.txt ;; + src/pages/learn/index.astro) echo 'https://gemmology.dev/learn/' >> .indexnow/urls.txt ;; + src/pages/gallery/index.astro) echo 'https://gemmology.dev/gallery/' >> .indexnow/urls.txt ;; + src/content/learn/*.yaml) + slug="${path#src/content/learn/}" + slug="${slug%.yaml}" + echo "https://gemmology.dev/learn/${slug}/" >> .indexnow/urls.txt + ;; + public/crystals/*.svg) + slug="${path#public/crystals/}" + slug="${slug%.svg}" + echo "https://gemmology.dev/minerals/${slug}/" >> .indexnow/urls.txt + ;; + esac + done < .indexnow/changed.txt + sort -u -o .indexnow/urls.txt .indexnow/urls.txt + fi + count=$(wc -l < .indexnow/urls.txt | tr -d ' ') + echo "count=$count" >> "$GITHUB_OUTPUT" + echo "Found $count URLs to submit" + + - name: Submit to IndexNow + if: ${{ steps.urls.outputs.count != '0' }} + env: + INDEXNOW_KEY: ${{ secrets.INDEXNOW_KEY }} + run: | + if [ -z "${INDEXNOW_KEY:-}" ]; then + echo "INDEXNOW_KEY secret not configured — skipping submission." + exit 0 + fi + mapfile -t URLS < .indexnow/urls.txt + # Build JSON array + payload=$(jq -n \ + --arg host "gemmology.dev" \ + --arg key "$INDEXNOW_KEY" \ + --arg keyLocation "https://gemmology.dev/${INDEXNOW_KEY}.txt" \ + --argjson urls "$(printf '%s\n' "${URLS[@]}" | jq -R . | jq -s .)" \ + '{host:$host, key:$key, keyLocation:$keyLocation, urlList:$urls}') + for endpoint in \ + https://api.indexnow.org/IndexNow \ + https://www.bing.com/indexnow \ + https://yandex.com/indexnow \ + https://searchadvisor.naver.com/indexnow ; do + echo "POST $endpoint" + curl -fsS -X POST "$endpoint" \ + -H 'Content-Type: application/json; charset=utf-8' \ + --data "$payload" || echo " (endpoint unreachable, continuing)" + done diff --git a/astro.config.mjs b/astro.config.mjs index e6a9c19..44acfbf 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -21,7 +21,31 @@ export default defineConfig({ }), react(), tailwind(), - sitemap(), + sitemap({ + filter: (page) => !page.includes('/admin'), + changefreq: 'weekly', + priority: 0.7, + lastmod: new Date(), + serialize(item) { + // Boost priority/lastmod for hub pages and canonical references + if (item.url === 'https://gemmology.dev/' || + item.url === 'https://gemmology.dev/gallery/' || + item.url === 'https://gemmology.dev/learn/') { + item.priority = 1.0; + item.changefreq = 'weekly'; + } else if (/\/minerals\/[^/]+\/$/.test(item.url)) { + item.priority = 0.8; + item.changefreq = 'monthly'; + } else if (/\/learn\//.test(item.url)) { + item.priority = 0.7; + item.changefreq = 'monthly'; + } else if (/\/docs\//.test(item.url)) { + item.priority = 0.5; + item.changefreq = 'monthly'; + } + return item; + }, + }), ], vite: { optimizeDeps: { diff --git a/package-lock.json b/package-lock.json index 06542bb..c6f819c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@astrojs/react": "^4.1.0", "@astrojs/sitemap": "^3.7.0", "@astrojs/tailwind": "^5.1.0", + "@fontsource-variable/inter": "^5.2.8", + "@fontsource-variable/jetbrains-mono": "^5.2.8", "@gemmology/mineral-data": "^2.2.1", "@monaco-editor/react": "^4.6.0", "@react-three/drei": "^9.105.0", @@ -951,6 +953,24 @@ "@expressive-code/core": "^0.41.6" } }, + "node_modules/@fontsource-variable/inter": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz", + "integrity": "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource-variable/jetbrains-mono": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource-variable/jetbrains-mono/-/jetbrains-mono-5.2.8.tgz", + "integrity": "sha512-WBA9elru6Jdp5df2mES55wuOO0WIrn3kpXnI4+W2ek5u3ZgLS9XS4gmIlcQhiZOWEKl95meYdvK7xI+ETLCq/Q==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@gemmology/mineral-data": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@gemmology/mineral-data/-/mineral-data-2.2.1.tgz", diff --git a/package.json b/package.json index 9ecf0fc..13e1851 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "preview": "astro preview", "copy-db": "node scripts/copy-database.js", "prerender": "node scripts/prerender-crystals.js", - "prebuild": "npm run sync && npm run copy-db", + "check-svgs": "node scripts/audit-crystal-svgs.mjs", + "prebuild": "npm run sync && npm run copy-db && npm run check-svgs", "generate-og": "npm run build && node scripts/generate-og-image.js" }, "dependencies": { @@ -18,6 +19,8 @@ "@astrojs/react": "^4.1.0", "@astrojs/sitemap": "^3.7.0", "@astrojs/tailwind": "^5.1.0", + "@fontsource-variable/inter": "^5.2.8", + "@fontsource-variable/jetbrains-mono": "^5.2.8", "@gemmology/mineral-data": "^2.2.1", "@monaco-editor/react": "^4.6.0", "@react-three/drei": "^9.105.0", diff --git a/public/48f06a3b34104910a4b95d23ad8cb13f.txt b/public/48f06a3b34104910a4b95d23ad8cb13f.txt new file mode 100644 index 0000000..88c763f --- /dev/null +++ b/public/48f06a3b34104910a4b95d23ad8cb13f.txt @@ -0,0 +1 @@ +48f06a3b34104910a4b95d23ad8cb13f diff --git a/public/_headers b/public/_headers new file mode 100644 index 0000000..655d1d2 --- /dev/null +++ b/public/_headers @@ -0,0 +1,27 @@ +/* + X-Content-Type-Options: nosniff + X-Frame-Options: DENY + Referrer-Policy: strict-origin-when-cross-origin + Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=() + Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; worker-src 'self' blob:; frame-ancestors 'none'; base-uri 'self'; form-action 'self' + Strict-Transport-Security: max-age=31536000; includeSubDomains; preload + +# Long-cache versioned static assets (Astro hashed bundle) +/_astro/* + Cache-Control: public, max-age=31536000, immutable + +# Crystal SVGs are stable per mineral id +/crystals/* + Cache-Control: public, max-age=604800, must-revalidate + +# Static GLB models +/models/* + Cache-Control: public, max-age=604800, must-revalidate + +# Database is regenerated on each build — short cache, must-revalidate +/minerals.db + Cache-Control: public, max-age=3600, must-revalidate + +# sql.js wasm +/sql.js/* + Cache-Control: public, max-age=2592000, must-revalidate diff --git a/public/_redirects b/public/_redirects new file mode 100644 index 0000000..8e136b8 --- /dev/null +++ b/public/_redirects @@ -0,0 +1,22 @@ +# Legacy flat learn slugs → topic/slug structure +# Pre-2026 site shipped /learn/; current structure is /learn//. +/learn/crystal-systems /learn/fundamentals/crystal-systems 301 +/learn/crystallography-advanced /learn/fundamentals/crystallography-advanced 301 +/learn/physical-properties /learn/fundamentals/physical-properties 301 +/learn/optical-properties /learn/fundamentals/optical-properties 301 +/learn/optical-properties-advanced /learn/fundamentals/optical-properties-advanced 301 +/learn/chemical-properties /learn/fundamentals/chemical-properties 301 +/learn/colour-theory /learn/fundamentals/colour-theory 301 +/learn/twin-laws /learn/fundamentals/twin-laws 301 +/learn/optic-sign-determination /learn/fundamentals/optic-sign-determination 301 +/learn/inclusions /learn/identification/inclusions 301 +/learn/treatments /learn/identification/treatments 301 +/learn/synthetics /learn/identification/synthetics 301 + +# Old gallery deep links +/minerals/ /gallery/ 301 +/gem/* /minerals/:splat 301 + +# Old docs +/cdl /docs/cdl 301 +/api /docs/api 301 diff --git a/public/crystals/actinolite-prism.svg b/public/crystals/actinolite-prism.svg index badda02..966aa42 100644 --- a/public/crystals/actinolite-prism.svg +++ b/public/crystals/actinolite-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.119380 + 2026-05-04T18:27:27.906484 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p752bcca1ec)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/alexandrite.svg b/public/crystals/alexandrite.svg index 8ad7956..11b52b2 100644 --- a/public/crystals/alexandrite.svg +++ b/public/crystals/alexandrite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.154437 + 2026-05-04T18:27:27.944212 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#pb599f89c9f)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/almandine-combination.svg b/public/crystals/almandine-combination.svg index 6bf9e25..1cf2266 100644 --- a/public/crystals/almandine-combination.svg +++ b/public/crystals/almandine-combination.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.253602 + 2026-05-04T18:27:28.096414 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#pd621c61ae1)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/almandine-dodecahedron.svg b/public/crystals/almandine-dodecahedron.svg index 6b2abe7..0ce2143 100644 --- a/public/crystals/almandine-dodecahedron.svg +++ b/public/crystals/almandine-dodecahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.274301 + 2026-05-04T18:27:28.125841 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/amazonite.svg b/public/crystals/amazonite.svg index 2026ef9..97563ae 100644 --- a/public/crystals/amazonite.svg +++ b/public/crystals/amazonite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.297294 + 2026-05-04T18:27:28.152478 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/ambroid.svg b/public/crystals/ambroid.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/ambroid.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/amethyst.svg b/public/crystals/amethyst.svg index 32628ff..e4a95fd 100644 --- a/public/crystals/amethyst.svg +++ b/public/crystals/amethyst.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.317476 + 2026-05-04T18:27:28.176713 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/ametrine.svg b/public/crystals/ametrine.svg new file mode 100644 index 0000000..eaac38d --- /dev/null +++ b/public/crystals/ametrine.svg @@ -0,0 +1,251 @@ + + + + + + + + 2026-05-04T18:28:52.526674 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/andalusite.svg b/public/crystals/andalusite.svg new file mode 100644 index 0000000..5ec2ba5 --- /dev/null +++ b/public/crystals/andalusite.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:52.576965 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/andesine-tabular.svg b/public/crystals/andesine-tabular.svg index 31e36c6..4cda0e4 100644 --- a/public/crystals/andesine-tabular.svg +++ b/public/crystals/andesine-tabular.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.335777 + 2026-05-04T18:27:28.200941 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pc67f8da872)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/andradite-dodecahedron.svg b/public/crystals/andradite-dodecahedron.svg index fc06f4d..78da826 100644 --- a/public/crystals/andradite-dodecahedron.svg +++ b/public/crystals/andradite-dodecahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.360824 + 2026-05-04T18:27:28.226928 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p4669a0792e)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/apatite.svg b/public/crystals/apatite.svg index d33cbcd..825a98b 100644 --- a/public/crystals/apatite.svg +++ b/public/crystals/apatite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.404084 + 2026-05-04T18:27:28.274516 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p12cc30aa6e)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/aquamarine.svg b/public/crystals/aquamarine.svg index 82eed2c..df6626c 100644 --- a/public/crystals/aquamarine.svg +++ b/public/crystals/aquamarine.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.423848 + 2026-05-04T18:27:28.298403 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p3579cc80b8)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/aragonite.svg b/public/crystals/aragonite.svg index 396d20d..baa155a 100644 --- a/public/crystals/aragonite.svg +++ b/public/crystals/aragonite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.441923 + 2026-05-04T18:27:28.321725 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/augite-prism.svg b/public/crystals/augite-prism.svg index d51c962..68095cd 100644 --- a/public/crystals/augite-prism.svg +++ b/public/crystals/augite-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.461098 + 2026-05-04T18:27:28.347605 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p167a5c21e2)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/azurite.svg b/public/crystals/azurite.svg index ae6d3f2..feeec95 100644 --- a/public/crystals/azurite.svg +++ b/public/crystals/azurite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.478496 + 2026-05-04T18:27:28.372635 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p36e957930d)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/barite.svg b/public/crystals/barite.svg index 9b09bad..28ce69f 100644 --- a/public/crystals/barite.svg +++ b/public/crystals/barite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.495853 + 2026-05-04T18:27:28.397538 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#p811c3bf999)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/benitoite.svg b/public/crystals/benitoite.svg new file mode 100644 index 0000000..c2922db --- /dev/null +++ b/public/crystals/benitoite.svg @@ -0,0 +1,289 @@ + + + + + + + + 2026-05-04T18:28:52.642751 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/beryl-prism.svg b/public/crystals/beryl-prism.svg index b9fd9fd..f9b2540 100644 --- a/public/crystals/beryl-prism.svg +++ b/public/crystals/beryl-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.512683 + 2026-05-04T18:27:28.420298 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p0c8a1df33b)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/beryl-tabular.svg b/public/crystals/beryl-tabular.svg index 33a91cc..3893a2f 100644 --- a/public/crystals/beryl-tabular.svg +++ b/public/crystals/beryl-tabular.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.529844 + 2026-05-04T18:27:28.445011 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p66468258ca)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/bone.svg b/public/crystals/bone.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/bone.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/bronzite.svg b/public/crystals/bronzite.svg new file mode 100644 index 0000000..f157f48 --- /dev/null +++ b/public/crystals/bronzite.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/bytownite-tabular.svg b/public/crystals/bytownite-tabular.svg index 3b71fa6..0fe9ca2 100644 --- a/public/crystals/bytownite-tabular.svg +++ b/public/crystals/bytownite-tabular.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.546144 + 2026-05-04T18:27:28.468946 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#p7164d8bbe2)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/calcite-nailhead.svg b/public/crystals/calcite-nailhead.svg index 1a6ba4e..d61eedc 100644 --- a/public/crystals/calcite-nailhead.svg +++ b/public/crystals/calcite-nailhead.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.603072 + 2026-05-04T18:27:28.519603 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pa16e1dece9)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/calcite-rhomb.svg b/public/crystals/calcite-rhomb.svg index 4603668..cc87efc 100644 --- a/public/crystals/calcite-rhomb.svg +++ b/public/crystals/calcite-rhomb.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.585206 + 2026-05-04T18:27:28.543703 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p7c515f8020)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/calcite-scalenohedron.svg b/public/crystals/calcite-scalenohedron.svg index 7cf5a1a..0a077e2 100644 --- a/public/crystals/calcite-scalenohedron.svg +++ b/public/crystals/calcite-scalenohedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.568174 + 2026-05-04T18:27:28.566271 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/calcite-stacked.svg b/public/crystals/calcite-stacked.svg index 3f46d35..6c9905e 100644 --- a/public/crystals/calcite-stacked.svg +++ b/public/crystals/calcite-stacked.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.621866 + 2026-05-04T18:27:28.588558 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p19d71681ad)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/cassiterite.svg b/public/crystals/cassiterite.svg index 05dc452..20de738 100644 --- a/public/crystals/cassiterite.svg +++ b/public/crystals/cassiterite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.649034 + 2026-05-04T18:27:28.620726 image/svg+xml @@ -21,69 +21,67 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - + - + - + - + - + - + - + +" clip-path="url(#pdb5d110480)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/celestine.svg b/public/crystals/celestine.svg index 9a68610..2670e0c 100644 --- a/public/crystals/celestine.svg +++ b/public/crystals/celestine.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.664156 + 2026-05-04T18:27:28.640072 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/chalcedony-botryoidal.svg b/public/crystals/chalcedony-botryoidal.svg index ab6f765..cf72459 100644 --- a/public/crystals/chalcedony-botryoidal.svg +++ b/public/crystals/chalcedony-botryoidal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.829606 + 2026-05-04T18:27:28.730064 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/chalcedony-massive.svg b/public/crystals/chalcedony-massive.svg index 1d2e8d0..8f48d87 100644 --- a/public/crystals/chalcedony-massive.svg +++ b/public/crystals/chalcedony-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:27.702872 + 2026-05-04T18:27:28.878618 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/chrome-diopside.svg b/public/crystals/chrome-diopside.svg new file mode 100644 index 0000000..b45bb91 --- /dev/null +++ b/public/crystals/chrome-diopside.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:52.691623 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/chrysoberyl-cats-eye.svg b/public/crystals/chrysoberyl-cats-eye.svg index 290b4e8..6e9c8d3 100644 --- a/public/crystals/chrysoberyl-cats-eye.svg +++ b/public/crystals/chrysoberyl-cats-eye.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.027042 + 2026-05-04T18:27:28.939200 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p0817e45cba)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/chrysoberyl-tabular.svg b/public/crystals/chrysoberyl-tabular.svg index 99380b5..048b507 100644 --- a/public/crystals/chrysoberyl-tabular.svg +++ b/public/crystals/chrysoberyl-tabular.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.009546 + 2026-05-04T18:27:28.963196 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#pbd9633c404)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/chrysoberyl-trilling.svg b/public/crystals/chrysoberyl-trilling.svg index 290e8ac..1d50bc3 100644 --- a/public/crystals/chrysoberyl-trilling.svg +++ b/public/crystals/chrysoberyl-trilling.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.046836 + 2026-05-04T18:27:28.988810 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/chrysocolla.svg b/public/crystals/chrysocolla.svg new file mode 100644 index 0000000..cb362eb --- /dev/null +++ b/public/crystals/chrysocolla.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/crystals/citrine.svg b/public/crystals/citrine.svg index 57e7438..0614b50 100644 --- a/public/crystals/citrine.svg +++ b/public/crystals/citrine.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.065474 + 2026-05-04T18:27:29.011988 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/colour-change-garnet-combination.svg b/public/crystals/colour-change-garnet-combination.svg index 0f31bfa..d56d13e 100644 --- a/public/crystals/colour-change-garnet-combination.svg +++ b/public/crystals/colour-change-garnet-combination.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.085559 + 2026-05-04T18:27:29.035210 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#pe8a468f808)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/copal.svg b/public/crystals/copal.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/copal.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/coral.svg b/public/crystals/coral.svg new file mode 100644 index 0000000..cb362eb --- /dev/null +++ b/public/crystals/coral.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/crystals/corundum-barrel.svg b/public/crystals/corundum-barrel.svg index 4df6eb1..9c3e9a5 100644 --- a/public/crystals/corundum-barrel.svg +++ b/public/crystals/corundum-barrel.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.124713 + 2026-05-04T18:27:29.060381 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#ped2e71009a)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/corundum-bipyramid.svg b/public/crystals/corundum-bipyramid.svg index a4c3f00..e53835d 100644 --- a/public/crystals/corundum-bipyramid.svg +++ b/public/crystals/corundum-bipyramid.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.106015 + 2026-05-04T18:27:29.083391 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/crocoite.svg b/public/crystals/crocoite.svg index ad0391e..ad3a209 100644 --- a/public/crystals/crocoite.svg +++ b/public/crystals/crocoite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.143123 + 2026-05-04T18:27:29.130576 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pbd4bde9c83)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/cubic-zirconia-brilliant.svg b/public/crystals/cubic-zirconia-brilliant.svg index 883935b..90dc5a8 100644 --- a/public/crystals/cubic-zirconia-brilliant.svg +++ b/public/crystals/cubic-zirconia-brilliant.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.161133 + 2026-05-04T18:27:29.152299 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/cuprite.svg b/public/crystals/cuprite.svg index 49efc89..f2b2854 100644 --- a/public/crystals/cuprite.svg +++ b/public/crystals/cuprite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.181156 + 2026-05-04T18:27:29.180516 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pad013d1330)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/demantoid.svg b/public/crystals/demantoid.svg index 3cc779d..530da3d 100644 --- a/public/crystals/demantoid.svg +++ b/public/crystals/demantoid.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.201501 + 2026-05-04T18:27:29.206356 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/diamond-cube.svg b/public/crystals/diamond-cube.svg index ed69dbc..95a1fe6 100644 --- a/public/crystals/diamond-cube.svg +++ b/public/crystals/diamond-cube.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.237520 + 2026-05-04T18:27:29.230913 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pfa36c8f571)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/diamond-macle.svg b/public/crystals/diamond-macle.svg index c75118c..86bfd58 100644 --- a/public/crystals/diamond-macle.svg +++ b/public/crystals/diamond-macle.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.292558 + 2026-05-04T18:27:29.257863 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/diamond-nested-phantom.svg b/public/crystals/diamond-nested-phantom.svg index 63529d2..703afff 100644 --- a/public/crystals/diamond-nested-phantom.svg +++ b/public/crystals/diamond-nested-phantom.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.274033 + 2026-05-04T18:27:29.281814 image/svg+xml @@ -21,109 +21,107 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/diamond-octahedron.svg b/public/crystals/diamond-octahedron.svg index 2e50ac3..edfb75f 100644 --- a/public/crystals/diamond-octahedron.svg +++ b/public/crystals/diamond-octahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.219282 + 2026-05-04T18:27:29.303395 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/diamond-phantom.svg b/public/crystals/diamond-phantom.svg index 00fe4e8..c4644c8 100644 --- a/public/crystals/diamond-phantom.svg +++ b/public/crystals/diamond-phantom.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.257576 + 2026-05-04T18:27:29.325118 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/diopside.svg b/public/crystals/diopside.svg index f29a4b9..814e328 100644 --- a/public/crystals/diopside.svg +++ b/public/crystals/diopside.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.312636 + 2026-05-04T18:27:29.350603 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pa91117d3f6)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/dravite-prism.svg b/public/crystals/dravite-prism.svg index 6fe3cc8..3d20981 100644 --- a/public/crystals/dravite-prism.svg +++ b/public/crystals/dravite-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.331922 + 2026-05-04T18:27:29.375514 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pe20c988274)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/dyed-howlite.svg b/public/crystals/dyed-howlite.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/dyed-howlite.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/dyed-magnesite.svg b/public/crystals/dyed-magnesite.svg new file mode 100644 index 0000000..a0928a6 --- /dev/null +++ b/public/crystals/dyed-magnesite.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:52.735406 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/elbaite-prism.svg b/public/crystals/elbaite-prism.svg index f8bf142..1f24c5a 100644 --- a/public/crystals/elbaite-prism.svg +++ b/public/crystals/elbaite-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.348069 + 2026-05-04T18:27:29.396605 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pd101014acd)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/emerald.svg b/public/crystals/emerald.svg index 496b5e2..368ac63 100644 --- a/public/crystals/emerald.svg +++ b/public/crystals/emerald.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.366831 + 2026-05-04T18:27:29.417151 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#peddae257a0)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/enstatite-prism.svg b/public/crystals/enstatite-prism.svg index a2e6b4f..a54d104 100644 --- a/public/crystals/enstatite-prism.svg +++ b/public/crystals/enstatite-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.385634 + 2026-05-04T18:27:29.442892 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pfed888c27c)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/epidote.svg b/public/crystals/epidote.svg index f9dd052..b514d6f 100644 --- a/public/crystals/epidote.svg +++ b/public/crystals/epidote.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.404079 + 2026-05-04T18:27:29.466268 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p8505dac60e)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/fluorite-cluster.svg b/public/crystals/fluorite-cluster.svg index 3e843da..b3c16af 100644 --- a/public/crystals/fluorite-cluster.svg +++ b/public/crystals/fluorite-cluster.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.528039 + 2026-05-04T18:27:29.490827 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/fluorite-cube.svg b/public/crystals/fluorite-cube.svg index 9be300c..24abb85 100644 --- a/public/crystals/fluorite-cube.svg +++ b/public/crystals/fluorite-cube.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.422849 + 2026-05-04T18:27:29.522226 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p92abc7d53f)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/fluorite-cuboctahedron.svg b/public/crystals/fluorite-cuboctahedron.svg index 5f02afc..e0b3edb 100644 --- a/public/crystals/fluorite-cuboctahedron.svg +++ b/public/crystals/fluorite-cuboctahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.456104 + 2026-05-04T18:27:29.548086 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/fluorite-interpenetrating.svg b/public/crystals/fluorite-interpenetrating.svg index 1b690fc..416661b 100644 --- a/public/crystals/fluorite-interpenetrating.svg +++ b/public/crystals/fluorite-interpenetrating.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.506889 + 2026-05-04T18:27:29.575548 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/fluorite-octahedron.svg b/public/crystals/fluorite-octahedron.svg index 784a472..16578b3 100644 --- a/public/crystals/fluorite-octahedron.svg +++ b/public/crystals/fluorite-octahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.439743 + 2026-05-04T18:27:29.598363 image/svg+xml @@ -21,69 +21,67 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - + - + - + - + - + - + - + +" clip-path="url(#pacb5c60fb1)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/fluorite-twin.svg b/public/crystals/fluorite-twin.svg index f2fe01c..091bc3e 100644 --- a/public/crystals/fluorite-twin.svg +++ b/public/crystals/fluorite-twin.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.481049 + 2026-05-04T18:27:29.650753 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/french-jet.svg b/public/crystals/french-jet.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/french-jet.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/galena.svg b/public/crystals/galena.svg index 80cda13..c8ce419 100644 --- a/public/crystals/galena.svg +++ b/public/crystals/galena.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.572042 + 2026-05-04T18:27:29.677421 image/svg+xml @@ -21,69 +21,67 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - + - + - + - + - + - + - + +" clip-path="url(#p8a65dc460a)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/garnet-combination.svg b/public/crystals/garnet-combination.svg index a89acc1..4f7853e 100644 --- a/public/crystals/garnet-combination.svg +++ b/public/crystals/garnet-combination.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.588917 + 2026-05-04T18:27:29.697720 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#pfeea446705)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/garnet-dodecahedron.svg b/public/crystals/garnet-dodecahedron.svg index 2c2a4e3..7a53dff 100644 --- a/public/crystals/garnet-dodecahedron.svg +++ b/public/crystals/garnet-dodecahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.609086 + 2026-05-04T18:27:29.722398 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/garnet-topped-doublet.svg b/public/crystals/garnet-topped-doublet.svg new file mode 100644 index 0000000..445a23c --- /dev/null +++ b/public/crystals/garnet-topped-doublet.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/garnet-trapezohedron.svg b/public/crystals/garnet-trapezohedron.svg index bdfa723..be5ff4f 100644 --- a/public/crystals/garnet-trapezohedron.svg +++ b/public/crystals/garnet-trapezohedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.628139 + 2026-05-04T18:27:29.745579 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p40a32c56ae)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/ggg-faceted.svg b/public/crystals/ggg-faceted.svg index 300eaec..0375e4f 100644 --- a/public/crystals/ggg-faceted.svg +++ b/public/crystals/ggg-faceted.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.649631 + 2026-05-04T18:27:29.771968 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p919b69e634)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/glass-simulant.svg b/public/crystals/glass-simulant.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/glass-simulant.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/goshenite.svg b/public/crystals/goshenite.svg new file mode 100644 index 0000000..879e454 --- /dev/null +++ b/public/crystals/goshenite.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:52.780731 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/grossular-trapezohedron.svg b/public/crystals/grossular-trapezohedron.svg index 39ec68b..ca5128a 100644 --- a/public/crystals/grossular-trapezohedron.svg +++ b/public/crystals/grossular-trapezohedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.670435 + 2026-05-04T18:27:29.796420 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/gypsum-swallowtail.svg b/public/crystals/gypsum-swallowtail.svg index 7b8840c..6533d4b 100644 --- a/public/crystals/gypsum-swallowtail.svg +++ b/public/crystals/gypsum-swallowtail.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.707713 + 2026-05-04T18:27:29.821480 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p1a1645add7)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/gypsum-tabular.svg b/public/crystals/gypsum-tabular.svg index 18bc130..7f6e2f2 100644 --- a/public/crystals/gypsum-tabular.svg +++ b/public/crystals/gypsum-tabular.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.688791 + 2026-05-04T18:27:29.845909 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p05f785c6cd)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/halite.svg b/public/crystals/halite.svg index fdb2975..03e894d 100644 --- a/public/crystals/halite.svg +++ b/public/crystals/halite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.725309 + 2026-05-04T18:27:29.869712 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pa73eb6960e)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/hauyne.svg b/public/crystals/hauyne.svg new file mode 100644 index 0000000..be08752 --- /dev/null +++ b/public/crystals/hauyne.svg @@ -0,0 +1,139 @@ + + + + + + + + 2026-05-04T18:28:52.821204 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/heliodor.svg b/public/crystals/heliodor.svg index 1f4462c..b7da9ff 100644 --- a/public/crystals/heliodor.svg +++ b/public/crystals/heliodor.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.744746 + 2026-05-04T18:27:29.892487 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p6acdca00e0)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/hematite.svg b/public/crystals/hematite.svg new file mode 100644 index 0000000..f157f48 --- /dev/null +++ b/public/crystals/hematite.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/hessonite-trapezohedron.svg b/public/crystals/hessonite-trapezohedron.svg index 33ee66d..a379019 100644 --- a/public/crystals/hessonite-trapezohedron.svg +++ b/public/crystals/hessonite-trapezohedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.762115 + 2026-05-04T18:27:29.914272 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/hiddenite.svg b/public/crystals/hiddenite.svg index 0476b2d..ee9d8d5 100644 --- a/public/crystals/hiddenite.svg +++ b/public/crystals/hiddenite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.779375 + 2026-05-04T18:27:29.936837 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p4b586e4575)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/hydrogrossular.svg b/public/crystals/hydrogrossular.svg new file mode 100644 index 0000000..ac18f9e --- /dev/null +++ b/public/crystals/hydrogrossular.svg @@ -0,0 +1,139 @@ + + + + + + + + 2026-05-04T18:28:52.929075 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/jadeite-crystal.svg b/public/crystals/jadeite-crystal.svg index 521beec..e835a05 100644 --- a/public/crystals/jadeite-crystal.svg +++ b/public/crystals/jadeite-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.881729 + 2026-05-04T18:27:29.961210 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p6e5a80e67d)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/jadeite-massive.svg b/public/crystals/jadeite-massive.svg index 9e672ed..0d4f9d7 100644 --- a/public/crystals/jadeite-massive.svg +++ b/public/crystals/jadeite-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.816927 + 2026-05-04T18:27:30.007271 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/jet.svg b/public/crystals/jet.svg new file mode 100644 index 0000000..cb362eb --- /dev/null +++ b/public/crystals/jet.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/crystals/kornerupine.svg b/public/crystals/kornerupine.svg new file mode 100644 index 0000000..6c7f52a --- /dev/null +++ b/public/crystals/kornerupine.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:52.958348 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/kunzite.svg b/public/crystals/kunzite.svg index 01b8dc0..1908d35 100644 --- a/public/crystals/kunzite.svg +++ b/public/crystals/kunzite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.900617 + 2026-05-04T18:27:30.064599 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p48a36b9b21)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/kyanite.svg b/public/crystals/kyanite.svg index 48a1201..f38beff 100644 --- a/public/crystals/kyanite.svg +++ b/public/crystals/kyanite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.918048 + 2026-05-04T18:27:30.088248 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p1572464d13)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/labradorite.svg b/public/crystals/labradorite.svg index ede1cb8..d75bad6 100644 --- a/public/crystals/labradorite.svg +++ b/public/crystals/labradorite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.934256 + 2026-05-04T18:27:30.112378 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pa8aca1f28a)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/lazurite-crystal.svg b/public/crystals/lazurite-crystal.svg index be0a6db..59a59c3 100644 --- a/public/crystals/lazurite-crystal.svg +++ b/public/crystals/lazurite-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.036677 + 2026-05-04T18:27:30.157195 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p6787d6de95)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/lazurite-massive.svg b/public/crystals/lazurite-massive.svg index 6182b21..331b12c 100644 --- a/public/crystals/lazurite-massive.svg +++ b/public/crystals/lazurite-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:28.971181 + 2026-05-04T18:27:30.201847 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/luag-faceted.svg b/public/crystals/luag-faceted.svg index 1e7c29e..043abeb 100644 --- a/public/crystals/luag-faceted.svg +++ b/public/crystals/luag-faceted.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.056507 + 2026-05-04T18:27:30.262743 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p3895176cad)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/magnetite.svg b/public/crystals/magnetite.svg index 9d7317a..54f23a1 100644 --- a/public/crystals/magnetite.svg +++ b/public/crystals/magnetite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.075350 + 2026-05-04T18:27:30.291866 image/svg+xml @@ -21,69 +21,67 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - + - + - + - + - + - + - + +" clip-path="url(#pb3c751ec43)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/malachite-crystal.svg b/public/crystals/malachite-crystal.svg index 6bbcd04..3255594 100644 --- a/public/crystals/malachite-crystal.svg +++ b/public/crystals/malachite-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.315900 + 2026-05-04T18:27:30.315738 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pe0b24ec06a)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/malachite-massive.svg b/public/crystals/malachite-massive.svg index 10076e0..ede235e 100644 --- a/public/crystals/malachite-massive.svg +++ b/public/crystals/malachite-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.153503 + 2026-05-04T18:27:30.403523 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/maw-sit-sit.svg b/public/crystals/maw-sit-sit.svg new file mode 100644 index 0000000..f157f48 --- /dev/null +++ b/public/crystals/maw-sit-sit.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/maxixe-beryl.svg b/public/crystals/maxixe-beryl.svg new file mode 100644 index 0000000..832f35a --- /dev/null +++ b/public/crystals/maxixe-beryl.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:52.984110 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/moissanite-faceted.svg b/public/crystals/moissanite-faceted.svg index d843efe..ef96aec 100644 --- a/public/crystals/moissanite-faceted.svg +++ b/public/crystals/moissanite-faceted.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.334348 + 2026-05-04T18:27:30.532835 image/svg+xml @@ -21,42 +21,40 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/moldavite.svg b/public/crystals/moldavite.svg new file mode 100644 index 0000000..cb362eb --- /dev/null +++ b/public/crystals/moldavite.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/crystals/moonstone.svg b/public/crystals/moonstone.svg index 104bfba..a3e91ee 100644 --- a/public/crystals/moonstone.svg +++ b/public/crystals/moonstone.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.367962 + 2026-05-04T18:27:30.554964 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#pf1d02cc8e6)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/morganite.svg b/public/crystals/morganite.svg index 60ae3af..309bb0a 100644 --- a/public/crystals/morganite.svg +++ b/public/crystals/morganite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.385673 + 2026-05-04T18:27:30.579133 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pfb4ddf4ee4)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/musgravite.svg b/public/crystals/musgravite.svg new file mode 100644 index 0000000..dabc852 --- /dev/null +++ b/public/crystals/musgravite.svg @@ -0,0 +1,251 @@ + + + + + + + + 2026-05-04T18:28:53.010601 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/nephrite-massive.svg b/public/crystals/nephrite-massive.svg index 94e2232..1c9de27 100644 --- a/public/crystals/nephrite-massive.svg +++ b/public/crystals/nephrite-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.422984 + 2026-05-04T18:27:30.624284 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/obsidian.svg b/public/crystals/obsidian.svg new file mode 100644 index 0000000..cb362eb --- /dev/null +++ b/public/crystals/obsidian.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/crystals/opal-doublet.svg b/public/crystals/opal-doublet.svg new file mode 100644 index 0000000..445a23c --- /dev/null +++ b/public/crystals/opal-doublet.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/opal-triplet.svg b/public/crystals/opal-triplet.svg new file mode 100644 index 0000000..445a23c --- /dev/null +++ b/public/crystals/opal-triplet.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/opal.svg b/public/crystals/opal.svg index 8d93da8..7d99c9e 100644 --- a/public/crystals/opal.svg +++ b/public/crystals/opal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.550087 + 2026-05-04T18:27:30.751987 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/orpiment.svg b/public/crystals/orpiment.svg index c3a914d..7d71cf5 100644 --- a/public/crystals/orpiment.svg +++ b/public/crystals/orpiment.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.710558 + 2026-05-04T18:27:30.933755 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p406cd79538)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/orthoclase-baveno.svg b/public/crystals/orthoclase-baveno.svg index bb8a49a..873284f 100644 --- a/public/crystals/orthoclase-baveno.svg +++ b/public/crystals/orthoclase-baveno.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.768761 + 2026-05-04T18:27:30.962088 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#pdbff432799)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/orthoclase-carlsbad.svg b/public/crystals/orthoclase-carlsbad.svg index 66e3eac..7eb960a 100644 --- a/public/crystals/orthoclase-carlsbad.svg +++ b/public/crystals/orthoclase-carlsbad.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.748330 + 2026-05-04T18:27:30.988921 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/orthoclase-prismatic.svg b/public/crystals/orthoclase-prismatic.svg index 3dfa69b..7bee152 100644 --- a/public/crystals/orthoclase-prismatic.svg +++ b/public/crystals/orthoclase-prismatic.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.727090 + 2026-05-04T18:27:31.016174 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#p225da28bec)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/padparadscha-bipyramid.svg b/public/crystals/padparadscha-bipyramid.svg index 5977245..e124e62 100644 --- a/public/crystals/padparadscha-bipyramid.svg +++ b/public/crystals/padparadscha-bipyramid.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.787992 + 2026-05-04T18:27:31.039393 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pe288ce1121)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pearl-aragonite.svg b/public/crystals/pearl-aragonite.svg index c1f959d..38c405e 100644 --- a/public/crystals/pearl-aragonite.svg +++ b/public/crystals/pearl-aragonite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.858266 + 2026-05-04T18:27:31.064881 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pearl-nacre.svg b/public/crystals/pearl-nacre.svg index 3843b83..0363abd 100644 --- a/public/crystals/pearl-nacre.svg +++ b/public/crystals/pearl-nacre.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.816896 + 2026-05-04T18:27:31.102091 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/peridot.svg b/public/crystals/peridot.svg index b293155..f156354 100644 --- a/public/crystals/peridot.svg +++ b/public/crystals/peridot.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.875996 + 2026-05-04T18:27:31.143138 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p10ff86cf1e)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pink-sapphire-bipyramid.svg b/public/crystals/pink-sapphire-bipyramid.svg index 2c7b926..0bdaa61 100644 --- a/public/crystals/pink-sapphire-bipyramid.svg +++ b/public/crystals/pink-sapphire-bipyramid.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.893229 + 2026-05-04T18:27:31.168028 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p9d19606ab0)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/plagioclase-albite.svg b/public/crystals/plagioclase-albite.svg index 5880aba..03ac8a9 100644 --- a/public/crystals/plagioclase-albite.svg +++ b/public/crystals/plagioclase-albite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.911802 + 2026-05-04T18:27:31.193009 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pyrite-cluster.svg b/public/crystals/pyrite-cluster.svg index 98d286a..9eadcee 100644 --- a/public/crystals/pyrite-cluster.svg +++ b/public/crystals/pyrite-cluster.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.996462 + 2026-05-04T18:27:31.217528 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pyrite-cube.svg b/public/crystals/pyrite-cube.svg index 9740abb..3d99219 100644 --- a/public/crystals/pyrite-cube.svg +++ b/public/crystals/pyrite-cube.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.930913 + 2026-05-04T18:27:31.246527 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pacc5a82b3e)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pyrite-iron-cross.svg b/public/crystals/pyrite-iron-cross.svg index 4b489dc..c770baf 100644 --- a/public/crystals/pyrite-iron-cross.svg +++ b/public/crystals/pyrite-iron-cross.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.974993 + 2026-05-04T18:27:31.275869 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pyrite-pyritohedron.svg b/public/crystals/pyrite-pyritohedron.svg index fb9f68d..81e1f71 100644 --- a/public/crystals/pyrite-pyritohedron.svg +++ b/public/crystals/pyrite-pyritohedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:29.953962 + 2026-05-04T18:27:31.302666 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/pyrope-dodecahedron.svg b/public/crystals/pyrope-dodecahedron.svg index 0dd132a..c9b3838 100644 --- a/public/crystals/pyrope-dodecahedron.svg +++ b/public/crystals/pyrope-dodecahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.022172 + 2026-05-04T18:27:31.329839 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p6c9b1d8cb6)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-amethyst-geode.svg b/public/crystals/quartz-amethyst-geode.svg index 20451fa..4458f58 100644 --- a/public/crystals/quartz-amethyst-geode.svg +++ b/public/crystals/quartz-amethyst-geode.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.284974 + 2026-05-04T18:27:31.373566 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-brazil-twin.svg b/public/crystals/quartz-brazil-twin.svg index 360af09..f90f886 100644 --- a/public/crystals/quartz-brazil-twin.svg +++ b/public/crystals/quartz-brazil-twin.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.209751 + 2026-05-04T18:27:31.445386 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p132d7a71ba)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-cluster.svg b/public/crystals/quartz-cluster.svg index 7778835..7f3dcba 100644 --- a/public/crystals/quartz-cluster.svg +++ b/public/crystals/quartz-cluster.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.235585 + 2026-05-04T18:27:31.473150 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-dauphine-twin.svg b/public/crystals/quartz-dauphine-twin.svg index 98a7122..042737a 100644 --- a/public/crystals/quartz-dauphine-twin.svg +++ b/public/crystals/quartz-dauphine-twin.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.187768 + 2026-05-04T18:27:31.531793 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-faden.svg b/public/crystals/quartz-faden.svg index 6a15426..07d906f 100644 --- a/public/crystals/quartz-faden.svg +++ b/public/crystals/quartz-faden.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.124479 + 2026-05-04T18:27:31.553882 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-japan-twin.svg b/public/crystals/quartz-japan-twin.svg index a3e5a9e..24b5e59 100644 --- a/public/crystals/quartz-japan-twin.svg +++ b/public/crystals/quartz-japan-twin.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.166385 + 2026-05-04T18:27:31.580883 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#pe4458b96ea)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-phantom.svg b/public/crystals/quartz-phantom.svg index 85c14bc..8cc2e40 100644 --- a/public/crystals/quartz-phantom.svg +++ b/public/crystals/quartz-phantom.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.102430 + 2026-05-04T18:27:31.605839 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p9f628ac999)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-prism.svg b/public/crystals/quartz-prism.svg index c6a4708..2ba3394 100644 --- a/public/crystals/quartz-prism.svg +++ b/public/crystals/quartz-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.042563 + 2026-05-04T18:27:31.630388 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-scepter.svg b/public/crystals/quartz-scepter.svg index f13d280..6674507 100644 --- a/public/crystals/quartz-scepter.svg +++ b/public/crystals/quartz-scepter.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.080163 + 2026-05-04T18:27:31.655038 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p1462cf7f6f)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/quartz-short.svg b/public/crystals/quartz-short.svg index ad05ca1..edd9084 100644 --- a/public/crystals/quartz-short.svg +++ b/public/crystals/quartz-short.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.060316 + 2026-05-04T18:27:31.679369 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/realgar.svg b/public/crystals/realgar.svg index be77b2d..d5efb4d 100644 --- a/public/crystals/realgar.svg +++ b/public/crystals/realgar.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.372021 + 2026-05-04T18:27:31.702871 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#pd690605d2f)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/reconstructed-turquoise.svg b/public/crystals/reconstructed-turquoise.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/reconstructed-turquoise.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/red-beryl.svg b/public/crystals/red-beryl.svg index d1c5886..0fd8103 100644 --- a/public/crystals/red-beryl.svg +++ b/public/crystals/red-beryl.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.389247 + 2026-05-04T18:27:31.725285 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pf52cc11b6d)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/rhodochrosite-banded.svg b/public/crystals/rhodochrosite-banded.svg index c1c616c..b43eef2 100644 --- a/public/crystals/rhodochrosite-banded.svg +++ b/public/crystals/rhodochrosite-banded.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.435941 + 2026-05-04T18:27:31.783573 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/rhodochrosite.svg b/public/crystals/rhodochrosite.svg index 52329ec..445f1cd 100644 --- a/public/crystals/rhodochrosite.svg +++ b/public/crystals/rhodochrosite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.407898 + 2026-05-04T18:27:31.747974 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pdc9fe8c1c8)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/rhodolite.svg b/public/crystals/rhodolite.svg index ca4b62b..501456c 100644 --- a/public/crystals/rhodolite.svg +++ b/public/crystals/rhodolite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.478716 + 2026-05-04T18:27:31.832226 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p28bfcb37c3)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/rhodonite.svg b/public/crystals/rhodonite.svg index 933ebd7..1b7cbc2 100644 --- a/public/crystals/rhodonite.svg +++ b/public/crystals/rhodonite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.499536 + 2026-05-04T18:27:31.876242 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#p6bc4e21844)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/rose-quartz-massive.svg b/public/crystals/rose-quartz-massive.svg index 0397a3c..a9b2986 100644 --- a/public/crystals/rose-quartz-massive.svg +++ b/public/crystals/rose-quartz-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.535089 + 2026-05-04T18:27:31.921727 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/rose-quartz-star.svg b/public/crystals/rose-quartz-star.svg index 440bd68..5a50c73 100644 --- a/public/crystals/rose-quartz-star.svg +++ b/public/crystals/rose-quartz-star.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.622270 + 2026-05-04T18:27:32.003732 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/ruby-star.svg b/public/crystals/ruby-star.svg index 108b4d2..6039373 100644 --- a/public/crystals/ruby-star.svg +++ b/public/crystals/ruby-star.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.704514 + 2026-05-04T18:27:32.098552 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pc07a9e80b1)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/ruby.svg b/public/crystals/ruby.svg index 67fabcf..4eb7b84 100644 --- a/public/crystals/ruby.svg +++ b/public/crystals/ruby.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.687733 + 2026-05-04T18:27:32.069701 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p4b83d2bd63)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/rutile.svg b/public/crystals/rutile.svg index d13d7ae..71a052e 100644 --- a/public/crystals/rutile.svg +++ b/public/crystals/rutile.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.721764 + 2026-05-04T18:27:32.166803 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + - + - + +" clip-path="url(#peed5662801)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/sanidine-tabular.svg b/public/crystals/sanidine-tabular.svg index 9036946..6527be6 100644 --- a/public/crystals/sanidine-tabular.svg +++ b/public/crystals/sanidine-tabular.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.739655 + 2026-05-04T18:27:32.193876 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#p572e04ae86)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/sapphire-star.svg b/public/crystals/sapphire-star.svg index fed57f2..e71248a 100644 --- a/public/crystals/sapphire-star.svg +++ b/public/crystals/sapphire-star.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.773937 + 2026-05-04T18:27:32.260332 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#p8b6959e9e3)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/sapphire.svg b/public/crystals/sapphire.svg index 61c0a04..b002548 100644 --- a/public/crystals/sapphire.svg +++ b/public/crystals/sapphire.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.756084 + 2026-05-04T18:27:32.231601 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/scapolite.svg b/public/crystals/scapolite.svg new file mode 100644 index 0000000..f157f48 --- /dev/null +++ b/public/crystals/scapolite.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/scheelite.svg b/public/crystals/scheelite.svg index 73c348e..d4f01ed 100644 --- a/public/crystals/scheelite.svg +++ b/public/crystals/scheelite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.793534 + 2026-05-04T18:27:32.293362 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p19a3b6f1f1)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/schorl-prism.svg b/public/crystals/schorl-prism.svg index 7a8939f..a313747 100644 --- a/public/crystals/schorl-prism.svg +++ b/public/crystals/schorl-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.810835 + 2026-05-04T18:27:32.320814 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pa9079711e7)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/serpentine.svg b/public/crystals/serpentine.svg new file mode 100644 index 0000000..f157f48 --- /dev/null +++ b/public/crystals/serpentine.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/sinhalite.svg b/public/crystals/sinhalite.svg new file mode 100644 index 0000000..29327a7 --- /dev/null +++ b/public/crystals/sinhalite.svg @@ -0,0 +1,147 @@ + + + + + + + + 2026-05-04T18:28:53.041209 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/slocum-stone.svg b/public/crystals/slocum-stone.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/slocum-stone.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/smoky-quartz-morion.svg b/public/crystals/smoky-quartz-morion.svg index 822d3d1..d7c4e36 100644 --- a/public/crystals/smoky-quartz-morion.svg +++ b/public/crystals/smoky-quartz-morion.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.846594 + 2026-05-04T18:27:32.347232 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/smoky-quartz-prism.svg b/public/crystals/smoky-quartz-prism.svg index 57ce8f2..326a0c8 100644 --- a/public/crystals/smoky-quartz-prism.svg +++ b/public/crystals/smoky-quartz-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.827391 + 2026-05-04T18:27:32.376807 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/sodalite-crystal.svg b/public/crystals/sodalite-crystal.svg index 6704d11..3a998fc 100644 --- a/public/crystals/sodalite-crystal.svg +++ b/public/crystals/sodalite-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.949738 + 2026-05-04T18:27:32.405801 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pa31968e51a)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/sodalite-massive.svg b/public/crystals/sodalite-massive.svg index 257a2fe..70a1367 100644 --- a/public/crystals/sodalite-massive.svg +++ b/public/crystals/sodalite-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.884228 + 2026-05-04T18:27:32.456639 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/soude-emerald.svg b/public/crystals/soude-emerald.svg new file mode 100644 index 0000000..445a23c --- /dev/null +++ b/public/crystals/soude-emerald.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/spessartine.svg b/public/crystals/spessartine.svg index 731adb2..f50ef9f 100644 --- a/public/crystals/spessartine.svg +++ b/public/crystals/spessartine.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.969022 + 2026-05-04T18:27:32.519252 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/sphene.svg b/public/crystals/sphene.svg index e04aef4..61af1b0 100644 --- a/public/crystals/sphene.svg +++ b/public/crystals/sphene.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:30.986372 + 2026-05-04T18:27:32.545057 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p16ccbc51b1)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/spinel-macle.svg b/public/crystals/spinel-macle.svg index ea4a1fa..dc6e98c 100644 --- a/public/crystals/spinel-macle.svg +++ b/public/crystals/spinel-macle.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.038356 + 2026-05-04T18:27:32.570364 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/spinel-octahedron.svg b/public/crystals/spinel-octahedron.svg index 762fb71..40d34a5 100644 --- a/public/crystals/spinel-octahedron.svg +++ b/public/crystals/spinel-octahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.021437 + 2026-05-04T18:27:32.595037 image/svg+xml @@ -21,69 +21,67 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - + - + - + - + - + - + - + +" clip-path="url(#p9a6083a7c4)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/spodumene-prism.svg b/public/crystals/spodumene-prism.svg index 8c185b8..786b39a 100644 --- a/public/crystals/spodumene-prism.svg +++ b/public/crystals/spodumene-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.057247 + 2026-05-04T18:27:32.618360 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#pa981e6cacb)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/star-diopside.svg b/public/crystals/star-diopside.svg new file mode 100644 index 0000000..f157f48 --- /dev/null +++ b/public/crystals/star-diopside.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/staurolite-cross-60.svg b/public/crystals/staurolite-cross-60.svg index a3f5c79..5639c49 100644 --- a/public/crystals/staurolite-cross-60.svg +++ b/public/crystals/staurolite-cross-60.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.100118 + 2026-05-04T18:27:32.645521 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/staurolite-cross-90.svg b/public/crystals/staurolite-cross-90.svg index eca0a38..fbc2f82 100644 --- a/public/crystals/staurolite-cross-90.svg +++ b/public/crystals/staurolite-cross-90.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.078228 + 2026-05-04T18:27:32.673688 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/strontium-titanate-faceted.svg b/public/crystals/strontium-titanate-faceted.svg index c4332ef..b0f4559 100644 --- a/public/crystals/strontium-titanate-faceted.svg +++ b/public/crystals/strontium-titanate-faceted.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.119851 + 2026-05-04T18:27:32.700812 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p826d94a3cf)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/sunstone.svg b/public/crystals/sunstone.svg index cff5c0e..820e569 100644 --- a/public/crystals/sunstone.svg +++ b/public/crystals/sunstone.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.139197 + 2026-05-04T18:27:32.754419 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pd082bf6d20)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-alexandrite-czochralski-boule.svg b/public/crystals/synthetic-alexandrite-czochralski-boule.svg index 4bdc29c..c4e9d93 100644 --- a/public/crystals/synthetic-alexandrite-czochralski-boule.svg +++ b/public/crystals/synthetic-alexandrite-czochralski-boule.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.156094 + 2026-05-04T18:27:32.776187 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p3958e5ed56)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-alexandrite-flux.svg b/public/crystals/synthetic-alexandrite-flux.svg new file mode 100644 index 0000000..33b3643 --- /dev/null +++ b/public/crystals/synthetic-alexandrite-flux.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:53.068570 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/synthetic-alexandrite-hydrothermal.svg b/public/crystals/synthetic-alexandrite-hydrothermal.svg new file mode 100644 index 0000000..370e4c0 --- /dev/null +++ b/public/crystals/synthetic-alexandrite-hydrothermal.svg @@ -0,0 +1,167 @@ + + + + + + + + 2026-05-04T18:28:53.095376 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/synthetic-coral.svg b/public/crystals/synthetic-coral.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/synthetic-coral.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/synthetic-diamond-cvd-plate.svg b/public/crystals/synthetic-diamond-cvd-plate.svg index 7525b46..e2879e3 100644 --- a/public/crystals/synthetic-diamond-cvd-plate.svg +++ b/public/crystals/synthetic-diamond-cvd-plate.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.172334 + 2026-05-04T18:27:32.800541 image/svg+xml @@ -21,69 +21,67 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - + - + - + - + - + - + - + +" clip-path="url(#p1a692b97aa)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-diamond-hpht-cuboctahedron.svg b/public/crystals/synthetic-diamond-hpht-cuboctahedron.svg index 75116e1..f817513 100644 --- a/public/crystals/synthetic-diamond-hpht-cuboctahedron.svg +++ b/public/crystals/synthetic-diamond-hpht-cuboctahedron.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.188621 + 2026-05-04T18:27:32.824635 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-emerald-flux-crystal.svg b/public/crystals/synthetic-emerald-flux-crystal.svg index 6b66a00..1dd74d7 100644 --- a/public/crystals/synthetic-emerald-flux-crystal.svg +++ b/public/crystals/synthetic-emerald-flux-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.207985 + 2026-05-04T18:27:32.847858 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pdc6af35a69)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-emerald-hydrothermal-crystal.svg b/public/crystals/synthetic-emerald-hydrothermal-crystal.svg index 23de297..4aba681 100644 --- a/public/crystals/synthetic-emerald-hydrothermal-crystal.svg +++ b/public/crystals/synthetic-emerald-hydrothermal-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.225904 + 2026-05-04T18:27:32.874127 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-emerald-lechleitner.svg b/public/crystals/synthetic-emerald-lechleitner.svg new file mode 100644 index 0000000..f157f48 --- /dev/null +++ b/public/crystals/synthetic-emerald-lechleitner.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/synthetic-lapis-gilson.svg b/public/crystals/synthetic-lapis-gilson.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/synthetic-lapis-gilson.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/synthetic-opal-gilson.svg b/public/crystals/synthetic-opal-gilson.svg new file mode 100644 index 0000000..cb362eb --- /dev/null +++ b/public/crystals/synthetic-opal-gilson.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/crystals/synthetic-paraiba-crystal.svg b/public/crystals/synthetic-paraiba-crystal.svg index 7238b96..82cb35d 100644 --- a/public/crystals/synthetic-paraiba-crystal.svg +++ b/public/crystals/synthetic-paraiba-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.245827 + 2026-05-04T18:27:32.896879 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p117e043d1d)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-quartz-hydrothermal-crystal.svg b/public/crystals/synthetic-quartz-hydrothermal-crystal.svg index 09db50c..b0f0d3b 100644 --- a/public/crystals/synthetic-quartz-hydrothermal-crystal.svg +++ b/public/crystals/synthetic-quartz-hydrothermal-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.263086 + 2026-05-04T18:27:32.922499 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-ruby-flux-crystal.svg b/public/crystals/synthetic-ruby-flux-crystal.svg index 1124204..8f83090 100644 --- a/public/crystals/synthetic-ruby-flux-crystal.svg +++ b/public/crystals/synthetic-ruby-flux-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.281647 + 2026-05-04T18:27:32.945993 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-ruby-hydrothermal.svg b/public/crystals/synthetic-ruby-hydrothermal.svg new file mode 100644 index 0000000..80101b2 --- /dev/null +++ b/public/crystals/synthetic-ruby-hydrothermal.svg @@ -0,0 +1,251 @@ + + + + + + + + 2026-05-04T18:28:53.119846 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/synthetic-ruby-kashan-flux.svg b/public/crystals/synthetic-ruby-kashan-flux.svg new file mode 100644 index 0000000..4c78a42 --- /dev/null +++ b/public/crystals/synthetic-ruby-kashan-flux.svg @@ -0,0 +1,251 @@ + + + + + + + + 2026-05-04T18:28:53.169944 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/synthetic-ruby-verneuil-boule.svg b/public/crystals/synthetic-ruby-verneuil-boule.svg index f0f1587..333f7f6 100644 --- a/public/crystals/synthetic-ruby-verneuil-boule.svg +++ b/public/crystals/synthetic-ruby-verneuil-boule.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.301367 + 2026-05-04T18:27:32.972127 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pc717645322)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-rutile-faceted.svg b/public/crystals/synthetic-rutile-faceted.svg index 2d5a671..2c52336 100644 --- a/public/crystals/synthetic-rutile-faceted.svg +++ b/public/crystals/synthetic-rutile-faceted.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.318604 + 2026-05-04T18:27:32.997616 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#pb5c6434263)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-sapphire-czochralski.svg b/public/crystals/synthetic-sapphire-czochralski.svg new file mode 100644 index 0000000..ebf9019 --- /dev/null +++ b/public/crystals/synthetic-sapphire-czochralski.svg @@ -0,0 +1,251 @@ + + + + + + + + 2026-05-04T18:28:53.196567 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/synthetic-sapphire-flux-crystal.svg b/public/crystals/synthetic-sapphire-flux-crystal.svg index 5d1ec07..a66c67c 100644 --- a/public/crystals/synthetic-sapphire-flux-crystal.svg +++ b/public/crystals/synthetic-sapphire-flux-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.338104 + 2026-05-04T18:27:33.021765 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-sapphire-verneuil-boule.svg b/public/crystals/synthetic-sapphire-verneuil-boule.svg index 76c3479..b22e510 100644 --- a/public/crystals/synthetic-sapphire-verneuil-boule.svg +++ b/public/crystals/synthetic-sapphire-verneuil-boule.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.358612 + 2026-05-04T18:27:33.048753 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-spinel-verneuil-boule.svg b/public/crystals/synthetic-spinel-verneuil-boule.svg index 73ed400..ad2e3dc 100644 --- a/public/crystals/synthetic-spinel-verneuil-boule.svg +++ b/public/crystals/synthetic-spinel-verneuil-boule.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.375138 + 2026-05-04T18:27:33.072319 image/svg+xml @@ -21,69 +21,67 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - + - + - + - + - + - + - + +" clip-path="url(#p5d741f991d)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/synthetic-turquoise-gilson-cabochon.svg b/public/crystals/synthetic-turquoise-gilson-cabochon.svg index dee9c7a..b54f6d5 100644 --- a/public/crystals/synthetic-turquoise-gilson-cabochon.svg +++ b/public/crystals/synthetic-turquoise-gilson-cabochon.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.389808 + 2026-05-04T18:27:33.094543 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pc0dea6976c)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/taaffeite.svg b/public/crystals/taaffeite.svg new file mode 100644 index 0000000..1d4d223 --- /dev/null +++ b/public/crystals/taaffeite.svg @@ -0,0 +1,251 @@ + + + + + + + + 2026-05-04T18:28:53.223255 + image/svg+xml + + + Matplotlib v3.10.8, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crystals/tanzanite.svg b/public/crystals/tanzanite.svg index 23a6805..cd13e47 100644 --- a/public/crystals/tanzanite.svg +++ b/public/crystals/tanzanite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.406851 + 2026-05-04T18:27:33.116196 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pdb438a3997)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/topaz-prism.svg b/public/crystals/topaz-prism.svg index 7e07cff..87d79bc 100644 --- a/public/crystals/topaz-prism.svg +++ b/public/crystals/topaz-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.423670 + 2026-05-04T18:27:33.138918 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p2c1e62742b)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/topaz-tabular.svg b/public/crystals/topaz-tabular.svg index c0d64a0..8a46fd1 100644 --- a/public/crystals/topaz-tabular.svg +++ b/public/crystals/topaz-tabular.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.441086 + 2026-05-04T18:27:33.163599 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p71caf9fa2b)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/tourmaline-prism.svg b/public/crystals/tourmaline-prism.svg index b97a2d3..5f31016 100644 --- a/public/crystals/tourmaline-prism.svg +++ b/public/crystals/tourmaline-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.459437 + 2026-05-04T18:27:33.185410 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pc018951d16)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/tourmaline-watermelon.svg b/public/crystals/tourmaline-watermelon.svg index 0f94b8b..e822087 100644 --- a/public/crystals/tourmaline-watermelon.svg +++ b/public/crystals/tourmaline-watermelon.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.478122 + 2026-05-04T18:27:33.246842 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#pf3ef24f3e7)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/tremolite-prism.svg b/public/crystals/tremolite-prism.svg index fe4ed05..bd18233 100644 --- a/public/crystals/tremolite-prism.svg +++ b/public/crystals/tremolite-prism.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.494557 + 2026-05-04T18:27:33.268905 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - +" style="stroke: #0369a1; stroke-opacity: 0.3"/> - - + + - - + - + - + - + - + +" clip-path="url(#p3923d5cda5)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/tsavorite.svg b/public/crystals/tsavorite.svg index 3c4844f..378f122 100644 --- a/public/crystals/tsavorite.svg +++ b/public/crystals/tsavorite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.514267 + 2026-05-04T18:27:33.294526 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p1b1f23fb5b)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/turquoise-crystal.svg b/public/crystals/turquoise-crystal.svg index d9a8ab4..d9f9f75 100644 --- a/public/crystals/turquoise-crystal.svg +++ b/public/crystals/turquoise-crystal.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.620715 + 2026-05-04T18:27:33.322611 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + +" clip-path="url(#p813dc119f4)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/turquoise-massive.svg b/public/crystals/turquoise-massive.svg index 3da869a..e978ac0 100644 --- a/public/crystals/turquoise-massive.svg +++ b/public/crystals/turquoise-massive.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.554323 + 2026-05-04T18:27:33.369695 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/uvarovite-druse.svg b/public/crystals/uvarovite-druse.svg index d371d59..824be4c 100644 --- a/public/crystals/uvarovite-druse.svg +++ b/public/crystals/uvarovite-druse.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.693896 + 2026-05-04T18:27:33.468008 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/vesuvianite.svg b/public/crystals/vesuvianite.svg index c21110d..b5e470b 100644 --- a/public/crystals/vesuvianite.svg +++ b/public/crystals/vesuvianite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.851527 + 2026-05-04T18:27:33.597283 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + +" clip-path="url(#p5f6927fc8a)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/vulcanite.svg b/public/crystals/vulcanite.svg new file mode 100644 index 0000000..2889122 --- /dev/null +++ b/public/crystals/vulcanite.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/crystals/wulfenite.svg b/public/crystals/wulfenite.svg index 40bc03b..79ebbe8 100644 --- a/public/crystals/wulfenite.svg +++ b/public/crystals/wulfenite.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.869194 + 2026-05-04T18:27:33.622738 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + - + - + - + - + - + - + +" clip-path="url(#pea00a03f9e)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/yag-faceted.svg b/public/crystals/yag-faceted.svg index fbca92f..33b1501 100644 --- a/public/crystals/yag-faceted.svg +++ b/public/crystals/yag-faceted.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.886963 + 2026-05-04T18:27:33.649400 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" clip-path="url(#p5cd481dd21)" style="fill: #0ea5e9; fill-opacity: 0.7; stroke: #0369a1; stroke-opacity: 0.7; stroke-width: 1.5"/> - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/crystals/zircon.svg b/public/crystals/zircon.svg index b55d7ac..6fb6ff5 100644 --- a/public/crystals/zircon.svg +++ b/public/crystals/zircon.svg @@ -1,12 +1,12 @@ - + - 2026-02-17T11:54:31.907137 + 2026-05-04T18:27:33.676055 image/svg+xml @@ -21,27 +21,25 @@ - +" style="fill: #ffffff"/> - +" style="fill: #ffffff"/> - - - + + - - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/public/robots.txt b/public/robots.txt index 5261405..a859c94 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -10,6 +10,9 @@ Sitemap: https://gemmology.dev/sitemap-index.xml # Disallow API endpoints (served by separate worker) Disallow: /api/ +# Disallow admin surface +Disallow: /admin/ + # Allow all crawlers to access static assets Allow: /crystals/ Allow: /og-images/ diff --git a/scripts/audit-crystal-svgs.mjs b/scripts/audit-crystal-svgs.mjs new file mode 100644 index 0000000..9b0e143 --- /dev/null +++ b/scripts/audit-crystal-svgs.mjs @@ -0,0 +1,35 @@ +#!/usr/bin/env node +/** + * Verify that every mineral_families row has a corresponding SVG in public/crystals/. + * Exits non-zero if any are missing. + */ +import { existsSync, readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import initSqlJs from 'sql.js'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ROOT = join(__dirname, '..'); +const DB_PATH = join(ROOT, 'node_modules', '@gemmology', 'mineral-data', 'minerals.db'); +const CRYSTALS_DIR = join(ROOT, 'public', 'crystals'); + +if (!existsSync(DB_PATH)) { + console.error(`mineral-data not installed at ${DB_PATH} — run npm install`); + process.exit(1); +} + +const SQL = await initSqlJs(); +const db = new SQL.Database(readFileSync(DB_PATH)); +const result = db.exec('SELECT id FROM mineral_families ORDER BY id'); +const ids = result[0].values.map((row) => row[0]); + +const missing = ids.filter((id) => !existsSync(join(CRYSTALS_DIR, `${id}.svg`))); + +if (missing.length === 0) { + console.log(`OK: all ${ids.length} mineral families have SVGs in public/crystals/`); + process.exit(0); +} + +console.error(`MISSING ${missing.length}/${ids.length} SVGs:`); +for (const id of missing) console.error(` - ${id}`); +process.exit(1); diff --git a/scripts/generate-missing-crystals.py b/scripts/generate-missing-crystals.py new file mode 100644 index 0000000..1ab5fde --- /dev/null +++ b/scripts/generate-missing-crystals.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +""" +Generate SVGs for mineral families missing from public/crystals/. + +Reads CDL expressions from the @gemmology/mineral-data SQLite DB +and renders missing families. For amorphous/composite/simulant +materials with no crystal morphology, writes a placeholder SVG. + +Usage: + python scripts/generate-missing-crystals.py +""" + +import sqlite3 +import sys +from pathlib import Path + +ROOT = Path(__file__).parent.parent +OUTPUT_DIR = ROOT / "public" / "crystals" +DB_PATH = ROOT / "node_modules" / "@gemmology" / "mineral-data" / "minerals.db" + +PLACEHOLDER_TEMPLATES = { + "amorphous": ''' + + + + + + + + + +''', + "composite": ''' + + + + +''', + "simulant": ''' + + + + +''', + "default": ''' + + + + +''', +} + + +def render_cdl_to_svg(cdl_string: str, output_path: Path) -> bool: + try: + from cdl_parser import parse_cdl + from crystal_geometry import cdl_to_geometry + from crystal_renderer.visualization import generate_geometry_svg + except ImportError as e: + print(f"ERR: missing toolchain: {e}", file=sys.stderr) + return False + + try: + parsed = parse_cdl(cdl_string) + geometry = cdl_to_geometry(parsed) + if not geometry or not geometry.is_valid or len(geometry.vertices) == 0: + return False + generate_geometry_svg( + geometry.vertices, + geometry.faces, + output_path, + face_normals=geometry.face_normals, + show_axes=False, + show_grid=False, + dpi=144, + ) + return True + except Exception as e: + print(f" parse/render failed: {e}") + return False + + +def main(): + if not DB_PATH.exists(): + print(f"DB not found at {DB_PATH}; run npm install first.", file=sys.stderr) + sys.exit(1) + + OUTPUT_DIR.mkdir(parents=True, exist_ok=True) + + conn = sqlite3.connect(DB_PATH) + conn.row_factory = sqlite3.Row + + families = conn.execute( + "SELECT id, crystal_system, origin, category FROM mineral_families ORDER BY id" + ).fetchall() + + rendered = 0 + placeholder = 0 + skipped = 0 + failed = [] + + for fam in families: + fid = fam["id"] + out = OUTPUT_DIR / f"{fid}.svg" + if out.exists(): + skipped += 1 + continue + + # Find the best expression — prefer "default", else first non-empty CDL + rows = conn.execute( + "SELECT slug, cdl FROM mineral_expressions WHERE family_id = ? ORDER BY (slug = 'default') DESC, slug", + (fid,), + ).fetchall() + + cdl = "" + for row in rows: + if row["cdl"] and row["cdl"].strip(): + cdl = row["cdl"] + break + + # Try CDL render first + if cdl and "amorphous" not in cdl.lower(): + if render_cdl_to_svg(cdl, out): + print(f" RENDER: {fid}") + rendered += 1 + continue + + # Pick placeholder type + system = (fam["crystal_system"] or "").lower() + origin = (fam["origin"] or "").lower() + if origin == "composite": + template = PLACEHOLDER_TEMPLATES["composite"] + elif origin == "simulant": + template = PLACEHOLDER_TEMPLATES["simulant"] + elif system == "amorphous": + template = PLACEHOLDER_TEMPLATES["amorphous"] + else: + template = PLACEHOLDER_TEMPLATES["default"] + + out.write_text(template) + print(f" PLACEHOLDER ({origin or system or 'default'}): {fid}") + placeholder += 1 + + print("-" * 50) + print(f"Rendered: {rendered}, Placeholder: {placeholder}, Skipped: {skipped}") + if failed: + print(f"Failed: {len(failed)}: {failed}") + + +if __name__ == "__main__": + main() diff --git a/src/components/admin/AdminPanel.tsx b/src/components/admin/AdminPanel.tsx index 7e3d1ab..9594305 100644 --- a/src/components/admin/AdminPanel.tsx +++ b/src/components/admin/AdminPanel.tsx @@ -410,7 +410,7 @@ export function AdminPanel() {
- + {tool.title} @@ -98,14 +98,6 @@ export function ProtectedTools() { ))}
- - {/* Info */} -
-

Professional Gemmological Tools

-

- Each tool category contains multiple calculators, reference guides, and interactive tools designed for FGA students and professional gemmologists. All tools are optimized for accuracy and ease of use in lab and field environments. -

-
diff --git a/src/components/calculator/ResultCard.tsx b/src/components/calculator/ResultCard.tsx index beab4d0..c9c258d 100644 --- a/src/components/calculator/ResultCard.tsx +++ b/src/components/calculator/ResultCard.tsx @@ -93,7 +93,7 @@ export function ResultCard({ {/* Main value */}

{value} - {unit && {unit}} + {unit && {unit}}

{/* Description */} @@ -122,7 +122,7 @@ export function ResultInline({ value, unit, label, className }: ResultInlineProp {label && {label}:} {value} - {unit && {unit}} + {unit && {unit}} ); } @@ -157,7 +157,7 @@ export function ResultGroup({ results, layout = 'horizontal', className }: Resul

{result.value} {result.unit && ( - {result.unit} + {result.unit} )}

diff --git a/src/components/calculator/results/MultiValueResult.tsx b/src/components/calculator/results/MultiValueResult.tsx index f164a0d..ff62969 100644 --- a/src/components/calculator/results/MultiValueResult.tsx +++ b/src/components/calculator/results/MultiValueResult.tsx @@ -37,7 +37,7 @@ interface MultiValueResultProps { } const variantTextClasses: Record = { - crystal: { value: 'text-crystal-700', unit: 'text-crystal-600' }, + crystal: { value: 'text-crystal-700', unit: 'text-crystal-700' }, emerald: { value: 'text-emerald-700', unit: 'text-emerald-600' }, sapphire: { value: 'text-blue-700', unit: 'text-blue-600' }, ruby: { value: 'text-red-700', unit: 'text-red-600' }, diff --git a/src/components/calculator/results/NumberResult.tsx b/src/components/calculator/results/NumberResult.tsx index 9a0f9ea..64ce108 100644 --- a/src/components/calculator/results/NumberResult.tsx +++ b/src/components/calculator/results/NumberResult.tsx @@ -35,7 +35,7 @@ interface NumberResultProps { } const variantTextClasses: Record = { - crystal: { value: 'text-crystal-700', unit: 'text-crystal-600' }, + crystal: { value: 'text-crystal-700', unit: 'text-crystal-700' }, emerald: { value: 'text-emerald-700', unit: 'text-emerald-600' }, sapphire: { value: 'text-blue-700', unit: 'text-blue-600' }, ruby: { value: 'text-red-700', unit: 'text-red-600' }, diff --git a/src/components/crystal/CrystalCard.tsx b/src/components/crystal/CrystalCard.tsx index 5d18981..4ff3fb9 100644 --- a/src/components/crystal/CrystalCard.tsx +++ b/src/components/crystal/CrystalCard.tsx @@ -92,7 +92,7 @@ export function CrystalCard({ {/* Info */}
-

+

{name}

diff --git a/src/components/crystal/HeroCrystal3D.tsx b/src/components/crystal/HeroCrystal3D.tsx index 5db402c..8e4cde4 100644 --- a/src/components/crystal/HeroCrystal3D.tsx +++ b/src/components/crystal/HeroCrystal3D.tsx @@ -8,9 +8,10 @@ import { Canvas, useFrame } from '@react-three/fiber'; import { Center, Edges } from '@react-three/drei'; -import { Suspense, useRef, useState, useEffect, useMemo } from 'react'; +import { Suspense, useRef, useState, useEffect } from 'react'; import * as THREE from 'three'; -import { getModelGLTF } from '../../lib/db'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; +import { isWebGLAvailable, prefersReducedMotion } from '../../lib/webgl'; interface HeroCrystal3DProps { mineralName?: string; @@ -78,7 +79,7 @@ function parseGLTFToGeometry(gltfData: any): THREE.BufferGeometry | null { } interface RotatingCrystalProps { - gltfData: object; + geometry: THREE.BufferGeometry; rotationSpeed: number; scale: number; } @@ -86,22 +87,15 @@ interface RotatingCrystalProps { /** * Rotating crystal mesh with Y-axis auto-rotation */ -function RotatingCrystal({ gltfData, rotationSpeed, scale }: RotatingCrystalProps) { +function RotatingCrystal({ geometry, rotationSpeed, scale }: RotatingCrystalProps) { const groupRef = useRef(null); - const geometry = useMemo(() => { - return parseGLTFToGeometry(gltfData); - }, [gltfData]); - - // Y-axis rotation animation useFrame((_, delta) => { if (groupRef.current) { groupRef.current.rotation.y += rotationSpeed * delta; } }); - if (!geometry) return null; - return ( @@ -153,50 +147,75 @@ export function HeroCrystal3D({ className = '', }: HeroCrystal3DProps) { const [isClient, setIsClient] = useState(false); - const [gltfData, setGltfData] = useState(null); - const [isLoading, setIsLoading] = useState(true); + const [geometry, setGeometry] = useState(null); + const [canRender3D, setCanRender3D] = useState(true); + const [reduceMotion, setReduceMotion] = useState(false); - // Only render on client side (Three.js requires DOM) useEffect(() => { setIsClient(true); + setCanRender3D(isWebGLAvailable()); + setReduceMotion(prefersReducedMotion()); }, []); - // Load mineral glTF data + // Load static .glb directly — no sql.js / minerals.db cost on home useEffect(() => { - if (!isClient) return; - + if (!isClient || !canRender3D) return; let cancelled = false; - - async function loadMineral() { - try { - const data = await getModelGLTF(mineralName); - if (!cancelled && data) { - setGltfData(data); - } - } catch (error) { - console.error('Failed to load mineral:', error); - } finally { - if (!cancelled) { - setIsLoading(false); - } - } - } - - loadMineral(); - + const slug = mineralName.toLowerCase().replace(/\s+/g, '-'); + const loader = new GLTFLoader(); + loader.load( + `/models/gltf/${slug}.glb`, + (gltf) => { + if (cancelled) return; + let geom: THREE.BufferGeometry | null = null; + gltf.scene.traverse((obj) => { + if (geom) return; + if (obj instanceof THREE.Mesh && obj.geometry) geom = obj.geometry as THREE.BufferGeometry; + }); + if (geom) setGeometry(geom); + }, + undefined, + () => { + // Static .glb missing: keep wireframe fallback (LoadingFallback) + }, + ); return () => { cancelled = true; }; - }, [isClient, mineralName]); + }, [isClient, canRender3D, mineralName]); if (!isClient) { return ( -
-
Loading...
+