kirikir13 commited on
Commit
52ec77f
·
verified ·
1 Parent(s): 6414fda

#ADD The ability Python PDF and HTML files as well as.Ininifil as part of the accepted converted to PD ankle gets the the unit if we make it look more like the Star Trek replicator blacks and Blues and hues and yellows I Star Trek theme herediscription i would lie fallowed please: "# Futuristic Drag-and-Drop User Interface Inspired by the Star Trek Replicator: Comprehensive Design and Implementation Report

Browse files

---
(use
using react and gradio hybrid) if possible.
## This detailed worksheet is a comprehensive blueprint for designing a futuristic, visually striking drag-and-drop user interface (GUI) inspired by the Star Trek Replicator, tailored for robust file handling and conversion workflows. The interface supports uploading up to 30 files, merging PDFs, and converting content into Markdown or JSON, all within a modular, extensible, and AI-enhanced GUI optimized for both desktop and mobile platforms.

The design is further elevated by the “pasquotic Jesus gold” aesthetic—a blend of sacred luminosity and high-tech sophistication—while integrating accessibility, security, and performance best practices. Implementation strategies for Python, Java, and Google Apps Script (GAS) are detailed, with recommendations for component libraries, animation frameworks, and AI-assisted features. Thisbased off latest research, design trends, and technical solutions to deliver a professional-grade, immersive sci-fi interface.

---

## 1. Overall UI Concept and User Flows

### 1.1. Star Trek Replicator as Visual Metaphor

The Star Trek Replicator is more than a functional device; it is a metaphor for transformation, immediacy, and user empowerment. In the context of a GUI, the replicator’s central hub and three distinct zones—receiving, uploading, and retrieval—map intuitively onto the stages of file handling:

- **Receiving Zone:** Represents the intake of items (files, packages, or food), visually echoing the anticipation of transformation.
- **Uploading Zone:** Serves as the drop-off area for user-initiated actions, such as dragging files or selecting from a dropdown.
- **Retrieval Zone:** Symbolizes the pickup or output area, where users collect the processed or converted results.

This tri-zonal hub structure fosters clarity, reduces cognitive load, and aligns with the LCARS (Library Computer Access/Retrieval System) interface principles from Star Trek, known for their modularity, color-coded panels, and tactile feedback.

### 1.2. User Flow Overview

The user journey through the interface is streamlined into clear, manageable steps:

1. **File Intake:** Users drag-and-drop up to 30 files or select files via a dropdown menu. Alternatively, up to 10 PDFs can be uploaded for merging.
2. **Processing:** Uploaded files are previewed, validated, and queued for conversion or merging. AI-assisted features may auto-tag, OCR, or suggest optimal conversion settings.
3. **Conversion:** The system merges files into a single PDF or message, then converts the output into Markdown or JSON as per user preference.
4. **Retrieval:** The final output is presented in the retrieval zone, with options to download, copy, or further process the result.

Each stage is visually and interactively demarcated, leveraging animation and microinteractions for feedback and immersion.

---

## 2. Functional Requirements

### 2.1. File Limits and Formats

- **Upload Capacity:** Up to 30 files (any supported format: PDF, DOCX, PPTX, XLSX, images, etc.)
- **PDF Merging:** Accepts up to 10 PDFs for merging into a single document or message.
- **Conversion Outputs:** Supports conversion to PDF, Markdown, or JSON formats.
- **Preview and Validation:** Real-time previews, file type validation, and error handling for unsupported or oversized files.
- **Multi-Source Integration:** Optionally integrates with cloud storage (Google Drive, Dropbox, OneDrive) and third-party APIs for direct file selection.

### 2.2. Conversion Workflows

- **Drag-and-Drop:** Primary interaction for file upload, with fallback to dropdown selection for accessibility.
- **Batch Processing:** Files are processed in parallel where possible, with progress indicators and status feedback.
- **AI-Assisted Conversion:** Incorporates OCR for scanned documents, auto-tagging for metadata, and intelligent format selection based on content analysis.
- **Output Customization:** Users select output format (Markdown or JSON) and can adjust conversion parameters (e.g., page range, image extraction, table formatting).

### 2.3. Error Handling and Feedback

- **Validation:** Checks for file type, size, and format compatibility before processing.
- **Specific Error Messages:** Provides actionable feedback (e.g., “File size exceeds 5MB limit”).
- **Recovery Options:** Allows users to retry failed uploads or adjust settings.

---

## 3. Visual Metaphor and Layout

### 3.1. Central Hub and Three Zones

The interface is anchored by a central hub, visually reminiscent of the Replicator’s control panel, with three clearly defined zones:

- **Receiving Zone:** Animated portal or pad where files are introduced, using glowing effects and subtle motion to evoke anticipation.
- **Uploading Zone:** Interactive drop-off area, highlighted with dynamic borders and LCARS-inspired color panels. Drag-and-drop cues and dropdown selectors are prominent.
- **Retrieval Zone:** Output pad or tray, featuring animated transitions as processed files materialize, with download and copy controls.

This spatial organization supports intuitive navigation and reinforces the metaphor of transformation and retrieval.

### 3.2. Responsive and Modular Design

- **Desktop Layout:** Zones are arranged horizontally or in a triangular configuration, with ample spacing and clear demarcation.
- **Mobile Layout:** Zones stack vertically, with adaptive touch targets and gesture-friendly controls.
- **Modularity:** Each zone is implemented as a reusable component, supporting extensibility and customization.

---

## 4. “Pasquotic Jesus Gold” Aesthetic: Color Palette and Materials

### 4.1. Interpreting the Aesthetic

The phrase “pasquotic Jesus gold” suggests a fusion of sacred luminosity, divine presence, and high-tech elegance. Drawing from biblical symbolism, gold represents purity, divinity, and glory. In tech branding, gold and purple tones evoke luxury, innovation, and spiritual resonance.

### 4.2. Recommended Color Palette

| Color Name | Hex Code | Usage |
|----------------------|------------|------------------------------|
| Satin Sheen Gold | #CAA034 | Primary accent, zone borders |
| American Gold | #D5B036 | Buttons, highlights |
| American Purple | #481D59 | Background, modal overlays |
| Maximum Purple | #6F307C | Secondary accents |
| Deep Peach | #FCCEA0 | Soft backgrounds, gradients |
| Firebrick | #BE2329 | Error states, active cues |

