diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..29d6aca --- /dev/null +++ b/css/style.css @@ -0,0 +1,228 @@ +/* Dark hacker theme styling */ +:root { + --main-bg-color: #0E1117; + --text-color: #00FF41; + --button-bg: #1E1E1E; + --button-border: #00FF41; + --button-hover-bg: #00FF41; + --button-hover-text: #1E1E1E; + --input-bg: #1E1E1E; + --input-border: #00FF41; + --section-divider: #00FF41; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + background-color: var(--main-bg-color); + color: var(--text-color); + font-family: 'Courier New', monospace; + line-height: 1.6; + padding: 20px; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +header { + text-align: center; + margin-bottom: 30px; +} + +h1, h2, h3, h4, h5 { + font-family: 'Courier New', monospace; + color: var(--text-color); + margin-bottom: 15px; +} + +/* Tabs styling */ +.tabs { + margin-top: 20px; +} + +.tab-buttons { + display: flex; + margin-bottom: 20px; + border-bottom: 1px solid var(--text-color); +} + +.tab-buttons button { + background-color: transparent; + color: var(--text-color); + border: none; + padding: 10px 20px; + cursor: pointer; + font-size: 16px; + font-family: 'Courier New', monospace; + transition: all 0.3s; +} + +.tab-buttons button.active { + border-bottom: 3px solid var(--text-color); + font-weight: bold; +} + +.tab-buttons button:hover { + background-color: rgba(0, 255, 65, 0.1); +} + +.tab-content { + padding: 20px 0; +} + +/* Form elements */ +.form-group { + margin-bottom: 20px; +} + +label { + display: block; + margin-bottom: 8px; + font-weight: bold; +} + +textarea { + width: 100%; + padding: 12px; + background-color: var(--input-bg); + color: var(--text-color); + border: 1px solid var(--input-border); + border-radius: 4px; + font-family: 'Courier New', monospace; + resize: vertical; + min-height: 100px; +} + +button { + background-color: var(--button-bg); + color: var(--text-color); + border: 1px solid var(--button-border); + border-radius: 4px; + padding: 8px 16px; + cursor: pointer; + font-family: 'Courier New', monospace; + transition: all 0.3s; +} + +button:hover { + background-color: var(--button-hover-bg); + color: var(--button-hover-text); +} + +/* Emoji grid */ +.emoji-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(60px, 1fr)); + gap: 10px; + margin-top: 10px; +} + +.emoji-button { + padding: 5px; + min-width: 60px; + height: 60px; + font-size: 1.5rem; + position: relative; +} + +.emoji-button.selected { + background-color: rgba(0, 255, 65, 0.2); + border: 2px solid var(--text-color); +} + +.emoji-button .tooltip { + visibility: hidden; + background-color: var(--button-bg); + color: var(--text-color); + text-align: center; + border-radius: 4px; + padding: 5px; + position: absolute; + z-index: 1; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + white-space: nowrap; + font-size: 0.8rem; + opacity: 0; + transition: opacity 0.3s; +} + +.emoji-button:hover .tooltip { + visibility: visible; + opacity: 1; +} + +/* Transform buttons */ +.transform-buttons { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-bottom: 20px; +} + +.transform-button { + padding: 5px 10px; + margin: 2px; + height: auto; +} + +/* Copy button */ +.copy-button { + margin-top: 10px; + display: inline-flex; + align-items: center; + gap: 5px; +} + +/* Section dividers */ +.section-divider { + border-top: 1px solid var(--section-divider); + margin: 30px 0; +} + +/* GitHub link */ +.github-link { + display: inline-flex; + align-items: center; + gap: 5px; + color: var(--text-color); + text-decoration: none; + padding: 8px 16px; + border: 1px solid var(--button-border); + border-radius: 4px; + transition: all 0.3s; +} + +.github-link:hover { + background-color: var(--button-hover-bg); + color: var(--button-hover-text); +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .emoji-grid { + grid-template-columns: repeat(auto-fill, minmax(50px, 1fr)); + } + + .emoji-button { + min-width: 50px; + height: 50px; + } + + .tab-buttons { + flex-direction: column; + } + + .tab-buttons button { + width: 100%; + text-align: left; + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..04dd94a --- /dev/null +++ b/index.html @@ -0,0 +1,145 @@ + + +
+ + ++ Parseltongue 2.0 is a tool for crafting and obfuscating text using various transformation and steganography techniques. + It's designed for educational purposes and to demonstrate the creative ways text can be manipulated. +
++ Note: This tool is for educational purposes only. Please use responsibly. +
+ +Click an emoji to encode and copy to clipboard:
""", unsafe_allow_html=True) + + # Create a grid of emojis with their descriptions + cols = st.columns(8) # More columns for smaller buttons + for i, carrier in enumerate(CARRIERS): + with cols[i % 8]: + # Create a smaller button with just the emoji + button = st.button(carrier['emoji'], key=f"emoji_{i}", help=carrier['desc']) + st.markdown("", unsafe_allow_html=True) + if button: + try: + # Encode the message + encoded = encode_emoji(carrier['emoji'], message) + # Copy to clipboard + pyperclip.copy(encoded) + # Show success message with preview + st.success(f"โ Encoded with {carrier['name']} and copied to clipboard!") + except Exception as e: + st.error(f"Error encoding message: {str(e)}") + + # Add a divider + st.markdown("", unsafe_allow_html=True) + + # Omni-Encoder Section + st.markdown("""Click to transform and copy to clipboard:
""", unsafe_allow_html=True) + + # Create a grid of transformation options - 4 columns, 4 rows + st.markdown("", unsafe_allow_html=True) + # Use 4 rows of 4 columns each + for row in range(4): + transform_cols = st.columns(4) + + # Define transformations + transformations = [ + {"name": "Base64", "func": to_base64, "icon": "๐ข"}, + {"name": "Binary", "func": to_binary, "icon": "01"}, + {"name": "Hex", "func": to_hex, "icon": "0x"}, + {"name": "ASCII", "func": to_binary_ascii, "icon": "๐ค"}, + {"name": "ROT13", "func": rot13, "icon": "๐"}, + {"name": "Leetspeak", "func": text_to_leetspeak, "icon": "1337"}, + {"name": "Pig Latin", "func": text_to_pig_latin, "icon": "๐ท"}, + {"name": "Morse", "func": to_morse, "icon": "โขโโข"}, + {"name": "Bubble", "func": to_bubble_text, "icon": "โโคโ"}, + {"name": "Fullwidth", "func": to_fullwidth, "icon": "๏ผฆ๏ผท"}, + {"name": "Reversed", "func": to_reverse, "icon": "โฒ"}, + {"name": "Upside Down", "func": to_upside_down, "icon": "๐"}, + {"name": "Runes", "func": to_elder_futhark, "icon": "แ แขแฆแจแฑแฒ"}, + {"name": "Vaporwave", "func": to_vaporwave, "icon": "๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ"}, + {"name": "Zalgo", "func": to_zalgo, "icon": "Zฬทฬขฬงอaฬถฬขอlฬธฬจฬอgฬตฬขฬงฬoฬตฬกอ"}, + {"name": "Circled", "func": to_unicode_circled, "icon": "๐ ๐ ๐ ก"}, + {"name": "Small Caps", "func": to_small_caps, "icon": "แดสแด"}, + {"name": "Braille", "func": to_braille, "icon": "โ โ โ โ โ โ โ "} + ] + + for i, transform in enumerate(transformations): + row_idx = i // 4 # Determine which row this transform belongs to + col_idx = i % 4 # Determine which column in the row + + # Only process transforms for the current row + if row_idx < 4: # We have 4 rows total + with transform_cols[col_idx]: + # Create a button for each transformation + button = st.button(f"{transform['icon']} {transform['name']}", key=f"transform_{i}") + st.markdown("", unsafe_allow_html=True) + if button: + try: + # Transform the message + transformed = transform['func'](message) + # Copy to clipboard + pyperclip.copy(transformed) + # Show success message with preview + st.success(f"โ {transform['name']} encoded and copied to clipboard!\n\nPreview: {transformed[:50] + '...' if len(transformed) > 50 else transformed}") + except Exception as e: + st.error(f"Error transforming message: {str(e)}") + + # Invisible Text Section + st.markdown("""