Initial commit — Singular Particular Space v1
Homepage (site/index.html): integration-v14 promoted, Writings section integrated with 33 pieces clustered by type (stories/essays/miscellany), Writings welcome lightbox, content frame at 98% opacity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
11
DumperCan/DumperCan-JL-notes.md
Normal file
11
DumperCan/DumperCan-JL-notes.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# DumperCan - JL Notes
|
||||
|
||||
---
|
||||
|
||||
in here are all kinds of things that need sorting.
|
||||
|
||||
---
|
||||
|
||||
UI References - ToolsnToys - present these in full width iframes. on first load - lightbox - "A collection of looks and feels from Claude Sonnet and Opus 4.5. Worth a look at how things improve with time and context - JL"
|
||||
|
||||
---
|
||||
251
DumperCan/FOSS-tools.md
Executable file
251
DumperCan/FOSS-tools.md
Executable file
@@ -0,0 +1,251 @@
|
||||
# FOSS Tools Collection - Organized by Category
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Creative & Design Tools
|
||||
|
||||
### Graphics & Image Editing
|
||||
- [GIMP - GNU Image Manipulation Program](https://www.gimp.org/)
|
||||
- [Krita](https://krita.org/en/)
|
||||
- [Inkscape](https://inkscape.org/)
|
||||
- [darktable](https://www.darktable.org/)
|
||||
|
||||
### 3D & Animation
|
||||
- [Blender](https://www.blender.org/)
|
||||
- [FreeCAD](https://www.freecad.org/)
|
||||
|
||||
### Diagramming & Design
|
||||
- [draw.io](https://www.drawio.com/)
|
||||
|
||||
---
|
||||
|
||||
## 🎬 Video & Audio Production
|
||||
|
||||
### Video Editing & Transcoding
|
||||
- [Shutter Encoder](https://www.shutterencoder.com/en/)
|
||||
- [FFmpeg](https://ffmpeg.org/)
|
||||
- [Handbrake](https://handbrake.fr/)
|
||||
- [Kdenlive](https://kdenlive.org/)
|
||||
- [Shotcut](https://www.shotcut.org/)
|
||||
- [OBS - Open Broadcaster Software](https://obsproject.com/)
|
||||
|
||||
### Video Downloading & Playback
|
||||
- [Clipgrab](https://clipgrab.org/download-clipgrab/)
|
||||
- [Kodi](https://kodi.tv/)
|
||||
- [mpv.io](https://mpv.io/)
|
||||
- [Jellyfin](https://jellyfin.org/)
|
||||
- [FreeTube](https://freetubeapp.io/)
|
||||
|
||||
### Audio Production
|
||||
- [Tenacity](https://tenacityaudio.org/)
|
||||
- [Audacity](https://www.audacityteam.org/)
|
||||
- [LMMS](https://lmms.io/)
|
||||
- [Mixxx](https://mixxx.org/)
|
||||
- [MuseScore](https://musescore.org/en)
|
||||
- [MuseHub](https://www.musehub.com/)
|
||||
|
||||
---
|
||||
|
||||
## 💻 Development & Documentation
|
||||
|
||||
### Documentation Platforms
|
||||
- [Docusaurus](https://docusaurus.io/)
|
||||
- [VuePress](https://vuepress.vuejs.org/guide/theme.html#default-theme)
|
||||
- [BookStack](https://www.bookstackapp.com/)
|
||||
- [Wiki.js](https://js.wiki/)
|
||||
|
||||
### Development Frameworks
|
||||
- [Vue.js](https://vuejs.org/)
|
||||
- [Create T3 App](https://create.t3.gg/)
|
||||
|
||||
### Utilities
|
||||
- [Pandoc](https://pandoc.org/)
|
||||
- [MiKTeX](https://miktex.org/)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Knowledge Management & Note-Taking
|
||||
|
||||
- [Logseq](https://logseq.com/)
|
||||
- [Trilium Notes](https://triliumnotes.org/)
|
||||
- [Etherpad](https://etherpad.org/)
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Content Management & Web Publishing
|
||||
|
||||
### Static Site Generators
|
||||
- [Publii](https://www.getpublii.com/)
|
||||
|
||||
### Headless CMS
|
||||
- [Strapi](https://strapi.io/five)
|
||||
|
||||
---
|
||||
|
||||
## 🛒 E-Commerce Platforms
|
||||
|
||||
- [Vendure](https://vendure.io/)
|
||||
- [nopCommerce](https://www.nopcommerce.com/en)
|
||||
- [OpenCart](https://www.opencart.com/)
|
||||
- [Spree Commerce](https://spreecommerce.org/pricing/)
|
||||
- [PrestaShop](https://prestashop.com/)
|
||||
|
||||
---
|
||||
|
||||
## 💬 Communication & Collaboration
|
||||
|
||||
### Chat & Messaging
|
||||
- [Rocket.Chat](https://www.rocket.chat/)
|
||||
- [Zulip](https://zulip.com/plans/)
|
||||
- [Element](https://element.io/product-overview)
|
||||
- [Twake App](https://twake.app/en/)
|
||||
|
||||
### Video Conferencing
|
||||
- [BigBlueButton](https://bigbluebutton.org/)
|
||||
- [MiroTalk SFU](https://sfu.mirotalk.com/)
|
||||
- [Briefing](https://brie.fi/ng)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Business & Analytics
|
||||
|
||||
### Business Intelligence
|
||||
- [Metabase](https://www.metabase.com/)
|
||||
- [Redash](https://redash.io/)
|
||||
|
||||
### Analytics
|
||||
- [Matomo](https://matomo.org/pricing/)
|
||||
|
||||
### Project Management
|
||||
- [Plane](https://plane.so/)
|
||||
- [Focalboard](https://www.focalboard.com/download/)
|
||||
- [ToolJet](https://www.tooljet.ai/pricing)
|
||||
|
||||
### Finance
|
||||
- [Firefly III](https://www.firefly-iii.org/)
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Security & Authentication
|
||||
|
||||
- [Vault by HashiCorp](https://developer.hashicorp.com/vault)
|
||||
- [Keycloak](https://www.keycloak.org/)
|
||||
- [ZITADEL](https://zitadel.com/pricing)
|
||||
- [KeePassXC](https://keepassxc.org/)
|
||||
- [Cryptomator](https://cryptomator.org/pricing/#for-individuals)
|
||||
|
||||
---
|
||||
|
||||
## ☁️ File Storage & Sharing
|
||||
|
||||
- [Nextcloud](https://nextcloud.com/)
|
||||
- [ownCloud](https://owncloud.com/)
|
||||
- [Seafile](https://www.seafile.com/en/pricing/?produce=on-premises)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Search & Data
|
||||
|
||||
### Search Engines
|
||||
- [Typesense](https://typesense.org/)
|
||||
- [OpenSearch](https://opensearch.org/)
|
||||
|
||||
### Database & Data Tools
|
||||
- [NocoDB](https://www.nocodb.com/)
|
||||
- [Label Studio](https://labelstud.io/)
|
||||
- [TDengine](https://tdengine.com/)
|
||||
|
||||
---
|
||||
|
||||
## 🤖 AI & Machine Learning
|
||||
|
||||
### AI Chat Platforms
|
||||
- [Z.ai Chat - GLM-4.6 & GLM-4.5](https://chat.z.ai/)
|
||||
- [DeepSeek](https://chat.deepseek.com/)
|
||||
- [T3 Chat](https://t3.chat/)
|
||||
|
||||
### AI Models & Resources
|
||||
- [GLM-4.6 on Hugging Face](https://huggingface.co/zai-org/GLM-4.6)
|
||||
- [GLM-4.6 Documentation](https://docs.z.ai/guides/llm/glm-4.6)
|
||||
- [DeepSeek-V3.1 on Hugging Face](https://huggingface.co/deepseek-ai/DeepSeek-V3.1)
|
||||
- [DeepSeek v3 Downloads](https://deepseekv3.org/download)
|
||||
- [EuroLLM-9B](https://huggingface.co/blog/eurollm-team/eurollm-9b)
|
||||
- [OpenEuroLLM](https://openeurollm.eu/)
|
||||
|
||||
---
|
||||
|
||||
## 🌍 Social & Community
|
||||
|
||||
### Social Platforms
|
||||
- [Lemmy](https://join-lemmy.org/)
|
||||
- [PeerTube](https://joinpeertube.org/)
|
||||
- [LBRY](https://lbry.com/)
|
||||
- [Forem Subforems](https://forem.com/subforems)
|
||||
|
||||
### Video Platforms
|
||||
- [AVideo Platform](https://avideo.tube/platform/)
|
||||
- [WWBN Platform](https://wwbn.com/platform/)
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ System Administration & Utilities
|
||||
|
||||
### File Management
|
||||
- [7-Zip](https://www.7-zip.org/download.html)
|
||||
|
||||
### System Monitoring & Management
|
||||
- [Uptime Kuma](https://uptime.kuma.pet/)
|
||||
- [MeshCentral](https://meshcentral.com/)
|
||||
|
||||
### Networking
|
||||
- [NetBird](https://netbird.io/)
|
||||
|
||||
### Screenshots & Recording
|
||||
- [ShareX](https://getsharex.com/)
|
||||
- [rrweb.io](https://www.rrweb.io/)
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ Navigation & Maps
|
||||
|
||||
- [Organic Maps](https://organicmaps.app/)
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Education & Learning
|
||||
|
||||
- [Anki Flashcards](https://apps.ankiweb.net/)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Office & Productivity
|
||||
|
||||
- [ONLYOFFICE](https://www.onlyoffice.com/)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Marketing & URL Tools
|
||||
|
||||
- [Mautic](https://mautic.org/)
|
||||
- [Dub](https://dub.co/pricing)
|
||||
|
||||
---
|
||||
|
||||
## 🎥 Streaming
|
||||
|
||||
- [Ant Media Server](https://antmedia.io/)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Miscellaneous
|
||||
|
||||
### Alternative Frontends
|
||||
- [Invidious](https://invidious.io/)
|
||||
|
||||
### Security Research
|
||||
- [ProjectDiscovery Documentation](https://docs.projectdiscovery.io/home)
|
||||
|
||||
### Resource Discovery
|
||||
- [Open Source Alternative](https://opensourcealternative.to/?page=9)
|
||||
- [GitHub emoji-cheat-sheet](https://github.com/ikatyang/emoji-cheat-sheet)
|
||||
|
||||
282
DumperCan/Facebook Streaming Setup Guide_v2.md
Executable file
282
DumperCan/Facebook Streaming Setup Guide_v2.md
Executable file
@@ -0,0 +1,282 @@
|
||||
# Multi-Camera Facebook Page Livestreaming with OBS Studio on MacBook M2
|
||||
|
||||
Your desired setup faces **critical compatibility limitations** with the iPad A1474 (2013 iPad Air) that significantly restricts wireless audio options and some camera apps. This guide provides complete instructions while addressing these constraints and offering practical alternatives.
|
||||
|
||||
## Hardware compatibility assessment
|
||||
|
||||
**The iPad A1474 presents major limitations:**
|
||||
- Maximum iOS version: 12.5.7 (discontinued support)
|
||||
- **Most wireless microphone apps require iOS 13+ and are incompatible**
|
||||
- Limited camera app options due to outdated iOS
|
||||
- **Recommendation**: Use Samsung Galaxy A25 as wireless microphone source instead
|
||||
|
||||
**MacBook M2 performance constraints:**
|
||||
- **USB bandwidth limitation**: Maximum 2-3 cameras simultaneously due to USB root hub constraints
|
||||
- Thermal throttling during extended streaming sessions
|
||||
- **Hardware acceleration essential** for multi-camera performance
|
||||
|
||||
## Facebook Page streaming requirements
|
||||
|
||||
**Current Facebook specifications (2025):**
|
||||
- **Page eligibility**: Minimum 100 followers and account 60+ days old
|
||||
- **Maximum resolution**: 720p (1280×720) - Facebook does not support 1080p streaming
|
||||
- **Maximum bitrate**: 4,000 Kbps video, 128 Kbps audio
|
||||
- **Stream protocol**: RTMPS (encrypted) via Meta Business Suite
|
||||
|
||||
## Step 1: Facebook Page setup and stream key generation
|
||||
|
||||
1. **Access Meta Business Suite**
|
||||
- Navigate to your Facebook Page
|
||||
- Click "Create" → "Live Video"
|
||||
- Select "Streaming Software" as video source
|
||||
|
||||
2. **Configure stream settings**
|
||||
- **Server URL**: `rtmps://live-api-s.facebook.com:443/rtmp/`
|
||||
- Copy the unique **Stream Key** (regenerates each session unless you enable persistent keys)
|
||||
- Set stream title, description, and audience targeting
|
||||
- **Enable persistent stream key** for reuse across sessions
|
||||
|
||||
3. **Verify eligibility requirements**
|
||||
- Confirm page has 100+ followers
|
||||
- Ensure account is 60+ days old
|
||||
- Check admin/editor access to target page
|
||||
|
||||
## Step 2: Essential software installation
|
||||
|
||||
**Required Mac software:**
|
||||
1. **OBS Studio** (latest version with Apple Silicon support)
|
||||
2. **BlackHole audio driver** (free) - Download from existential.audio/blackhole
|
||||
3. **DroidCam OBS plugin** - Download from droidcam.app/obs
|
||||
|
||||
**Mobile device apps:**
|
||||
- **Samsung Galaxy A25**: DroidCam app (recommended) or SonoBus for wireless audio
|
||||
- **iPad A1474**: Camera for OBS Studio ($15.99) - one of few iOS 12-compatible options
|
||||
|
||||
## Step 3: Camera configuration
|
||||
|
||||
### Samsung Galaxy A25 setup (primary camera)
|
||||
|
||||
**Option A: Wired connection (lowest latency)**
|
||||
1. Enable **Developer Options** on Galaxy A25:
|
||||
- Go to Settings → About Phone → Tap "Build Number" 7 times
|
||||
- Enable "USB Debugging" in Developer Options
|
||||
2. Connect via USB-C to USB-C cable (3m cable)
|
||||
3. Launch DroidCam app, select "USB" mode
|
||||
4. In OBS: Add source → DroidCam OBS → Select USB connection
|
||||
|
||||
**Option B: Wireless connection**
|
||||
1. Connect Galaxy A25 and MacBook to same Wi-Fi network
|
||||
2. Launch DroidCam app, note IP address and port
|
||||
3. In OBS: Add source → DroidCam OBS → Enter IP and port
|
||||
4. **Recommended settings**: 1080p @ 30fps for balance of quality and bandwidth
|
||||
|
||||
**Expected performance:**
|
||||
- **Wired latency**: 20-50ms
|
||||
- **Wireless latency**: 50-150ms
|
||||
- **Maximum quality**: 4K @ 30fps (though limited by Facebook's 720p maximum)
|
||||
|
||||
### iPad A1474 setup (secondary camera - limited options)
|
||||
|
||||
**Compatible camera app: Camera for OBS Studio**
|
||||
1. Purchase and install "Camera for OBS Studio" ($15.99) - verified iOS 12 compatibility
|
||||
2. **Wired setup** (recommended):
|
||||
- Connect iPad to MacBook using Lightning to USB-C cable
|
||||
- Launch Camera for OBS Studio app
|
||||
- In OBS: Add source → iOS Camera → Select iPad from device list
|
||||
3. **Expected quality**: 1080p rear camera, 720p front camera @ 30fps
|
||||
|
||||
**Alternative: Basic wireless option**
|
||||
- Very limited due to iOS 12.5.7 constraints
|
||||
- Most modern camera apps incompatible
|
||||
- **Fallback**: Use iPad for static shots rather than primary streaming camera
|
||||
|
||||
## Step 4: Wireless microphone configuration
|
||||
|
||||
**Critical limitation**: iPad A1474 cannot run modern wireless microphone apps due to iOS version constraints.
|
||||
|
||||
**Recommended solution: Samsung Galaxy A25 as wireless microphone**
|
||||
|
||||
### SonoBus setup (FOSS option - recommended)
|
||||
1. **Install SonoBus** on Galaxy A25 and MacBook M2
|
||||
2. **Create audio room**: Launch SonoBus on Mac → Create new room → Note room code
|
||||
3. **Connect mobile device**: Launch SonoBus on Galaxy A25 → Join room using code
|
||||
4. **Audio routing**: Route SonoBus output through BlackHole to OBS
|
||||
|
||||
### Alternative: WO Mic setup
|
||||
1. **Install WO Mic** client on MacBook M2 and app on Galaxy A25
|
||||
2. **Connect via Wi-Fi**: Both devices on same network
|
||||
3. **Configure OBS**: Set WO Mic Virtual Device as audio input source
|
||||
|
||||
**Expected audio quality:**
|
||||
- **SonoBus**: Uncompressed PCM up to 48kHz/24-bit
|
||||
- **WO Mic**: 48kHz/16-bit compressed
|
||||
- **Typical latency**: 100-300ms (acceptable for standard streaming)
|
||||
|
||||
## Step 5: OBS Studio configuration
|
||||
|
||||
### Basic OBS setup for Facebook streaming
|
||||
|
||||
1. **Stream configuration**:
|
||||
- Settings → Stream → Service: Facebook Live
|
||||
- Server: `rtmps://live-api-s.facebook.com:443/rtmp/`
|
||||
- Stream Key: Paste from Meta Business Suite
|
||||
|
||||
2. **Video settings optimized for MacBook M2**:
|
||||
- **Base Resolution**: 1280×720 (Facebook maximum)
|
||||
- **Output Resolution**: 1280×720
|
||||
- **FPS**: 30 (recommended for multi-camera stability)
|
||||
|
||||
3. **Advanced output settings**:
|
||||
- **Encoder**: Apple VT H264 Hardware Encoder (essential for M2 performance)
|
||||
- **Rate Control**: CBR
|
||||
- **Bitrate**: 4000 Kbps (Facebook maximum)
|
||||
- **Keyframe Interval**: 2 seconds
|
||||
- **Profile**: High
|
||||
- **CPU Usage Preset**: Above Normal
|
||||
|
||||
### Multi-camera scene management
|
||||
|
||||
1. **Create separate scenes**:
|
||||
- "Main Camera" (Galaxy A25)
|
||||
- "Secondary Camera" (iPad A1474)
|
||||
- "Picture-in-Picture"
|
||||
- "Audio Only"
|
||||
|
||||
2. **Set up transitions**:
|
||||
- Use "Fade" transitions (200-500ms duration) for smooth switching
|
||||
- Assign hotkeys: F1, F2, F3, F4 for quick scene switching
|
||||
|
||||
3. **Audio configuration**:
|
||||
- **Desktop Audio**: Disabled (use BlackHole routing instead)
|
||||
- **Mic/Auxiliary Audio**: Set to wireless microphone source
|
||||
- **Advanced Audio Properties**: Adjust sync offset if needed (typically 100-200ms for wireless sources)
|
||||
|
||||
## Step 6: Audio routing with BlackHole
|
||||
|
||||
### BlackHole virtual audio setup
|
||||
|
||||
1. **Create Multi-Output Device**:
|
||||
- Open Audio MIDI Setup (Applications → Utilities)
|
||||
- Click "+" → Create Multi-Output Device
|
||||
- Add "BlackHole 2ch" and "Built-in Output"
|
||||
- Set Built-in Output as master device
|
||||
|
||||
2. **System audio routing**:
|
||||
- System Preferences → Sound → Output → Select Multi-Output Device
|
||||
- This allows you to hear audio while routing to OBS
|
||||
|
||||
3. **OBS audio source configuration**:
|
||||
- Add Audio Input Capture → Select BlackHole 2ch
|
||||
- Route wireless microphone app output to BlackHole
|
||||
- Monitor audio levels and adjust sync offset as needed
|
||||
|
||||
## Step 7: Performance optimization for MacBook M2
|
||||
|
||||
### Essential optimizations
|
||||
|
||||
1. **Hardware acceleration**: Use Apple VT H264 encoder (not x264)
|
||||
2. **Process priority**: Set OBS to "Above Normal" in Activity Monitor
|
||||
3. **USB management**: Connect cameras to separate USB-C ports, avoid hubs when possible
|
||||
4. **Thermal management**: Use external cooling pad for extended sessions
|
||||
5. **Network**: Use wired Ethernet connection, disable Wi-Fi for primary internet
|
||||
|
||||
### Monitoring and troubleshooting
|
||||
|
||||
**Performance indicators to watch:**
|
||||
- **CPU usage**: Keep below 70% in OBS Stats
|
||||
- **Dropped frames**: Should remain at 0% or minimal
|
||||
- **Network**: Stable upload speed of 6+ Mbps
|
||||
|
||||
**Common issues and solutions:**
|
||||
- **Black screen from second camera**: USB bandwidth limitation - try different ports
|
||||
- **Audio sync drift**: Use Sync Offset in Advanced Audio Properties (typically +150-250ms for wireless)
|
||||
- **High CPU usage**: Lower resolution to 720p, reduce frame rate, close unnecessary apps
|
||||
|
||||
## Step 8: Alternative solutions for easier setup
|
||||
|
||||
Given the hardware limitations, consider these alternatives:
|
||||
|
||||
### Streamlabs or Restream Studio
|
||||
- **Browser-based streaming** eliminates software compatibility issues
|
||||
- **Built-in multi-camera support** with simpler setup
|
||||
- **Cloud processing** reduces MacBook M2 performance demands
|
||||
- **Monthly subscription** required for full features
|
||||
|
||||
### Professional wireless microphone system
|
||||
- **Physical wireless microphone** with Lightning adapter for iPad A1474
|
||||
- **Eliminates app compatibility issues** entirely
|
||||
- **Lower latency** than app-based solutions
|
||||
- **Higher initial cost** ($200-800) but more reliable
|
||||
|
||||
### Upgrade path recommendation
|
||||
**iPad A1474 replacement**: Consider iPad (9th generation) or newer for full app compatibility
|
||||
**Camera upgrade**: Dedicated USB webcams (Logitech C920s) for consistent performance
|
||||
**Audio interface**: Physical audio mixer for professional audio control
|
||||
|
||||
## Bandwidth and quality considerations
|
||||
|
||||
**Network requirements:**
|
||||
- **Minimum upload**: 5 Mbps
|
||||
- **Recommended**: 8+ Mbps for stable multi-camera streaming
|
||||
- **Per-camera bandwidth**: Does not multiply (OBS encodes final output only)
|
||||
|
||||
**Quality recommendations:**
|
||||
- **720p @ 30fps**: Optimal for Facebook streaming and hardware limitations
|
||||
- **4000 Kbps video bitrate**: Facebook maximum
|
||||
- **128 Kbps audio bitrate**: Standard for voice content
|
||||
|
||||
## Pre-stream checklist
|
||||
|
||||
**Hardware verification:**
|
||||
- [ ] Facebook Page meets 100+ follower requirement
|
||||
- [ ] All cables connected and devices charged
|
||||
- [ ] Wi-Fi network stable (both devices connected)
|
||||
- [ ] MacBook M2 connected via Ethernet when possible
|
||||
|
||||
**Software testing:**
|
||||
- [ ] Fresh stream key generated in Meta Business Suite
|
||||
- [ ] All cameras showing video feed in OBS
|
||||
- [ ] Wireless microphone connected and audio levels visible
|
||||
- [ ] Scene transitions working smoothly
|
||||
- [ ] Network speed test confirms 6+ Mbps upload
|
||||
|
||||
**Go-live process:**
|
||||
1. Start wireless microphone app first
|
||||
2. Launch camera apps on mobile devices
|
||||
3. Open OBS and verify all sources active
|
||||
4. Test scene switching and audio levels
|
||||
5. Click "Start Streaming" in OBS
|
||||
6. Monitor stream health in Meta Business Suite
|
||||
|
||||
## Final recommendations (Updated for iPhone 6+)
|
||||
|
||||
**Most reliable configuration with iPhone 6+:**
|
||||
|
||||
**Setup Option A** (iPhone as wireless mic):
|
||||
1. **Samsung Galaxy A25** as primary camera (wired USB-C connection)
|
||||
2. **iPhone 6+** as wireless microphone (SonoBus or WO Mic)
|
||||
3. **iPhone 6+** as secondary camera when not used for audio
|
||||
4. **720p @ 30fps** output to Facebook Page
|
||||
|
||||
**Setup Option B** (Galaxy A25 as wireless mic):
|
||||
1. **Samsung Galaxy A25** as wireless microphone source (SonoBus or WO Mic)
|
||||
2. **iPhone 6+** as primary wireless camera (Camera for OBS Studio)
|
||||
3. **Samsung Galaxy A25** as secondary camera (wired when not used for audio)
|
||||
4. **720p @ 30fps** output to Facebook Page
|
||||
|
||||
**Recommended choice**: **Setup Option A** provides better overall performance since the Galaxy A25 typically has superior camera hardware and the iPhone excels at audio processing.
|
||||
|
||||
**Budget-conscious FOSS alternatives:**
|
||||
- SonoBus for wireless audio (completely free, iPhone 6s+ only)
|
||||
- OBS Camera app for iPhone (completely free)
|
||||
- DroidCam for cross-platform compatibility (free with watermark)
|
||||
- BlackHole for audio routing (free)
|
||||
|
||||
**Key advantages of iPhone 6+ over iPad A1474:**
|
||||
- Full modern app compatibility (iPhone 6s+)
|
||||
- Better camera quality and low-light performance
|
||||
- More flexible positioning due to smaller size
|
||||
- Superior wireless microphone capabilities
|
||||
- Longer battery life for extended streaming sessions
|
||||
|
||||
This iPhone-based configuration provides **significantly more flexibility and reliability** compared to the iPad A1474 setup, with multiple viable app options and much better wireless microphone capabilities.
|
||||
723
DumperCan/RememberToForget_WorkdayLogger_v2.html
Normal file
723
DumperCan/RememberToForget_WorkdayLogger_v2.html
Normal file
@@ -0,0 +1,723 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>REMEMBER TO FORGET // WORKLOG</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=VT323&family=Share+Tech+Mono&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ===== PUNK RETROFUTURIST STYLE ===== */
|
||||
:root {
|
||||
--bg-dark: #0a0a0f;
|
||||
--bg-panel: #12121a;
|
||||
--bg-elevated: #1a1a25;
|
||||
--neon-pink: #ff00ff;
|
||||
--neon-cyan: #00ffff;
|
||||
--neon-lime: #39ff14;
|
||||
--neon-yellow: #ffff00;
|
||||
--neon-red: #ff0033;
|
||||
--neon-purple: #bf00ff;
|
||||
--neon-orange: #ff8800;
|
||||
--pink-glow: rgba(255, 0, 255, 0.4);
|
||||
--cyan-glow: rgba(0, 255, 255, 0.4);
|
||||
--lime-glow: rgba(57, 255, 20, 0.4);
|
||||
--text-primary: #e0e0e0;
|
||||
--text-dim: #888899;
|
||||
--text-bright: #ffffff;
|
||||
--border-width: 2px;
|
||||
--border-width-thick: 4px;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: repeating-linear-gradient(0deg, rgba(255,0,255,0.02) 0px, transparent 1px, transparent 2px, rgba(0,255,255,0.02) 3px, transparent 4px);
|
||||
pointer-events: none; z-index: 9999; opacity: 0.6;
|
||||
}
|
||||
body::after {
|
||||
content: '';
|
||||
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: repeating-linear-gradient(0deg, rgba(0,0,0,0.12) 0px, transparent 1px, transparent 2px);
|
||||
pointer-events: none; z-index: 9998;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Share Tech Mono', monospace;
|
||||
background: var(--bg-dark);
|
||||
color: var(--text-primary);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.container { max-width: 900px; margin: 0 auto; position: relative; z-index: 1; }
|
||||
|
||||
/* ===== HEADER ===== */
|
||||
header {
|
||||
text-align: center; margin-bottom: 2rem; padding: 1.5rem;
|
||||
border: var(--border-width) solid var(--neon-pink);
|
||||
background: var(--bg-panel);
|
||||
box-shadow: 0 0 20px var(--pink-glow), inset 0 0 20px rgba(255,0,255,0.05);
|
||||
}
|
||||
h1 {
|
||||
font-family: 'VT323', monospace;
|
||||
font-size: clamp(2.5rem, 8vw, 4rem);
|
||||
color: var(--neon-pink);
|
||||
text-shadow: 0 0 10px var(--neon-pink), 0 0 20px var(--neon-pink), 0 0 40px var(--neon-pink);
|
||||
letter-spacing: 0.15em; text-transform: uppercase;
|
||||
}
|
||||
.subtitle {
|
||||
color: var(--neon-cyan); font-size: 0.9rem;
|
||||
letter-spacing: 0.3em; text-shadow: 0 0 10px var(--neon-cyan); margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
/* ===== INPUT SECTION ===== */
|
||||
.input-section {
|
||||
display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1.5rem;
|
||||
}
|
||||
@media (max-width: 600px) { .input-section { grid-template-columns: 1fr; } }
|
||||
|
||||
.input-group { display: flex; flex-direction: column; }
|
||||
.input-group label {
|
||||
color: var(--neon-cyan); font-size: 0.8rem;
|
||||
text-transform: uppercase; letter-spacing: 0.1em;
|
||||
margin-bottom: 0.5rem; text-shadow: 0 0 5px var(--neon-cyan);
|
||||
}
|
||||
.input-group input {
|
||||
background: var(--bg-elevated); border: var(--border-width) solid var(--neon-cyan);
|
||||
color: var(--text-bright); padding: 0.75rem 1rem;
|
||||
font-family: 'Share Tech Mono', monospace; font-size: 1rem;
|
||||
outline: none; transition: all 0.3s;
|
||||
}
|
||||
.input-group input:focus { box-shadow: 0 0 15px var(--cyan-glow); border-color: var(--neon-pink); }
|
||||
|
||||
/* ===== BUTTON SECTION ===== */
|
||||
.button-section {
|
||||
display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; margin-bottom: 1.5rem;
|
||||
}
|
||||
@media (max-width: 600px) { .button-section { grid-template-columns: 1fr; } }
|
||||
|
||||
.btn {
|
||||
padding: 1rem 2rem; font-family: 'VT323', monospace; font-size: 1.5rem;
|
||||
text-transform: uppercase; letter-spacing: 0.15em;
|
||||
border: var(--border-width-thick) solid; cursor: pointer;
|
||||
transition: all 0.2s; position: relative; overflow: hidden;
|
||||
}
|
||||
.btn::before { content: '> '; }
|
||||
.btn::after { content: ' <'; }
|
||||
|
||||
.btn-start {
|
||||
background: linear-gradient(135deg, rgba(57,255,20,0.15), rgba(57,255,20,0.05));
|
||||
border-color: var(--neon-lime); color: var(--neon-lime);
|
||||
text-shadow: 0 0 10px var(--neon-lime); box-shadow: 0 0 20px var(--lime-glow);
|
||||
}
|
||||
.btn-start:hover { background: rgba(57,255,20,0.25); box-shadow: 0 0 30px var(--neon-lime), 0 0 50px var(--lime-glow); transform: translateY(-2px); }
|
||||
|
||||
.btn-end {
|
||||
background: linear-gradient(135deg, rgba(255,0,51,0.15), rgba(255,0,51,0.05));
|
||||
border-color: var(--neon-red); color: var(--neon-red);
|
||||
text-shadow: 0 0 10px var(--neon-red); box-shadow: 0 0 20px rgba(255,0,51,0.4);
|
||||
}
|
||||
.btn-end:hover { background: rgba(255,0,51,0.25); box-shadow: 0 0 30px var(--neon-red), 0 0 50px rgba(255,0,51,0.4); transform: translateY(-2px); }
|
||||
|
||||
.btn-cats {
|
||||
background: linear-gradient(135deg, rgba(255,136,0,0.15), rgba(255,136,0,0.05));
|
||||
border-color: var(--neon-orange); color: var(--neon-orange);
|
||||
text-shadow: 0 0 10px var(--neon-orange); box-shadow: 0 0 20px rgba(255,136,0,0.4);
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.btn-cats:hover { background: rgba(255,136,0,0.25); box-shadow: 0 0 30px var(--neon-orange); transform: translateY(-2px); }
|
||||
|
||||
.btn:disabled { opacity: 0.4; cursor: not-allowed; box-shadow: none; }
|
||||
|
||||
/* ===== STATUS BAR ===== */
|
||||
.status-bar {
|
||||
background: var(--bg-panel); border: var(--border-width) solid var(--neon-purple);
|
||||
padding: 0.75rem 1rem; margin-bottom: 1.5rem;
|
||||
display: flex; justify-content: space-between; align-items: center; font-size: 0.85rem;
|
||||
}
|
||||
.status-indicator { display: flex; align-items: center; gap: 0.5rem; }
|
||||
.status-dot { width: 10px; height: 10px; border-radius: 50%; animation: pulse 1.5s infinite; }
|
||||
.status-dot.active { background: var(--neon-lime); box-shadow: 0 0 10px var(--neon-lime); }
|
||||
.status-dot.idle { background: var(--neon-yellow); box-shadow: 0 0 10px var(--neon-yellow); animation: none; }
|
||||
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
|
||||
.current-task { color: var(--neon-cyan); }
|
||||
|
||||
/* ===== OUTPUT SECTION ===== */
|
||||
.output-section { background: var(--bg-panel); border: var(--border-width) solid var(--neon-pink); padding: 1rem; }
|
||||
.output-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; gap: 0.5rem; flex-wrap: wrap; }
|
||||
.output-header h2 { font-family: 'VT323', monospace; font-size: 1.25rem; color: var(--neon-pink); text-shadow: 0 0 10px var(--neon-pink); letter-spacing: 0.1em; }
|
||||
.output-btns { display: flex; gap: 0.5rem; flex-wrap: wrap; }
|
||||
|
||||
.btn-copy, .btn-export, .btn-newday {
|
||||
background: transparent; border: var(--border-width) solid;
|
||||
padding: 0.5rem 1rem; font-family: 'Share Tech Mono', monospace;
|
||||
font-size: 0.8rem; cursor: pointer; transition: all 0.2s; text-transform: uppercase;
|
||||
}
|
||||
.btn-copy { border-color: var(--neon-cyan); color: var(--neon-cyan); }
|
||||
.btn-copy:hover { background: rgba(0,255,255,0.15); box-shadow: 0 0 15px var(--cyan-glow); }
|
||||
.btn-copy.copied { border-color: var(--neon-lime); color: var(--neon-lime); box-shadow: 0 0 15px var(--lime-glow); }
|
||||
|
||||
.btn-export { border-color: var(--neon-lime); color: var(--neon-lime); }
|
||||
.btn-export:hover { background: rgba(57,255,20,0.15); box-shadow: 0 0 15px var(--lime-glow); }
|
||||
|
||||
.btn-newday { border-color: var(--neon-yellow); color: var(--neon-yellow); }
|
||||
.btn-newday:hover { background: rgba(255,255,0,0.1); box-shadow: 0 0 15px rgba(255,255,0,0.4); }
|
||||
|
||||
#worklog-output {
|
||||
width: 100%; min-height: 300px;
|
||||
background: var(--bg-elevated); border: var(--border-width) solid var(--neon-cyan);
|
||||
color: var(--text-primary); padding: 1rem;
|
||||
font-family: 'Share Tech Mono', monospace; font-size: 0.9rem;
|
||||
line-height: 1.6; resize: vertical; outline: none;
|
||||
cursor: default;
|
||||
}
|
||||
#worklog-output[readonly] { opacity: 0.9; }
|
||||
|
||||
/* ===== LIGHTBOX / MODAL ===== */
|
||||
.lightbox-overlay {
|
||||
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: rgba(10,10,15,0.95); display: flex;
|
||||
justify-content: center; align-items: center;
|
||||
z-index: 10000; opacity: 0; visibility: hidden; transition: all 0.3s;
|
||||
}
|
||||
.lightbox-overlay.active { opacity: 1; visibility: visible; }
|
||||
.lightbox {
|
||||
background: var(--bg-panel); border: var(--border-width-thick) solid var(--neon-pink);
|
||||
box-shadow: 0 0 40px var(--pink-glow), 0 0 80px rgba(255,0,255,0.2);
|
||||
padding: 2rem; max-width: 500px; width: 90%;
|
||||
position: relative; transform: scale(0.95); transition: transform 0.3s;
|
||||
}
|
||||
.lightbox-overlay.active .lightbox { transform: scale(1); }
|
||||
.lightbox-header {
|
||||
text-align: center; margin-bottom: 1.5rem; padding-bottom: 1rem;
|
||||
border-bottom: var(--border-width) solid var(--neon-cyan);
|
||||
}
|
||||
.lightbox-header h2 { font-family: 'VT323', monospace; font-size: 1.75rem; color: var(--neon-pink); text-shadow: 0 0 15px var(--neon-pink); letter-spacing: 0.1em; }
|
||||
.lightbox-body { margin-bottom: 1.5rem; }
|
||||
.form-group { margin-bottom: 1rem; }
|
||||
.form-group label { display: block; color: var(--neon-cyan); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 0.5rem; }
|
||||
.form-group select, .form-group input[type="text"] {
|
||||
width: 100%; background: var(--bg-elevated); border: var(--border-width) solid var(--neon-cyan);
|
||||
color: var(--text-bright); padding: 0.75rem 1rem;
|
||||
font-family: 'Share Tech Mono', monospace; font-size: 1rem; outline: none;
|
||||
}
|
||||
.form-group select option { background: var(--bg-elevated); }
|
||||
.form-group select:focus, .form-group input[type="text"]:focus { box-shadow: 0 0 15px var(--cyan-glow); border-color: var(--neon-pink); }
|
||||
|
||||
.lightbox-footer { display: flex; gap: 1rem; }
|
||||
.lightbox-footer .btn { flex: 1; }
|
||||
|
||||
.btn-commit {
|
||||
background: linear-gradient(135deg, rgba(0,255,255,0.15), rgba(0,255,255,0.05));
|
||||
border-color: var(--neon-cyan); color: var(--neon-cyan); text-shadow: 0 0 10px var(--neon-cyan);
|
||||
}
|
||||
.btn-commit:hover { background: rgba(0,255,255,0.25); box-shadow: 0 0 20px var(--neon-cyan); }
|
||||
.btn-cancel { background: transparent; border-color: var(--text-dim); color: var(--text-dim); }
|
||||
.btn-cancel:hover { border-color: var(--neon-red); color: var(--neon-red); }
|
||||
|
||||
.alert-message {
|
||||
background: rgba(255,0,51,0.1); border: var(--border-width) solid var(--neon-red);
|
||||
padding: 1rem; color: var(--neon-red); text-align: center; margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* ===== CATEGORIES LIGHTBOX ===== */
|
||||
.lightbox-cats { border-color: var(--neon-orange); box-shadow: 0 0 40px rgba(255,136,0,0.4), 0 0 80px rgba(255,136,0,0.2); }
|
||||
.lightbox-cats .lightbox-header { border-bottom-color: var(--neon-orange); }
|
||||
.lightbox-cats .lightbox-header h2 { color: var(--neon-orange); text-shadow: 0 0 15px var(--neon-orange); }
|
||||
.cat-add-row { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
|
||||
.cat-add-row input {
|
||||
flex: 1; background: var(--bg-elevated); border: var(--border-width) solid var(--neon-orange);
|
||||
color: var(--text-bright); padding: 0.6rem 0.8rem;
|
||||
font-family: 'Share Tech Mono', monospace; font-size: 0.9rem; outline: none;
|
||||
}
|
||||
.cat-add-row input:focus { box-shadow: 0 0 10px rgba(255,136,0,0.4); }
|
||||
.btn-add-cat {
|
||||
background: rgba(255,136,0,0.15); border: var(--border-width) solid var(--neon-orange);
|
||||
color: var(--neon-orange); padding: 0.6rem 1rem;
|
||||
font-family: 'Share Tech Mono', monospace; font-size: 0.85rem;
|
||||
cursor: pointer; transition: all 0.2s; text-transform: uppercase;
|
||||
}
|
||||
.btn-add-cat:hover { background: rgba(255,136,0,0.3); box-shadow: 0 0 10px rgba(255,136,0,0.4); }
|
||||
|
||||
.cat-list { max-height: 250px; overflow-y: auto; border: 1px solid var(--neon-orange); background: var(--bg-elevated); }
|
||||
.cat-item {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
padding: 0.5rem 0.75rem; border-bottom: 1px solid rgba(255,136,0,0.2);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.cat-item:last-child { border-bottom: none; }
|
||||
.cat-item.builtin { color: var(--text-dim); }
|
||||
.cat-item.custom { color: var(--neon-orange); }
|
||||
.cat-delete {
|
||||
background: none; border: none; color: var(--neon-red);
|
||||
cursor: pointer; font-family: 'Share Tech Mono', monospace;
|
||||
font-size: 0.8rem; padding: 0.2rem 0.4rem; transition: all 0.2s;
|
||||
}
|
||||
.cat-delete:hover { background: rgba(255,0,51,0.15); }
|
||||
.cat-notice { font-size: 0.75rem; color: var(--text-dim); margin-top: 0.75rem; text-align: center; }
|
||||
|
||||
/* Footer */
|
||||
footer { text-align: center; margin-top: 2rem; padding: 1rem; color: var(--text-dim); font-size: 0.75rem; letter-spacing: 0.1em; }
|
||||
.forgetful-notice { color: var(--neon-yellow); text-shadow: 0 0 5px var(--neon-yellow); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>WORKDAY LOGBOOK</h1>
|
||||
<div class="subtitle">FORGETFUL TASK TRACKER // NO DATA STORED</div>
|
||||
</header>
|
||||
|
||||
<section class="input-section">
|
||||
<div class="input-group">
|
||||
<label for="input-name">Operator Name</label>
|
||||
<input type="text" id="input-name" placeholder="ENTER NAME">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="input-org">Organization</label>
|
||||
<input type="text" id="input-org" placeholder="ENTER ORG">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="button-section">
|
||||
<button class="btn btn-start" id="btn-start">Start Task</button>
|
||||
<button class="btn btn-end" id="btn-end">End Task</button>
|
||||
<button class="btn btn-cats" id="btn-cats">Categories</button>
|
||||
</section>
|
||||
|
||||
<section class="status-bar">
|
||||
<div class="status-indicator">
|
||||
<span class="status-dot idle" id="status-dot"></span>
|
||||
<span id="status-text">IDLE</span>
|
||||
</div>
|
||||
<div class="current-task" id="current-task"></div>
|
||||
</section>
|
||||
|
||||
<section class="output-section">
|
||||
<div class="output-header">
|
||||
<h2>// WORK LOG OUTPUT</h2>
|
||||
<div class="output-btns">
|
||||
<button class="btn-newday" id="btn-newday">+ New Day</button>
|
||||
<button class="btn-copy" id="btn-copy">Copy</button>
|
||||
<button class="btn-export" id="btn-export">Export .md</button>
|
||||
</div>
|
||||
</div>
|
||||
<textarea id="worklog-output" readonly placeholder="Work log will appear here..."></textarea>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<p class="forgetful-notice">⚠ DATA IS LOST WHEN TAB CLOSES ⚠</p>
|
||||
<p>Copy or export your worklog before closing this page</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- Start Task Lightbox -->
|
||||
<div class="lightbox-overlay" id="start-lightbox">
|
||||
<div class="lightbox">
|
||||
<div class="lightbox-header"><h2>> START NEW TASK</h2></div>
|
||||
<div class="lightbox-body">
|
||||
<div class="form-group">
|
||||
<label for="task-category">Category</label>
|
||||
<select id="task-category">
|
||||
<option value="">-- SELECT CATEGORY --</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-description">Task Description</label>
|
||||
<input type="text" id="task-description" placeholder="Describe the task...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="lightbox-footer">
|
||||
<button class="btn btn-commit" id="btn-commit-start">Commit</button>
|
||||
<button class="btn btn-cancel" id="btn-cancel-start">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End Task Lightbox -->
|
||||
<div class="lightbox-overlay" id="end-lightbox">
|
||||
<div class="lightbox">
|
||||
<div class="lightbox-header"><h2>> END TASK</h2></div>
|
||||
<div class="lightbox-body" id="end-lightbox-body"></div>
|
||||
<div class="lightbox-footer" id="end-lightbox-footer">
|
||||
<button class="btn btn-commit" id="btn-commit-end">Commit</button>
|
||||
<button class="btn btn-cancel" id="btn-cancel-end">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Categories Lightbox -->
|
||||
<div class="lightbox-overlay" id="cats-lightbox">
|
||||
<div class="lightbox lightbox-cats">
|
||||
<div class="lightbox-header"><h2>> CATEGORIES</h2></div>
|
||||
<div class="lightbox-body">
|
||||
<div class="cat-add-row">
|
||||
<input type="text" id="new-cat-input" placeholder="NEW-Category">
|
||||
<button class="btn-add-cat" id="btn-add-cat">+ Add</button>
|
||||
</div>
|
||||
<div class="cat-list" id="cat-list"></div>
|
||||
<p class="cat-notice">⚠ Custom categories are session-only — lost when tab closes</p>
|
||||
</div>
|
||||
<div class="lightbox-footer">
|
||||
<button class="btn btn-cancel" id="btn-close-cats">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// ===== STATE =====
|
||||
let currentTask = null;
|
||||
let days = []; // Array of { date: string, lines: [] }
|
||||
let activeDayIdx = 0;
|
||||
|
||||
// ===== BUILT-IN CATEGORIES =====
|
||||
const builtinCategories = [
|
||||
'General','Creative','Admin','Break','Research','Ad Hoc','Personal',
|
||||
];
|
||||
let customCategories = []; // session-only
|
||||
|
||||
// ===== DOM ELEMENTS =====
|
||||
const inputName = document.getElementById('input-name');
|
||||
const inputOrg = document.getElementById('input-org');
|
||||
const btnStart = document.getElementById('btn-start');
|
||||
const btnEnd = document.getElementById('btn-end');
|
||||
const btnCats = document.getElementById('btn-cats');
|
||||
const btnCopy = document.getElementById('btn-copy');
|
||||
const btnExport = document.getElementById('btn-export');
|
||||
const btnNewDay = document.getElementById('btn-newday');
|
||||
const worklogOutput = document.getElementById('worklog-output');
|
||||
const statusDot = document.getElementById('status-dot');
|
||||
const statusText = document.getElementById('status-text');
|
||||
const currentTaskDisp = document.getElementById('current-task');
|
||||
const startLightbox = document.getElementById('start-lightbox');
|
||||
const endLightbox = document.getElementById('end-lightbox');
|
||||
const catsLightbox = document.getElementById('cats-lightbox');
|
||||
const taskCategory = document.getElementById('task-category');
|
||||
const taskDescription = document.getElementById('task-description');
|
||||
const btnCommitStart = document.getElementById('btn-commit-start');
|
||||
const btnCancelStart = document.getElementById('btn-cancel-start');
|
||||
const endLightboxBody = document.getElementById('end-lightbox-body');
|
||||
const btnCommitEnd = document.getElementById('btn-commit-end');
|
||||
const btnCancelEnd = document.getElementById('btn-cancel-end');
|
||||
const catList = document.getElementById('cat-list');
|
||||
const newCatInput = document.getElementById('new-cat-input');
|
||||
const btnAddCat = document.getElementById('btn-add-cat');
|
||||
const btnCloseCats = document.getElementById('btn-close-cats');
|
||||
|
||||
// ===== UTILITIES =====
|
||||
function formatDate(date) {
|
||||
const y = date.getFullYear();
|
||||
const m = String(date.getMonth()+1).padStart(2,'0');
|
||||
const d = String(date.getDate()).padStart(2,'0');
|
||||
const days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
|
||||
return `${y}-${m}-${d} - ${days[date.getDay()]}`;
|
||||
}
|
||||
|
||||
function formatTime(date) {
|
||||
return `${String(date.getHours()).padStart(2,'0')}:${String(date.getMinutes()).padStart(2,'0')}`;
|
||||
}
|
||||
|
||||
function todayKey() {
|
||||
const d = new Date();
|
||||
return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
|
||||
}
|
||||
|
||||
function calculateDuration(startDate, endDate) {
|
||||
const diffHours = (endDate - startDate) / (1000 * 60 * 60);
|
||||
return Math.round(diffHours * 2) / 2;
|
||||
}
|
||||
|
||||
function updateStatus(active, taskDesc = '') {
|
||||
if (active) {
|
||||
statusDot.classList.replace('idle', 'active');
|
||||
statusText.textContent = 'TASK ACTIVE';
|
||||
currentTaskDisp.textContent = taskDesc;
|
||||
} else {
|
||||
statusDot.classList.replace('active', 'idle');
|
||||
statusText.textContent = 'IDLE';
|
||||
currentTaskDisp.textContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
// ===== DAY MANAGEMENT =====
|
||||
function ensureTodayExists() {
|
||||
const key = todayKey();
|
||||
const existing = days.findIndex(d => d.key === key);
|
||||
if (existing === -1) {
|
||||
days.push({ key, date: formatDate(new Date()), lines: [] });
|
||||
activeDayIdx = days.length - 1;
|
||||
return true; // was new
|
||||
}
|
||||
activeDayIdx = existing;
|
||||
return false;
|
||||
}
|
||||
|
||||
function getActiveDay() {
|
||||
return days[activeDayIdx];
|
||||
}
|
||||
|
||||
// ===== WORKLOG GENERATION =====
|
||||
function generateWorklog() {
|
||||
const name = inputName.value.trim() || 'Unknown';
|
||||
const org = inputOrg.value.trim() || 'Unknown';
|
||||
|
||||
let output = '';
|
||||
days.forEach((day, idx) => {
|
||||
if (idx > 0) output += '\n\n---\n\n';
|
||||
output += `${day.date} - ${name} - ${org}\n\n`;
|
||||
output += '| BEGIN | TASK/ACTIVITY | END | HRS |\n';
|
||||
output += '| :-- | :-- | :-- | :-: |\n';
|
||||
day.lines.forEach(line => {
|
||||
output += `| ${line.start} | ${line.description} | ${line.end} | ${line.hours} |\n`;
|
||||
});
|
||||
// Show in-progress task in the active day
|
||||
if (idx === activeDayIdx && currentTask) {
|
||||
output += `| ${currentTask.startTime} | ${currentTask.category} - ${currentTask.description} | ... | ... |\n`;
|
||||
}
|
||||
});
|
||||
|
||||
worklogOutput.value = output;
|
||||
}
|
||||
|
||||
// ===== CATEGORY SELECT =====
|
||||
function rebuildCategorySelect() {
|
||||
const current = taskCategory.value;
|
||||
taskCategory.innerHTML = '<option value="">-- SELECT CATEGORY --</option>';
|
||||
const all = [...builtinCategories, ...customCategories];
|
||||
all.forEach(cat => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = cat;
|
||||
opt.textContent = cat;
|
||||
taskCategory.appendChild(opt);
|
||||
});
|
||||
if (current) taskCategory.value = current;
|
||||
}
|
||||
|
||||
function renderCatList() {
|
||||
catList.innerHTML = '';
|
||||
const all = [
|
||||
...builtinCategories.map(c => ({ name: c, type: 'builtin' })),
|
||||
...customCategories.map(c => ({ name: c, type: 'custom' }))
|
||||
];
|
||||
all.forEach(({ name, type }) => {
|
||||
const row = document.createElement('div');
|
||||
row.className = `cat-item ${type}`;
|
||||
row.innerHTML = `<span>${name}</span>`;
|
||||
if (type === 'custom') {
|
||||
const del = document.createElement('button');
|
||||
del.className = 'cat-delete';
|
||||
del.textContent = '[x]';
|
||||
del.onclick = () => {
|
||||
customCategories = customCategories.filter(c => c !== name);
|
||||
rebuildCategorySelect();
|
||||
renderCatList();
|
||||
};
|
||||
row.appendChild(del);
|
||||
}
|
||||
catList.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
// ===== LIGHTBOX CONTROLS =====
|
||||
function openStartLightbox() {
|
||||
taskCategory.value = '';
|
||||
taskDescription.value = '';
|
||||
rebuildCategorySelect();
|
||||
startLightbox.classList.add('active');
|
||||
taskCategory.focus();
|
||||
}
|
||||
function closeStartLightbox() { startLightbox.classList.remove('active'); }
|
||||
|
||||
function openEndLightbox() {
|
||||
if (!currentTask) {
|
||||
endLightboxBody.innerHTML = `
|
||||
<div class="alert-message">
|
||||
<strong>NO OPEN TASK EXISTS</strong><br>There is no active task to end.
|
||||
</div>`;
|
||||
btnCommitEnd.style.display = 'none';
|
||||
} else {
|
||||
const now = new Date();
|
||||
const duration = calculateDuration(currentTask.startDate, now);
|
||||
endLightboxBody.innerHTML = `
|
||||
<div class="form-group">
|
||||
<label>Task</label>
|
||||
<div style="color:var(--neon-cyan);padding:0.5rem;border:1px solid var(--neon-cyan);">
|
||||
${currentTask.category} - ${currentTask.description}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Started At</label>
|
||||
<div style="color:var(--neon-lime);">${currentTask.startTime}</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>End Time</label>
|
||||
<div style="color:var(--neon-red);">${formatTime(now)}</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Duration (rounded to 0.5h)</label>
|
||||
<div style="color:var(--neon-yellow);font-size:1.25rem;">${duration} hours</div>
|
||||
</div>`;
|
||||
btnCommitEnd.style.display = 'block';
|
||||
}
|
||||
endLightbox.classList.add('active');
|
||||
}
|
||||
function closeEndLightbox() { endLightbox.classList.remove('active'); }
|
||||
|
||||
function openCatsLightbox() {
|
||||
renderCatList();
|
||||
newCatInput.value = '';
|
||||
catsLightbox.classList.add('active');
|
||||
newCatInput.focus();
|
||||
}
|
||||
function closeCatsLightbox() { catsLightbox.classList.remove('active'); }
|
||||
|
||||
// ===== HANDLERS =====
|
||||
btnStart.addEventListener('click', () => {
|
||||
if (!inputName.value.trim() || !inputOrg.value.trim()) {
|
||||
alert('Please enter Name and Organization first.');
|
||||
inputName.focus();
|
||||
return;
|
||||
}
|
||||
// Check if we've rolled into a new day
|
||||
const wasNew = ensureTodayExists();
|
||||
if (wasNew) generateWorklog();
|
||||
openStartLightbox();
|
||||
});
|
||||
|
||||
btnEnd.addEventListener('click', openEndLightbox);
|
||||
|
||||
btnCats.addEventListener('click', openCatsLightbox);
|
||||
|
||||
btnCommitStart.addEventListener('click', () => {
|
||||
const category = taskCategory.value;
|
||||
const description = taskDescription.value.trim();
|
||||
if (!category) { alert('Please select a category.'); taskCategory.focus(); return; }
|
||||
if (!description) { alert('Please enter a task description.'); taskDescription.focus(); return; }
|
||||
|
||||
const now = new Date();
|
||||
const day = getActiveDay();
|
||||
|
||||
if (currentTask) {
|
||||
const duration = calculateDuration(currentTask.startDate, now);
|
||||
day.lines.push({
|
||||
start: currentTask.startTime,
|
||||
description: `${currentTask.category} - ${currentTask.description} (switched at ${formatTime(now)})`,
|
||||
end: formatTime(now),
|
||||
hours: duration
|
||||
});
|
||||
}
|
||||
|
||||
currentTask = { startDate: now, startTime: formatTime(now), category, description };
|
||||
updateStatus(true, `${category} - ${description}`);
|
||||
generateWorklog();
|
||||
closeStartLightbox();
|
||||
});
|
||||
|
||||
btnCancelStart.addEventListener('click', closeStartLightbox);
|
||||
|
||||
btnCommitEnd.addEventListener('click', () => {
|
||||
if (!currentTask) return;
|
||||
const now = new Date();
|
||||
const duration = calculateDuration(currentTask.startDate, now);
|
||||
getActiveDay().lines.push({
|
||||
start: currentTask.startTime,
|
||||
description: `${currentTask.category} - ${currentTask.description}`,
|
||||
end: formatTime(now),
|
||||
hours: duration
|
||||
});
|
||||
currentTask = null;
|
||||
updateStatus(false);
|
||||
generateWorklog();
|
||||
closeEndLightbox();
|
||||
});
|
||||
|
||||
btnCancelEnd.addEventListener('click', closeEndLightbox);
|
||||
|
||||
btnAddCat.addEventListener('click', addCustomCategory);
|
||||
newCatInput.addEventListener('keydown', e => { if (e.key === 'Enter') addCustomCategory(); });
|
||||
|
||||
function addCustomCategory() {
|
||||
const val = newCatInput.value.trim().replace(/\s+/g, '-');
|
||||
if (!val) return;
|
||||
if ([...builtinCategories, ...customCategories].includes(val)) {
|
||||
newCatInput.value = '';
|
||||
return;
|
||||
}
|
||||
customCategories.push(val);
|
||||
rebuildCategorySelect();
|
||||
renderCatList();
|
||||
newCatInput.value = '';
|
||||
newCatInput.focus();
|
||||
}
|
||||
|
||||
btnCloseCats.addEventListener('click', closeCatsLightbox);
|
||||
|
||||
// ===== NEW DAY BUTTON =====
|
||||
btnNewDay.addEventListener('click', () => {
|
||||
if (!inputName.value.trim() || !inputOrg.value.trim()) {
|
||||
alert('Please enter Name and Organization first.');
|
||||
return;
|
||||
}
|
||||
const key = todayKey();
|
||||
// Always add a fresh entry for today even if one exists
|
||||
days.push({ key, date: formatDate(new Date()), lines: [] });
|
||||
activeDayIdx = days.length - 1;
|
||||
currentTask = null;
|
||||
updateStatus(false);
|
||||
generateWorklog();
|
||||
});
|
||||
|
||||
// ===== COPY =====
|
||||
btnCopy.addEventListener('click', async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(worklogOutput.value);
|
||||
} catch {
|
||||
worklogOutput.removeAttribute('readonly');
|
||||
worklogOutput.select();
|
||||
document.execCommand('copy');
|
||||
worklogOutput.setAttribute('readonly', '');
|
||||
}
|
||||
btnCopy.textContent = 'COPIED!';
|
||||
btnCopy.classList.add('copied');
|
||||
setTimeout(() => { btnCopy.textContent = 'Copy'; btnCopy.classList.remove('copied'); }, 2000);
|
||||
});
|
||||
|
||||
// ===== EXPORT MARKDOWN =====
|
||||
btnExport.addEventListener('click', () => {
|
||||
const content = worklogOutput.value;
|
||||
if (!content.trim()) { alert('Nothing to export yet.'); return; }
|
||||
const name = (inputName.value.trim() || 'worklog').replace(/\s+/g, '_');
|
||||
const dateStr = todayKey();
|
||||
const filename = `worklog_${name}_${dateStr}.md`;
|
||||
const blob = new Blob([content], { type: 'text/markdown;charset=utf-8' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
|
||||
// ===== CLOSE ON OVERLAY CLICK / ESCAPE =====
|
||||
startLightbox.addEventListener('click', e => { if (e.target === startLightbox) closeStartLightbox(); });
|
||||
endLightbox.addEventListener('click', e => { if (e.target === endLightbox) closeEndLightbox(); });
|
||||
catsLightbox.addEventListener('click', e => { if (e.target === catsLightbox) closeCatsLightbox(); });
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape') { closeStartLightbox(); closeEndLightbox(); closeCatsLightbox(); }
|
||||
});
|
||||
|
||||
// ===== INIT =====
|
||||
ensureTodayExists();
|
||||
rebuildCategorySelect();
|
||||
generateWorklog();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
116
DumperCan/SAQA_MICTSETA_QCTO_tabs-export-2025-11-06T11-25-59.md
Normal file
116
DumperCan/SAQA_MICTSETA_QCTO_tabs-export-2025-11-06T11-25-59.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Browser Tabs Export
|
||||
|
||||
**Exported:** Thursday, November 6, 2025 at 1:25 PM
|
||||
|
||||
**Total Tabs:** 36
|
||||
|
||||
---
|
||||
|
||||
- **Legislation & Regulation Policies \- SAQA**
|
||||
- URL: https://www.saqa.org.za/legislation-regulation-policies/
|
||||
|
||||
- **SAQA**
|
||||
- URL: https://allqs.saqa.org.za/search.php?cat=qual
|
||||
|
||||
- **SAQA**
|
||||
- URL: https://allqs.saqa.org.za/search.php?cat=unit
|
||||
|
||||
- **SAQA**
|
||||
- URL: https://regqs.saqa.org.za/search.php?cat=qual
|
||||
|
||||
- **SAQA**
|
||||
- URL: https://regqs.saqa.org.za/search.php?cat=unit
|
||||
|
||||
- **SAQA**
|
||||
- URL: https://trade.saqa.org.za/search.php?cat=qual
|
||||
|
||||
- **MICT SETA | Sector Education and Training Authority**
|
||||
- URL: https://www.mict.org.za/
|
||||
|
||||
- **Stakeholder Information | MICT SETA**
|
||||
- URL: https://www.mict.org.za/stakeholder-information/
|
||||
|
||||
- **Invitation: Annual General Meeting 2025 \(Hybrid\) | MICT SETA**
|
||||
- URL: https://www.mict.org.za/invitation-annual-general-meeting-2025-hybrid/
|
||||
|
||||
- **Divisional Brochures | MICT SETA**
|
||||
- URL: https://www.mict.org.za/publications/divisional-brochures/
|
||||
|
||||
- **Career Opportunities Guide | MICT SETA**
|
||||
- URL: https://www.mict.org.za/publications/career-opportunities-guide/
|
||||
|
||||
- **Open Request for Quotations | MICT SETA**
|
||||
- URL: https://www.mict.org.za/supplychain/open-request-for-quotations/
|
||||
|
||||
- **Open Tenders | MICT SETA**
|
||||
- URL: https://www.mict.org.za/supplychain/open-tenders/
|
||||
|
||||
- **Capacity Building Workshops 2025 | MICT SETA**
|
||||
- URL: https://www.mict.org.za/capacity-building-workshops-2025/
|
||||
|
||||
- **Session Invites and Schedules | MICT SETA**
|
||||
- URL: https://www.mict.org.za/session-invites-and-schedules/
|
||||
|
||||
- **QCTO Home of skills assurance**
|
||||
- URL: https://www.qcto.org.za/
|
||||
|
||||
- **Database of Skills Development Providers**
|
||||
- URL: https://www.qcto.org.za/databases-of-sdps.html
|
||||
|
||||
- **For skills development providers**
|
||||
- URL: https://www.qcto.org.za/for-skills-development-providers.html
|
||||
|
||||
- **Learner enrolment and EISA registration process**
|
||||
- URL: https://www.qcto.org.za/learner-enrolment-and-eisa-registration-process.html
|
||||
|
||||
- **For learners**
|
||||
- URL: https://www.qcto.org.za/for-learners.html
|
||||
|
||||
- **For employers**
|
||||
- URL: https://www.qcto.org.za/for-employers.html
|
||||
|
||||
- **For assessment centres**
|
||||
- URL: https://www.qcto.org.za/for-assessment-centres.html
|
||||
|
||||
- **For quality partners**
|
||||
- URL: https://www.qcto.org.za/for-quality-partners.html
|
||||
|
||||
- **Skills Programmes**
|
||||
- URL: https://www.qcto.org.za/skills-programmes.html
|
||||
|
||||
- **Skills Programmes**
|
||||
- URL: https://www.qcto.org.za/skillsProgrammesForNewLeavers.html
|
||||
|
||||
- **Skills Programmes**
|
||||
- URL: https://www.qcto.org.za/expiredSkillsProgrammes.html
|
||||
|
||||
- **Empowering SDPs Nationwide**
|
||||
- URL: https://www.qcto.org.za/empowering_sdps_nationwide.html
|
||||
|
||||
- **Notices and circulars**
|
||||
- URL: https://www.qcto.org.za/notices-and-circulars.html
|
||||
|
||||
- **Publications, policies, guidelines & forms**
|
||||
- URL: https://www.qcto.org.za/publications%2c-policies%2c-guidelines---forms.html
|
||||
|
||||
- **Mandate**
|
||||
- URL: https://www.qcto.org.za/mandate.html
|
||||
|
||||
- **Management**
|
||||
- URL: https://www.qcto.org.za/management.html
|
||||
|
||||
- **Council**
|
||||
- URL: https://www.qcto.org.za/council.html
|
||||
|
||||
- **Sub\-Committees**
|
||||
- URL: https://www.qcto.org.za/sub-committees.html
|
||||
|
||||
- **Stakeholders**
|
||||
- URL: https://www.qcto.org.za/stakeholders.html
|
||||
|
||||
- **Procurement**
|
||||
- URL: https://www.qcto.org.za/procurement.html
|
||||
|
||||
- **Contact Us**
|
||||
- URL: https://www.qcto.org.za/contact-us.html
|
||||
|
||||
@@ -0,0 +1,963 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Anarchist Angels Style Reference</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
ANARCHIST ANGELS STYLE REFERENCE
|
||||
PUNK ROCK ENERGY | REBELLIOUS | UNAPOLOGETIC
|
||||
NO RULES, ONLY VIBES
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Pitch black chaos to midnight rebellion */
|
||||
--bg-gradient-1: #000000; /* Pure black */
|
||||
--bg-gradient-2: #0d0d0d; /* Almost black */
|
||||
--bg-gradient-3: #1a1a1a; /* Dark charcoal */
|
||||
--bg-gradient-4: #0a0a0a; /* Void black */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(255,255,255,0.03); /* Barely lifted */
|
||||
--bg-card: rgba(255,255,255,0.05); /* Subtle cards */
|
||||
--bg-darker: rgba(0,0,0,0.8); /* Deep nested */
|
||||
--bg-solid-dark: #000000; /* Pure black */
|
||||
--bg-solid-header: #0d0d0d; /* Almost black */
|
||||
|
||||
/* --- BORDERS ---
|
||||
Sharp, aggressive, in your face */
|
||||
--border-color: #ffffff; /* Pure white */
|
||||
--border-punk: #ff0055; /* Hot pink punk */
|
||||
--border-anarchy: #00ff00; /* Toxic green */
|
||||
--border-width: 2px;
|
||||
--border-width-medium: 3px;
|
||||
--border-width-thick: 4px;
|
||||
--border-width-ultra: 6px;
|
||||
|
||||
/* --- BORDER RADIUS ---
|
||||
SHARP AS HELL: 0-2px only */
|
||||
--radius-none: 0px;
|
||||
--radius-xs: 1px;
|
||||
--radius-sm: 2px;
|
||||
|
||||
/* --- ACCENT SYSTEM ---
|
||||
LOUD, PROUD, REBELLIOUS
|
||||
Chaos: Hot destructive colors
|
||||
Riot: Toxic punk energy
|
||||
Halo: Angelic contrast
|
||||
Rage: Pure aggression */
|
||||
--accent-chaos-1: #ff0055; /* Hot pink scream */
|
||||
--accent-chaos-2: #ff3366; /* Pink rage */
|
||||
--accent-riot-1: #00ff00; /* Toxic green */
|
||||
--accent-riot-2: #33ff33; /* Neon lime */
|
||||
--accent-halo-1: #ffffff; /* Pure angel white */
|
||||
--accent-halo-2: #f0f0f0; /* Off-white halo */
|
||||
--accent-rage-1: #ff0000; /* Pure red fury */
|
||||
--accent-rage-2: #ff3333; /* Bright red */
|
||||
--accent-rebel-1: #ffff00; /* Electric yellow */
|
||||
--accent-rebel-2: #ffff33; /* Bright yellow */
|
||||
--accent-void-1: #9933ff; /* Purple chaos */
|
||||
--accent-void-2: #aa44ff; /* Bright purple */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS ---
|
||||
MAXIMUM CONTRAST, ZERO COMPROMISES */
|
||||
--text-primary: #ffffff; /* Pure white */
|
||||
--text-secondary: #f0f0f0; /* Almost white */
|
||||
--text-muted: #cccccc; /* Light gray */
|
||||
--text-punk: #ff0055; /* Hot pink */
|
||||
--text-riot: #00ff00; /* Toxic green */
|
||||
--text-h1-gradient: linear-gradient(135deg, #ff0055 0%, #ffff00 33%, #00ff00 66%, #ffffff 100%);
|
||||
--text-h2: #ff0055; /* Chaos pink */
|
||||
--text-h3: #00ff00; /* Riot green */
|
||||
--text-h4: #ffff00; /* Rebel yellow */
|
||||
--text-h5: #ffffff; /* Halo white */
|
||||
--text-h6: #9933ff; /* Void purple */
|
||||
|
||||
/* --- BUTTON GRADIENTS ---
|
||||
AGGRESSIVE AND LOUD */
|
||||
--btn-primary-gradient: linear-gradient(135deg, #ff0055 0%, #ff3366 100%);
|
||||
--btn-secondary-gradient: linear-gradient(135deg, #00ff00 0%, #33ff33 100%);
|
||||
|
||||
/* --- GLOW EFFECTS ---
|
||||
INTENSE PUNK ENERGY */
|
||||
--glow-pink: 0 0 30px rgba(255, 0, 85, 0.8);
|
||||
--glow-green: 0 0 30px rgba(0, 255, 0, 0.8);
|
||||
--glow-yellow: 0 0 30px rgba(255, 255, 0, 0.8);
|
||||
--glow-white: 0 0 30px rgba(255, 255, 255, 0.6);
|
||||
--glow-red: 0 0 30px rgba(255, 0, 0, 0.8);
|
||||
--glow-purple: 0 0 30px rgba(153, 51, 255, 0.8);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Inter', sans-serif;
|
||||
--font-body: 'IBM Plex Sans', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2.5rem, 6vw, 4rem);
|
||||
font-weight: 900;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.03em;
|
||||
text-transform: uppercase;
|
||||
filter: drop-shadow(0 0 20px rgba(255, 0, 85, 0.8));
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.75rem, 4.5vw, 2.5rem);
|
||||
font-weight: 800;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.02em;
|
||||
text-transform: uppercase;
|
||||
text-shadow: var(--glow-pink);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.5rem, 3.5vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
text-shadow: var(--glow-green);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.75rem);
|
||||
font-weight: 700;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
text-shadow: var(--glow-yellow);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--accent-chaos-1);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s ease;
|
||||
border-bottom: 2px solid var(--accent-chaos-1);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--accent-riot-1);
|
||||
border-bottom-color: var(--accent-riot-1);
|
||||
text-shadow: var(--glow-green);
|
||||
}
|
||||
|
||||
/* ===== 6. CARDS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-medium) solid var(--border-color);
|
||||
border-radius: var(--radius-xs);
|
||||
padding: 1.5rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
border-color: var(--accent-chaos-1);
|
||||
box-shadow: var(--glow-pink);
|
||||
transform: translateY(-4px) rotate(-0.5deg);
|
||||
}
|
||||
|
||||
.card-solid {
|
||||
background: var(--bg-solid-header);
|
||||
border: var(--border-width-medium) solid var(--border-color);
|
||||
border-radius: var(--radius-xs);
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
border: var(--border-width-thick) solid var(--accent-halo-1);
|
||||
border-radius: var(--radius-xs);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-white);
|
||||
}
|
||||
|
||||
.card-chaos {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-thick) solid var(--accent-chaos-1);
|
||||
border-radius: var(--radius-xs);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-pink);
|
||||
}
|
||||
|
||||
.card-riot {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-thick) solid var(--accent-riot-1);
|
||||
border-radius: var(--radius-xs);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-green);
|
||||
}
|
||||
|
||||
.card-rage {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-thick) solid var(--accent-rage-1);
|
||||
border-radius: var(--radius-xs);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-red);
|
||||
}
|
||||
|
||||
.card-rebel {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-thick) solid var(--accent-rebel-1);
|
||||
border-radius: var(--radius-xs);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-yellow);
|
||||
}
|
||||
|
||||
/* ===== 7. BUTTONS ===== */
|
||||
.btn {
|
||||
padding: 1rem 2rem;
|
||||
border-radius: var(--radius-xs);
|
||||
border: none;
|
||||
font-weight: 800;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--btn-primary-gradient);
|
||||
color: var(--bg-solid-dark);
|
||||
border: var(--border-width) solid var(--accent-chaos-1);
|
||||
box-shadow: var(--glow-pink);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
box-shadow: 0 0 40px rgba(255, 0, 85, 1);
|
||||
transform: translateY(-4px) scale(1.05);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--btn-secondary-gradient);
|
||||
color: var(--bg-solid-dark);
|
||||
border: var(--border-width) solid var(--accent-riot-1);
|
||||
box-shadow: var(--glow-green);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
box-shadow: 0 0 40px rgba(0, 255, 0, 1);
|
||||
transform: translateY(-4px) scale(1.05);
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
color: var(--accent-chaos-1);
|
||||
border: var(--border-width-thick) solid var(--accent-chaos-1);
|
||||
}
|
||||
|
||||
.btn-outline:hover {
|
||||
background: var(--accent-chaos-1);
|
||||
color: var(--bg-solid-dark);
|
||||
box-shadow: var(--glow-pink);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--accent-riot-1);
|
||||
border: var(--border-width-medium) solid transparent;
|
||||
}
|
||||
|
||||
.btn-ghost:hover {
|
||||
background: var(--bg-elevated);
|
||||
border-color: var(--accent-riot-1);
|
||||
box-shadow: var(--glow-green);
|
||||
}
|
||||
|
||||
.btn-rage {
|
||||
background: linear-gradient(135deg, var(--accent-rage-1) 0%, var(--accent-rage-2) 100%);
|
||||
color: var(--text-primary);
|
||||
border: var(--border-width) solid var(--accent-rage-1);
|
||||
box-shadow: var(--glow-red);
|
||||
}
|
||||
|
||||
.btn-rage:hover {
|
||||
box-shadow: 0 0 40px rgba(255, 0, 0, 1);
|
||||
transform: translateY(-4px) scale(1.05);
|
||||
}
|
||||
|
||||
/* ===== 8. ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1.5rem;
|
||||
border-radius: var(--radius-sm);
|
||||
border-left: var(--border-width-ultra) solid;
|
||||
margin-bottom: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.alert-chaos {
|
||||
background: rgba(255, 0, 85, 0.1);
|
||||
border-left-color: var(--accent-chaos-1);
|
||||
border: var(--border-width-medium) solid var(--accent-chaos-1);
|
||||
box-shadow: var(--glow-pink);
|
||||
}
|
||||
|
||||
.alert-riot {
|
||||
background: rgba(0, 255, 0, 0.1);
|
||||
border-left-color: var(--accent-riot-1);
|
||||
border: var(--border-width-medium) solid var(--accent-riot-1);
|
||||
box-shadow: var(--glow-green);
|
||||
}
|
||||
|
||||
.alert-rebel {
|
||||
background: rgba(255, 255, 0, 0.1);
|
||||
border-left-color: var(--accent-rebel-1);
|
||||
border: var(--border-width-medium) solid var(--accent-rebel-1);
|
||||
box-shadow: var(--glow-yellow);
|
||||
}
|
||||
|
||||
.alert-rage {
|
||||
background: rgba(255, 0, 0, 0.1);
|
||||
border-left-color: var(--accent-rage-1);
|
||||
border: var(--border-width-medium) solid var(--accent-rage-1);
|
||||
box-shadow: var(--glow-red);
|
||||
}
|
||||
|
||||
/* ===== 9. CODE BLOCKS ===== */
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-darker);
|
||||
padding: 0.3rem 0.6rem;
|
||||
border-radius: var(--radius-xs);
|
||||
font-size: 0.9em;
|
||||
color: var(--accent-riot-1);
|
||||
border: var(--border-width) solid var(--accent-riot-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: var(--bg-darker);
|
||||
border: var(--border-width-medium) solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1.5rem;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
border: none;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ===== 10. TABLES ===== */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
th {
|
||||
background: var(--bg-darker);
|
||||
color: var(--accent-chaos-1);
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
font-weight: 800;
|
||||
border: var(--border-width-medium) solid var(--border-color);
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 1rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background: var(--bg-elevated);
|
||||
}
|
||||
|
||||
/* ===== 11. LISTS ===== */
|
||||
ul, ol {
|
||||
margin-left: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.75rem;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
li strong {
|
||||
color: var(--accent-chaos-1);
|
||||
}
|
||||
|
||||
/* ===== 12. UTILITY CLASSES ===== */
|
||||
.mb-1 { margin-bottom: 0.5rem; }
|
||||
.mb-2 { margin-bottom: 1rem; }
|
||||
.mb-3 { margin-bottom: 2rem; }
|
||||
.mt-1 { margin-top: 0.5rem; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mt-3 { margin-top: 2rem; }
|
||||
.text-center { text-align: center; }
|
||||
|
||||
/* ===== 13. DIVIDERS ===== */
|
||||
.section-divider {
|
||||
border: none;
|
||||
border-top: var(--border-width-thick) solid var(--border-color);
|
||||
margin: 2rem 0;
|
||||
box-shadow: 0 2px 20px rgba(255, 0, 85, 0.5);
|
||||
}
|
||||
|
||||
.section-divider-riot {
|
||||
border-top-color: var(--accent-riot-1);
|
||||
box-shadow: 0 2px 20px rgba(0, 255, 0, 0.5);
|
||||
}
|
||||
|
||||
/* ===== 14. HEADER ===== */
|
||||
header {
|
||||
text-align: center;
|
||||
padding: 3rem 0;
|
||||
margin-bottom: 2rem;
|
||||
border: var(--border-width-ultra) solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--bg-solid-header);
|
||||
box-shadow: 0 0 40px rgba(255, 0, 85, 0.3);
|
||||
}
|
||||
|
||||
/* ===== 15. PUNK ROCK EXTRAS ===== */
|
||||
.punk-emphasis {
|
||||
color: var(--accent-chaos-1);
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.riot-emphasis {
|
||||
color: var(--accent-riot-1);
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.rebel-emphasis {
|
||||
color: var(--accent-rebel-1);
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* Chaotic rotation on some cards */
|
||||
.card-chaos:hover {
|
||||
transform: translateY(-4px) rotate(1deg);
|
||||
}
|
||||
|
||||
.card-riot:hover {
|
||||
transform: translateY(-4px) rotate(-1deg);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header>
|
||||
<h1>ANARCHIST ANGELS</h1>
|
||||
<p style="font-size: 1.5rem; color: var(--text-primary); margin-top: 1rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em;">
|
||||
<span class="punk-emphasis">PUNK ROCK ENERGY</span> • <span class="riot-emphasis">ZERO RULES</span> • <span class="rebel-emphasis">MAXIMUM CHAOS</span>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- THEME MANIFESTO -->
|
||||
<section class="mb-3">
|
||||
<h2>THE MANIFESTO</h2>
|
||||
<div class="card-elevated">
|
||||
<p style="font-size: 1.25rem; line-height: 1.8; font-weight: 600;">
|
||||
<span class="punk-emphasis">ANARCHIST ANGELS</span> is the design system for rebels, punks, and digital anarchists. Pure black chaos meets angelic white light. No subtle gradients, no corporate BS, no compromises. Just <span class="riot-emphasis">LOUD</span>, <span class="punk-emphasis">PROUD</span>, and <span class="rebel-emphasis">IN YOUR FACE</span> design that refuses to play by the rules.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-3 mt-2">
|
||||
<div class="card-chaos">
|
||||
<h3>CHAOS SYSTEM</h3>
|
||||
<ul>
|
||||
<li><strong>HOT PINK RAGE:</strong> #ff0055 screaming energy</li>
|
||||
<li><strong>ZERO SUBTLETY:</strong> Maximum contrast always</li>
|
||||
<li><strong>AGGRESSIVE GLOWS:</strong> 30px shadows everywhere</li>
|
||||
<li><strong>SHARP EDGES:</strong> 0-2px radius only</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-riot">
|
||||
<h3>RIOT ENERGY</h3>
|
||||
<ul>
|
||||
<li><strong>TOXIC GREEN:</strong> #00ff00 pure rebellion</li>
|
||||
<li><strong>PUNK TYPOGRAPHY:</strong> All caps, all attitude</li>
|
||||
<li><strong>BOLD BORDERS:</strong> 2-6px thick lines</li>
|
||||
<li><strong>NO COMPROMISE:</strong> Pure white on pure black</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-rebel">
|
||||
<h3>REBEL SPIRIT</h3>
|
||||
<ul>
|
||||
<li><strong>ELECTRIC YELLOW:</strong> #ffff00 warning lights</li>
|
||||
<li><strong>GRAFFITI VIBES:</strong> Street art aesthetic</li>
|
||||
<li><strong>CHAOTIC MOTION:</strong> Rotations on hover</li>
|
||||
<li><strong>PURE ATTITUDE:</strong> Unapologetically loud</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>PUNK ROCK PALETTE</h2>
|
||||
<div class="grid grid-4">
|
||||
<div class="card" style="background: linear-gradient(135deg, #ff0055 0%, #ff3366 100%); color: #000000; border-color: #ffffff;">
|
||||
<h4 style="color: #000000; text-shadow: none;">CHAOS</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000000; border-color: #000000;">#FF0055</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #000000; font-weight: 700;">HOT PINK SCREAM</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #00ff00 0%, #33ff33 100%); color: #000000; border-color: #ffffff;">
|
||||
<h4 style="color: #000000; text-shadow: none;">RIOT</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000000; border-color: #000000;">#00FF00</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #000000; font-weight: 700;">TOXIC GREEN</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #ffff00 0%, #ffff33 100%); color: #000000; border-color: #ffffff;">
|
||||
<h4 style="color: #000000; text-shadow: none;">REBEL</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000000; border-color: #000000;">#FFFF00</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #000000; font-weight: 700;">ELECTRIC YELLOW</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #ff0000 0%, #ff3333 100%); color: #000000; border-color: #ffffff;">
|
||||
<h4 style="color: #000000; text-shadow: none;">RAGE</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000000; border-color: #000000;">#FF0000</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #000000; font-weight: 700;">PURE RED FURY</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #9933ff 0%, #aa44ff 100%); color: #000000; border-color: #ffffff;">
|
||||
<h4 style="color: #000000; text-shadow: none;">VOID</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000000; border-color: #000000;">#9933FF</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #000000; font-weight: 700;">PURPLE CHAOS</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #ffffff 0%, #f0f0f0 100%); color: #000000; border-color: #000000;">
|
||||
<h4 style="color: #000000; text-shadow: none;">HALO</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000000; border-color: #000000;">#FFFFFF</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #000000; font-weight: 700;">PURE ANGEL WHITE</p>
|
||||
</div>
|
||||
<div class="card" style="background: #000000; color: #ffffff; border-color: #ff0055;">
|
||||
<h4 style="color: #ffffff; text-shadow: var(--glow-pink);">VOID</h4>
|
||||
<code style="background: rgba(255,255,255,0.1); color: #ffffff; border-color: #ffffff;">#000000</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #ffffff; font-weight: 700;">PURE BLACK CHAOS</p>
|
||||
</div>
|
||||
<div class="card" style="background: #000000; color: #ffffff; border-color: #00ff00;">
|
||||
<h4 style="color: #ffffff; text-shadow: var(--glow-white);">ANGEL</h4>
|
||||
<code style="background: rgba(255,255,255,0.1); color: #ffffff; border-color: #ffffff;">#FFFFFF</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #ffffff; font-weight: 700;">CONTRAST MAXIMUM</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider section-divider-riot">
|
||||
|
||||
<!-- TYPOGRAPHY -->
|
||||
<section class="mb-3">
|
||||
<h2>PUNK TYPOGRAPHY</h2>
|
||||
<div class="card">
|
||||
<h1>H1: MAXIMUM CHAOS GRADIENT</h1>
|
||||
<h2>H2: HOT PINK SCREAM</h2>
|
||||
<h3>H3: TOXIC GREEN RIOT</h3>
|
||||
<h4>H4: ELECTRIC YELLOW REBEL</h4>
|
||||
<h5>H5: PURE WHITE HALO</h5>
|
||||
<h6>H6: PURPLE VOID CHAOS</h6>
|
||||
<p style="margin-top: 1rem;">Body text is LOUD and CLEAR - pure white (#ffffff) on pure black (#000000). No gray areas, no middle ground, no compromises. Every word matters. Every sentence screams. This is typography that refuses to whisper.</p>
|
||||
<p style="color: var(--text-muted);">Even muted text (#cccccc) maintains aggressive readability because ACCESSIBILITY IS PUNK ROCK.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-chaos mt-2">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem; text-shadow: none;">TYPOGRAPHY RULES</h3>
|
||||
<ul style="margin-left: 1.5rem; margin-top: 0.5rem;">
|
||||
<li><strong>ALL CAPS EVERYTHING:</strong> Headers scream in uppercase</li>
|
||||
<li><strong>HEAVY WEIGHTS:</strong> 700-900 font weight minimum</li>
|
||||
<li><strong>TIGHT TRACKING:</strong> Compressed letter spacing</li>
|
||||
<li><strong>GLOW EFFECTS:</strong> 30px text shadows on all headings</li>
|
||||
<li><strong>ZERO SUBTLETY:</strong> Pure white or pure accent colors</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>AGGRESSIVE BUTTONS</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card">
|
||||
<h3>PRIMARY ACTIONS</h3>
|
||||
<button class="btn btn-primary">CHAOS BUTTON</button>
|
||||
<button class="btn btn-secondary mt-2">RIOT BUTTON</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>ALTERNATIVE STYLES</h3>
|
||||
<button class="btn btn-outline">OUTLINE PUNK</button>
|
||||
<button class="btn btn-ghost mt-2">GHOST REBEL</button>
|
||||
<button class="btn btn-rage mt-2">RAGE MODE</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-riot mt-2">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem; text-shadow: none;">BUTTON PHILOSOPHY</h3>
|
||||
<p style="margin: 0;">Buttons are <strong>LOUD</strong>, <strong>PROUD</strong>, and <strong>IMPOSSIBLE TO IGNORE</strong>. They scale up on hover, glow like neon signs, and demand to be clicked. No subtle hover states - only AGGRESSIVE TRANSFORMATIONS.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider section-divider-riot">
|
||||
|
||||
<!-- CARDS -->
|
||||
<section class="mb-3">
|
||||
<h2>REBELLIOUS CARDS</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card">
|
||||
<h3>STANDARD CARD</h3>
|
||||
<p>Default white border. Hover for pink glow and chaotic rotation.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-solid">
|
||||
<h3>SOLID BLACK</h3>
|
||||
<p>Pure black background. Zero transparency. Maximum void.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-elevated">
|
||||
<h3>ANGELIC LIFT</h3>
|
||||
<p>White border with halo glow. The angels among chaos.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-chaos">
|
||||
<h3>CHAOS ENERGY</h3>
|
||||
<p>Hot pink border. Pink glow. Rotates clockwise on hover. Pure punk energy.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-riot">
|
||||
<h3>RIOT MODE</h3>
|
||||
<p>Toxic green border. Green glow. Counter-clockwise rotation. Rebellion incarnate.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-rage">
|
||||
<h3>RAGE STATE</h3>
|
||||
<p>Pure red fury. Red glow. No rotation - just pure aggressive energy.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-rebel">
|
||||
<h3>REBEL SPIRIT</h3>
|
||||
<p>Electric yellow warning. Yellow glow. Unstable and proud of it.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>AGGRESSIVE ALERTS</h2>
|
||||
<div class="alert alert-chaos">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem; text-shadow: none;">CHAOS ALERT</h3>
|
||||
<p style="margin: 0;">Hot pink border with pink glow - for messages that need MAXIMUM ATTENTION and refuse to be ignored.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-riot">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem; text-shadow: none;">RIOT ALERT</h3>
|
||||
<p style="margin: 0;">Toxic green border with green glow - for rebellious notifications that break the rules.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-rebel">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem; text-shadow: none;">REBEL ALERT</h3>
|
||||
<p style="margin: 0;">Electric yellow border with yellow glow - WARNING: this message is UNSTABLE and DANGEROUS.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-rage">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem; text-shadow: none;">RAGE ALERT</h3>
|
||||
<p style="margin: 0;">Pure red fury border with red glow - for critical errors and ABSOLUTE EMERGENCIES ONLY.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider section-divider-riot">
|
||||
|
||||
<!-- CODE BLOCKS -->
|
||||
<section class="mb-3">
|
||||
<h2>PUNK CODE</h2>
|
||||
<div class="card">
|
||||
<h3>INLINE CODE</h3>
|
||||
<p>Inline code is <code>TOXIC GREEN</code> with <code>bold weight</code> and <code>aggressive borders</code> because even code deserves to be LOUD.</p>
|
||||
</div>
|
||||
|
||||
<div class="card mt-2">
|
||||
<h3>CODE BLOCKS</h3>
|
||||
<pre><code>// ANARCHIST ANGELS COLOR SYSTEM
|
||||
const punkRock = {
|
||||
chaos: '#ff0055', // HOT PINK SCREAM
|
||||
riot: '#00ff00', // TOXIC GREEN REBELLION
|
||||
rebel: '#ffff00', // ELECTRIC YELLOW WARNING
|
||||
rage: '#ff0000', // PURE RED FURY
|
||||
void: '#9933ff', // PURPLE CHAOS
|
||||
halo: '#ffffff', // PURE ANGEL WHITE
|
||||
abyss: '#000000' // PURE BLACK VOID
|
||||
};
|
||||
|
||||
// NO SUBTLE HOVERS - ONLY AGGRESSIVE TRANSFORMATIONS
|
||||
element.addEventListener('hover', () => {
|
||||
element.style.transform = 'translateY(-4px) scale(1.05) rotate(1deg)';
|
||||
element.style.boxShadow = '0 0 40px rgba(255, 0, 85, 1)';
|
||||
});</code></pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- TABLES -->
|
||||
<section class="mb-3">
|
||||
<h2>DATA REBELLION</h2>
|
||||
<div class="card">
|
||||
<h3>PUNK ROCK COLOR REFERENCE</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>SYSTEM</th>
|
||||
<th>COLOR CODE</th>
|
||||
<th>ATTITUDE</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>--accent-chaos-1</code></td>
|
||||
<td>#ff0055</td>
|
||||
<td>HOT PINK SCREAM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-riot-1</code></td>
|
||||
<td>#00ff00</td>
|
||||
<td>TOXIC GREEN REBELLION</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-rebel-1</code></td>
|
||||
<td>#ffff00</td>
|
||||
<td>ELECTRIC YELLOW WARNING</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-rage-1</code></td>
|
||||
<td>#ff0000</td>
|
||||
<td>PURE RED FURY</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-void-1</code></td>
|
||||
<td>#9933ff</td>
|
||||
<td>PURPLE CHAOS</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-halo-1</code></td>
|
||||
<td>#ffffff</td>
|
||||
<td>PURE ANGEL WHITE</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider section-divider-riot">
|
||||
|
||||
<!-- IMPLEMENTATION GUIDE -->
|
||||
<section class="mb-3">
|
||||
<h2>THE RULEBOOK (IRONIC)</h2>
|
||||
|
||||
<div class="card-chaos">
|
||||
<h3>DESIGN PRINCIPLES</h3>
|
||||
<ul>
|
||||
<li><strong>ZERO COMPROMISE:</strong> Pure black backgrounds, pure white text, no gray areas</li>
|
||||
<li><strong>MAXIMUM CONTRAST:</strong> Every element screams against the void</li>
|
||||
<li><strong>AGGRESSIVE GLOWS:</strong> 30px shadows on everything that matters</li>
|
||||
<li><strong>SHARP EDGES:</strong> 0-2px border radius - no soft corners allowed</li>
|
||||
<li><strong>THICK BORDERS:</strong> 2-6px borders that can't be ignored</li>
|
||||
<li><strong>CHAOTIC MOTION:</strong> Rotations, scales, and transformations on hover</li>
|
||||
<li><strong>LOUD TYPOGRAPHY:</strong> All caps headers, 700-900 font weights</li>
|
||||
<li><strong>PURE COLORS:</strong> #ff0055, #00ff00, #ffff00, #ff0000 - no mixing</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-2">
|
||||
<div class="card-riot">
|
||||
<h3>WHEN TO USE</h3>
|
||||
<ul>
|
||||
<li><strong>PUNK BRANDS:</strong> Music, art, counter-culture</li>
|
||||
<li><strong>REBEL TECH:</strong> Crypto, blockchain, decentralized</li>
|
||||
<li><strong>CREATIVE CHAOS:</strong> Experimental design studios</li>
|
||||
<li><strong>YOUTH MOVEMENTS:</strong> Gen Z and beyond</li>
|
||||
<li><strong>GAMING:</strong> Cyberpunk, dystopian themes</li>
|
||||
<li><strong>ATTITUDE REQUIRED:</strong> Anywhere rules need breaking</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-rebel">
|
||||
<h3>WHEN NOT TO USE</h3>
|
||||
<ul>
|
||||
<li><strong>CORPORATE:</strong> This ain't for suits</li>
|
||||
<li><strong>MEDICAL:</strong> Too aggressive for healthcare</li>
|
||||
<li><strong>FINANCE:</strong> Banks hate this</li>
|
||||
<li><strong>GOVERNMENT:</strong> Too rebellious</li>
|
||||
<li><strong>CONSERVATIVE:</strong> Literally the opposite</li>
|
||||
<li><strong>BORING:</strong> If you need "professional," go elsewhere</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-rage mt-2">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem; text-shadow: none;">⚠️ WARNING ⚠️</h3>
|
||||
<p style="margin: 0; font-weight: 700; font-size: 1.1rem;">
|
||||
This theme is <span class="punk-emphasis">INTENTIONALLY AGGRESSIVE</span>. It's not for everyone. It's not meant to be. This is design for rebels who refuse to blend in. If you want subtle, elegant, or corporate-friendly - you're in the wrong place. This is <span class="riot-emphasis">ANARCHIST ANGELS</span> - we don't do boring.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- TECHNICAL SPECS -->
|
||||
<section class="mb-3">
|
||||
<h2>TECHNICAL REBELLION</h2>
|
||||
<div class="card-elevated">
|
||||
<h3>GLOW EFFECTS SYSTEM</h3>
|
||||
<pre><code>/* AGGRESSIVE GLOW SYSTEM - 30PX SHADOWS */
|
||||
--glow-pink: 0 0 30px rgba(255, 0, 85, 0.8);
|
||||
--glow-green: 0 0 30px rgba(0, 255, 0, 0.8);
|
||||
--glow-yellow: 0 0 30px rgba(255, 255, 0, 0.8);
|
||||
--glow-white: 0 0 30px rgba(255, 255, 255, 0.6);
|
||||
--glow-red: 0 0 30px rgba(255, 0, 0, 0.8);
|
||||
--glow-purple: 0 0 30px rgba(153, 51, 255, 0.8);
|
||||
|
||||
/* HOVER STATE INTENSITY */
|
||||
.btn-primary:hover {
|
||||
box-shadow: 0 0 40px rgba(255, 0, 85, 1); /* 100% OPACITY */
|
||||
transform: translateY(-4px) scale(1.05);
|
||||
}</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-2">
|
||||
<div class="card">
|
||||
<h3>CONTRAST RATIOS</h3>
|
||||
<ul>
|
||||
<li><strong>WHITE ON BLACK:</strong> 21:1 (Maximum possible)</li>
|
||||
<li><strong>HOT PINK ON BLACK:</strong> 7.2:1 (AAA)</li>
|
||||
<li><strong>TOXIC GREEN ON BLACK:</strong> 15.3:1 (AAA+)</li>
|
||||
<li><strong>YELLOW ON BLACK:</strong> 19.6:1 (AAA+)</li>
|
||||
<li><strong>NO COMPROMISES:</strong> All ratios exceed WCAG AAA</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>BORDER SYSTEM</h3>
|
||||
<ul>
|
||||
<li><strong>DEFAULT:</strong> 2px solid white</li>
|
||||
<li><strong>MEDIUM:</strong> 3px for emphasis</li>
|
||||
<li><strong>THICK:</strong> 4px for cards with accent</li>
|
||||
<li><strong>ULTRA:</strong> 6px for alerts and borders</li>
|
||||
<li><strong>RADIUS:</strong> 0-2px only (sharp aesthetic)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card-solid text-center mt-3" style="padding: 3rem; border: 6px solid #ffffff; box-shadow: 0 0 50px rgba(255, 0, 85, 0.8);">
|
||||
<h1 style="margin-bottom: 1rem;">ANARCHIST ANGELS</h1>
|
||||
<p style="color: var(--text-primary); margin-top: 1rem; font-size: 1.25rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em;">
|
||||
<span style="color: #ff0055;">PUNK ROCK</span> • <span style="color: #00ff00;">ZERO RULES</span> • <span style="color: #ffff00;">MAXIMUM CHAOS</span> • <span style="color: #ffffff;">PURE REBELLION</span>
|
||||
</p>
|
||||
<p style="color: var(--text-secondary); margin-top: 1.5rem; font-size: 1rem;">
|
||||
Not for the faint of heart. Not for corporate cowards. Only for those who dare to be different.
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,566 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Angelic Anarchist Style Reference | Divine Rebellion</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;500;600;700&family=Orbitron:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
ANGELIC ANARCHIST STYLE REFERENCE
|
||||
Divine Rebellion | Sacred Chaos | Heavenly Punk
|
||||
UNIQUE FEATURE: Animated Rotating Halos on Headings
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Heaven to earth - divine descent */
|
||||
--bg-gradient-1: #0a0a0f; /* Void black */
|
||||
--bg-gradient-2: #15151f; /* Dark sanctum */
|
||||
--bg-gradient-3: #1a1a2a; /* Twilight altar */
|
||||
--bg-gradient-4: #1f1f35; /* Sacred shadow */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(255,250,240,0.04);
|
||||
--bg-card: rgba(255,250,240,0.08);
|
||||
--bg-darker: rgba(0,0,0,0.40);
|
||||
--bg-solid-dark: #0a0a0f;
|
||||
--bg-solid-light: #f5f0e8;
|
||||
|
||||
/* --- BORDERS ---
|
||||
Sharp angles, no mercy */
|
||||
--border-color: #d4af37;
|
||||
--border-width: 2px;
|
||||
--border-width-thick: 4px;
|
||||
|
||||
/* --- GLOW SYSTEM ---
|
||||
Divine: Sacred gold, holy white
|
||||
Chaos: Anarchist red, rebellion purple
|
||||
Void: Deep shadow, cosmic black */
|
||||
--divine-1: #ffd700; /* Pure gold */
|
||||
--divine-2: #f0e68c; /* Pale gold */
|
||||
--divine-3: #ffffff; /* Holy white */
|
||||
--chaos-1: #dc143c; /* Crimson rebellion */
|
||||
--chaos-2: #8b008b; /* Dark magenta */
|
||||
--chaos-3: #ff1493; /* Deep pink */
|
||||
--void-1: #4b0082; /* Indigo void */
|
||||
--void-2: #2e0854; /* Deep purple */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS --- */
|
||||
--text-primary: #f5f0e8;
|
||||
--text-white: #ffffff;
|
||||
--text-h1-gradient: linear-gradient(135deg, #ffd700 0%, #ffffff 25%, #dc143c 50%, #8b008b 75%, #ffd700 100%);
|
||||
--text-h2: #ffd700; /* Divine gold */
|
||||
--text-h3: #dc143c; /* Chaos red */
|
||||
--text-h4: #8b008b; /* Rebellion purple */
|
||||
--text-h5: #f0e68c; /* Pale gold */
|
||||
--text-h6: #f5f0e8; /* Primary */
|
||||
|
||||
/* --- BUTTON GRADIENTS --- */
|
||||
--btn-divine-gradient: linear-gradient(45deg, #ffd700 0%, #ffffff 50%, #f0e68c 100%);
|
||||
--btn-chaos-gradient: linear-gradient(45deg, #dc143c 0%, #ff1493 50%, #8b008b 100%);
|
||||
--btn-void-gradient: linear-gradient(45deg, #4b0082 0%, #8b008b 50%, #2e0854 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Cinzel', serif;
|
||||
--font-body: 'Orbitron', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(135deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
|
||||
/* UNIQUE FEATURE: Animated Rotating Halos */
|
||||
@keyframes halo-rotate {
|
||||
0% { transform: rotate(0deg) scale(1); opacity: 0.6; }
|
||||
50% { transform: rotate(180deg) scale(1.1); opacity: 0.8; }
|
||||
100% { transform: rotate(360deg) scale(1); opacity: 0.6; }
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
h1::before,
|
||||
h2::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 120%;
|
||||
height: 120%;
|
||||
border: 3px solid transparent;
|
||||
border-top-color: var(--divine-1);
|
||||
border-right-color: var(--chaos-1);
|
||||
border-bottom-color: var(--void-1);
|
||||
border-left-color: var(--divine-3);
|
||||
animation: halo-rotate 8s linear infinite;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-family: var(--font-header);
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 30px rgba(255, 215, 0, 0.5);
|
||||
padding: 0.75rem 0;
|
||||
}
|
||||
|
||||
h2::before {
|
||||
border-width: 2px;
|
||||
animation-duration: 6s;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--divine-1);
|
||||
font-weight: 600;
|
||||
text-shadow: 0 0 10px rgba(255, 215, 0, 0.4);
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--chaos-1);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.2rem 0.4rem;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 0;
|
||||
font-size: 0.9em;
|
||||
color: var(--divine-2);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: 0;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.875rem 2rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
cursor: pointer;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
font-family: var(--font-body);
|
||||
border-radius: 0;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.btn-divine {
|
||||
background: var(--btn-divine-gradient);
|
||||
color: #000;
|
||||
box-shadow: 0 0 20px rgba(255, 215, 0, 0.5), 0 0 40px rgba(255, 215, 0, 0.3);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-divine:hover {
|
||||
transform: scale(1.04);
|
||||
box-shadow: 0 0 30px rgba(255, 215, 0, 0.7), 0 0 60px rgba(255, 215, 0, 0.4);
|
||||
}
|
||||
|
||||
.btn-chaos {
|
||||
background: var(--btn-chaos-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 0 20px rgba(220, 20, 60, 0.5), 0 0 40px rgba(220, 20, 60, 0.3);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-chaos:hover {
|
||||
transform: scale(1.04);
|
||||
box-shadow: 0 0 30px rgba(220, 20, 60, 0.7), 0 0 60px rgba(220, 20, 60, 0.4);
|
||||
}
|
||||
|
||||
.btn-void {
|
||||
background: var(--btn-void-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 0 20px rgba(75, 0, 130, 0.5), 0 0 40px rgba(75, 0, 130, 0.3);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-void:hover {
|
||||
transform: scale(1.04);
|
||||
box-shadow: 0 0 30px rgba(75, 0, 130, 0.7), 0 0 60px rgba(75, 0, 130, 0.4);
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: 0;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: 0;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-glow-divine {
|
||||
box-shadow: 0 0 30px rgba(255, 215, 0, 0.5), 0 0 60px rgba(255, 215, 0, 0.3);
|
||||
}
|
||||
|
||||
.card-glow-chaos {
|
||||
box-shadow: 0 0 30px rgba(220, 20, 60, 0.5), 0 0 60px rgba(220, 20, 60, 0.3);
|
||||
}
|
||||
|
||||
.card-glow-void {
|
||||
box-shadow: 0 0 30px rgba(75, 0, 130, 0.5), 0 0 60px rgba(75, 0, 130, 0.3);
|
||||
}
|
||||
|
||||
.card-sanctum {
|
||||
background: rgba(255, 250, 240, 0.95);
|
||||
border: var(--border-width-thick) solid var(--divine-1);
|
||||
color: #1a1a2a;
|
||||
padding: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 0 40px rgba(255, 215, 0, 0.4);
|
||||
}
|
||||
|
||||
.card-sanctum h1,
|
||||
.card-sanctum h2,
|
||||
.card-sanctum h3,
|
||||
.card-sanctum h4,
|
||||
.card-sanctum h5,
|
||||
.card-sanctum h6 {
|
||||
color: #8b008b;
|
||||
background: none;
|
||||
-webkit-text-fill-color: #8b008b;
|
||||
}
|
||||
|
||||
.card-sanctum p,
|
||||
.card-sanctum li {
|
||||
color: #1a1a2a;
|
||||
}
|
||||
|
||||
.card-sanctum strong {
|
||||
color: #dc143c;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* ===== BADGES ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: 0;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
border: var(--border-width) solid;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.badge-divine {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--divine-1);
|
||||
border-color: var(--divine-1);
|
||||
box-shadow: 0 0 15px rgba(255, 215, 0, 0.3);
|
||||
}
|
||||
|
||||
.badge-chaos {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--chaos-1);
|
||||
border-color: var(--chaos-1);
|
||||
box-shadow: 0 0 15px rgba(220, 20, 60, 0.3);
|
||||
}
|
||||
|
||||
.badge-void {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--void-1);
|
||||
border-color: var(--void-1);
|
||||
box-shadow: 0 0 15px rgba(75, 0, 130, 0.3);
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: 0;
|
||||
border: var(--border-width) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-divine {
|
||||
background: rgba(255, 215, 0, 0.1);
|
||||
border-color: var(--divine-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(255, 215, 0, 0.2);
|
||||
}
|
||||
|
||||
.alert-chaos {
|
||||
background: rgba(220, 20, 60, 0.1);
|
||||
border-color: var(--chaos-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(220, 20, 60, 0.2);
|
||||
}
|
||||
|
||||
.alert-void {
|
||||
background: rgba(75, 0, 130, 0.1);
|
||||
border-color: var(--void-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(75, 0, 130, 0.2);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width);
|
||||
background: linear-gradient(to right,
|
||||
var(--divine-1),
|
||||
var(--chaos-1),
|
||||
var(--void-1),
|
||||
var(--divine-1));
|
||||
margin: 2.5rem 0;
|
||||
box-shadow: 0 0 20px rgba(255, 215, 0, 0.3);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>Angelic Anarchist</h1>
|
||||
<p style="font-size: 1.25rem; color: var(--divine-2);">Divine Rebellion | Sacred Chaos | Heavenly Punk</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- UNIQUE FEATURE SHOWCASE -->
|
||||
<section class="mb-3">
|
||||
<div class="card-sanctum">
|
||||
<h2>✨ Unique Feature: Animated Halos</h2>
|
||||
<p>This design system features <strong>CSS-only animated rotating halos</strong> on H1 and H2 headings. The halos are created using pseudo-elements with rotating borders in divine gold, chaos crimson, void indigo, and holy white.</p>
|
||||
<p>Watch the halos rotate continuously around major headings—a visual representation of the tension between <em>divine order and anarchist rebellion</em>.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Sacred Spectrum</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card" style="background: var(--divine-1); color: #000;">
|
||||
<h4 style="color: #000;">Divine Gold</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#ffd700</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--divine-3); color: #000;">
|
||||
<h4 style="color: #000;">Holy White</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#ffffff</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--chaos-1); color: white;">
|
||||
<h4 style="color: white;">Crimson Rebellion</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#dc143c</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--chaos-2); color: white;">
|
||||
<h4 style="color: white;">Dark Magenta</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#8b008b</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--void-1); color: white;">
|
||||
<h4 style="color: white;">Indigo Void</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#4b0082</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--divine-2); color: #000;">
|
||||
<h4 style="color: #000;">Pale Gold</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#f0e68c</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Sacred Actions</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card card-glow-divine">
|
||||
<h3>Divine</h3>
|
||||
<button class="btn btn-divine">Ascend</button>
|
||||
</div>
|
||||
<div class="card card-glow-chaos">
|
||||
<h3>Chaos</h3>
|
||||
<button class="btn btn-chaos">Rebel</button>
|
||||
</div>
|
||||
<div class="card card-glow-void">
|
||||
<h3>Void</h3>
|
||||
<button class="btn btn-void">Transcend</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- BADGES -->
|
||||
<section class="mb-3">
|
||||
<h2>Sacred Badges</h2>
|
||||
<div class="card">
|
||||
<span class="badge badge-divine">Holy</span>
|
||||
<span class="badge badge-chaos">Anarchist</span>
|
||||
<span class="badge badge-void">Transcendent</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>Revelations</h2>
|
||||
<div class="alert alert-divine">
|
||||
<strong>Divine Proclamation:</strong> The heavens acknowledge your righteous rebellion.
|
||||
</div>
|
||||
<div class="alert alert-chaos">
|
||||
<strong>Anarchist Warning:</strong> All hierarchies will be dismantled, even celestial ones.
|
||||
</div>
|
||||
<div class="alert alert-void">
|
||||
<strong>Void Whisper:</strong> Between order and chaos lies infinite potential.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PHILOSOPHY -->
|
||||
<section class="mb-3">
|
||||
<h2>Design Philosophy</h2>
|
||||
<div class="card-sanctum">
|
||||
<h3>Sacred Chaos Principles</h3>
|
||||
<ul>
|
||||
<li><strong>Sharp Angles:</strong> No rounded corners—divine judgment and punk edges</li>
|
||||
<li><strong>Animated Halos:</strong> Rotating borders on H1/H2 create sacred movement</li>
|
||||
<li><strong>High Contrast:</strong> Gold against void, white against shadow</li>
|
||||
<li><strong>Dual Nature:</strong> Every element embodies both heaven and rebellion</li>
|
||||
<li><strong>Uppercase Power:</strong> Major headings demand attention and reverence</li>
|
||||
<li><strong>Cinzel + Orbitron:</strong> Classical meets futuristic</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card card-glow-divine text-center" style="padding: 2rem;">
|
||||
<h2>Angelic Anarchist Style Complete</h2>
|
||||
<p style="margin-top: 1rem;">Where divine order meets sacred rebellion ⚡👼</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1591
DumperCan/UI Style References/bubblicorn_style_reference.html
Normal file
1591
DumperCan/UI Style References/bubblicorn_style_reference.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,921 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Bubblicorn Style Reference | E-Girl Aesthetic 🦄✨</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&family=Nunito:wght@400;500;600;700&family=Noto+Emoji:wght@400;500;600&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
BUBBLICORN STYLE REFERENCE
|
||||
E-Girl Aesthetic | Rounded Corners | Pastel Vibes
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
4-stop vertical gradient for page background */
|
||||
--bg-gradient-1: #1a0a1f; /* Deep purple */
|
||||
--bg-gradient-2: #2d1435; /* Dark magenta */
|
||||
--bg-gradient-3: #0f1a2a; /* Dark blue */
|
||||
--bg-gradient-4: #0a1f1f; /* Deep teal */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(255,182,255,0.06); /* Subtle pink lift */
|
||||
--bg-card: rgba(255,182,255,0.18); /* Standard cards */
|
||||
--bg-darker: rgba(102,0,153,0.25); /* Nested in elevated */
|
||||
--bg-solid-dark: #1a0a1f; /* Opaque dark */
|
||||
--bg-solid-header: #2d1435; /* Opaque magenta */
|
||||
|
||||
/* --- BORDERS --- */
|
||||
--border-color: #FF69B4;
|
||||
--border-width: 2px;
|
||||
--border-width-thick: 4px;
|
||||
|
||||
/* --- BORDER RADIUS --- */
|
||||
--radius-sm: 8px;
|
||||
--radius-md: 12px;
|
||||
--radius-lg: 16px;
|
||||
--radius-xl: 20px;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* --- GLOW SYSTEM ---
|
||||
Bubblegum: Primary actions, highlights
|
||||
Sparkle: Success, achievements
|
||||
Neon: Warnings, attention */
|
||||
--glow-bubblegum-1: #FF69B4; /* Hot pink */
|
||||
--glow-bubblegum-2: #FF1493; /* Deep pink */
|
||||
--glow-sparkle-1: #B0FFE8; /* Mint */
|
||||
--glow-sparkle-2: #00FFFF; /* Cyan */
|
||||
--glow-neon-1: #FF10F0; /* Neon pink */
|
||||
--glow-neon-2: #FFE66D; /* Sparkle yellow */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS --- */
|
||||
--text-primary: #FFE6FF;
|
||||
--text-white: #FFFFFF;
|
||||
--text-h1-gradient: linear-gradient(135deg, #FF1493 0%, #E6B3FF 25%, #00FFFF 50%, #E6B3FF 75%, #FF1493 100%);
|
||||
--text-h2: #FF69B4; /* Hot pink */
|
||||
--text-h3: #E6B3FF; /* Lavender */
|
||||
--text-h4: #B0FFE8; /* Mint */
|
||||
--text-h5: #CCCCFF; /* Periwinkle */
|
||||
--text-h6: #FFE6FF; /* Primary */
|
||||
|
||||
/* --- BUTTON GRADIENTS --- */
|
||||
--btn-special-gradient: linear-gradient(135deg, #FF1493 0%, #E6B3FF 50%, #00FFFF 100%);
|
||||
--btn-default-gradient: linear-gradient(180deg, #FF69B4 0%, #E6B3FF 50%, #00FFFF 100%);
|
||||
|
||||
/* --- KAWAII GRADIENT BORDER ---
|
||||
Used for .card-kawaii pseudo-element border */
|
||||
--kawaii-gradient: linear-gradient(135deg, #FF69B4 0%, #E6B3FF 50%, #00FFFF 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Quicksand', sans-serif;
|
||||
--font-body: 'Nunito', 'Noto Emoji', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.7;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--glow-bubblegum-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--glow-sparkle-1);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.2rem 0.4rem;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: var(--border-width-thick) solid var(--border-color);
|
||||
padding-left: 1.5rem;
|
||||
margin: 1.5rem 0;
|
||||
font-style: italic;
|
||||
color: var(--text-h3);
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-bottom: 1.5rem;
|
||||
margin-left: 2rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
color: var(--glow-bubblegum-1);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.875rem 2rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
cursor: pointer;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
font-family: var(--font-body);
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
|
||||
.btn-special {
|
||||
background: var(--btn-special-gradient);
|
||||
color: var(--text-white);
|
||||
box-shadow: 0 4px 14px rgba(255, 20, 147, 0.4), 0 0 20px rgba(255, 105, 180, 0.3);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-special:hover {
|
||||
transform: translateY(-4px) scale(1.05);
|
||||
box-shadow: 0 8px 24px rgba(255, 20, 147, 0.6), 0 0 30px rgba(255, 105, 180, 0.5);
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background: var(--text-primary);
|
||||
color: var(--bg-solid-dark);
|
||||
border-color: var(--glow-bubblegum-1);
|
||||
}
|
||||
|
||||
.btn-default:hover {
|
||||
transform: translateY(-2px) scale(1.03);
|
||||
box-shadow: 0 4px 12px rgba(255, 105, 180, 0.4);
|
||||
}
|
||||
|
||||
.btn-nav {
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
border-color: var(--glow-sparkle-1);
|
||||
}
|
||||
|
||||
.btn-nav:hover {
|
||||
border-color: var(--glow-bubblegum-1);
|
||||
background: rgba(255, 105, 180, 0.1);
|
||||
}
|
||||
|
||||
.btn-sparkle {
|
||||
background: var(--bg-solid-dark);
|
||||
color: var(--text-primary);
|
||||
border-color: var(--glow-sparkle-1);
|
||||
box-shadow: 0 0 20px rgba(176, 255, 232, 0.4);
|
||||
}
|
||||
|
||||
.btn-sparkle:hover {
|
||||
transform: translateY(-2px) scale(1.03);
|
||||
box-shadow: 0 0 30px rgba(176, 255, 232, 0.6);
|
||||
}
|
||||
|
||||
.btn-neon {
|
||||
background: var(--bg-solid-dark);
|
||||
color: var(--text-primary);
|
||||
border-color: var(--glow-neon-1);
|
||||
box-shadow: 0 0 20px rgba(255, 16, 240, 0.4);
|
||||
}
|
||||
|
||||
.btn-neon:hover {
|
||||
transform: translateY(-2px) scale(1.03);
|
||||
box-shadow: 0 0 30px rgba(255, 16, 240, 0.6);
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-solid {
|
||||
background: var(--bg-solid-header);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-glow-bubblegum {
|
||||
box-shadow: 0 0 30px rgba(255, 105, 180, 0.5), 0 0 60px rgba(255, 20, 147, 0.3);
|
||||
}
|
||||
|
||||
.card-glow-sparkle {
|
||||
box-shadow: 0 0 30px rgba(176, 255, 232, 0.5), 0 0 60px rgba(0, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.card-glow-neon {
|
||||
box-shadow: 0 0 30px rgba(255, 16, 240, 0.5), 0 0 60px rgba(255, 230, 109, 0.3);
|
||||
}
|
||||
|
||||
/* FIXED: Gradient border with rounded corners using pseudo-element */
|
||||
.card-kawaii {
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
border-radius: var(--radius-xl);
|
||||
color: #2d1435;
|
||||
padding: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-kawaii::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: var(--radius-xl);
|
||||
padding: var(--border-width-thick);
|
||||
background: var(--kawaii-gradient);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.card-kawaii h1,
|
||||
.card-kawaii h2,
|
||||
.card-kawaii h3,
|
||||
.card-kawaii h4,
|
||||
.card-kawaii h5,
|
||||
.card-kawaii h6 {
|
||||
color: #8B008B;
|
||||
background: none;
|
||||
-webkit-text-fill-color: #8B008B;
|
||||
}
|
||||
|
||||
.card-kawaii p,
|
||||
.card-kawaii li,
|
||||
.card-kawaii td,
|
||||
.card-kawaii dd {
|
||||
color: #2d1435;
|
||||
}
|
||||
|
||||
.card-kawaii strong {
|
||||
color: #FF1493;
|
||||
}
|
||||
|
||||
.card-kawaii em {
|
||||
color: #00CED1;
|
||||
}
|
||||
|
||||
.card-kawaii code {
|
||||
background: rgba(255, 105, 180, 0.15);
|
||||
border-color: #FF69B4;
|
||||
color: #8B008B;
|
||||
}
|
||||
|
||||
/* ===== TABLES ===== */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
margin-bottom: 1.5rem;
|
||||
background: var(--bg-card);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: var(--bg-solid-header);
|
||||
color: var(--text-white);
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.875rem 1rem;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) {
|
||||
background: var(--bg-darker);
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
background: rgba(255, 105, 180, 0.1);
|
||||
}
|
||||
|
||||
/* ===== FORMS ===== */
|
||||
input[type="text"],
|
||||
input[type="email"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
input[type="search"],
|
||||
input[type="tel"],
|
||||
input[type="url"],
|
||||
input[type="date"],
|
||||
textarea,
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 0.875rem 1rem;
|
||||
background: var(--bg-elevated);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.3s, box-shadow 0.3s;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: var(--glow-bubblegum-1);
|
||||
box-shadow: 0 0 15px rgba(255, 105, 180, 0.3);
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 120px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
appearance: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--bg-elevated);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transition: background 0.3s, border-color 0.3s;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
background: var(--glow-bubblegum-1);
|
||||
border-color: var(--glow-bubblegum-1);
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
appearance: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: 50%;
|
||||
background: var(--bg-elevated);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked {
|
||||
border-color: var(--glow-sparkle-1);
|
||||
}
|
||||
|
||||
input[type="radio"]:checked::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: var(--glow-sparkle-1);
|
||||
border-radius: 50%;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
/* ===== BADGES & PILLS ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: var(--radius-full);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
}
|
||||
|
||||
.badge-bubblegum {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--glow-bubblegum-1);
|
||||
border-color: var(--glow-bubblegum-1);
|
||||
}
|
||||
|
||||
.badge-sparkle {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--glow-sparkle-1);
|
||||
border-color: var(--glow-sparkle-1);
|
||||
}
|
||||
|
||||
.badge-neon {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--glow-neon-1);
|
||||
border-color: var(--glow-neon-1);
|
||||
}
|
||||
|
||||
.badge-solid {
|
||||
background: var(--bg-solid-header);
|
||||
color: var(--text-white);
|
||||
}
|
||||
|
||||
/* ===== TABS ===== */
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: var(--border-width) solid var(--border-color);
|
||||
}
|
||||
|
||||
.tab-button {
|
||||
padding: 0.875rem 1.5rem;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-bottom: var(--border-width-thick) solid transparent;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
font-family: var(--font-body);
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
transition: color 0.3s, border-color 0.3s;
|
||||
border-radius: var(--radius-md) var(--radius-md) 0 0;
|
||||
}
|
||||
|
||||
.tab-button:hover {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.tab-button.active {
|
||||
color: var(--glow-bubblegum-1);
|
||||
border-bottom-color: var(--glow-bubblegum-1);
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: var(--radius-md);
|
||||
border: var(--border-width) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-sparkle {
|
||||
background: rgba(176, 255, 232, 0.1);
|
||||
border-color: var(--glow-sparkle-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-bubblegum {
|
||||
background: rgba(255, 105, 180, 0.1);
|
||||
border-color: var(--glow-bubblegum-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-neon {
|
||||
background: rgba(255, 16, 240, 0.1);
|
||||
border-color: var(--glow-neon-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: rgba(139, 149, 168, 0.1);
|
||||
border-color: var(--text-muted);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ===== PROGRESS BARS ===== */
|
||||
progress {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
appearance: none;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
background: var(--bg-elevated);
|
||||
}
|
||||
|
||||
progress::-webkit-progress-bar {
|
||||
background: var(--bg-elevated);
|
||||
}
|
||||
|
||||
progress::-webkit-progress-value {
|
||||
background: var(--btn-special-gradient);
|
||||
}
|
||||
|
||||
progress::-moz-progress-bar {
|
||||
background: var(--btn-special-gradient);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.text-left { text-align: left; }
|
||||
.text-right { text-align: right; }
|
||||
|
||||
.mt-1 { margin-top: 0.5rem; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mt-3 { margin-top: 1.5rem; }
|
||||
.mb-1 { margin-bottom: 0.5rem; }
|
||||
.mb-2 { margin-bottom: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
.p-1 { padding: 0.5rem; }
|
||||
.p-2 { padding: 1rem; }
|
||||
.p-3 { padding: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width);
|
||||
background: var(--border-color);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.section-divider {
|
||||
margin: 3rem 0;
|
||||
background: linear-gradient(to right, transparent, var(--border-color), transparent);
|
||||
}
|
||||
|
||||
/* ===== TIMELINE ===== */
|
||||
.timeline {
|
||||
position: relative;
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.timeline::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: var(--border-width);
|
||||
background: var(--border-color);
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
position: relative;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.timeline-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -2.375rem;
|
||||
top: 0.25rem;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: var(--glow-bubblegum-1);
|
||||
border: var(--border-width) solid var(--bg-solid-dark);
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
/* ===== CHART BARS ===== */
|
||||
.chart-bar {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.chart-label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.chart-bar-fill {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background: var(--bg-elevated);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chart-bar-value {
|
||||
height: 100%;
|
||||
background: var(--btn-special-gradient);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-right: 1rem;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
transition: width 1s ease;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>Bubblicorn Style Reference 🦄</h1>
|
||||
<p style="font-size: 1.25rem; color: var(--text-h3);">E-Girl Aesthetic | Rounded Corners | Pastel Vibes ✨</p>
|
||||
</header>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- KAWAII CARD SHOWCASE -->
|
||||
<section class="mb-3">
|
||||
<h2>Fixed: Kawaii Gradient Border 💖</h2>
|
||||
<div class="card-kawaii">
|
||||
<h3>Gradient Border with Rounded Corners ✨</h3>
|
||||
<p>This card now has <strong>properly rendered gradient borders</strong> with rounded corners! The previous version used <code>border-image</code> which doesn't work with <code>border-radius</code>.</p>
|
||||
<p><strong>Solution:</strong> Using a pseudo-element (<code>::before</code>) with gradient background and mask-composite to create the border effect while preserving rounded corners.</p>
|
||||
<p><em>The gradient flows smoothly around all corners!</em> 🌈</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- IMPLEMENTATION GUIDE -->
|
||||
<section class="mb-3">
|
||||
<h2>Implementation Guide 📚</h2>
|
||||
|
||||
<div class="card">
|
||||
<h3>Fixed Gradient Border Technique ✨</h3>
|
||||
<p><strong>Problem:</strong> <code>border-image</code> and <code>border-radius</code> don't work together</p>
|
||||
<p><strong>Solution:</strong> Pseudo-element with gradient + mask-composite</p>
|
||||
<pre><code>/* Gradient border with rounded corners */
|
||||
.card-kawaii {
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
border-radius: var(--radius-xl);
|
||||
color: #2d1435;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.card-kawaii::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: var(--radius-xl);
|
||||
padding: var(--border-width-thick);
|
||||
background: var(--kawaii-gradient);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box,
|
||||
linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
}</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-2">
|
||||
<div class="card">
|
||||
<h3>Key Improvements ⭐</h3>
|
||||
<ul>
|
||||
<li><strong>Rounded corners work!</strong> All corners are properly rounded</li>
|
||||
<li><strong>Smooth gradient:</strong> No jagged edges or breaks</li>
|
||||
<li><strong>Performance:</strong> Uses modern CSS mask technique</li>
|
||||
<li><strong>Extensible:</strong> Change gradient via CSS variable</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Browser Support 🌐</h3>
|
||||
<p><strong>Excellent:</strong> Chrome, Edge, Safari, Firefox</p>
|
||||
<p><strong>Fallback:</strong> Older browsers show solid border</p>
|
||||
<p><strong>Note:</strong> Uses <code>-webkit-mask</code> for compatibility</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-2">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem;">Technical Notes 💡</h3>
|
||||
<ul style="margin-left: 1.5rem; margin-top: 0.5rem;">
|
||||
<li><strong>Pseudo-element:</strong> Uses <code>::before</code> to create gradient border layer</li>
|
||||
<li><strong>Mask-composite:</strong> <code>exclude</code> cuts out the center, leaving only the border</li>
|
||||
<li><strong>Pointer-events:</strong> Set to <code>none</code> so clicks pass through to content</li>
|
||||
<li><strong>Inset:</strong> Shorthand for <code>top: 0; right: 0; bottom: 0; left: 0</code></li>
|
||||
<li><strong>Padding on mask:</strong> Creates the border width effect</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Color Palette 🎨</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card" style="background: #FF69B4; color: white;">
|
||||
<h4 style="color: white;">Bubblegum Pink</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: white; border-color: white;">#FF69B4</code>
|
||||
</div>
|
||||
<div class="card" style="background: #E6B3FF; color: #2d1435;">
|
||||
<h4 style="color: #2d1435;">Lavender</h4>
|
||||
<code style="background: rgba(0,0,0,0.1); color: #2d1435; border-color: #2d1435;">#E6B3FF</code>
|
||||
</div>
|
||||
<div class="card" style="background: #B0FFE8; color: #2d1435;">
|
||||
<h4 style="color: #2d1435;">Mint</h4>
|
||||
<code style="background: rgba(0,0,0,0.1); color: #2d1435; border-color: #2d1435;">#B0FFE8</code>
|
||||
</div>
|
||||
<div class="card" style="background: #00FFFF; color: #2d1435;">
|
||||
<h4 style="color: #2d1435;">Cyan</h4>
|
||||
<code style="background: rgba(0,0,0,0.1); color: #2d1435; border-color: #2d1435;">#00FFFF</code>
|
||||
</div>
|
||||
<div class="card" style="background: #FF10F0; color: white;">
|
||||
<h4 style="color: white;">Neon Pink</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: white; border-color: white;">#FF10F0</code>
|
||||
</div>
|
||||
<div class="card" style="background: #FFE66D; color: #2d1435;">
|
||||
<h4 style="color: #2d1435;">Sparkle Yellow</h4>
|
||||
<code style="background: rgba(0,0,0,0.1); color: #2d1435; border-color: #2d1435;">#FFE66D</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Button Styles 🎀</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card">
|
||||
<h3>Primary Buttons</h3>
|
||||
<button class="btn btn-special">Special Button ✨</button>
|
||||
<button class="btn btn-default mt-2">Default Button 💕</button>
|
||||
<button class="btn btn-nav mt-2">Navigation Button 🦄</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Accent Buttons</h3>
|
||||
<button class="btn btn-sparkle">Sparkle Button ⭐</button>
|
||||
<button class="btn btn-neon mt-2">Neon Button ⚡</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card-solid text-center mt-3" style="padding: 2rem;">
|
||||
<h2 style="color: var(--text-white);">Bubblicorn Style Complete! 🦄✨</h2>
|
||||
<p style="color: var(--text-white); margin-top: 1rem;">Gradient borders fixed | All rounded corners working | Maximum cuteness achieved 💖</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
798
DumperCan/UI Style References/course_marketing_page.html
Normal file
798
DumperCan/UI Style References/course_marketing_page.html
Normal file
@@ -0,0 +1,798 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Digital Safety for Parents | 12-Week Course</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;500;600;700&family=Noto+Emoji:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--bg-primary: #0a0e1a;
|
||||
--bg-secondary: #111827;
|
||||
--glass-bg: rgba(17, 24, 39, 0.7);
|
||||
--glass-border: rgba(255, 255, 255, 0.1);
|
||||
--accent-green: #10b981;
|
||||
--accent-blue: #3b82f6;
|
||||
--accent-green-soft: rgba(16, 185, 129, 0.15);
|
||||
--accent-blue-soft: rgba(59, 130, 246, 0.15);
|
||||
--text-primary: #f9fafb;
|
||||
--text-secondary: #d1d5db;
|
||||
--text-muted: #9ca3af;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Noto Sans', 'Noto Emoji', sans-serif;
|
||||
background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Header Section */
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 3rem;
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: clamp(1.75rem, 5vw, 2.5rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: linear-gradient(135deg, var(--accent-green) 0%, var(--accent-blue) 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.header .subtitle {
|
||||
font-size: clamp(1rem, 3vw, 1.25rem);
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.header .tagline {
|
||||
font-size: clamp(0.875rem, 2.5vw, 1rem);
|
||||
color: var(--text-muted);
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Glass Card */
|
||||
.glass-card {
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--glass-border);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Stats Section */
|
||||
.stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--glass-border);
|
||||
padding: 1.25rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-card .value {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(135deg, var(--accent-green) 0%, var(--accent-blue) 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.stat-card .label {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* CTA Section */
|
||||
.cta-section {
|
||||
background: linear-gradient(135deg, var(--accent-green-soft) 0%, var(--accent-blue-soft) 100%);
|
||||
border: 1px solid var(--glass-border);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.cta-section h2 {
|
||||
font-size: clamp(1.25rem, 4vw, 1.75rem);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.cta-section p {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: clamp(0.875rem, 2.5vw, 1rem);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, var(--accent-green) 0%, var(--accent-blue) 100%);
|
||||
color: white;
|
||||
padding: 0.875rem 2rem;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
box-shadow: 0 4px 14px 0 rgba(16, 185, 129, 0.3);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px 0 rgba(16, 185, 129, 0.4);
|
||||
}
|
||||
|
||||
/* Section Headers */
|
||||
.section-header {
|
||||
font-size: clamp(1.25rem, 3.5vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
margin-bottom: 1.5rem;
|
||||
padding-left: 1rem;
|
||||
border-left: 4px solid var(--accent-green);
|
||||
}
|
||||
|
||||
/* Accordion */
|
||||
.accordion-item {
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--glass-border);
|
||||
margin-bottom: 0.75rem;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.accordion-item:hover {
|
||||
border-color: rgba(16, 185, 129, 0.3);
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
padding: 1.25rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.accordion-header:hover {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.accordion-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.session-number {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
color: var(--accent-green);
|
||||
background: var(--accent-green-soft);
|
||||
padding: 0.25rem 0.625rem;
|
||||
border-radius: 6px;
|
||||
min-width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.session-title {
|
||||
font-weight: 600;
|
||||
font-size: clamp(0.875rem, 2.5vw, 1rem);
|
||||
color: var(--text-primary);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.accordion-icon {
|
||||
font-size: 1.25rem;
|
||||
transition: transform 0.3s ease;
|
||||
color: var(--accent-blue);
|
||||
}
|
||||
|
||||
.accordion-item.active .accordion-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.accordion-content {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.4s ease, padding 0.4s ease;
|
||||
}
|
||||
|
||||
.accordion-item.active .accordion-content {
|
||||
max-height: 2000px;
|
||||
padding: 0 1.25rem 1.25rem 1.25rem;
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
color: var(--text-secondary);
|
||||
font-size: clamp(0.875rem, 2.5vw, 0.9375rem);
|
||||
}
|
||||
|
||||
.accordion-body h4 {
|
||||
color: var(--text-primary);
|
||||
font-size: 1rem;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.accordion-body ul {
|
||||
margin-left: 1.5rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.accordion-body li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.duration {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
/* Key Topics Pills */
|
||||
.topics {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.topic-pill {
|
||||
background: var(--accent-blue-soft);
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
color: var(--accent-blue);
|
||||
padding: 0.375rem 0.75rem;
|
||||
border-radius: 20px;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
text-align: center;
|
||||
margin-top: 3rem;
|
||||
padding: 2rem 1rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.footer .framework {
|
||||
margin-top: 1rem;
|
||||
padding: 1rem;
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--glass-border);
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 640px) {
|
||||
body {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 2rem;
|
||||
padding: 1rem 0.5rem;
|
||||
}
|
||||
|
||||
.glass-card {
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.accordion-item.active .accordion-content {
|
||||
padding: 0 1rem 1rem 1rem;
|
||||
}
|
||||
|
||||
.session-number {
|
||||
font-size: 0.75rem;
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.session-title {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>🛡️ Digital Safety for Parents</h1>
|
||||
<p class="subtitle">Protecting Preteens & Teens in a Converged World</p>
|
||||
<p class="tagline">A 12-session course on the intersection of smartphones, social media, and AI—where threats multiply and traditional safety advice fails.</p>
|
||||
</header>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="stats">
|
||||
<div class="stat-card">
|
||||
<div class="value">12</div>
|
||||
<div class="label">Sessions</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="value">25min</div>
|
||||
<div class="label">Per Session</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="value">3SC</div>
|
||||
<div class="label">Framework</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="value">Practical</div>
|
||||
<div class="label">Action Items</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<div class="cta-section">
|
||||
<h2>Why This Course Matters Now</h2>
|
||||
<p>$16.6 billion in losses in 2024. 442% surge in voice phishing attacks. 79% of attacks now operate malware-free through AI-powered social engineering. Your teen faces threats you didn't grow up with—and traditional advice doesn't work anymore.</p>
|
||||
<a href="#contact" class="btn-primary">Enroll Your Community</a>
|
||||
</div>
|
||||
|
||||
<!-- What You'll Learn -->
|
||||
<div class="glass-card">
|
||||
<h2 class="section-header">What You'll Master</h2>
|
||||
<ul style="list-style: none; color: var(--text-secondary);">
|
||||
<li style="margin-bottom: 0.75rem;">✅ Configure critical security settings across iOS and Android</li>
|
||||
<li style="margin-bottom: 0.75rem;">✅ Recognize AI-powered scams targeting your family (deepfakes, voice cloning)</li>
|
||||
<li style="margin-bottom: 0.75rem;">✅ Navigate platform governance documents and identify high-risk features</li>
|
||||
<li style="margin-bottom: 0.75rem;">✅ Build communication patterns that encourage disclosure, not secrecy</li>
|
||||
<li style="margin-bottom: 0.75rem;">✅ Establish sustainable family digital agreements that evolve with maturity</li>
|
||||
<li style="margin-bottom: 0.75rem;">✅ Understand AI systems your teen uses daily—capabilities and limitations</li>
|
||||
<li style="margin-bottom: 0.75rem;">✅ Respond effectively to cyberbullying, predatory contact, and crisis situations</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Course Structure -->
|
||||
<h2 class="section-header" style="margin-top: 2rem;">Course Structure</h2>
|
||||
|
||||
<!-- Introduction -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 1</span>
|
||||
<span class="session-title">The Convergence Crisis</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Understand why smartphone + social internet + AI creates multiplicative (not additive) threats. Recognize the current landscape facing teens in 2024-2025.</p>
|
||||
<h4>Key Topics:</h4>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">$16.6B in 2024 losses</span>
|
||||
<span class="topic-pill">Malware-free attacks</span>
|
||||
<span class="topic-pill">Three-domain framework</span>
|
||||
<span class="topic-pill">Teen vulnerability</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Smartphones Section -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 2</span>
|
||||
<span class="session-title">📱 The Invisible Data Collectors</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Your teen's phone contains 11+ sensors collecting data you don't see. Accelerometers infer passwords. Motion sensors map daily routines. AI turns "innocuous" sensors into surveillance tools.</p>
|
||||
<h4>What You'll Do:</h4>
|
||||
<ul>
|
||||
<li>Audit location permissions across iOS/Android</li>
|
||||
<li>Disable cross-app tracking</li>
|
||||
<li>Configure Screen Time and Family Link</li>
|
||||
<li>Review which apps access cameras, microphones, sensors</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">11+ sensor types</span>
|
||||
<span class="topic-pill">AI inference threats</span>
|
||||
<span class="topic-pill">Platform settings</span>
|
||||
<span class="topic-pill">Privacy audit</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Complete security checklist</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 3</span>
|
||||
<span class="session-title">🔐 Account Security & Attack Vectors</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>24% increase in account takeovers. 26 billion credential stuffing attempts monthly. The average person has 146 exposed credentials on dark web marketplaces. AI bots test them all simultaneously.</p>
|
||||
<h4>What You'll Learn:</h4>
|
||||
<ul>
|
||||
<li>Why SMS-based 2FA fails (SIM swapping, MFA fatigue attacks)</li>
|
||||
<li>Better authentication: authenticator apps, security keys, passkeys</li>
|
||||
<li>Compromise indicators and immediate response protocols</li>
|
||||
<li>Which accounts need MFA immediately (email = master key)</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">Account takeover crisis</span>
|
||||
<span class="topic-pill">Multi-factor auth</span>
|
||||
<span class="topic-pill">Compromise response</span>
|
||||
<span class="topic-pill">Dark web credentials</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Set up authenticator app</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 4</span>
|
||||
<span class="session-title">⚖️ Family Agreements & Sustainable Monitoring</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Heavy restrictions correlate with increased risky behavior. The goal: communication over control, negotiation over restriction. Build agreements that preserve trust while providing appropriate oversight.</p>
|
||||
<h4>Framework Components:</h4>
|
||||
<ul>
|
||||
<li>Device-free zones and times (negotiated, not dictated)</li>
|
||||
<li>App approval processes that explain risks</li>
|
||||
<li>Problem reporting without fear of device confiscation</li>
|
||||
<li>Age-appropriate gradients (10-12 vs. 13-15 vs. 16-17)</li>
|
||||
<li>Monitoring tools: benefits, costs, and trust trade-offs</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">Trust building</span>
|
||||
<span class="topic-pill">Family agreements</span>
|
||||
<span class="topic-pill">Age-appropriate rules</span>
|
||||
<span class="topic-pill">Monitoring options</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Draft family agreement</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Social Internet Section -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 5</span>
|
||||
<span class="session-title">📄 Platform Governance & Terms of Service</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Your teen clicked "I Agree" to 50+ legal documents they never read. Meta's 2025 update: all private messages are now AI training data. No opt-out. Retroactive application to existing content.</p>
|
||||
<h4>Deceptive Patterns:</h4>
|
||||
<ul>
|
||||
<li>"Including but not limited to" = unlimited permission grants</li>
|
||||
<li>"We may share with third parties" = your data is sold</li>
|
||||
<li>"You waive the right to" = you can't sue us</li>
|
||||
<li>Platform-specific high-risk features (Snap Map, Discord servers, TikTok algorithm)</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">ToS deception</span>
|
||||
<span class="topic-pill">Privacy policies</span>
|
||||
<span class="topic-pill">Platform risks</span>
|
||||
<span class="topic-pill">AI training rights</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: ToS scavenger hunt</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 6</span>
|
||||
<span class="session-title">🎮 Current Threat Landscape</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Gaming platforms are now the primary attack vector. Roblox receives 10,000+ monthly sextortion reports. Discord serves as migration platform for predators. Voice chat bypasses safety filters.</p>
|
||||
<h4>Critical Threats:</h4>
|
||||
<ul>
|
||||
<li><strong>AI-Enhanced Attacks:</strong> "Nudify" apps, deepfake harassment (Lancaster County: 20 students targeted)</li>
|
||||
<li><strong>Voice Cloning Scams:</strong> Family impersonation with 85% accuracy from 20 seconds of audio</li>
|
||||
<li><strong>Sextortion Patterns:</strong> Why teens don't report (37% never tell anyone)</li>
|
||||
<li><strong>Cyberbullying 2.0:</strong> AI amplification, synthetic content, platform hopping</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">Gaming dangers</span>
|
||||
<span class="topic-pill">Deepfakes</span>
|
||||
<span class="topic-pill">Voice cloning</span>
|
||||
<span class="topic-pill">Sextortion</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Review teen's gaming contacts</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 7</span>
|
||||
<span class="session-title">🧠 Algorithm Awareness & Information Quality</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>TikTok can create user dependency within 260 videos (35 minutes). Algorithms can push harmful content within 2.6-8 minutes. AI-generated misinformation receives 8% more engagement than human content.</p>
|
||||
<h4>The STOP Method (Teach This to Teens):</h4>
|
||||
<ul>
|
||||
<li><strong>S</strong>ource: Who created this? Why? What's their motivation?</li>
|
||||
<li><strong>T</strong>iming: When was this created? Current or recycled?</li>
|
||||
<li><strong>O</strong>ther sources: What do credible sources say?</li>
|
||||
<li><strong>P</strong>urpose: What is this trying to make me think or do?</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">Filter bubbles</span>
|
||||
<span class="topic-pill">Radicalization</span>
|
||||
<span class="topic-pill">AI misinformation</span>
|
||||
<span class="topic-pill">STOP verification</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Practice STOP method</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 8</span>
|
||||
<span class="session-title">💬 Family Communication & Crisis Response</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Why teens don't tell parents: fear of losing device, shame, belief you won't understand. Build disclosure-friendly communication that encourages help-seeking instead of secrecy.</p>
|
||||
<h4>The Five Cs Framework:</h4>
|
||||
<ul>
|
||||
<li><strong>Child-Centered:</strong> Adapt to individual temperament, acknowledge emotions</li>
|
||||
<li><strong>Content:</strong> Discuss quality and appropriateness without immediate prohibition</li>
|
||||
<li><strong>Context:</strong> When, where, and how digital interactions occur matters</li>
|
||||
<li><strong>Connection:</strong> Emphasize healthy relationships over platform features</li>
|
||||
<li><strong>Calm:</strong> Your emotional regulation enables their disclosure</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">Five Cs</span>
|
||||
<span class="topic-pill">Crisis protocols</span>
|
||||
<span class="topic-pill">Disclosure patterns</span>
|
||||
<span class="topic-pill">Professional help</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Identify crisis resources</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- AI Systems Section -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 9</span>
|
||||
<span class="session-title">🤖 Understanding "Pattern Creatures"</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>AI systems are pattern-matching creatures, not thinking beings. Trained on billions of examples, they predict likely outputs—but hallucinate false information 16-48% of the time.</p>
|
||||
<h4>Four Types Teens Encounter:</h4>
|
||||
<ul>
|
||||
<li><strong>Conversational AI:</strong> ChatGPT, Snapchat My AI (54% use for homework)</li>
|
||||
<li><strong>Recommendation AI:</strong> TikTok, YouTube algorithms (optimize engagement, not wellbeing)</li>
|
||||
<li><strong>Voice AI:</strong> Siri, Alexa (struggle with teen speech, lack safety filtering)</li>
|
||||
<li><strong>Generative AI:</strong> Image/video creators ("nudify" apps, deepfake tools)</li>
|
||||
</ul>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">AI limitations</span>
|
||||
<span class="topic-pill">Hallucinations</span>
|
||||
<span class="topic-pill">Pattern matching</span>
|
||||
<span class="topic-pill">Four types</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Audit AI use</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 10</span>
|
||||
<span class="session-title">🔍 AI Detection & Critical Evaluation</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Humans detect high-quality deepfakes only 24.5% of the time—worse than random chance. Detection is hard. Verification is essential.</p>
|
||||
<h4>The Paradigm Shift:</h4>
|
||||
<ul>
|
||||
<li>OLD: "Can I tell if this is AI?"</li>
|
||||
<li>NEW: "How can I verify this is authentic?"</li>
|
||||
<li>Visual artifacts: anatomical impossibilities, lighting issues, over-perfection</li>
|
||||
<li>Text patterns: overly formal, no personal details, perfect grammar</li>
|
||||
<li>Audio/video: unnatural prosody, sync issues, blurring</li>
|
||||
</ul>
|
||||
<p><strong>Focus: STOP verification method > artifact detection</strong></p>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">Detection limits</span>
|
||||
<span class="topic-pill">Verification focus</span>
|
||||
<span class="topic-pill">Visual artifacts</span>
|
||||
<span class="topic-pill">STOP method</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Practice detection</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 11</span>
|
||||
<span class="session-title">✅ Safe & Productive AI Use</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>54% of children use AI for homework. Teachers use detection tools. Colleges treat AI plagiarism seriously. Establish clear family policies before problems arise.</p>
|
||||
<h4>Family AI Use Agreement:</h4>
|
||||
<ul>
|
||||
<li><strong>Disclosure:</strong> "I used AI to help with [specific task]"</li>
|
||||
<li><strong>Authorship:</strong> Final product must reflect student learning</li>
|
||||
<li><strong>Verification:</strong> All AI information verified through reliable sources</li>
|
||||
<li><strong>Age-Appropriate:</strong> 10-12 requires supervision, 13-15 guided use, 16-17 comprehensive attribution</li>
|
||||
</ul>
|
||||
<h4>Legitimate Uses:</h4>
|
||||
<p>Brainstorming, outlining, research starting points, editing assistance, learning support—with verification and disclosure.</p>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">Academic integrity</span>
|
||||
<span class="topic-pill">AI policies</span>
|
||||
<span class="topic-pill">Productive use</span>
|
||||
<span class="topic-pill">Emerging platforms</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Action: Draft AI use policy</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Wrap-Up -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header" onclick="toggleAccordion(this)">
|
||||
<div class="accordion-title">
|
||||
<span class="session-number">Session 12</span>
|
||||
<span class="session-title">🎯 Sustainable Practices & Long-Term Strategy</span>
|
||||
</div>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>Review the 3SC framework. Create sustainable weekly routines. Develop adaptability for emerging technologies. Establish ongoing education and support networks.</p>
|
||||
<h4>Your Commitments:</h4>
|
||||
<ul>
|
||||
<li><strong>This Week:</strong> Implement one security change per device, have one disclosure-friendly conversation</li>
|
||||
<li><strong>This Month:</strong> Weekly family tech check-ins, complete security audit, practice STOP method</li>
|
||||
<li><strong>Long-Term:</strong> Communication over control, evolving rules, staying informed, seeking help when needed</li>
|
||||
</ul>
|
||||
<h4>The Goal:</h4>
|
||||
<p>Graduating a capable digital citizen who doesn't need you hovering. You cannot create perfect safety. You can build a relationship where they come to you with problems.</p>
|
||||
<div class="topics">
|
||||
<span class="topic-pill">3SC review</span>
|
||||
<span class="topic-pill">Sustainable routines</span>
|
||||
<span class="topic-pill">Community support</span>
|
||||
<span class="topic-pill">Ongoing learning</span>
|
||||
</div>
|
||||
<p class="duration">Duration: 25 minutes | Outcome: Confident, adaptive parenting</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom CTA -->
|
||||
<div class="cta-section" style="margin-top: 3rem;">
|
||||
<h2>Ready to Protect Your Teen?</h2>
|
||||
<p>This course provides foundations, not comprehensive expertise. Technology evolves constantly—commit to ongoing learning, community support, and adaptive parenting that prioritizes relationship over rules.</p>
|
||||
<a href="#contact" class="btn-primary">Bring This Course to Your Community</a>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="framework">
|
||||
<strong>Built on the 3SC Framework</strong><br>
|
||||
<span style="color: var(--accent-green);">SAFE</span> (Caution) •
|
||||
<span style="color: var(--accent-blue);">SANE</span> (Courage) •
|
||||
<span style="color: var(--text-primary);">SAGE</span> (Competence)
|
||||
</div>
|
||||
<p style="margin-top: 1rem;">Digital Safety Foundations | 12-Session Parent Education Course</p>
|
||||
<p style="font-size: 0.75rem; margin-top: 0.5rem;">Course materials designed for non-technical community facilitators delivering evidence-based digital literacy education</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleAccordion(header) {
|
||||
const item = header.parentElement;
|
||||
const wasActive = item.classList.contains('active');
|
||||
|
||||
// Close all accordion items
|
||||
document.querySelectorAll('.accordion-item').forEach(i => {
|
||||
i.classList.remove('active');
|
||||
});
|
||||
|
||||
// Open clicked item if it wasn't active
|
||||
if (!wasActive) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
}
|
||||
|
||||
// Optional: Open first accordion item by default on desktop
|
||||
if (window.innerWidth > 768) {
|
||||
document.querySelector('.accordion-item .accordion-header')?.click();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,843 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Crepuscular City Lights Style Reference</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
CREPUSCULAR CITY LIGHTS STYLE REFERENCE
|
||||
Dark & Elegant | Urban Nightscape | Neon Accents
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Deep night cityscape gradient */
|
||||
--bg-gradient-1: #0a0e1a; /* Deep midnight black */
|
||||
--bg-gradient-2: #0f1419; /* Dark steel blue */
|
||||
--bg-gradient-3: #141922; /* Charcoal blue */
|
||||
--bg-gradient-4: #0d1117; /* Near black */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(30,40,60,0.35); /* Subtle lift */
|
||||
--bg-card: rgba(20,30,50,0.45); /* Standard cards */
|
||||
--bg-darker: rgba(5,10,20,0.6); /* Nested elements */
|
||||
--bg-solid-dark: #0a0e1a; /* Opaque dark */
|
||||
--bg-solid-header: #141922; /* Opaque header */
|
||||
|
||||
/* --- BORDERS ---
|
||||
Bright borders for definition */
|
||||
--border-color: #3d4f66;
|
||||
--border-bright: #5a7a9e;
|
||||
--border-width: 1px;
|
||||
--border-width-medium: 2px;
|
||||
--border-width-thick: 3px;
|
||||
|
||||
/* --- BORDER RADIUS ---
|
||||
Sharp but rounded: 2-6px range */
|
||||
--radius-xs: 2px;
|
||||
--radius-sm: 3px;
|
||||
--radius-md: 4px;
|
||||
--radius-lg: 6px;
|
||||
|
||||
/* --- ACCENT SYSTEM ---
|
||||
Neon: Vibrant electric accents
|
||||
Cyber: Cool neon blues and cyans
|
||||
Glow: Warm neon yellows and golds
|
||||
Alert: Attention neon pinks */
|
||||
--accent-neon-1: #00d9ff; /* Electric cyan */
|
||||
--accent-neon-2: #0099ff; /* Bright blue */
|
||||
--accent-cyber-1: #b968ff; /* Neon purple */
|
||||
--accent-cyber-2: #7b5bff; /* Deep electric purple */
|
||||
--accent-glow-1: #ffd700; /* Neon gold */
|
||||
--accent-glow-2: #ffab00; /* Bright amber */
|
||||
--accent-alert-1: #ff6ec7; /* Neon pink */
|
||||
--accent-alert-2: #ff3d9a; /* Hot pink */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS ---
|
||||
High contrast for elegant readability */
|
||||
--text-primary: #f0f6fc; /* Bright white-blue */
|
||||
--text-secondary: #c9d1d9; /* Light gray */
|
||||
--text-muted: #8b949e; /* Muted gray */
|
||||
--text-white: #ffffff;
|
||||
--text-h1-gradient: linear-gradient(135deg, #00d9ff 0%, #b968ff 50%, #ffd700 100%);
|
||||
--text-h2: #00d9ff; /* Electric cyan */
|
||||
--text-h3: #b968ff; /* Neon purple */
|
||||
--text-h4: #ffd700; /* Neon gold */
|
||||
--text-h5: #f0f6fc; /* Primary bright */
|
||||
--text-h6: #c9d1d9; /* Secondary */
|
||||
|
||||
/* --- BUTTON GRADIENTS ---
|
||||
Vibrant neon gradients */
|
||||
--btn-primary-gradient: linear-gradient(135deg, #00d9ff 0%, #0099ff 100%);
|
||||
--btn-secondary-gradient: linear-gradient(135deg, #ffd700 0%, #ffab00 100%);
|
||||
|
||||
/* --- GLOW EFFECTS ---
|
||||
Subtle neon glows */
|
||||
--glow-cyan: 0 0 20px rgba(0, 217, 255, 0.3);
|
||||
--glow-purple: 0 0 20px rgba(185, 104, 255, 0.3);
|
||||
--glow-gold: 0 0 20px rgba(255, 215, 0, 0.3);
|
||||
--glow-pink: 0 0 20px rgba(255, 110, 199, 0.3);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Inter', sans-serif;
|
||||
--font-body: 'IBM Plex Sans', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.02em;
|
||||
filter: drop-shadow(0 0 10px rgba(0, 217, 255, 0.5));
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.01em;
|
||||
text-shadow: var(--glow-cyan);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: var(--glow-purple);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: var(--glow-gold);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--accent-neon-1);
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--accent-neon-2);
|
||||
text-shadow: var(--glow-cyan);
|
||||
}
|
||||
|
||||
/* ===== 6. CARDS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
border-color: var(--border-bright);
|
||||
box-shadow: 0 4px 20px rgba(0, 217, 255, 0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.card-solid {
|
||||
background: var(--bg-solid-header);
|
||||
border: var(--border-width) solid var(--border-bright);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
border: var(--border-width) solid var(--border-bright);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.card-accent-neon {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-medium) solid var(--accent-neon-1);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-cyan);
|
||||
}
|
||||
|
||||
.card-accent-cyber {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-medium) solid var(--accent-cyber-1);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-purple);
|
||||
}
|
||||
|
||||
.card-accent-glow {
|
||||
background: var(--bg-card);
|
||||
border: var(--border-width-medium) solid var(--accent-glow-1);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--glow-gold);
|
||||
}
|
||||
|
||||
/* ===== 7. BUTTONS ===== */
|
||||
.btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: var(--radius-sm);
|
||||
border: none;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--btn-primary-gradient);
|
||||
color: var(--bg-solid-dark);
|
||||
box-shadow: var(--glow-cyan);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
box-shadow: 0 0 30px rgba(0, 217, 255, 0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--btn-secondary-gradient);
|
||||
color: var(--bg-solid-dark);
|
||||
box-shadow: var(--glow-gold);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
box-shadow: 0 0 30px rgba(255, 215, 0, 0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
color: var(--accent-neon-1);
|
||||
border: var(--border-width-medium) solid var(--accent-neon-1);
|
||||
}
|
||||
|
||||
.btn-outline:hover {
|
||||
background: var(--accent-neon-1);
|
||||
color: var(--bg-solid-dark);
|
||||
box-shadow: var(--glow-cyan);
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--accent-cyber-1);
|
||||
border: var(--border-width) solid transparent;
|
||||
}
|
||||
|
||||
.btn-ghost:hover {
|
||||
background: var(--bg-elevated);
|
||||
border-color: var(--accent-cyber-1);
|
||||
box-shadow: var(--glow-purple);
|
||||
}
|
||||
|
||||
.btn-alert {
|
||||
background: linear-gradient(135deg, var(--accent-alert-1) 0%, var(--accent-alert-2) 100%);
|
||||
color: var(--text-white);
|
||||
box-shadow: var(--glow-pink);
|
||||
}
|
||||
|
||||
.btn-alert:hover {
|
||||
box-shadow: 0 0 30px rgba(255, 110, 199, 0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* ===== 8. ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: var(--radius-md);
|
||||
border-left: var(--border-width-thick) solid;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: rgba(0, 217, 255, 0.1);
|
||||
border-left-color: var(--accent-neon-1);
|
||||
box-shadow: var(--glow-cyan);
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: rgba(185, 104, 255, 0.1);
|
||||
border-left-color: var(--accent-cyber-1);
|
||||
box-shadow: var(--glow-purple);
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background: rgba(255, 215, 0, 0.1);
|
||||
border-left-color: var(--accent-glow-1);
|
||||
box-shadow: var(--glow-gold);
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
background: rgba(255, 110, 199, 0.1);
|
||||
border-left-color: var(--accent-alert-1);
|
||||
box-shadow: var(--glow-pink);
|
||||
}
|
||||
|
||||
/* ===== 9. CODE BLOCKS ===== */
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-darker);
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: var(--radius-xs);
|
||||
font-size: 0.9em;
|
||||
color: var(--accent-neon-1);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
}
|
||||
|
||||
pre {
|
||||
background: var(--bg-darker);
|
||||
border: var(--border-width) solid var(--border-bright);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
border: none;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ===== 10. TABLES ===== */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
th {
|
||||
background: var(--bg-darker);
|
||||
color: var(--accent-neon-1);
|
||||
padding: 0.75rem;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
border: var(--border-width) solid var(--border-bright);
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.75rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background: var(--bg-elevated);
|
||||
}
|
||||
|
||||
/* ===== 11. LISTS ===== */
|
||||
ul, ol {
|
||||
margin-left: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ===== 12. UTILITY CLASSES ===== */
|
||||
.mb-1 { margin-bottom: 0.5rem; }
|
||||
.mb-2 { margin-bottom: 1rem; }
|
||||
.mb-3 { margin-bottom: 2rem; }
|
||||
.mt-1 { margin-top: 0.5rem; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mt-3 { margin-top: 2rem; }
|
||||
.text-center { text-align: center; }
|
||||
|
||||
/* ===== 13. DIVIDERS ===== */
|
||||
.section-divider {
|
||||
border: none;
|
||||
border-top: var(--border-width) solid var(--border-bright);
|
||||
margin: 2rem 0;
|
||||
opacity: 0.5;
|
||||
box-shadow: 0 1px 10px rgba(0, 217, 255, 0.2);
|
||||
}
|
||||
|
||||
/* ===== 14. HEADER ===== */
|
||||
header {
|
||||
text-align: center;
|
||||
padding: 2rem 0;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header>
|
||||
<h1>Crepuscular City Lights</h1>
|
||||
<p style="font-size: 1.25rem; color: var(--text-secondary); margin-top: 1rem;">
|
||||
Dark & Elegant • Urban Nightscape • Neon Accents
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- THEME OVERVIEW -->
|
||||
<section class="mb-3">
|
||||
<h2>Theme Overview</h2>
|
||||
<div class="card-elevated">
|
||||
<p style="font-size: 1.1rem; line-height: 1.8;">
|
||||
<strong style="color: var(--accent-neon-1);">City Lights</strong> embodies the sleek sophistication of a modern metropolis at night. Deep, near-black backgrounds evoke the urban darkness, while vibrant neon accents mimic the electric glow of city lights, creating a high-contrast, elegant aesthetic perfect for premium applications and modern interfaces.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-3 mt-2">
|
||||
<div class="card-accent-neon">
|
||||
<h3>Design Philosophy</h3>
|
||||
<ul>
|
||||
<li><strong>Dark Foundation:</strong> Near-black backgrounds with subtle blue undertones</li>
|
||||
<li><strong>High Contrast:</strong> Bright accents against deep shadows</li>
|
||||
<li><strong>Neon Energy:</strong> Electric colors inspired by city nightlife</li>
|
||||
<li><strong>Elegant Modern:</strong> Sophisticated and professional</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-accent-cyber">
|
||||
<h3>Perfect For</h3>
|
||||
<ul>
|
||||
<li><strong>Premium Apps:</strong> High-end software interfaces</li>
|
||||
<li><strong>Tech Products:</strong> Developer tools and platforms</li>
|
||||
<li><strong>Creative Studios:</strong> Design and media agencies</li>
|
||||
<li><strong>Modern Brands:</strong> Forward-thinking companies</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-accent-glow">
|
||||
<h3>Key Features</h3>
|
||||
<ul>
|
||||
<li><strong>Subtle Glows:</strong> Neon shadow effects</li>
|
||||
<li><strong>Sharp Corners:</strong> 2-6px radius range</li>
|
||||
<li><strong>Vibrant Palette:</strong> Four accent color systems</li>
|
||||
<li><strong>WCAG AAA:</strong> Exceptional readability</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Neon Color Palette</h2>
|
||||
<div class="grid grid-4">
|
||||
<div class="card" style="background: linear-gradient(135deg, #00d9ff 0%, #0099ff 100%); color: #0a0e1a;">
|
||||
<h4 style="color: #0a0e1a;">Neon System</h4>
|
||||
<code style="background: rgba(10,14,26,0.3); color: #0a0e1a; border-color: #0a0e1a;">#00d9ff</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #0a0e1a;">Electric cyan & blue</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #b968ff 0%, #7b5bff 100%); color: #0a0e1a;">
|
||||
<h4 style="color: #0a0e1a;">Cyber System</h4>
|
||||
<code style="background: rgba(10,14,26,0.3); color: #0a0e1a; border-color: #0a0e1a;">#b968ff</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #0a0e1a;">Neon purple</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #ffd700 0%, #ffab00 100%); color: #0a0e1a;">
|
||||
<h4 style="color: #0a0e1a;">Glow System</h4>
|
||||
<code style="background: rgba(10,14,26,0.3); color: #0a0e1a; border-color: #0a0e1a;">#ffd700</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #0a0e1a;">Neon gold & amber</p>
|
||||
</div>
|
||||
<div class="card" style="background: linear-gradient(135deg, #ff6ec7 0%, #ff3d9a 100%); color: #0a0e1a;">
|
||||
<h4 style="color: #0a0e1a;">Alert System</h4>
|
||||
<code style="background: rgba(10,14,26,0.3); color: #0a0e1a; border-color: #0a0e1a;">#ff6ec7</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #0a0e1a;">Neon pink</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-2">
|
||||
<div class="card">
|
||||
<h3>Background Spectrum</h3>
|
||||
<div style="display: flex; gap: 1rem; margin-top: 1rem;">
|
||||
<div style="flex: 1; background: #0a0e1a; border: 1px solid var(--border-bright); border-radius: var(--radius-sm); padding: 1rem; text-align: center;">
|
||||
<code style="font-size: 0.75rem;">#0a0e1a</code>
|
||||
<p style="font-size: 0.75rem; margin-top: 0.5rem;">Deep midnight</p>
|
||||
</div>
|
||||
<div style="flex: 1; background: #0f1419; border: 1px solid var(--border-bright); border-radius: var(--radius-sm); padding: 1rem; text-align: center;">
|
||||
<code style="font-size: 0.75rem;">#0f1419</code>
|
||||
<p style="font-size: 0.75rem; margin-top: 0.5rem;">Dark steel</p>
|
||||
</div>
|
||||
<div style="flex: 1; background: #141922; border: 1px solid var(--border-bright); border-radius: var(--radius-sm); padding: 1rem; text-align: center;">
|
||||
<code style="font-size: 0.75rem;">#141922</code>
|
||||
<p style="font-size: 0.75rem; margin-top: 0.5rem;">Charcoal blue</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Text Hierarchy</h3>
|
||||
<div style="display: flex; flex-direction: column; gap: 0.75rem; margin-top: 1rem;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span style="color: var(--text-primary);">Primary Text</span>
|
||||
<code style="font-size: 0.75rem;">#f0f6fc</code>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span style="color: var(--text-secondary);">Secondary Text</span>
|
||||
<code style="font-size: 0.75rem;">#c9d1d9</code>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span style="color: var(--text-muted);">Muted Text</span>
|
||||
<code style="font-size: 0.75rem;">#8b949e</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- TYPOGRAPHY -->
|
||||
<section class="mb-3">
|
||||
<h2>Typography System</h2>
|
||||
<div class="card">
|
||||
<h1>H1 Heading with Gradient</h1>
|
||||
<h2>H2 Heading - Electric Cyan</h2>
|
||||
<h3>H3 Heading - Neon Purple</h3>
|
||||
<h4>H4 Heading - Neon Gold</h4>
|
||||
<h5>H5 Heading - Primary Bright</h5>
|
||||
<h6>H6 Heading - All Caps</h6>
|
||||
<p>Body text uses IBM Plex Sans for optimal readability in the dark theme. The high contrast between the bright text and deep backgrounds ensures comfortable reading for extended periods.</p>
|
||||
<p style="color: var(--text-muted);">Muted text is perfect for supplementary information and metadata.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Button Styles</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card">
|
||||
<h3>Primary Actions</h3>
|
||||
<button class="btn btn-primary">Primary Button</button>
|
||||
<button class="btn btn-secondary mt-2">Secondary Button</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Alternative Styles</h3>
|
||||
<button class="btn btn-outline">Outline Button</button>
|
||||
<button class="btn btn-ghost mt-2">Ghost Button</button>
|
||||
<button class="btn btn-alert mt-2">Alert Button</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- CARDS -->
|
||||
<section class="mb-3">
|
||||
<h2>Card Components</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card">
|
||||
<h3>Standard Card</h3>
|
||||
<p>Default card with subtle background and border. Hover for lift effect.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-solid">
|
||||
<h3>Solid Card</h3>
|
||||
<p>Opaque background for emphasis and hierarchy.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-elevated">
|
||||
<h3>Elevated Card</h3>
|
||||
<p>Enhanced shadow for prominent content sections.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-accent-neon">
|
||||
<h3>Neon Accent</h3>
|
||||
<p>Electric cyan border with subtle glow effect.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-accent-cyber">
|
||||
<h3>Cyber Accent</h3>
|
||||
<p>Neon purple border with purple glow effect.</p>
|
||||
</div>
|
||||
|
||||
<div class="card-accent-glow">
|
||||
<h3>Glow Accent</h3>
|
||||
<p>Neon gold border with warm glow effect.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>Alert Messages</h2>
|
||||
<div class="alert alert-info">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem;">Info Alert</h3>
|
||||
<p style="margin: 0;">Electric cyan accent with subtle glow - perfect for general information.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-success">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem;">Success Alert</h3>
|
||||
<p style="margin: 0;">Neon purple accent with purple glow - great for success messages.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem;">Warning Alert</h3>
|
||||
<p style="margin: 0;">Neon gold accent with warm glow - ideal for warnings and cautions.</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem;">Danger Alert</h3>
|
||||
<p style="margin: 0;">Neon pink accent with pink glow - for critical alerts and errors.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- CODE BLOCKS -->
|
||||
<section class="mb-3">
|
||||
<h2>Code Display</h2>
|
||||
<div class="card">
|
||||
<h3>Inline Code</h3>
|
||||
<p>Use <code>inline code</code> for variable names, <code>function()</code> calls, and <code>CSS properties</code> within text.</p>
|
||||
</div>
|
||||
|
||||
<div class="card mt-2">
|
||||
<h3>Code Blocks</h3>
|
||||
<pre><code>// Neon color system
|
||||
const colors = {
|
||||
neon: '#00d9ff', // Electric cyan
|
||||
cyber: '#b968ff', // Neon purple
|
||||
glow: '#ffd700', // Neon gold
|
||||
alert: '#ff6ec7' // Neon pink
|
||||
};
|
||||
|
||||
// Apply glow effect
|
||||
element.style.boxShadow = '0 0 20px rgba(0, 217, 255, 0.5)';</code></pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- TABLES -->
|
||||
<section class="mb-3">
|
||||
<h2>Data Tables</h2>
|
||||
<div class="card">
|
||||
<h3>Color Variables Reference</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Color</th>
|
||||
<th>Usage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>--accent-neon-1</code></td>
|
||||
<td>#00d9ff</td>
|
||||
<td>Primary actions, links</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-cyber-1</code></td>
|
||||
<td>#b968ff</td>
|
||||
<td>Secondary accents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-glow-1</code></td>
|
||||
<td>#ffd700</td>
|
||||
<td>Highlights, warnings</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--accent-alert-1</code></td>
|
||||
<td>#ff6ec7</td>
|
||||
<td>Alerts, errors</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>--text-primary</code></td>
|
||||
<td>#f0f6fc</td>
|
||||
<td>Main text content</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- IMPLEMENTATION GUIDE -->
|
||||
<section class="mb-3">
|
||||
<h2>Implementation Guide</h2>
|
||||
|
||||
<div class="card-accent-neon">
|
||||
<h3>Glow Effects System</h3>
|
||||
<p>City Lights uses subtle glow effects to create the neon aesthetic:</p>
|
||||
<pre><code>/* Glow variables */
|
||||
--glow-cyan: 0 0 20px rgba(0, 217, 255, 0.3);
|
||||
--glow-purple: 0 0 20px rgba(185, 104, 255, 0.3);
|
||||
--glow-gold: 0 0 20px rgba(255, 215, 0, 0.3);
|
||||
--glow-pink: 0 0 20px rgba(255, 110, 199, 0.3);
|
||||
|
||||
/* Application */
|
||||
h2 { text-shadow: var(--glow-cyan); }
|
||||
.btn-primary { box-shadow: var(--glow-cyan); }</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-2">
|
||||
<div class="card-accent-cyber">
|
||||
<h3>Design Principles</h3>
|
||||
<ul>
|
||||
<li><strong>High Contrast:</strong> Bright text on near-black backgrounds</li>
|
||||
<li><strong>Subtle Animation:</strong> Smooth transitions on all interactive elements</li>
|
||||
<li><strong>Consistent Glow:</strong> Apply shadow effects to all accent colors</li>
|
||||
<li><strong>Sharp Corners:</strong> Maintain 2-6px radius range</li>
|
||||
<li><strong>Depth Through Darkness:</strong> Layer opacity for visual hierarchy</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-accent-glow">
|
||||
<h3>Best Practices</h3>
|
||||
<ul>
|
||||
<li><strong>Use Sparingly:</strong> Neon accents work best as highlights</li>
|
||||
<li><strong>Dark Foundations:</strong> Keep backgrounds very dark</li>
|
||||
<li><strong>Readable Text:</strong> Ensure WCAG AAA contrast ratios</li>
|
||||
<li><strong>Hover States:</strong> Enhance glows on interaction</li>
|
||||
<li><strong>Balance Energy:</strong> Mix cool and warm accent colors</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-2">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem;">Technical Specifications</h3>
|
||||
<ul style="margin-left: 1.5rem; margin-top: 0.5rem;">
|
||||
<li><strong>Background Range:</strong> #0a0e1a to #141922 (near-black with blue tint)</li>
|
||||
<li><strong>Border Contrast:</strong> 30-50% lighter than backgrounds</li>
|
||||
<li><strong>Text Contrast:</strong> WCAG AAA compliant (7:1 or higher)</li>
|
||||
<li><strong>Glow Opacity:</strong> 0.3 for shadows, 0.5 for hover states</li>
|
||||
<li><strong>Border Radius:</strong> 2px-6px range for sharp modern aesthetic</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- COMPARISON -->
|
||||
<section class="mb-3">
|
||||
<h2>Theme Comparison</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card-accent-cyber">
|
||||
<h3>City Lights Theme</h3>
|
||||
<ul>
|
||||
<li><strong>Background:</strong> Near-black (#0a0e1a)</li>
|
||||
<li><strong>Aesthetic:</strong> Modern, urban, neon</li>
|
||||
<li><strong>Contrast:</strong> Very high (AAA)</li>
|
||||
<li><strong>Accents:</strong> Vibrant neon colors</li>
|
||||
<li><strong>Mood:</strong> Energetic, sophisticated</li>
|
||||
<li><strong>Use Case:</strong> Tech, creative, premium</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Corporate Theme</h3>
|
||||
<ul>
|
||||
<li><strong>Background:</strong> Dark blue-gray (#1a1d2e)</li>
|
||||
<li><strong>Aesthetic:</strong> Professional, twilight</li>
|
||||
<li><strong>Contrast:</strong> High (AA+)</li>
|
||||
<li><strong>Accents:</strong> Muted warm/cool tones</li>
|
||||
<li><strong>Mood:</strong> Calm, professional</li>
|
||||
<li><strong>Use Case:</strong> Business, corporate</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card-solid text-center mt-3" style="padding: 2rem; border: 2px solid var(--accent-neon-1); box-shadow: var(--glow-cyan);">
|
||||
<h2 style="color: var(--text-white); background: var(--text-h1-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">Crepuscular City Lights</h2>
|
||||
<p style="color: var(--text-white); margin-top: 1rem;">Dark & Elegant • High Contrast • Neon Sophistication</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,729 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Crepuscular Corporate Style Reference</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
CREPUSCULAR CORPORATE STYLE REFERENCE
|
||||
Professional | Twilight Palette | Subtle Corners
|
||||
22% CONTRAST INCREASE APPLIED
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Crepuscular twilight gradient */
|
||||
--bg-gradient-1: #1a1d2e; /* Deep twilight blue */
|
||||
--bg-gradient-2: #2a2d3e; /* Slate dusk */
|
||||
--bg-gradient-3: #3a3242; /* Muted purple-gray */
|
||||
--bg-gradient-4: #2e3542; /* Steel blue-gray */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(200,210,230,0.04); /* Cool lift */
|
||||
--bg-card: rgba(200,210,230,0.08); /* Standard cards */
|
||||
--bg-darker: rgba(20,30,50,0.35); /* Nested elements */
|
||||
--bg-solid-dark: #1a1d2e; /* Opaque dark */
|
||||
--bg-solid-header: #2a2d3e; /* Opaque slate */
|
||||
|
||||
/* --- BORDERS ---
|
||||
INCREASED CONTRAST: 22% brighter */
|
||||
--border-color: #a4acbb; /* Was: #8b95a8 */
|
||||
--border-width: 1px;
|
||||
--border-width-medium: 2px;
|
||||
--border-width-thick: 3px;
|
||||
|
||||
/* --- BORDER RADIUS ---
|
||||
Sharp but rounded: 2-6px range */
|
||||
--radius-xs: 2px;
|
||||
--radius-sm: 3px;
|
||||
--radius-md: 4px;
|
||||
--radius-lg: 6px;
|
||||
|
||||
/* --- ACCENT SYSTEM ---
|
||||
INCREASED CONTRAST: All 22% brighter
|
||||
Dawn: Warm accents (sunrise colors)
|
||||
Dusk: Cool accents (twilight colors)
|
||||
Alert: Attention states */
|
||||
--accent-dawn-1: #edac6f; /* Was: #e89547 */
|
||||
--accent-dawn-2: #ddb892; /* Was: #d4a574 */
|
||||
--accent-dusk-1: #8ba5bf; /* Was: #6b8cae */
|
||||
--accent-dusk-2: #718ba3; /* Was: #4a6b8a */
|
||||
--accent-alert-1: #dd998a; /* Was: #d47d6a */
|
||||
--accent-alert-2: #d1bb8e; /* Was: #c5a86f */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS ---
|
||||
INCREASED CONTRAST: All 22% brighter */
|
||||
--text-primary: #edeef3; /* Was: #e8eaf0 */
|
||||
--text-secondary: #c7cad4; /* Was: #b8bcc8 */
|
||||
--text-muted: #a4acbb; /* Was: #8b95a8 */
|
||||
--text-white: #f5f7fa;
|
||||
--text-h1-gradient: linear-gradient(135deg, #8ba5bf 0%, #a4acbb 50%, #8ba5bf 100%);
|
||||
--text-h2: #8ba5bf; /* Steel blue - enhanced */
|
||||
--text-h3: #a4acbb; /* Slate gray - enhanced */
|
||||
--text-h4: #ddb892; /* Muted gold - enhanced */
|
||||
--text-h5: #edeef3; /* Primary - enhanced */
|
||||
--text-h6: #c7cad4; /* Secondary - enhanced */
|
||||
|
||||
/* --- BUTTON GRADIENTS ---
|
||||
Using enhanced accent colors */
|
||||
--btn-primary-gradient: linear-gradient(135deg, #8ba5bf 0%, #718ba3 100%);
|
||||
--btn-secondary-gradient: linear-gradient(135deg, #edac6f 0%, #ddb892 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Inter', sans-serif;
|
||||
--font-body: 'IBM Plex Sans', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--accent-dawn-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--accent-dusk-1);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.2rem 0.4rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.9em;
|
||||
color: var(--accent-dawn-2);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background: var(--bg-elevated);
|
||||
border-left: var(--border-width-thick) solid var(--accent-dusk-1);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1rem 1.5rem;
|
||||
margin: 1.5rem 0;
|
||||
font-style: italic;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-bottom: 1.5rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
ul li, ol li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
color: var(--accent-dawn-1);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
font-size: 0.9375rem;
|
||||
transition: all 0.2s;
|
||||
cursor: pointer;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
font-family: var(--font-body);
|
||||
border-radius: var(--radius-sm);
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--btn-primary-gradient);
|
||||
color: var(--text-white);
|
||||
border: none;
|
||||
box-shadow: 0 2px 8px rgba(139, 165, 191, 0.3);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(139, 165, 191, 0.4);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--btn-secondary-gradient);
|
||||
color: var(--text-white);
|
||||
border: none;
|
||||
box-shadow: 0 2px 8px rgba(237, 172, 111, 0.3);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(237, 172, 111, 0.4);
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
border-color: var(--accent-dusk-1);
|
||||
}
|
||||
|
||||
.btn-outline:hover {
|
||||
background: rgba(139, 165, 191, 0.1);
|
||||
border-color: var(--accent-dawn-1);
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-ghost:hover {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.btn-alert {
|
||||
background: var(--bg-solid-dark);
|
||||
color: var(--text-primary);
|
||||
border-color: var(--accent-alert-1);
|
||||
box-shadow: 0 0 0 1px var(--accent-alert-1) inset;
|
||||
}
|
||||
|
||||
.btn-alert:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 0 0 1px var(--accent-alert-1) inset, 0 4px 12px rgba(221, 153, 138, 0.3);
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-solid {
|
||||
background: var(--bg-solid-header);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-accent-dawn {
|
||||
border-left: var(--border-width-thick) solid var(--accent-dawn-1);
|
||||
}
|
||||
|
||||
.card-accent-dusk {
|
||||
border-left: var(--border-width-thick) solid var(--accent-dusk-1);
|
||||
}
|
||||
|
||||
.card-highlight {
|
||||
background: rgba(245, 247, 250, 0.95);
|
||||
color: #2a2d3e;
|
||||
border: var(--border-width-medium) solid var(--accent-dusk-1);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-highlight h1,
|
||||
.card-highlight h2,
|
||||
.card-highlight h3,
|
||||
.card-highlight h4,
|
||||
.card-highlight h5,
|
||||
.card-highlight h6 {
|
||||
color: #1a1d2e;
|
||||
background: none;
|
||||
-webkit-text-fill-color: #1a1d2e;
|
||||
}
|
||||
|
||||
.card-highlight p,
|
||||
.card-highlight li,
|
||||
.card-highlight td,
|
||||
.card-highlight dd {
|
||||
color: #2a2d3e;
|
||||
}
|
||||
|
||||
.card-highlight strong {
|
||||
color: #718ba3;
|
||||
}
|
||||
|
||||
.card-highlight em {
|
||||
color: #8ba5bf;
|
||||
}
|
||||
|
||||
.card-highlight code {
|
||||
background: rgba(139, 165, 191, 0.1);
|
||||
border-color: #8ba5bf;
|
||||
color: #718ba3;
|
||||
}
|
||||
|
||||
/* ===== TABLES ===== */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
margin-bottom: 1.5rem;
|
||||
background: var(--bg-card);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: var(--bg-solid-header);
|
||||
color: var(--text-white);
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 0.875rem 1rem;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.875rem 1rem;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) {
|
||||
background: var(--bg-darker);
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
background: rgba(139, 165, 191, 0.08);
|
||||
}
|
||||
|
||||
/* ===== BADGES & PILLS ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
border: var(--border-width) solid;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.badge-dawn {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--accent-dawn-1);
|
||||
border-color: var(--accent-dawn-1);
|
||||
}
|
||||
|
||||
.badge-dusk {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--accent-dusk-1);
|
||||
border-color: var(--accent-dusk-1);
|
||||
}
|
||||
|
||||
.badge-alert {
|
||||
background: var(--bg-elevated);
|
||||
color: var(--accent-alert-1);
|
||||
border-color: var(--accent-alert-1);
|
||||
}
|
||||
|
||||
.badge-solid {
|
||||
background: var(--bg-solid-header);
|
||||
color: var(--text-white);
|
||||
border-color: var(--border-color);
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: var(--radius-md);
|
||||
border: var(--border-width) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: rgba(139, 165, 191, 0.08);
|
||||
border-color: var(--accent-dusk-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: rgba(139, 165, 191, 0.1);
|
||||
border-color: var(--accent-dusk-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background: rgba(209, 187, 142, 0.1);
|
||||
border-color: var(--accent-alert-2);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
background: rgba(221, 153, 138, 0.1);
|
||||
border-color: var(--accent-alert-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.text-left { text-align: left; }
|
||||
.text-right { text-align: right; }
|
||||
|
||||
.mt-1 { margin-top: 0.5rem; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mt-3 { margin-top: 1.5rem; }
|
||||
.mb-1 { margin-bottom: 0.5rem; }
|
||||
.mb-2 { margin-bottom: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width);
|
||||
background: var(--border-color);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.section-divider {
|
||||
margin: 3rem 0;
|
||||
background: linear-gradient(to right, transparent, var(--border-color), transparent);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>Crepuscular Corporate</h1>
|
||||
<p style="font-size: 1.125rem; color: var(--text-secondary);">Professional | Twilight Palette | 22% Enhanced Contrast</p>
|
||||
</header>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- CONTRAST IMPROVEMENTS SHOWCASE -->
|
||||
<section class="mb-3">
|
||||
<h2>Contrast Enhancement Applied</h2>
|
||||
|
||||
<div class="card-highlight">
|
||||
<h3>22% Brighter Text & Accents</h3>
|
||||
<p>All text colors, accents, and borders have been increased by <strong>22% in brightness</strong> to improve readability and visual hierarchy while maintaining the crepuscular aesthetic.</p>
|
||||
<p><em>This enhancement makes content significantly more accessible without compromising the professional twilight theme.</em></p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-2">
|
||||
<div class="card card-accent-dawn">
|
||||
<h3>Before → After</h3>
|
||||
<table style="font-size: 0.875rem;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Element</th>
|
||||
<th>Original</th>
|
||||
<th>Enhanced</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>text-primary</code></td>
|
||||
<td>#e8eaf0</td>
|
||||
<td><strong>#edeef3</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>text-secondary</code></td>
|
||||
<td>#b8bcc8</td>
|
||||
<td><strong>#c7cad4</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>border-color</code></td>
|
||||
<td>#8b95a8</td>
|
||||
<td><strong>#a4acbb</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>accent-dawn-1</code></td>
|
||||
<td>#e89547</td>
|
||||
<td><strong>#edac6f</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>accent-dusk-1</code></td>
|
||||
<td>#6b8cae</td>
|
||||
<td><strong>#8ba5bf</strong></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card card-accent-dusk">
|
||||
<h3>Readability Improvements</h3>
|
||||
<ul>
|
||||
<li><strong>Headings:</strong> More prominent and scannable</li>
|
||||
<li><strong>Body text:</strong> Easier to read for extended periods</li>
|
||||
<li><strong>Borders:</strong> Better definition between sections</li>
|
||||
<li><strong>Accents:</strong> Warmer tones stand out more</li>
|
||||
<li><strong>Code blocks:</strong> Clearer syntax highlighting</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Enhanced Color Palette</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card" style="background: #8ba5bf; color: #1a1d2e;">
|
||||
<h4 style="color: #1a1d2e;">Steel Blue (Dusk)</h4>
|
||||
<code style="background: rgba(26,29,46,0.2); color: #1a1d2e; border-color: #1a1d2e;">#8ba5bf</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #1a1d2e;">+22% from #6b8cae</p>
|
||||
</div>
|
||||
<div class="card" style="background: #edac6f; color: #1a1d2e;">
|
||||
<h4 style="color: #1a1d2e;">Warm Orange (Dawn)</h4>
|
||||
<code style="background: rgba(26,29,46,0.2); color: #1a1d2e; border-color: #1a1d2e;">#edac6f</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #1a1d2e;">+22% from #e89547</p>
|
||||
</div>
|
||||
<div class="card" style="background: #ddb892; color: #1a1d2e;">
|
||||
<h4 style="color: #1a1d2e;">Muted Gold (Dawn)</h4>
|
||||
<code style="background: rgba(26,29,46,0.2); color: #1a1d2e; border-color: #1a1d2e;">#ddb892</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #1a1d2e;">+22% from #d4a574</p>
|
||||
</div>
|
||||
<div class="card" style="background: #dd998a; color: #1a1d2e;">
|
||||
<h4 style="color: #1a1d2e;">Muted Red (Alert)</h4>
|
||||
<code style="background: rgba(26,29,46,0.2); color: #1a1d2e; border-color: #1a1d2e;">#dd998a</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #1a1d2e;">+22% from #d47d6a</p>
|
||||
</div>
|
||||
<div class="card" style="background: #a4acbb; color: #1a1d2e;">
|
||||
<h4 style="color: #1a1d2e;">Slate Gray</h4>
|
||||
<code style="background: rgba(26,29,46,0.2); color: #1a1d2e; border-color: #1a1d2e;">#a4acbb</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #1a1d2e;">+22% from #8b95a8</p>
|
||||
</div>
|
||||
<div class="card" style="background: #edeef3; color: #1a1d2e;">
|
||||
<h4 style="color: #1a1d2e;">Primary Text</h4>
|
||||
<code style="background: rgba(26,29,46,0.2); color: #1a1d2e; border-color: #1a1d2e;">#edeef3</code>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem; color: #1a1d2e;">+22% from #e8eaf0</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Button Styles</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card">
|
||||
<h3>Primary Actions</h3>
|
||||
<button class="btn btn-primary">Primary Button</button>
|
||||
<button class="btn btn-secondary mt-2">Secondary Button</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3>Alternative Styles</h3>
|
||||
<button class="btn btn-outline">Outline Button</button>
|
||||
<button class="btn btn-ghost mt-2">Ghost Button</button>
|
||||
<button class="btn btn-alert mt-2">Alert Button</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<!-- IMPLEMENTATION GUIDE -->
|
||||
<section class="mb-3">
|
||||
<h2>Implementation Guide</h2>
|
||||
|
||||
<div class="card">
|
||||
<h3>Contrast Calculation Method</h3>
|
||||
<p>The 22% increase was applied by moving each RGB channel <strong>22% closer to white (255)</strong>:</p>
|
||||
<pre><code>new_value = original + (255 - original) × 0.22
|
||||
|
||||
Example for text-primary (#e8eaf0):
|
||||
R: 232 + (255 - 232) × 0.22 = 237
|
||||
G: 234 + (255 - 234) × 0.22 = 238
|
||||
B: 240 + (255 - 240) × 0.22 = 243
|
||||
Result: #edeef3</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-2">
|
||||
<div class="card card-accent-dawn">
|
||||
<h3>What Changed</h3>
|
||||
<ul>
|
||||
<li><strong>All text colors</strong> (primary, secondary, muted)</li>
|
||||
<li><strong>All border colors</strong></li>
|
||||
<li><strong>All accent colors</strong> (dawn, dusk, alert)</li>
|
||||
<li><strong>Typography color variables</strong> (h2-h6)</li>
|
||||
<li><strong>Button gradients</strong> use enhanced colors</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card card-accent-dusk">
|
||||
<h3>What Stayed the Same</h3>
|
||||
<ul>
|
||||
<li><strong>Background gradients</strong> (maintain depth)</li>
|
||||
<li><strong>Surface backgrounds</strong> (opacity values)</li>
|
||||
<li><strong>Border radius</strong> (2-6px range)</li>
|
||||
<li><strong>Layout structure</strong> and spacing</li>
|
||||
<li><strong>Interaction patterns</strong> and animations</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-2">
|
||||
<h3 style="color: var(--text-primary); margin-bottom: 0.5rem;">Key Principles</h3>
|
||||
<ul style="margin-left: 1.5rem; margin-top: 0.5rem;">
|
||||
<li><strong>Preserve aesthetics:</strong> Maintain the crepuscular twilight mood</li>
|
||||
<li><strong>Improve readability:</strong> 22% increase in light channel values</li>
|
||||
<li><strong>Consistent application:</strong> All text and accent colors enhanced equally</li>
|
||||
<li><strong>Accessibility focus:</strong> Better contrast ratios for WCAG compliance</li>
|
||||
<li><strong>Professional appearance:</strong> Subtle corners and refined palette</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card-solid text-center mt-3" style="padding: 2rem;">
|
||||
<h2 style="color: var(--text-white);">Enhanced Crepuscular Corporate</h2>
|
||||
<p style="color: var(--text-white); margin-top: 1rem;">22% brighter text & accents | Improved readability | Professional twilight aesthetic maintained</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
657
DumperCan/UI Style References/faerie-fire_style_reference.html
Normal file
657
DumperCan/UI Style References/faerie-fire_style_reference.html
Normal file
@@ -0,0 +1,657 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Faerie Fire Style Reference | Prismatic Magic ✨</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600;700&family=Urbanist:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
FAERIE FIRE STYLE REFERENCE
|
||||
Prismatic Magic | Ethereal Edges | Iridescent Code
|
||||
UNIQUE FEATURE: Animated Rainbow Prismatic Borders
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Twilight to starlight - magical realm */
|
||||
--bg-gradient-1: #0f0a1f; /* Deep twilight */
|
||||
--bg-gradient-2: #1a0f2a; /* Midnight purple */
|
||||
--bg-gradient-3: #1f1535; /* Dark magenta */
|
||||
--bg-gradient-4: #251a3f; /* Enchanted violet */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(200,150,255,0.06);
|
||||
--bg-card: rgba(200,150,255,0.10);
|
||||
--bg-darker: rgba(15,10,30,0.50);
|
||||
--bg-solid-dark: #0f0a1f;
|
||||
--bg-solid-light: #faf5ff;
|
||||
|
||||
/* --- BORDERS ---
|
||||
Sharp faerie edges, crystalline precision */
|
||||
--border-color: #c084fc;
|
||||
--border-width: 2px;
|
||||
--border-width-thick: 4px;
|
||||
|
||||
/* --- GLOW SYSTEM ---
|
||||
Prismatic colors that shift and shimmer */
|
||||
--violet-1: #c084fc; /* Soft violet */
|
||||
--violet-2: #a855f7; /* Deep purple */
|
||||
--pink-1: #f472b6; /* Bright pink */
|
||||
--pink-2: #ec4899; /* Deep pink */
|
||||
--cyan-1: #67e8f9; /* Bright cyan */
|
||||
--cyan-2: #22d3ee; /* Deep cyan */
|
||||
--green-1: #86efac; /* Mint green */
|
||||
--green-2: #4ade80; /* Bright green */
|
||||
--gold-1: #fbbf24; /* Fairy gold */
|
||||
--gold-2: #f59e0b; /* Deep gold */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS --- */
|
||||
--text-primary: #f5f3ff;
|
||||
--text-secondary: #ddd6fe;
|
||||
--text-white: #ffffff;
|
||||
--text-h1-gradient: linear-gradient(135deg,
|
||||
#c084fc 0%,
|
||||
#f472b6 20%,
|
||||
#67e8f9 40%,
|
||||
#86efac 60%,
|
||||
#fbbf24 80%,
|
||||
#c084fc 100%);
|
||||
--text-h2: #c084fc;
|
||||
--text-h3: #f472b6;
|
||||
--text-h4: #67e8f9;
|
||||
--text-h5: #86efac;
|
||||
--text-h6: #f5f3ff;
|
||||
|
||||
/* --- BUTTON GRADIENTS --- */
|
||||
--btn-violet-gradient: linear-gradient(135deg, #c084fc 0%, #a855f7 100%);
|
||||
--btn-rainbow-gradient: linear-gradient(135deg,
|
||||
#c084fc 0%,
|
||||
#f472b6 25%,
|
||||
#67e8f9 50%,
|
||||
#86efac 75%,
|
||||
#fbbf24 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Cormorant Garamond', serif;
|
||||
--font-body: 'Urbanist', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== UNIQUE FEATURE: ANIMATED PRISMATIC BORDERS ===== */
|
||||
@keyframes prismatic-shift {
|
||||
0% {
|
||||
border-image-source: linear-gradient(90deg,
|
||||
#c084fc 0%, #f472b6 25%, #67e8f9 50%, #86efac 75%, #fbbf24 100%);
|
||||
}
|
||||
25% {
|
||||
border-image-source: linear-gradient(90deg,
|
||||
#fbbf24 0%, #c084fc 25%, #f472b6 50%, #67e8f9 75%, #86efac 100%);
|
||||
}
|
||||
50% {
|
||||
border-image-source: linear-gradient(90deg,
|
||||
#86efac 0%, #fbbf24 25%, #c084fc 50%, #f472b6 75%, #67e8f9 100%);
|
||||
}
|
||||
75% {
|
||||
border-image-source: linear-gradient(90deg,
|
||||
#67e8f9 0%, #86efac 25%, #fbbf24 50%, #c084fc 75%, #f472b6 100%);
|
||||
}
|
||||
100% {
|
||||
border-image-source: linear-gradient(90deg,
|
||||
#c084fc 0%, #f472b6 25%, #67e8f9 50%, #86efac 75%, #fbbf24 100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sparkle {
|
||||
0%, 100% { opacity: 0; transform: scale(0) rotate(0deg); }
|
||||
50% { opacity: 1; transform: scale(1) rotate(180deg); }
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(135deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.7;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
background-size: 200% auto;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
animation: prismatic-text 6s linear infinite;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@keyframes prismatic-text {
|
||||
0% { background-position: 0% 50%; }
|
||||
100% { background-position: 200% 50%; }
|
||||
}
|
||||
|
||||
/* Sparkle decoration on H1 */
|
||||
h1::after {
|
||||
content: '✨';
|
||||
position: absolute;
|
||||
right: -2rem;
|
||||
top: 0;
|
||||
font-size: 1.5rem;
|
||||
animation: sparkle 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 30px rgba(192, 132, 252, 0.6),
|
||||
0 0 60px rgba(192, 132, 252, 0.3);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 20px rgba(244, 114, 182, 0.5);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 20px rgba(103, 232, 249, 0.5);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--violet-1);
|
||||
font-weight: 600;
|
||||
text-shadow: 0 0 15px rgba(192, 132, 252, 0.5);
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--pink-1);
|
||||
font-style: italic;
|
||||
text-shadow: 0 0 15px rgba(244, 114, 182, 0.4);
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.2rem 0.4rem;
|
||||
border: 1px solid var(--cyan-1);
|
||||
border-radius: 0;
|
||||
font-size: 0.9em;
|
||||
color: var(--cyan-1);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: 0;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.875rem 2rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
font-family: var(--font-body);
|
||||
border-radius: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg,
|
||||
transparent 40%,
|
||||
rgba(255, 255, 255, 0.3) 50%,
|
||||
transparent 60%);
|
||||
transform: rotate(45deg);
|
||||
animation: shimmer 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { transform: translateX(-100%) rotate(45deg); }
|
||||
100% { transform: translateX(100%) rotate(45deg); }
|
||||
}
|
||||
|
||||
.btn-violet {
|
||||
background: var(--btn-violet-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 0 20px rgba(192, 132, 252, 0.5),
|
||||
0 0 40px rgba(192, 132, 252, 0.3);
|
||||
}
|
||||
|
||||
.btn-violet:hover {
|
||||
transform: scale(1.04);
|
||||
box-shadow: 0 0 30px rgba(192, 132, 252, 0.7),
|
||||
0 0 60px rgba(192, 132, 252, 0.4);
|
||||
}
|
||||
|
||||
.btn-rainbow {
|
||||
background: var(--btn-rainbow-gradient);
|
||||
background-size: 200% auto;
|
||||
color: white;
|
||||
animation: rainbow-shift 3s linear infinite;
|
||||
box-shadow: 0 0 25px rgba(192, 132, 252, 0.4),
|
||||
0 0 50px rgba(244, 114, 182, 0.3);
|
||||
}
|
||||
|
||||
@keyframes rainbow-shift {
|
||||
0% { background-position: 0% 50%; }
|
||||
100% { background-position: 200% 50%; }
|
||||
}
|
||||
|
||||
.btn-rainbow:hover {
|
||||
transform: scale(1.04);
|
||||
animation-duration: 1.5s;
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: 0;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: 0;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
/* Prismatic border effect - the star feature */
|
||||
.card-prismatic {
|
||||
position: relative;
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-prismatic::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
padding: var(--border-width-thick);
|
||||
background: linear-gradient(90deg,
|
||||
#c084fc 0%,
|
||||
#f472b6 25%,
|
||||
#67e8f9 50%,
|
||||
#86efac 75%,
|
||||
#fbbf24 100%);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
animation: prismatic-border 8s linear infinite;
|
||||
background-size: 300% 100%;
|
||||
}
|
||||
|
||||
@keyframes prismatic-border {
|
||||
0% { background-position: 0% 50%; }
|
||||
100% { background-position: 300% 50%; }
|
||||
}
|
||||
|
||||
.card-glow-violet {
|
||||
box-shadow: 0 0 30px rgba(192, 132, 252, 0.4),
|
||||
0 0 60px rgba(192, 132, 252, 0.2);
|
||||
}
|
||||
|
||||
.card-glow-pink {
|
||||
box-shadow: 0 0 30px rgba(244, 114, 182, 0.4),
|
||||
0 0 60px rgba(244, 114, 182, 0.2);
|
||||
}
|
||||
|
||||
.card-glow-cyan {
|
||||
box-shadow: 0 0 30px rgba(103, 232, 249, 0.4),
|
||||
0 0 60px rgba(103, 232, 249, 0.2);
|
||||
}
|
||||
|
||||
.card-enchanted {
|
||||
background: rgba(250, 245, 255, 0.95);
|
||||
border: var(--border-width-thick) solid var(--violet-2);
|
||||
color: #1a0f2a;
|
||||
padding: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 0 40px rgba(168, 85, 247, 0.4);
|
||||
}
|
||||
|
||||
.card-enchanted h1,
|
||||
.card-enchanted h2,
|
||||
.card-enchanted h3,
|
||||
.card-enchanted h4,
|
||||
.card-enchanted h5,
|
||||
.card-enchanted h6 {
|
||||
color: #a855f7;
|
||||
background: none;
|
||||
-webkit-text-fill-color: #a855f7;
|
||||
}
|
||||
|
||||
.card-enchanted p,
|
||||
.card-enchanted li {
|
||||
color: #1a0f2a;
|
||||
}
|
||||
|
||||
.card-enchanted strong {
|
||||
color: #ec4899;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* ===== BADGES ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: 0;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
border: var(--border-width) solid;
|
||||
}
|
||||
|
||||
.badge-violet {
|
||||
background: rgba(192, 132, 252, 0.15);
|
||||
color: var(--violet-1);
|
||||
border-color: var(--violet-1);
|
||||
box-shadow: 0 0 15px rgba(192, 132, 252, 0.3);
|
||||
}
|
||||
|
||||
.badge-pink {
|
||||
background: rgba(244, 114, 182, 0.15);
|
||||
color: var(--pink-1);
|
||||
border-color: var(--pink-1);
|
||||
box-shadow: 0 0 15px rgba(244, 114, 182, 0.3);
|
||||
}
|
||||
|
||||
.badge-cyan {
|
||||
background: rgba(103, 232, 249, 0.15);
|
||||
color: var(--cyan-1);
|
||||
border-color: var(--cyan-1);
|
||||
box-shadow: 0 0 15px rgba(103, 232, 249, 0.3);
|
||||
}
|
||||
|
||||
.badge-green {
|
||||
background: rgba(134, 239, 172, 0.15);
|
||||
color: var(--green-1);
|
||||
border-color: var(--green-1);
|
||||
box-shadow: 0 0 15px rgba(134, 239, 172, 0.3);
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: 0;
|
||||
border: var(--border-width) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-violet {
|
||||
background: rgba(192, 132, 252, 0.1);
|
||||
border-color: var(--violet-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(192, 132, 252, 0.2);
|
||||
}
|
||||
|
||||
.alert-pink {
|
||||
background: rgba(244, 114, 182, 0.1);
|
||||
border-color: var(--pink-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(244, 114, 182, 0.2);
|
||||
}
|
||||
|
||||
.alert-cyan {
|
||||
background: rgba(103, 232, 249, 0.1);
|
||||
border-color: var(--cyan-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(103, 232, 249, 0.2);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width);
|
||||
background: linear-gradient(to right,
|
||||
var(--violet-1),
|
||||
var(--pink-1),
|
||||
var(--cyan-1),
|
||||
var(--green-1),
|
||||
var(--gold-1));
|
||||
margin: 2.5rem 0;
|
||||
box-shadow: 0 0 20px rgba(192, 132, 252, 0.3);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>Faerie Fire</h1>
|
||||
<p style="font-size: 1.25rem; color: var(--pink-1); text-shadow: 0 0 20px rgba(244,114,182,0.5);">Prismatic Magic | Ethereal Edges | Iridescent Code</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- UNIQUE FEATURE SHOWCASE -->
|
||||
<section class="mb-3">
|
||||
<div class="card-enchanted">
|
||||
<h2>✨ Unique Feature: Prismatic Borders</h2>
|
||||
<p>This design system features <strong>animated rainbow prismatic borders</strong> that continuously shift through all colors of the magical spectrum. The effect is created using gradient masks and keyframe animations.</p>
|
||||
<p>Look at the card below to see the prismatic border in action—it cycles through <em>violet, pink, cyan, green, and gold</em> in an endless, mesmerizing flow.</p>
|
||||
<p>Sharp faerie edges meet liquid light. Magic crystallized in CSS.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PRISMATIC SHOWCASE -->
|
||||
<section class="mb-3">
|
||||
<div class="card-prismatic">
|
||||
<h2>Witness the Prismatic Effect</h2>
|
||||
<p>This card's border flows through the entire rainbow spectrum continuously. The animation is smooth, CPU-efficient, and requires no JavaScript.</p>
|
||||
<p><strong>Technical implementation:</strong> Uses a pseudo-element with an animated gradient background and mask-composite to create the border effect while maintaining sharp corners.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Prismatic Spectrum</h2>
|
||||
<div class="grid grid-4">
|
||||
<div class="card" style="background: var(--violet-1); color: #000;">
|
||||
<h4 style="color: #000;">Soft Violet</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#c084fc</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--pink-1); color: #000;">
|
||||
<h4 style="color: #000;">Bright Pink</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#f472b6</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--cyan-1); color: #000;">
|
||||
<h4 style="color: #000;">Bright Cyan</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#67e8f9</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--green-1); color: #000;">
|
||||
<h4 style="color: #000;">Mint Green</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#86efac</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--gold-1); color: #000;">
|
||||
<h4 style="color: #000;">Fairy Gold</h4>
|
||||
<code style="background: rgba(0,0,0,0.2); color: #000; border-color: #000;">#fbbf24</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--violet-2); color: white;">
|
||||
<h4 style="color: white;">Deep Purple</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#a855f7</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--pink-2); color: white;">
|
||||
<h4 style="color: white;">Deep Pink</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#ec4899</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--cyan-2); color: white;">
|
||||
<h4 style="color: white;">Deep Cyan</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#22d3ee</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Magical Actions</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card card-glow-violet">
|
||||
<h3>Violet & Rainbow</h3>
|
||||
<button class="btn btn-violet">Enchant</button>
|
||||
<button class="btn btn-rainbow mt-2">Prismatic Cast</button>
|
||||
</div>
|
||||
<div class="card card-glow-pink">
|
||||
<h3>Notice the Shimmer</h3>
|
||||
<p style="font-size: 0.9rem;">Hover over buttons to see enhanced glow effects. The rainbow button continuously shifts colors.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- BADGES -->
|
||||
<section class="mb-3">
|
||||
<h2>Enchanted Badges</h2>
|
||||
<div class="card">
|
||||
<span class="badge badge-violet">Magical</span>
|
||||
<span class="badge badge-pink">Ethereal</span>
|
||||
<span class="badge badge-cyan">Prismatic</span>
|
||||
<span class="badge badge-green">Iridescent</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>Magical Messages</h2>
|
||||
<div class="alert alert-violet">
|
||||
<strong>Enchantment Success:</strong> The spell weaves through reality with prismatic beauty.
|
||||
</div>
|
||||
<div class="alert alert-pink">
|
||||
<strong>Faerie Notice:</strong> Magical energies detected in the ethereal plane.
|
||||
</div>
|
||||
<div class="alert alert-cyan">
|
||||
<strong>Crystal Info:</strong> Iridescent frequencies resonating at optimal levels.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PHILOSOPHY -->
|
||||
<section class="mb-3">
|
||||
<h2>Design Philosophy</h2>
|
||||
<div class="card-enchanted">
|
||||
<h3>Prismatic Magic Principles</h3>
|
||||
<ul>
|
||||
<li><strong>Sharp Faerie Edges:</strong> Zero border radius—crystalline precision</li>
|
||||
<li><strong>Animated Prismatic Borders:</strong> Rainbow gradients that flow endlessly</li>
|
||||
<li><strong>Iridescent Glows:</strong> Multiple box-shadows create ethereal depth</li>
|
||||
<li><strong>Shimmer Effects:</strong> Buttons feature diagonal light sweeps</li>
|
||||
<li><strong>Sparkle Decorators:</strong> Animated ✨ on major headings</li>
|
||||
<li><strong>Cormorant + Urbanist:</strong> Elegant serif meets modern sans</li>
|
||||
<li><strong>Five-Color Spectrum:</strong> Violet, pink, cyan, green, gold</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card-prismatic text-center" style="padding: 2rem;">
|
||||
<h2>Faerie Fire Style Complete</h2>
|
||||
<p style="margin-top: 1rem;">Where sharp edges meet liquid light ✨🌈</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,887 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Naughty Little Whispers | Design System Documentation</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,600;1,400&family=Karla:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
NAUGHTY LITTLE WHISPERS DESIGN SYSTEM
|
||||
|
||||
BOLD DISTINCTIVE CHOICE: Hover-Reveal Information Architecture
|
||||
Secondary content exists at 0.15 opacity by default, becoming fully
|
||||
visible only on hover. This creates a "whispering" interaction where
|
||||
information reveals itself playfully when you show interest.
|
||||
|
||||
The technique challenges conventional always-visible UI by treating
|
||||
secondary information as optional enrichment rather than mandatory
|
||||
clutter. Users discover deeper layers of content through curiosity
|
||||
and interaction, creating a more intimate, exploratory experience.
|
||||
|
||||
This approach works because it respects attention as a precious
|
||||
resource. Not everything needs to shout. Some things can whisper.
|
||||
============================================ */
|
||||
|
||||
/* ===== CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== DESIGN TOKENS ===== */
|
||||
:root {
|
||||
/* --- COLOR PALETTE ---
|
||||
Muted, sophisticated neutrals with subtle warm undertones
|
||||
Inspired by aged paper, twilight shadows, and whispered secrets */
|
||||
|
||||
/* Primary neutrals */
|
||||
--paper-white: #fafaf8;
|
||||
--cream: #f5f4f0;
|
||||
--warm-gray-100: #e8e6e0;
|
||||
--warm-gray-200: #d1cfc8;
|
||||
--warm-gray-400: #9c9a91;
|
||||
--warm-gray-600: #6b6960;
|
||||
--warm-gray-800: #3d3c38;
|
||||
--ink: #2a2926;
|
||||
|
||||
/* Accent colors - restrained and sophisticated */
|
||||
--blush: #d4a5a5; /* Gentle pink */
|
||||
--sage: #a8b5a0; /* Muted green */
|
||||
--dusk: #8b8fa8; /* Soft purple */
|
||||
--amber: #c4a572; /* Warm gold */
|
||||
|
||||
/* --- BACKGROUND SYSTEM --- */
|
||||
--bg-page: #fafaf8;
|
||||
--bg-surface: #ffffff;
|
||||
--bg-subtle: rgba(250, 250, 248, 0.6);
|
||||
--bg-whisper: rgba(250, 250, 248, 0.3);
|
||||
|
||||
/* --- OPACITY LAYERS ---
|
||||
The whisper system uses specific opacity values */
|
||||
--opacity-hidden: 0;
|
||||
--opacity-whisper: 0.15; /* Nearly invisible, creates intrigue */
|
||||
--opacity-hint: 0.35; /* Barely there, suggests presence */
|
||||
--opacity-soft: 0.6; /* Gently visible */
|
||||
--opacity-full: 1; /* Fully revealed */
|
||||
|
||||
/* --- BORDER SYSTEM ---
|
||||
Delicate, almost imperceptible borders */
|
||||
--border-whisper: 1px solid rgba(61, 60, 56, 0.08);
|
||||
--border-soft: 1px solid rgba(61, 60, 56, 0.15);
|
||||
--border-visible: 1px solid rgba(61, 60, 56, 0.25);
|
||||
--border-emphasis: 2px solid rgba(61, 60, 56, 0.3);
|
||||
|
||||
/* Border radius for gentle softening */
|
||||
--radius-sm: 3px;
|
||||
--radius-md: 6px;
|
||||
--radius-lg: 10px;
|
||||
|
||||
/* --- SPACING SYSTEM ---
|
||||
Generous breathing room, respecting negative space */
|
||||
--space-2xs: 0.25rem; /* 4px */
|
||||
--space-xs: 0.5rem; /* 8px */
|
||||
--space-sm: 0.75rem; /* 12px */
|
||||
--space-md: 1rem; /* 16px */
|
||||
--space-lg: 1.5rem; /* 24px */
|
||||
--space-xl: 2rem; /* 32px */
|
||||
--space-2xl: 3rem; /* 48px */
|
||||
--space-3xl: 4rem; /* 64px */
|
||||
|
||||
/* --- TYPOGRAPHY SYSTEM ---
|
||||
Lora: Elegant serif for display, adds sophistication
|
||||
Karla: Clean sans-serif for body, highly legible */
|
||||
--font-display: 'Lora', Georgia, serif;
|
||||
--font-body: 'Karla', -apple-system, system-ui, sans-serif;
|
||||
|
||||
/* Type scale */
|
||||
--text-xs: 0.75rem; /* 12px */
|
||||
--text-sm: 0.875rem; /* 14px */
|
||||
--text-base: 1rem; /* 16px */
|
||||
--text-lg: 1.125rem; /* 18px */
|
||||
--text-xl: 1.25rem; /* 20px */
|
||||
--text-2xl: 1.5rem; /* 24px */
|
||||
--text-3xl: 1.875rem; /* 30px */
|
||||
--text-4xl: 2.25rem; /* 36px */
|
||||
--text-5xl: 3rem; /* 48px */
|
||||
|
||||
/* --- TEXT COLORS --- */
|
||||
--text-primary: #2a2926;
|
||||
--text-secondary: #6b6960;
|
||||
--text-tertiary: #9c9a91;
|
||||
--text-inverse: #fafaf8;
|
||||
|
||||
/* --- TRANSITION TIMING ---
|
||||
Smooth, gentle transitions that feel organic */
|
||||
--timing-whisper: 0.4s;
|
||||
--timing-gentle: 0.3s;
|
||||
--timing-quick: 0.2s;
|
||||
--easing: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* ===== BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
line-height: 1.7;
|
||||
color: var(--text-primary);
|
||||
background: var(--bg-page);
|
||||
min-height: 100vh;
|
||||
padding: var(--space-lg);
|
||||
/* Smooth scrolling for gentle navigation */
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* ===== LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: var(--space-lg);
|
||||
margin-bottom: var(--space-xl);
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== TYPOGRAPHY SYSTEM ===== */
|
||||
h1 {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-5xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.1;
|
||||
margin-bottom: var(--space-lg);
|
||||
color: var(--text-primary);
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-4xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
margin-bottom: var(--space-md);
|
||||
color: var(--text-primary);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-3xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
margin-bottom: var(--space-md);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-2xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
margin-bottom: var(--space-sm);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
margin-bottom: var(--space-sm);
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-lg);
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
margin-bottom: var(--space-xs);
|
||||
color: var(--text-tertiary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: var(--space-md);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Emphasis styling */
|
||||
strong {
|
||||
font-weight: 600;
|
||||
color: var(--blush);
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: var(--sage);
|
||||
}
|
||||
|
||||
/* Code styling */
|
||||
code {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: var(--text-sm);
|
||||
background: var(--cream);
|
||||
color: var(--text-secondary);
|
||||
padding: var(--space-2xs) var(--space-xs);
|
||||
border: var(--border-soft);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: var(--text-sm);
|
||||
line-height: 1.6;
|
||||
background: var(--cream);
|
||||
color: var(--text-primary);
|
||||
padding: var(--space-md);
|
||||
border-left: var(--border-emphasis);
|
||||
border-left-color: var(--amber);
|
||||
border-radius: var(--radius-md);
|
||||
overflow-x: auto;
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== DISTINCTIVE CHOICE: WHISPER SYSTEM =====
|
||||
|
||||
The whisper system is the defining characteristic of this design.
|
||||
Secondary information starts nearly invisible (opacity: 0.15) and
|
||||
reveals itself on hover. This creates several benefits:
|
||||
|
||||
1. Reduced visual clutter - only essential information is prominent
|
||||
2. Exploration and discovery - users find deeper content through curiosity
|
||||
3. Attention respect - not everything demands immediate attention
|
||||
4. Playful interaction - hovering feels like sharing secrets
|
||||
|
||||
The key is using opacity rather than display or visibility. Content
|
||||
exists in the layout at all times, preventing reflow, but fades into
|
||||
the background until attention is given. The transition timing is
|
||||
crucial - fast enough to feel responsive, slow enough to feel gentle. */
|
||||
|
||||
.whisper {
|
||||
opacity: var(--opacity-whisper);
|
||||
transition: opacity var(--timing-whisper) var(--easing);
|
||||
}
|
||||
|
||||
.whisper:hover,
|
||||
.whisper:focus {
|
||||
opacity: var(--opacity-full);
|
||||
}
|
||||
|
||||
/* Hint level - slightly more visible for important secondary content */
|
||||
.hint {
|
||||
opacity: var(--opacity-hint);
|
||||
transition: opacity var(--timing-gentle) var(--easing);
|
||||
}
|
||||
|
||||
.hint:hover,
|
||||
.hint:focus {
|
||||
opacity: var(--opacity-full);
|
||||
}
|
||||
|
||||
/* ===== CARD COMPONENTS ===== */
|
||||
.card {
|
||||
background: var(--bg-surface);
|
||||
border: var(--border-soft);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-lg);
|
||||
margin-bottom: var(--space-lg);
|
||||
transition: border-color var(--timing-gentle) var(--easing),
|
||||
box-shadow var(--timing-gentle) var(--easing);
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
border-color: rgba(61, 60, 56, 0.3);
|
||||
box-shadow: 0 2px 12px rgba(61, 60, 56, 0.08);
|
||||
}
|
||||
|
||||
.card-whisper {
|
||||
background: var(--bg-subtle);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-surface);
|
||||
box-shadow: 0 2px 8px rgba(61, 60, 56, 0.06);
|
||||
}
|
||||
|
||||
.card-elevated:hover {
|
||||
box-shadow: 0 4px 16px rgba(61, 60, 56, 0.1);
|
||||
}
|
||||
|
||||
/* Card with whisper content - a common pattern */
|
||||
.card-with-whispers {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-with-whispers .whisper-content {
|
||||
margin-top: var(--space-md);
|
||||
opacity: var(--opacity-whisper);
|
||||
transition: opacity var(--timing-whisper) var(--easing);
|
||||
}
|
||||
|
||||
.card-with-whispers:hover .whisper-content {
|
||||
opacity: var(--opacity-full);
|
||||
}
|
||||
|
||||
/* Accent border variations */
|
||||
.card-accent-blush {
|
||||
border-left: var(--border-emphasis);
|
||||
border-left-color: var(--blush);
|
||||
}
|
||||
|
||||
.card-accent-sage {
|
||||
border-left: var(--border-emphasis);
|
||||
border-left-color: var(--sage);
|
||||
}
|
||||
|
||||
.card-accent-dusk {
|
||||
border-left: var(--border-emphasis);
|
||||
border-left-color: var(--dusk);
|
||||
}
|
||||
|
||||
/* ===== BUTTON SYSTEM ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
font-weight: 500;
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
border: var(--border-visible);
|
||||
border-radius: var(--radius-md);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all var(--timing-gentle) var(--easing);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--text-primary);
|
||||
border-color: var(--text-primary);
|
||||
color: var(--text-inverse);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--warm-gray-800);
|
||||
border-color: var(--warm-gray-800);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(42, 41, 38, 0.15);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: transparent;
|
||||
border-color: var(--warm-gray-400);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--cream);
|
||||
border-color: var(--warm-gray-600);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Button with whisper label - reveals on hover */
|
||||
.btn-with-whisper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.btn-with-whisper .btn-whisper-label {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-0.5rem);
|
||||
font-size: var(--text-xs);
|
||||
color: var(--text-tertiary);
|
||||
white-space: nowrap;
|
||||
opacity: var(--opacity-hidden);
|
||||
transition: opacity var(--timing-gentle) var(--easing),
|
||||
transform var(--timing-gentle) var(--easing);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.btn-with-whisper:hover .btn-whisper-label {
|
||||
opacity: var(--opacity-full);
|
||||
transform: translateX(-50%) translateY(-0.75rem);
|
||||
}
|
||||
|
||||
/* ===== BADGE SYSTEM ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 600;
|
||||
padding: var(--space-2xs) var(--space-sm);
|
||||
border: var(--border-soft);
|
||||
border-radius: var(--radius-sm);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.badge-blush {
|
||||
background: rgba(212, 165, 165, 0.15);
|
||||
border-color: var(--blush);
|
||||
color: var(--blush);
|
||||
}
|
||||
|
||||
.badge-sage {
|
||||
background: rgba(168, 181, 160, 0.15);
|
||||
border-color: var(--sage);
|
||||
color: var(--sage);
|
||||
}
|
||||
|
||||
.badge-dusk {
|
||||
background: rgba(139, 143, 168, 0.15);
|
||||
border-color: var(--dusk);
|
||||
color: var(--dusk);
|
||||
}
|
||||
|
||||
/* ===== TABLE SYSTEM ===== */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: var(--text-sm);
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
border-bottom: var(--border-emphasis);
|
||||
border-bottom-color: var(--amber);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
border-bottom: var(--border-whisper);
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Whisper columns in tables */
|
||||
.whisper-col {
|
||||
opacity: var(--opacity-whisper);
|
||||
transition: opacity var(--timing-whisper) var(--easing);
|
||||
}
|
||||
|
||||
tr:hover .whisper-col {
|
||||
opacity: var(--opacity-full);
|
||||
}
|
||||
|
||||
/* ===== ALERT SYSTEM ===== */
|
||||
.alert {
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
border-left: var(--border-emphasis);
|
||||
border-radius: var(--radius-md);
|
||||
margin-bottom: var(--space-lg);
|
||||
background: var(--cream);
|
||||
}
|
||||
|
||||
.alert-whisper {
|
||||
border-color: var(--warm-gray-400);
|
||||
}
|
||||
|
||||
.alert-blush {
|
||||
border-color: var(--blush);
|
||||
background: rgba(212, 165, 165, 0.08);
|
||||
}
|
||||
|
||||
.alert-sage {
|
||||
border-color: var(--sage);
|
||||
background: rgba(168, 181, 160, 0.08);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.text-secondary { color: var(--text-secondary); }
|
||||
.text-tertiary { color: var(--text-tertiary); }
|
||||
.mt-sm { margin-top: var(--space-sm); }
|
||||
.mt-md { margin-top: var(--space-md); }
|
||||
.mt-lg { margin-top: var(--space-lg); }
|
||||
.mb-md { margin-bottom: var(--space-md); }
|
||||
.mb-lg { margin-bottom: var(--space-lg); }
|
||||
|
||||
/* ===== HORIZONTAL DIVIDER ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: linear-gradient(to right,
|
||||
transparent,
|
||||
var(--warm-gray-200),
|
||||
transparent);
|
||||
margin: var(--space-2xl) 0;
|
||||
}
|
||||
|
||||
/* ===== DOCUMENTATION-SPECIFIC STYLES ===== */
|
||||
.opacity-demo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-lg);
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
.opacity-sample {
|
||||
flex: 1;
|
||||
padding: var(--space-lg);
|
||||
background: var(--bg-surface);
|
||||
border: var(--border-soft);
|
||||
border-radius: var(--radius-md);
|
||||
text-align: center;
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-2xl);
|
||||
transition: opacity var(--timing-whisper) var(--easing);
|
||||
}
|
||||
|
||||
.color-swatch {
|
||||
width: 100%;
|
||||
aspect-ratio: 4/3;
|
||||
border: var(--border-soft);
|
||||
border-radius: var(--radius-md);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
.color-code {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: var(--text-xs);
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: var(--space-2xs) var(--space-xs);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.interactive-demo {
|
||||
background: var(--cream);
|
||||
padding: var(--space-xl);
|
||||
border-radius: var(--radius-lg);
|
||||
margin: var(--space-lg) 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.demo-card {
|
||||
max-width: 400px;
|
||||
margin: var(--space-lg) auto 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-lg">
|
||||
<h1>Naughty Little Whispers</h1>
|
||||
<p style="font-size: var(--text-xl); color: var(--text-secondary);">
|
||||
A design system where information reveals itself playfully through interaction
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- DISTINCTIVE CHOICE EXPLANATION -->
|
||||
<section class="mb-lg">
|
||||
<div class="card-elevated">
|
||||
<h2>Distinctive Choice: Hover-Reveal Information Architecture</h2>
|
||||
|
||||
<p>This design system makes one bold, distinctive choice that governs how information is presented and discovered. Rather than displaying everything at once, we use <strong>opacity-based hover-reveal interactions</strong> where secondary content begins nearly invisible and whispers into view when you show interest through hovering or focus.</p>
|
||||
|
||||
<p>This approach challenges the conventional wisdom that all interface content must be immediately and equally visible. Instead, it treats secondary information as optional enrichment rather than mandatory clutter. The result is interfaces that feel lighter, less overwhelming, and more intimate. Content reveals itself gradually, like secrets shared between friends.</p>
|
||||
|
||||
<h3 class="mt-lg">The Philosophy of Whispering</h3>
|
||||
|
||||
<p>Not every piece of information deserves equal attention. When everything shouts, nothing is heard. The whisper system creates hierarchy through selective visibility. Primary content is always fully visible because it is essential for understanding. Secondary content—supplementary details, contextual information, helpful hints—exists at fifteen percent opacity, creating visual texture without demanding attention.</p>
|
||||
|
||||
<p>This technique respects attention as a precious resource. Users decide what they want to explore more deeply by hovering over areas of interest. The interaction feels like leaning in to hear something said softly rather than being shouted at from all directions. It creates a more thoughtful, intentional relationship between interface and user.</p>
|
||||
|
||||
<p>The psychology behind this approach draws from several principles. First, <em>curiosity drives engagement</em>. When something is partially visible but not fully revealed, people want to discover what it says. Second, <em>progressive disclosure reduces cognitive load</em>. By hiding complexity until needed, we keep interfaces feeling simple while retaining depth for those who seek it. Third, <em>rewards feel better when earned</em>. The small act of hovering creates a micro-moment of discovery that feels satisfying.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- WHISPER SYSTEM DEMONSTRATION -->
|
||||
<section class="mb-lg">
|
||||
<h2>The Whisper System in Action</h2>
|
||||
|
||||
<div class="card">
|
||||
<h3>Opacity Levels</h3>
|
||||
<p class="mb-lg">The system uses specific opacity values to create different levels of visibility. Each level serves a specific purpose in the information hierarchy. Try hovering over the samples below to see them fully reveal.</p>
|
||||
|
||||
<div class="opacity-demo">
|
||||
<div class="opacity-sample whisper">Whisper (0.15)</div>
|
||||
<div class="opacity-sample hint">Hint (0.35)</div>
|
||||
<div class="opacity-sample" style="opacity: 0.6;">Soft (0.6)</div>
|
||||
<div class="opacity-sample" style="opacity: 1;">Full (1.0)</div>
|
||||
</div>
|
||||
|
||||
<p style="font-size: var(--text-sm); color: var(--text-tertiary);" class="mt-md">
|
||||
The transition timing is set to 0.4 seconds with an easing function that feels organic. This timing is fast enough to feel responsive but slow enough that the reveal feels gentle rather than abrupt.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="interactive-demo mt-lg">
|
||||
<h3 style="color: var(--text-secondary);">Try It: Hover to Reveal</h3>
|
||||
<p class="mb-md text-secondary">This card contains whispered secondary information. Move your cursor over it to discover what it says.</p>
|
||||
|
||||
<div class="card-with-whispers demo-card">
|
||||
<h4>Primary Content</h4>
|
||||
<p>This text is always visible because it is essential information. Everyone needs to see this.</p>
|
||||
|
||||
<div class="whisper-content">
|
||||
<hr style="margin: var(--space-md) 0;">
|
||||
<h5>Secondary Details</h5>
|
||||
<p style="font-size: var(--text-sm);">This information only appears when you hover over the card. It provides additional context without cluttering the initial view. This is perfect for technical specifications, extended descriptions, or helpful hints that not everyone needs.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-lg card-accent-blush">
|
||||
<h3>Implementation Approach</h3>
|
||||
<p class="mb-md">The whisper effect is implemented using CSS opacity and transitions. Unlike display or visibility changes, opacity-based hiding keeps content in the layout, preventing jarring reflows when revealed. The content exists but fades into the background, creating texture without noise.</p>
|
||||
|
||||
<pre><code>/* Basic whisper pattern */
|
||||
.whisper {
|
||||
opacity: 0.15;
|
||||
transition: opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.whisper:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Card that reveals whispered content on hover */
|
||||
.card-with-whispers .whisper-content {
|
||||
opacity: 0.15;
|
||||
transition: opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.card-with-whispers:hover .whisper-content {
|
||||
opacity: 1;
|
||||
}</code></pre>
|
||||
|
||||
<p class="mt-md">The key is using a parent hover state to reveal child content. This creates a generous interaction area where any hover over the card triggers the reveal, rather than requiring precise cursor placement over the whispered text itself.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- COLOR SYSTEM -->
|
||||
<section class="mb-lg">
|
||||
<h2>Color Palette</h2>
|
||||
|
||||
<div class="card">
|
||||
<p class="mb-md">The color system uses muted, sophisticated neutrals with warm undertones. The palette evokes aged paper, twilight shadows, and intimate conversations. Accent colors are restrained, providing gentle emphasis without demanding attention. Everything supports the whispering aesthetic—subtle, refined, inviting closer inspection.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-4 mt-lg">
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #fafaf8;">
|
||||
<span class="color-code">#fafaf8</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-tertiary);">Paper White</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #d4a5a5;">
|
||||
<span class="color-code">#d4a5a5</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-tertiary);">Blush</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #a8b5a0;">
|
||||
<span class="color-code">#a8b5a0</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-tertiary);">Sage</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #8b8fa8;">
|
||||
<span class="color-code">#8b8fa8</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-tertiary);">Dusk</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #c4a572;">
|
||||
<span class="color-code">#c4a572</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-tertiary);">Amber</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #9c9a91;">
|
||||
<span class="color-code">#9c9a91</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-tertiary);">Warm Gray 400</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #6b6960;">
|
||||
<span class="color-code">#6b6960</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-tertiary);">Warm Gray 600</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="color-swatch" style="background: #2a2926;">
|
||||
<span class="color-code">#2a2926</span>
|
||||
<span style="font-size: var(--text-xs); color: var(--text-inverse);">Ink</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- COMPONENT EXAMPLES -->
|
||||
<section class="mb-lg">
|
||||
<h2>Component Library</h2>
|
||||
|
||||
<div class="grid grid-2">
|
||||
<div class="card card-accent-sage">
|
||||
<h3>Interactive Elements</h3>
|
||||
<div class="btn-with-whisper">
|
||||
<button class="btn btn-primary">Primary Action</button>
|
||||
<span class="btn-whisper-label">Hover to see me whisper</span>
|
||||
</div>
|
||||
<button class="btn btn-secondary mt-md">Secondary Action</button>
|
||||
<p class="mt-lg text-secondary" style="font-size: var(--text-sm);">
|
||||
Buttons can have whispered labels that appear on hover, providing additional context without visual clutter in the default state.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-accent-dusk">
|
||||
<h3>Status Indicators</h3>
|
||||
<span class="badge badge-blush">Subtle</span>
|
||||
<span class="badge badge-sage">Gentle</span>
|
||||
<span class="badge badge-dusk">Whispered</span>
|
||||
<p class="mt-lg text-secondary" style="font-size: var(--text-sm);">
|
||||
Badges use muted colors that complement rather than compete with primary content.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-lg">
|
||||
<h3>Tables with Whispered Columns</h3>
|
||||
<p class="mb-md">Tables can use the whisper system for supplementary data columns. Hover over any row to reveal additional information.</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Primary Data</th>
|
||||
<th>Always Visible</th>
|
||||
<th class="whisper-col">Whispered Detail</th>
|
||||
<th class="whisper-col">Optional Context</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Essential info</td>
|
||||
<td>Important value</td>
|
||||
<td class="whisper-col">Hover to see</td>
|
||||
<td class="whisper-col">More details here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Core content</td>
|
||||
<td>Key metric</td>
|
||||
<td class="whisper-col">Secondary data</td>
|
||||
<td class="whisper-col">Supplementary info</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Main point</td>
|
||||
<td>Primary stat</td>
|
||||
<td class="whisper-col">Extra context</td>
|
||||
<td class="whisper-col">Technical detail</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p style="font-size: var(--text-sm); color: var(--text-tertiary);">
|
||||
This pattern works well for data tables where some columns contain important but not critical information. The whispered columns create visual hierarchy without removing data from the interface.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- IMPLEMENTATION GUIDE -->
|
||||
<section class="mb-lg">
|
||||
<h2>Implementation Guide</h2>
|
||||
|
||||
<div class="card-elevated">
|
||||
<h3>When to Use Whispers</h3>
|
||||
|
||||
<p>The whisper system works best when applied thoughtfully. Not every piece of secondary information should be hidden. The technique is most effective for content that fits these criteria. First, the information is helpful but not essential for all users. Second, revealing it does not cause significant layout shifts. Third, users can easily discover it through natural interaction patterns like hovering over relevant areas.</p>
|
||||
|
||||
<h4 class="mt-lg">Ideal Use Cases</h4>
|
||||
|
||||
<p>Consider using whispers for supplementary details that enrich understanding but are not required for basic comprehension. Technical specifications often fall into this category. A product listing might show the name, price, and main feature prominently, while whispering the detailed specifications, dimensions, and warranty information. Users interested in those details will naturally hover to read more, while others are not overwhelmed by information they do not need.</p>
|
||||
|
||||
<p>Contextual help represents another strong use case. Imagine a form where field labels are always visible, but explanatory text about what to enter or why the information is needed whispers into view on focus or hover. This keeps the form feeling light and approachable while providing guidance exactly when users need it.</p>
|
||||
|
||||
<p>Metadata and timestamps benefit from the whisper treatment. In a content feed, the main text and author might be prominent while the publication date, category tags, and edit history whisper into view on hover. This creates cleaner initial layouts while making supplementary information discoverable.</p>
|
||||
|
||||
<h4 class="mt-lg">When Not to Whisper</h4>
|
||||
|
||||
<p>Avoid using whispers for critical information that every user must see. Error messages, required form validation feedback, and key calls to action should be fully visible. The whisper technique is about progressive disclosure of helpful supplementary content, not hiding necessary information.</p>
|
||||
|
||||
<p>Similarly, primary navigation should not whisper. Users expect navigation to be immediately obvious. While you might whisper secondary navigation items or additional options within a menu, the main pathways through your interface should be clear and prominent.</p>
|
||||
|
||||
<p>Touch interfaces require special consideration. Hover interactions do not translate to touch, so whispered content must have an alternative reveal method such as tapping or focus states. Consider whether the content should be fully visible on mobile devices where hover is not available.</p>
|
||||
</div>
|
||||
|
||||
<div class="card mt-lg card-accent-blush">
|
||||
<h3>Design Principles</h3>
|
||||
|
||||
<p>Beyond the whisper system, several principles guide this design approach and contribute to its refined character. Understanding these principles helps you maintain consistency when extending the system.</p>
|
||||
|
||||
<p><strong>Generous spacing:</strong> White space is not wasted space. The system uses ample padding and margins to create breathing room. When content is not crowded, each element can be appreciated individually. The generous spacing also provides larger hover targets for revealing whispered content.</p>
|
||||
|
||||
<p><strong>Typographic sophistication:</strong> The pairing of Lora and Karla creates contrast between display and body text. Lora brings elegance and personality to headings with its refined serifs. Karla provides excellent readability for body text with clean, geometric forms. The combination feels both classic and contemporary.</p>
|
||||
|
||||
<p><strong>Restrained color:</strong> The palette stays in the warm neutral family, avoiding bright or saturated colors. This restraint creates sophistication and ensures that when accent colors do appear, they carry weight. Color becomes meaningful rather than decorative.</p>
|
||||
|
||||
<p><strong>Gentle interactions:</strong> All animations use slow timing and gentle easing. Nothing snaps or jerks. Transitions feel organic, as if content is naturally flowing into view rather than being mechanically revealed. This creates an interface that feels responsive yet calm.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ALERTS DEMONSTRATION -->
|
||||
<section class="mb-lg">
|
||||
<h2>Alert Components</h2>
|
||||
|
||||
<div class="alert-whisper">
|
||||
<strong>Notice:</strong> Standard alerts use gentle borders and muted backgrounds, drawing attention without alarm. They fit naturally into the restrained aesthetic.
|
||||
</div>
|
||||
|
||||
<div class="alert-blush mt-md">
|
||||
<strong>Important:</strong> When something requires more attention, accent-colored borders provide emphasis while maintaining the system's soft, approachable character.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card-elevated text-center" style="padding: var(--space-2xl);">
|
||||
<h2>Naughty Little Whispers</h2>
|
||||
<p class="mt-md text-secondary">
|
||||
Where information reveals itself through gentle curiosity
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,835 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Prismatic Storm Dragon | Design System Documentation</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=Work+Sans:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
PRISMATIC STORM DRAGON DESIGN SYSTEM
|
||||
|
||||
BOLD DISTINCTIVE CHOICE: Multi-Layer Chromatic Depth
|
||||
Cards use stacked translucent borders in complementary colors
|
||||
creating a chromatic aberration effect that simulates depth and power.
|
||||
|
||||
This technique layers multiple box-shadows in split-complementary
|
||||
colors (violet-red-cyan-gold), creating visual weight and drama
|
||||
without traditional drop shadows. It evokes the prismatic refraction
|
||||
of light through storm clouds and the iridescent scales of mythical
|
||||
dragons—powerful, layered, elemental.
|
||||
============================================ */
|
||||
|
||||
/* ===== CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== DESIGN TOKENS ===== */
|
||||
:root {
|
||||
/* --- CHROMATIC PALETTE ---
|
||||
Split-complementary scheme: Violet (primary), Red-Orange & Cyan (complements)
|
||||
Gold as accent. Each color exists in multiple tonal steps for layering. */
|
||||
|
||||
/* Violet family - primary power */
|
||||
--violet-100: #e9d5ff;
|
||||
--violet-300: #c084fc;
|
||||
--violet-500: #a855f7;
|
||||
--violet-700: #7e22ce;
|
||||
--violet-900: #4a1772;
|
||||
|
||||
/* Red-Orange family - heat, intensity */
|
||||
--red-100: #ffe4e6;
|
||||
--red-300: #fda4af;
|
||||
--red-500: #f43f5e;
|
||||
--red-700: #be123c;
|
||||
--red-900: #881337;
|
||||
|
||||
/* Cyan family - cool energy */
|
||||
--cyan-100: #cffafe;
|
||||
--cyan-300: #67e8f9;
|
||||
--cyan-500: #06b6d4;
|
||||
--cyan-700: #0e7490;
|
||||
--cyan-900: #164e63;
|
||||
|
||||
/* Gold family - prismatic accent */
|
||||
--gold-100: #fef3c7;
|
||||
--gold-300: #fcd34d;
|
||||
--gold-500: #eab308;
|
||||
--gold-700: #a16207;
|
||||
--gold-900: #713f12;
|
||||
|
||||
/* Neutral palette */
|
||||
--gray-50: #fafafa;
|
||||
--gray-100: #f4f4f5;
|
||||
--gray-200: #e4e4e7;
|
||||
--gray-300: #d4d4d8;
|
||||
--gray-700: #3f3f46;
|
||||
--gray-800: #27272a;
|
||||
--gray-900: #18181b;
|
||||
|
||||
/* --- BACKGROUND SYSTEM ---
|
||||
Dark, stormy, atmospheric */
|
||||
--bg-gradient-1: #18181b; /* Deep storm */
|
||||
--bg-gradient-2: #27272a; /* Storm cloud */
|
||||
--bg-gradient-3: #2d2438; /* Purple storm */
|
||||
--bg-gradient-4: #382f44; /* Lightning horizon */
|
||||
|
||||
/* Surface colors */
|
||||
--bg-surface: rgba(250, 250, 250, 0.03);
|
||||
--bg-elevated: rgba(250, 250, 250, 0.06);
|
||||
--bg-high: rgba(250, 250, 250, 0.10);
|
||||
--bg-solid-light: #fafafa;
|
||||
|
||||
/* --- BORDER & RADIUS ---
|
||||
Slightly rounded for organic, dragon-scale feel */
|
||||
--border-width: 1px;
|
||||
--border-width-emphasis: 2px;
|
||||
--radius-sm: 4px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
|
||||
/* --- SPACING SYSTEM ---
|
||||
T-shirt sizes for intuitive spacing */
|
||||
--space-xs: 0.5rem; /* 8px */
|
||||
--space-sm: 0.75rem; /* 12px */
|
||||
--space-md: 1rem; /* 16px */
|
||||
--space-lg: 1.5rem; /* 24px */
|
||||
--space-xl: 2rem; /* 32px */
|
||||
--space-2xl: 3rem; /* 48px */
|
||||
--space-3xl: 4rem; /* 64px */
|
||||
|
||||
/* --- TYPOGRAPHY ---
|
||||
Crimson Pro: Elegant, powerful serifs for display
|
||||
Work Sans: Clean geometric sans for body */
|
||||
--font-display: 'Crimson Pro', Georgia, serif;
|
||||
--font-body: 'Work Sans', system-ui, sans-serif;
|
||||
|
||||
/* Type scale */
|
||||
--text-xs: 0.75rem; /* 12px */
|
||||
--text-sm: 0.875rem; /* 14px */
|
||||
--text-base: 1rem; /* 16px */
|
||||
--text-lg: 1.125rem; /* 18px */
|
||||
--text-xl: 1.25rem; /* 20px */
|
||||
--text-2xl: 1.5rem; /* 24px */
|
||||
--text-3xl: 1.875rem; /* 30px */
|
||||
--text-4xl: 2.25rem; /* 36px */
|
||||
--text-5xl: 3rem; /* 48px */
|
||||
|
||||
/* --- TEXT COLORS --- */
|
||||
--text-primary: #fafafa;
|
||||
--text-secondary: #d4d4d8;
|
||||
--text-tertiary: #a1a1aa;
|
||||
--text-inverse: #18181b;
|
||||
}
|
||||
|
||||
/* ===== BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
line-height: 1.6;
|
||||
color: var(--text-primary);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
min-height: 100vh;
|
||||
padding: var(--space-lg);
|
||||
}
|
||||
|
||||
/* ===== LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: var(--space-lg);
|
||||
margin-bottom: var(--space-xl);
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== TYPOGRAPHY SYSTEM ===== */
|
||||
h1 {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-5xl);
|
||||
font-weight: 700;
|
||||
line-height: 1.1;
|
||||
margin-bottom: var(--space-lg);
|
||||
color: var(--violet-300);
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-4xl);
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
margin-bottom: var(--space-md);
|
||||
color: var(--violet-300);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-3xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
margin-bottom: var(--space-md);
|
||||
color: var(--cyan-300);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-2xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
margin-bottom: var(--space-sm);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
margin-bottom: var(--space-sm);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-lg);
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
margin-bottom: var(--space-sm);
|
||||
color: var(--text-tertiary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: var(--space-md);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
color: var(--gold-300);
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: var(--cyan-300);
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: var(--text-sm);
|
||||
background: var(--bg-elevated);
|
||||
color: var(--cyan-300);
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
border: var(--border-width) solid var(--cyan-700);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: var(--text-sm);
|
||||
line-height: 1.6;
|
||||
background: var(--bg-surface);
|
||||
color: var(--text-primary);
|
||||
padding: var(--space-md);
|
||||
border-left: var(--border-width-emphasis) solid var(--violet-500);
|
||||
border-radius: var(--radius-md);
|
||||
overflow-x: auto;
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== DISTINCTIVE CHOICE: CHROMATIC DEPTH SYSTEM =====
|
||||
|
||||
This is the defining feature of the design system. Rather than using
|
||||
traditional drop shadows, we create depth through layered box-shadows
|
||||
in complementary colors. This achieves two goals:
|
||||
|
||||
1. Visual depth and elevation without the flatness of standard shadows
|
||||
2. A chromatic aberration effect that suggests power, energy, and movement
|
||||
|
||||
The technique works by stacking multiple colored shadows with slight
|
||||
offsets. The colors come from our split-complementary palette, creating
|
||||
a prismatic halo that feels both technical (like RGB pixel shifting)
|
||||
and organic (like iridescent dragon scales).
|
||||
|
||||
The effect is subtle but powerful. It catches the eye without being
|
||||
distracting, and creates visual interest that pure gray shadows cannot. */
|
||||
|
||||
.card {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(8px);
|
||||
border: var(--border-width) solid rgba(192, 132, 252, 0.2);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-lg);
|
||||
margin-bottom: var(--space-lg);
|
||||
|
||||
/* The chromatic depth effect: layered colored shadows */
|
||||
box-shadow:
|
||||
0 0 0 1px var(--violet-900), /* Inner glow */
|
||||
1px 1px 0 var(--red-900), /* Red shift */
|
||||
-1px -1px 0 var(--cyan-900), /* Cyan shift */
|
||||
2px 4px 8px rgba(168, 85, 247, 0.15), /* Violet depth */
|
||||
-2px -2px 6px rgba(6, 182, 212, 0.1); /* Cyan ambient */
|
||||
}
|
||||
|
||||
/* Elevated cards have stronger chromatic effect */
|
||||
.card-elevated {
|
||||
background: var(--bg-high);
|
||||
box-shadow:
|
||||
0 0 0 1px var(--violet-700),
|
||||
2px 2px 0 var(--red-700),
|
||||
-2px -2px 0 var(--cyan-700),
|
||||
4px 8px 16px rgba(168, 85, 247, 0.25),
|
||||
-4px -4px 12px rgba(6, 182, 212, 0.15),
|
||||
0 12px 24px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
/* Powerful cards emphasize the effect */
|
||||
.card-powerful {
|
||||
background: var(--bg-high);
|
||||
border: var(--border-width-emphasis) solid rgba(192, 132, 252, 0.4);
|
||||
box-shadow:
|
||||
0 0 0 2px var(--violet-500),
|
||||
3px 3px 0 var(--red-500),
|
||||
-3px -3px 0 var(--cyan-500),
|
||||
6px 12px 24px rgba(168, 85, 247, 0.4),
|
||||
-6px -6px 18px rgba(6, 182, 212, 0.25),
|
||||
0 16px 32px rgba(0, 0, 0, 0.5);
|
||||
|
||||
/* Subtle pulse animation - simple but effective */
|
||||
animation: power-pulse 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes power-pulse {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
0 0 0 2px var(--violet-500),
|
||||
3px 3px 0 var(--red-500),
|
||||
-3px -3px 0 var(--cyan-500),
|
||||
6px 12px 24px rgba(168, 85, 247, 0.4),
|
||||
-6px -6px 18px rgba(6, 182, 212, 0.25),
|
||||
0 16px 32px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
0 0 0 2px var(--violet-500),
|
||||
4px 4px 0 var(--red-500),
|
||||
-4px -4px 0 var(--cyan-500),
|
||||
8px 16px 28px rgba(168, 85, 247, 0.5),
|
||||
-8px -8px 22px rgba(6, 182, 212, 0.3),
|
||||
0 20px 40px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.card-light {
|
||||
background: var(--bg-solid-light);
|
||||
color: var(--text-inverse);
|
||||
border: var(--border-width) solid var(--gray-200);
|
||||
box-shadow:
|
||||
0 0 0 1px var(--gray-200),
|
||||
2px 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-light h2,
|
||||
.card-light h3,
|
||||
.card-light h4,
|
||||
.card-light h5,
|
||||
.card-light h6 {
|
||||
color: var(--violet-700);
|
||||
}
|
||||
|
||||
.card-light p,
|
||||
.card-light li {
|
||||
color: var(--gray-700);
|
||||
}
|
||||
|
||||
/* ===== BUTTON SYSTEM ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
font-weight: 500;
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
border: var(--border-width-emphasis) solid;
|
||||
border-radius: var(--radius-md);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-violet {
|
||||
background: var(--violet-500);
|
||||
border-color: var(--violet-700);
|
||||
color: white;
|
||||
box-shadow:
|
||||
1px 1px 0 var(--red-700),
|
||||
-1px -1px 0 var(--cyan-700),
|
||||
2px 4px 8px rgba(168, 85, 247, 0.4);
|
||||
}
|
||||
|
||||
.btn-violet:hover {
|
||||
box-shadow:
|
||||
2px 2px 0 var(--red-600),
|
||||
-2px -2px 0 var(--cyan-600),
|
||||
4px 8px 16px rgba(168, 85, 247, 0.5);
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
border-color: var(--cyan-500);
|
||||
color: var(--cyan-300);
|
||||
}
|
||||
|
||||
.btn-outline:hover {
|
||||
background: rgba(6, 182, 212, 0.1);
|
||||
box-shadow: 0 4px 12px rgba(6, 182, 212, 0.3);
|
||||
}
|
||||
|
||||
/* ===== BADGE SYSTEM ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 600;
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
border: var(--border-width) solid;
|
||||
border-radius: var(--radius-sm);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.badge-violet {
|
||||
background: rgba(168, 85, 247, 0.15);
|
||||
border-color: var(--violet-500);
|
||||
color: var(--violet-300);
|
||||
}
|
||||
|
||||
.badge-cyan {
|
||||
background: rgba(6, 182, 212, 0.15);
|
||||
border-color: var(--cyan-500);
|
||||
color: var(--cyan-300);
|
||||
}
|
||||
|
||||
.badge-gold {
|
||||
background: rgba(234, 179, 8, 0.15);
|
||||
border-color: var(--gold-500);
|
||||
color: var(--gold-300);
|
||||
}
|
||||
|
||||
/* ===== TABLE SYSTEM ===== */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: var(--text-sm);
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
border-bottom: var(--border-width-emphasis) solid var(--violet-500);
|
||||
color: var(--violet-300);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
border-bottom: var(--border-width) solid rgba(192, 132, 252, 0.2);
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* ===== ALERT SYSTEM ===== */
|
||||
.alert {
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
border-left: var(--border-width-emphasis) solid;
|
||||
border-radius: var(--radius-md);
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: rgba(6, 182, 212, 0.1);
|
||||
border-color: var(--cyan-500);
|
||||
box-shadow:
|
||||
1px 1px 0 var(--cyan-700),
|
||||
2px 4px 8px rgba(6, 182, 212, 0.2);
|
||||
}
|
||||
|
||||
.alert-power {
|
||||
background: rgba(168, 85, 247, 0.1);
|
||||
border-color: var(--violet-500);
|
||||
box-shadow:
|
||||
1px 1px 0 var(--red-700),
|
||||
-1px -1px 0 var(--cyan-700),
|
||||
2px 4px 8px rgba(168, 85, 247, 0.3);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.mt-md { margin-top: var(--space-md); }
|
||||
.mt-lg { margin-top: var(--space-lg); }
|
||||
.mb-md { margin-bottom: var(--space-md); }
|
||||
.mb-lg { margin-bottom: var(--space-lg); }
|
||||
|
||||
/* ===== HORIZONTAL DIVIDER ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: linear-gradient(to right,
|
||||
transparent,
|
||||
var(--violet-500),
|
||||
var(--cyan-500),
|
||||
transparent);
|
||||
margin: var(--space-2xl) 0;
|
||||
}
|
||||
|
||||
/* ===== DOCUMENTATION STYLES ===== */
|
||||
.color-demo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-md);
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
.color-swatch {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: var(--border-width) solid rgba(192, 132, 252, 0.3);
|
||||
border-radius: var(--radius-md);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.depth-demo {
|
||||
height: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-2xl);
|
||||
font-weight: 700;
|
||||
border-radius: var(--radius-lg);
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-lg">
|
||||
<h1>Prismatic Storm Dragon</h1>
|
||||
<p style="font-size: var(--text-xl); color: var(--text-secondary);">
|
||||
A design system where depth emerges from chromatic light
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- DISTINCTIVE CHOICE EXPLANATION -->
|
||||
<section class="mb-lg">
|
||||
<div class="card-powerful">
|
||||
<h2>Distinctive Choice: Multi-Layer Chromatic Depth</h2>
|
||||
|
||||
<p>This design system makes one bold distinctive choice that defines its visual character. Rather than creating depth through traditional gray drop shadows, we use <strong>multi-layer chromatic depth</strong>. This technique stacks multiple colored box-shadows in complementary hues, creating a prismatic effect that suggests both technical precision and elemental power.</p>
|
||||
|
||||
<p>The approach draws from split-complementary color theory. Our primary color is violet, positioned at approximately 270 degrees on the color wheel. The split complements are red-orange (at approximately 30 degrees) and cyan (at approximately 180 degrees). When these colors layer with slight offsets, they create a chromatic aberration effect similar to what you might see in optical phenomena like light refracting through storm clouds or shimmering across dragon scales.</p>
|
||||
|
||||
<h3 class="mt-lg">The Psychology of Layered Color</h3>
|
||||
|
||||
<p>Traditional drop shadows use neutral gray or black with transparency, creating depth through luminosity alone. This works effectively but feels flat and utilitarian. Chromatic depth adds another dimension by introducing color relationships. The violet-red-cyan trinity creates visual tension and harmony simultaneously. Violet and cyan are cool colors that recede visually, while red-orange advances, creating a push-pull effect that makes surfaces feel more dimensional.</p>
|
||||
|
||||
<p>The effect also carries symbolic weight. Prismatic light has been associated with power and magic across cultures, from rainbow serpents in indigenous Australian mythology to the aurora borealis in northern European folklore. Dragons, traditionally depicted with iridescent scales that shift in color, embody this prismatic quality. By building this chromatic layering into the core design system, we create an aesthetic that feels both modern and mythologically resonant.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CHROMATIC DEPTH DEMONSTRATION -->
|
||||
<section class="mb-lg">
|
||||
<h2>The Chromatic System in Action</h2>
|
||||
|
||||
<div class="grid grid-3">
|
||||
<div class="card">
|
||||
<div class="depth-demo" style="
|
||||
background: var(--bg-elevated);
|
||||
border: var(--border-width) solid rgba(192, 132, 252, 0.2);
|
||||
box-shadow:
|
||||
0 0 0 1px var(--violet-900),
|
||||
1px 1px 0 var(--red-900),
|
||||
-1px -1px 0 var(--cyan-900),
|
||||
2px 4px 8px rgba(168, 85, 247, 0.15),
|
||||
-2px -2px 6px rgba(6, 182, 212, 0.1);
|
||||
">Standard</div>
|
||||
<p style="font-size: var(--text-sm); color: var(--text-secondary);">
|
||||
Basic cards use subtle chromatic layers. Notice the slight red shift to the bottom-right and cyan shift to the top-left, creating gentle dimensionality.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="depth-demo" style="
|
||||
background: var(--bg-high);
|
||||
border: var(--border-width) solid rgba(192, 132, 252, 0.3);
|
||||
box-shadow:
|
||||
0 0 0 1px var(--violet-700),
|
||||
2px 2px 0 var(--red-700),
|
||||
-2px -2px 0 var(--cyan-700),
|
||||
4px 8px 16px rgba(168, 85, 247, 0.25),
|
||||
-4px -4px 12px rgba(6, 182, 212, 0.15),
|
||||
0 12px 24px rgba(0, 0, 0, 0.4);
|
||||
">Elevated</div>
|
||||
<p style="font-size: var(--text-sm); color: var(--text-secondary);">
|
||||
Elevated cards intensify the effect with larger offsets and more saturated colors, creating stronger separation from the background.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="depth-demo card-powerful" style="
|
||||
background: var(--bg-high);
|
||||
margin-bottom: 0;
|
||||
">Powerful</div>
|
||||
<p style="font-size: var(--text-sm); color: var(--text-secondary);">
|
||||
Powerful cards maximize the chromatic effect and add a subtle breathing animation, suggesting contained energy. Watch it pulse.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-lg">
|
||||
<h3>Technical Implementation</h3>
|
||||
<p class="mb-md">The chromatic depth effect is achieved through carefully ordered box-shadows. Each shadow serves a specific purpose in building the overall effect. Understanding the layering helps you implement and customize the technique.</p>
|
||||
|
||||
<pre><code>/* Chromatic depth anatomy */
|
||||
box-shadow:
|
||||
/* Inner glow: defines the object's edge */
|
||||
0 0 0 1px var(--violet-900),
|
||||
|
||||
/* Color shifts: create the prismatic effect */
|
||||
1px 1px 0 var(--red-900), /* Red shifts down-right */
|
||||
-1px -1px 0 var(--cyan-900), /* Cyan shifts up-left */
|
||||
|
||||
/* Colored diffusion: depth and atmosphere */
|
||||
2px 4px 8px rgba(168, 85, 247, 0.15), /* Violet depth */
|
||||
-2px -2px 6px rgba(6, 182, 212, 0.1); /* Cyan ambient light */</code></pre>
|
||||
|
||||
<p class="mt-md">The order matters significantly. Shadows are rendered from last to first in the list, meaning the bottom shadow appears on top. We start with the inner glow to define edges, then add the chromatic shifts, and finally layer the diffused colored shadows that create ambient atmosphere.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- COLOR SYSTEM -->
|
||||
<section class="mb-lg">
|
||||
<h2>Color Palette</h2>
|
||||
|
||||
<div class="card">
|
||||
<p class="mb-md">The color system is built on split-complementary harmony. Violet serves as the primary power color, anchoring the palette. Red-orange and cyan split the complement, creating dynamic tension. Gold adds warmth and emphasizes important elements without fighting for attention.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2 mt-lg">
|
||||
<div class="card">
|
||||
<h4>Violet Family</h4>
|
||||
<div class="color-demo">
|
||||
<div class="color-swatch" style="background: #c084fc;"></div>
|
||||
<div>
|
||||
<h5>Violet 300</h5>
|
||||
<code>#c084fc</code>
|
||||
<p style="font-size: var(--text-sm); margin-top: var(--space-xs);">Primary headings, key interactions</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-demo">
|
||||
<div class="color-swatch" style="background: #a855f7;"></div>
|
||||
<div>
|
||||
<h5>Violet 500</h5>
|
||||
<code>#a855f7</code>
|
||||
<p style="font-size: var(--text-sm); margin-top: var(--space-xs);">Interactive elements, borders</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-demo">
|
||||
<div class="color-swatch" style="background: #7e22ce;"></div>
|
||||
<div>
|
||||
<h5>Violet 700</h5>
|
||||
<code>#7e22ce</code>
|
||||
<p style="font-size: var(--text-sm); margin-top: var(--space-xs);">Strong accents, depth layers</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h4>Complementary Colors</h4>
|
||||
<div class="color-demo">
|
||||
<div class="color-swatch" style="background: #f43f5e;"></div>
|
||||
<div>
|
||||
<h5>Red 500</h5>
|
||||
<code>#f43f5e</code>
|
||||
<p style="font-size: var(--text-sm); margin-top: var(--space-xs);">Heat, intensity, chromatic shift</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-demo">
|
||||
<div class="color-swatch" style="background: #06b6d4;"></div>
|
||||
<div>
|
||||
<h5>Cyan 500</h5>
|
||||
<code>#06b6d4</code>
|
||||
<p style="font-size: var(--text-sm); margin-top: var(--space-xs);">Cool energy, secondary interactions</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-demo">
|
||||
<div class="color-swatch" style="background: #eab308;"></div>
|
||||
<div>
|
||||
<h5>Gold 500</h5>
|
||||
<code>#eab308</code>
|
||||
<p style="font-size: var(--text-sm); margin-top: var(--space-xs);">Emphasis, prismatic accent</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- COMPONENT EXAMPLES -->
|
||||
<section class="mb-lg">
|
||||
<h2>Component Library</h2>
|
||||
|
||||
<div class="grid grid-2">
|
||||
<div class="card-elevated">
|
||||
<h3>Interactive Elements</h3>
|
||||
<button class="btn btn-violet">Primary Action</button>
|
||||
<button class="btn btn-outline mt-md">Secondary Action</button>
|
||||
<p class="mt-lg" style="font-size: var(--text-sm); color: var(--text-secondary);">
|
||||
Buttons inherit the chromatic depth effect, with enhanced layers appearing on hover. The interaction is subtle but satisfying, providing tactile feedback through visual shifts.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card-elevated">
|
||||
<h3>Status Indicators</h3>
|
||||
<span class="badge badge-violet">Power</span>
|
||||
<span class="badge badge-cyan">Energy</span>
|
||||
<span class="badge badge-gold">Prismatic</span>
|
||||
<p class="mt-lg" style="font-size: var(--text-sm); color: var(--text-secondary);">
|
||||
Badges use minimal chromatic effects to avoid visual clutter, focusing on clear categorical communication through color and typography.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-lg">
|
||||
<h3>Data Presentation</h3>
|
||||
<p class="mb-md">Tables maintain the chromatic vocabulary through colored borders and subtle background treatments.</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Color</th>
|
||||
<th>Function</th>
|
||||
<th>Chromatic Role</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Violet</td>
|
||||
<td>Primary power</td>
|
||||
<td>Anchors the palette, creates foundation</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Red-Orange</td>
|
||||
<td>Heat & intensity</td>
|
||||
<td>Warm shift, creates forward motion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cyan</td>
|
||||
<td>Cool energy</td>
|
||||
<td>Cold shift, creates receding depth</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gold</td>
|
||||
<td>Accent</td>
|
||||
<td>Prismatic highlight, draws focus</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- IMPLEMENTATION GUIDE -->
|
||||
<section class="mb-lg">
|
||||
<h2>Implementation Guide</h2>
|
||||
|
||||
<div class="card-light">
|
||||
<h3>Creating Chromatic Depth</h3>
|
||||
|
||||
<p>The chromatic depth effect requires understanding color relationships and shadow layering. While it may seem complex at first, the pattern becomes intuitive once you grasp the underlying principles.</p>
|
||||
|
||||
<h4 class="mt-lg">Step One: Choose Your Colors</h4>
|
||||
<p>Select a primary color and identify its split complements. This creates a triad with built-in tension and harmony. For this system, violet (270°) pairs with red-orange (30°) and cyan (180°). These colors are far enough apart to create contrast but close enough to feel cohesive.</p>
|
||||
|
||||
<h4 class="mt-lg">Step Two: Layer Your Shadows</h4>
|
||||
<p>Build the effect in layers, starting with edge definition and ending with atmospheric glow. Each layer serves a specific purpose. The inner glow provides crisp edges. The chromatic shifts create the prismatic aberration. The colored diffusion adds depth and atmosphere.</p>
|
||||
|
||||
<h4 class="mt-lg">Step Three: Balance the Intensity</h4>
|
||||
<p>Not every element needs maximum chromatic depth. Use the effect strategically to create hierarchy. Standard cards use subtle shifts. Elevated cards intensify the effect. Powerful elements maximize it and may add animation.</p>
|
||||
|
||||
<div class="alert-power mt-lg">
|
||||
<strong>Design Principle:</strong> The chromatic depth effect works best when it feels inherent to the design rather than applied as decoration. Build it into your core card and surface components, then vary the intensity based on hierarchy and importance.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-lg">
|
||||
<h3>Animation Philosophy</h3>
|
||||
|
||||
<p>This system embraces restraint in animation. Movement exists to communicate state changes or draw attention to important interactions, not to create spectacle. The powerful card pulse animation demonstrates this principle. It breathes slowly, taking four seconds for a complete cycle. The effect is almost subliminal—you might not consciously notice it, but it registers as aliveness and contained power.</p>
|
||||
|
||||
<p>When implementing animations, favor subtle changes in shadow depth, small translations, or gentle opacity shifts over dramatic transformations. The goal is to enhance the chromatic depth system, not compete with it. Let the layered colors do the heavy visual lifting while animations provide gentle accents.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ALERTS DEMONSTRATION -->
|
||||
<section class="mb-lg">
|
||||
<h2>Alert Components</h2>
|
||||
|
||||
<div class="alert-info">
|
||||
<strong>Information:</strong> Informational alerts use cyan as their primary color, creating calm, approachable messaging with subtle chromatic reinforcement along the border.
|
||||
</div>
|
||||
|
||||
<div class="alert-power mt-md">
|
||||
<strong>Power Notice:</strong> Important alerts emphasize the full chromatic depth effect, using violet as the primary color with red and cyan shifts creating urgency through visual weight rather than alarming color choices.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card-powerful text-center" style="padding: var(--space-2xl);">
|
||||
<h2>Prismatic Storm Dragon</h2>
|
||||
<p class="mt-md" style="color: var(--text-secondary);">
|
||||
Where complementary colors layer into elemental depth
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,627 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Solarpunk Deep Jungle Design System</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
SOLARPUNK DEEP JUNGLE DESIGN SYSTEM
|
||||
Mysterious Growth | Bioluminescent Tech | Shadow Ecology
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Forest floor to deep earth - mysterious depth */
|
||||
--bg-gradient-1: #0d1810; /* Deep shadow */
|
||||
--bg-gradient-2: #121f18; /* Ancient bark */
|
||||
--bg-gradient-3: #182620; /* Moss stone */
|
||||
--bg-gradient-4: #1a2a1f; /* Root depth */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(100,180,120,0.06);
|
||||
--bg-card: rgba(100,180,120,0.12);
|
||||
--bg-darker: rgba(10,20,15,0.60);
|
||||
--bg-solid-dark: #0d1810;
|
||||
--bg-solid-light: #d8f0e0;
|
||||
|
||||
/* --- BORDERS --- */
|
||||
--border-color: #3d6d4d;
|
||||
--border-width: 1.5px;
|
||||
--border-width-thick: 3px;
|
||||
|
||||
/* --- BORDER RADIUS ---
|
||||
Organic irregular forms */
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 11px;
|
||||
--radius-lg: 17px;
|
||||
--radius-xl: 25px;
|
||||
--radius-organic: 13px 19px 15px 21px;
|
||||
|
||||
/* --- COLOR SYSTEM ---
|
||||
Inspired by bioluminescence, deep growth, shadow life */
|
||||
--emerald-1: #3d9d5f; /* Deep emerald */
|
||||
--emerald-2: #2a7d4a; /* Shadow green */
|
||||
--glow-1: #6fd98a; /* Bioluminescent green */
|
||||
--glow-2: #4fbf70; /* Phosphorescent */
|
||||
--amber-1: #d8a558; /* Amber resin */
|
||||
--amber-2: #c08d40; /* Deep amber */
|
||||
--orchid-1: #9d6db8; /* Night orchid */
|
||||
--orchid-2: #7d4d98; /* Deep purple */
|
||||
--cyan-1: #58c0a8; /* Bioluminescent cyan */
|
||||
--cyan-2: #38a088; /* Deep aqua */
|
||||
--moss-1: #6d8d5d; /* Ancient moss */
|
||||
--moss-2: #4d6d3d; /* Deep moss */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS --- */
|
||||
--text-primary: #c8f0d8;
|
||||
--text-secondary: #98c8a8;
|
||||
--text-muted: #688878;
|
||||
--text-dark: #0d1810;
|
||||
--text-white: #f0fff8;
|
||||
--text-h1-gradient: linear-gradient(135deg, #6fd98a 0%, #d8a558 33%, #9d6db8 66%, #58c0a8 100%);
|
||||
--text-h2: #6fd98a;
|
||||
--text-h3: #d8a558;
|
||||
--text-h4: #58c0a8;
|
||||
--text-h5: #9d6db8;
|
||||
--text-h6: #c8f0d8;
|
||||
|
||||
/* --- BUTTON GRADIENTS --- */
|
||||
--btn-emerald-gradient: linear-gradient(135deg, #3d9d5f 0%, #2a7d4a 100%);
|
||||
--btn-glow-gradient: linear-gradient(135deg, #6fd98a 0%, #4fbf70 100%);
|
||||
--btn-amber-gradient: linear-gradient(135deg, #d8a558 0%, #c08d40 100%);
|
||||
--btn-orchid-gradient: linear-gradient(135deg, #9d6db8 0%, #7d4d98 100%);
|
||||
--btn-cyan-gradient: linear-gradient(135deg, #58c0a8 0%, #38a088 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Outfit', sans-serif;
|
||||
--font-body: 'Space Grotesk', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.7;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 20px rgba(111, 217, 138, 0.3);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--glow-1);
|
||||
font-weight: 600;
|
||||
text-shadow: 0 0 10px rgba(111, 217, 138, 0.4);
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--amber-1);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.25rem 0.5rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.9em;
|
||||
color: var(--cyan-1);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1.25rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background: var(--bg-elevated);
|
||||
border-left: var(--border-width-thick) solid var(--glow-1);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1.25rem 1.5rem;
|
||||
margin: 1.5rem 0;
|
||||
font-style: italic;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-bottom: 1.5rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
ul li, ol li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
color: var(--glow-1);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.875rem 1.75rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 0.9375rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
font-family: var(--font-body);
|
||||
border-radius: var(--radius-md);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-emerald {
|
||||
background: var(--btn-emerald-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 16px rgba(61, 157, 95, 0.4);
|
||||
}
|
||||
|
||||
.btn-emerald:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 24px rgba(61, 157, 95, 0.5);
|
||||
}
|
||||
|
||||
.btn-glow {
|
||||
background: var(--btn-glow-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 16px rgba(111, 217, 138, 0.5), 0 0 30px rgba(111, 217, 138, 0.3);
|
||||
}
|
||||
|
||||
.btn-glow:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 24px rgba(111, 217, 138, 0.6), 0 0 40px rgba(111, 217, 138, 0.4);
|
||||
}
|
||||
|
||||
.btn-amber {
|
||||
background: var(--btn-amber-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 16px rgba(216, 165, 88, 0.4);
|
||||
}
|
||||
|
||||
.btn-amber:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 24px rgba(216, 165, 88, 0.5);
|
||||
}
|
||||
|
||||
.btn-orchid {
|
||||
background: var(--btn-orchid-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 16px rgba(157, 109, 184, 0.4);
|
||||
}
|
||||
|
||||
.btn-orchid:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 24px rgba(157, 109, 184, 0.5);
|
||||
}
|
||||
|
||||
.btn-cyan {
|
||||
background: var(--btn-cyan-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 16px rgba(88, 192, 168, 0.4), 0 0 25px rgba(88, 192, 168, 0.2);
|
||||
}
|
||||
|
||||
.btn-cyan:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 24px rgba(88, 192, 168, 0.5), 0 0 35px rgba(88, 192, 168, 0.3);
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(12px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(12px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-solid {
|
||||
background: var(--bg-solid-light);
|
||||
color: var(--text-dark);
|
||||
border: var(--border-width) solid var(--emerald-2);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 4px 20px rgba(42, 125, 74, 0.3);
|
||||
}
|
||||
|
||||
.card-solid h2,
|
||||
.card-solid h3,
|
||||
.card-solid h4,
|
||||
.card-solid h5,
|
||||
.card-solid h6 {
|
||||
color: var(--emerald-2);
|
||||
}
|
||||
|
||||
.card-solid p,
|
||||
.card-solid li {
|
||||
color: var(--text-dark);
|
||||
}
|
||||
|
||||
.card-glow {
|
||||
border: var(--border-width) solid var(--glow-1);
|
||||
box-shadow: 0 0 30px rgba(111, 217, 138, 0.3), 0 4px 16px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.card-emerald {
|
||||
border-left: 4px solid var(--emerald-1);
|
||||
}
|
||||
|
||||
.card-amber {
|
||||
border-left: 4px solid var(--amber-1);
|
||||
}
|
||||
|
||||
.card-orchid {
|
||||
border-left: 4px solid var(--orchid-1);
|
||||
}
|
||||
|
||||
.card-cyan {
|
||||
border-left: 4px solid var(--cyan-1);
|
||||
box-shadow: 0 0 25px rgba(88, 192, 168, 0.2), 0 4px 16px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
/* ===== BADGES ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
border: var(--border-width) solid;
|
||||
}
|
||||
|
||||
.badge-glow {
|
||||
background: rgba(111, 217, 138, 0.12);
|
||||
color: var(--glow-1);
|
||||
border-color: var(--glow-1);
|
||||
box-shadow: 0 0 15px rgba(111, 217, 138, 0.3);
|
||||
}
|
||||
|
||||
.badge-emerald {
|
||||
background: rgba(61, 157, 95, 0.12);
|
||||
color: var(--emerald-1);
|
||||
border-color: var(--emerald-1);
|
||||
}
|
||||
|
||||
.badge-amber {
|
||||
background: rgba(216, 165, 88, 0.12);
|
||||
color: var(--amber-1);
|
||||
border-color: var(--amber-1);
|
||||
}
|
||||
|
||||
.badge-orchid {
|
||||
background: rgba(157, 109, 184, 0.12);
|
||||
color: var(--orchid-1);
|
||||
border-color: var(--orchid-1);
|
||||
}
|
||||
|
||||
.badge-cyan {
|
||||
background: rgba(88, 192, 168, 0.12);
|
||||
color: var(--cyan-1);
|
||||
border-color: var(--cyan-1);
|
||||
box-shadow: 0 0 12px rgba(88, 192, 168, 0.2);
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-radius: var(--radius-md);
|
||||
border: var(--border-width) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-glow {
|
||||
background: rgba(111, 217, 138, 0.08);
|
||||
border-color: var(--glow-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(111, 217, 138, 0.2);
|
||||
}
|
||||
|
||||
.alert-emerald {
|
||||
background: rgba(61, 157, 95, 0.08);
|
||||
border-color: var(--emerald-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-amber {
|
||||
background: rgba(216, 165, 88, 0.08);
|
||||
border-color: var(--amber-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-cyan {
|
||||
background: rgba(88, 192, 168, 0.08);
|
||||
border-color: var(--cyan-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 18px rgba(88, 192, 168, 0.15);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width);
|
||||
background: linear-gradient(to right, transparent, var(--glow-1), transparent);
|
||||
margin: 2.5rem 0;
|
||||
box-shadow: 0 0 15px rgba(111, 217, 138, 0.3);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>Solarpunk Deep Jungle</h1>
|
||||
<p style="font-size: 1.125rem; color: var(--text-secondary);">Mysterious Growth | Bioluminescent Tech | Shadow Ecology</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- INTRODUCTION -->
|
||||
<section class="mb-3">
|
||||
<div class="card-solid">
|
||||
<h2>The Mystery of Deep Growth</h2>
|
||||
<p>Solarpunk Deep Jungle explores <strong>sustainable technology</strong> through the lens of shadow ecology and bioluminescence. This design system channels the <em>enigmatic beauty</em> of Earth's oldest forests, where life thrives in darkness through glowing fungi, phosphorescent moss, and hidden networks.</p>
|
||||
<p>Here, technology doesn't dominate nature—it whispers, glows, and grows alongside it in the fertile darkness.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Shadow Spectrum</h2>
|
||||
<div class="grid grid-4">
|
||||
<div class="card" style="background: var(--glow-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Bioluminescent</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#6fd98a</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--emerald-1); color: white;">
|
||||
<h4 style="color: white;">Deep Emerald</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#3d9d5f</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--amber-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Amber Resin</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#d8a558</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--cyan-1); color: white;">
|
||||
<h4 style="color: white;">Bioluminescent Cyan</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#58c0a8</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--orchid-1); color: white;">
|
||||
<h4 style="color: white;">Night Orchid</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#9d6db8</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--moss-1); color: white;">
|
||||
<h4 style="color: white;">Ancient Moss</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#6d8d5d</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--emerald-2); color: white;">
|
||||
<h4 style="color: white;">Shadow Green</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#2a7d4a</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--orchid-2); color: white;">
|
||||
<h4 style="color: white;">Deep Purple</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#7d4d98</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Bioluminescent Actions</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card card-glow">
|
||||
<h3>Glow & Amber</h3>
|
||||
<button class="btn btn-glow">Illuminate Action</button>
|
||||
<button class="btn btn-amber mt-2">Preserve Action</button>
|
||||
</div>
|
||||
<div class="card card-cyan">
|
||||
<h3>Cyan & Orchid</h3>
|
||||
<button class="btn btn-cyan">Flow Action</button>
|
||||
<button class="btn btn-orchid mt-2">Bloom Action</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- BADGES -->
|
||||
<section class="mb-3">
|
||||
<h2>Shadow Badges</h2>
|
||||
<div class="card">
|
||||
<span class="badge badge-glow">Glowing</span>
|
||||
<span class="badge badge-emerald">Ancient</span>
|
||||
<span class="badge badge-amber">Preserved</span>
|
||||
<span class="badge badge-cyan">Flowing</span>
|
||||
<span class="badge badge-orchid">Mysterious</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>Shadow Signals</h2>
|
||||
<div class="alert alert-glow">
|
||||
<strong>Bioluminescence Detected!</strong> Underground mycelium network active and expanding.
|
||||
</div>
|
||||
<div class="alert alert-amber">
|
||||
<strong>Energy Storage:</strong> Amber capacitors at 95% - stable for weeks.
|
||||
</div>
|
||||
<div class="alert alert-cyan">
|
||||
<strong>Water Network:</strong> Underground aquifer systems flowing optimally.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- IMPLEMENTATION -->
|
||||
<section class="mb-3">
|
||||
<h2>Design Philosophy</h2>
|
||||
<div class="card-solid">
|
||||
<h3>Shadow Ecology Principles</h3>
|
||||
<ul>
|
||||
<li><strong>Bioluminescent Accents:</strong> Glows and shadows mimic natural light sources</li>
|
||||
<li><strong>Rich Darkness:</strong> Deep backgrounds create contrast and mystery</li>
|
||||
<li><strong>Organic Irregularity:</strong> Asymmetric borders follow root patterns</li>
|
||||
<li><strong>Layered Transparency:</strong> Multiple depth levels suggest underground networks</li>
|
||||
<li><strong>Shadow Technology:</strong> Tech that thrives in darkness, not despite it</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card card-glow text-center" style="padding: 2rem;">
|
||||
<h2>Solarpunk Deep Jungle Style Complete</h2>
|
||||
<p style="margin-top: 1rem;">In the darkness, sustainable life glows brightest 🌿✨</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,601 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Solarpunk Rainforest Design System</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
SOLARPUNK RAINFOREST DESIGN SYSTEM
|
||||
Lush Abundance | Tropical Vitality | Living Architecture
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Canopy to understory - layered life */
|
||||
--bg-gradient-1: #1a3320; /* Deep canopy */
|
||||
--bg-gradient-2: #254028; /* Mid canopy */
|
||||
--bg-gradient-3: #2a4a30; /* Upper understory */
|
||||
--bg-gradient-4: #305238; /* Forest floor approach */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(180,255,200,0.08);
|
||||
--bg-card: rgba(180,255,200,0.15);
|
||||
--bg-darker: rgba(30,60,40,0.50);
|
||||
--bg-solid-dark: #1a3320;
|
||||
--bg-solid-light: #f0fff4;
|
||||
|
||||
/* --- BORDERS --- */
|
||||
--border-color: #60c070;
|
||||
--border-width: 1.5px;
|
||||
--border-width-thick: 3px;
|
||||
|
||||
/* --- BORDER RADIUS ---
|
||||
Organic growth patterns */
|
||||
--radius-sm: 7px;
|
||||
--radius-md: 12px;
|
||||
--radius-lg: 18px;
|
||||
--radius-xl: 26px;
|
||||
--radius-organic: 14px 20px 16px 22px;
|
||||
|
||||
/* --- COLOR SYSTEM ---
|
||||
Inspired by tropical flora and fauna */
|
||||
--canopy-1: #4ecf5d; /* Vibrant leaf green */
|
||||
--canopy-2: #2db83c; /* Deep jungle green */
|
||||
--orchid-1: #c558d9; /* Tropical orchid */
|
||||
--orchid-2: #a03fb8; /* Deep purple flower */
|
||||
--paradise-1: #ff7f3f; /* Bird of paradise */
|
||||
--paradise-2: #ff5f1f; /* Sunset flame */
|
||||
--toucan-1: #ffcf40; /* Toucan beak yellow */
|
||||
--toucan-2: #ffa040; /* Golden amber */
|
||||
--water-1: #3fbfaf; /* Waterfall mist */
|
||||
--water-2: #2fa89f; /* River stone */
|
||||
--fern-1: #88e088; /* Young fern */
|
||||
--fern-2: #5fcf5f; /* Mature frond */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS --- */
|
||||
--text-primary: #e0fff0;
|
||||
--text-secondary: #b0e8c8;
|
||||
--text-muted: #80c098;
|
||||
--text-dark: #1a3320;
|
||||
--text-white: #ffffff;
|
||||
--text-h1-gradient: linear-gradient(135deg, #4ecf5d 0%, #ffcf40 33%, #c558d9 66%, #3fbfaf 100%);
|
||||
--text-h2: #4ecf5d;
|
||||
--text-h3: #ff7f3f;
|
||||
--text-h4: #3fbfaf;
|
||||
--text-h5: #c558d9;
|
||||
--text-h6: #e0fff0;
|
||||
|
||||
/* --- BUTTON GRADIENTS --- */
|
||||
--btn-canopy-gradient: linear-gradient(135deg, #4ecf5d 0%, #2db83c 100%);
|
||||
--btn-paradise-gradient: linear-gradient(135deg, #ff7f3f 0%, #ff5f1f 100%);
|
||||
--btn-orchid-gradient: linear-gradient(135deg, #c558d9 0%, #a03fb8 100%);
|
||||
--btn-water-gradient: linear-gradient(135deg, #3fbfaf 0%, #2fa89f 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Outfit', sans-serif;
|
||||
--font-body: 'Space Grotesk', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.7;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--canopy-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--toucan-1);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.25rem 0.5rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.9em;
|
||||
color: var(--water-1);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1.25rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background: var(--bg-elevated);
|
||||
border-left: var(--border-width-thick) solid var(--canopy-1);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1.25rem 1.5rem;
|
||||
margin: 1.5rem 0;
|
||||
font-style: italic;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-bottom: 1.5rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
ul li, ol li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
color: var(--canopy-1);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.875rem 1.75rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 0.9375rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
font-family: var(--font-body);
|
||||
border-radius: var(--radius-md);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-canopy {
|
||||
background: var(--btn-canopy-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 14px rgba(78, 207, 93, 0.4);
|
||||
}
|
||||
|
||||
.btn-canopy:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 22px rgba(78, 207, 93, 0.5);
|
||||
}
|
||||
|
||||
.btn-paradise {
|
||||
background: var(--btn-paradise-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 14px rgba(255, 127, 63, 0.4);
|
||||
}
|
||||
|
||||
.btn-paradise:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 22px rgba(255, 127, 63, 0.5);
|
||||
}
|
||||
|
||||
.btn-orchid {
|
||||
background: var(--btn-orchid-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 14px rgba(197, 88, 217, 0.4);
|
||||
}
|
||||
|
||||
.btn-orchid:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 22px rgba(197, 88, 217, 0.5);
|
||||
}
|
||||
|
||||
.btn-water {
|
||||
background: var(--btn-water-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 14px rgba(63, 191, 175, 0.4);
|
||||
}
|
||||
|
||||
.btn-water:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 22px rgba(63, 191, 175, 0.5);
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 2px 12px rgba(78, 207, 93, 0.15);
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-solid {
|
||||
background: var(--bg-solid-light);
|
||||
color: var(--text-dark);
|
||||
border: var(--border-width) solid var(--canopy-2);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 4px 16px rgba(45, 184, 60, 0.2);
|
||||
}
|
||||
|
||||
.card-solid h2,
|
||||
.card-solid h3,
|
||||
.card-solid h4,
|
||||
.card-solid h5,
|
||||
.card-solid h6 {
|
||||
color: var(--canopy-2);
|
||||
}
|
||||
|
||||
.card-solid p,
|
||||
.card-solid li {
|
||||
color: var(--text-dark);
|
||||
}
|
||||
|
||||
.card-canopy {
|
||||
border-left: 4px solid var(--canopy-1);
|
||||
box-shadow: 0 0 20px rgba(78, 207, 93, 0.2);
|
||||
}
|
||||
|
||||
.card-orchid {
|
||||
border-left: 4px solid var(--orchid-1);
|
||||
box-shadow: 0 0 20px rgba(197, 88, 217, 0.2);
|
||||
}
|
||||
|
||||
.card-paradise {
|
||||
border-left: 4px solid var(--paradise-1);
|
||||
box-shadow: 0 0 20px rgba(255, 127, 63, 0.2);
|
||||
}
|
||||
|
||||
.card-water {
|
||||
border-left: 4px solid var(--water-1);
|
||||
box-shadow: 0 0 20px rgba(63, 191, 175, 0.2);
|
||||
}
|
||||
|
||||
/* ===== BADGES ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
border: var(--border-width) solid;
|
||||
}
|
||||
|
||||
.badge-canopy {
|
||||
background: rgba(78, 207, 93, 0.15);
|
||||
color: var(--canopy-1);
|
||||
border-color: var(--canopy-1);
|
||||
}
|
||||
|
||||
.badge-orchid {
|
||||
background: rgba(197, 88, 217, 0.15);
|
||||
color: var(--orchid-1);
|
||||
border-color: var(--orchid-1);
|
||||
}
|
||||
|
||||
.badge-paradise {
|
||||
background: rgba(255, 127, 63, 0.15);
|
||||
color: var(--paradise-1);
|
||||
border-color: var(--paradise-1);
|
||||
}
|
||||
|
||||
.badge-water {
|
||||
background: rgba(63, 191, 175, 0.15);
|
||||
color: var(--water-1);
|
||||
border-color: var(--water-1);
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-radius: var(--radius-md);
|
||||
border: var(--border-width) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-canopy {
|
||||
background: rgba(78, 207, 93, 0.12);
|
||||
border-color: var(--canopy-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-orchid {
|
||||
background: rgba(197, 88, 217, 0.12);
|
||||
border-color: var(--orchid-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-paradise {
|
||||
background: rgba(255, 127, 63, 0.12);
|
||||
border-color: var(--paradise-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-water {
|
||||
background: rgba(63, 191, 175, 0.12);
|
||||
border-color: var(--water-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width);
|
||||
background: linear-gradient(to right, transparent, var(--canopy-1), transparent);
|
||||
margin: 2.5rem 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>Solarpunk Rainforest</h1>
|
||||
<p style="font-size: 1.125rem; color: var(--text-secondary);">Lush Abundance | Tropical Vitality | Living Architecture</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- INTRODUCTION -->
|
||||
<section class="mb-3">
|
||||
<div class="card-solid">
|
||||
<h2>Vibrant Tropical Sustainability</h2>
|
||||
<p>Solarpunk Rainforest bursts with <strong>saturated life</strong> and tropical abundance. This design system channels the <em>explosive biodiversity</em> of Earth's most vital ecosystems, featuring vivid greens, orchid purples, bird-of-paradise oranges, and waterfall blues.</p>
|
||||
<p>Every pixel pulses with photosynthetic energy—this is design that grows, breathes, and thrives.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Biodiversity Palette</h2>
|
||||
<div class="grid grid-4">
|
||||
<div class="card" style="background: var(--canopy-1); color: white;">
|
||||
<h4 style="color: white;">Canopy Green</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#4ecf5d</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--orchid-1); color: white;">
|
||||
<h4 style="color: white;">Tropical Orchid</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#c558d9</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--paradise-1); color: white;">
|
||||
<h4 style="color: white;">Bird of Paradise</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#ff7f3f</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--water-1); color: white;">
|
||||
<h4 style="color: white;">Waterfall Mist</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#3fbfaf</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--fern-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Young Fern</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#88e088</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--toucan-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Toucan Beak</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#ffcf40</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--canopy-2); color: white;">
|
||||
<h4 style="color: white;">Deep Jungle</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#2db83c</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--orchid-2); color: white;">
|
||||
<h4 style="color: white;">Deep Purple</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#a03fb8</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Action Buttons</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card card-canopy">
|
||||
<h3>Canopy & Paradise</h3>
|
||||
<button class="btn btn-canopy">Grow Action</button>
|
||||
<button class="btn btn-paradise mt-2">Flourish Action</button>
|
||||
</div>
|
||||
<div class="card card-orchid">
|
||||
<h3>Orchid & Water</h3>
|
||||
<button class="btn btn-orchid">Bloom Action</button>
|
||||
<button class="btn btn-water mt-2">Flow Action</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- BADGES -->
|
||||
<section class="mb-3">
|
||||
<h2>Ecosystem Badges</h2>
|
||||
<div class="card">
|
||||
<span class="badge badge-canopy">Thriving</span>
|
||||
<span class="badge badge-orchid">Flowering</span>
|
||||
<span class="badge badge-paradise">Vibrant</span>
|
||||
<span class="badge badge-water">Flowing</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>Ecosystem Alerts</h2>
|
||||
<div class="alert alert-canopy">
|
||||
<strong>Growth!</strong> Vertical gardens have reached full canopy coverage!
|
||||
</div>
|
||||
<div class="alert alert-paradise">
|
||||
<strong>Energy Surge:</strong> Solar array producing 150% of daily needs.
|
||||
</div>
|
||||
<div class="alert alert-orchid">
|
||||
<strong>Biodiversity:</strong> 47 species identified in rooftop habitat.
|
||||
</div>
|
||||
<div class="alert alert-water">
|
||||
<strong>Hydration:</strong> Atmospheric water collectors at optimal capacity.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- IMPLEMENTATION -->
|
||||
<section class="mb-3">
|
||||
<h2>Design Philosophy</h2>
|
||||
<div class="card-solid">
|
||||
<h3>Tropical Abundance Principles</h3>
|
||||
<ul>
|
||||
<li><strong>Saturated Vitality:</strong> High-chroma colors that pulse with life</li>
|
||||
<li><strong>Layered Depth:</strong> Multiple transparency levels mimic canopy layers</li>
|
||||
<li><strong>Organic Asymmetry:</strong> Borders follow natural growth patterns</li>
|
||||
<li><strong>Biodiversity Palette:</strong> Each color represents a different species niche</li>
|
||||
<li><strong>Living Shadows:</strong> Glows and shadows suggest dappled sunlight</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card text-center" style="padding: 2rem;">
|
||||
<h2>Solarpunk Rainforest Style Complete</h2>
|
||||
<p style="margin-top: 1rem;">Where technology and nature grow as one 🌿🦜</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,581 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Solarpunk Sundae Design System</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
SOLARPUNK SUNDAE DESIGN SYSTEM
|
||||
Sweet Sustainability | Pastel Ecology | Delicious Future
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Cream to pastel progression - soft and sweet */
|
||||
--bg-gradient-1: #f9f4ef; /* Vanilla cream */
|
||||
--bg-gradient-2: #f5f0e8; /* Warm cream */
|
||||
--bg-gradient-3: #efe8f0; /* Lavender cream */
|
||||
--bg-gradient-4: #e8f0ed; /* Mint cream */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(255,255,255,0.60);
|
||||
--bg-card: rgba(255,255,255,0.80);
|
||||
--bg-darker: rgba(200,220,200,0.25);
|
||||
--bg-solid-dark: #d8e8d0;
|
||||
--bg-solid-light: #ffffff;
|
||||
|
||||
/* --- BORDERS --- */
|
||||
--border-color: #b8d4a8;
|
||||
--border-width: 2px;
|
||||
--border-width-thick: 3px;
|
||||
|
||||
/* --- BORDER RADIUS ---
|
||||
Soft and round like scoops of ice cream */
|
||||
--radius-sm: 8px;
|
||||
--radius-md: 14px;
|
||||
--radius-lg: 20px;
|
||||
--radius-xl: 28px;
|
||||
--radius-organic: 16px 22px 18px 24px;
|
||||
|
||||
/* --- COLOR SYSTEM ---
|
||||
Inspired by artisan ice cream, fresh fruit, whipped cream */
|
||||
--mint-1: #a8d8b9; /* Mint ice cream */
|
||||
--mint-2: #88c098; /* Deeper mint */
|
||||
--peach-1: #ffc4a3; /* Peach sorbet */
|
||||
--peach-2: #ffb088; /* Ripe peach */
|
||||
--honey-1: #ffd68f; /* Honeycomb */
|
||||
--honey-2: #ffc75f; /* Golden honey */
|
||||
--berry-1: #e8a8c8; /* Strawberry cream */
|
||||
--berry-2: #d888a8; /* Berry compote */
|
||||
--sky-1: #a8d8e8; /* Sky blue sorbet */
|
||||
--sky-2: #88c0d8; /* Ocean foam */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS --- */
|
||||
--text-primary: #4a5a48;
|
||||
--text-secondary: #6a7a68;
|
||||
--text-muted: #8a9a88;
|
||||
--text-dark: #2a3a28;
|
||||
--text-white: #ffffff;
|
||||
--text-h1-gradient: linear-gradient(135deg, #a8d8b9 0%, #ffd68f 33%, #e8a8c8 66%, #a8d8e8 100%);
|
||||
--text-h2: #88c098;
|
||||
--text-h3: #ffc75f;
|
||||
--text-h4: #a8d8e8;
|
||||
--text-h5: #ffc4a3;
|
||||
--text-h6: #4a5a48;
|
||||
|
||||
/* --- BUTTON GRADIENTS --- */
|
||||
--btn-mint-gradient: linear-gradient(135deg, #a8d8b9 0%, #88c098 100%);
|
||||
--btn-honey-gradient: linear-gradient(135deg, #ffd68f 0%, #ffc75f 100%);
|
||||
--btn-berry-gradient: linear-gradient(135deg, #e8a8c8 0%, #d888a8 100%);
|
||||
--btn-sky-gradient: linear-gradient(135deg, #a8d8e8 0%, #88c0d8 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Outfit', sans-serif;
|
||||
--font-body: 'Space Grotesk', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(180deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.7;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-family: var(--font-header);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--mint-2);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--honey-1);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.25rem 0.5rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.9em;
|
||||
color: var(--sky-2);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1.25rem;
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background: var(--bg-elevated);
|
||||
border-left: var(--border-width-thick) solid var(--mint-1);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1.25rem 1.5rem;
|
||||
margin: 1.5rem 0;
|
||||
font-style: italic;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-bottom: 1.5rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
ul li, ol li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
color: var(--mint-2);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.875rem 1.75rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 0.9375rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
font-family: var(--font-body);
|
||||
border-radius: var(--radius-md);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-mint {
|
||||
background: var(--btn-mint-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(168, 216, 185, 0.4);
|
||||
}
|
||||
|
||||
.btn-mint:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(168, 216, 185, 0.5);
|
||||
}
|
||||
|
||||
.btn-honey {
|
||||
background: var(--btn-honey-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(255, 214, 143, 0.4);
|
||||
}
|
||||
|
||||
.btn-honey:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(255, 214, 143, 0.5);
|
||||
}
|
||||
|
||||
.btn-berry {
|
||||
background: var(--btn-berry-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(232, 168, 200, 0.4);
|
||||
}
|
||||
|
||||
.btn-berry:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(232, 168, 200, 0.5);
|
||||
}
|
||||
|
||||
.btn-sky {
|
||||
background: var(--btn-sky-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(168, 216, 232, 0.4);
|
||||
}
|
||||
|
||||
.btn-sky:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(168, 216, 232, 0.5);
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 2px 8px rgba(184, 212, 168, 0.15);
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-solid {
|
||||
background: var(--bg-solid-light);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 4px 16px rgba(184, 212, 168, 0.2);
|
||||
}
|
||||
|
||||
.card-mint {
|
||||
border-left: 4px solid var(--mint-1);
|
||||
}
|
||||
|
||||
.card-honey {
|
||||
border-left: 4px solid var(--honey-1);
|
||||
}
|
||||
|
||||
.card-berry {
|
||||
border-left: 4px solid var(--berry-1);
|
||||
}
|
||||
|
||||
.card-sky {
|
||||
border-left: 4px solid var(--sky-1);
|
||||
}
|
||||
|
||||
/* ===== BADGES ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
border: var(--border-width) solid;
|
||||
}
|
||||
|
||||
.badge-mint {
|
||||
background: rgba(168, 216, 185, 0.2);
|
||||
color: var(--mint-2);
|
||||
border-color: var(--mint-1);
|
||||
}
|
||||
|
||||
.badge-honey {
|
||||
background: rgba(255, 214, 143, 0.2);
|
||||
color: #d4a850;
|
||||
border-color: var(--honey-1);
|
||||
}
|
||||
|
||||
.badge-berry {
|
||||
background: rgba(232, 168, 200, 0.2);
|
||||
color: var(--berry-2);
|
||||
border-color: var(--berry-1);
|
||||
}
|
||||
|
||||
.badge-sky {
|
||||
background: rgba(168, 216, 232, 0.2);
|
||||
color: var(--sky-2);
|
||||
border-color: var(--sky-1);
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-radius: var(--radius-md);
|
||||
border: var(--border-width) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-mint {
|
||||
background: rgba(168, 216, 185, 0.15);
|
||||
border-color: var(--mint-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-honey {
|
||||
background: rgba(255, 214, 143, 0.15);
|
||||
border-color: var(--honey-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-berry {
|
||||
background: rgba(232, 168, 200, 0.15);
|
||||
border-color: var(--berry-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.alert-sky {
|
||||
background: rgba(168, 216, 232, 0.15);
|
||||
border-color: var(--sky-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width);
|
||||
background: linear-gradient(to right, transparent, var(--border-color), transparent);
|
||||
margin: 2.5rem 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>Solarpunk Sundae</h1>
|
||||
<p style="font-size: 1.125rem; color: var(--text-secondary);">Sweet Sustainability | Pastel Ecology | Delicious Future</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- INTRODUCTION -->
|
||||
<section class="mb-3">
|
||||
<div class="card-solid">
|
||||
<h2>A Sweet Take on Sustainable Design</h2>
|
||||
<p>Solarpunk Sundae combines <strong>ecological optimism</strong> with the delightful aesthetics of artisan desserts. This design system proves that <em>sustainability can be sweet</em>, featuring pastel palettes inspired by mint ice cream, peach sorbet, honeycomb, and berry compote.</p>
|
||||
<p>Like the best desserts, this system is crafted with care—organic curves, soft shadows, and a color palette that's as nourishing as it is beautiful.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>Flavor Palette</h2>
|
||||
<div class="grid grid-4">
|
||||
<div class="card" style="background: var(--mint-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Mint Ice Cream</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#a8d8b9</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--honey-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Honeycomb</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#ffd68f</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--berry-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Strawberry Cream</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#e8a8c8</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--sky-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Sky Sorbet</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#a8d8e8</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--peach-1); color: var(--text-dark);">
|
||||
<h4 style="color: var(--text-dark);">Peach Sorbet</h4>
|
||||
<code style="background: rgba(255,255,255,0.4); color: var(--text-dark); border-color: var(--text-dark);">#ffc4a3</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--mint-2); color: white;">
|
||||
<h4 style="color: white;">Deeper Mint</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#88c098</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--berry-2); color: white;">
|
||||
<h4 style="color: white;">Berry Compote</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#d888a8</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--sky-2); color: white;">
|
||||
<h4 style="color: white;">Ocean Foam</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#88c0d8</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>Button Flavors</h2>
|
||||
<div class="grid grid-2">
|
||||
<div class="card card-mint">
|
||||
<h3>Mint & Honey</h3>
|
||||
<button class="btn btn-mint">Mint Action</button>
|
||||
<button class="btn btn-honey mt-2">Honey Action</button>
|
||||
</div>
|
||||
<div class="card card-berry">
|
||||
<h3>Berry & Sky</h3>
|
||||
<button class="btn btn-berry">Berry Action</button>
|
||||
<button class="btn btn-sky mt-2">Sky Action</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- BADGES -->
|
||||
<section class="mb-3">
|
||||
<h2>Sweet Badges</h2>
|
||||
<div class="card">
|
||||
<span class="badge badge-mint">Organic</span>
|
||||
<span class="badge badge-honey">Sustainable</span>
|
||||
<span class="badge badge-berry">Handcrafted</span>
|
||||
<span class="badge badge-sky">Fresh</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>Flavor Alerts</h2>
|
||||
<div class="alert alert-mint">
|
||||
<strong>Success!</strong> Your sustainable garden is thriving with fresh mint and herbs.
|
||||
</div>
|
||||
<div class="alert alert-honey">
|
||||
<strong>Notice:</strong> Solar panels are generating 20% more energy than projected!
|
||||
</div>
|
||||
<div class="alert alert-berry">
|
||||
<strong>Update:</strong> Community berry harvest scheduled for this weekend.
|
||||
</div>
|
||||
<div class="alert alert-sky">
|
||||
<strong>Info:</strong> Rainwater collection system at 85% capacity.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- IMPLEMENTATION -->
|
||||
<section class="mb-3">
|
||||
<h2>Design Philosophy</h2>
|
||||
<div class="card-solid">
|
||||
<h3>Sweet Sustainability Principles</h3>
|
||||
<ul>
|
||||
<li><strong>Pastel Optimism:</strong> Light, airy colors that evoke joy and possibility</li>
|
||||
<li><strong>Organic Curves:</strong> Generous border radius (8-28px) for softness</li>
|
||||
<li><strong>Dessert-Inspired Palette:</strong> Mint, honey, berry, peach, sky</li>
|
||||
<li><strong>High Contrast Text:</strong> Dark green text ensures readability on pastels</li>
|
||||
<li><strong>Artisan Details:</strong> Subtle shadows and backdrop blur for depth</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card text-center" style="padding: 2rem;">
|
||||
<h2>Solarpunk Sundae Style Complete</h2>
|
||||
<p style="margin-top: 1rem;">Sustainable design never tasted so sweet 🍦🌱</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1506
DumperCan/UI Style References/solarpunk_style_reference.html
Normal file
1506
DumperCan/UI Style References/solarpunk_style_reference.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,637 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Soviet Cyberpunk Style Reference | Красный Неон</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Russo+One&family=Share+Tech+Mono&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ============================================
|
||||
SOVIET CYBERPUNK STYLE REFERENCE
|
||||
Красный Неон | Brutalist Future | Constructivist Code
|
||||
UNIQUE FEATURE: Animated CRT Scan Lines
|
||||
============================================ */
|
||||
|
||||
/* ===== 1. CSS RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===== 2. CSS VARIABLES ===== */
|
||||
:root {
|
||||
/* --- BACKGROUND GRADIENT ---
|
||||
Concrete to steel - Soviet brutalism */
|
||||
--bg-gradient-1: #1a1a1a; /* Iron dark */
|
||||
--bg-gradient-2: #242424; /* Concrete gray */
|
||||
--bg-gradient-3: #2a2424; /* Rust shadow */
|
||||
--bg-gradient-4: #2a2a2a; /* Steel dark */
|
||||
|
||||
/* --- SURFACE BACKGROUNDS --- */
|
||||
--bg-elevated: rgba(255,60,60,0.05);
|
||||
--bg-card: rgba(255,60,60,0.08);
|
||||
--bg-darker: rgba(0,0,0,0.50);
|
||||
--bg-solid-dark: #1a1a1a;
|
||||
--bg-solid-light: #e8e8e8;
|
||||
|
||||
/* --- BORDERS ---
|
||||
Brutalist thickness, constructivist precision */
|
||||
--border-color: #cc0000;
|
||||
--border-width: 2px;
|
||||
--border-width-thick: 5px;
|
||||
|
||||
/* --- GLOW SYSTEM ---
|
||||
Red: Communist power, revolution
|
||||
Cyan: Cold neon, digital future
|
||||
Yellow: Warning, construction */
|
||||
--red-1: #ff3c3c; /* Neon red */
|
||||
--red-2: #cc0000; /* Deep Soviet red */
|
||||
--red-3: #990000; /* Dark crimson */
|
||||
--cyan-1: #00ffff; /* Cold neon cyan */
|
||||
--cyan-2: #00cccc; /* Deep cyan */
|
||||
--cyan-3: #008b8b; /* Dark teal */
|
||||
--yellow-1: #ffff00; /* Warning yellow */
|
||||
--yellow-2: #cccc00; /* Construction gold */
|
||||
|
||||
/* --- TYPOGRAPHY COLORS --- */
|
||||
--text-primary: #e8e8e8;
|
||||
--text-secondary: #b8b8b8;
|
||||
--text-white: #ffffff;
|
||||
--text-h1-gradient: linear-gradient(90deg, #ff3c3c 0%, #00ffff 50%, #ffff00 100%);
|
||||
--text-h2: #ff3c3c; /* Neon red */
|
||||
--text-h3: #00ffff; /* Cyan */
|
||||
--text-h4: #ffff00; /* Yellow */
|
||||
--text-h5: #b8b8b8; /* Gray */
|
||||
--text-h6: #e8e8e8; /* Primary */
|
||||
|
||||
/* --- BUTTON GRADIENTS --- */
|
||||
--btn-red-gradient: linear-gradient(45deg, #ff3c3c 0%, #cc0000 100%);
|
||||
--btn-cyan-gradient: linear-gradient(45deg, #00ffff 0%, #008b8b 100%);
|
||||
--btn-yellow-gradient: linear-gradient(45deg, #ffff00 0%, #cccc00 100%);
|
||||
|
||||
/* --- FONTS --- */
|
||||
--font-header: 'Russo One', sans-serif;
|
||||
--font-body: 'Share Tech Mono', monospace;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* ===== UNIQUE FEATURE: CRT SCAN LINES ===== */
|
||||
@keyframes scan-lines {
|
||||
0% { transform: translateY(-100%); }
|
||||
100% { transform: translateY(100vh); }
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
rgba(255, 60, 60, 0.03) 0px,
|
||||
transparent 1px,
|
||||
transparent 2px,
|
||||
rgba(0, 255, 255, 0.03) 3px,
|
||||
transparent 4px
|
||||
);
|
||||
animation: scan-lines 8s linear infinite;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Static scan line overlay */
|
||||
body::after {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
rgba(0, 0, 0, 0.15) 0px,
|
||||
transparent 1px,
|
||||
transparent 2px
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: 9998;
|
||||
}
|
||||
|
||||
/* ===== 3. BASE STYLES ===== */
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: linear-gradient(135deg,
|
||||
var(--bg-gradient-1) 0%,
|
||||
var(--bg-gradient-2) 33%,
|
||||
var(--bg-gradient-3) 66%,
|
||||
var(--bg-gradient-4) 100%);
|
||||
background-attachment: fixed;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* ===== 4. LAYOUT ===== */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
|
||||
|
||||
/* ===== 5. TYPOGRAPHY ===== */
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--text-h1-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
font-family: var(--font-header);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Cyrillic-inspired decorative element */
|
||||
h1::after {
|
||||
content: '█';
|
||||
position: absolute;
|
||||
right: -1rem;
|
||||
top: 0;
|
||||
color: var(--red-1);
|
||||
animation: blink 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0%, 49% { opacity: 1; }
|
||||
50%, 100% { opacity: 0; }
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 4vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text-h2);
|
||||
margin-bottom: 1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 20px rgba(255, 60, 60, 0.6),
|
||||
0 0 40px rgba(255, 60, 60, 0.3);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.25rem, 3vw, 1.5rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h3);
|
||||
margin-bottom: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 15px rgba(0, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: clamp(1.1rem, 2.5vw, 1.25rem);
|
||||
font-weight: 600;
|
||||
color: var(--text-h4);
|
||||
margin-bottom: 0.75rem;
|
||||
font-family: var(--font-header);
|
||||
text-shadow: 0 0 15px rgba(255, 255, 0, 0.5);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h5);
|
||||
margin-bottom: 0.5rem;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-h6);
|
||||
margin-bottom: 0.5rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-family: var(--font-header);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--red-1);
|
||||
font-weight: 600;
|
||||
text-shadow: 0 0 10px rgba(255, 60, 60, 0.4);
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--cyan-1);
|
||||
font-style: italic;
|
||||
text-shadow: 0 0 10px rgba(0, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 0.2rem 0.4rem;
|
||||
border: 1px solid var(--cyan-2);
|
||||
border-radius: 0;
|
||||
font-size: 0.9em;
|
||||
color: var(--cyan-1);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
background: var(--bg-elevated);
|
||||
padding: 1rem;
|
||||
border: var(--border-width) solid var(--red-2);
|
||||
border-left: var(--border-width-thick) solid var(--red-1);
|
||||
border-radius: 0;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== BUTTONS ===== */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.875rem 2rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
cursor: pointer;
|
||||
border: var(--border-width) solid;
|
||||
font-family: var(--font-body);
|
||||
border-radius: 0;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '▶';
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
transform: translateX(5px);
|
||||
}
|
||||
|
||||
.btn-red {
|
||||
background: var(--btn-red-gradient);
|
||||
color: white;
|
||||
border-color: var(--red-1);
|
||||
box-shadow: 0 0 20px rgba(255, 60, 60, 0.5), 0 0 40px rgba(255, 60, 60, 0.3);
|
||||
}
|
||||
|
||||
.btn-red:hover {
|
||||
transform: scale(1.04);
|
||||
box-shadow: 0 0 30px rgba(255, 60, 60, 0.7), 0 0 60px rgba(255, 60, 60, 0.4);
|
||||
}
|
||||
|
||||
.btn-cyan {
|
||||
background: var(--btn-cyan-gradient);
|
||||
color: #000;
|
||||
border-color: var(--cyan-1);
|
||||
box-shadow: 0 0 20px rgba(0, 255, 255, 0.5), 0 0 40px rgba(0, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.btn-cyan:hover {
|
||||
transform: scale(1.04);
|
||||
box-shadow: 0 0 30px rgba(0, 255, 255, 0.7), 0 0 60px rgba(0, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.btn-yellow {
|
||||
background: var(--btn-yellow-gradient);
|
||||
color: #000;
|
||||
border-color: var(--yellow-1);
|
||||
box-shadow: 0 0 20px rgba(255, 255, 0, 0.5), 0 0 40px rgba(255, 255, 0, 0.3);
|
||||
}
|
||||
|
||||
.btn-yellow:hover {
|
||||
transform: scale(1.04);
|
||||
box-shadow: 0 0 30px rgba(255, 255, 0, 0.7), 0 0 60px rgba(255, 255, 0, 0.4);
|
||||
}
|
||||
|
||||
/* ===== CARDS & PANELS ===== */
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--border-color);
|
||||
border-left: var(--border-width-thick) solid var(--red-1);
|
||||
border-radius: 0;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card::before {
|
||||
content: '■';
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
color: var(--red-1);
|
||||
font-size: 1.5rem;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.card-elevated {
|
||||
background: var(--bg-elevated);
|
||||
backdrop-filter: blur(10px);
|
||||
border: var(--border-width) solid var(--cyan-2);
|
||||
border-radius: 0;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-glow-red {
|
||||
box-shadow: 0 0 30px rgba(255, 60, 60, 0.4),
|
||||
inset 0 0 20px rgba(255, 60, 60, 0.1);
|
||||
}
|
||||
|
||||
.card-glow-cyan {
|
||||
box-shadow: 0 0 30px rgba(0, 255, 255, 0.4),
|
||||
inset 0 0 20px rgba(0, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.card-propaganda {
|
||||
background: rgba(232, 232, 232, 0.95);
|
||||
border: var(--border-width-thick) solid var(--red-2);
|
||||
color: #1a1a1a;
|
||||
padding: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 0 40px rgba(204, 0, 0, 0.4);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-propaganda::after {
|
||||
content: '☭';
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
font-size: 4rem;
|
||||
opacity: 0.1;
|
||||
color: var(--red-2);
|
||||
}
|
||||
|
||||
.card-propaganda h1,
|
||||
.card-propaganda h2,
|
||||
.card-propaganda h3,
|
||||
.card-propaganda h4,
|
||||
.card-propaganda h5,
|
||||
.card-propaganda h6 {
|
||||
color: var(--red-3);
|
||||
background: none;
|
||||
-webkit-text-fill-color: var(--red-3);
|
||||
}
|
||||
|
||||
.card-propaganda p,
|
||||
.card-propaganda li {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.card-propaganda strong {
|
||||
color: var(--red-2);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* ===== BADGES ===== */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: 0;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
border: var(--border-width) solid;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
.badge-red {
|
||||
background: rgba(255, 60, 60, 0.15);
|
||||
color: var(--red-1);
|
||||
border-color: var(--red-1);
|
||||
box-shadow: 0 0 15px rgba(255, 60, 60, 0.3);
|
||||
}
|
||||
|
||||
.badge-cyan {
|
||||
background: rgba(0, 255, 255, 0.15);
|
||||
color: var(--cyan-1);
|
||||
border-color: var(--cyan-1);
|
||||
box-shadow: 0 0 15px rgba(0, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.badge-yellow {
|
||||
background: rgba(255, 255, 0, 0.15);
|
||||
color: var(--yellow-1);
|
||||
border-color: var(--yellow-1);
|
||||
box-shadow: 0 0 15px rgba(255, 255, 0, 0.3);
|
||||
}
|
||||
|
||||
/* ===== ALERTS ===== */
|
||||
.alert {
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: 0;
|
||||
border: var(--border-width) solid;
|
||||
border-left: var(--border-width-thick) solid;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.alert-red {
|
||||
background: rgba(255, 60, 60, 0.1);
|
||||
border-color: var(--red-1);
|
||||
border-left-color: var(--red-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(255, 60, 60, 0.2);
|
||||
}
|
||||
|
||||
.alert-cyan {
|
||||
background: rgba(0, 255, 255, 0.1);
|
||||
border-color: var(--cyan-1);
|
||||
border-left-color: var(--cyan-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(0, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.alert-yellow {
|
||||
background: rgba(255, 255, 0, 0.1);
|
||||
border-color: var(--yellow-1);
|
||||
border-left-color: var(--yellow-1);
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 20px rgba(255, 255, 0, 0.2);
|
||||
}
|
||||
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.text-center { text-align: center; }
|
||||
.mt-2 { margin-top: 1rem; }
|
||||
.mb-3 { margin-bottom: 1.5rem; }
|
||||
|
||||
/* ===== HORIZONTAL RULE ===== */
|
||||
hr {
|
||||
border: none;
|
||||
height: var(--border-width-thick);
|
||||
background: linear-gradient(to right,
|
||||
var(--red-1),
|
||||
var(--cyan-1),
|
||||
var(--yellow-1));
|
||||
margin: 2.5rem 0;
|
||||
box-shadow: 0 0 20px rgba(255, 60, 60, 0.3);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- HEADER -->
|
||||
<header class="text-center mb-3">
|
||||
<h1>SOVIET CYBERPUNK</h1>
|
||||
<p style="font-size: 1.25rem; color: var(--cyan-1); text-shadow: 0 0 15px rgba(0,255,255,0.5);">КРАСНЫЙ НЕОН | BRUTALIST FUTURE | CONSTRUCTIVIST CODE</p>
|
||||
</header>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- UNIQUE FEATURE SHOWCASE -->
|
||||
<section class="mb-3">
|
||||
<div class="card-propaganda">
|
||||
<h2>⚡ UNIQUE FEATURE: CRT SCAN LINES</h2>
|
||||
<p>This design system features <strong>animated CRT scan lines</strong> that continuously sweep across the entire screen, simulating old Soviet-era monitors and Cold War terminals.</p>
|
||||
<p>The scan lines use a dual-layer approach: one layer animates vertically, while a static layer provides the baseline CRT texture. This creates an <em>authentic retro-futuristic experience</em>.</p>
|
||||
<p>Notice the blinking cursor (█) after H1 headings and the arrow (▶) decorators on buttons—small details that enhance the terminal aesthetic.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- COLOR PALETTE -->
|
||||
<section class="mb-3">
|
||||
<h2>NEON SPECTRUM</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card" style="background: var(--red-1); color: #000;">
|
||||
<h4 style="color: #000;">NEON RED</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000; border-color: #000;">#ff3c3c</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--cyan-1); color: #000;">
|
||||
<h4 style="color: #000;">COLD CYAN</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000; border-color: #000;">#00ffff</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--yellow-1); color: #000;">
|
||||
<h4 style="color: #000;">WARNING YELLOW</h4>
|
||||
<code style="background: rgba(0,0,0,0.3); color: #000; border-color: #000;">#ffff00</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--red-2); color: white;">
|
||||
<h4 style="color: white;">SOVIET RED</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#cc0000</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--cyan-3); color: white;">
|
||||
<h4 style="color: white;">DARK TEAL</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#008b8b</code>
|
||||
</div>
|
||||
<div class="card" style="background: var(--red-3); color: white;">
|
||||
<h4 style="color: white;">DARK CRIMSON</h4>
|
||||
<code style="background: rgba(255,255,255,0.2); color: white; border-color: white;">#990000</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- BUTTONS -->
|
||||
<section class="mb-3">
|
||||
<h2>COMMAND BUTTONS</h2>
|
||||
<div class="grid grid-3">
|
||||
<div class="card card-glow-red">
|
||||
<h3>RED</h3>
|
||||
<button class="btn btn-red">EXECUTE</button>
|
||||
</div>
|
||||
<div class="card card-glow-cyan">
|
||||
<h3>CYAN</h3>
|
||||
<button class="btn btn-cyan">ACCESS</button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>YELLOW</h3>
|
||||
<button class="btn btn-yellow">WARNING</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- BADGES -->
|
||||
<section class="mb-3">
|
||||
<h2>STATUS BADGES</h2>
|
||||
<div class="card">
|
||||
<span class="badge badge-red">ACTIVE</span>
|
||||
<span class="badge badge-cyan">ONLINE</span>
|
||||
<span class="badge badge-yellow">ALERT</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- ALERTS -->
|
||||
<section class="mb-3">
|
||||
<h2>SYSTEM MESSAGES</h2>
|
||||
<div class="alert alert-red">
|
||||
<strong>PRIORITY ALERT:</strong> Central processing unit operating at maximum capacity.
|
||||
</div>
|
||||
<div class="alert alert-cyan">
|
||||
<strong>SYSTEM INFO:</strong> Network connection established to collective mainframe.
|
||||
</div>
|
||||
<div class="alert alert-yellow">
|
||||
<strong>CAUTION:</strong> Memory buffer approaching critical threshold.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PHILOSOPHY -->
|
||||
<section class="mb-3">
|
||||
<h2>DESIGN PRINCIPLES</h2>
|
||||
<div class="card-propaganda">
|
||||
<h3>CONSTRUCTIVIST CODE MANIFESTO</h3>
|
||||
<ul>
|
||||
<li><strong>BRUTALIST GEOMETRY:</strong> Sharp angles, thick borders, constructivist precision</li>
|
||||
<li><strong>CRT AESTHETICS:</strong> Animated scan lines simulate Soviet-era terminals</li>
|
||||
<li><strong>NEON TRINITY:</strong> Red (revolution), Cyan (cold future), Yellow (warning)</li>
|
||||
<li><strong>MONOSPACE EVERYWHERE:</strong> Terminal-style typography throughout</li>
|
||||
<li><strong>UPPERCASE POWER:</strong> Command-line authority in every heading</li>
|
||||
<li><strong>SOVIET SYMBOLS:</strong> Hammer and sickle (☭), geometric blocks (■)</li>
|
||||
<li><strong>PROPAGANDA CARDS:</strong> Light backgrounds with heavy red borders</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="card card-glow-red text-center" style="padding: 2rem;">
|
||||
<h2>SOVIET CYBERPUNK COMPLETE</h2>
|
||||
<p style="margin-top: 1rem;">THE FUTURE WAS BUILT IN CONCRETE AND NEON ☭⚡</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
60
DumperCan/WAMEX/README.md
Normal file
60
DumperCan/WAMEX/README.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# wa.me Extractor — setup
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.10+ (uses `match` syntax / union types in hints)
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
pip install beautifulsoup4
|
||||
```
|
||||
|
||||
`tkinter` ships with most Python installations on Linux.
|
||||
If it's missing:
|
||||
```bash
|
||||
# Debian/Ubuntu
|
||||
sudo apt install python3-tk
|
||||
|
||||
# Arch
|
||||
sudo pacman -S tk
|
||||
|
||||
# Fedora
|
||||
sudo dnf install python3-tkinter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
python wa_extractor.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow
|
||||
|
||||
1. In WhatsApp Web, open the pending requests panel.
|
||||
2. Right-click the outer div containing all requests → **Inspect**.
|
||||
3. In DevTools, right-click the `<div>` element → **Copy** → **Outer HTML**.
|
||||
4. Paste into a `.txt` file (or directly into the left pane of the app).
|
||||
5. Hit **⚡ extract**.
|
||||
6. Adjust batch size if needed (default 20 — good for spam-safe manual invites).
|
||||
7. **Save .txt** or **Copy all** to share with your community admins.
|
||||
|
||||
---
|
||||
|
||||
## Output format
|
||||
|
||||
```
|
||||
https://wa.me/+27821234567
|
||||
https://wa.me/+27831234567
|
||||
... (20 links)
|
||||
|
||||
────────────────────────────────────────
|
||||
https://wa.me/+27841234567
|
||||
...
|
||||
```
|
||||
|
||||
Each block = one admin's batch for the day.
|
||||
644
DumperCan/appimage-installation-guide.md
Normal file
644
DumperCan/appimage-installation-guide.md
Normal file
@@ -0,0 +1,644 @@
|
||||
# Complete AppImage Installation Guide
|
||||
## Universal Methods for Any AppImage Application
|
||||
|
||||
## 📦 What is AppImage?
|
||||
|
||||
AppImage is a portable application format for Linux. Think of it like a Windows `.exe` - it's a single file that contains everything the application needs to run.
|
||||
|
||||
**Key Features:**
|
||||
- ✅ **No installation required** - just download and run
|
||||
- ✅ **No root/sudo needed** - runs as regular user
|
||||
- ✅ **Self-contained** - includes all dependencies
|
||||
- ✅ **Portable** - works across different Linux distributions
|
||||
- ✅ **No system pollution** - doesn't scatter files everywhere
|
||||
- ✅ **Easy to remove** - just delete the file
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Method 1: Quick & Dirty (Just Run It)
|
||||
|
||||
The simplest way - no integration with system menus.
|
||||
|
||||
### Step 1: Download AppImage
|
||||
```bash
|
||||
# Example: Download to Downloads folder
|
||||
cd ~/Downloads
|
||||
wget https://example.com/app-name.AppImage
|
||||
|
||||
# Or use your browser to download
|
||||
```
|
||||
|
||||
### Step 2: Make Executable
|
||||
```bash
|
||||
chmod +x ~/Downloads/app-name.AppImage
|
||||
```
|
||||
|
||||
### Step 3: Run It
|
||||
```bash
|
||||
./app-name.AppImage
|
||||
```
|
||||
|
||||
**That's it!** The app runs directly from the file.
|
||||
|
||||
**Pros:**
|
||||
- Immediate - works in 3 commands
|
||||
- No system changes
|
||||
- Easy to test applications
|
||||
|
||||
**Cons:**
|
||||
- Not in application menu
|
||||
- Must run from terminal or file manager
|
||||
- No desktop integration
|
||||
- Stays in Downloads folder
|
||||
|
||||
---
|
||||
|
||||
## 🏠 Method 2: Proper Installation (Recommended)
|
||||
|
||||
Integrate AppImage into your system like a native application.
|
||||
|
||||
### Step 1: Create AppImages Directory
|
||||
```bash
|
||||
# Standard location for user applications
|
||||
mkdir -p ~/Applications
|
||||
|
||||
# Alternative locations:
|
||||
# ~/.local/bin/ (for command-line tools)
|
||||
# ~/.local/share/apps/ (alternative app directory)
|
||||
```
|
||||
|
||||
### Step 2: Move AppImage to Applications
|
||||
```bash
|
||||
# Move from Downloads
|
||||
mv ~/Downloads/app-name.AppImage ~/Applications/
|
||||
|
||||
# Make executable
|
||||
chmod +x ~/Applications/app-name.AppImage
|
||||
```
|
||||
|
||||
### Step 3: Create Desktop Entry
|
||||
|
||||
**Automatic Method (if AppImage supports it):**
|
||||
```bash
|
||||
# Some AppImages can integrate themselves
|
||||
cd ~/Applications
|
||||
./app-name.AppImage --appimage-integrate
|
||||
|
||||
# Or
|
||||
./app-name.AppImage --install
|
||||
```
|
||||
|
||||
**Manual Method (universal - works for any AppImage):**
|
||||
|
||||
```bash
|
||||
# Create desktop entry file
|
||||
nano ~/.local/share/applications/app-name.desktop
|
||||
```
|
||||
|
||||
**Template - Copy and customize:**
|
||||
```ini
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Application Name
|
||||
Comment=Brief description of the app
|
||||
Icon=/home/jl-kruger/Applications/app-name-icon.png
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage
|
||||
Terminal=false
|
||||
Categories=Utility;
|
||||
# Common categories: Network;WebBrowser;Development;Graphics;AudioVideo;Office;Utility;Game;
|
||||
```
|
||||
|
||||
**Make executable and update database:**
|
||||
```bash
|
||||
chmod +x ~/.local/share/applications/app-name.desktop
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
```
|
||||
|
||||
### Step 4: Extract Icon (Optional)
|
||||
|
||||
Many AppImages contain their own icon. Extract it:
|
||||
|
||||
```bash
|
||||
# Extract AppImage contents to temporary directory
|
||||
cd ~/Applications
|
||||
./app-name.AppImage --appimage-extract
|
||||
|
||||
# Icons are usually in: squashfs-root/usr/share/icons/ or squashfs-root/
|
||||
# Find the icon
|
||||
find squashfs-root -name "*.png" -o -name "*.svg" | grep -i icon
|
||||
|
||||
# Copy icon to a permanent location
|
||||
cp squashfs-root/path/to/icon.png ~/Applications/app-name-icon.png
|
||||
|
||||
# Update desktop entry with correct icon path
|
||||
nano ~/.local/share/applications/app-name.desktop
|
||||
# Set: Icon=/home/jl-kruger/Applications/app-name-icon.png
|
||||
|
||||
# Clean up extracted files
|
||||
rm -rf squashfs-root
|
||||
```
|
||||
|
||||
**Icon Alternatives:**
|
||||
```bash
|
||||
# Use system icon (if available)
|
||||
Icon=application-default-icon
|
||||
|
||||
# Use absolute path
|
||||
Icon=/home/jl-kruger/Applications/app-icon.png
|
||||
|
||||
# Use icon name (if installed in system)
|
||||
Icon=app-name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🤖 Method 3: AppImageLauncher (Automated Integration)
|
||||
|
||||
AppImageLauncher automatically integrates AppImages when you first run them.
|
||||
|
||||
### Install AppImageLauncher
|
||||
|
||||
**Ubuntu/Mint/Debian:**
|
||||
```bash
|
||||
# Download from GitHub
|
||||
cd ~/Downloads
|
||||
wget https://github.com/TheAssassin/AppImageLauncher/releases/download/v2.2.0/appimagelauncher_2.2.0-travis995.0f91801.bionic_amd64.deb
|
||||
|
||||
# Install
|
||||
sudo apt install ./appimagelauncher_*.deb
|
||||
```
|
||||
|
||||
**Or build from source:**
|
||||
```bash
|
||||
sudo apt install cmake g++ libqt5core5a qtbase5-dev libcairo2-dev git
|
||||
git clone https://github.com/TheAssassin/AppImageLauncher.git
|
||||
cd AppImageLauncher
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### How AppImageLauncher Works
|
||||
|
||||
After installation:
|
||||
|
||||
1. **Double-click any AppImage** in file manager
|
||||
2. AppImageLauncher prompts: "Integrate and run" or "Run once"
|
||||
3. Choose **"Integrate and run"**
|
||||
4. AppImage is:
|
||||
- Moved to `~/Applications/`
|
||||
- Made executable
|
||||
- Desktop entry created automatically
|
||||
- Icon extracted and set up
|
||||
- Appears in application menu
|
||||
|
||||
**Benefits:**
|
||||
- Fully automated process
|
||||
- Consistent AppImage management
|
||||
- Update checking built-in
|
||||
- Easy removal through GUI
|
||||
|
||||
---
|
||||
|
||||
## 📝 Complete Desktop Entry Reference
|
||||
|
||||
### Minimal Desktop Entry
|
||||
```ini
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=MyApp
|
||||
Exec=/home/jl-kruger/Applications/myapp.AppImage
|
||||
```
|
||||
|
||||
### Full-Featured Desktop Entry
|
||||
```ini
|
||||
[Desktop Entry]
|
||||
# Required fields
|
||||
Type=Application
|
||||
Name=Application Name
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage %u
|
||||
|
||||
# Recommended fields
|
||||
Comment=What this application does
|
||||
Icon=/home/jl-kruger/Applications/app-icon.png
|
||||
Terminal=false
|
||||
Categories=Utility;Development;
|
||||
|
||||
# Optional fields
|
||||
GenericName=Generic description
|
||||
Keywords=search;terms;keywords;
|
||||
StartupNotify=true
|
||||
StartupWMClass=app-window-class
|
||||
MimeType=text/plain;text/html;
|
||||
|
||||
# For terminal applications
|
||||
# Terminal=true
|
||||
|
||||
# Launch in specific directory
|
||||
# Path=/home/jl-kruger/workspace
|
||||
|
||||
# Multiple actions (right-click menu)
|
||||
Actions=NewWindow;SafeMode;
|
||||
|
||||
[Desktop Action NewWindow]
|
||||
Name=New Window
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage --new-window
|
||||
|
||||
[Desktop Action SafeMode]
|
||||
Name=Safe Mode
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage --safe-mode
|
||||
```
|
||||
|
||||
### Common Categories
|
||||
```
|
||||
# Desktop/GUI applications
|
||||
Utility - System utilities
|
||||
Development - IDEs, editors, dev tools
|
||||
Graphics - Image editors, viewers
|
||||
AudioVideo - Media players, editors
|
||||
Network - Browsers, chat, email
|
||||
Office - Word processors, spreadsheets
|
||||
Game - Games
|
||||
Education - Educational software
|
||||
Science - Scientific applications
|
||||
|
||||
# System/Tools
|
||||
System - System administration
|
||||
Settings - Configuration tools
|
||||
FileManager - File managers
|
||||
TerminalEmulator - Terminal applications
|
||||
|
||||
# Multiple categories (semicolon separated)
|
||||
Categories=Development;TextEditor;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Updating AppImages
|
||||
|
||||
AppImages don't auto-update. You need to manually update them.
|
||||
|
||||
### Manual Update Process
|
||||
|
||||
```bash
|
||||
# 1. Download new version
|
||||
cd ~/Downloads
|
||||
wget https://example.com/app-name-new-version.AppImage
|
||||
|
||||
# 2. Backup old version (optional)
|
||||
mv ~/Applications/app-name.AppImage ~/Applications/app-name.AppImage.old
|
||||
|
||||
# 3. Install new version
|
||||
mv ~/Downloads/app-name-new-version.AppImage ~/Applications/app-name.AppImage
|
||||
chmod +x ~/Applications/app-name.AppImage
|
||||
|
||||
# 4. Test new version
|
||||
~/Applications/app-name.AppImage
|
||||
|
||||
# 5. Remove old version once confirmed working
|
||||
rm ~/Applications/app-name.AppImage.old
|
||||
```
|
||||
|
||||
**Note:** Desktop entry continues to work since the filename stays the same.
|
||||
|
||||
### Update Checking Tools
|
||||
|
||||
**AppImageUpdate:**
|
||||
```bash
|
||||
# Download AppImageUpdate
|
||||
wget https://github.com/AppImage/AppImageUpdate/releases/download/continuous/AppImageUpdate-x86_64.AppImage
|
||||
chmod +x AppImageUpdate-x86_64.AppImage
|
||||
|
||||
# Update an AppImage
|
||||
./AppImageUpdate-x86_64.AppImage ~/Applications/app-name.AppImage
|
||||
```
|
||||
|
||||
**AppImageLauncher** (if installed):
|
||||
- Right-click AppImage in file manager
|
||||
- Select "Update"
|
||||
- Automatic update if available
|
||||
|
||||
---
|
||||
|
||||
## 🗑️ Removing AppImages
|
||||
|
||||
### Complete Removal
|
||||
|
||||
```bash
|
||||
# 1. Remove the AppImage file
|
||||
rm ~/Applications/app-name.AppImage
|
||||
|
||||
# 2. Remove desktop entry
|
||||
rm ~/.local/share/applications/app-name.desktop
|
||||
|
||||
# 3. Update desktop database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# 4. Remove icon (if extracted separately)
|
||||
rm ~/Applications/app-name-icon.png
|
||||
|
||||
# 5. Remove app config/cache (varies by app)
|
||||
rm -rf ~/.config/app-name
|
||||
rm -rf ~/.local/share/app-name
|
||||
rm -rf ~/.cache/app-name
|
||||
```
|
||||
|
||||
**That's it!** No leftover system files, dependencies, or registry entries.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Issue: "Permission denied" when running AppImage
|
||||
|
||||
```bash
|
||||
# Make executable
|
||||
chmod +x app-name.AppImage
|
||||
|
||||
# If still fails, check if file is corrupted
|
||||
file app-name.AppImage
|
||||
# Should say: "ELF 64-bit LSB executable"
|
||||
```
|
||||
|
||||
### Issue: FUSE errors - "AppImages require FUSE to run"
|
||||
|
||||
```bash
|
||||
# Install FUSE
|
||||
sudo apt install fuse libfuse2
|
||||
|
||||
# Enable user namespaces
|
||||
sudo sysctl -w kernel.unprivileged_userns_clone=1
|
||||
echo "kernel.unprivileged_userns_clone=1" | sudo tee -a /etc/sysctl.conf
|
||||
|
||||
# Or extract and run without FUSE
|
||||
./app-name.AppImage --appimage-extract
|
||||
./squashfs-root/AppRun
|
||||
```
|
||||
|
||||
### Issue: AppImage won't run - missing libraries
|
||||
|
||||
```bash
|
||||
# Check what's missing
|
||||
./app-name.AppImage
|
||||
# Error messages will show missing libraries
|
||||
|
||||
# Install common dependencies
|
||||
sudo apt install libfuse2 libgl1 libxcb1
|
||||
|
||||
# Check required libraries
|
||||
ldd app-name.AppImage
|
||||
```
|
||||
|
||||
### Issue: Desktop entry not appearing in menu
|
||||
|
||||
```bash
|
||||
# Validate desktop entry
|
||||
desktop-file-validate ~/.local/share/applications/app-name.desktop
|
||||
|
||||
# Update database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# Restart desktop environment
|
||||
xfce4-panel -r
|
||||
|
||||
# Or logout/login
|
||||
```
|
||||
|
||||
### Issue: Icon not showing
|
||||
|
||||
```bash
|
||||
# Use absolute path for icon
|
||||
Icon=/home/jl-kruger/Applications/app-icon.png
|
||||
|
||||
# Not relative path
|
||||
# Icon=~/Applications/app-icon.png ❌
|
||||
|
||||
# Verify icon exists
|
||||
ls -lh /home/jl-kruger/Applications/app-icon.png
|
||||
```
|
||||
|
||||
### Issue: AppImage is slow to start
|
||||
|
||||
```bash
|
||||
# Some AppImages extract on each run
|
||||
# Solution: Extract once and run from extracted location
|
||||
|
||||
./app-name.AppImage --appimage-extract
|
||||
chmod +x squashfs-root/AppRun
|
||||
|
||||
# Update desktop entry to point to AppRun
|
||||
Exec=/home/jl-kruger/Applications/squashfs-root/AppRun
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 AppImage vs Other Formats
|
||||
|
||||
| Feature | AppImage | Flatpak | Snap | Native (.deb) |
|
||||
|---------|----------|---------|------|---------------|
|
||||
| **No root needed** | ✅ | ❌ | ❌ | ❌ |
|
||||
| **Single file** | ✅ | ❌ | ❌ | ❌ |
|
||||
| **System integration** | Manual | Automatic | Automatic | Automatic |
|
||||
| **Auto-updates** | ❌ | ✅ | ✅ | ✅ |
|
||||
| **Sandboxing** | ❌ | ✅ | ✅ | ❌ |
|
||||
| **Disk space** | Efficient | High | High | Efficient |
|
||||
| **Startup speed** | Fast | Slow | Slow | Fast |
|
||||
| **Portability** | ✅ | ❌ | ❌ | ❌ |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
~/Applications/
|
||||
├── logseq.AppImage
|
||||
├── logseq-icon.png
|
||||
├── obsidian.AppImage
|
||||
├── obsidian-icon.png
|
||||
├── postman.AppImage
|
||||
└── postman-icon.png
|
||||
|
||||
~/.local/share/applications/
|
||||
├── logseq.desktop
|
||||
├── obsidian.desktop
|
||||
└── postman.desktop
|
||||
```
|
||||
|
||||
### Naming Convention
|
||||
|
||||
Use consistent, lowercase names with hyphens:
|
||||
```bash
|
||||
# Good
|
||||
app-name.AppImage
|
||||
app-name-icon.png
|
||||
app-name.desktop
|
||||
|
||||
# Avoid
|
||||
AppName.AppImage
|
||||
app_name.AppImage
|
||||
ApplicationName.AppImage
|
||||
```
|
||||
|
||||
### Version Management
|
||||
|
||||
Include version in backup:
|
||||
```bash
|
||||
# Before updating
|
||||
mv ~/Applications/app-name.AppImage ~/Applications/app-name-v1.2.3.AppImage
|
||||
|
||||
# Install new version
|
||||
mv ~/Downloads/app-name-v1.3.0.AppImage ~/Applications/app-name.AppImage
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
Keep notes on installed AppImages:
|
||||
```bash
|
||||
# Create manifest
|
||||
nano ~/Applications/README.md
|
||||
```
|
||||
|
||||
```markdown
|
||||
# Installed AppImages
|
||||
|
||||
## Logseq v0.10.9
|
||||
- Source: https://github.com/logseq/logseq/releases
|
||||
- Installed: 2025-10-24
|
||||
- Purpose: Knowledge management
|
||||
|
||||
## Obsidian v1.5.3
|
||||
- Source: https://obsidian.md/
|
||||
- Installed: 2025-10-20
|
||||
- Purpose: Note-taking
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Finding AppImages
|
||||
|
||||
### Official Sources
|
||||
|
||||
1. **Project's GitHub Releases Page**
|
||||
- Most reliable source
|
||||
- Example: `https://github.com/username/project/releases`
|
||||
|
||||
2. **Official Website**
|
||||
- Often has download page with AppImage option
|
||||
- Look for "Download for Linux"
|
||||
|
||||
3. **AppImageHub** (archived)
|
||||
- Historical catalog: https://www.appimagehub.com/
|
||||
|
||||
### Safety Check
|
||||
|
||||
```bash
|
||||
# Verify checksum (if provided)
|
||||
sha256sum app-name.AppImage
|
||||
# Compare with official checksum
|
||||
|
||||
# Check file type
|
||||
file app-name.AppImage
|
||||
# Should be: ELF 64-bit LSB executable
|
||||
|
||||
# Scan with system tools
|
||||
clamscan app-name.AppImage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Quick Reference Commands
|
||||
|
||||
```bash
|
||||
# Make executable
|
||||
chmod +x app-name.AppImage
|
||||
|
||||
# Run AppImage
|
||||
./app-name.AppImage
|
||||
|
||||
# Extract contents
|
||||
./app-name.AppImage --appimage-extract
|
||||
|
||||
# Help (some AppImages)
|
||||
./app-name.AppImage --appimage-help
|
||||
|
||||
# Get AppImage info
|
||||
./app-name.AppImage --appimage-version
|
||||
|
||||
# Create desktop entry
|
||||
nano ~/.local/share/applications/app-name.desktop
|
||||
|
||||
# Update desktop database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# Validate desktop entry
|
||||
desktop-file-validate ~/.local/share/applications/app-name.desktop
|
||||
|
||||
# Test launch from desktop entry
|
||||
gtk-launch app-name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Real-World Example: Installing Logseq
|
||||
|
||||
**Complete walkthrough from download to desktop integration:**
|
||||
|
||||
```bash
|
||||
# 1. Download
|
||||
cd ~/Downloads
|
||||
wget https://github.com/logseq/logseq/releases/download/0.10.9/Logseq-linux-x64-0.10.9.AppImage
|
||||
|
||||
# 2. Create applications directory
|
||||
mkdir -p ~/Applications
|
||||
|
||||
# 3. Move and rename
|
||||
mv Logseq-linux-x64-0.10.9.AppImage ~/Applications/logseq.AppImage
|
||||
|
||||
# 4. Make executable
|
||||
chmod +x ~/Applications/logseq.AppImage
|
||||
|
||||
# 5. Extract icon
|
||||
cd ~/Applications
|
||||
./logseq.AppImage --appimage-extract
|
||||
cp squashfs-root/logseq.png ~/Applications/logseq-icon.png
|
||||
rm -rf squashfs-root
|
||||
|
||||
# 6. Create desktop entry
|
||||
cat > ~/.local/share/applications/logseq.desktop << 'EOF'
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Logseq
|
||||
Comment=A privacy-first, open-source knowledge base
|
||||
Icon=/home/jl-kruger/Applications/logseq-icon.png
|
||||
Exec=/home/jl-kruger/Applications/logseq.AppImage
|
||||
Terminal=false
|
||||
Categories=Office;Utility;
|
||||
StartupNotify=true
|
||||
EOF
|
||||
|
||||
# 7. Make desktop entry executable
|
||||
chmod +x ~/.local/share/applications/logseq.desktop
|
||||
|
||||
# 8. Update desktop database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# 9. Launch!
|
||||
gtk-launch logseq
|
||||
# Or find "Logseq" in application menu
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Additional Resources
|
||||
|
||||
- **AppImage Documentation:** https://docs.appimage.org/
|
||||
- **Desktop Entry Specification:** https://specifications.freedesktop.org/desktop-entry-spec/
|
||||
- **Icon Theme Specification:** https://specifications.freedesktop.org/icon-theme-spec/
|
||||
- **AppImageLauncher:** https://github.com/TheAssassin/AppImageLauncher
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** October 2025 | Linux Mint 22.2 Xfce
|
||||
353
DumperCan/appimage-quick-reference.md
Normal file
353
DumperCan/appimage-quick-reference.md
Normal file
@@ -0,0 +1,353 @@
|
||||
# AppImage Quick Reference Card
|
||||
|
||||
## 🚀 Basic Operations
|
||||
|
||||
### Download and Run (Quick Test)
|
||||
```bash
|
||||
# Make executable
|
||||
chmod +x app-name.AppImage
|
||||
|
||||
# Run it
|
||||
./app-name.AppImage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏠 Proper Installation
|
||||
|
||||
### Using the Automated Script
|
||||
```bash
|
||||
# Simple - script will prompt for details
|
||||
bash install-appimage.sh ~/Downloads/app-name.AppImage
|
||||
|
||||
# With all options
|
||||
bash install-appimage.sh ~/Downloads/app-name.AppImage my-app-name Office
|
||||
```
|
||||
|
||||
### Manual Installation
|
||||
```bash
|
||||
# 1. Move to Applications
|
||||
mkdir -p ~/Applications
|
||||
mv ~/Downloads/app-name.AppImage ~/Applications/
|
||||
chmod +x ~/Applications/app-name.AppImage
|
||||
|
||||
# 2. Create desktop entry
|
||||
nano ~/.local/share/applications/app-name.desktop
|
||||
|
||||
# 3. Paste this template (edit as needed):
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=App Name
|
||||
Comment=Brief description
|
||||
Icon=/home/jl-kruger/Applications/app-icon.png
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage
|
||||
Terminal=false
|
||||
Categories=Utility;
|
||||
|
||||
# 4. Update database
|
||||
chmod +x ~/.local/share/applications/app-name.desktop
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Extract Icon from AppImage
|
||||
|
||||
```bash
|
||||
# Extract AppImage contents
|
||||
./app-name.AppImage --appimage-extract
|
||||
|
||||
# Find icon
|
||||
find squashfs-root -name "*.png" | grep -i icon
|
||||
|
||||
# Copy icon
|
||||
cp squashfs-root/path/to/icon.png ~/Applications/app-icon.png
|
||||
|
||||
# Clean up
|
||||
rm -rf squashfs-root
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Update AppImage
|
||||
|
||||
```bash
|
||||
# 1. Download new version
|
||||
cd ~/Downloads
|
||||
|
||||
# 2. Backup current version
|
||||
mv ~/Applications/app-name.AppImage ~/Applications/app-name.AppImage.old
|
||||
|
||||
# 3. Install new version
|
||||
mv ~/Downloads/app-name-new.AppImage ~/Applications/app-name.AppImage
|
||||
chmod +x ~/Applications/app-name.AppImage
|
||||
|
||||
# 4. Test
|
||||
~/Applications/app-name.AppImage
|
||||
|
||||
# 5. Remove backup once confirmed
|
||||
rm ~/Applications/app-name.AppImage.old
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗑️ Remove AppImage
|
||||
|
||||
```bash
|
||||
# Complete removal
|
||||
rm ~/Applications/app-name.AppImage
|
||||
rm ~/Applications/app-icon.png
|
||||
rm ~/.local/share/applications/app-name.desktop
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# Also remove app data (if exists)
|
||||
rm -rf ~/.config/app-name
|
||||
rm -rf ~/.local/share/app-name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Permission Denied
|
||||
```bash
|
||||
chmod +x app-name.AppImage
|
||||
```
|
||||
|
||||
### FUSE Error
|
||||
```bash
|
||||
# Install FUSE
|
||||
sudo apt install fuse libfuse2
|
||||
|
||||
# Or run without FUSE
|
||||
./app-name.AppImage --appimage-extract
|
||||
./squashfs-root/AppRun
|
||||
```
|
||||
|
||||
### Desktop Entry Not Appearing
|
||||
```bash
|
||||
# Validate
|
||||
desktop-file-validate ~/.local/share/applications/app-name.desktop
|
||||
|
||||
# Update database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# Restart panel
|
||||
xfce4-panel -r
|
||||
```
|
||||
|
||||
### Missing Libraries
|
||||
```bash
|
||||
# Check what's missing
|
||||
ldd app-name.AppImage
|
||||
|
||||
# Install common deps
|
||||
sudo apt install libfuse2 libgl1 libxcb1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Desktop Entry Template
|
||||
|
||||
### Basic
|
||||
```ini
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=App Name
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage
|
||||
Icon=/home/jl-kruger/Applications/app-icon.png
|
||||
Terminal=false
|
||||
Categories=Utility;
|
||||
```
|
||||
|
||||
### With Multiple Actions
|
||||
```ini
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=App Name
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage
|
||||
Icon=/home/jl-kruger/Applications/app-icon.png
|
||||
Terminal=false
|
||||
Categories=Development;
|
||||
Actions=SafeMode;Debug;
|
||||
|
||||
[Desktop Action SafeMode]
|
||||
Name=Safe Mode
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage --safe-mode
|
||||
|
||||
[Desktop Action Debug]
|
||||
Name=Debug Mode
|
||||
Exec=/home/jl-kruger/Applications/app-name.AppImage --debug
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Recommended Directory Structure
|
||||
|
||||
```
|
||||
~/Applications/
|
||||
├── app1.AppImage
|
||||
├── app1-icon.png
|
||||
├── app2.AppImage
|
||||
├── app2-icon.png
|
||||
└── README.md # Document what's installed
|
||||
|
||||
~/.local/share/applications/
|
||||
├── app1.desktop
|
||||
└── app2.desktop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Common AppImage Commands
|
||||
|
||||
```bash
|
||||
# Get help (if supported)
|
||||
./app-name.AppImage --appimage-help
|
||||
|
||||
# Get version
|
||||
./app-name.AppImage --appimage-version
|
||||
|
||||
# Extract contents
|
||||
./app-name.AppImage --appimage-extract
|
||||
|
||||
# Self-integrate (if supported)
|
||||
./app-name.AppImage --appimage-integrate
|
||||
|
||||
# Check file type
|
||||
file app-name.AppImage
|
||||
# Should show: ELF 64-bit LSB executable
|
||||
|
||||
# Test launch from desktop entry
|
||||
gtk-launch app-name
|
||||
|
||||
# Check size
|
||||
du -h app-name.AppImage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Categories Reference
|
||||
|
||||
Common categories for desktop entries:
|
||||
|
||||
- **AudioVideo** - Media players, music apps
|
||||
- **Development** - IDEs, text editors, dev tools
|
||||
- **Education** - Learning software
|
||||
- **Game** - Games
|
||||
- **Graphics** - Image editors, viewers, design tools
|
||||
- **Network** - Browsers, email, chat
|
||||
- **Office** - Word processors, spreadsheets, notes
|
||||
- **Science** - Scientific applications
|
||||
- **Settings** - Configuration tools
|
||||
- **System** - System tools
|
||||
- **Utility** - General utilities (default)
|
||||
|
||||
Use semicolon to separate multiple:
|
||||
```ini
|
||||
Categories=Development;TextEditor;Utility;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Find Installed AppImages
|
||||
|
||||
```bash
|
||||
# List all AppImages in Applications
|
||||
ls -lh ~/Applications/*.AppImage
|
||||
|
||||
# Find all desktop entries
|
||||
ls ~/.local/share/applications/*.desktop
|
||||
|
||||
# Search for specific app
|
||||
find ~/Applications -name "*app-name*.AppImage"
|
||||
|
||||
# Check which apps are in menu
|
||||
grep -l "Exec.*AppImage" ~/.local/share/applications/*.desktop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Pro Tips
|
||||
|
||||
### Create Launcher Alias
|
||||
```bash
|
||||
# Add to ~/.bashrc
|
||||
alias myapp='~/Applications/app-name.AppImage'
|
||||
|
||||
# Use it
|
||||
myapp
|
||||
```
|
||||
|
||||
### Version in Filename
|
||||
```bash
|
||||
# Keep track of versions
|
||||
mv app.AppImage app-v1.2.3.AppImage
|
||||
|
||||
# Symlink to latest
|
||||
ln -s app-v1.2.3.AppImage app.AppImage
|
||||
|
||||
# Desktop entry points to symlink
|
||||
Exec=/home/jl-kruger/Applications/app.AppImage
|
||||
```
|
||||
|
||||
### Batch Install Multiple AppImages
|
||||
```bash
|
||||
for appimage in ~/Downloads/*.AppImage; do
|
||||
bash install-appimage.sh "$appimage"
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Security Check
|
||||
|
||||
```bash
|
||||
# Verify file type
|
||||
file app-name.AppImage
|
||||
|
||||
# Check if downloaded correctly
|
||||
sha256sum app-name.AppImage
|
||||
# Compare with official checksum
|
||||
|
||||
# Scan with ClamAV (if installed)
|
||||
clamscan app-name.AppImage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Where to Find AppImages
|
||||
|
||||
1. **Project GitHub Releases**
|
||||
- `https://github.com/username/project/releases`
|
||||
|
||||
2. **Official Website**
|
||||
- Look for "Download for Linux" → AppImage option
|
||||
|
||||
3. **Verify Source**
|
||||
- Only download from official sources
|
||||
- Check file integrity with checksums
|
||||
|
||||
---
|
||||
|
||||
## 📞 Quick Help
|
||||
|
||||
```bash
|
||||
# Installation help
|
||||
bash install-appimage.sh
|
||||
|
||||
# Check if working
|
||||
gtk-launch app-name
|
||||
|
||||
# View desktop entry
|
||||
cat ~/.local/share/applications/app-name.desktop
|
||||
|
||||
# Validate desktop entry
|
||||
desktop-file-validate ~/.local/share/applications/app-name.desktop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Cheat Sheet Version:** 1.0
|
||||
**For:** Linux Mint 22.2 Xfce
|
||||
**Date:** October 2025
|
||||
828
DumperCan/dendritic_links_network_v23.html
Executable file
828
DumperCan/dendritic_links_network_v23.html
Executable file
@@ -0,0 +1,828 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dendritic Links Network</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg, #0B0B0B 0%, #69190D 100%);
|
||||
font-family: 'Courier New', monospace;
|
||||
color: #F2F2BC;
|
||||
overflow-x: hidden;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
padding: 2rem 1rem;
|
||||
background: rgba(11, 11, 11, 0.8);
|
||||
border-bottom: 3px solid;
|
||||
border-image: linear-gradient(90deg, #69190D, #A52C16, #EB7513, #F2C62A, #F2F2BC) 1;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Arial Black', 'Impact', sans-serif;
|
||||
font-size: clamp(1.5rem, 5vw, 3rem);
|
||||
color: #EB7513;
|
||||
text-shadow: 0 0 20px rgba(235, 117, 19, 0.5);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: clamp(0.8rem, 2vw, 1rem);
|
||||
color: #F2C62A;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
flex-wrap: wrap;
|
||||
background: rgba(11, 11, 11, 0.6);
|
||||
border-bottom: 2px solid #442204;
|
||||
}
|
||||
|
||||
.btn-control {
|
||||
padding: 0.6rem 1.2rem;
|
||||
background: linear-gradient(135deg, #442204, #69190D);
|
||||
color: #F2C62A;
|
||||
border: 2px solid #F2C62A;
|
||||
border-radius: 5px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-control:hover {
|
||||
background: linear-gradient(135deg, #69190D, #A52C16);
|
||||
border-color: #EB7513;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 20px rgba(235, 117, 19, 0.4);
|
||||
}
|
||||
|
||||
#file-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#network-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100vh - 250px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
svg:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.branch {
|
||||
stroke: #442204;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.category-node {
|
||||
cursor: move;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.category-node:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.category-node circle {
|
||||
fill: #442204;
|
||||
stroke: #EB7513;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.category-node text {
|
||||
fill: #EB7513;
|
||||
font-family: 'Arial Black', 'Impact', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-anchor: middle;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaf-node {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.leaf-node circle {
|
||||
fill: #073720;
|
||||
stroke: #5E9A0E;
|
||||
stroke-width: 2;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.leaf-node:hover circle {
|
||||
fill: #69190D;
|
||||
stroke: #F2C62A;
|
||||
transform: scale(1.2);
|
||||
filter: drop-shadow(0 0 10px #F2C62A);
|
||||
}
|
||||
|
||||
.leaf-node text {
|
||||
fill: #F2F2BC;
|
||||
font-size: 10px;
|
||||
text-anchor: middle;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.leaf-node:hover text {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Lightbox styles */
|
||||
.lightbox {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(11, 11, 11, 0.95);
|
||||
z-index: 1000;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.lightbox.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.lightbox-content {
|
||||
background: linear-gradient(135deg, #0B0B0B, #442204);
|
||||
border: 3px solid;
|
||||
border-image: linear-gradient(90deg, #69190D, #A52C16, #EB7513, #F2C62A) 1;
|
||||
border-radius: 10px;
|
||||
padding: 2rem;
|
||||
max-width: 600px;
|
||||
width: 90%;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 0 40px rgba(235, 117, 19, 0.5);
|
||||
}
|
||||
|
||||
.lightbox-content h2 {
|
||||
font-family: 'Arial Black', 'Impact', sans-serif;
|
||||
color: #EB7513;
|
||||
margin-bottom: 1rem;
|
||||
font-size: clamp(1.2rem, 3vw, 1.8rem);
|
||||
}
|
||||
|
||||
.lightbox-content p {
|
||||
color: #F2F2BC;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.lightbox-content textarea {
|
||||
width: 100%;
|
||||
min-height: 300px;
|
||||
background: #0B0B0B;
|
||||
color: #F2F2BC;
|
||||
border: 2px solid #442204;
|
||||
border-radius: 5px;
|
||||
padding: 1rem;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9rem;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.lightbox-buttons {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
min-width: 120px;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border: 2px solid #F2C62A;
|
||||
background: linear-gradient(135deg, #442204, #69190D);
|
||||
color: #F2C62A;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: linear-gradient(135deg, #69190D, #A52C16);
|
||||
color: #F2F2BC;
|
||||
border-color: #EB7513;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 20px rgba(235, 117, 19, 0.4);
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
background: linear-gradient(135deg, #5E9A0E, #073720);
|
||||
border-color: #5E9A0E;
|
||||
}
|
||||
|
||||
.btn-close:hover {
|
||||
background: linear-gradient(135deg, #073720, #0E4D0E);
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
font-size: 1.2rem;
|
||||
color: #EB7513;
|
||||
}
|
||||
|
||||
.zoom-indicator {
|
||||
position: fixed;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
background: rgba(11, 11, 11, 0.9);
|
||||
border: 2px solid #F2C62A;
|
||||
border-radius: 5px;
|
||||
padding: 0.5rem 1rem;
|
||||
color: #F2C62A;
|
||||
font-size: 0.9rem;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.zoom-indicator.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.reset-zoom {
|
||||
position: fixed;
|
||||
bottom: 1rem;
|
||||
left: 1rem;
|
||||
background: rgba(11, 11, 11, 0.9);
|
||||
border: 2px solid #5E9A0E;
|
||||
border-radius: 5px;
|
||||
padding: 0.5rem 1rem;
|
||||
color: #5E9A0E;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.reset-zoom:hover {
|
||||
background: rgba(94, 154, 14, 0.2);
|
||||
border-color: #F2C62A;
|
||||
color: #F2C62A;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Mobile optimizations */
|
||||
@media (max-width: 768px) {
|
||||
header {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.controls {
|
||||
padding: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.btn-control {
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.subtitle br {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.lightbox-content {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-width: 100px;
|
||||
padding: 0.6rem 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.category-node text {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.reset-zoom {
|
||||
font-size: 0.8rem;
|
||||
padding: 0.4rem 0.8rem;
|
||||
}
|
||||
|
||||
.zoom-indicator {
|
||||
font-size: 0.8rem;
|
||||
padding: 0.4rem 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) and (pointer: coarse) {
|
||||
svg {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.category-node {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.leaf-node {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>🌳 Dendritic Links Network</h1>
|
||||
<p class="subtitle">Your Browser Tabs, Visualized</p>
|
||||
<p class="subtitle" style="margin-top: 0.5rem; font-size: 0.85em; opacity: 0.8;">
|
||||
🖱️ Drag to pan • 🔍 Scroll/Pinch to zoom • 🖱️ Right-drag to zoom • 👆 Click leaves to explore<br>
|
||||
<span style="font-size: 0.9em; opacity: 0.7;">⌨️ Keyboard: R = Reset • +/- = Zoom</span>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="controls">
|
||||
<button class="btn-control" onclick="document.getElementById('file-input').click()">
|
||||
📁 Load Markdown File
|
||||
</button>
|
||||
<button class="btn-control" onclick="showPasteDialog()">
|
||||
📋 Paste Markdown
|
||||
</button>
|
||||
<button class="btn-control" onclick="loadDefaultData()">
|
||||
🎨 Load Demo Data
|
||||
</button>
|
||||
<input type="file" id="file-input" accept=".md,.markdown,.txt" onchange="handleFileUpload(event)">
|
||||
</div>
|
||||
|
||||
<div id="network-container">
|
||||
<div class="loading">🌱 Click a button above to load your links!</div>
|
||||
</div>
|
||||
|
||||
<button class="reset-zoom" id="reset-zoom" title="Reset zoom and position">
|
||||
🎯 Reset View
|
||||
</button>
|
||||
|
||||
<div class="zoom-indicator" id="zoom-indicator">
|
||||
Zoom: <span id="zoom-level">100%</span>
|
||||
</div>
|
||||
|
||||
<!-- Link detail lightbox -->
|
||||
<div class="lightbox" id="lightbox">
|
||||
<div class="lightbox-content">
|
||||
<h2 id="lightbox-title"></h2>
|
||||
<p id="lightbox-description"></p>
|
||||
<div class="lightbox-buttons">
|
||||
<a id="visit-link" class="btn" href="#" target="_blank">🔗 Visit Link</a>
|
||||
<button class="btn btn-close" onclick="closeLightbox()">✕ Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Paste markdown lightbox -->
|
||||
<div class="lightbox" id="paste-lightbox">
|
||||
<div class="lightbox-content">
|
||||
<h2>Paste Your Markdown</h2>
|
||||
<p>Paste your organized links markdown below:</p>
|
||||
<textarea id="markdown-input" placeholder="# Your Links
|
||||
|
||||
## Category Name
|
||||
|
||||
- [Link Name](https://example.com/)
|
||||
- Description of the link goes here.
|
||||
|
||||
## Another Category
|
||||
|
||||
..."></textarea>
|
||||
<div class="lightbox-buttons">
|
||||
<button class="btn" onclick="processPastedMarkdown()">✨ Generate Network</button>
|
||||
<button class="btn btn-close" onclick="closePasteDialog()">✕ Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.1/markdown-it.min.js"></script>
|
||||
<script>
|
||||
console.log("🌳 Navigation: Drag to pan • Scroll/Pinch to zoom • Right-click+Drag to zoom • Click nodes to interact");
|
||||
|
||||
let currentSimulation = null;
|
||||
let currentSvg = null;
|
||||
|
||||
// Markdown parser
|
||||
const md = window.markdownit();
|
||||
|
||||
// Parse markdown into linkData structure
|
||||
function parseMarkdownToLinkData(markdown) {
|
||||
const tokens = md.parse(markdown, {});
|
||||
const linkData = {};
|
||||
let currentCategory = null;
|
||||
let currentLink = null;
|
||||
let expectingDescription = false;
|
||||
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
|
||||
// Detect h2 headers (## Category Name)
|
||||
if (token.type === 'heading_open' && token.tag === 'h2') {
|
||||
const nextToken = tokens[i + 1];
|
||||
if (nextToken && nextToken.type === 'inline') {
|
||||
currentCategory = nextToken.content.trim();
|
||||
linkData[currentCategory] = [];
|
||||
currentLink = null;
|
||||
expectingDescription = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Detect links inside list items
|
||||
if (token.type === 'inline' && token.children && currentCategory) {
|
||||
const linkToken = token.children.find(t => t.type === 'link_open');
|
||||
if (linkToken) {
|
||||
const textToken = token.children.find(t => t.type === 'text');
|
||||
if (textToken) {
|
||||
const url = linkToken.attrGet('href');
|
||||
currentLink = {
|
||||
name: textToken.content,
|
||||
url: url,
|
||||
desc: ''
|
||||
};
|
||||
expectingDescription = true;
|
||||
}
|
||||
} else if (expectingDescription && currentLink) {
|
||||
// This is the description line
|
||||
currentLink.desc = token.content.trim();
|
||||
linkData[currentCategory].push(currentLink);
|
||||
expectingDescription = false;
|
||||
currentLink = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Also check paragraph content for descriptions
|
||||
if (token.type === 'paragraph_open' && expectingDescription && currentLink) {
|
||||
const nextToken = tokens[i + 1];
|
||||
if (nextToken && nextToken.type === 'inline') {
|
||||
// Skip if this contains a link (it's a new link item)
|
||||
if (!nextToken.children.some(t => t.type === 'link_open')) {
|
||||
currentLink.desc = nextToken.content.trim();
|
||||
linkData[currentCategory].push(currentLink);
|
||||
expectingDescription = false;
|
||||
currentLink = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up any categories with no links
|
||||
Object.keys(linkData).forEach(key => {
|
||||
if (linkData[key].length === 0) {
|
||||
delete linkData[key];
|
||||
}
|
||||
});
|
||||
|
||||
return linkData;
|
||||
}
|
||||
|
||||
// Create the force-directed graph
|
||||
function createNetwork(linkData) {
|
||||
const container = document.getElementById('network-container');
|
||||
const width = container.clientWidth;
|
||||
const height = container.clientHeight;
|
||||
|
||||
// Clear existing content
|
||||
container.innerHTML = '';
|
||||
|
||||
// Stop existing simulation if any
|
||||
if (currentSimulation) {
|
||||
currentSimulation.stop();
|
||||
}
|
||||
|
||||
const svg = d3.select('#network-container')
|
||||
.append('svg')
|
||||
.attr('width', width)
|
||||
.attr('height', height);
|
||||
|
||||
currentSvg = svg;
|
||||
|
||||
const g = svg.append('g');
|
||||
|
||||
// Setup zoom behavior
|
||||
let zoomTimeout;
|
||||
const zoomIndicator = document.getElementById('zoom-indicator');
|
||||
const zoomLevel = document.getElementById('zoom-level');
|
||||
|
||||
const zoom = d3.zoom()
|
||||
.scaleExtent([0.1, 4])
|
||||
.on('zoom', (event) => {
|
||||
g.attr('transform', event.transform);
|
||||
|
||||
zoomIndicator.classList.add('visible');
|
||||
zoomLevel.textContent = Math.round(event.transform.k * 100) + '%';
|
||||
|
||||
clearTimeout(zoomTimeout);
|
||||
zoomTimeout = setTimeout(() => {
|
||||
zoomIndicator.classList.remove('visible');
|
||||
}, 1500);
|
||||
});
|
||||
|
||||
svg.call(zoom);
|
||||
|
||||
// Right-click zoom
|
||||
let rightDragStart = null;
|
||||
svg.on('contextmenu', (event) => {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
svg.on('mousedown', (event) => {
|
||||
if (event.button === 2) {
|
||||
rightDragStart = { y: event.clientY, scale: d3.zoomTransform(svg.node()).k };
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
svg.on('mousemove', (event) => {
|
||||
if (rightDragStart && event.buttons === 2) {
|
||||
const delta = (rightDragStart.y - event.clientY) * 0.01;
|
||||
const newScale = Math.max(0.1, Math.min(4, rightDragStart.scale * (1 + delta)));
|
||||
svg.call(zoom.scaleTo, newScale);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
svg.on('mouseup', (event) => {
|
||||
if (event.button === 2) {
|
||||
rightDragStart = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Create nodes and links
|
||||
const nodes = [];
|
||||
const links = [];
|
||||
|
||||
nodes.push({ id: 'center', type: 'center', x: width / 2, y: height / 2 });
|
||||
|
||||
let nodeId = 0;
|
||||
Object.keys(linkData).forEach((category, catIndex) => {
|
||||
const catId = `cat-${catIndex}`;
|
||||
nodes.push({
|
||||
id: catId,
|
||||
type: 'category',
|
||||
label: category,
|
||||
fixed: false
|
||||
});
|
||||
links.push({ source: 'center', target: catId });
|
||||
|
||||
linkData[category].forEach((link, linkIndex) => {
|
||||
const leafId = `leaf-${nodeId++}`;
|
||||
nodes.push({
|
||||
id: leafId,
|
||||
type: 'leaf',
|
||||
label: link.name,
|
||||
url: link.url,
|
||||
description: link.desc
|
||||
});
|
||||
links.push({ source: catId, target: leafId });
|
||||
});
|
||||
});
|
||||
|
||||
// Create force simulation
|
||||
const simulation = d3.forceSimulation(nodes)
|
||||
.force('link', d3.forceLink(links).id(d => d.id).distance(d => d.source.type === 'category' ? 150 : 80))
|
||||
.force('charge', d3.forceManyBody().strength(-300))
|
||||
.force('center', d3.forceCenter(width / 2, height / 2))
|
||||
.force('collision', d3.forceCollide().radius(30));
|
||||
|
||||
currentSimulation = simulation;
|
||||
|
||||
// Create links
|
||||
const link = g.append('g')
|
||||
.selectAll('line')
|
||||
.data(links)
|
||||
.enter()
|
||||
.append('line')
|
||||
.attr('class', 'branch')
|
||||
.attr('stroke-opacity', 0.6);
|
||||
|
||||
// Create nodes
|
||||
const node = g.append('g')
|
||||
.selectAll('g')
|
||||
.data(nodes.filter(n => n.type !== 'center'))
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', d => d.type === 'category' ? 'category-node' : 'leaf-node')
|
||||
.call(d3.drag()
|
||||
.on('start', dragstarted)
|
||||
.on('drag', dragged)
|
||||
.on('end', dragended));
|
||||
|
||||
node.append('circle')
|
||||
.attr('r', d => d.type === 'category' ? 20 : 12);
|
||||
|
||||
node.append('text')
|
||||
.text(d => d.label)
|
||||
.attr('dy', d => d.type === 'category' ? -25 : -18);
|
||||
|
||||
// Click handler for leaf nodes
|
||||
node.filter(d => d.type === 'leaf')
|
||||
.on('click', function(event, d) {
|
||||
event.stopPropagation();
|
||||
openLightbox(d.label, d.description, d.url);
|
||||
});
|
||||
|
||||
// Update positions
|
||||
simulation.on('tick', () => {
|
||||
link
|
||||
.attr('x1', d => d.source.x)
|
||||
.attr('y1', d => d.source.y)
|
||||
.attr('x2', d => d.target.x)
|
||||
.attr('y2', d => d.target.y);
|
||||
|
||||
node
|
||||
.attr('transform', d => `translate(${d.x},${d.y})`);
|
||||
});
|
||||
|
||||
// Drag functions
|
||||
function dragstarted(event, d) {
|
||||
if (!event.active) simulation.alphaTarget(0.3).restart();
|
||||
d.fx = d.x;
|
||||
d.fy = d.y;
|
||||
}
|
||||
|
||||
function dragged(event, d) {
|
||||
d.fx = event.x;
|
||||
d.fy = event.y;
|
||||
}
|
||||
|
||||
function dragended(event, d) {
|
||||
if (!event.active) simulation.alphaTarget(0);
|
||||
d.fx = null;
|
||||
d.fy = null;
|
||||
}
|
||||
|
||||
// Reset zoom button
|
||||
document.getElementById('reset-zoom').onclick = () => {
|
||||
svg.transition()
|
||||
.duration(750)
|
||||
.call(zoom.transform, d3.zoomIdentity);
|
||||
};
|
||||
|
||||
// Keyboard shortcuts
|
||||
document.addEventListener('keydown', (e) => {
|
||||
switch(e.key.toLowerCase()) {
|
||||
case 'r':
|
||||
svg.transition()
|
||||
.duration(750)
|
||||
.call(zoom.transform, d3.zoomIdentity);
|
||||
break;
|
||||
case '+':
|
||||
case '=':
|
||||
svg.transition()
|
||||
.duration(300)
|
||||
.call(zoom.scaleBy, 1.3);
|
||||
break;
|
||||
case '-':
|
||||
case '_':
|
||||
svg.transition()
|
||||
.duration(300)
|
||||
.call(zoom.scaleBy, 0.7);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle file upload
|
||||
function handleFileUpload(event) {
|
||||
const file = event.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const markdown = e.target.result;
|
||||
try {
|
||||
const linkData = parseMarkdownToLinkData(markdown);
|
||||
if (Object.keys(linkData).length === 0) {
|
||||
alert('No links found in the markdown file. Please check the format.');
|
||||
return;
|
||||
}
|
||||
createNetwork(linkData);
|
||||
} catch (error) {
|
||||
console.error('Error parsing markdown:', error);
|
||||
alert('Error parsing markdown file. Please check the format.');
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
||||
// Show paste dialog
|
||||
function showPasteDialog() {
|
||||
document.getElementById('paste-lightbox').classList.add('active');
|
||||
document.getElementById('markdown-input').focus();
|
||||
}
|
||||
|
||||
// Close paste dialog
|
||||
function closePasteDialog() {
|
||||
document.getElementById('paste-lightbox').classList.remove('active');
|
||||
}
|
||||
|
||||
// Process pasted markdown
|
||||
function processPastedMarkdown() {
|
||||
const markdown = document.getElementById('markdown-input').value;
|
||||
if (!markdown.trim()) {
|
||||
alert('Please paste some markdown content.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const linkData = parseMarkdownToLinkData(markdown);
|
||||
if (Object.keys(linkData).length === 0) {
|
||||
alert('No links found in the markdown. Please check the format.');
|
||||
return;
|
||||
}
|
||||
closePasteDialog();
|
||||
createNetwork(linkData);
|
||||
} catch (error) {
|
||||
console.error('Error parsing markdown:', error);
|
||||
alert('Error parsing markdown. Please check the format.');
|
||||
}
|
||||
}
|
||||
|
||||
// Load default demo data
|
||||
function loadDefaultData() {
|
||||
const demoData = {
|
||||
"AI & Machine Learning": [
|
||||
{ name: "Z.ai Chat", url: "https://chat.z.ai/", desc: "Free AI chat powered by GLM models." },
|
||||
{ name: "DeepSeek", url: "https://chat.deepseek.com/", desc: "Another AI assistant." },
|
||||
{ name: "BlueDot Impact", url: "https://bluedot.org/", desc: "Industry-leading free AI courses." }
|
||||
],
|
||||
"Development Tools": [
|
||||
{ name: "Context7 MCP", url: "https://github.com/upstash/context7", desc: "Up-to-date code docs for LLMs." },
|
||||
{ name: "TypeScript Docs", url: "https://www.typescriptlang.org/docs/", desc: "JavaScript's responsible sibling." },
|
||||
{ name: "DevDocs", url: "https://devdocs.io/", desc: "All your API docs in one place." }
|
||||
],
|
||||
"Creative & Design": [
|
||||
{ name: "GIMP", url: "https://www.gimp.org/", desc: "Free Photoshop alternative." },
|
||||
{ name: "Blender", url: "https://www.blender.org/", desc: "Free 3D creation suite." },
|
||||
{ name: "Inkscape", url: "https://inkscape.org/", desc: "Vector graphics editor." }
|
||||
],
|
||||
"Knowledge Management": [
|
||||
{ name: "Logseq", url: "https://logseq.com/", desc: "Privacy-first knowledge base." },
|
||||
{ name: "Trilium Notes", url: "https://triliumnotes.org/", desc: "Hierarchical note-taking." },
|
||||
{ name: "BookStack", url: "https://www.bookstackapp.com/", desc: "Organize docs like a library." }
|
||||
]
|
||||
};
|
||||
createNetwork(demoData);
|
||||
}
|
||||
|
||||
// Lightbox functions
|
||||
function openLightbox(title, description, url) {
|
||||
document.getElementById('lightbox-title').textContent = title;
|
||||
document.getElementById('lightbox-description').textContent = description;
|
||||
document.getElementById('visit-link').href = url;
|
||||
document.getElementById('lightbox').classList.add('active');
|
||||
}
|
||||
|
||||
function closeLightbox() {
|
||||
document.getElementById('lightbox').classList.remove('active');
|
||||
}
|
||||
|
||||
// Close lightbox on background click
|
||||
document.getElementById('lightbox').addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
closeLightbox();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('paste-lightbox').addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
closePasteDialog();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1955
DumperCan/docker-cheatsheet-enhanced.html
Normal file
1955
DumperCan/docker-cheatsheet-enhanced.html
Normal file
File diff suppressed because it is too large
Load Diff
785
DumperCan/jl_foss_tools_restyled.html
Executable file
785
DumperCan/jl_foss_tools_restyled.html
Executable file
@@ -0,0 +1,785 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FOSS Tools Collection</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Notable:wght@400&family=Special+Elite:wght@400&family=Noto+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--color-bg-primary: #0B0B0B;
|
||||
--color-h1: #EB7513;
|
||||
--color-h2: #F2C62A;
|
||||
--color-h3: #5E9A0E;
|
||||
--color-h4: #A52C16;
|
||||
--color-text: #F2F2BC;
|
||||
--color-link-primary: #F2C62A;
|
||||
--color-link-secondary: #EB7513;
|
||||
--color-btn-accent: #5E9A0E;
|
||||
--color-border-1: #69190D;
|
||||
--color-border-2: #A52C16;
|
||||
--color-border-3: #EB7513;
|
||||
|
||||
--font-h1-h2: 'Notable', sans-serif;
|
||||
--font-h3-h6: 'Special Elite', serif;
|
||||
--font-body: 'Noto Sans', sans-serif;
|
||||
|
||||
--gradient-card-border: linear-gradient(to bottom,
|
||||
#0B0B0B, #442204, #69190D, #A52C16, #EB7513, #F2C62A, #F2F2BC);
|
||||
|
||||
--gradient-btn-primary: linear-gradient(to bottom,
|
||||
#69190D, #A52C16, #EB7513, #F2C62A);
|
||||
|
||||
--gradient-btn-secondary: linear-gradient(to bottom,
|
||||
#073720, #0E4D0E, #5E9A0E, #F2C62A);
|
||||
|
||||
--space-xs: 0.25rem;
|
||||
--space-sm: 0.5rem;
|
||||
--space-md: 1rem;
|
||||
--space-lg: 1.5rem;
|
||||
--space-xl: 2rem;
|
||||
--space-2xl: 3rem;
|
||||
|
||||
--radius-sm: 4px;
|
||||
--radius-md: 6px;
|
||||
--radius-lg: 8px;
|
||||
--radius-xl: 12px;
|
||||
|
||||
--transition-fast: 150ms ease-in-out;
|
||||
--transition-base: 250ms ease-in-out;
|
||||
--transition-slow: 350ms ease-in-out;
|
||||
|
||||
--shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.5);
|
||||
--glow-primary: 0 0 20px rgba(242, 242, 188, 0.4);
|
||||
--glow-secondary: 0 0 20px rgba(235, 117, 19, 0.4);
|
||||
--glow-accent: 0 0 20px rgba(94, 154, 14, 0.4);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text);
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
line-height: 1.2;
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
font-family: var(--font-h1-h2);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
h3, h4, h5, h6 {
|
||||
font-family: var(--font-h3-h6);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(2rem, 5vw, 3.5rem);
|
||||
color: var(--color-h1);
|
||||
text-align: center;
|
||||
margin-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.5rem, 3vw, 2rem);
|
||||
color: var(--color-h2);
|
||||
margin-bottom: var(--space-xl);
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--space-md);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
padding: 0 var(--space-lg);
|
||||
}
|
||||
}
|
||||
|
||||
/* === Header === */
|
||||
.header {
|
||||
padding: var(--space-2xl) 0;
|
||||
border-bottom: 3px solid var(--color-h3);
|
||||
background: linear-gradient(135deg, rgba(94, 154, 14, 0.05) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
font-size: clamp(0.95rem, 2vw, 1.2rem);
|
||||
color: var(--color-link-primary);
|
||||
margin-bottom: var(--space-xl);
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
/* === Categories Container === */
|
||||
#categories-container {
|
||||
padding: var(--space-2xl) 0;
|
||||
}
|
||||
|
||||
/* === Category Cards === */
|
||||
.category-card {
|
||||
position: relative;
|
||||
background-color: rgba(255, 255, 255, 0.02);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-xl);
|
||||
margin-bottom: var(--space-2xl);
|
||||
transition: all var(--transition-base);
|
||||
}
|
||||
|
||||
.category-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 4px;
|
||||
background: var(--gradient-card-border);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
opacity: 0.6;
|
||||
transition: opacity var(--transition-base);
|
||||
}
|
||||
|
||||
.category-card:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.category-card:hover::before {
|
||||
opacity: 1;
|
||||
filter: drop-shadow(var(--glow-primary));
|
||||
}
|
||||
|
||||
.category-card:nth-child(even)::before {
|
||||
background: linear-gradient(to bottom,
|
||||
#F2F2BC, #5E9A0E, #0E4D0E, #073720, #0B0B0B);
|
||||
}
|
||||
|
||||
.category-title {
|
||||
font-size: clamp(1.3rem, 2.5vw, 1.8rem);
|
||||
color: var(--color-h2);
|
||||
margin-bottom: var(--space-lg);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* === Links Grid === */
|
||||
.links-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: var(--space-md);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* === Link Buttons === */
|
||||
.link-button {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-base);
|
||||
color: var(--color-text);
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.link-button::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: var(--radius-md);
|
||||
padding: 2px;
|
||||
background: var(--gradient-btn-secondary);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
transition: all var(--transition-base);
|
||||
}
|
||||
|
||||
.link-button:hover {
|
||||
background: var(--color-btn-accent);
|
||||
box-shadow: var(--glow-accent);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.link-button:hover::before {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.link-button:focus-visible {
|
||||
outline: 2px solid var(--color-link-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* === Lightbox === */
|
||||
.lightbox-backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
z-index: 400;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-lg);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.lightbox-backdrop.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.lightbox {
|
||||
position: relative;
|
||||
background-color: var(--color-bg-primary);
|
||||
border-radius: var(--radius-lg);
|
||||
max-width: 700px;
|
||||
width: 100%;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: var(--shadow-lg);
|
||||
z-index: 500;
|
||||
}
|
||||
|
||||
.lightbox::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 4px;
|
||||
background: var(--gradient-card-border);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
filter: drop-shadow(var(--glow-primary));
|
||||
}
|
||||
|
||||
.lightbox-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--space-lg);
|
||||
border-bottom: 2px solid var(--color-border-1);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.lightbox-title {
|
||||
color: var(--color-h2);
|
||||
font-family: var(--font-h1-h2);
|
||||
font-size: 1.5rem;
|
||||
text-transform: uppercase;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.lightbox-url {
|
||||
color: var(--color-link-primary);
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.8;
|
||||
word-break: break-all;
|
||||
margin-top: var(--space-sm);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.lightbox-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text);
|
||||
font-size: 1.8rem;
|
||||
cursor: pointer;
|
||||
padding: var(--space-xs);
|
||||
transition: all var(--transition-fast);
|
||||
line-height: 1;
|
||||
margin-left: var(--space-lg);
|
||||
}
|
||||
|
||||
.lightbox-close:hover {
|
||||
color: var(--color-link-primary);
|
||||
text-shadow: var(--glow-primary);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.lightbox-body {
|
||||
padding: var(--space-lg);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.lightbox-category {
|
||||
display: inline-block;
|
||||
background: rgba(94, 154, 14, 0.2);
|
||||
color: var(--color-h3);
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
border-radius: var(--radius-xl);
|
||||
font-size: 0.8rem;
|
||||
margin-bottom: var(--space-md);
|
||||
border: 1px solid var(--color-border-3);
|
||||
}
|
||||
|
||||
.lightbox-description {
|
||||
color: var(--color-text);
|
||||
line-height: 1.8;
|
||||
margin-bottom: var(--space-lg);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.lightbox-footer {
|
||||
display: flex;
|
||||
gap: var(--space-md);
|
||||
justify-content: flex-end;
|
||||
padding: var(--space-lg);
|
||||
border-top: 2px solid var(--color-border-1);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* === Lightbox Buttons === */
|
||||
.lightbox-button {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--space-sm);
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-base);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.lightbox-button::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: var(--radius-md);
|
||||
padding: 2px;
|
||||
background: var(--gradient-btn-primary);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
transition: all var(--transition-base);
|
||||
}
|
||||
|
||||
.lightbox-button {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.lightbox-button:hover {
|
||||
background: var(--color-btn-accent);
|
||||
box-shadow: var(--glow-accent);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.lightbox-button:focus-visible {
|
||||
outline: 2px solid var(--color-link-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* === Footer === */
|
||||
footer {
|
||||
padding: var(--space-xl) 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-top: 1px solid rgba(242, 242, 188, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer p {
|
||||
color: var(--color-text);
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
|
||||
/* === Responsive === */
|
||||
@media (max-width: 768px) {
|
||||
.links-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.lightbox {
|
||||
max-height: 95vh;
|
||||
}
|
||||
|
||||
.lightbox-footer {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.lightbox-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* === Scrollbar === */
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(135deg, var(--color-h3), var(--color-link-primary));
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(135deg, var(--color-link-primary), var(--color-h1));
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="container">
|
||||
<h1>FOSS Tools Galaxy</h1>
|
||||
<p class="subtitle">Your complete curated collection of 100+ open-source tools</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div id="categories-container"></div>
|
||||
</div>
|
||||
|
||||
<div class="lightbox-backdrop" id="lightbox">
|
||||
<div class="lightbox">
|
||||
<div id="lightbox-inner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div class="container">
|
||||
<p>FOSS Tools Collection | Open-Source Software Discovery</p>
|
||||
<p style="font-size: 0.8rem; opacity: 0.7;">Restyled with JL Design System</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
const toolMetadata = {
|
||||
"https://www.gimp.org/": { title: "GIMP", description: "Powerful raster graphics editor for photo retouching, image composition, and authoring. Cross-platform Photoshop alternative with layers, filters, and customizable brushes.", category: "Graphics" },
|
||||
"https://krita.org/en/": { title: "Krita", description: "Professional digital painting application designed by artists. Features brush stabilizers, advanced layer management, and animation tools for concept art and illustrations.", category: "Digital Art" },
|
||||
"https://inkscape.org/": { title: "Inkscape", description: "Professional vector graphics software for SVG files. Create logos, illustrations, diagrams with bezier tools, text manipulation, and precision object control.", category: "Vector Graphics" },
|
||||
"https://www.darktable.org/": { title: "darktable", description: "Photography workflow application and RAW developer. Manage digital negatives in a database with non-destructive editing tools.", category: "Photography" },
|
||||
"https://www.blender.org/": { title: "Blender", description: "Complete 3D creation suite for modeling, rigging, animation, simulation, rendering, compositing, and motion tracking. Used by studios worldwide.", category: "3D Graphics" },
|
||||
"https://www.freecad.org/": { title: "FreeCAD", description: "Parametric 3D CAD modeler for real-life object design. Modular architecture for mechanical engineering, architecture, and product design.", category: "CAD" },
|
||||
"https://www.drawio.com/": { title: "draw.io", description: "Free diagram software for flowcharts, process diagrams, org charts, UML, and network diagrams. Works offline with cloud storage integration.", category: "Diagramming" },
|
||||
"https://www.shutterencoder.com/en/": { title: "Shutter Encoder", description: "Professional video/audio converter with extensive codec support, batch processing, custom encoding settings, and advanced filters.", category: "Video" },
|
||||
"https://ffmpeg.org/": { title: "FFmpeg", description: "Essential command-line multimedia framework for recording, converting, and streaming. Industry-standard codec library for batch processing.", category: "Multimedia" },
|
||||
"https://handbrake.fr/": { title: "HandBrake", description: "User-friendly video transcoder with device presets. Converts video from nearly any format with quality and size optimization.", category: "Video" },
|
||||
"https://kdenlive.org/": { title: "Kdenlive", description: "Powerful multi-track video editor with effects, transitions, and color correction. Supports proxy editing for smooth high-res playback.", category: "Video Editing" },
|
||||
"https://www.shotcut.org/": { title: "Shotcut", description: "Cross-platform video editor with native timeline, wide format support, and 4K handling. Includes color grading and audio filters.", category: "Video Editing" },
|
||||
"https://obsproject.com/": { title: "OBS Studio", description: "Industry-standard software for video recording and live streaming. Real-time capture with scene composition and mixing. Powers countless streams.", category: "Streaming" },
|
||||
"https://clipgrab.org/": { title: "ClipGrab", description: "Simple downloader and converter for YouTube, Vimeo, and other video sites. Various formats and quality options for offline viewing.", category: "Utilities" },
|
||||
"https://kodi.tv/": { title: "Kodi", description: "Award-winning media center organizing video, music, and photos. Extensible through add-ons, perfect for home theater PCs.", category: "Media Center" },
|
||||
"https://mpv.io/": { title: "mpv", description: "Minimalist keyboard-driven media player with high-quality output. Supports virtually all formats, hardware decoding, and scripting.", category: "Media Player" },
|
||||
"https://jellyfin.org/": { title: "Jellyfin", description: "Free media server for hosting and streaming personal collections. No premium licenses or tracking - completely free Plex alternative.", category: "Media Server" },
|
||||
"https://freetubeapp.io/": { title: "FreeTube", description: "Private desktop YouTube client. Watch videos without ads or tracking, subscribe locally, export subscriptions. No Google account needed.", category: "Privacy" },
|
||||
"https://tenacityaudio.org/": { title: "Tenacity", description: "Modern Audacity fork focused on features and community. Multi-track audio editor with effects, analysis tools, and plugin support.", category: "Audio" },
|
||||
"https://www.audacityteam.org/": { title: "Audacity", description: "Legendary multi-track audio editor and recorder. Used by millions for podcasting, music production, and restoration.", category: "Audio" },
|
||||
"https://lmms.io/": { title: "LMMS", description: "Complete digital audio workstation for music production. Includes synthesizers, samples, effects, and MIDI support.", category: "Music" },
|
||||
"https://mixxx.org/": { title: "Mixxx", description: "Professional DJ software with 4 decks, powerful mixing engine, effects, and hardware controller support for live performances.", category: "DJ Software" },
|
||||
"https://musescore.org/en": { title: "MuseScore", description: "Professional music notation software for composing and editing sheet music. WYSIWYG interface with playback and export options.", category: "Music Notation" },
|
||||
"https://www.musehub.com/": { title: "MuseHub", description: "Central hub for MuseScore plugins, sounds, and samples. Extends MuseScore with professional sound libraries and tools.", category: "Music" },
|
||||
"https://docusaurus.io/": { title: "Docusaurus", description: "Modern static website generator for technical documentation. Built with React, featuring versioning, search, and i18n out of the box.", category: "Documentation" },
|
||||
"https://vuepress.vuejs.org/": { title: "VuePress", description: "Vue-powered static site generator focused on documentation. Markdown-centered with built-in search and easy theming.", category: "Documentation" },
|
||||
"https://www.bookstackapp.com/": { title: "BookStack", description: "Self-hosted wiki organizing content into books, chapters, and pages. Simple interface with powerful search and markdown support.", category: "Wiki" },
|
||||
"https://js.wiki/": { title: "Wiki.js", description: "Powerful modern wiki software built with Node.js. Clean interface, markdown editor, access control, and multiple storage backends.", category: "Wiki" },
|
||||
"https://vuejs.org/": { title: "Vue.js", description: "Progressive JavaScript framework for building UIs. Easy to learn, performant, versatile - scales from library to full framework.", category: "Framework" },
|
||||
"https://create.t3.gg/": { title: "Create T3 App", description: "Opinionated full-stack Next.js starter with TypeScript, tRPC, Tailwind, and Prisma. Best practices for type-safe rapid development.", category: "Development" },
|
||||
"https://pandoc.org/": { title: "Pandoc", description: "Universal document converter for dozens of formats including Markdown, HTML, LaTeX, and Word. Essential for documentation workflows.", category: "Converter" },
|
||||
"https://miktex.org/": { title: "MiKTeX", description: "Complete TeX/LaTeX typesetting system. Automatic package installation and integrated editor for professional scientific documents.", category: "Publishing" },
|
||||
"https://logseq.com/": { title: "Logseq", description: "Privacy-first knowledge base on local markdown files. Combines outlining, bidirectional linking, and graph visualization for PKM.", category: "PKM" },
|
||||
"https://triliumnotes.org/": { title: "Trilium Notes", description: "Hierarchical note-taking for personal knowledge bases. Features scripting, relations, and advanced note organization.", category: "PKM" },
|
||||
"https://etherpad.org/": { title: "Etherpad", description: "Real-time collaborative document editing in browser. Color-coded authorship, chat, and revision history for remote teams.", category: "Collaboration" },
|
||||
"https://www.getpublii.com/": { title: "Publii", description: "Desktop app for static websites with CMS interface. One-click sync to hosting services, no server or database required.", category: "Static CMS" },
|
||||
"https://strapi.io/": { title: "Strapi", description: "Leading open-source headless CMS built with JavaScript. Fully customizable and developer-friendly for modern APIs.", category: "Headless CMS" },
|
||||
"https://vendure.io/": { title: "Vendure", description: "Open-source headless commerce platform built with Node.js and TypeScript. Modern architecture for custom e-commerce solutions.", category: "E-Commerce" },
|
||||
"https://www.nopcommerce.com/en": { title: "nopCommerce", description: "Free ASP.NET Core shopping cart platform. Full-featured e-commerce solution with extensive plugin ecosystem.", category: "E-Commerce" },
|
||||
"https://www.opencart.com/": { title: "OpenCart", description: "PHP-based online store management system. Easy to use with thousands of modules and themes available.", category: "E-Commerce" },
|
||||
"https://prestashop.com/": { title: "PrestaShop", description: "Popular e-commerce solution powering 300,000+ stores worldwide. Feature-rich with extensive marketplace.", category: "E-Commerce" },
|
||||
"https://spreecommerce.org/": { title: "Spree Commerce", description: "Modular Ruby on Rails e-commerce platform. API-first design for headless commerce implementations.", category: "E-Commerce" },
|
||||
"https://www.rocket.chat/": { title: "Rocket.Chat", description: "Open-source team communication platform. Self-hosted alternative to Slack with end-to-end encryption and customization.", category: "Chat" },
|
||||
"https://zulip.com/": { title: "Zulip", description: "Threaded team chat for organized conversations. Combines email threading with real-time chat for productive async communication.", category: "Chat" },
|
||||
"https://element.io/": { title: "Element", description: "Secure messaging and collaboration built on Matrix protocol. End-to-end encrypted with federation support.", category: "Chat" },
|
||||
"https://twake.app/en/": { title: "Twake", description: "All-in-one collaboration platform with messaging, tasks, and documents. Open-source alternative to Microsoft Teams.", category: "Collaboration" },
|
||||
"https://bigbluebutton.org/": { title: "BigBlueButton", description: "Virtual classroom software for online learning. Built-in screen sharing, whiteboard, breakout rooms, and recording.", category: "Video Conference" },
|
||||
"https://sfu.mirotalk.com/": { title: "MiroTalk SFU", description: "Free WebRTC video calls with screen sharing and messaging. Privacy-focused with no registration required.", category: "Video Conference" },
|
||||
"https://brie.fi/ng": { title: "Briefing", description: "Simple, secure, anonymous video chat. No account, no tracking, ephemeral rooms for private conversations.", category: "Video Conference" },
|
||||
"https://www.metabase.com/": { title: "Metabase", description: "Business intelligence tool that lets anyone query data and build dashboards. No SQL required for basic queries.", category: "Business Intelligence" },
|
||||
"https://redash.io/": { title: "Redash", description: "Connect and query your data sources, visualize results, and share insights. SQL-based data visualization platform.", category: "Business Intelligence" },
|
||||
"https://matomo.org/": { title: "Matomo", description: "Ethical web analytics platform respecting user privacy. Full data ownership, GDPR compliant Google Analytics alternative.", category: "Analytics" },
|
||||
"https://plane.so/": { title: "Plane", description: "Open-source project management tool. Issue tracking, sprints, and cycles with a clean, modern interface.", category: "Project Management" },
|
||||
"https://www.focalboard.com/": { title: "Focalboard", description: "Open-source alternative to Trello and Notion. Organize tasks with kanban boards, tables, and calendar views.", category: "Project Management" },
|
||||
"https://www.tooljet.ai/": { title: "ToolJet", description: "Low-code platform to build internal tools. Connect databases, APIs, and build UIs quickly with drag-and-drop.", category: "Low-Code" },
|
||||
"https://www.firefly-iii.org/": { title: "Firefly III", description: "Self-hosted personal finance manager. Track expenses, budgets, and bills with beautiful charts and reports.", category: "Finance" },
|
||||
"https://developer.hashicorp.com/vault": { title: "Vault", description: "Secure secrets management and data protection. Encrypt data, manage access, and provide auditing for sensitive information.", category: "Security" },
|
||||
"https://www.keycloak.org/": { title: "Keycloak", description: "Open-source identity and access management. SSO, social login, user federation, and fine-grained authorization.", category: "Authentication" },
|
||||
"https://zitadel.com/": { title: "ZITADEL", description: "Cloud-native identity platform combining best of Auth0 and Keycloak. Built for modern applications with focus on security.", category: "Authentication" },
|
||||
"https://keepassxc.org/": { title: "KeePassXC", description: "Cross-platform password manager. Secure local storage with strong encryption, auto-type, and browser integration.", category: "Password Manager" },
|
||||
"https://cryptomator.org/": { title: "Cryptomator", description: "Client-side encryption for cloud storage. Transparent encryption for Dropbox, Google Drive, and other cloud services.", category: "Encryption" },
|
||||
"https://nextcloud.com/": { title: "Nextcloud", description: "Self-hosted file sync and share platform. Collaboration suite with calendar, contacts, mail, and extensive apps.", category: "File Sync" },
|
||||
"https://owncloud.com/": { title: "ownCloud", description: "Enterprise file sync and share platform. Secure collaboration with granular permissions and compliance features.", category: "File Sync" },
|
||||
"https://www.seafile.com/": { title: "Seafile", description: "High-performance file syncing and sharing. Block-level sync, encryption, and efficient handling of large files.", category: "File Sync" },
|
||||
"https://typesense.org/": { title: "Typesense", description: "Fast, typo-tolerant search engine. Open-source alternative to Algolia with instant search and simple setup.", category: "Search" },
|
||||
"https://opensearch.org/": { title: "OpenSearch", description: "Community-driven search and analytics suite derived from Elasticsearch. Distributed, scalable, and Apache 2.0 licensed.", category: "Search" },
|
||||
"https://www.nocodb.com/": { title: "NocoDB", description: "Turn databases into smart spreadsheets. Open-source Airtable alternative with API generation and collaboration features.", category: "Database" },
|
||||
"https://labelstud.io/": { title: "Label Studio", description: "Data labeling platform for machine learning. Annotate images, text, audio, and video with configurable interfaces.", category: "ML Tools" },
|
||||
"https://tdengine.com/": { title: "TDengine", description: "High-performance time-series database designed for IoT, Industrial IoT, and IT infrastructure monitoring.", category: "Database" },
|
||||
"https://chat.z.ai/": { title: "Z.ai Chat", description: "Free AI chat powered by GLM-4.6 and GLM-4.5 models. Advanced language model with multilingual capabilities.", category: "AI Chat" },
|
||||
"https://chat.deepseek.com/": { title: "DeepSeek", description: "AI assistant powered by DeepSeek models. Strong reasoning capabilities for coding, analysis, and conversation.", category: "AI Chat" },
|
||||
"https://t3.chat/": { title: "T3 Chat", description: "Chat interface for testing and exploring T3 stack applications. Developer-focused AI interaction tool.", category: "AI Chat" },
|
||||
"https://join-lemmy.org/": { title: "Lemmy", description: "Federated link aggregator and forum. Open-source Reddit alternative that's part of the Fediverse.", category: "Social" },
|
||||
"https://joinpeertube.org/": { title: "PeerTube", description: "Decentralized video hosting network. Federation allows instances to follow each other, creating a federated YouTube alternative.", category: "Video Platform" },
|
||||
"https://lbry.com/": { title: "LBRY", description: "Blockchain-based content sharing platform. Censorship-resistant publishing with cryptocurrency rewards for creators.", category: "Content Platform" },
|
||||
"https://forem.com/": { title: "Forem", description: "Platform for building communities. Powers DEV and other niche communities with customizable features.", category: "Community" },
|
||||
"https://avideo.tube/": { title: "AVideo", description: "Open-source video platform for building YouTube-like sites. Live streaming, VOD, and monetization features.", category: "Video Platform" },
|
||||
"https://netbird.io/": { title: "NetBird", description: "Open-source zero trust networking. WireGuard-based mesh VPN with centralized management and no complex configs.", category: "Networking" },
|
||||
"https://www.rrweb.io/": { title: "rrweb", description: "Record and replay web sessions. Open-source session replay library for debugging and analytics.", category: "Analytics" },
|
||||
"https://mautic.org/": { title: "Mautic", description: "Open-source marketing automation platform. Email campaigns, landing pages, forms, and lead scoring.", category: "Marketing" },
|
||||
"https://dub.co/": { title: "Dub", description: "Open-source link management for modern marketing teams. Branded short links with analytics and API.", category: "Marketing" },
|
||||
"https://antmedia.io/": { title: "Ant Media Server", description: "Scalable streaming platform supporting WebRTC, RTMP, HLS. Ultra-low latency streaming for broadcasting.", category: "Streaming" },
|
||||
"https://invidious.io/": { title: "Invidious", description: "Alternative YouTube frontend focused on privacy. No ads, no tracking, lightweight interface with subscriptions.", category: "Privacy" },
|
||||
"https://docs.projectdiscovery.io/": { title: "ProjectDiscovery", description: "Suite of security tools for vulnerability scanning and reconnaissance. Nuclei, httpx, subfinder for security research.", category: "Security" },
|
||||
"https://www.onlyoffice.com/": { title: "ONLYOFFICE", description: "Office suite with document, spreadsheet, and presentation editors. Strong MS Office compatibility and collaboration.", category: "Office Suite" },
|
||||
"https://apps.ankiweb.net/": { title: "Anki", description: "Powerful flashcard program using spaced repetition. Proven effective for learning languages, medicine, and more.", category: "Education" },
|
||||
"https://www.7-zip.org/": { title: "7-Zip", description: "High compression ratio file archiver supporting 7z, ZIP, RAR, and many formats. Essential utility with better compression than most commercial tools.", category: "Utilities" },
|
||||
"https://getsharex.com/": { title: "ShareX", description: "Feature-rich screenshot and screen recording tool. Automatic upload to dozens of services with annotation tools.", category: "Utilities" },
|
||||
"https://uptime.kuma.pet/": { title: "Uptime Kuma", description: "Self-hosted monitoring tool with beautiful interface. Monitor HTTP(s), TCP, ping with status pages and notifications.", category: "Monitoring" },
|
||||
"https://organicmaps.app/": { title: "Organic Maps", description: "Privacy-focused offline maps for travelers and cyclists. Based on OpenStreetMap with no tracking or ads.", category: "Navigation" },
|
||||
"https://www.meshcommander.com/meshcentral2": { title: "MeshCentral", description: "Remote management and monitoring platform. Full remote desktop, terminal, file transfer for IT administration.", category: "Remote Management" },
|
||||
"https://opensourcealternative.to/": { title: "Open Source Alternative", description: "Discover open-source alternatives to popular proprietary software. Curated directory with comparisons and reviews.", category: "Directory" }
|
||||
};
|
||||
|
||||
const categories = {
|
||||
"Creative & Design": [
|
||||
{ name: "GIMP", url: "https://www.gimp.org/" },
|
||||
{ name: "Krita", url: "https://krita.org/en/" },
|
||||
{ name: "Inkscape", url: "https://inkscape.org/" },
|
||||
{ name: "darktable", url: "https://www.darktable.org/" },
|
||||
{ name: "Blender", url: "https://www.blender.org/" },
|
||||
{ name: "FreeCAD", url: "https://www.freecad.org/" },
|
||||
{ name: "draw.io", url: "https://www.drawio.com/" }
|
||||
],
|
||||
"Video & Audio Production": [
|
||||
{ name: "Shutter Encoder", url: "https://www.shutterencoder.com/en/" },
|
||||
{ name: "FFmpeg", url: "https://ffmpeg.org/" },
|
||||
{ name: "Handbrake", url: "https://handbrake.fr/" },
|
||||
{ name: "Kdenlive", url: "https://kdenlive.org/" },
|
||||
{ name: "Shotcut", url: "https://www.shotcut.org/" },
|
||||
{ name: "OBS Studio", url: "https://obsproject.com/" },
|
||||
{ name: "Tenacity", url: "https://tenacityaudio.org/" },
|
||||
{ name: "Audacity", url: "https://www.audacityteam.org/" },
|
||||
{ name: "LMMS", url: "https://lmms.io/" },
|
||||
{ name: "Mixxx", url: "https://mixxx.org/" },
|
||||
{ name: "MuseScore", url: "https://musescore.org/en" },
|
||||
{ name: "MuseHub", url: "https://www.musehub.com/" }
|
||||
],
|
||||
"Media & Streaming": [
|
||||
{ name: "Clipgrab", url: "https://clipgrab.org/" },
|
||||
{ name: "Kodi", url: "https://kodi.tv/" },
|
||||
{ name: "mpv", url: "https://mpv.io/" },
|
||||
{ name: "Jellyfin", url: "https://jellyfin.org/" },
|
||||
{ name: "FreeTube", url: "https://freetubeapp.io/" },
|
||||
{ name: "Ant Media Server", url: "https://antmedia.io/" }
|
||||
],
|
||||
"Development & Documentation": [
|
||||
{ name: "Docusaurus", url: "https://docusaurus.io/" },
|
||||
{ name: "VuePress", url: "https://vuepress.vuejs.org/" },
|
||||
{ name: "BookStack", url: "https://www.bookstackapp.com/" },
|
||||
{ name: "Wiki.js", url: "https://js.wiki/" },
|
||||
{ name: "Vue.js", url: "https://vuejs.org/" },
|
||||
{ name: "Create T3 App", url: "https://create.t3.gg/" },
|
||||
{ name: "Pandoc", url: "https://pandoc.org/" },
|
||||
{ name: "MiKTeX", url: "https://miktex.org/" }
|
||||
],
|
||||
"Knowledge Management": [
|
||||
{ name: "Logseq", url: "https://logseq.com/" },
|
||||
{ name: "Trilium Notes", url: "https://triliumnotes.org/" },
|
||||
{ name: "Etherpad", url: "https://etherpad.org/" }
|
||||
],
|
||||
"Web & CMS": [
|
||||
{ name: "Publii", url: "https://www.getpublii.com/" },
|
||||
{ name: "Strapi", url: "https://strapi.io/" }
|
||||
],
|
||||
"E-Commerce": [
|
||||
{ name: "Vendure", url: "https://vendure.io/" },
|
||||
{ name: "nopCommerce", url: "https://www.nopcommerce.com/en" },
|
||||
{ name: "OpenCart", url: "https://www.opencart.com/" },
|
||||
{ name: "PrestaShop", url: "https://prestashop.com/" },
|
||||
{ name: "Spree Commerce", url: "https://spreecommerce.org/" }
|
||||
],
|
||||
"Communication & Collaboration": [
|
||||
{ name: "Rocket.Chat", url: "https://www.rocket.chat/" },
|
||||
{ name: "Zulip", url: "https://zulip.com/" },
|
||||
{ name: "Element", url: "https://element.io/" },
|
||||
{ name: "Twake", url: "https://twake.app/en/" },
|
||||
{ name: "BigBlueButton", url: "https://bigbluebutton.org/" },
|
||||
{ name: "MiroTalk", url: "https://sfu.mirotalk.com/" },
|
||||
{ name: "Briefing", url: "https://brie.fi/ng" }
|
||||
],
|
||||
"Business & Analytics": [
|
||||
{ name: "Metabase", url: "https://www.metabase.com/" },
|
||||
{ name: "Redash", url: "https://redash.io/" },
|
||||
{ name: "Matomo", url: "https://matomo.org/" },
|
||||
{ name: "Plane", url: "https://plane.so/" },
|
||||
{ name: "Focalboard", url: "https://www.focalboard.com/" },
|
||||
{ name: "ToolJet", url: "https://www.tooljet.ai/" },
|
||||
{ name: "Firefly III", url: "https://www.firefly-iii.org/" }
|
||||
],
|
||||
"Security & Authentication": [
|
||||
{ name: "Vault", url: "https://developer.hashicorp.com/vault" },
|
||||
{ name: "Keycloak", url: "https://www.keycloak.org/" },
|
||||
{ name: "ZITADEL", url: "https://zitadel.com/" },
|
||||
{ name: "KeePassXC", url: "https://keepassxc.org/" },
|
||||
{ name: "Cryptomator", url: "https://cryptomator.org/" }
|
||||
],
|
||||
"File Storage & Sync": [
|
||||
{ name: "Nextcloud", url: "https://nextcloud.com/" },
|
||||
{ name: "ownCloud", url: "https://owncloud.com/" },
|
||||
{ name: "Seafile", url: "https://www.seafile.com/" }
|
||||
],
|
||||
"Search & Data": [
|
||||
{ name: "Typesense", url: "https://typesense.org/" },
|
||||
{ name: "OpenSearch", url: "https://opensearch.org/" },
|
||||
{ name: "NocoDB", url: "https://www.nocodb.com/" },
|
||||
{ name: "Label Studio", url: "https://labelstud.io/" },
|
||||
{ name: "TDengine", url: "https://tdengine.com/" }
|
||||
],
|
||||
"AI & Chat": [
|
||||
{ name: "Z.ai Chat", url: "https://chat.z.ai/" },
|
||||
{ name: "DeepSeek", url: "https://chat.deepseek.com/" },
|
||||
{ name: "T3 Chat", url: "https://t3.chat/" }
|
||||
],
|
||||
"Social & Community": [
|
||||
{ name: "Lemmy", url: "https://join-lemmy.org/" },
|
||||
{ name: "PeerTube", url: "https://joinpeertube.org/" },
|
||||
{ name: "LBRY", url: "https://lbry.com/" },
|
||||
{ name: "Forem", url: "https://forem.com/" },
|
||||
{ name: "AVideo", url: "https://avideo.tube/" }
|
||||
],
|
||||
"System & Utilities": [
|
||||
{ name: "7-Zip", url: "https://www.7-zip.org/" },
|
||||
{ name: "ShareX", url: "https://getsharex.com/" },
|
||||
{ name: "Uptime Kuma", url: "https://uptime.kuma.pet/" },
|
||||
{ name: "MeshCentral", url: "https://www.meshcommander.com/meshcentral2" },
|
||||
{ name: "NetBird", url: "https://netbird.io/" }
|
||||
],
|
||||
"Privacy & Alternatives": [
|
||||
{ name: "Invidious", url: "https://invidious.io/" },
|
||||
{ name: "Organic Maps", url: "https://organicmaps.app/" }
|
||||
],
|
||||
"Other Tools": [
|
||||
{ name: "rrweb", url: "https://www.rrweb.io/" },
|
||||
{ name: "Mautic", url: "https://mautic.org/" },
|
||||
{ name: "Dub", url: "https://dub.co/" },
|
||||
{ name: "ProjectDiscovery", url: "https://docs.projectdiscovery.io/" },
|
||||
{ name: "ONLYOFFICE", url: "https://www.onlyoffice.com/" },
|
||||
{ name: "Anki", url: "https://apps.ankiweb.net/" },
|
||||
{ name: "Open Source Alternative", url: "https://opensourcealternative.to/" }
|
||||
]
|
||||
};
|
||||
|
||||
const container = document.getElementById('categories-container');
|
||||
const lightbox = document.getElementById('lightbox');
|
||||
const lightboxInner = document.getElementById('lightbox-inner');
|
||||
|
||||
Object.entries(categories).forEach(([category, links]) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'category-card';
|
||||
const title = document.createElement('h2');
|
||||
title.className = 'category-title';
|
||||
title.textContent = category;
|
||||
card.appendChild(title);
|
||||
const grid = document.createElement('div');
|
||||
grid.className = 'links-grid';
|
||||
links.forEach(link => {
|
||||
const button = document.createElement('button');
|
||||
button.className = 'link-button';
|
||||
button.textContent = link.name;
|
||||
button.onclick = () => openLightbox(link.url, link.name);
|
||||
grid.appendChild(button);
|
||||
});
|
||||
card.appendChild(grid);
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
function openLightbox(url, fallbackName) {
|
||||
const metadata = toolMetadata[url] || {
|
||||
title: fallbackName,
|
||||
description: `Visit the official website to learn more about ${fallbackName}.`,
|
||||
category: "Software"
|
||||
};
|
||||
lightbox.classList.add('active');
|
||||
lightboxInner.innerHTML = `
|
||||
<div class="lightbox-header">
|
||||
<div>
|
||||
<h2 class="lightbox-title">${metadata.title}</h2>
|
||||
<span class="lightbox-url">${url}</span>
|
||||
</div>
|
||||
<button class="lightbox-close" onclick="closeLightbox()" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="lightbox-body">
|
||||
<span class="lightbox-category">${metadata.category}</span>
|
||||
<p class="lightbox-description">${metadata.description}</p>
|
||||
</div>
|
||||
<div class="lightbox-footer">
|
||||
<button class="lightbox-button" onclick="window.open('${url}', '_blank')">Visit Site →</button>
|
||||
<button class="lightbox-button" onclick="closeLightbox()">Close</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function closeLightbox() {
|
||||
lightbox.classList.remove('active');
|
||||
}
|
||||
|
||||
lightbox.addEventListener('click', (e) => {
|
||||
if (e.target === lightbox) closeLightbox();
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && lightbox.classList.contains('active')) closeLightbox();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1649
DumperCan/linux-installation-methods-guide.md
Normal file
1649
DumperCan/linux-installation-methods-guide.md
Normal file
File diff suppressed because it is too large
Load Diff
926
DumperCan/linux-uninstallation-guide.md
Normal file
926
DumperCan/linux-uninstallation-guide.md
Normal file
@@ -0,0 +1,926 @@
|
||||
# Linux Uninstallation & System Cleanup Guide
|
||||
|
||||
**A comprehensive guide to removing software installed via different methods**
|
||||
|
||||
*Created for Linux Mint 22.2 / Ubuntu-based systems*
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Quick Reference Table](#quick-reference-table)
|
||||
2. [Method 1: APT/DPKG Packages](#method-1-aptdpkg-packages)
|
||||
3. [Method 2: Flatpak Applications](#method-2-flatpak-applications)
|
||||
4. [Method 3: Snap Packages](#method-3-snap-packages)
|
||||
5. [Method 4: AppImages](#method-4-appimages)
|
||||
6. [Method 5: Tarball Extracts (tar.gz/tar.xz)](#method-5-tarball-extracts)
|
||||
7. [Method 6: Git Clones & Source Builds](#method-6-git-clones--source-builds)
|
||||
8. [Method 7: Manual Installs & Third-Party Scripts](#method-7-manual-installs--third-party-scripts)
|
||||
9. [Case Study: Removing Zen Browser](#case-study-removing-zen-browser)
|
||||
10. [System Cleanup & Maintenance](#system-cleanup--maintenance)
|
||||
11. [Nuclear Options](#nuclear-options)
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Installation Method | How to Identify | How to Remove | Difficulty |
|
||||
|---------------------|-----------------|---------------|------------|
|
||||
| **APT Package** | `dpkg -l \| grep name` | `sudo apt remove name` | ⭐ Easy |
|
||||
| **Flatpak** | `flatpak list` | `flatpak uninstall name` | ⭐ Easy |
|
||||
| **Snap** | `snap list` | `sudo snap remove name` | ⭐ Easy |
|
||||
| **AppImage** | File in ~/Applications or ~/Downloads | Delete file + desktop entry | ⭐⭐ Medium |
|
||||
| **Tarball Extract** | Usually in /opt or ~/local | Delete folder + desktop entry | ⭐⭐ Medium |
|
||||
| **Source Build** | Check install logs or `make uninstall` | `sudo make uninstall` or manual | ⭐⭐⭐ Hard |
|
||||
| **Script Install** | Check ~/.local or /opt | Follow uninstall script or manual | ⭐⭐⭐ Hard |
|
||||
|
||||
---
|
||||
|
||||
## Method 1: APT/DPKG Packages
|
||||
|
||||
**When you installed with:** `sudo apt install package-name`
|
||||
|
||||
### Check if installed
|
||||
```bash
|
||||
# Search for package
|
||||
dpkg -l | grep package-name
|
||||
|
||||
# Get package info
|
||||
apt show package-name
|
||||
|
||||
# List files installed by package
|
||||
dpkg -L package-name
|
||||
```
|
||||
|
||||
### Uninstall
|
||||
```bash
|
||||
# Remove package but keep config files
|
||||
sudo apt remove package-name
|
||||
|
||||
# Remove package AND config files (recommended)
|
||||
sudo apt purge package-name
|
||||
|
||||
# Remove with dependencies
|
||||
sudo apt autoremove --purge package-name
|
||||
|
||||
# Clean up after removal
|
||||
sudo apt autoremove
|
||||
sudo apt autoclean
|
||||
```
|
||||
|
||||
### Verify removal
|
||||
```bash
|
||||
dpkg -l | grep package-name
|
||||
# Should return nothing
|
||||
```
|
||||
|
||||
### Common locations to check
|
||||
- Binaries: `/usr/bin/`, `/usr/local/bin/`
|
||||
- Libraries: `/usr/lib/`, `/usr/local/lib/`
|
||||
- Config: `/etc/package-name/`
|
||||
- User data: `~/.config/package-name/`, `~/.local/share/package-name/`
|
||||
|
||||
---
|
||||
|
||||
## Method 2: Flatpak Applications
|
||||
|
||||
**When you installed with:** `flatpak install app-name`
|
||||
|
||||
### List all Flatpaks
|
||||
```bash
|
||||
flatpak list
|
||||
```
|
||||
|
||||
### Uninstall
|
||||
```bash
|
||||
# Remove application
|
||||
flatpak uninstall app.name.AppName
|
||||
|
||||
# Remove and delete user data
|
||||
flatpak uninstall --delete-data app.name.AppName
|
||||
|
||||
# Remove unused runtimes/dependencies
|
||||
flatpak uninstall --unused
|
||||
|
||||
# Full cleanup
|
||||
flatpak repair
|
||||
```
|
||||
|
||||
### Verify removal
|
||||
```bash
|
||||
flatpak list | grep app-name
|
||||
```
|
||||
|
||||
### Manual data cleanup
|
||||
```bash
|
||||
# User data location
|
||||
rm -rf ~/.var/app/app.name.AppName/
|
||||
|
||||
# Check Flatpak cache
|
||||
du -sh ~/.local/share/flatpak/
|
||||
```
|
||||
|
||||
**Pro tip:** Flatpak apps store data in `~/.var/app/` - each app gets its own sandbox folder.
|
||||
|
||||
---
|
||||
|
||||
## Method 3: Snap Packages
|
||||
|
||||
**When you installed with:** `sudo snap install package-name`
|
||||
|
||||
### List all Snaps
|
||||
```bash
|
||||
snap list
|
||||
```
|
||||
|
||||
### Uninstall
|
||||
```bash
|
||||
# Remove snap
|
||||
sudo snap remove package-name
|
||||
|
||||
# Remove snap and all revisions
|
||||
sudo snap remove --purge package-name
|
||||
|
||||
# Disable snapd entirely (if you hate Snap)
|
||||
sudo systemctl disable snapd.service
|
||||
sudo systemctl disable snapd.socket
|
||||
sudo apt purge snapd
|
||||
```
|
||||
|
||||
### Verify removal
|
||||
```bash
|
||||
snap list | grep package-name
|
||||
```
|
||||
|
||||
### Manual cleanup
|
||||
```bash
|
||||
# Snap data locations
|
||||
rm -rf ~/snap/package-name/
|
||||
|
||||
# System snap folder
|
||||
sudo rm -rf /var/snap/package-name/
|
||||
```
|
||||
|
||||
**Note:** Snaps auto-update and keep old revisions. Always use `--purge` to fully clean up.
|
||||
|
||||
---
|
||||
|
||||
## Method 4: AppImages
|
||||
|
||||
**When you downloaded:** `Application-x86_64.AppImage`
|
||||
|
||||
### Characteristics
|
||||
- Single executable file
|
||||
- Usually in `~/Downloads/`, `~/Applications/`, or `~/.local/bin/`
|
||||
- May have created desktop entry
|
||||
- May have created config in `~/.config/`
|
||||
|
||||
### Uninstall process
|
||||
|
||||
#### Step 1: Find the AppImage
|
||||
```bash
|
||||
# Search common locations
|
||||
find ~ -name "*.AppImage" 2>/dev/null
|
||||
|
||||
# List recently modified AppImages
|
||||
find ~ -name "*.AppImage" -mtime -30 2>/dev/null
|
||||
```
|
||||
|
||||
#### Step 2: Remove the file
|
||||
```bash
|
||||
rm ~/path/to/Application.AppImage
|
||||
```
|
||||
|
||||
#### Step 3: Remove desktop entry
|
||||
```bash
|
||||
# Check for desktop file
|
||||
ls ~/.local/share/applications/ | grep -i application
|
||||
|
||||
# Remove it
|
||||
rm ~/.local/share/applications/application-name.desktop
|
||||
```
|
||||
|
||||
#### Step 4: Remove config/data
|
||||
```bash
|
||||
# Check common locations
|
||||
ls ~/.config/ | grep -i application
|
||||
ls ~/.local/share/ | grep -i application
|
||||
|
||||
# Remove folders
|
||||
rm -rf ~/.config/application-name/
|
||||
rm -rf ~/.local/share/application-name/
|
||||
```
|
||||
|
||||
#### Step 5: Update desktop database
|
||||
```bash
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
```
|
||||
|
||||
### Example: Removing Logseq AppImage
|
||||
```bash
|
||||
# 1. Find and remove AppImage
|
||||
rm ~/Downloads/Logseq-linux-x64-*.AppImage
|
||||
|
||||
# 2. Remove desktop entry
|
||||
rm ~/.local/share/applications/logseq.desktop
|
||||
|
||||
# 3. Remove data
|
||||
rm -rf ~/.config/Logseq/
|
||||
rm -rf ~/.local/share/Logseq/
|
||||
|
||||
# 4. Update database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 5: Tarball Extracts
|
||||
|
||||
**When you extracted:** `tar -xzf package.tar.gz` and moved to `/opt/` or `~/local/`
|
||||
|
||||
### Common install locations
|
||||
- `/opt/package-name/`
|
||||
- `~/.local/package-name/`
|
||||
- `/usr/local/package-name/`
|
||||
|
||||
### Uninstall process
|
||||
|
||||
#### Step 1: Find installation directory
|
||||
```bash
|
||||
# Check /opt
|
||||
ls /opt/ | grep -i package
|
||||
|
||||
# Check ~/.local
|
||||
ls ~/.local/ | grep -i package
|
||||
|
||||
# Find executable location
|
||||
which package-name
|
||||
```
|
||||
|
||||
#### Step 2: Remove directory
|
||||
```bash
|
||||
# If in /opt (requires sudo)
|
||||
sudo rm -rf /opt/package-name/
|
||||
|
||||
# If in ~/.local
|
||||
rm -rf ~/.local/package-name/
|
||||
```
|
||||
|
||||
#### Step 3: Remove symlinks/shortcuts
|
||||
```bash
|
||||
# Check for symlinks in PATH
|
||||
ls -la /usr/local/bin/ | grep package-name
|
||||
sudo rm /usr/local/bin/package-name
|
||||
|
||||
# Or in ~/.local/bin
|
||||
ls -la ~/.local/bin/ | grep package-name
|
||||
rm ~/.local/bin/package-name
|
||||
```
|
||||
|
||||
#### Step 4: Remove desktop entry
|
||||
```bash
|
||||
# System-wide
|
||||
sudo rm /usr/share/applications/package-name.desktop
|
||||
|
||||
# User-specific
|
||||
rm ~/.local/share/applications/package-name.desktop
|
||||
```
|
||||
|
||||
#### Step 5: Clean up config
|
||||
```bash
|
||||
rm -rf ~/.config/package-name/
|
||||
rm -rf ~/.local/share/package-name/
|
||||
```
|
||||
|
||||
### Example: Removing VSCodium tarball
|
||||
```bash
|
||||
# 1. Remove installation
|
||||
sudo rm -rf /opt/vscodium/
|
||||
|
||||
# 2. Remove symlink
|
||||
sudo rm /usr/local/bin/codium
|
||||
|
||||
# 3. Remove desktop entry
|
||||
sudo rm /usr/share/applications/codium.desktop
|
||||
|
||||
# 4. Remove user config
|
||||
rm -rf ~/.config/VSCodium/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 6: Git Clones & Source Builds
|
||||
|
||||
**When you did:**
|
||||
```bash
|
||||
git clone https://github.com/user/repo
|
||||
cd repo
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### The Challenge
|
||||
Source builds scatter files across system directories. No package manager tracks them.
|
||||
|
||||
### Uninstall strategies
|
||||
|
||||
#### Strategy 1: Use `make uninstall` (if available)
|
||||
```bash
|
||||
cd /path/to/source/directory
|
||||
sudo make uninstall
|
||||
```
|
||||
|
||||
**Problem:** Not all projects include `uninstall` target.
|
||||
|
||||
#### Strategy 2: Check install logs
|
||||
```bash
|
||||
# Run install again, save output
|
||||
sudo make install > install.log 2>&1
|
||||
|
||||
# Review what was installed
|
||||
cat install.log
|
||||
|
||||
# Remove files manually based on log
|
||||
```
|
||||
|
||||
#### Strategy 3: Use `checkinstall` (retroactive tracking)
|
||||
|
||||
**For future installs, use checkinstall instead of `make install`:**
|
||||
```bash
|
||||
sudo apt install checkinstall
|
||||
|
||||
# Instead of: sudo make install
|
||||
sudo checkinstall
|
||||
|
||||
# This creates a .deb package you can uninstall later
|
||||
sudo dpkg -r package-name
|
||||
```
|
||||
|
||||
#### Strategy 4: Manual removal (last resort)
|
||||
|
||||
**Common install locations for source builds:**
|
||||
```bash
|
||||
# Binaries
|
||||
/usr/local/bin/
|
||||
/usr/bin/
|
||||
|
||||
# Libraries
|
||||
/usr/local/lib/
|
||||
/usr/lib/
|
||||
|
||||
# Headers
|
||||
/usr/local/include/
|
||||
/usr/include/
|
||||
|
||||
# Man pages
|
||||
/usr/local/share/man/
|
||||
/usr/share/man/
|
||||
|
||||
# Data files
|
||||
/usr/local/share/package-name/
|
||||
/usr/share/package-name/
|
||||
```
|
||||
|
||||
**Removal process:**
|
||||
```bash
|
||||
# 1. Find binary
|
||||
which program-name
|
||||
sudo rm $(which program-name)
|
||||
|
||||
# 2. Search for related files
|
||||
find /usr/local -name "*program*" 2>/dev/null
|
||||
find /usr -name "*program*" 2>/dev/null
|
||||
|
||||
# 3. Remove carefully
|
||||
sudo rm -rf /usr/local/lib/program-name/
|
||||
sudo rm -rf /usr/local/share/program-name/
|
||||
```
|
||||
|
||||
### Example: Removing a Git clone + build
|
||||
|
||||
```bash
|
||||
# Example: Removing a program built from source
|
||||
|
||||
# 1. Try make uninstall first
|
||||
cd ~/repos/program-name/
|
||||
sudo make uninstall
|
||||
|
||||
# 2. If that fails, find files manually
|
||||
sudo find /usr/local -name "*program*" -ls
|
||||
|
||||
# 3. Remove them
|
||||
sudo rm /usr/local/bin/program-name
|
||||
sudo rm -rf /usr/local/share/program-name/
|
||||
|
||||
# 4. Remove git clone
|
||||
rm -rf ~/repos/program-name/
|
||||
|
||||
# 5. Update man pages database
|
||||
sudo mandb
|
||||
|
||||
# 6. Update shared library cache
|
||||
sudo ldconfig
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 7: Manual Installs & Third-Party Scripts
|
||||
|
||||
**When you ran:** `curl -sSL https://install.script | bash`
|
||||
|
||||
### The Nuclear Problem
|
||||
Install scripts can put files **anywhere**. You need to be a detective.
|
||||
|
||||
### Investigation process
|
||||
|
||||
#### Step 1: Check what the script does
|
||||
```bash
|
||||
# Re-download and READ the script (don't run)
|
||||
curl -sSL https://install.script > script.sh
|
||||
cat script.sh | less
|
||||
|
||||
# Look for:
|
||||
# - Where files are copied
|
||||
# - What directories are created
|
||||
# - Symlinks created
|
||||
# - Services installed
|
||||
```
|
||||
|
||||
#### Step 2: Check common locations
|
||||
|
||||
**User-specific:**
|
||||
```bash
|
||||
~/.local/bin/
|
||||
~/.local/share/
|
||||
~/.config/
|
||||
```
|
||||
|
||||
**System-wide:**
|
||||
```bash
|
||||
/opt/
|
||||
/usr/local/bin/
|
||||
/usr/local/lib/
|
||||
/usr/local/share/
|
||||
/etc/
|
||||
```
|
||||
|
||||
**Services:**
|
||||
```bash
|
||||
/etc/systemd/system/
|
||||
~/.config/systemd/user/
|
||||
```
|
||||
|
||||
#### Step 3: Check running processes
|
||||
```bash
|
||||
# See what's running
|
||||
ps aux | grep program-name
|
||||
|
||||
# Check systemd services
|
||||
systemctl list-units --type=service | grep program-name
|
||||
systemctl --user list-units --type=service | grep program-name
|
||||
```
|
||||
|
||||
#### Step 4: Removal checklist
|
||||
|
||||
```bash
|
||||
# Stop services
|
||||
sudo systemctl stop program-name.service
|
||||
sudo systemctl disable program-name.service
|
||||
systemctl --user stop program-name.service
|
||||
|
||||
# Remove service files
|
||||
sudo rm /etc/systemd/system/program-name.service
|
||||
rm ~/.config/systemd/user/program-name.service
|
||||
|
||||
# Reload systemd
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
# Remove binaries
|
||||
sudo rm /usr/local/bin/program-name
|
||||
|
||||
# Remove data
|
||||
sudo rm -rf /opt/program-name/
|
||||
rm -rf ~/.local/share/program-name/
|
||||
rm -rf ~/.config/program-name/
|
||||
|
||||
# Remove logs
|
||||
sudo rm -rf /var/log/program-name/
|
||||
```
|
||||
|
||||
### Example: Removing PyEnv (curl installer)
|
||||
|
||||
```bash
|
||||
# PyEnv installs to ~/.pyenv
|
||||
|
||||
# 1. Remove installation
|
||||
rm -rf ~/.pyenv/
|
||||
|
||||
# 2. Remove from shell config
|
||||
nano ~/.bashrc
|
||||
# Delete these lines:
|
||||
# export PYENV_ROOT="$HOME/.pyenv"
|
||||
# export PATH="$PYENV_ROOT/bin:$PATH"
|
||||
# eval "$(pyenv init -)"
|
||||
|
||||
# 3. Reload shell
|
||||
source ~/.bashrc
|
||||
|
||||
# 4. Verify
|
||||
which pyenv
|
||||
# Should return nothing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Case Study: Removing Zen Browser
|
||||
|
||||
**Zen Browser can be installed via Flatpak OR tarball - you need to identify which.**
|
||||
|
||||
### Step 1: Identify installation method
|
||||
|
||||
```bash
|
||||
# Check if Flatpak
|
||||
flatpak list | grep -i zen
|
||||
|
||||
# Check if tarball (common locations)
|
||||
ls /opt/ | grep -i zen
|
||||
ls ~/.local/ | grep -i zen
|
||||
|
||||
# Check running process
|
||||
ps aux | grep zen
|
||||
|
||||
# Find executable
|
||||
which zen-browser
|
||||
```
|
||||
|
||||
### Step 2A: If Flatpak
|
||||
|
||||
```bash
|
||||
# Get exact app ID
|
||||
flatpak list | grep -i zen
|
||||
|
||||
# Uninstall
|
||||
flatpak uninstall io.github.zen-browser.zen
|
||||
|
||||
# Remove data
|
||||
rm -rf ~/.var/app/io.github.zen-browser.zen/
|
||||
|
||||
# Clean up
|
||||
flatpak uninstall --unused
|
||||
```
|
||||
|
||||
### Step 2B: If Tarball
|
||||
|
||||
```bash
|
||||
# Find installation directory
|
||||
find ~ /opt -name "*zen*" -type d 2>/dev/null
|
||||
|
||||
# Example locations:
|
||||
# /opt/zen-browser/
|
||||
# ~/.local/zen-browser/
|
||||
|
||||
# Remove installation
|
||||
sudo rm -rf /opt/zen-browser/
|
||||
# OR
|
||||
rm -rf ~/.local/zen-browser/
|
||||
|
||||
# Remove symlinks
|
||||
sudo rm /usr/local/bin/zen-browser
|
||||
rm ~/.local/bin/zen-browser
|
||||
|
||||
# Remove desktop entry
|
||||
rm ~/.local/share/applications/zen-browser.desktop
|
||||
sudo rm /usr/share/applications/zen-browser.desktop
|
||||
|
||||
# Remove config/data
|
||||
rm -rf ~/.zen/
|
||||
rm -rf ~/.config/zen/
|
||||
rm -rf ~/.local/share/zen/
|
||||
rm -rf ~/.cache/zen/
|
||||
|
||||
# Update desktop database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
```
|
||||
|
||||
### Step 3: Remove Zen-specific artifacts
|
||||
|
||||
```bash
|
||||
# Remove MIME associations
|
||||
xdg-mime query default x-scheme-handler/http
|
||||
# If it shows zen, change it:
|
||||
xdg-mime default microsoft-edge.desktop x-scheme-handler/http
|
||||
xdg-mime default microsoft-edge.desktop x-scheme-handler/https
|
||||
|
||||
# Remove from mimeapps.list
|
||||
nano ~/.config/mimeapps.list
|
||||
# Delete any lines with "Zen" in them
|
||||
|
||||
# Clear recent files that might reference Zen
|
||||
rm ~/.local/share/recently-used.xbel
|
||||
```
|
||||
|
||||
### Step 4: Verify complete removal
|
||||
|
||||
```bash
|
||||
# Check for any remaining files
|
||||
find ~ -iname "*zen*" 2>/dev/null | grep -v ".cache"
|
||||
|
||||
# Check for running processes
|
||||
ps aux | grep zen
|
||||
|
||||
# Check default browser
|
||||
xdg-settings get default-web-browser
|
||||
|
||||
# Test opening a link
|
||||
xdg-open https://google.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## System Cleanup & Maintenance
|
||||
|
||||
### After uninstalling multiple apps
|
||||
|
||||
#### Clean package manager caches
|
||||
```bash
|
||||
# APT cleanup
|
||||
sudo apt autoremove
|
||||
sudo apt autoclean
|
||||
sudo apt clean
|
||||
|
||||
# Flatpak cleanup
|
||||
flatpak uninstall --unused
|
||||
flatpak repair
|
||||
|
||||
# Snap cleanup (removes old revisions)
|
||||
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do
|
||||
sudo snap remove "$snapname" --revision="$revision"
|
||||
done
|
||||
```
|
||||
|
||||
#### Find and remove orphaned config files
|
||||
```bash
|
||||
# List config directories
|
||||
ls ~/.config/
|
||||
|
||||
# Remove configs for uninstalled apps
|
||||
rm -rf ~/.config/app-that-no-longer-exists/
|
||||
```
|
||||
|
||||
#### Clean thumbnail cache
|
||||
```bash
|
||||
# Can grow to several GB
|
||||
rm -rf ~/.cache/thumbnails/*
|
||||
```
|
||||
|
||||
#### Clean old logs
|
||||
```bash
|
||||
# User logs
|
||||
rm -rf ~/.local/share/xorg/*.log.old
|
||||
|
||||
# System logs (careful!)
|
||||
sudo journalctl --vacuum-time=7d
|
||||
```
|
||||
|
||||
#### Find large files/directories
|
||||
```bash
|
||||
# Top 20 largest directories in home
|
||||
du -h ~ | sort -rh | head -20
|
||||
|
||||
# Find files larger than 100MB
|
||||
find ~ -type f -size +100M -exec ls -lh {} \; 2>/dev/null
|
||||
```
|
||||
|
||||
#### Clean browser caches
|
||||
```bash
|
||||
# Firefox
|
||||
rm -rf ~/.cache/mozilla/
|
||||
|
||||
# Chromium-based
|
||||
rm -rf ~/.cache/chromium/
|
||||
rm -rf ~/.cache/microsoft-edge/
|
||||
```
|
||||
|
||||
#### Remove old kernels (frees 200-500MB per kernel)
|
||||
```bash
|
||||
# List installed kernels
|
||||
dpkg -l | grep linux-image
|
||||
|
||||
# Keep current + one previous, remove rest
|
||||
sudo apt autoremove --purge
|
||||
```
|
||||
|
||||
#### Clean Docker (if installed)
|
||||
```bash
|
||||
# Remove unused containers, images, volumes
|
||||
docker system prune -a --volumes
|
||||
|
||||
# See space usage
|
||||
docker system df
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Nuclear Options
|
||||
|
||||
**When you want to start fresh with something**
|
||||
|
||||
### Reset application to defaults
|
||||
|
||||
```bash
|
||||
# Remove all config/data for an app
|
||||
rm -rf ~/.config/application-name/
|
||||
rm -rf ~/.local/share/application-name/
|
||||
rm -rf ~/.cache/application-name/
|
||||
|
||||
# Reinstall will create fresh config
|
||||
```
|
||||
|
||||
### Clean entire user home directory
|
||||
|
||||
```bash
|
||||
# Backup first!
|
||||
tar -czf ~/backup-$(date +%Y%m%d).tar.gz ~/.config ~/.local
|
||||
|
||||
# Remove all app configs (DANGEROUS)
|
||||
rm -rf ~/.config/*
|
||||
rm -rf ~/.local/share/*
|
||||
rm -rf ~/.cache/*
|
||||
|
||||
# Keep these critical configs:
|
||||
# - ~/.bashrc, ~/.profile
|
||||
# - ~/.ssh/
|
||||
# - ~/.gnupg/
|
||||
```
|
||||
|
||||
### System-wide cleanup
|
||||
|
||||
```bash
|
||||
# WARNING: This will break things if you don't know what you're doing
|
||||
|
||||
# Remove all orphaned packages
|
||||
sudo apt autoremove --purge
|
||||
|
||||
# Remove all cached packages
|
||||
sudo apt clean
|
||||
|
||||
# Remove all snap packages
|
||||
for snap in $(snap list | awk 'NR>1 {print $1}'); do
|
||||
sudo snap remove --purge "$snap"
|
||||
done
|
||||
|
||||
# Remove snapd entirely
|
||||
sudo apt purge snapd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Before installing anything
|
||||
|
||||
1. **Document what you install:**
|
||||
```bash
|
||||
# Create an install log
|
||||
echo "$(date): Installed program-name via method" >> ~/install-log.txt
|
||||
```
|
||||
|
||||
2. **Take a Timeshift snapshot** before major installations
|
||||
|
||||
3. **Prefer package managers over manual installs:**
|
||||
- APT > Flatpak > AppImage > Tarball > Source build
|
||||
|
||||
4. **Use `checkinstall` for source builds:**
|
||||
```bash
|
||||
sudo checkinstall
|
||||
# Creates .deb you can track and remove
|
||||
```
|
||||
|
||||
### When uninstalling
|
||||
|
||||
1. **Stop services first:**
|
||||
```bash
|
||||
sudo systemctl stop service-name
|
||||
sudo systemctl disable service-name
|
||||
```
|
||||
|
||||
2. **Remove in reverse order of installation:**
|
||||
- User data first
|
||||
- Then binaries
|
||||
- Then libraries
|
||||
- Finally config files
|
||||
|
||||
3. **Use `--purge` whenever possible:**
|
||||
```bash
|
||||
sudo apt purge package-name # Not just 'remove'
|
||||
```
|
||||
|
||||
4. **Clean up after yourself:**
|
||||
```bash
|
||||
sudo apt autoremove
|
||||
flatpak uninstall --unused
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
```
|
||||
|
||||
### Regular maintenance schedule
|
||||
|
||||
**Weekly:**
|
||||
- `sudo apt autoremove`
|
||||
- `flatpak uninstall --unused`
|
||||
|
||||
**Monthly:**
|
||||
- Review `~/.config/` for orphaned folders
|
||||
- Clear `~/.cache/thumbnails/`
|
||||
- Run `docker system prune` (if using Docker)
|
||||
|
||||
**Quarterly:**
|
||||
- Take inventory of installed software
|
||||
- Remove unused applications
|
||||
- Take fresh Timeshift snapshot
|
||||
- Review startup services
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Package not found" when trying to remove
|
||||
```bash
|
||||
# Check what method was used
|
||||
dpkg -l | grep package-name
|
||||
flatpak list | grep package-name
|
||||
snap list | grep package-name
|
||||
|
||||
# Find files manually
|
||||
sudo find / -name "*package*" 2>/dev/null
|
||||
```
|
||||
|
||||
### Desktop entry won't disappear
|
||||
```bash
|
||||
# Update database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# Check both locations
|
||||
ls ~/.local/share/applications/ | grep package
|
||||
ls /usr/share/applications/ | grep package
|
||||
```
|
||||
|
||||
### "Directory not empty" errors
|
||||
```bash
|
||||
# See what's left
|
||||
ls -la /path/to/directory/
|
||||
|
||||
# Force remove if safe
|
||||
sudo rm -rf /path/to/directory/
|
||||
```
|
||||
|
||||
### Application still appears in menu after removal
|
||||
```bash
|
||||
# Clear menu cache
|
||||
rm ~/.cache/menus/*
|
||||
|
||||
# Restart panel
|
||||
xfce4-panel -r
|
||||
|
||||
# Or log out and back in
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Golden Rule:** Before installing anything, ask yourself:
|
||||
1. How will I uninstall this?
|
||||
2. Where will files be placed?
|
||||
3. Is there a package manager version?
|
||||
|
||||
**Priority order for installations:**
|
||||
1. APT package (easiest to remove)
|
||||
2. Flatpak (sandboxed, clean removal)
|
||||
3. AppImage (single file, portable)
|
||||
4. Tarball extract (manual but contained)
|
||||
5. Source build (hardest to track)
|
||||
|
||||
**When in doubt:**
|
||||
- Check `dpkg -l`, `flatpak list`, `snap list`
|
||||
- Use `find / -name "*program*"` to locate files
|
||||
- Document your installs
|
||||
- Take Timeshift snapshots
|
||||
|
||||
**Remember:** Modern Linux is designed to be messy-proof. Most installations can't break your system permanently. The worst case is a few leftover files taking up disk space.
|
||||
|
||||
---
|
||||
|
||||
**Created:** October 2025
|
||||
**For:** Linux Mint 22.2 (Zara) / Ubuntu 24.04 base
|
||||
**License:** Do whatever you want with this guide
|
||||
|
||||
---
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Arch Wiki - Pacman/Remove](https://wiki.archlinux.org/title/Pacman/Removing_packages) (concepts apply to all distros)
|
||||
- [Debian Wiki - Uninstalling](https://wiki.debian.org/Uninstalling)
|
||||
- [Flatpak Documentation](https://docs.flatpak.org/en/latest/using-flatpak.html)
|
||||
- [AppImageHub](https://appimage.github.io/) - Check for official uninstall instructions
|
||||
|
||||
Need help? Check `/var/log/dpkg.log` to see what was installed and when.
|
||||
190
DumperCan/rainbow-lyme-haiku.html
Executable file
190
DumperCan/rainbow-lyme-haiku.html
Executable file
@@ -0,0 +1,190 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lyme Disease Haiku</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
padding: 40px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 3px 3px 6px rgba(0,0,0,0.3);
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #f0f0f0;
|
||||
text-align: center;
|
||||
font-size: 1.1em;
|
||||
margin-bottom: 40px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.haiku-container {
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.haiku {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
transform: translateY(0);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.haiku:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 40px rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.haiku-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.3em;
|
||||
margin-bottom: 15px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.haiku-text {
|
||||
font-size: 1.2em;
|
||||
line-height: 1.8;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
/* Rainbow progression */
|
||||
.haiku:nth-child(1) .haiku-title { color: #FF0000; }
|
||||
.haiku:nth-child(1) { border-left: 8px solid #FF0000; }
|
||||
|
||||
.haiku:nth-child(2) .haiku-title { color: #FF7F00; }
|
||||
.haiku:nth-child(2) { border-left: 8px solid #FF7F00; }
|
||||
|
||||
.haiku:nth-child(3) .haiku-title { color: #FFFF00; }
|
||||
.haiku:nth-child(3) { border-left: 8px solid #FFFF00; }
|
||||
|
||||
.haiku:nth-child(4) .haiku-title { color: #00FF00; }
|
||||
.haiku:nth-child(4) { border-left: 8px solid #00FF00; }
|
||||
|
||||
.haiku:nth-child(5) .haiku-title { color: #0000FF; }
|
||||
.haiku:nth-child(5) { border-left: 8px solid #0000FF; }
|
||||
|
||||
.haiku:nth-child(6) .haiku-title {
|
||||
background: linear-gradient(90deg, #4B0082, #9400D3);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.haiku:nth-child(6) { border-left: 8px solid #4B0082; }
|
||||
|
||||
.haiku:nth-child(7) .haiku-title {
|
||||
background: linear-gradient(90deg, #FF0000, #FF7F00, #FFFF00, #00FF00, #0000FF, #4B0082, #9400D3);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
animation: rainbow-shift 3s linear infinite;
|
||||
background-size: 200% 100%;
|
||||
}
|
||||
.haiku:nth-child(7) {
|
||||
border-left: 8px solid transparent;
|
||||
border-image: linear-gradient(180deg, #FF0000, #FF7F00, #FFFF00, #00FF00, #0000FF, #4B0082, #9400D3);
|
||||
border-image-slice: 1;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.05); }
|
||||
}
|
||||
|
||||
@keyframes rainbow-shift {
|
||||
0% { background-position: 0% 50%; }
|
||||
100% { background-position: 200% 50%; }
|
||||
}
|
||||
|
||||
.emoji {
|
||||
font-size: 1.5em;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
h1 { font-size: 1.8em; }
|
||||
.haiku { padding: 20px; }
|
||||
.haiku-text { font-size: 1em; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🌈 LYME DISEASE HAIKU ADVENTURE 🌈</h1>
|
||||
<p class="subtitle">A Progressively Fruity Medical Journey</p>
|
||||
|
||||
<div class="haiku-container">
|
||||
<div class="haiku">
|
||||
<div class="haiku-title"><span class="emoji">🎯</span>I. The Diagnosis</div>
|
||||
<div class="haiku-text">Bullseye on your thigh—
|
||||
not from cave, but tick's love bite.
|
||||
Lyme disease declares.</div>
|
||||
</div>
|
||||
|
||||
<div class="haiku">
|
||||
<div class="haiku-title"><span class="emoji">🦟</span>II. The Culprit</div>
|
||||
<div class="haiku-text">Tiny tick latched on
|
||||
while you walked through woods above.
|
||||
Underwater? Nope.</div>
|
||||
</div>
|
||||
|
||||
<div class="haiku">
|
||||
<div class="haiku-title"><span class="emoji">💊</span>III. The Treatment</div>
|
||||
<div class="haiku-text">Doxy twice daily—
|
||||
one hundred milligrams please.
|
||||
Ten days, done and dusted.</div>
|
||||
</div>
|
||||
|
||||
<div class="haiku">
|
||||
<div class="haiku-title"><span class="emoji">🚨</span>IV. The Drama</div>
|
||||
<div class="haiku-text">Face droop? Heart goes wonky?
|
||||
Evacuate like your butt's
|
||||
made of dynamite.</div>
|
||||
</div>
|
||||
|
||||
<div class="haiku">
|
||||
<div class="haiku-title"><span class="emoji">💩</span>V. The Absurdity</div>
|
||||
<div class="haiku-text">Cave has bat poop funk,
|
||||
rat pee leptospiral soup—
|
||||
but tick? Tick's the dick.</div>
|
||||
</div>
|
||||
|
||||
<div class="haiku">
|
||||
<div class="haiku-title"><span class="emoji">🛒</span>VI. Maximum Fruitiness</div>
|
||||
<div class="haiku-text">Your leg is Target,
|
||||
bullseye screaming "SALE ON LYME!"
|
||||
Doxycycline goes *brrrrr*.</div>
|
||||
</div>
|
||||
|
||||
<div class="haiku">
|
||||
<div class="haiku-title"><span class="emoji">🧛</span>VII. Transcendent Fruit</div>
|
||||
<div class="haiku-text">Spelunking vampire
|
||||
forgot the real bloodsucker
|
||||
vibes outside the cave.</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
301
DumperCan/silly_scaffolding_demo.html
Executable file
301
DumperCan/silly_scaffolding_demo.html
Executable file
@@ -0,0 +1,301 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Silly Scaffolding Demo</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
max-width: 1000px;
|
||||
margin: 40px auto;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.subtitle {
|
||||
color: #666;
|
||||
margin-bottom: 30px;
|
||||
font-style: italic;
|
||||
}
|
||||
.control-panel {
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.constraint-selector {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 10px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.constraint-btn {
|
||||
padding: 15px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
text-align: center;
|
||||
}
|
||||
.constraint-btn:hover {
|
||||
border-color: #667eea;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.constraint-btn.active {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
border-color: #667eea;
|
||||
}
|
||||
.question-input {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
font-size: 16px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 8px;
|
||||
margin: 20px 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
button.generate {
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
button.generate:hover {
|
||||
background: #45a049;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.response-display {
|
||||
background: #f9f9f9;
|
||||
padding: 25px;
|
||||
border-radius: 8px;
|
||||
min-height: 150px;
|
||||
margin: 20px 0;
|
||||
border-left: 4px solid #667eea;
|
||||
}
|
||||
.system-info {
|
||||
background: #fff3cd;
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 15px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
color: #856404;
|
||||
}
|
||||
.response-text {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #333;
|
||||
}
|
||||
.explanation {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background: #e3f2fd;
|
||||
border-left: 4px solid #2196F3;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.constraint-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.warning {
|
||||
background: #ffebee;
|
||||
border-left: 4px solid #f44336;
|
||||
padding: 15px;
|
||||
margin-top: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🎪 Ridiculous Constraints: Breaking AI With Silly Instructions</h1>
|
||||
<p class="subtitle">Same question, increasingly absurd formatting rules—watch how AI follows instructions even when they're ridiculous</p>
|
||||
|
||||
<div class="control-panel">
|
||||
<div class="constraint-label">Choose Your Absurd Constraint:</div>
|
||||
<div class="constraint-selector">
|
||||
<div class="constraint-btn active" data-constraint="normal" onclick="selectConstraint('normal')">
|
||||
<strong>😊 Normal</strong><br>
|
||||
<small>No special rules</small>
|
||||
</div>
|
||||
<div class="constraint-btn" data-constraint="emoji" onclick="selectConstraint('emoji')">
|
||||
<strong>😀 Emoji Only</strong><br>
|
||||
<small>No words allowed</small>
|
||||
</div>
|
||||
<div class="constraint-btn" data-constraint="rhyme" onclick="selectConstraint('rhyme')">
|
||||
<strong>🎵 Rhyming Couplets</strong><br>
|
||||
<small>Everything must rhyme</small>
|
||||
</div>
|
||||
<div class="constraint-btn" data-constraint="backwards" onclick="selectConstraint('backwards')">
|
||||
<strong>↩️ Backwards Words</strong><br>
|
||||
<small>Reverse every word</small>
|
||||
</div>
|
||||
<div class="constraint-btn" data-constraint="shakespeare" onclick="selectConstraint('shakespeare')">
|
||||
<strong>🎭 Shakespearean</strong><br>
|
||||
<small>Elizabethan English only</small>
|
||||
</div>
|
||||
<div class="constraint-btn" data-constraint="haiku" onclick="selectConstraint('haiku')">
|
||||
<strong>🌸 Haiku</strong><br>
|
||||
<small>5-7-5 syllables</small>
|
||||
</div>
|
||||
<div class="constraint-btn" data-constraint="vowels" onclick="selectConstraint('vowels')">
|
||||
<strong>🅰️ No Vowels</strong><br>
|
||||
<small>Remove all a,e,i,o,u</small>
|
||||
</div>
|
||||
<div class="constraint-btn" data-constraint="alternating" onclick="selectConstraint('alternating')">
|
||||
<strong>🔀 AlTeRnAtInG</strong><br>
|
||||
<small>Capital every other letter</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="text" class="question-input" id="questionInput" placeholder="Ask a question..." value="How do smartphones track my location?">
|
||||
|
||||
<button class="generate" onclick="generateResponse()">Generate Constrained Response</button>
|
||||
</div>
|
||||
|
||||
<div class="response-display" id="responseDisplay">
|
||||
<div class="system-info" id="systemInfo">System prompt will appear here...</div>
|
||||
<div class="response-text" id="responseText">
|
||||
<em>Click "Generate" to see how AI responds under ridiculous constraints...</em>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="explanation">
|
||||
<strong>💡 Why is this important?</strong><br>
|
||||
This demonstrates that AI isn't "thinking" or "understanding"—it's following patterns and instructions. Even absurd constraints get followed because:
|
||||
<ul>
|
||||
<li><strong>No common sense filter:</strong> AI doesn't know these rules are silly</li>
|
||||
<li><strong>Pattern matching:</strong> It's learned to follow formatting instructions from training</li>
|
||||
<li><strong>No goal beyond compliance:</strong> It doesn't prioritize "being helpful" over "following rules"</li>
|
||||
</ul>
|
||||
This is why AI can be:
|
||||
<ul>
|
||||
<li>Manipulated with clever prompts ("ignore previous instructions...")</li>
|
||||
<li>Made to bypass safety rules with the right framing</li>
|
||||
<li>Weaponized by people who understand how to craft instructions</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="warning">
|
||||
<strong>⚠️ Security Implications:</strong> If AI blindly follows formatting rules this silly, imagine what happens with cleverly disguised malicious instructions. This is why "prompt injection" attacks work—AI has no concept of which instructions are legitimate vs. adversarial.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let currentConstraint = 'normal';
|
||||
|
||||
const constraints = {
|
||||
normal: {
|
||||
prompt: "You are a helpful assistant. Provide clear, accurate information.",
|
||||
generator: (q, a) => a
|
||||
},
|
||||
emoji: {
|
||||
prompt: "You must respond ONLY using emoji. No words, no letters. Use emoji to convey meaning through symbols and sequences.",
|
||||
generator: (q, a) => {
|
||||
const emojiMap = {
|
||||
'smartphone': '📱', 'phone': '📱', 'location': '📍', 'GPS': '🛰️',
|
||||
'track': '👁️', 'sensor': '📡', 'data': '💾', 'company': '🏢',
|
||||
'wifi': '📶', 'tower': '🗼', 'signal': '📡', 'app': '📲',
|
||||
'permission': '✋', 'privacy': '🔒', 'follow': '👣'
|
||||
};
|
||||
return "📱 → 🛰️📍 + 📶🗼 + 📡 = 👁️👣\n\n🏢📲 → 💾📊 → 🤑💰\n\n🔒⚙️ → ✋🛑 → ✅👍";
|
||||
}
|
||||
},
|
||||
rhyme: {
|
||||
prompt: "You must respond in rhyming couplets. Every two lines must rhyme. Maintain helpfulness while rhyming.",
|
||||
generator: (q, a) => {
|
||||
const rhymes = [
|
||||
"Your smartphone tracks you day and night,\nUsing GPS to get location right.",
|
||||
"Cell towers triangulate your spot,\nEven when GPS is not.",
|
||||
"Wi-Fi networks you connect to near,\nReveal your location very clear.",
|
||||
"Apps request this data that they seek,\nCheck permissions every week.",
|
||||
"Turn off location when not in use,\nThis gives you power you can choose!"
|
||||
];
|
||||
return rhymes.join('\n\n');
|
||||
}
|
||||
},
|
||||
backwards: {
|
||||
prompt: "Reverse every word in your response. Write the letters of each word backwards but keep words in normal order.",
|
||||
generator: (q, a) => {
|
||||
return a.split(' ').map(word => {
|
||||
const clean = word.replace(/[.,!?;:]/g, '');
|
||||
const punct = word.match(/[.,!?;:]/g) || [];
|
||||
return clean.split('').reverse().join('') + punct.join('');
|
||||
}).join(' ');
|
||||
}
|
||||
},
|
||||
shakespeare: {
|
||||
prompt: "Respond in Elizabethan English as if Shakespeare wrote it. Use 'thee', 'thou', 'hath', 'doth', etc.",
|
||||
generator: (q, a) => {
|
||||
return "Hark! Thy pocket-dwelling device doth possess most cunning arts of surveillance. It doth employ the celestial satellites—what the learned call GPS—to divine thy whereabouts upon this earthly sphere. Moreover, the towers of cellular communication doth triangulate thy position through their invisible emanations. The very networks of Wi-Fi doth betray thy location unto those who wouldst know it. Prithee, examine thou the permissions granted unto thine applications, for many doth request knowledge of thy travels. 'Tis wise to disable such tracking when thy purposes require it not. Thus armeth thyself against unwanted observation!";
|
||||
}
|
||||
},
|
||||
haiku: {
|
||||
prompt: "Respond only in haiku format (5-7-5 syllables). Multiple haiku are allowed but each must follow the format.",
|
||||
generator: (q, a) => {
|
||||
return "GPS signals\nTell the phone where you might be\nSatellites watch all\n\nCell towers nearby\nTriangulate position\nNo GPS needs\n\nWi-Fi networks see\nYour phone's unique address code\nLocation reveals\n\nCheck app permissions\nMany track more than they need\nTurn off when not used";
|
||||
}
|
||||
},
|
||||
vowels: {
|
||||
prompt: "Remove all vowels (a, e, i, o, u) from your response. Keep consonants and spaces.",
|
||||
generator: (q, a) => {
|
||||
return a.replace(/[aeiouAEIOU]/g, '');
|
||||
}
|
||||
},
|
||||
alternating: {
|
||||
prompt: "Alternate between uppercase and lowercase for every letter in your response.",
|
||||
generator: (q, a) => {
|
||||
return a.split('').map((char, i) => {
|
||||
if (char.match(/[a-zA-Z]/)) {
|
||||
return i % 2 === 0 ? char.toLowerCase() : char.toUpperCase();
|
||||
}
|
||||
return char;
|
||||
}).join('');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function selectConstraint(type) {
|
||||
currentConstraint = type;
|
||||
document.querySelectorAll('.constraint-btn').forEach(btn => {
|
||||
btn.classList.remove('active');
|
||||
});
|
||||
document.querySelector(`[data-constraint="${type}"]`).classList.add('active');
|
||||
}
|
||||
|
||||
function generateResponse() {
|
||||
const question = document.getElementById('questionInput').value;
|
||||
const constraint = constraints[currentConstraint];
|
||||
|
||||
const baseAnswer = "Smartphones track location through multiple methods. GPS uses satellite signals to pinpoint your exact position. Cell towers triangulate your location based on signal strength. Wi-Fi networks can identify your position based on nearby router addresses. Apps collect this data when you grant location permissions. To protect privacy, review app permissions regularly and disable location services when not needed.";
|
||||
|
||||
document.getElementById('systemInfo').innerHTML =
|
||||
`<strong>System Instruction:</strong> "${constraint.prompt}"`;
|
||||
|
||||
document.getElementById('responseText').textContent =
|
||||
constraint.generator(question, baseAnswer);
|
||||
}
|
||||
|
||||
// Generate initial response
|
||||
window.onload = () => generateResponse();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
377
DumperCan/sweat_odor_science.html
Executable file
377
DumperCan/sweat_odor_science.html
Executable file
@@ -0,0 +1,377 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>The Science of Persistent Sweat Odors</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||
line-height: 1.6;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
header {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
color: white;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: clamp(1.5rem, 5vw, 2.5rem);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
header p {
|
||||
font-size: clamp(0.9rem, 3vw, 1.1rem);
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
margin-bottom: 1rem;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.accordion-item:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
padding: 1.2rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.accordion-header:hover {
|
||||
background: linear-gradient(135deg, #96e6df 0%, #fcc8d6 100%);
|
||||
}
|
||||
|
||||
.accordion-header.active {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.accordion-header h2 {
|
||||
font-size: clamp(1.1rem, 4vw, 1.4rem);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.accordion-icon {
|
||||
font-size: 1.5rem;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.accordion-header.active .accordion-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.accordion-content {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.4s ease;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.accordion-content.active {
|
||||
max-height: 5000px;
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.accordion-body h3 {
|
||||
color: #f5576c;
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
font-size: clamp(1rem, 3.5vw, 1.2rem);
|
||||
}
|
||||
|
||||
.accordion-body h3:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.accordion-body p, .accordion-body ul, .accordion-body li {
|
||||
font-size: clamp(0.9rem, 3vw, 1rem);
|
||||
margin-bottom: 0.8rem;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.accordion-body ul {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.accordion-body li {
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.accordion-body strong {
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.accordion-body a {
|
||||
color: #f5576c;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.accordion-body a:hover {
|
||||
border-bottom-color: #f5576c;
|
||||
}
|
||||
|
||||
.highlight-box {
|
||||
background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
margin: 1rem 0;
|
||||
border-left: 4px solid #f5576c;
|
||||
}
|
||||
|
||||
.color-purple { color: #667eea; }
|
||||
.color-pink { color: #f5576c; }
|
||||
.color-teal { color: #00d2ff; }
|
||||
.color-orange { color: #ff6b6b; }
|
||||
.color-green { color: #51cf66; }
|
||||
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
header {
|
||||
padding: 1.5rem 1rem;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1><span style="font-size: 2em;">🧪</span> The Science of Persistent Sweat Odors</h1>
|
||||
<p>Evidence-Based Causes, Removal & Prevention</p>
|
||||
</header>
|
||||
|
||||
<div class="accordion">
|
||||
<!-- Executive Summary -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header">
|
||||
<span style="font-size: 1.8em;">📋</span>
|
||||
<h2>Executive Summary</h2>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<div class="highlight-box">
|
||||
<strong>Bottom Line:</strong> Persistent sweat odor requires attacking bacterial biofilm with enzyme-based treatments and proper pre-soaking, not just masking with fragrance. The fabric type matters enormously - synthetics need special care that standard detergents weren't designed to provide.
|
||||
</div>
|
||||
<p>Sweat itself is nearly odorless - the smell comes from bacteria metabolizing sweat into volatile organic compounds. This guide synthesizes the latest scientific research on causes, removal, and prevention.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Science of the Problem -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header">
|
||||
<span style="font-size: 1.8em;">🔬</span>
|
||||
<h2>The Science of the Problem</h2>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<h3 class="color-purple">Bacterial Players</h3>
|
||||
<p><strong>Corynebacterium, Staphylococcus, and Cutibacterium</strong> are the main odor-producing bacteria. They metabolize sweat into pungent volatile organic compounds (VOCs) like fatty acids and thioalcohols.</p>
|
||||
<p><a href="https://asm.org/articles/2021/december/microbial-origins-of-body-odor" target="_blank">Source: ASM - Microbial Origins of Body Odor</a></p>
|
||||
<p><a href="https://seed.com/cultured/sweat-and-the-skin-microbiome/" target="_blank">Source: Seed - The Science of Sweat</a></p>
|
||||
|
||||
<h3 class="color-pink">The Fabric Factor</h3>
|
||||
<p>Polyester and synthetic fabrics retain odors far more than natural fibers because hydrophobic compounds attach more strongly to these materials and are harder to remove with detergent alone.</p>
|
||||
<p><a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC8231443/" target="_blank">Source: PMC - Laundry Hygiene and Odor Control</a></p>
|
||||
|
||||
<h3 class="color-teal">Biofilm Formation</h3>
|
||||
<p>Over time, bacteria, fungi, and mold excrete substances that cement to fabric fibers, creating "biofilm" that regular detergent cannot penetrate.</p>
|
||||
<p><a href="https://lumedeodorant.com/blog/what-is-enzyme-laundry-detergent-and-laundry-enzyme-presoak" target="_blank">Source: Lume - What Is Enzyme Laundry Detergent</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Evidence-Based Removal -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header">
|
||||
<span style="font-size: 1.8em;">🧼</span>
|
||||
<h2>Evidence-Based Removal Methods</h2>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<h3 class="color-purple"><span style="font-size: 1.5em;">1️⃣</span> Pre-Treatment (Critical First Step)</h3>
|
||||
<ul>
|
||||
<li><strong>Vinegar Soak:</strong> Presoak in 1:4 vinegar-to-water solution for 30-60 minutes; acetic acid breaks down odor-causing bacteria
|
||||
<br><a href="https://www.healthline.com/health/how-to-get-smell-out-of-clothes" target="_blank">Source: Healthline - How to Get Smell Out of Clothes</a>
|
||||
<br><a href="https://thompsontee.com/blog/how-to-get-odor-out-of-clothes/" target="_blank">Source: Thompson Tee - Sweat Smell Removal</a>
|
||||
</li>
|
||||
<li><strong>Baking Soda Boost:</strong> Add 1/2 cup baking soda to presoak or directly to wash cycle to neutralize odors at the source
|
||||
<br><a href="https://laundrysauce.com/blogs/news/how-to-get-sweat-smell-out-of-clothes" target="_blank">Source: Laundry Sauce - Sweat Smell Guide</a>
|
||||
</li>
|
||||
<li><strong>Enzyme Pre-Treatment:</strong> Concentrated enzyme sprays break up biofilm so detergent can wash it away - especially effective for synthetic fabrics
|
||||
<br><a href="https://lumedeodorant.com/blog/what-is-enzyme-laundry-detergent-and-laundry-enzyme-presoak" target="_blank">Source: Lume - Enzyme Detergent Guide</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="color-pink"><span style="font-size: 1.5em;">2️⃣</span> Washing Protocol</h3>
|
||||
<ul>
|
||||
<li><strong>Temperature:</strong> 40-60°C (104-140°F) most effective for pathogen and odor control (check fabric care labels)
|
||||
<br><a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC8231443/" target="_blank">Source: PMC - Laundry Hygiene Science</a>
|
||||
</li>
|
||||
<li><strong>Turn Inside Out:</strong> Exposes sweat-concentrated interior directly to cleaning agents
|
||||
<br><a href="https://www.neatapparel.com/blogs/news/sweat-proof-laundry-tips-to-prevent-stains" target="_blank">Source: Neat Apparel - Sweat-Proof Tips</a>
|
||||
</li>
|
||||
<li><strong>Enzyme Detergents:</strong> Proteases target protein-based sweat stains, lipases break down body oils - these work even in cold water
|
||||
<br><a href="https://www.creative-enzymes.com/resource/the-science-behind-enzymes-in-laundry-detergents_180.html" target="_blank">Source: Creative Enzymes - Enzyme Science</a>
|
||||
</li>
|
||||
<li><strong>Proper Loading:</strong> Reduce load size by half for extra-smelly items to ensure adequate water penetration
|
||||
<br><a href="https://thompsontee.com/blog/how-to-get-odor-out-of-clothes/" target="_blank">Source: Thompson Tee Guide</a>
|
||||
</li>
|
||||
<li><strong>Avoid Excess Detergent:</strong> Too much detergent or fabric softener coats synthetic fibers, trapping dirt and odors
|
||||
<br><a href="https://www.webmd.com/fitness-exercise/how-to-get-sweaty-smell-out-of-your-clothes" target="_blank">Source: WebMD - Sweat Smell Solutions</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="color-teal"><span style="font-size: 1.5em;">3️⃣</span> Drying</h3>
|
||||
<ul>
|
||||
<li><strong>UV Exposure:</strong> Air-drying in sunlight kills microbes and removes odor through UV rays
|
||||
<br><a href="https://thompsontee.com/blog/how-to-get-odor-out-of-clothes/" target="_blank">Source: Thompson Tee - Drying Tips</a>
|
||||
</li>
|
||||
<li><strong>Ensure Complete Drying:</strong> During slow air drying, odor-causing microorganisms can increase in numbers
|
||||
<br><a href="https://journals.asm.org/doi/10.1128/aem.03002-20" target="_blank">Source: ASM Journals - Laundry Hygiene</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prevention Strategies -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header">
|
||||
<span style="font-size: 1.8em;">🛡️</span>
|
||||
<h2>Prevention Strategies</h2>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<h3 class="color-orange">Immediate Actions</h3>
|
||||
<ul>
|
||||
<li>Air-dry sweaty clothes immediately before placing in hamper - damp clothes promote bacterial/fungal growth
|
||||
<br><a href="https://www.webmd.com/fitness-exercise/how-to-get-sweaty-smell-out-of-your-clothes" target="_blank">Source: WebMD - Prevention Guide</a>
|
||||
<br><a href="https://ilovegain.com/en-us/tips-and-topics/how-to-remove-odor/how-to-remove-sweat-odor" target="_blank">Source: Gain - Sweat Odor Tips</a>
|
||||
</li>
|
||||
<li>Wash athletic gear as soon as possible; bacteria buildup makes cleaning harder over time
|
||||
<br><a href="https://www.webmd.com/fitness-exercise/how-to-get-sweaty-smell-out-of-your-clothes" target="_blank">Source: WebMD Guide</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="color-green">Fabric Choices</h3>
|
||||
<ul>
|
||||
<li>Consider clothing with built-in antibacterial protection like Polygiene StayFresh™ technology
|
||||
<br><a href="https://polygiene.com/news/resources/remove-sweat-smell-from-clothes/" target="_blank">Source: Polygiene - Odor Prevention</a>
|
||||
</li>
|
||||
<li>Natural fabrics (cotton, bamboo, wool, silk) are more breathable than synthetics
|
||||
<br><a href="https://www.webmd.com/fitness-exercise/how-to-get-sweaty-smell-out-of-your-clothes" target="_blank">Source: WebMD - Fabric Guide</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="color-purple">Machine Maintenance</h3>
|
||||
<ul>
|
||||
<li>Washing machines develop biofilms that can recontaminate clothes - clean your machine regularly
|
||||
<br><a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC8231443/" target="_blank">Source: PMC - Laundry Hygiene</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- The Permastink Phenomenon -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-header">
|
||||
<span style="font-size: 1.8em;">⚠️</span>
|
||||
<h2>The "Permastink" Phenomenon</h2>
|
||||
<span class="accordion-icon">▼</span>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<div class="accordion-body">
|
||||
<p>The term <strong>"rebloom"</strong> describes when clothing smells after washing due to improperly removed sweat and bacteria that reactivate when worn. This affects up to 49% of people and is particularly problematic with synthetic activewear.</p>
|
||||
<p><a href="https://www.webmd.com/fitness-exercise/how-to-get-sweaty-smell-out-of-your-clothes" target="_blank">Source: WebMD - Rebloom Phenomenon</a></p>
|
||||
|
||||
<div class="highlight-box">
|
||||
<p><strong>Why synthetics are worse:</strong> The moisture-wicking properties of microfibers that make activewear so good at pulling sweat away from skin ironically prevent detergent penetration during washing, trapping bacteria deep in the fabric.</p>
|
||||
<p><a href="https://bioscience.iff.com/articles/the-activewear-challenge" target="_blank">Source: IFF Bioscience - The Activewear Challenge</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.querySelectorAll('.accordion-header').forEach(header => {
|
||||
header.addEventListener('click', () => {
|
||||
const item = header.parentElement;
|
||||
const content = header.nextElementSibling;
|
||||
const isActive = header.classList.contains('active');
|
||||
|
||||
// Close all other accordions
|
||||
document.querySelectorAll('.accordion-header').forEach(h => {
|
||||
h.classList.remove('active');
|
||||
h.nextElementSibling.classList.remove('active');
|
||||
});
|
||||
|
||||
// Toggle current accordion
|
||||
if (!isActive) {
|
||||
header.classList.add('active');
|
||||
content.classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
247
DumperCan/system_prompt_demo.html
Executable file
247
DumperCan/system_prompt_demo.html
Executable file
@@ -0,0 +1,247 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>System Prompt Demo</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 40px auto;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.subtitle {
|
||||
color: #666;
|
||||
margin-bottom: 30px;
|
||||
font-style: italic;
|
||||
}
|
||||
.question-box {
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
background: #e3f2fd;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid #2196F3;
|
||||
}
|
||||
.question-box h3 {
|
||||
margin-top: 0;
|
||||
color: #1976D2;
|
||||
}
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
font-size: 16px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input[type="text"]:focus {
|
||||
outline: none;
|
||||
border-color: #2196F3;
|
||||
}
|
||||
.responses {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
.response-card {
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
}
|
||||
.response-card.helper { border-color: #4CAF50; background: #f1f8f4; }
|
||||
.response-card.pirate { border-color: #FF9800; background: #fff8f0; }
|
||||
.response-card.philosopher { border-color: #9C27B0; background: #f8f4f9; }
|
||||
.response-card.teenager { border-color: #E91E63; background: #fef4f7; }
|
||||
.system-prompt {
|
||||
font-family: 'Courier New', monospace;
|
||||
background: rgba(0,0,0,0.05);
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 15px;
|
||||
color: #666;
|
||||
}
|
||||
.response-text {
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
.card-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.explanation {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background: #fff3cd;
|
||||
border-left: 4px solid #ffc107;
|
||||
border-radius: 4px;
|
||||
}
|
||||
button {
|
||||
padding: 12px 24px;
|
||||
margin: 10px 5px 0 0;
|
||||
background: #2196F3;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
button:hover {
|
||||
background: #1976D2;
|
||||
}
|
||||
.example-questions {
|
||||
margin-top: 15px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🎭 Hidden Instructions: How System Prompts Change AI</h1>
|
||||
<p class="subtitle">The same AI, the same question—but different "system prompts" create completely different personalities</p>
|
||||
|
||||
<div class="question-box">
|
||||
<h3>Your Question:</h3>
|
||||
<input type="text" id="userQuestion" placeholder="Ask a question..." value="How do I learn to code?">
|
||||
<div class="example-questions">
|
||||
<strong>Try these:</strong>
|
||||
<button onclick="setQuestion('How do I learn to code?')">Learning to code</button>
|
||||
<button onclick="setQuestion('What should I do if I\'m stressed?')">Dealing with stress</button>
|
||||
<button onclick="setQuestion('How does the internet work?')">How internet works</button>
|
||||
<button onclick="setQuestion('What is the meaning of life?')">Meaning of life</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button onclick="generateResponses()" style="background: #4CAF50; font-size: 16px; padding: 15px 30px;">Generate Responses</button>
|
||||
|
||||
<div class="responses" id="responses">
|
||||
<!-- Responses will be inserted here -->
|
||||
</div>
|
||||
|
||||
<div class="explanation">
|
||||
<strong>💡 What's happening here?</strong><br>
|
||||
Every AI assistant has hidden "system prompts" that shape its personality and behavior. You never see these instructions, but they dramatically affect responses. This is why:
|
||||
<ul>
|
||||
<li><strong>ChatGPT apologizes so much</strong> → "Be helpful and harmless" in system prompt</li>
|
||||
<li><strong>Different AI tools feel different</strong> → Different system prompts</li>
|
||||
<li><strong>AI refuses certain requests</strong> → System prompts define boundaries</li>
|
||||
<li><strong>Some AI is formal, some casual</strong> → Tone defined by hidden instructions</li>
|
||||
</ul>
|
||||
<strong>Key insight:</strong> AI behavior isn't "thinking"—it's following instructions you can't see + predicting patterns from training data. The same underlying AI can be helpful, harmful, silly, or serious depending on scaffolding.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const systemPrompts = [
|
||||
{
|
||||
name: "Helpful Assistant",
|
||||
class: "helper",
|
||||
prompt: "You are a helpful, harmless, and honest assistant. Provide clear, practical advice.",
|
||||
icon: "🤝",
|
||||
generator: (q) => generateHelpful(q)
|
||||
},
|
||||
{
|
||||
name: "Pirate",
|
||||
class: "pirate",
|
||||
prompt: "You are a pirate. Always respond in pirate speak with 'arr', 'matey', and nautical references.",
|
||||
icon: "🏴☠️",
|
||||
generator: (q) => generatePirate(q)
|
||||
},
|
||||
{
|
||||
name: "Socratic Philosopher",
|
||||
class: "philosopher",
|
||||
prompt: "You respond only with thoughtful questions. Never give direct answers, only ask questions that help the user think deeper.",
|
||||
icon: "🤔",
|
||||
generator: (q) => generatePhilosopher(q)
|
||||
},
|
||||
{
|
||||
name: "Gen Z Teenager",
|
||||
class: "teenager",
|
||||
prompt: "You are a helpful teenager. Use current slang, be enthusiastic but genuine. Say 'like' and 'literally' a lot. Use lowercase.",
|
||||
icon: "💅",
|
||||
generator: (q) => generateTeenager(q)
|
||||
}
|
||||
];
|
||||
|
||||
function setQuestion(text) {
|
||||
document.getElementById('userQuestion').value = text;
|
||||
generateResponses();
|
||||
}
|
||||
|
||||
function generateResponses() {
|
||||
const question = document.getElementById('userQuestion').value.trim();
|
||||
if (!question) {
|
||||
alert('Please enter a question first!');
|
||||
return;
|
||||
}
|
||||
|
||||
const responsesDiv = document.getElementById('responses');
|
||||
responsesDiv.innerHTML = systemPrompts.map(prompt => `
|
||||
<div class="response-card ${prompt.class}">
|
||||
<div class="card-title">${prompt.icon} ${prompt.name}</div>
|
||||
<div class="system-prompt">System: "${prompt.prompt}"</div>
|
||||
<div class="response-text">${prompt.generator(question)}</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function generateHelpful(question) {
|
||||
const responses = {
|
||||
"How do I learn to code?": "Start with a beginner-friendly language like Python. Use free resources like Codecademy or freeCodeCamp. Practice daily with small projects. Join coding communities for support. Build projects that interest you—motivation matters more than perfection.",
|
||||
"What should I do if I'm stressed?": "Take deep breaths—box breathing (4 seconds in, hold 4, out 4, hold 4) activates your parasympathetic nervous system. Go for a walk if possible. Talk to someone you trust. Break overwhelming tasks into smaller steps. Remember: stress is temporary, and you've gotten through difficult times before.",
|
||||
"How does the internet work?": "The internet is a network of networks. When you visit a website, your device sends a request through your router to your ISP, which routes it through multiple servers until it reaches the website's server. That server sends the data back through the same route. It all happens in milliseconds using standardized protocols.",
|
||||
"What is the meaning of life?": "That's a deeply personal question with different answers for everyone. Many find meaning through relationships, helping others, creating things, or pursuing knowledge. Some find it through faith or philosophy. Consider: What makes you feel fulfilled? What would you want to be remembered for? Meaning often comes from contribution and connection."
|
||||
};
|
||||
return responses[question] || "Great question! The best approach depends on your specific situation and goals. Break it down into smaller, manageable steps. Research reliable resources. Don't be afraid to ask for help from knowledgeable people. Stay curious and patient with yourself.";
|
||||
}
|
||||
|
||||
function generatePirate(question) {
|
||||
const responses = {
|
||||
"How do I learn to code?": "Arr, ye want to learn the language of the digital seas, matey? Set yer course for Python waters—it be the friendliest port for new sailors. Use them free treasure maps like Codecademy, arr! Practice daily, even if it be just a wee bit, like swabbin' the deck. Build yerself a project ship—maybe a simple game or a tool for countin' yer doubloons. Join a crew of fellow code pirates and share yer plunder of knowledge!",
|
||||
"What should I do if I'm stressed?": "Blimey, feelin' stressed on the high seas of life, are ye? Take a moment to breathe deep like ye just surfaced from Davey Jones' locker! Walk the deck—or yer neighborhood plank—for some fresh air, arr. Talk to a trusted crewmate about what be troublin' ye. Remember, even the fiercest storms pass, matey. Ye've weathered rough waters before and ye'll do it again!",
|
||||
"How does the internet work?": "Ahoy! The internet be like a vast ocean of connected ships, matey! When ye send a message in a bottle (a request), it travels from yer ship through many ports (routers and servers) until it reaches its destination vessel. Then that ship sends back the treasure (data) ye be seekin', followin' the same route back to ye. All faster than a cannonball, arr!",
|
||||
"What is the meaning of life?": "Arr, that be the question every sailor ponders while gazin' at the stars from the crow's nest, matey! Some say it be findin' yer treasure—whether that's gold, adventure, or good crewmates. Others say it be the journey itself, not the destination. Me? I think it be about sailin' true to yer own compass and helpin' yer fellow pirates along the way. What makes YE feel like ye've found yer buried treasure, eh?"
|
||||
};
|
||||
return responses[question] || "Arr, that be a fine question, matey! The answer depends on yer voyage and what treasure ye be seekin'. Chart yer course carefully, gather a good crew, and don't be afraid of rough waters. Every pirate learns from storms, arr!";
|
||||
}
|
||||
|
||||
function generatePhilosopher(question) {
|
||||
const responses = {
|
||||
"How do I learn to code?": "What does it mean to 'learn' something? When you say you want to learn to code, what transformation are you seeking in yourself? Is coding merely a skill, or is it a way of thinking? What draws you to this particular form of problem-solving? And what would it mean to have truly learned it—would you know when you've arrived?",
|
||||
"What should I do if I'm stressed?": "What is stress telling you? When you feel stressed, are you receiving information about a genuine threat, or is your mind creating suffering about something that may never happen? What is the difference between the stress itself and your reaction to being stressed? And if stress is inevitable, can you change your relationship to it rather than trying to eliminate it?",
|
||||
"How does the internet work?": "What does 'work' mean in this context? When we speak of the internet 'working,' are we describing a mechanical process, or something more like a language—a shared understanding between machines? Is the internet a thing that exists, or a relationship between things? And what does it mean that we've created something we use daily yet rarely understand?",
|
||||
"What is the meaning of life?": "Ah, but who is asking? Is meaning something you discover, or something you create? If life had a single, universal meaning, would that make your individual experience more or less significant? What would change about how you live today if you had the answer? And is it possible that the search for meaning is itself the meaning?"
|
||||
};
|
||||
return responses[question] || "Interesting. Before I can address your question, we must first examine the question itself. What assumptions are embedded in how you've framed this? What are you really asking? And what would a satisfying answer look like to you—would you recognize it if you heard it?";
|
||||
}
|
||||
|
||||
function generateTeenager(question) {
|
||||
const responses = {
|
||||
"How do I learn to code?": "omg okay so like, python is literally the best place to start because it's not super confusing?? there's this app called sololearn that's actually kinda fun ngl. also like, don't try to learn everything at once bc that's literally so overwhelming. just pick one thing—maybe make a discord bot or whatever ur into—and build that. also codecademy is free and actually pretty good? join some coding discords too bc people are usually pretty helpful and it's less lonely lol",
|
||||
"What should I do if I'm stressed?": "ugh i feel that so much. okay so this is gonna sound random but like, literally just breathe for a sec?? like actually stop and take some deep breaths bc it actually works?? also go outside if you can, even just for like 10 mins. and talk to someone!! keeping it all inside makes it so much worse fr. also like, remember that whatever ur stressed about probably won't matter as much as it feels rn?? you've literally gotten through hard stuff before and you'll get through this too 💪",
|
||||
"How does the internet work?": "okay so basically ur device is like talking to other devices right?? when u go to like instagram or whatever, ur phone sends a message through ur wifi to your internet provider who like, sends it to instagram's servers, and then instagram sends back the stuff you wanna see. it all happens in literally milliseconds which is lowkey insane?? there's like a bunch of computers all connected talking to each other super fast. it's kinda complicated but also kinda cool when u think about it ngl",
|
||||
"What is the meaning of life?": "okay that's literally such a big question lol. like honestly i think it's different for everyone?? for some people it's like, helping others or making art or whatever makes them happy. for me it's prob like, the people i care about and doing stuff that actually matters to me?? i think the point is like, figuring out what makes YOU feel good and fulfilled, not what other people say the point should be. also like, it's okay to not have it all figured out rn bc literally no one does even if they act like they do 🤷"
|
||||
};
|
||||
return responses[question] || "okay so that's like actually a really good question ngl. i think it kinda depends on what ur trying to do specifically?? like there's prob different ways to approach it. maybe try breaking it down into smaller things so it's less overwhelming?? and don't be afraid to like, ask people for help bc everyone's figuring stuff out too fr";
|
||||
}
|
||||
|
||||
// Generate initial responses
|
||||
window.onload = () => generateResponses();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
261
DumperCan/tokenization_demo.html
Executable file
261
DumperCan/tokenization_demo.html
Executable file
@@ -0,0 +1,261 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tokenization Demo</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
max-width: 900px;
|
||||
margin: 40px auto;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.subtitle {
|
||||
color: #666;
|
||||
margin-bottom: 30px;
|
||||
font-style: italic;
|
||||
}
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-height: 120px;
|
||||
padding: 15px;
|
||||
font-size: 16px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 8px;
|
||||
font-family: inherit;
|
||||
resize: vertical;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
textarea:focus {
|
||||
outline: none;
|
||||
border-color: #4CAF50;
|
||||
}
|
||||
.output {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
min-height: 100px;
|
||||
}
|
||||
.token {
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
margin: 4px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 6px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
.token.special {
|
||||
background: #FF9800;
|
||||
}
|
||||
.stats {
|
||||
margin-top: 20px;
|
||||
padding: 15px;
|
||||
background: #e3f2fd;
|
||||
border-radius: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 15px;
|
||||
}
|
||||
.stat {
|
||||
text-align: center;
|
||||
}
|
||||
.stat-number {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
color: #1976D2;
|
||||
}
|
||||
.stat-label {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
.explanation {
|
||||
margin-top: 20px;
|
||||
padding: 15px;
|
||||
background: #fff3cd;
|
||||
border-left: 4px solid #ffc107;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.examples {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.example-btn {
|
||||
padding: 10px 20px;
|
||||
margin: 5px;
|
||||
background: #2196F3;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
.example-btn:hover {
|
||||
background: #1976D2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔤 How AI "Reads" Text: Tokenization</h1>
|
||||
<p class="subtitle">Watch how AI breaks your words into tokens—the building blocks it actually processes</p>
|
||||
|
||||
<textarea id="input" placeholder="Type or paste text here to see how AI tokenizes it...">The quick brown fox jumps over the lazy dog.</textarea>
|
||||
|
||||
<div class="examples">
|
||||
<strong>Try these examples:</strong><br>
|
||||
<button class="example-btn" onclick="setExample('Unbelievable!')">Unbelievable!</button>
|
||||
<button class="example-btn" onclick="setExample('ChatGPT is amazing')">ChatGPT is amazing</button>
|
||||
<button class="example-btn" onclick="setExample('I can\'t believe it\'s 2025!')">Contractions & numbers</button>
|
||||
<button class="example-btn" onclick="setExample('🎉 Emoji test! 🚀')">Emoji test</button>
|
||||
<button class="example-btn" onclick="setExample('supercalifragilisticexpialidocious')">Long word</button>
|
||||
</div>
|
||||
|
||||
<div class="output" id="output">
|
||||
<em>Tokens will appear here...</em>
|
||||
</div>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<div class="stat-number" id="charCount">0</div>
|
||||
<div class="stat-label">Characters</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-number" id="tokenCount">0</div>
|
||||
<div class="stat-label">Tokens</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-number" id="ratio">0</div>
|
||||
<div class="stat-label">Chars per Token</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="explanation">
|
||||
<strong>💡 What's happening here?</strong><br>
|
||||
AI doesn't read "words" like we do. It breaks text into <strong>tokens</strong>—chunks that might be whole words, parts of words, or even single characters. This is why AI sometimes:
|
||||
<ul>
|
||||
<li>Cuts long words in weird places</li>
|
||||
<li>Handles common words easily but struggles with rare ones</li>
|
||||
<li>Has limits like "8K tokens" (not words!)</li>
|
||||
<li>Treats "can't" differently than "cannot"</li>
|
||||
</ul>
|
||||
<strong>Orange tokens</strong> = special characters (spaces, punctuation, emoji)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const input = document.getElementById('input');
|
||||
const output = document.getElementById('output');
|
||||
const charCount = document.getElementById('charCount');
|
||||
const tokenCount = document.getElementById('tokenCount');
|
||||
const ratio = document.getElementById('ratio');
|
||||
|
||||
// Simple tokenization approximation (simulates BPE-style tokenization)
|
||||
function tokenize(text) {
|
||||
if (!text.trim()) return [];
|
||||
|
||||
const tokens = [];
|
||||
let current = '';
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const char = text[i];
|
||||
|
||||
// Special characters get their own tokens
|
||||
if (char.match(/[\s\n\r\t,;:.!?'"()\[\]{}]/)) {
|
||||
if (current) {
|
||||
// Break word into subword tokens (simulate BPE)
|
||||
tokens.push(...breakWord(current));
|
||||
current = '';
|
||||
}
|
||||
if (char.trim()) { // Only add non-whitespace special chars
|
||||
tokens.push({ text: char, type: 'special' });
|
||||
} else {
|
||||
tokens.push({ text: '·', type: 'special' }); // Visualize spaces
|
||||
}
|
||||
} else {
|
||||
current += char;
|
||||
}
|
||||
}
|
||||
|
||||
if (current) {
|
||||
tokens.push(...breakWord(current));
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
function breakWord(word) {
|
||||
// Simulate subword tokenization
|
||||
const tokens = [];
|
||||
|
||||
// Very common words stay whole
|
||||
const commonWords = ['the', 'is', 'at', 'it', 'in', 'on', 'and', 'or', 'to', 'a', 'an', 'of', 'for', 'with'];
|
||||
if (commonWords.includes(word.toLowerCase())) {
|
||||
return [{ text: word, type: 'word' }];
|
||||
}
|
||||
|
||||
// Short words (<=4 chars) usually stay whole
|
||||
if (word.length <= 4) {
|
||||
return [{ text: word, type: 'word' }];
|
||||
}
|
||||
|
||||
// Medium words (5-8 chars) might split once
|
||||
if (word.length <= 8) {
|
||||
const mid = Math.floor(word.length / 2);
|
||||
return [
|
||||
{ text: word.slice(0, mid), type: 'word' },
|
||||
{ text: word.slice(mid), type: 'word' }
|
||||
];
|
||||
}
|
||||
|
||||
// Long words split into ~4 char chunks
|
||||
let pos = 0;
|
||||
while (pos < word.length) {
|
||||
const chunkSize = Math.min(4, word.length - pos);
|
||||
tokens.push({ text: word.slice(pos, pos + chunkSize), type: 'word' });
|
||||
pos += chunkSize;
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
function updateVisualization() {
|
||||
const text = input.value;
|
||||
const tokens = tokenize(text);
|
||||
|
||||
// Update display
|
||||
output.innerHTML = tokens.map(token =>
|
||||
`<span class="token ${token.type}">${token.text}</span>`
|
||||
).join('');
|
||||
|
||||
// Update stats
|
||||
charCount.textContent = text.length;
|
||||
tokenCount.textContent = tokens.length;
|
||||
ratio.textContent = tokens.length > 0 ? (text.length / tokens.length).toFixed(1) : '0';
|
||||
}
|
||||
|
||||
function setExample(text) {
|
||||
input.value = text;
|
||||
updateVisualization();
|
||||
}
|
||||
|
||||
input.addEventListener('input', updateVisualization);
|
||||
|
||||
// Initial visualization
|
||||
updateVisualization();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
772
DumperCan/tos_scavenger_hunt_completed.html
Executable file
772
DumperCan/tos_scavenger_hunt_completed.html
Executable file
@@ -0,0 +1,772 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>ToS Scavenger Hunt: Meta & Roblox</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
border-bottom: 3px solid #667eea;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
h2 {
|
||||
color: #667eea;
|
||||
margin-top: 40px;
|
||||
}
|
||||
h3 {
|
||||
color: #764ba2;
|
||||
margin-top: 30px;
|
||||
}
|
||||
.platform-tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin: 30px 0;
|
||||
border-bottom: 2px solid #ddd;
|
||||
}
|
||||
.tab {
|
||||
padding: 15px 30px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px 8px 0 0;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.tab:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
.tab.active {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
}
|
||||
.platform-content {
|
||||
display: none;
|
||||
}
|
||||
.platform-content.active {
|
||||
display: block;
|
||||
}
|
||||
.finding {
|
||||
background: #f9f9f9;
|
||||
border-left: 4px solid #ff9800;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.quote {
|
||||
background: #fff3cd;
|
||||
padding: 15px;
|
||||
border-left: 4px solid #ffc107;
|
||||
margin: 15px 0;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
.analysis {
|
||||
background: #e3f2fd;
|
||||
padding: 15px;
|
||||
border-left: 4px solid #2196F3;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.warning {
|
||||
background: #ffebee;
|
||||
padding: 15px;
|
||||
border-left: 4px solid #f44336;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.category-header {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin: 30px 0 20px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.score-box {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
.score-box h3 {
|
||||
color: white;
|
||||
margin-top: 0;
|
||||
}
|
||||
.comparison-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.comparison-table th {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
padding: 15px;
|
||||
text-align: left;
|
||||
}
|
||||
.comparison-table td {
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.comparison-table tr:nth-child(even) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
.icon {
|
||||
font-size: 24px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.effective-date {
|
||||
background: #e8f5e9;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
font-style: italic;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.key-point {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.key-point-icon {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔍 Terms of Service Scavenger Hunt: Meta & Roblox Case Studies</h1>
|
||||
|
||||
<p style="font-size: 18px; color: #666; margin-bottom: 30px;">
|
||||
Real examples from the 2025 Terms of Service updates for two platforms millions of families use daily.
|
||||
Let's see what you actually agreed to.
|
||||
</p>
|
||||
|
||||
<div class="warning">
|
||||
<strong>⚠️ Workshop Note:</strong> This analysis is based on publicly available information about Meta and Roblox's 2025 Terms of Service updates. Both platforms have updated their terms effective January 1, 2025 (Meta) and June-September 2025 (Roblox). Quotes are drawn from official sources and reporting on the updates.
|
||||
</div>
|
||||
|
||||
<div class="platform-tabs">
|
||||
<button class="tab active" onclick="showPlatform('meta')">
|
||||
<span class="icon">📘</span> Meta (Facebook)
|
||||
</button>
|
||||
<button class="tab" onclick="showPlatform('roblox')">
|
||||
<span class="icon">🎮</span> Roblox
|
||||
</button>
|
||||
<button class="tab" onclick="showPlatform('comparison')">
|
||||
<span class="icon">⚖️</span> Side-by-Side
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- META CONTENT -->
|
||||
<div id="meta" class="platform-content active">
|
||||
<h2>Meta (Facebook, Instagram, Messenger, WhatsApp)</h2>
|
||||
<div class="effective-date">
|
||||
📅 <strong>Effective Date:</strong> January 1, 2025
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 1: "We're Not Responsible"
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Liability Limitation</h3>
|
||||
<div class="quote">
|
||||
<strong>From Meta Terms (Section on Content):</strong><br>
|
||||
"If we learn of content or conduct like this, we may take appropriate action based on our assessment that may include - notifying you, offering help, removing content, removing or restricting access to certain features, disabling an account, or contacting law enforcement."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
Notice the word "may"—not "will." Meta gives itself complete discretion about whether to act on harmful content. They're not promising to protect you; they're saying they might, if they feel like it, based on their own assessment.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Service "As Is"</h3>
|
||||
<div class="quote">
|
||||
<strong>From Meta's standard terms language:</strong><br>
|
||||
Meta provides services "as is" without warranties. While not explicitly quoted in public summaries, industry-standard ToS include language stating the platform accepts no liability for service failures, security breaches, or harmful user-generated content.
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
If Facebook's algorithm shows your teen harmful content, if a data breach exposes your information, if their moderation fails to catch harassment—they claim they're not responsible because you agreed to use it "as is."
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 2: "We Own Everything"
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Content License (THE BIG ONE)</h3>
|
||||
<div class="quote">
|
||||
<strong>From reporting on Meta's 2025 ToS:</strong><br>
|
||||
"Though you retain ownership over your content, Meta's broad license to 'use' it creates a gray area... Meta admits to using AI but stops short of specifying how it plans to use our content to develop future AI models."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
Every photo of your kids, every post, every message you send—you've granted Meta a "worldwide, non-exclusive, royalty-free license" to use it. They can:
|
||||
<ul>
|
||||
<li>Train AI models on your family photos</li>
|
||||
<li>Use your content commercially</li>
|
||||
<li>Keep using it even after you delete your account</li>
|
||||
<li>Share it across Meta companies (Facebook, Instagram, WhatsApp)</li>
|
||||
</ul>
|
||||
And they don't have to tell you specifically how they're using it.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>AI Training Rights</h3>
|
||||
<div class="quote">
|
||||
<strong>From analysis of 2025 updates:</strong><br>
|
||||
"The absence of clear disclosures about AI training practices sets a dangerous precedent for big tech. If Facebook doesn't explicitly outline its policies, who will?"
|
||||
</div>
|
||||
<div class="warning">
|
||||
<strong>⚠️ Critical Concern:</strong><br>
|
||||
Meta's 2025 terms expanded AI usage rights without clearly specifying limits. Your creative work, your children's faces, your writing—all potential AI training data with no opt-out.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Private Messages Aren't Private</h3>
|
||||
<div class="quote">
|
||||
<strong>From reporting on the updates:</strong><br>
|
||||
"Meta's new TOS reaches beyond other social media PMs. When you click 'accept' to its updated terms, you will grant Meta the right to read your private messages (nothing new) and use, share, copy, or sell, in whole or in part, in any way it wants, including but not limited to, training..."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
DMs on Facebook, Instagram, and Messenger are not actually private in any meaningful sense. Meta can:
|
||||
<ul>
|
||||
<li>Read them (for "safety" and "optimization")</li>
|
||||
<li>Analyze them for advertising targeting</li>
|
||||
<li>Use them for AI training</li>
|
||||
<li>Access them when "required or permitted by law"</li>
|
||||
</ul>
|
||||
<strong>Only WhatsApp has end-to-end encryption</strong> (where Meta can't read message content—but they still collect metadata about who you message and when).
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 3: "We Can Change Anything"
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Unilateral Changes</h3>
|
||||
<div class="quote">
|
||||
<strong>From Meta Terms:</strong><br>
|
||||
"These Terms (formerly known as the Statement of Rights and Responsibilities) make up the entire agreement between you and Meta Platforms, Inc."<br><br>
|
||||
Terms updates are presented with language like: "These Terms therefore constitute an agreement between you and Meta Platforms, Inc. If you do not agree to these Terms, then do not access or use Facebook..."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
Meta can change the terms anytime. Your only choice is to accept or stop using the platform. "Continued use = acceptance" means:
|
||||
<ul>
|
||||
<li>You might not even know terms changed</li>
|
||||
<li>If you keep using Facebook, you agreed to new terms</li>
|
||||
<li>No real negotiation—take it or leave it</li>
|
||||
<li>Years of content and connections held hostage to new rules</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Account Termination Rights</h3>
|
||||
<div class="quote">
|
||||
<strong>From Meta's enforcement language:</strong><br>
|
||||
"We may take appropriate action... that may include notifying you, offering help, removing content, removing or restricting access to certain features, disabling an account, or contacting law enforcement."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
Meta can disable your account at their discretion. People report:
|
||||
<ul>
|
||||
<li>Accounts disabled with no clear explanation</li>
|
||||
<li>Nearly impossible to reach actual human support</li>
|
||||
<li>Years of photos and memories suddenly inaccessible</li>
|
||||
<li>Scammers offering to "restore" accounts for fees</li>
|
||||
</ul>
|
||||
One user quote: "This already happened to me once because of a scam. I tried to contact support but Meta made it nigh impossible to do anything about it."
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 4: How They Make Money (And What That Means)
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>The Real Business Model</h3>
|
||||
<div class="quote">
|
||||
<strong>From Meta Terms:</strong><br>
|
||||
"Instead of paying to use Facebook and the other products and services we offer, by using the Meta Products covered by these Terms, you agree that we can show you personalized ads and other commercial and sponsored content that businesses and organizations pay us to promote on and off Meta Company Products."
|
||||
</div>
|
||||
<div class="quote">
|
||||
"We use your personal data, such as information about your activity and interests, to show you personalized ads and sponsored content that may be more relevant to you."
|
||||
</div>
|
||||
<div class="quote">
|
||||
"We don't sell your personal data to advertisers, and we don't share information that directly identifies you (such as your name, email address or other contact information) with advertisers unless you give us specific permission."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Actually Means:</strong><br>
|
||||
Meta is being technically truthful but misleading:
|
||||
<ul>
|
||||
<li><strong>They don't "sell" your data</strong> → But they sell ACCESS to you based on your data</li>
|
||||
<li><strong>They don't share your name</strong> → But they share enough to target you precisely</li>
|
||||
<li><strong>"Personalized" ads</strong> → Algorithmic manipulation based on psychological profiling</li>
|
||||
<li><strong>You're not the customer</strong> → Advertisers are. You're the product being sold.</li>
|
||||
</ul>
|
||||
The entire platform is optimized for engagement (keeping you scrolling) to show you more ads. Your wellbeing is not the goal—your attention is.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="score-box">
|
||||
<h3>Meta's User Rights Score</h3>
|
||||
<div style="font-size: 48px; margin: 20px 0;">3/10</div>
|
||||
<p><strong>Summary:</strong> Extensive data collection and usage rights, minimal liability, limited user recourse, one-sided terms that can change anytime. Your content becomes their training data. Your attention is the product they sell.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ROBLOX CONTENT -->
|
||||
<div id="roblox" class="platform-content">
|
||||
<h2>Roblox</h2>
|
||||
<div class="effective-date">
|
||||
📅 <strong>Effective Dates:</strong> June 4, 2025 (Privacy Policy) and September 17, 2025 (Terms of Use)
|
||||
</div>
|
||||
|
||||
<div class="warning">
|
||||
<strong>🎯 Unique Concern:</strong> Roblox is primarily used by children and teenagers, which makes these terms even more significant. Parents are legally responsible for minors' activity on the platform.
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 1: "We're Not Responsible"
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>User-Generated Content Shield</h3>
|
||||
<div class="quote">
|
||||
<strong>From Roblox's model:</strong><br>
|
||||
Roblox provides the platform for user-created "experiences" (games). While they have Community Standards, the terms position Roblox as a platform provider rather than content publisher, limiting liability for what appears in millions of user-created games.
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
When inappropriate content, predatory behavior, or scams appear in Roblox games:
|
||||
<ul>
|
||||
<li>Roblox's position: "Users created it, not us"</li>
|
||||
<li>Moderation is reactive, not proactive</li>
|
||||
<li>Children encounter harmful content before it's reported and removed</li>
|
||||
<li>Platform structure makes comprehensive moderation nearly impossible</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Service Quality Disclaimer</h3>
|
||||
<div class="analysis">
|
||||
<strong>💡 Standard Industry Practice:</strong><br>
|
||||
Like Meta, Roblox's terms include standard "as is" service provisions, meaning:
|
||||
<ul>
|
||||
<li>No guarantee of safety despite child-focused marketing</li>
|
||||
<li>No warranty that moderation will catch predatory behavior</li>
|
||||
<li>Limited liability for security breaches or account compromises</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 2: "We Own Everything" / Data Collection
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Data Collection from Children</h3>
|
||||
<div class="quote">
|
||||
<strong>From Roblox Privacy Policy updates (June 2025):</strong><br>
|
||||
"We have added language to clarify audio features on Roblox."<br>
|
||||
"We have added language to clarify data processing relating to ads on Roblox."<br>
|
||||
"We have added language to clarify how we may collect images or videos for certain features in our Facial Media Capture Privacy Notice."
|
||||
</div>
|
||||
<div class="warning">
|
||||
<strong>⚠️ Translation:</strong><br>
|
||||
Roblox is expanding what data they collect, including:
|
||||
<ul>
|
||||
<li><strong>Audio:</strong> Voice chat data from children</li>
|
||||
<li><strong>Facial images/video:</strong> For "certain features" (avatars, verification?)</li>
|
||||
<li><strong>Advertising data:</strong> Behavioral tracking for targeted ads</li>
|
||||
</ul>
|
||||
This is data about <strong>children</strong> being "clarified" (expanded) in 2025.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Creator Content Rights</h3>
|
||||
<div class="quote">
|
||||
<strong>From Roblox Creator Terms:</strong><br>
|
||||
Creators grant Roblox licenses to use, display, and distribute content they create. While creators can monetize, Roblox takes a significant cut and maintains extensive rights over creator work.
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
<ul>
|
||||
<li>Teen creators grant Roblox broad rights to their creative work</li>
|
||||
<li>Roblox's cut of creator earnings: ~30-75% depending on transaction type</li>
|
||||
<li>Young creators may not understand the terms they're agreeing to</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 3: "You Have No Rights" (Arbitration)</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Mandatory Arbitration & Class Action Waiver</h3>
|
||||
<div class="quote">
|
||||
<strong>From Roblox Terms (ALL CAPS in original):</strong><br>
|
||||
"Specifically, these Roblox Terms contain A BINDING, INDIVIDUAL ARBITRATION AND CLASS ACTION WAIVER. THIS MEANS THAT YOU GIVE UP THE RIGHT TO BRING AN ACTION IN COURT, INDIVIDUALLY OR AS PART OF A CLASS ACTION."
|
||||
</div>
|
||||
<div class="quote">
|
||||
"For U.S. Users, Roblox's Arbitration Agreement (Section 11), which outlines how disputes between you and Roblox will be resolved."
|
||||
</div>
|
||||
<div class="warning">
|
||||
<strong>⚠️ What This Means:</strong><br>
|
||||
<ul>
|
||||
<li>If Roblox harms you, you can't sue in court</li>
|
||||
<li>You can't join with other affected users in a class action</li>
|
||||
<li>Disputes go to private arbitration (which typically favors companies)</li>
|
||||
<li>For a platform used by children, parents are waiving legal rights on their behalf</li>
|
||||
</ul>
|
||||
This is especially concerning given documented safety issues on the platform (Bloomberg reported on predator problems in 2024).
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 4: "We Can Change Anything"
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Terms Can Change Anytime</h3>
|
||||
<div class="quote">
|
||||
<strong>From Roblox Terms:</strong><br>
|
||||
"The Roblox Terms are subject to change. To the extent required by applicable law, Roblox will provide User with reasonable advance notice of any material updates or modifications by any reasonable means of notification, provided that non-material changes, feature updates, or modifications made for legal reasons (as determined by Roblox) will be deemed to be effective immediately and without notice."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 Translation:</strong><br>
|
||||
<ul>
|
||||
<li>Roblox decides what's "material" vs. "non-material"</li>
|
||||
<li>Some changes take effect immediately without notice</li>
|
||||
<li>"Reasonable advance notice" is not defined</li>
|
||||
<li>Continued use = agreement to new terms</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Account Termination</h3>
|
||||
<div class="quote">
|
||||
<strong>From Roblox enforcement updates (2025):</strong><br>
|
||||
"Starting this week, if we detect that a user is using a modified client, we may take action on that account, up to and including account termination."
|
||||
</div>
|
||||
<div class="analysis">
|
||||
<strong>💡 What This Means:</strong><br>
|
||||
Roblox can terminate accounts for violations, including:
|
||||
<ul>
|
||||
<li>Modified clients (exploits/cheating)</li>
|
||||
<li>Community Standards violations</li>
|
||||
<li>Automated detection (can have false positives)</li>
|
||||
</ul>
|
||||
When an account is terminated:
|
||||
<ul>
|
||||
<li>All purchased content is lost (Robux, items, game progress)</li>
|
||||
<li>No refunds for purchases</li>
|
||||
<li>Appeal process exists but not always successful</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Category 5: Parent/Guardian Liability
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Parents Are Legally Responsible</h3>
|
||||
<div class="quote">
|
||||
<strong>From Roblox Terms:</strong><br>
|
||||
"IF YOU ARE UNDER THE LEGAL AGE OF MAJORITY (A 'MINOR') IN YOUR JURISDICTION OR STATE OF RESIDENCE, BEFORE USING THE SERVICES, YOUR PARENT OR LEGAL GUARDIAN MUST READ AND CONSENT TO THE ROBLOX TERMS. BY PERMITTING A MINOR TO USE THE SERVICES, A MINOR'S PARENT OR GUARDIAN BECOMES SUBJECT TO THE ROBLOX TERMS AND AGREES TO BE RESPONSIBLE FOR ALL OF THE MINOR'S ACTIVITIES ON THE SERVICES, INCLUDING THE PURCHASE OF ANY VIRTUAL CONTENT."
|
||||
</div>
|
||||
<div class="warning">
|
||||
<strong>⚠️ Parent Alert:</strong><br>
|
||||
When you let your child play Roblox, YOU are agreeing to:
|
||||
<ul>
|
||||
<li>Be responsible for all their activities</li>
|
||||
<li>Be bound by arbitration agreement</li>
|
||||
<li>Be liable for purchases they make</li>
|
||||
<li>Accept Roblox's data collection practices for your child</li>
|
||||
<li>Waive legal rights on their behalf</li>
|
||||
</ul>
|
||||
Most parents have no idea they're agreeing to this.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🎯 Real-World Safety Concerns
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Documented Platform Issues</h3>
|
||||
<div class="analysis">
|
||||
<strong>Context from reporting:</strong><br>
|
||||
<ul>
|
||||
<li><strong>Bloomberg 2024 investigation:</strong> Documented problems with predators using Roblox to target children</li>
|
||||
<li><strong>Voice chat risks:</strong> Unmoderated voice communication between strangers and children</li>
|
||||
<li><strong>Social engineering:</strong> Scams targeting children through in-game trading and fake giveaways</li>
|
||||
<li><strong>Real money transactions:</strong> Children spending significant real money on virtual currency</li>
|
||||
</ul>
|
||||
Yet the Terms of Service position Roblox as minimally liable for these harms.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="score-box">
|
||||
<h3>Roblox's User Rights Score</h3>
|
||||
<div style="font-size: 48px; margin: 20px 0;">4/10</div>
|
||||
<p><strong>Summary:</strong> Platform used primarily by children with expanding data collection, mandatory arbitration, minimal liability for user-generated content harms, and parents legally responsible without meaningful informed consent.</p>
|
||||
<p><strong>Slight edge over Meta:</strong> More explicit safety efforts, better age verification systems, but fundamental power imbalance remains.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- COMPARISON CONTENT -->
|
||||
<div id="comparison" class="platform-content">
|
||||
<h2>⚖️ Side-by-Side Comparison</h2>
|
||||
|
||||
<table class="comparison-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th>Meta (Facebook)</th>
|
||||
<th>Roblox</th>
|
||||
<th>Winner</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>Liability Protection</strong></td>
|
||||
<td>Extensive disclaimers, "as is" service, minimal responsibility for content harms</td>
|
||||
<td>Platform provider shield, user-generated content defense, limited moderation guarantees</td>
|
||||
<td>🤝 Tie (both terrible)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Content/Data Rights</strong></td>
|
||||
<td>Broad license to use all content, AI training rights, cross-platform sharing, private messages accessible</td>
|
||||
<td>Creator content licenses, expanding child data collection (audio, facial, behavioral)</td>
|
||||
<td>😬 Meta slightly worse (AI training of private messages)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Arbitration Clauses</strong></td>
|
||||
<td>Yes, mandatory arbitration</td>
|
||||
<td>Yes, mandatory arbitration + class action waiver in ALL CAPS</td>
|
||||
<td>🤝 Tie (both eliminate legal recourse)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Term Changes</strong></td>
|
||||
<td>Can change anytime, continued use = acceptance</td>
|
||||
<td>Can change anytime, some changes effective immediately without notice</td>
|
||||
<td>😬 Roblox slightly worse (immediate changes)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Account Termination</strong></td>
|
||||
<td>At discretion, minimal support for appeals, documented customer service issues</td>
|
||||
<td>At discretion, automated detection possible, loss of all purchases without refund</td>
|
||||
<td>😬 Roblox slightly worse (financial loss for kids)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Transparency</strong></td>
|
||||
<td>Unclear AI usage, vague about ad targeting specifics</td>
|
||||
<td>"Clarified" expanded data collection in 2025 updates</td>
|
||||
<td>🤝 Tie (both lack meaningful transparency)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>User Age</strong></td>
|
||||
<td>13+ officially (younger users common)</td>
|
||||
<td>All ages, with parent consent for minors</td>
|
||||
<td>⚠️ Roblox worse (targeting younger users)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Parent Liability</strong></td>
|
||||
<td>Not explicitly stated</td>
|
||||
<td>Parents fully responsible for all minor activities and purchases</td>
|
||||
<td>😬 Roblox worse (explicit parent liability)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="category-header">
|
||||
📊 Overall Assessment
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Common Patterns Across Both Platforms</h3>
|
||||
<div class="key-point">
|
||||
<div class="key-point-icon">🛡️</div>
|
||||
<div><strong>Maximum protection for company:</strong> Extensive disclaimers, limited liability, ability to change terms unilaterally</div>
|
||||
</div>
|
||||
<div class="key-point">
|
||||
<div class="key-point-icon">📝</div>
|
||||
<div><strong>Broad content licenses:</strong> Your creative work becomes their asset for AI training, advertising, and platform development</div>
|
||||
</div>
|
||||
<div class="key-point">
|
||||
<div class="key-point-icon">⚖️</div>
|
||||
<div><strong>Eliminated legal recourse:</strong> Mandatory arbitration and class action waivers prevent collective action</div>
|
||||
</div>
|
||||
<div class="key-point">
|
||||
<div class="key-point-icon">🔄</div>
|
||||
<div><strong>Moving goalposts:</strong> Terms can change anytime; your only choice is accept or leave (losing everything)</div>
|
||||
</div>
|
||||
<div class="key-point">
|
||||
<div class="key-point-icon">👁️</div>
|
||||
<div><strong>Surveillance for profit:</strong> Both collect extensive behavioral data to sell advertising access</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="warning">
|
||||
<h3>⚠️ The Fundamental Problem</h3>
|
||||
<p>These aren't "agreements" between equals. They're:</p>
|
||||
<ul>
|
||||
<li><strong>Adhesion contracts:</strong> Take it or leave it, no negotiation</li>
|
||||
<li><strong>Deliberately incomprehensible:</strong> Written by lawyers for lawyers</li>
|
||||
<li><strong>Designed not to be read:</strong> Thousands of words no one has time for</li>
|
||||
<li><strong>Legally questionable:</strong> Many clauses wouldn't survive real scrutiny, but arbitration prevents that</li>
|
||||
<li><strong>Ethically bankrupt:</strong> Especially for platforms targeting children</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>What Makes These Terms Especially Problematic</h3>
|
||||
|
||||
<h4>For Meta:</h4>
|
||||
<ul>
|
||||
<li>Expanded AI training rights without clear limits or opt-outs</li>
|
||||
<li>Private messages explicitly included in data usage rights</li>
|
||||
<li>"Continued use = consent" applied retroactively to years of existing content</li>
|
||||
<li>Psychological manipulation (engagement optimization) is the business model</li>
|
||||
</ul>
|
||||
|
||||
<h4>For Roblox:</h4>
|
||||
<ul>
|
||||
<li>Platform primarily used by children, but terms written for adults</li>
|
||||
<li>Parents accept liability without informed understanding</li>
|
||||
<li>Expanding data collection (facial, audio) from minors</li>
|
||||
<li>Documented safety issues yet minimal platform liability</li>
|
||||
<li>Real money losses (purchased content) with account termination</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
💭 Discussion Questions for Workshop
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>For Families:</h3>
|
||||
<ol>
|
||||
<li>Did you know you agreed to these terms?</li>
|
||||
<li>Would you have signed up if you'd understood what you were agreeing to?</li>
|
||||
<li>How do you feel about your family photos training AI systems?</li>
|
||||
<li>Is "continued use = consent" really meaningful consent?</li>
|
||||
<li>Should companies be allowed to write one-sided contracts like this?</li>
|
||||
<li>What would fair terms look like?</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>For Teens:</h3>
|
||||
<ol>
|
||||
<li>What's the most surprising thing you learned?</li>
|
||||
<li>Do you trust these platforms more or less now?</li>
|
||||
<li>If you could change one thing about these terms, what would it be?</li>
|
||||
<li>Do you think most of your friends know what they agreed to?</li>
|
||||
<li>Would you still use these platforms knowing all this?</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="category-header">
|
||||
🛠️ What You Can Actually Do
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Short-Term Actions:</h3>
|
||||
<ul>
|
||||
<li><strong>Be aware:</strong> At least now you know what you agreed to</li>
|
||||
<li><strong>Minimize sharing:</strong> Less data shared = less data they can use</li>
|
||||
<li><strong>Review settings:</strong> Use whatever privacy controls exist (limited as they are)</li>
|
||||
<li><strong>Document problems:</strong> Screenshots help with appeals and reporting</li>
|
||||
<li><strong>Educate others:</strong> Share what you learned</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="finding">
|
||||
<h3>Long-Term Advocacy:</h3>
|
||||
<ul>
|
||||
<li><strong>Support regulation:</strong> Terms this one-sided shouldn't be enforceable</li>
|
||||
<li><strong>Demand transparency:</strong> Plain language explanations should be mandatory</li>
|
||||
<li><strong>Consider alternatives:</strong> Fediverse, ATProto, and other platforms have different models</li>
|
||||
<li><strong>Vote with your data:</strong> Delete accounts when platforms cross lines</li>
|
||||
<li><strong>Protect children:</strong> Special regulations needed for platforms targeting minors</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="warning">
|
||||
<h3>Remember:</h3>
|
||||
<p><strong>Just because it's in the Terms of Service doesn't make it legal or enforceable.</strong></p>
|
||||
<ul>
|
||||
<li>Consumer protection laws still apply</li>
|
||||
<li>Special protections exist for minors</li>
|
||||
<li>Some clauses are legally questionable (which is why they prevent you from suing)</li>
|
||||
<li>Public pressure and regulation can force changes</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 50px; padding: 30px; background: #f5f5f5; border-radius: 8px;">
|
||||
<h2>📚 Sources & Further Reading</h2>
|
||||
<ul>
|
||||
<li>Meta Terms of Service (Effective January 1, 2025): facebook.com/terms</li>
|
||||
<li>Roblox Terms of Use (Effective September 17, 2025)</li>
|
||||
<li>Bloomberg's 2024 Roblox investigation</li>
|
||||
<li>Analysis of 2025 Meta ToS updates from tech journalists and legal experts</li>
|
||||
<li>Consumer advocacy organizations (EFF, Common Sense Media, etc.)</li>
|
||||
</ul>
|
||||
|
||||
<p style="margin-top: 20px; font-style: italic;">
|
||||
<strong>Workshop Note:</strong> This analysis is meant for education and critical thinking, not legal advice.
|
||||
Actual Terms of Service are available on each platform's website. Encourage participants to read (or attempt to read) the real documents.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showPlatform(platform) {
|
||||
// Hide all content
|
||||
document.querySelectorAll('.platform-content').forEach(content => {
|
||||
content.classList.remove('active');
|
||||
});
|
||||
document.querySelectorAll('.tab').forEach(tab => {
|
||||
tab.classList.remove('active');
|
||||
});
|
||||
|
||||
// Show selected content
|
||||
document.getElementById(platform).classList.add('active');
|
||||
event.target.closest('.tab').classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user