**Palette Analysis:**
The gold tones (#CAA034, #D5B036) serve as luminous accents, framing the central hub and interactive elements. Purples (#481D59, #6F307C) provide depth and contrast, supporting the sci-fi ambiance. Deep Peach (#FCCEA0) softens backgrounds and gradients, while Firebrick (#BE2329) is reserved for error or active states.

### 4.3. Material and Texture

- **Glassmorphism:** Subtle frosted glass overlays, echoing the Replicator’s sleek surfaces and LCARS panels.
- **Metallic Highlights:** Gold and chrome accents on borders and buttons, with animated reflections.
- **Glow Effects:** Soft, radiant glows around active zones and controls, reinforcing the sense of sacred energy.

### 4.4. Accessibility Considerations

- **Contrast Ratios:** All colors and backgrounds meet WCAG 2.2 AA/AAA standards for contrast (minimum 4.5:1 for text, 3:1 for UI components).
- **Color Blindness:** Palette is tested for distinguishability across common color vision deficiencies; icons and patterns supplement color cues.

---

## 5. Iconography and Imagery: LCARS and Replicator Inspiration

### 5.1. LCARS-Inspired Elements

- **Rounded Panels:** Use of pill-shaped, segmented panels with bold color blocks, as seen in LCARS interfaces.
- **Minimalist Icons:** Abstract, geometric icons for upload, merge, convert, and retrieve actions, echoing Star Trek’s visual language.
- **Animated Buttons:** Buttons with subtle pulsing or glowing effects, reminiscent of LCARS touch controls.

### 5.2. Replicator Imagery

- **Portal Animation:** Receiving and retrieval zones feature animated portals or pads, with materialization effects (particles, light rays).
- **Central Hub:** The hub is visually framed by concentric rings or energy fields, suggesting power and transformation.

### 5.3. Icon Library Recommendations

- **Custom SVG Set:** Develop a bespoke icon set in SVG, optimized for scalability and theming.
- **Integration with Existing Libraries:** For rapid prototyping, leverage libraries such as Material Icons (customized for LCARS style), Feather Icons, or Rive for animated icons.

---

## 6. Animation and Microinteractions

### 6.1. Animation Principles

- **Materialization:** Files “appear” in the retrieval zone with particle effects, fade-ins, or morphing transitions.
- **Drag-and-Drop Feedback:** Real-time motion cues, such as glowing borders, ripple effects, and animated drop targets.
- **Progress Indicators:** LCARS-style segmented bars, circular loaders, or animated gradients signal ongoing processing.

### 6.2. Animation Tools and Formats

| Tool/Format | Features | Integration Platforms |
|---------------|--------------------------------------------|------------------------------|
| Lottie | Lightweight JSON-based vector animations | Web, Python, Java, GAS |
| Rive | State-driven, interactive animations | Web, Python, Java, Flutter |
| GSAP | High-performance JS animation library | Web (React, Vue, Svelte) |
| Framer | Design-to-code, interactive prototyping | Web, React |

**Analysis:**
Lottie and Rive are recommended for cross-platform, scalable animations.

Files changed (6) hide show
  1. README.md +8 -5
  2. components/footer.js +118 -0
  3. components/header.js +112 -0
  4. index.html +109 -18
  5. script.js +383 -0
  6. style.css +440 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Trekpdf Replicator
3
- emoji: 🏃
4
- colorFrom: blue
5
- colorTo: blue
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: TrekPDF Replicator 🖖✨
3
+ colorFrom: yellow
4
+ colorTo: purple
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/footer.js ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomFooter extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ :host {
7
+ display: block;
8
+ margin-top: auto;
9
+ }
10
+
11
+ .footer {
12
+ background: linear-gradient(90deg, #0f0f23 0%, #1a1a2e 100%);
13
+ border-top: 1px solid rgba(218, 165, 32, 0.3);
14
+ padding: 2rem 0;
15
+ margin-top: 3rem;
16
+ }
17
+
18
+ .container {
19
+ max-width: 1200px;
20
+ margin: 0 auto;
21
+ padding: 0 1rem;
22
+ }
23
+
24
+ .footer-content {
25
+ display: flex;
26
+ justify-content: space-between;
27
+ align-items: center;
28
+ flex-wrap: wrap;
29
+ }
30
+
31
+ .footer-logo {
32
+ display: flex;
33
+ align-items: center;
34
+ color: #DAA520;
35
+ }
36
+
37
+ .footer-logo i {
38
+ margin-right: 10px;
39
+ color: #5B9BD5;
40
+ }
41
+
42
+ .footer-logo span {
43
+ font-family: 'Orbitron', sans-serif;
44
+ font-size: 1.2rem;
45
+ font-weight: 700;
46
+ }
47
+
48
+ .footer-links {
49
+ display: flex;
50
+ list-style: none;
51
+ }
52
+
53
+ .footer-link {
54
+ margin-left: 1.5rem;
55
+ color: #aaa;
56
+ text-decoration: none;
57
+ transition: color 0.3s;
58
+ }
59
+
60
+ .footer-link:hover {
61
+ color: #DAA520;
62
+ }
63
+
64
+ .copyright {
65
+ width: 100%;
66
+ text-align: center;
67
+ margin-top: 1.5rem;
68
+ color: #777;
69
+ font-size: 0.9rem;
70
+ }
71
+
72
+ @media (max-width: 768px) {
73
+ .footer-content {
74
+ flex-direction: column;
75
+ }
76
+
77
+ .footer-links {
78
+ margin: 1rem 0;
79
+ }
80
+
81
+ .footer-link {
82
+ margin: 0 0.5rem;
83
+ }
84
+ }
85
+ </style>
86
+
87
+ <footer class="footer">
88
+ <div class="container">
89
+ <div class="footer-content">
90
+ <div class="footer-logo">
91
+ <i data-feather="cpu"></i>
92
+ <span>TrekPDF Replicator</span>
93
+ </div>
94
+
95
+ <ul class="footer-links">
96
+ <li><a href="#" class="footer-link">Privacy Policy</a></li>
97
+ <li><a href="#" class="footer-link">Terms of Service</a></li>
98
+ <li><a href="#" class="footer-link">Contact</a></li>
99
+ </ul>
100
+ </div>
101
+
102
+ <div class="copyright">
103
+ &copy; 2023 TrekPDF Replicator. All systems operational. 🖖
104
+ </div>
105
+ </div>
106
+ </footer>
107
+ `;
108
+
109
+ // Initialize Feather Icons after a short delay to ensure DOM is ready
110
+ setTimeout(() => {
111
+ if (typeof feather !== 'undefined') {
112
+ feather.replace();
113
+ }
114
+ }, 100);
115
+ }
116
+ }
117
+
118
+ customElements.define('custom-footer', CustomFooter);
components/header.js ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomHeader extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ :host {
7
+ display: block;
8
+ }
9
+
10
+ .header {
11
+ background: linear-gradient(90deg, #0f0f23 0%, #1a1a2e 100%);
12
+ border-bottom: 1px solid rgba(218, 165, 32, 0.3);
13
+ padding: 1rem 0;
14
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
15
+ }
16
+
17
+ .container {
18
+ max-width: 1200px;
19
+ margin: 0 auto;
20
+ padding: 0 1rem;
21
+ display: flex;
22
+ justify-content: space-between;
23
+ align-items: center;
24
+ }
25
+
26
+ .logo {
27
+ display: flex;
28
+ align-items: center;
29
+ color: #DAA520;
30
+ text-decoration: none;
31
+ }
32
+
33
+ .logo-icon {
34
+ margin-right: 12px;
35
+ color: #5B9BD5;
36
+ }
37
+
38
+ .logo-text {
39
+ font-family: 'Orbitron', sans-serif;
40
+ font-size: 1.8rem;
41
+ font-weight: 700;
42
+ letter-spacing: 2px;
43
+ background: linear-gradient(90deg, #DAA520, #5B9BD5);
44
+ -webkit-background-clip: text;
45
+ -webkit-text-fill-color: transparent;
46
+ }
47
+
48
+ .nav-links {
49
+ display: flex;
50
+ list-style: none;
51
+ }
52
+
53
+ .nav-link {
54
+ margin-left: 2rem;
55
+ color: #aaa;
56
+ text-decoration: none;
57
+ font-family: 'Orbitron', sans-serif;
58
+ font-size: 1rem;
59
+ transition: color 0.3s;
60
+ display: flex;
61
+ align-items: center;
62
+ }
63
+
64
+ .nav-link:hover {
65
+ color: #DAA520;
66
+ }
67
+
68
+ .nav-link i {
69
+ margin-right: 8px;
70
+ }
71
+
72
+ @media (max-width: 768px) {
73
+ .container {
74
+ flex-direction: column;
75
+ }
76
+
77
+ .nav-links {
78
+ margin-top: 1rem;
79
+ }
80
+
81
+ .nav-link {
82
+ margin: 0 1rem;
83
+ }
84
+ }
85
+ </style>
86
+
87
+ <header class="header">
88
+ <div class="container">
89
+ <a href="/" class="logo">
90
+ <i data-feather="cpu" class="logo-icon"></i>
91
+ <span class="logo-text">TrekPDF</span>
92
+ </a>
93
+
94
+ <ul class="nav-links">
95
+ <li><a href="#" class="nav-link"><i data-feather="home"></i> Home</a></li>
96
+ <li><a href="#" class="nav-link"><i data-feather="settings"></i> Settings</a></li>
97
+ <li><a href="#" class="nav-link"><i data-feather="help-circle"></i> Help</a></li>
98
+ </ul>
99
+ </div>
100
+ </header>
101
+ `;
102
+
103
+ // Initialize Feather Icons after a short delay to ensure DOM is ready
104
+ setTimeout(() => {
105
+ if (typeof feather !== 'undefined') {
106
+ feather.replace();
107
+ }
108
+ }, 100);
109
+ }
110
+ }
111
+
112
+ customElements.define('custom-header', CustomHeader);
index.html CHANGED
@@ -1,19 +1,110 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>TrekPDF Replicator</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <link rel="stylesheet" href="style.css">
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script src="https://unpkg.com/feather-icons"></script>
12
+ </head>
13
+ <body class="bg-gray-900 text-white min-h-screen">
14
+ <custom-header></custom-header>
15
+
16
+ <main class="container mx-auto px-4 py-8">
17
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
18
+ <!-- File Upload Section -->
19
+ <div class="bg-gray-800 rounded-xl p-6 border-2 border-lime-500 shadow-lg">
20
+ <h2 class="text-2xl font-bold mb-6 text-lime-400 flex items-center">
21
+ <i data-feather="upload" class="mr-2"></i>Replicator Input Bay
22
+ </h2>
23
+
24
+ <div id="drop-zone" class="border-2 border-dashed border-lime-400 rounded-lg p-8 text-center cursor-pointer hover:bg-gray-700 transition-all">
25
+ <i data-feather="hard-drive" class="w-12 h-12 mx-auto text-lime-400 mb-4"></i>
26
+ <p class="mb-2">Drag & drop files here or click to browse</p>
27
+ <p class="text-sm text-gray-400">Supports: TXT, DOC, DOCX, MD, PNG, JPG, JPEG, GIF, PDF, HTML, PY, INI (up to 30 files)</p>
28
+ </div>
29
+
30
+ <div id="file-list" class="mt-6 max-h-60 overflow-y-auto">
31
+ <!-- Files will be listed here -->
32
+ </div>
33
+
34
+ <div class="mt-6">
35
+ <label class="flex items-center mb-4">
36
+ <input type="checkbox" id="sort-toggle" class="form-checkbox h-5 w-5 text-lime-500">
37
+ <span class="ml-2">Intelligently sort document order</span>
38
+ </label>
39
+
40
+ <button id="process-btn" class="w-full bg-lime-500 hover:bg-lime-600 text-gray-900 font-bold py-3 px-4 rounded-lg transition-all flex items-center justify-center">
41
+ <i data-feather="zap" class="mr-2"></i>Initiate Replication Sequence
42
+ </button>
43
+ </div>
44
+ </div>
45
+
46
+ <!-- PDF Processing Section -->
47
+ <div class="bg-gray-800 rounded-xl p-6 border-2 border-fuchsia-500 shadow-lg">
48
+ <h2 class="text-2xl font-bold mb-6 text-fuchsia-400 flex items-center">
49
+ <i data-feather="file-text" class="mr-2"></i>PDF Decomposition Matrix
50
+ </h2>
51
+
52
+ <div id="pdf-drop-zone" class="border-2 border-dashed border-fuchsia-400 rounded-lg p-8 text-center cursor-pointer hover:bg-gray-700 transition-all">
53
+ <i data-feather="file" class="w-12 h-12 mx-auto text-fuchsia-400 mb-4"></i>
54
+ <p class="mb-2">Drag & drop PDF files here or click to browse</p>
55
+ <p class="text-sm text-gray-400">Convert PDF to MD or JSON format</p>
56
+ </div>
57
+
58
+ <div class="mt-6">
59
+ <label class="block mb-2">Output Format:</label>
60
+ <div class="flex space-x-4 mb-6">
61
+ <label class="flex items-center">
62
+ <input type="radio" name="output-format" value="md" class="form-radio text-fuchsia-500" checked>
63
+ <span class="ml-2">Markdown (.md)</span>
64
+ </label>
65
+ <label class="flex items-center">
66
+ <input type="radio" name="output-format" value="json" class="form-radio text-fuchsia-500">
67
+ <span class="ml-2">JSON (.json)</span>
68
+ </label>
69
+ </div>
70
+
71
+ <button id="pdf-process-btn" class="w-full bg-fuchsia-500 hover:bg-fuchsia-600 text-gray-900 font-bold py-3 px-4 rounded-lg transition-all flex items-center justify-center">
72
+ <i data-feather="cpu" class="mr-2"></i>Activate Decomposition Sequence
73
+ </button>
74
+ </div>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- Transporter Animation Section -->
79
+ <div id="transporter-section" class="mt-12 bg-gray-800 rounded-xl p-6 border-2 border-blue-400 shadow-lg hidden">
80
+ <h2 class="text-2xl font-bold mb-6 text-blue-400 text-center">Transporter Active</h2>
81
+ <div id="transporter-animation" class="flex justify-center items-center h-64">
82
+ <div class="relative">
83
+ <div class="transporter-ring"></div>
84
+ <div class="transporter-core"></div>
85
+ <div class="transporter-beam"></div>
86
+ </div>
87
+ </div>
88
+ <p id="transporter-status" class="text-center mt-4 text-lg">Initializing transport sequence...</p>
89
+ </div>
90
+
91
+ <!-- Completed Files Section -->
92
+ <div id="completed-section" class="mt-12 bg-gray-800 rounded-xl p-6 border-2 border-yellow-400 shadow-lg hidden">
93
+ <h2 class="text-2xl font-bold mb-6 text-yellow-400 flex items-center justify-center">
94
+ <i data-feather="gift" class="mr-2"></i>Replicated Documents
95
+ </h2>
96
+ <div id="completed-files" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
97
+ <!-- Completed files will appear here -->
98
+ </div>
99
+ </div>
100
+ </main>
101
+
102
+ <custom-footer></custom-footer>
103
+
104
+ <script src="components/header.js"></script>
105
+ <script src="components/footer.js"></script>
106
+ <script src="script.js"></script>
107
+ <script>feather.replace();</script>
108
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
109
+ </body>
110
  </html>
script.js ADDED
@@ -0,0 +1,383 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', function() {
2
+ // DOM Elements
3
+ const dropZone = document.getElementById('drop-zone');
4
+ const pdfDropZone = document.getElementById('pdf-drop-zone');
5
+ const fileList = document.getElementById('file-list');
6
+ const processBtn = document.getElementById('process-btn');
7
+ const pdfProcessBtn = document.getElementById('pdf-process-btn');
8
+ const transporterSection = document.getElementById('transporter-section');
9
+ const transporterStatus = document.getElementById('transporter-status');
10
+ const completedSection = document.getElementById('completed-section');
11
+ const completedFiles = document.getElementById('completed-files');
12
+
13
+ // File storage
14
+ let filesToProcess = [];
15
+ let currentPdfFile = null;
16
+
17
+ // Initialize Feather Icons
18
+ feather.replace();
19
+
20
+ // File type icons mapping
21
+ const fileTypeIcons = {
22
+ 'text/plain': 'file-text',
23
+ 'application/msword': 'file-text',
24
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'file-text',
25
+ 'image/png': 'image',
26
+ 'image/jpeg': 'image',
27
+ 'image/gif': 'image',
28
+ 'application/pdf': 'file'
29
+ };
30
+
31
+ // Supported file types
32
+ const supportedTypes = [
33
+ 'text/plain',
34
+ 'application/msword',
35
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
36
+ 'text/markdown',
37
+ 'image/png',
38
+ 'image/jpeg',
39
+ 'image/gif'
40
+ ];
41
+
42
+ // Setup drag and drop for file upload
43
+ setupDragAndDrop(dropZone, handleFiles);
44
+
45
+ // Setup drag and drop for PDF upload
46
+ setupDragAndDrop(pdfDropZone, handlePdfFiles);
47
+
48
+ // Process button event
49
+ processBtn.addEventListener('click', processFiles);
50
+
51
+ // PDF process button event
52
+ pdfProcessBtn.addEventListener('click', processPdfFile);
53
+
54
+ // Setup drag and drop functionality
55
+ function setupDragAndDrop(zone, handler) {
56
+ zone.addEventListener('dragover', (e) => {
57
+ e.preventDefault();
58
+ zone.classList.add('drop-zone-active');
59
+ });
60
+
61
+ zone.addEventListener('dragleave', () => {
62
+ zone.classList.remove('drop-zone-active');
63
+ });
64
+
65
+ zone.addEventListener('drop', (e) => {
66
+ e.preventDefault();
67
+ zone.classList.remove('drop-zone-active');
68
+ const files = e.dataTransfer.files;
69
+ handler(files);
70
+ });
71
+
72
+ zone.addEventListener('click', () => {
73
+ const fileInput = document.createElement('input');
74
+ fileInput.type = 'file';
75
+ fileInput.multiple = true;
76
+ fileInput.accept = supportedTypes.join(',');
77
+
78
+ fileInput.addEventListener('change', (e) => {
79
+ handler(e.target.files);
80
+ });
81
+
82
+ fileInput.click();
83
+ });
84
+ }
85
+
86
+ // Handle file selection for document creation
87
+ function handleFiles(files) {
88
+ for (let i = 0; i < files.length; i++) {
89
+ const file = files[i];
90
+
91
+ // Check if file type is supported
92
+ if (supportedTypes.includes(file.type) && filesToProcess.length < 30) {
93
+ // Check for duplicates
94
+ if (!filesToProcess.some(f => f.name === file.name && f.size === file.size)) {
95
+ filesToProcess.push(file);
96
+ renderFileItem(file);
97
+ }
98
+ } else if (filesToProcess.length >= 30) {
99
+ alert('Maximum of 30 files allowed');
100
+ break;
101
+ }
102
+ }
103
+ }
104
+
105
+ // Handle PDF file selection
106
+ function handlePdfFiles(files) {
107
+ if (files.length > 0) {
108
+ const file = files[0];
109
+ if (file.type === 'application/pdf') {
110
+ currentPdfFile = file;
111
+ pdfDropZone.innerHTML = `
112
+ <i data-feather="file" class="w-12 h-12 mx-auto text-fuchsia-400 mb-4"></i>
113
+ <p class="mb-2">${file.name}</p>
114
+ <p class="text-sm text-gray-400">${(file.size / 1024 / 1024).toFixed(2)} MB</p>
115
+ `;
116
+ feather.replace();
117
+ } else {
118
+ alert('Please select a PDF file');
119
+ }
120
+ }
121
+ }
122
+
123
+ // Render file item in the list
124
+ function renderFileItem(file) {
125
+ const fileItem = document.createElement('div');
126
+ fileItem.className = 'file-item mb-2';
127
+ fileItem.dataset.fileName = file.name;
128
+
129
+ const fileType = file.type.split('/')[1] || 'file';
130
+ const iconType = fileTypeIcons[file.type] || 'file';
131
+
132
+ fileItem.innerHTML = `
133
+ <div class="file-icon bg-lime-500">
134
+ <i data-feather="${iconType}" class="text-gray-900"></i>
135
+ </div>
136
+ <div class="file-info">
137
+ <div class="file-name">${file.name}</div>
138
+ <div class="file-size">${(file.size / 1024).toFixed(1)} KB</div>
139
+ </div>
140
+ <button class="remove-file" data-file-name="${file.name}">
141
+ <i data-feather="x"></i>
142
+ </button>
143
+ `;
144
+
145
+ fileList.appendChild(fileItem);
146
+ feather.replace();
147
+
148
+ // Add remove event
149
+ fileItem.querySelector('.remove-file').addEventListener('click', () => {
150
+ filesToProcess = filesToProcess.filter(f => f.name !== file.name);
151
+ fileItem.remove();
152
+ });
153
+ }
154
+
155
+ // Process files to create PDF
156
+ function processFiles() {
157
+ if (filesToProcess.length === 0) {
158
+ alert('Please add files to process');
159
+ return;
160
+ }
161
+
162
+ // Show transporter animation
163
+ transporterSection.classList.remove('hidden');
164
+ transporterStatus.textContent = 'Initializing transport sequence...';
165
+
166
+ // Simulate processing with transporter animation
167
+ simulateTransporterAnimation(() => {
168
+ // Create a mock PDF file
169
+ const fileName = `replicated_document_${Date.now()}.pdf`;
170
+ const mockPdf = new Blob(['Mock PDF content'], { type: 'application/pdf' });
171
+
172
+ // Add to completed files
173
+ addCompletedFile(fileName, mockPdf, 'PDF Document');
174
+
175
+ // Reset
176
+ filesToProcess = [];
177
+ fileList.innerHTML = '';
178
+ transporterSection.classList.add('hidden');
179
+ });
180
+ }
181
+
182
+ // Process PDF file
183
+ function processPdfFile() {
184
+ if (!currentPdfFile) {
185
+ alert('Please select a PDF file to process');
186
+ return;
187
+ }
188
+
189
+ const format = document.querySelector('input[name="output-format"]:checked').value;
190
+ const fileName = currentPdfFile.name.replace('.pdf', `.${format}`);
191
+
192
+ // Show transporter animation
193
+ transporterSection.classList.remove('hidden');
194
+ transporterStatus.textContent = 'Decomposing document...';
195
+
196
+ // Simulate processing
197
+ simulateTransporterAnimation(() => {
198
+ // Create mock output file
199
+ const content = format === 'md' ? '# Mock Markdown Content' : '{"content": "Mock JSON Content"}';
200
+ const mimeType = format === 'md' ? 'text/markdown' : 'application/json';
201
+ const mockFile = new Blob([content], { type: mimeType });
202
+
203
+ // Add to completed files
204
+ addCompletedFile(fileName, mockFile, `${format.toUpperCase()} Document`);
205
+
206
+ // Reset
207
+ currentPdfFile = null;
208
+ pdfDropZone.innerHTML = `
209
+ <i data-feather="file" class="w-12 h-12 mx-auto text-fuchsia-400 mb-4"></i>
210
+ <p class="mb-2">Drag & drop PDF files here or click to browse</p>
211
+ <p class="text-sm text-gray-400">Convert PDF to MD or JSON format</p>
212
+ `;
213
+ feather.replace();
214
+ transporterSection.classList.add('hidden');
215
+ });
216
+ }
217
+
218
+ // Simulate transporter animation
219
+ function simulateTransporterAnimation(callback) {
220
+ const messages = [
221
+ 'Initializing transport sequence...',
222
+ 'Locking coordinates...',
223
+ 'Energizing pattern buffer...',
224
+ 'Dematerializing subject...',
225
+ 'Transport in progress...',
226
+ 'Rematerializing at destination...',
227
+ 'Transport complete!'
228
+ ];
229
+
230
+ let index = 0;
231
+ const interval = setInterval(() => {
232
+ transporterStatus.textContent = messages[index];
233
+ index++;
234
+
235
+ if (index >= messages.length) {
236
+ clearInterval(interval);
237
+ setTimeout(callback, 500);
238
+ }
239
+ }, 800);
240
+
241
+ // Create sparkle effects
242
+ createSparkles(20);
243
+ }
244
+
245
+ // Create sparkle effects
246
+ function createSparkles(count) {
247
+ const transporterAnimation = document.getElementById('transporter-animation');
248
+ for (let i = 0; i < count; i++) {
249
+ setTimeout(() => {
250
+ const sparkle = document.createElement('div');
251
+ sparkle.className = 'sparkle';
252
+ sparkle.style.left = `${Math.random() * 100}%`;
253
+ sparkle.style.top = `${Math.random() * 100}%`;
254
+ sparkle.style.animation = `sparkle 0.8s ease-out`;
255
+ transporterAnimation.appendChild(sparkle);
256
+
257
+ setTimeout(() => {
258
+ sparkle.remove();
259
+ }, 800);
260
+ }, i * 100);
261
+ }
262
+ }
263
+
264
+ // Add completed file to the display
265
+ function addCompletedFile(fileName, blob, fileType) {
266
+ completedSection.classList.remove('hidden');
267
+
268
+ const fileElement = document.createElement('div');
269
+ fileElement.className = 'completed-file';
270
+ fileElement.innerHTML = `
271
+ <div class="ribbon"></div>
272
+ <div class="mb-4">
273
+ <i data-feather="file" class="w-16 h-16 mx-auto text-yellow-400"></i>
274
+ </div>
275
+ <h3 class="font-bold text-lg mb-2 truncate">${fileName}</h3>
276
+ <p class="text-gray-400 text-sm mb-4">${fileType}</p>
277
+ <div class="flex justify-center space-x-2">
278
+ <button class="download-btn bg-lime-500 hover:bg-lime-600 text-gray-900 py-2 px-4 rounded flex items-center">
279
+ <i data-feather="download" class="mr-1"></i> Save
280
+ </button>
281
+ <button class="open-btn bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded flex items-center">
282
+ <i data-feather="eye" class="mr-1"></i> View
283
+ </button>
284
+ </div>
285
+ `;
286
+
287
+ completedFiles.appendChild(fileElement);
288
+ feather.replace();
289
+
290
+ // Add event listeners
291
+ const downloadBtn = fileElement.querySelector('.download-btn');
292
+ const openBtn = fileElement.querySelector('.open-btn');
293
+
294
+ downloadBtn.addEventListener('click', () => {
295
+ showSaveModal(fileName, blob);
296
+ });
297
+
298
+ openBtn.addEventListener('click', () => {
299
+ const url = URL.createObjectURL(blob);
300
+ window.open(url, '_blank');
301
+ });
302
+ }
303
+
304
+ // Show save modal
305
+ function showSaveModal(fileName, blob) {
306
+ // Create modal overlay
307
+ const overlay = document.createElement('div');
308
+ overlay.className = 'modal-overlay';
309
+ document.body.appendChild(overlay);
310
+
311
+ // Create modal
312
+ const modal = document.createElement('div');
313
+ modal.className = 'save-modal';
314
+ modal.innerHTML = `
315
+ <div class="modal-header">
316
+ <h3>Save Document</h3>
317
+ <button class="close-modal">&times;</button>
318
+ </div>
319
+ <div class="modal-body">
320
+ <div class="form-group">
321
+ <label for="file-name">File Name</label>
322
+ <input type="text" id="file-name" class="form-control" value="${fileName}">
323
+ </div>
324
+ <div class="form-group">
325
+ <label for="save-location">Save Location</label>
326
+ <select id="save-location" class="form-control">
327
+ <option value="downloads">Downloads Folder</option>
328
+ <option value="documents">Documents Folder</option>
329
+ <option value="desktop">Desktop</option>
330
+ </select>
331
+ </div>
332
+ </div>
333
+ <div class="modal-footer">
334
+ <button class="btn btn-secondary cancel-btn">Cancel</button>
335
+ <button class="btn btn-success save-btn">Save Now</button>
336
+ <button class="btn btn-primary consume-btn">Consume Now</button>
337
+ </div>
338
+ `;
339
+
340
+ document.body.appendChild(modal);
341
+
342
+ // Add event listeners
343
+ const closeBtn = modal.querySelector('.close-modal');
344
+ const cancelBtn = modal.querySelector('.cancel-btn');
345
+ const saveBtn = modal.querySelector('.save-btn');
346
+ const consumeBtn = modal.querySelector('.consume-btn');
347
+
348
+ const closeModal = () => {
349
+ overlay.remove();
350
+ modal.remove();
351
+ };
352
+
353
+ closeBtn.addEventListener('click', closeModal);
354
+ cancelBtn.addEventListener('click', closeModal);
355
+ overlay.addEventListener('click', closeModal);
356
+
357
+ saveBtn.addEventListener('click', () => {
358
+ const fileName = document.getElementById('file-name').value;
359
+ saveFile(blob, fileName);
360
+ closeModal();
361
+ });
362
+
363
+ consumeBtn.addEventListener('click', () => {
364
+ const fileName = document.getElementById('file-name').value;
365
+ saveFile(blob, fileName);
366
+ const url = URL.createObjectURL(blob);
367
+ window.open(url, '_blank');
368
+ closeModal();
369
+ });
370
+ }
371
+
372
+ // Save file to user's device
373
+ function saveFile(blob, fileName) {
374
+ const url = URL.createObjectURL(blob);
375
+ const a = document.createElement('a');
376
+ a.href = url;
377
+ a.download = fileName;
378
+ document.body.appendChild(a);
379
+ a.click();
380
+ document.body.removeChild(a);
381
+ URL.revokeObjectURL(url);
382
+ }
383
+ });
style.css CHANGED
@@ -1,28 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
 
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Roboto:wght@300;400;500;700&display=swap');
2
+
3
+ :root {
4
+ --star-trek-gold: #DAA520;
5
+ --star-trek-blue: #5B9BD5;
6
+ --star-trek-red: #C00000;
7
+ --star-trek-gray: #2D2D2D;
8
+ }
9
+
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+
16
  body {
17
+ font-family: 'Roboto', sans-serif;
18
+ background: linear-gradient(135deg, #0a0a1a 0%, #1a1a2e 100%);
19
+ color: #ffffff;
20
+ min-height: 100vh;
21
+ position: relative;
22
+ overflow-x: hidden;
23
+ }
24
+
25
+ body::before {
26
+ content: "";
27
+ position: absolute;
28
+ top: 0;
29
+ left: 0;
30
+ width: 100%;
31
+ height: 100%;
32
+ background:
33
+ radial-gradient(circle at 10% 20%, rgba(92, 107, 192, 0.1) 0%, transparent 20%),
34
+ radial-gradient(circle at 90% 80%, rgba(126, 87, 194, 0.1) 0%, transparent 20%);
35
+ z-index: -1;
36
+ }
37
+
38
+ h1, h2, h3, h4, h5, h6 {
39
+ font-family: 'Orbitron', sans-serif;
40
+ letter-spacing: 1px;
41
+ }
42
+
43
+ .transporter-ring {
44
+ width: 150px;
45
+ height: 150px;
46
+ border: 3px solid var(--star-trek-blue);
47
+ border-radius: 50%;
48
+ position: relative;
49
+ animation: ring-pulse 2s infinite;
50
+ }
51
+
52
+ .transporter-core {
53
+ position: absolute;
54
+ top: 50%;
55
+ left: 50%;
56
+ transform: translate(-50%, -50%);
57
+ width: 40px;
58
+ height: 40px;
59
+ background: var(--star-trek-blue);
60
+ border-radius: 50%;
61
+ box-shadow: 0 0 20px var(--star-trek-blue);
62
+ animation: core-pulse 1.5s infinite;
63
+ }
64
+
65
+ .transporter-beam {
66
+ position: absolute;
67
+ top: 0;
68
+ left: 50%;
69
+ transform: translateX(-50%);
70
+ width: 8px;
71
+ height: 200px;
72
+ background: linear-gradient(to bottom,
73
+ transparent 0%,
74
+ var(--star-trek-blue) 20%,
75
+ var(--star-trek-blue) 80%,
76
+ transparent 100%);
77
+ opacity: 0.7;
78
+ animation: beam-flicker 0.5s infinite;
79
+ }
80
+
81
+ @keyframes ring-pulse {
82
+ 0% {
83
+ transform: scale(0.95);
84
+ box-shadow: 0 0 0 0 rgba(92, 107, 192, 0.7);
85
+ }
86
+ 70% {
87
+ transform: scale(1);
88
+ box-shadow: 0 0 0 20px rgba(92, 107, 192, 0);
89
+ }
90
+ 100% {
91
+ transform: scale(0.95);
92
+ box-shadow: 0 0 0 0 rgba(92, 107, 192, 0);
93
+ }
94
+ }
95
+
96
+ @keyframes core-pulse {
97
+ 0% {
98
+ box-shadow: 0 0 0 0 rgba(92, 107, 192, 0.7);
99
+ }
100
+ 70% {
101
+ box-shadow: 0 0 0 15px rgba(92, 107, 192, 0);
102
+ }
103
+ 100% {
104
+ box-shadow: 0 0 0 0 rgba(92, 107, 192, 0);
105
+ }
106
+ }
107
+
108
+ @keyframes beam-flicker {
109
+ 0%, 100% {
110
+ opacity: 0.7;
111
+ }
112
+ 50% {
113
+ opacity: 0.3;
114
+ }
115
+ }
116
+
117
+ .file-item {
118
+ transition: all 0.3s ease;
119
+ }
120
+
121
+ .file-item:hover {
122
+ transform: translateY(-3px);
123
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
124
+ }
125
+
126
+ .completed-file {
127
+ background: linear-gradient(135deg, #1a2a4a 0%, #2a3a5a 100%);
128
+ border-radius: 12px;
129
+ padding: 20px;
130
+ text-align: center;
131
+ transition: all 0.3s ease;
132
+ position: relative;
133
+ overflow: hidden;
134
+ border: 1px solid rgba(218, 165, 32, 0.3);
135
+ }
136
+
137
+ .completed-file:hover {
138
+ transform: translateY(-5px);
139
+ box-shadow: 0 10px 25px rgba(218, 165, 32, 0.2);
140
+ border-color: rgba(218, 165, 32, 0.6);
141
+ }
142
+
143
+ .completed-file::before {
144
+ content: "";
145
+ position: absolute;
146
+ top: 0;
147
+ left: 0;
148
+ right: 0;
149
+ height: 4px;
150
+ background: linear-gradient(90deg, var(--star-trek-gold), #5B9BD5, var(--star-trek-red));
151
+ }
152
+
153
+ .ribbon {
154
+ position: absolute;
155
+ top: -10px;
156
+ right: -10px;
157
+ width: 80px;
158
+ height: 80px;
159
+ overflow: hidden;
160
+ }
161
+
162
+ .ribbon::before {
163
+ content: "";
164
+ position: absolute;
165
+ width: 15px;
166
+ height: 80px;
167
+ background: var(--star-trek-gold);
168
+ transform: rotate(45deg);
169
+ top: 15px;
170
+ right: -30px;
171
+ box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
172
+ }
173
+
174
+ .drop-zone-active {
175
+ background-color: rgba(59, 130, 246, 0.1);
176
+ border-color: #3b82f6;
177
+ }
178
+
179
+ .file-icon {
180
+ width: 40px;
181
+ height: 40px;
182
+ display: flex;
183
+ align-items: center;
184
+ justify-content: center;
185
+ border-radius: 8px;
186
+ margin-right: 12px;
187
+ }
188
+
189
+ .file-item {
190
+ display: flex;
191
+ align-items: center;
192
+ padding: 12px;
193
+ background: rgba(255, 255, 255, 0.05);
194
+ border-radius: 8px;
195
+ margin-bottom: 8px;
196
+ transition: all 0.2s ease;
197
+ }
198
+
199
+ .file-item:hover {
200
+ background: rgba(255, 255, 255, 0.1);
201
+ }
202
+
203
+ .file-info {
204
+ flex-grow: 1;
205
+ }
206
+
207
+ .file-name {
208
+ font-weight: 500;
209
+ margin-bottom: 4px;
210
+ }
211
+
212
+ .file-size {
213
+ font-size: 0.8rem;
214
+ color: #aaa;
215
+ }
216
+
217
+ .remove-file {
218
+ background: none;
219
+ border: none;
220
+ color: #ff6b6b;
221
+ cursor: pointer;
222
+ padding: 4px;
223
+ border-radius: 4px;
224
+ transition: background 0.2s;
225
+ }
226
+
227
+ .remove-file:hover {
228
+ background: rgba(255, 255, 255, 0.1);
229
+ }
230
+
231
+ .processing-overlay {
232
+ position: fixed;
233
+ top: 0;
234
+ left: 0;
235
+ width: 100%;
236
+ height: 100%;
237
+ background: rgba(0, 0, 0, 0.8);
238
+ display: flex;
239
+ justify-content: center;
240
+ align-items: center;
241
+ z-index: 1000;
242
+ backdrop-filter: blur(5px);
243
+ }
244
+
245
+ .transporter-animation {
246
+ text-align: center;
247
+ padding: 30px;
248
+ background: rgba(30, 30, 60, 0.9);
249
+ border-radius: 20px;
250
+ border: 2px solid var(--star-trek-blue);
251
+ box-shadow: 0 0 30px rgba(92, 107, 192, 0.5);
252
+ }
253
+
254
+ .transporter-animation h3 {
255
+ color: var(--star-trek-blue);
256
+ margin-bottom: 20px;
257
+ font-size: 1.5rem;
258
+ }
259
+
260
+ .transporter-ring-large {
261
+ width: 200px;
262
+ height: 200px;
263
+ margin: 0 auto 20px;
264
+ position: relative;
265
+ }
266
+
267
+ .transporter-core-large {
268
+ position: absolute;
269
+ top: 50%;
270
+ left: 50%;
271
+ transform: translate(-50%, -50%);
272
+ width: 60px;
273
+ height: 60px;
274
+ background: var(--star-trek-blue);
275
+ border-radius: 50%;
276
+ box-shadow: 0 0 30px var(--star-trek-blue);
277
+ }
278
+
279
+ .transporter-beam-large {
280
+ position: absolute;
281
+ top: -50px;
282
+ left: 50%;
283
+ transform: translateX(-50%);
284
+ width: 12px;
285
+ height: 300px;
286
+ background: linear-gradient(to bottom,
287
+ transparent 0%,
288
+ var(--star-trek-blue) 20%,
289
+ var(--star-trek-blue) 80%,
290
+ transparent 100%);
291
+ opacity: 0.7;
292
+ }
293
+
294
+ .status-text {
295
+ font-size: 1.2rem;
296
+ margin-top: 20px;
297
+ color: #ddd;
298
+ }
299
+
300
+ .sparkle {
301
+ position: absolute;
302
+ width: 8px;
303
+ height: 8px;
304
+ background: white;
305
+ border-radius: 50%;
306
+ pointer-events: none;
307
+ opacity: 0;
308
+ }
309
+
310
+ @keyframes sparkle {
311
+ 0% {
312
+ transform: scale(0);
313
+ opacity: 1;
314
+ }
315
+ 50% {
316
+ opacity: 1;
317
+ }
318
+ 100% {
319
+ transform: scale(1.5);
320
+ opacity: 0;
321
+ }
322
+ }
323
+
324
+ .save-modal {
325
+ position: fixed;
326
+ top: 50%;
327
+ left: 50%;
328
+ transform: translate(-50%, -50%);
329
+ background: #1a1a2e;
330
+ border: 2px solid var(--star-trek-gold);
331
+ border-radius: 12px;
332
+ padding: 30px;
333
+ z-index: 1001;
334
+ width: 90%;
335
+ max-width: 500px;
336
+ box-shadow: 0 0 30px rgba(218, 165, 32, 0.3);
337
+ }
338
+
339
+ .modal-overlay {
340
+ position: fixed;
341
+ top: 0;
342
+ left: 0;
343
+ width: 100%;
344
+ height: 100%;
345
+ background: rgba(0, 0, 0, 0.7);
346
+ z-index: 1000;
347
  }
348
 
349
+ .modal-header {
350
+ display: flex;
351
+ justify-content: space-between;
352
+ align-items: center;
353
+ margin-bottom: 20px;
354
+ padding-bottom: 15px;
355
+ border-bottom: 1px solid rgba(218, 165, 32, 0.3);
356
  }
357
 
358
+ .modal-header h3 {
359
+ color: var(--star-trek-gold);
360
+ font-size: 1.4rem;
 
 
361
  }
362
 
363
+ .close-modal {
364
+ background: none;
365
+ border: none;
366
+ color: #aaa;
367
+ font-size: 1.5rem;
368
+ cursor: pointer;
369
+ transition: color 0.2s;
370
  }
371
 
372
+ .close-modal:hover {
373
+ color: #fff;
374
  }
375
+
376
+ .modal-body {
377
+ margin-bottom: 25px;
378
+ }
379
+
380
+ .form-group {
381
+ margin-bottom: 20px;
382
+ }
383
+
384
+ .form-group label {
385
+ display: block;
386
+ margin-bottom: 8px;
387
+ color: #ddd;
388
+ }
389
+
390
+ .form-control {
391
+ width: 100%;
392
+ padding: 12px;
393
+ background: rgba(255, 255, 255, 0.05);
394
+ border: 1px solid #444;
395
+ border-radius: 6px;
396
+ color: #fff;
397
+ font-size: 1rem;
398
+ }
399
+
400
+ .form-control:focus {
401
+ outline: none;
402
+ border-color: var(--star-trek-gold);
403
+ background: rgba(218, 165, 32, 0.1);
404
+ }
405
+
406
+ .modal-footer {
407
+ display: flex;
408
+ justify-content: flex-end;
409
+ gap: 12px;
410
+ }
411
+
412
+ .btn {
413
+ padding: 10px 20px;
414
+ border-radius: 6px;
415
+ font-weight: 500;
416
+ cursor: pointer;
417
+ transition: all 0.2s;
418
+ border: none;
419
+ font-size: 1rem;
420
+ }
421
+
422
+ .btn-primary {
423
+ background: var(--star-trek-gold);
424
+ color: #000;
425
+ }
426
+
427
+ .btn-primary:hover {
428
+ background: #e6b800;
429
+ transform: translateY(-2px);
430
+ }
431
+
432
+ .btn-secondary {
433
+ background: #444;
434
+ color: #fff;
435
+ }
436
+
437
+ .btn-secondary:hover {
438
+ background: #555;
439
+ transform: translateY(-2px);
440
+ }
441
+
442
+ .btn-success {
443
+ background: #28a745;
444
+ color: #fff;
445
+ }
446
+
447
+ .btn-success:hover {
448
+ background: #218838;
449
+ transform: translateY(-2px);
450
+ }