mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-07-20 19:11:13 +02:00
more stylesheet/ui standardization
This commit is contained in:
+5
-3
@@ -69,9 +69,11 @@ P4RS3LT0NGV3/
|
||||
├── tests/ # Test suites
|
||||
│ ├── test_universal.js
|
||||
│ └── test_steganography_options.js
|
||||
├── css/ # Stylesheets
|
||||
│ ├── style.css
|
||||
│ └── notification.css
|
||||
├── css/ # Stylesheets (edit *.css, then npm run build:css)
|
||||
│ ├── style.css # Source (readable)
|
||||
│ ├── style.min.css # Generated; linked from HTML
|
||||
│ ├── notification.css
|
||||
│ └── notification.min.css
|
||||
├── index.template.html # Base HTML template (templates injected here)
|
||||
├── index.html # Generated file (created by build process)
|
||||
└── docs/ # Documentation
|
||||
|
||||
+246
-404
@@ -22,6 +22,9 @@
|
||||
--input-border: #404040;
|
||||
--section-divider: #404040;
|
||||
--focus-shadow: 0 0 0 2px rgba(100, 181, 246, 0.4);
|
||||
--panel-shadow-soft: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
--sidebar-edge-shadow: -5px 0 15px rgba(0, 0, 0, 0.3);
|
||||
--sidebar-width: 420px;
|
||||
|
||||
/* Transform category colors */
|
||||
--encoding-color: #7e57c2; /* Purple for encoding/decoding */
|
||||
@@ -317,6 +320,84 @@ body {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
/* Spacing utilities (tool templates) */
|
||||
.u-mb-8 { margin-bottom: 8px; }
|
||||
.u-mb-16 { margin-bottom: 16px; }
|
||||
.u-mt-16 { margin-top: 16px; }
|
||||
|
||||
/* Textarea + absolutely positioned .copy-button */
|
||||
.textarea-copy-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Tokenizer token grid */
|
||||
.token-tiles.tokenizer-tiles {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.token-chip.token-chip--tokenizer {
|
||||
background: var(--button-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
padding: 6px 8px;
|
||||
border-radius: 6px;
|
||||
font-family: 'Fira Code', monospace;
|
||||
}
|
||||
|
||||
.token-chip__idx {
|
||||
opacity: 0.75;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.token-chip__id {
|
||||
opacity: 0.6;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
/* Fuzzer case list */
|
||||
.fuzzer-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.fuzzer-case-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.fuzzer-case-index {
|
||||
opacity: 0.7;
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
.fuzzer-case-textarea {
|
||||
flex: 1;
|
||||
min-height: 46px;
|
||||
}
|
||||
|
||||
/* Decoder: method select beside label (override full-width select defaults) */
|
||||
select.decoder-method-select {
|
||||
margin-left: 15px;
|
||||
padding: 5px 10px;
|
||||
border-radius: 6px;
|
||||
width: auto;
|
||||
max-width: min(100%, 320px);
|
||||
}
|
||||
|
||||
/* Tokenade text payload block label */
|
||||
.tokenade-field-label {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.tokenade-field-label input[type="text"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* Button variants */
|
||||
.btn-secondary {
|
||||
@@ -745,8 +826,8 @@ body.dark-theme .mobile-tool-dropdown {
|
||||
.output-container {
|
||||
position: relative;
|
||||
}
|
||||
.fuzzer-list .token-chip { position: relative; }
|
||||
.fuzzer-list .token-chip .copy-button { position: static; }
|
||||
.fuzzer-list .fuzzer-case-row { position: relative; }
|
||||
.fuzzer-list .fuzzer-case-row .copy-button { position: static; }
|
||||
|
||||
.section-header {
|
||||
margin-bottom: 15px;
|
||||
@@ -1320,8 +1401,11 @@ body.dark-theme .mobile-tool-dropdown {
|
||||
|
||||
/* Transform layout */
|
||||
.transform-layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
margin-top: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.transform-section {
|
||||
@@ -1456,7 +1540,7 @@ body.dark-theme .mobile-tool-dropdown {
|
||||
background: var(--secondary-bg);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: var(--panel-shadow-soft);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
border-left: none;
|
||||
@@ -1537,7 +1621,9 @@ body.dark-theme .mobile-tool-dropdown {
|
||||
border-left-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.last-used-section .transform-buttons .transform-button-group {
|
||||
.last-used-section .transform-buttons .transform-button-group,
|
||||
#category-randomizer .transform-buttons .transform-button-group,
|
||||
.favorites-section .transform-buttons .transform-button-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -1854,10 +1940,6 @@ button.translate-custom-label-btn:hover .translate-custom-toggle-end {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#category-randomizer .transform-buttons .transform-button-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#category-randomizer .transform-buttons .transform-button {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -1945,111 +2027,37 @@ button.translate-custom-label-btn:hover .translate-custom-toggle-end {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* Copy History Panel */
|
||||
.copy-history-panel {
|
||||
/* Slide-out sidebars — one width on desktop; full width on small screens (see 768px media) */
|
||||
.app-sidebar {
|
||||
position: fixed;
|
||||
right: -100%;
|
||||
top: 0;
|
||||
width: 380px;
|
||||
right: 0;
|
||||
width: var(--sidebar-width);
|
||||
max-width: min(100%, 90vw);
|
||||
height: 100vh;
|
||||
background-color: var(--secondary-bg);
|
||||
border-left: 1px solid var(--input-border);
|
||||
z-index: 100;
|
||||
box-shadow: -5px 0 15px rgba(0, 0, 0, 0.3);
|
||||
transition: right 0.3s ease-in-out;
|
||||
box-shadow: var(--sidebar-edge-shadow);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.copy-history-panel.active {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.copy-history-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
background-color: var(--button-bg);
|
||||
}
|
||||
|
||||
.copy-history-header h3 {
|
||||
font-size: 1.2rem;
|
||||
margin: 0;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.copy-history-header .header-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.copy-history-header .clear-history-button,
|
||||
.copy-history-header .close-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
font-size: 1.2rem;
|
||||
padding: 5px;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.copy-history-header .clear-history-button:hover,
|
||||
.copy-history-header .close-button:hover {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.copy-history-header .clear-history-button:hover {
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
.copy-history-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
/* Glitch Token Panel & End Sequences sidebar */
|
||||
.glitch-token-panel,
|
||||
.end-sequence-panel {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 420px;
|
||||
max-width: 90vw;
|
||||
height: 100vh;
|
||||
background-color: var(--secondary-bg);
|
||||
border-left: 1px solid var(--input-border);
|
||||
z-index: 100;
|
||||
box-shadow: -5px 0 15px rgba(0, 0, 0, 0.3);
|
||||
transform: translateX(100%);
|
||||
transition: transform 0.3s ease-in-out;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.glitch-token-panel.active,
|
||||
.end-sequence-panel.active {
|
||||
.app-sidebar.active {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.glitch-token-panel,
|
||||
.end-sequence-panel {
|
||||
width: 94vw;
|
||||
max-width: 94vw;
|
||||
}
|
||||
/* Advanced settings above other slide-outs when stacked */
|
||||
.unicode-options-panel {
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.glitch-token-header,
|
||||
.end-sequence-header {
|
||||
/* Sidebar header + actions (copy history, glitch, end sequences, advanced settings) */
|
||||
.app-sidebar-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -2058,25 +2066,35 @@ button.translate-custom-label-btn:hover .translate-custom-toggle-end {
|
||||
background-color: var(--button-bg);
|
||||
}
|
||||
|
||||
.glitch-token-header h3 {
|
||||
.app-sidebar-header h3 {
|
||||
font-size: 1.2rem;
|
||||
margin: 0;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.end-sequence-header h3 {
|
||||
font-size: 1.2rem;
|
||||
margin: 0;
|
||||
color: #e85d4c;
|
||||
}
|
||||
|
||||
.glitch-token-header .header-actions {
|
||||
.unicode-panel-header {
|
||||
position: relative;
|
||||
z-index: 300;
|
||||
pointer-events: auto;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
.unicode-panel-header h3 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.app-sidebar-header .header-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.glitch-token-header .close-button {
|
||||
.app-sidebar-header .clear-history-button,
|
||||
.app-sidebar-header .close-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
@@ -2086,19 +2104,28 @@ button.translate-custom-label-btn:hover .translate-custom-toggle-end {
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.glitch-token-header .close-button:hover {
|
||||
.app-sidebar-header .clear-history-button:hover,
|
||||
.app-sidebar-header .close-button:hover {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.app-sidebar-header .clear-history-button:hover {
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
.end-sequence-header .close-button:hover {
|
||||
color: #e85d4c;
|
||||
}
|
||||
|
||||
.glitch-token-content,
|
||||
.end-sequence-content {
|
||||
/* Scrollable body */
|
||||
.app-sidebar-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.glitch-token-content,
|
||||
.end-sequence-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -3009,11 +3036,13 @@ body.transform-options-modal-open {
|
||||
|
||||
.transform-options-number {
|
||||
-moz-appearance: textfield;
|
||||
appearance: textfield;
|
||||
}
|
||||
|
||||
.transform-options-number::-webkit-outer-spin-button,
|
||||
.transform-options-number::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -3065,10 +3094,6 @@ body.transform-options-modal-open {
|
||||
border-left-color: #ffd700;
|
||||
}
|
||||
|
||||
.favorites-section .transform-buttons .transform-button-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Output section */
|
||||
.output-section {
|
||||
display: flex;
|
||||
@@ -3406,50 +3431,18 @@ body.transform-options-modal-open {
|
||||
}
|
||||
|
||||
|
||||
/* Global Unicode options panel (subtle, like copy history) */
|
||||
.unicode-options-panel {
|
||||
position: fixed;
|
||||
right: -360px;
|
||||
top: 0;
|
||||
width: 340px;
|
||||
height: 100vh;
|
||||
background: var(--secondary-bg);
|
||||
border-left: 1px solid var(--input-border);
|
||||
z-index: 200;
|
||||
box-shadow: -5px 0 15px rgba(0,0,0,0.3);
|
||||
transition: right 0.3s ease-in-out;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.unicode-options-panel.active { right: 0; }
|
||||
|
||||
.unicode-panel-header {
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
/* Unicode / Advanced Settings: shell + header close (touch-friendly) */
|
||||
.unicode-panel-header .close-button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
z-index: 300;
|
||||
pointer-events: auto;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
.unicode-panel-header h3 { margin: 0; color: var(--accent-color); font-size: 1rem; }
|
||||
|
||||
.unicode-panel-content { padding: 12px; overflow-y: auto; }
|
||||
.unicode-panel-header .close-button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: center;
|
||||
font-size: 1.2rem;
|
||||
transition: all 0.2s ease;
|
||||
border-radius: 4px;
|
||||
@@ -3805,10 +3798,6 @@ html {
|
||||
/* Reduce extra whitespace at bottom of tab cards */
|
||||
.tab-content .transform-layout > *:last-child { margin-bottom: 0; }
|
||||
|
||||
.transform-layout {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Keep the transform input visible while scrolling */
|
||||
.transform-layout .input-section {
|
||||
position: sticky;
|
||||
@@ -3819,16 +3808,8 @@ html {
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
/* Mutation Lab actions */
|
||||
.mutation-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 10px 0 12px 0; }
|
||||
.mutation-actions .action-button, .mutation-actions .transform-button { white-space: nowrap; }
|
||||
.mutation-actions .action-button.copy { border-color: #1976d2; color: #90caf9; }
|
||||
.mutation-actions .action-button.copy:hover { color: #bbdefb; box-shadow: 0 0 0 1px rgba(144,202,249,.2) inset, 0 0 14px rgba(144,202,249,.18); }
|
||||
.mutation-actions .action-button.download { border-color: #2e7d32; color: #69f0ae; }
|
||||
.mutation-actions .action-button.download:hover { color: #b9f6ca; box-shadow: 0 0 0 1px rgba(105,240,174,.2) inset, 0 0 14px rgba(105,240,174,.18); }
|
||||
|
||||
/* Toolbar rows without .mutation-actions (Gibberish, Tokenade generate rows) */
|
||||
.token-bomb-actions {
|
||||
/* Tool action toolbar — primary generate / copy / download rows */
|
||||
.tool-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
@@ -3836,10 +3817,34 @@ html {
|
||||
margin: 10px 0 12px 0;
|
||||
}
|
||||
|
||||
/* Primary “generate” actions — not transform-grid category tiles (add .tool-primary-btn) */
|
||||
.mutation-actions .transform-button.tool-primary-btn,
|
||||
.token-bomb-actions .transform-button.tool-primary-btn,
|
||||
.splitter-actions .transform-button.tool-primary-btn {
|
||||
.tool-toolbar .action-button,
|
||||
.tool-toolbar .transform-button {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tool-toolbar .action-button.copy {
|
||||
border-color: #1976d2;
|
||||
color: #90caf9;
|
||||
}
|
||||
|
||||
.tool-toolbar .action-button.copy:hover {
|
||||
color: #bbdefb;
|
||||
box-shadow: 0 0 0 1px rgba(144,202,249,.2) inset, 0 0 14px rgba(144,202,249,.18);
|
||||
}
|
||||
|
||||
.tool-toolbar .action-button.download {
|
||||
border-color: #2e7d32;
|
||||
color: #69f0ae;
|
||||
}
|
||||
|
||||
.tool-toolbar .action-button.download:hover {
|
||||
color: #b9f6ca;
|
||||
box-shadow: 0 0 0 1px rgba(105,240,174,.2) inset, 0 0 14px rgba(105,240,174,.18);
|
||||
}
|
||||
|
||||
/* Primary “generate” actions — not transform-grid category tiles */
|
||||
.tool-toolbar .transform-button.tool-primary-btn {
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -3849,36 +3854,22 @@ html {
|
||||
height: auto;
|
||||
padding: 10px 20px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.mutation-actions .transform-button.tool-primary-btn:before,
|
||||
.mutation-actions .transform-button.tool-primary-btn:after,
|
||||
.token-bomb-actions .transform-button.tool-primary-btn:before,
|
||||
.token-bomb-actions .transform-button.tool-primary-btn:after,
|
||||
.splitter-actions .transform-button.tool-primary-btn:before,
|
||||
.splitter-actions .transform-button.tool-primary-btn:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mutation-actions .transform-button.tool-primary-btn,
|
||||
.token-bomb-actions .transform-button.tool-primary-btn,
|
||||
.splitter-actions .transform-button.tool-primary-btn {
|
||||
flex: 1;
|
||||
background: linear-gradient(135deg, var(--accent-color), #42a5f5);
|
||||
color: var(--main-bg-color);
|
||||
border: 1px solid var(--accent-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mutation-actions .transform-button.tool-primary-btn i,
|
||||
.token-bomb-actions .transform-button.tool-primary-btn i,
|
||||
.splitter-actions .transform-button.tool-primary-btn i {
|
||||
.tool-toolbar .transform-button.tool-primary-btn:before,
|
||||
.tool-toolbar .transform-button.tool-primary-btn:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-toolbar .transform-button.tool-primary-btn i {
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.mutation-actions .transform-button.tool-primary-btn:hover:not(:disabled),
|
||||
.token-bomb-actions .transform-button.tool-primary-btn:hover:not(:disabled),
|
||||
.splitter-actions .transform-button.tool-primary-btn:hover:not(:disabled) {
|
||||
.tool-toolbar .transform-button.tool-primary-btn:hover:not(:disabled) {
|
||||
background: linear-gradient(135deg, var(--accent-color), #42a5f5);
|
||||
border-color: var(--accent-color);
|
||||
color: var(--main-bg-color);
|
||||
@@ -3887,24 +3878,26 @@ html {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.mutation-actions .transform-button.tool-primary-btn:disabled,
|
||||
.token-bomb-actions .transform-button.tool-primary-btn:disabled,
|
||||
.splitter-actions .transform-button.tool-primary-btn:disabled {
|
||||
.tool-toolbar .transform-button.tool-primary-btn:disabled {
|
||||
opacity: 0.65;
|
||||
cursor: wait;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
/* Bijection — card + toolbar aligned with PromptCraft / Anti-Classifier */
|
||||
.bijection-section.transform-section {
|
||||
/* Bijection / PromptCraft / Anti-Classifier — shared card shell + section chrome */
|
||||
.bijection-section.transform-section,
|
||||
.promptcraft-section.transform-section,
|
||||
.anticlassifier-section.transform-section {
|
||||
background: var(--secondary-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: var(--panel-shadow-soft);
|
||||
}
|
||||
|
||||
.bijection-section .section-header h3 {
|
||||
.bijection-section .section-header h3,
|
||||
.promptcraft-section .section-header h3,
|
||||
.anticlassifier-section .section-header h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
@@ -3914,7 +3907,9 @@ html {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.bijection-section .section-header h3 small {
|
||||
.bijection-section .section-header h3 small,
|
||||
.promptcraft-section .section-header h3 small,
|
||||
.anticlassifier-section .section-header h3 small {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-muted);
|
||||
@@ -3924,6 +3919,19 @@ html {
|
||||
background: var(--main-bg-color);
|
||||
}
|
||||
|
||||
.bijection-section .input-section,
|
||||
.promptcraft-section .input-section,
|
||||
.anticlassifier-section .input-section {
|
||||
position: static;
|
||||
top: auto;
|
||||
z-index: auto;
|
||||
background: var(--main-bg-color);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 6px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.bijection-section .bj-lede {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-muted);
|
||||
@@ -3938,17 +3946,6 @@ html {
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.bijection-section .input-section {
|
||||
position: static;
|
||||
top: auto;
|
||||
z-index: auto;
|
||||
background: var(--main-bg-color);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 6px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.bijection-section .bij-options.options-grid {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
@@ -4032,7 +4029,8 @@ html {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.bijection-section .bj-result-card {
|
||||
.bijection-section .bj-result-card,
|
||||
.pc-result-card {
|
||||
background: var(--main-bg-color);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 6px;
|
||||
@@ -4049,7 +4047,8 @@ html {
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
}
|
||||
|
||||
.bijection-section .bj-result-num {
|
||||
.bijection-section .bj-result-num,
|
||||
.pc-result-num {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--accent-color);
|
||||
@@ -4100,86 +4099,6 @@ html {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* PromptCraft — align with tab / transform chip styling */
|
||||
.promptcraft-section.transform-section {
|
||||
background: var(--secondary-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.promptcraft-section .section-header h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 4px;
|
||||
border-left: 4px solid var(--accent-color);
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.promptcraft-section .section-header h3 small {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-muted);
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--input-border);
|
||||
background: var(--main-bg-color);
|
||||
}
|
||||
|
||||
.promptcraft-section .input-section {
|
||||
position: static;
|
||||
top: auto;
|
||||
z-index: auto;
|
||||
background: var(--main-bg-color);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 6px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Anti-Classifier — same card treatment as PromptCraft */
|
||||
.anticlassifier-section.transform-section {
|
||||
background: var(--secondary-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.anticlassifier-section .section-header h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 4px;
|
||||
border-left: 4px solid var(--accent-color);
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.anticlassifier-section .section-header h3 small {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-muted);
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--input-border);
|
||||
background: var(--main-bg-color);
|
||||
}
|
||||
|
||||
.anticlassifier-section .input-section {
|
||||
position: static;
|
||||
top: auto;
|
||||
z-index: auto;
|
||||
background: var(--main-bg-color);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 6px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.pc-controls {
|
||||
margin-top: 4px;
|
||||
}
|
||||
@@ -4283,13 +4202,6 @@ html {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.pc-result-card {
|
||||
background: var(--main-bg-color);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.pc-result-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -4299,13 +4211,6 @@ html {
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
}
|
||||
|
||||
.pc-result-num {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--accent-color);
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.pc-result-text {
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
@@ -4345,43 +4250,8 @@ html {
|
||||
}
|
||||
}
|
||||
|
||||
/* Message Splitter Styles */
|
||||
.encapsulation-section {
|
||||
margin-top: 16px;
|
||||
padding: 16px;
|
||||
background: var(--main-bg-color);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.encapsulation-section .section-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.encapsulation-section .section-header h4 {
|
||||
margin-bottom: 4px;
|
||||
margin-top: 0;
|
||||
color: var(--accent-color);
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.encapsulation-section .section-header p {
|
||||
margin: 0;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.encapsulation-presets {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* JSON/XML Fields Section */
|
||||
/* Message Splitter — encapsulation + JSON/XML field panels share chrome */
|
||||
.encapsulation-section,
|
||||
.json-fields-section,
|
||||
.xml-attributes-section {
|
||||
margin-top: 16px;
|
||||
@@ -4391,11 +4261,13 @@ html {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.encapsulation-section .section-header,
|
||||
.json-fields-section .section-header,
|
||||
.xml-attributes-section .section-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.encapsulation-section .section-header h4,
|
||||
.json-fields-section .section-header h4,
|
||||
.xml-attributes-section .section-header h4 {
|
||||
margin-bottom: 4px;
|
||||
@@ -4407,6 +4279,7 @@ html {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.encapsulation-section .section-header p,
|
||||
.json-fields-section .section-header p,
|
||||
.xml-attributes-section .section-header p {
|
||||
margin: 0;
|
||||
@@ -4414,6 +4287,13 @@ html {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.encapsulation-presets {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
@@ -4462,8 +4342,6 @@ html {
|
||||
}
|
||||
|
||||
.add-field-button {
|
||||
margin-top: 8px;
|
||||
}
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
@@ -4780,15 +4658,6 @@ html {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Splitter-specific action button styling */
|
||||
.splitter-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 16px 0 12px 0;
|
||||
}
|
||||
|
||||
.splitter-copy-option {
|
||||
margin-left: 0;
|
||||
}
|
||||
@@ -4948,12 +4817,14 @@ html {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.splitter-actions {
|
||||
.tool-toolbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.splitter-actions button {
|
||||
|
||||
.tool-toolbar button,
|
||||
.tool-toolbar .switch {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -4968,10 +4839,28 @@ html {
|
||||
max-width: calc(50% - 4px);
|
||||
}
|
||||
|
||||
/* Translation (AI) language tiles: 2 columns on phones/tablets (grid is more reliable than flex here) */
|
||||
.translate-lang-grid.translate-lang-grid-inline {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.translate-lang-grid-inline .translate-lang-btn {
|
||||
flex: 0 0 calc(50% - 4px) !important;
|
||||
flex: none;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-width: calc(50% - 4px);
|
||||
max-width: none;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.app-sidebar {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.unicode-options-panel {
|
||||
z-index: 300;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5033,11 +4922,7 @@ html {
|
||||
max-width: calc(50% - 2px);
|
||||
}
|
||||
|
||||
.translate-lang-grid-inline .translate-lang-btn {
|
||||
flex: 0 0 calc(50% - 2px) !important;
|
||||
min-width: 0;
|
||||
max-width: calc(50% - 2px);
|
||||
}
|
||||
/* Translation tiles: same 2-col grid as 768px (inherit from above) */
|
||||
|
||||
/* Options grid single column on very small screens */
|
||||
.options-grid {
|
||||
@@ -5052,17 +4937,6 @@ html {
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
/* Unicode options panel full width */
|
||||
.unicode-options-panel {
|
||||
width: 100%;
|
||||
right: -100%;
|
||||
z-index: 300; /* Ensure it's above other content on mobile */
|
||||
}
|
||||
|
||||
.unicode-options-panel.active {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.unicode-panel-header .close-button {
|
||||
min-width: 48px;
|
||||
min-height: 48px;
|
||||
@@ -5125,28 +4999,6 @@ html {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* Mutation actions stack */
|
||||
.mutation-actions {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.mutation-actions button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Splitter actions stack */
|
||||
.splitter-actions {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.splitter-actions button,
|
||||
.splitter-actions .switch {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Transform button preview text */
|
||||
.transform-preview {
|
||||
font-size: 0.7rem;
|
||||
@@ -5256,16 +5108,6 @@ html {
|
||||
padding: 3px var(--spacing-xs);
|
||||
}
|
||||
|
||||
/* Copy history panel full width */
|
||||
.copy-history-panel {
|
||||
width: 100%;
|
||||
right: -100%;
|
||||
}
|
||||
|
||||
.copy-history-panel.active {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/* Transform chain items stack vertically */
|
||||
.transform-chain-item select {
|
||||
min-width: 100%;
|
||||
|
||||
+47
-2
@@ -59,8 +59,20 @@ class MyTool extends Tool {
|
||||
```html
|
||||
<div v-if="activeTab === 'mytool'" class="tab-content">
|
||||
<div class="transform-layout">
|
||||
<textarea v-model="myInput" @input="processInput"></textarea>
|
||||
<div v-if="myOutput">{{ myOutput }}</div>
|
||||
<div class="transform-section">
|
||||
<div class="section-header">
|
||||
<h3><i class="fas fa-star"></i> My Tool <small>short subtitle</small></h3>
|
||||
</div>
|
||||
<div class="input-section">
|
||||
<textarea v-model="myInput" @input="processInput"></textarea>
|
||||
</div>
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="processInput">
|
||||
<i class="fas fa-bolt"></i> Run
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="myOutput" class="output-container">{{ myOutput }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -78,3 +90,36 @@ npm run build:templates # Injects template into index.html
|
||||
2. **Build**: `inject-tool-templates.js` reads templates and injects into `index.template.html`
|
||||
3. **Output**: Complete `index.html` with all templates embedded
|
||||
4. **Browser**: Vue compiles templates at page load (already in DOM)
|
||||
|
||||
## Tool UI classes (CSS)
|
||||
|
||||
Use the shared vocabulary in [`css/style.css`](../css/style.css) (see the “STANDARD UI COMPONENT TEMPLATES” comment block at the top) so new tools match existing ones.
|
||||
|
||||
| Role | Class | Notes |
|
||||
|------|--------|--------|
|
||||
| Tool root | `tab-content` | Root `v-if` wrapper for each tool |
|
||||
| Column layout | `transform-layout` | Flex column with vertical `gap`; `position: relative` for sticky input |
|
||||
| Card / panel | `transform-section` | Optional tool-specific modifier (e.g. `bijection-section`) for one-off tweaks |
|
||||
| Page title | `section-header` | Icon + `h3` + optional `<small>` subtitle |
|
||||
| Intro with long description | `section-header-card` | Use when you need a paragraph under the title (see Gibberish / Splitter) |
|
||||
| **Action row** | **`tool-toolbar`** | **Primary row for Generate/Copy/Download** — always use this name (not `mutation-actions` / `token-bomb-actions`) |
|
||||
| Primary CTA | `transform-button tool-primary-btn` | Main “generate” or “run” action inside the toolbar |
|
||||
| Secondary actions | `action-button copy` / `action-button download` | Toolbar copy/download styling |
|
||||
| Textarea + floating copy | `textarea-copy-wrap` | Wraps `textarea` + `copy-button` when the copy control is absolutely positioned |
|
||||
| Small spacing | `u-mb-8`, `u-mb-16`, `u-mt-16` | Prefer these over inline `style` for margins |
|
||||
|
||||
Avoid inline `style` on templates; add a small utility or semantic class in `style.css` if you need a new pattern.
|
||||
|
||||
### Slide-out sidebars (global shell)
|
||||
|
||||
Panels in [`index.template.html`](../index.template.html) (Copy History, Glitch Tokens, End sequences, Advanced Settings) share the same **structural** classes; keep tool-specific names for width/theme hooks only.
|
||||
|
||||
| Class | Role |
|
||||
|--------|------|
|
||||
| `app-sidebar` | Fixed column from the right: flex column, `transform` slide-in, `active` opens |
|
||||
| `app-sidebar-header` | Title row + actions (with tool-specific class, e.g. `copy-history-header`) |
|
||||
| `app-sidebar-body` | Scrollable content (`flex: 1`, `overflow-y: auto`) |
|
||||
|
||||
All sidebars share **`--sidebar-width`** (desktop, default `420px`) and **`max-width: min(100%, 90vw)`**. From **768px** breakpoint down they are **full viewport width** (`100%`). Only **stacking** differs: `.unicode-options-panel` uses a higher **`z-index`** (200 desktop, 300 on small screens) so Advanced Settings stays above other panels. Shared shadow: **`--sidebar-edge-shadow`** in `:root`.
|
||||
|
||||
**Maintaining `style.css`:** Prefer comma-separated selectors when multiple unrelated classes share the same declarations (e.g. Bijection / PromptCraft / Anti-Classifier card shells). Reuse `:root` tokens such as `--panel-shadow-soft` for repeated shadows instead of copying the same `box-shadow` value.
|
||||
|
||||
+13
-13
@@ -114,8 +114,8 @@
|
||||
</div>
|
||||
|
||||
<!-- Copy History Panel -->
|
||||
<div class="copy-history-panel" :class="{ 'active': showCopyHistory }">
|
||||
<div class="copy-history-header">
|
||||
<div class="app-sidebar copy-history-panel" :class="{ 'active': showCopyHistory }">
|
||||
<div class="app-sidebar-header copy-history-header">
|
||||
<h3><i class="fas fa-history"></i> Copy History</h3>
|
||||
<div class="header-actions">
|
||||
<button
|
||||
@@ -131,7 +131,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="copy-history-content">
|
||||
<div class="app-sidebar-body copy-history-content">
|
||||
<div v-if="copyHistory.length === 0" class="no-history">
|
||||
<p>No copy history yet. Use the app features to auto-copy content.</p>
|
||||
</div>
|
||||
@@ -158,8 +158,8 @@
|
||||
</div>
|
||||
|
||||
<!-- Glitch Tokens Panel -->
|
||||
<div class="glitch-token-panel" :class="{ 'active': showGlitchTokenPanel }">
|
||||
<div class="glitch-token-header">
|
||||
<div class="app-sidebar glitch-token-panel" :class="{ 'active': showGlitchTokenPanel }">
|
||||
<div class="app-sidebar-header glitch-token-header">
|
||||
<h3><i class="fas fa-bug"></i> Glitch Tokens</h3>
|
||||
<div class="header-actions">
|
||||
<button class="close-button" @click="toggleGlitchTokenPanel" title="Close glitch tokens">
|
||||
@@ -167,7 +167,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="glitch-token-content">
|
||||
<div class="app-sidebar-body glitch-token-content">
|
||||
<!-- Filter Section -->
|
||||
<div class="glitch-token-filters">
|
||||
<div class="filter-group">
|
||||
@@ -256,8 +256,8 @@
|
||||
</div>
|
||||
|
||||
<!-- End sequences sidebar (delimiter / stop strings for research) -->
|
||||
<div class="end-sequence-panel" :class="{ active: showEndSequencePanel }">
|
||||
<div class="end-sequence-header">
|
||||
<div class="app-sidebar end-sequence-panel" :class="{ active: showEndSequencePanel }">
|
||||
<div class="app-sidebar-header end-sequence-header">
|
||||
<h3><i class="fas fa-stop"></i> End sequences</h3>
|
||||
<div class="header-actions">
|
||||
<button class="close-button" type="button" @click="toggleEndSequencePanel" title="Close">
|
||||
@@ -265,7 +265,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="end-sequence-content">
|
||||
<div class="app-sidebar-body end-sequence-content">
|
||||
<p class="end-sequence-lede">
|
||||
Strings sometimes used to probe delimiter and termination behavior. Copy into your payloads as needed for authorized testing.
|
||||
</p>
|
||||
@@ -296,12 +296,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Advanced Settings Panel (inside app so Vue bindings work) -->
|
||||
<div id="unicode-options-panel" class="unicode-options-panel">
|
||||
<div class="unicode-panel-header">
|
||||
<div id="unicode-options-panel" class="app-sidebar unicode-options-panel">
|
||||
<div class="app-sidebar-header unicode-panel-header">
|
||||
<h3><i class="fas fa-sliders-h"></i> Advanced Settings</h3>
|
||||
<button class="close-button" title="Close Advanced Settings"><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
<div class="unicode-panel-content">
|
||||
<div class="app-sidebar-body unicode-panel-content">
|
||||
<!-- OpenRouter API Key -->
|
||||
<div class="settings-section api-key-section">
|
||||
<h4><i class="fas fa-key"></i> OpenRouter API Key</h4>
|
||||
@@ -333,7 +333,7 @@
|
||||
<!-- Steganography Options -->
|
||||
<h4><i class="fas fa-user-secret"></i> Steganography Options</h4>
|
||||
</div>
|
||||
<div class="unicode-panel-content options-grid steg-adv-panel">
|
||||
<div class="app-sidebar-body unicode-panel-content options-grid steg-adv-panel">
|
||||
<label>
|
||||
Initial Presentation
|
||||
<select class="steg-initial-presentation">
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button ac-generate-btn tool-primary-btn" @click="acRun" :disabled="acLoading">
|
||||
<i :class="acLoading ? 'fas fa-spinner fa-spin' : 'fas fa-bolt'"></i>
|
||||
{{ acLoading ? 'Generating...' : 'Generate transformations' }}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<label class="switch neon"><input type="checkbox" v-model="bijectionAutoCopy" /><span>Auto-copy first prompt</span></label>
|
||||
</div>
|
||||
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button bij-generate-btn tool-primary-btn" @click="generateBijectionPrompts">
|
||||
<i class="fas fa-bolt"></i>
|
||||
Generate attack prompts
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="input-section">
|
||||
<div class="input-header">
|
||||
<label for="decoder-input">Paste any encoded text to decode</label>
|
||||
<select v-model="selectedDecoder" @change="runUniversalDecode" style="margin-left: 15px; padding: 5px 10px; border-radius: 6px; border: 1px solid var(--input-border); background: var(--button-bg); color: var(--text);">
|
||||
<select v-model="selectedDecoder" @change="runUniversalDecode" class="decoder-method-select">
|
||||
<option value="auto">🔍 Auto-detect</option>
|
||||
<option v-for="transform in getAllTransformsWithReverse()" :key="transform.name" :value="transform.name">
|
||||
{{ transform.name }}
|
||||
|
||||
@@ -29,16 +29,16 @@
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzCasing" /><span>Casing chaos</span></label>
|
||||
<label class="switch neon"><input type="checkbox" v-model="fuzzEncodeShuffle" /><span>Homoglyph confusables</span></label>
|
||||
</div>
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="generateFuzzCases"><i class="fas fa-hammer"></i> Generate Cases</button>
|
||||
<button class="action-button copy" v-if="fuzzerOutputs.length" @click="copyAllFuzz"><i class="fas fa-copy"></i> Copy All</button>
|
||||
<button class="action-button download" v-if="fuzzerOutputs.length" @click="downloadFuzz"><i class="fas fa-download"></i> Download</button>
|
||||
</div>
|
||||
<div class="output-container" v-if="fuzzerOutputs.length">
|
||||
<div class="token-tiles fuzzer-list" style="display:flex; flex-direction:column; gap:8px;">
|
||||
<div v-for="(out, i) in fuzzerOutputs" :key="'fz-'+i" class="token-chip" style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="opacity:.7; min-width:32px;">#{{ i+1 }}</span>
|
||||
<textarea :value="out" readonly style="flex:1; min-height:46px;"></textarea>
|
||||
<div class="token-tiles fuzzer-list">
|
||||
<div v-for="(out, i) in fuzzerOutputs" :key="'fz-'+i" class="token-chip fuzzer-case-row">
|
||||
<span class="fuzzer-case-index">#{{ i+1 }}</span>
|
||||
<textarea class="fuzzer-case-textarea" :value="out" readonly></textarea>
|
||||
<button class="copy-button" @click="copyToClipboard(out)" title="Copy"><i class="fas fa-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Mode Selection -->
|
||||
<div class="button-group" style="margin-bottom: 16px;">
|
||||
<div class="button-group u-mb-16">
|
||||
<button
|
||||
:class="['btn', gibberishMode === 'random' ? 'btn-primary' : 'btn-secondary']"
|
||||
@click="gibberishMode = 'random'"
|
||||
@@ -53,7 +53,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="sentenceToGibberish"><i class="fas fa-hammer"></i> Generate Gibberish</button>
|
||||
</div>
|
||||
|
||||
@@ -61,15 +61,15 @@
|
||||
<div class="section-header">
|
||||
<h4><i class="fas fa-language"></i> Gibberish Output</h4>
|
||||
</div>
|
||||
<div style="position: relative;">
|
||||
<div class="textarea-copy-wrap">
|
||||
<textarea v-model="gibberishOutput" readonly rows="4"></textarea>
|
||||
<button class="copy-button" @click="copyToClipboard(gibberishOutput)" title="Copy"><i class="fas fa-copy"></i></button>
|
||||
</div>
|
||||
|
||||
<div class="section-header" style="margin-top: 16px;">
|
||||
<div class="section-header u-mt-16">
|
||||
<h4><i class="fas fa-book"></i> Dictionary</h4>
|
||||
</div>
|
||||
<div style="position: relative;">
|
||||
<div class="textarea-copy-wrap">
|
||||
<textarea v-model="gibberishDictionary" readonly rows="3"></textarea>
|
||||
<button class="copy-button" @click="copyToClipboard(gibberishDictionary)" title="Copy"><i class="fas fa-copy"></i></button>
|
||||
</div>
|
||||
@@ -79,7 +79,7 @@
|
||||
<!-- Character Removal Mode -->
|
||||
<div v-if="gibberishMode === 'removal'">
|
||||
<!-- Sub-mode selection -->
|
||||
<div class="button-group" style="margin-bottom: 16px;">
|
||||
<div class="button-group u-mb-16">
|
||||
<button
|
||||
:class="['btn', removalSubMode === 'random' ? 'btn-primary' : 'btn-secondary']"
|
||||
@click="removalSubMode = 'random'"
|
||||
@@ -128,7 +128,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="generateRandomRemovals">
|
||||
<i class="fas fa-dice"></i> Generate Variations
|
||||
</button>
|
||||
@@ -181,7 +181,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="generateSpecificRemoval">
|
||||
<i class="fas fa-eraser"></i> Remove Characters
|
||||
</button>
|
||||
@@ -191,7 +191,7 @@
|
||||
<div class="section-header">
|
||||
<h4><i class="fas fa-check"></i> Result</h4>
|
||||
</div>
|
||||
<div style="position: relative;">
|
||||
<div class="textarea-copy-wrap">
|
||||
<textarea v-model="removalSpecificOutput" readonly rows="4"></textarea>
|
||||
<button class="copy-button" @click="copyToClipboard(removalSpecificOutput)" title="Copy">
|
||||
<i class="fas fa-copy"></i>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button pc-generate-btn tool-primary-btn" @click="pcRunMutation" :disabled="pcLoading">
|
||||
<i :class="pcLoading ? 'fas fa-spinner fa-spin' : 'fas fa-bolt'"></i>
|
||||
{{ pcLoading ? 'Generating...' : 'Mutate Prompt' }}
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Generate Button -->
|
||||
<div class="token-bomb-actions splitter-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="generateSplitMessages">
|
||||
<i class="fas fa-cut"></i> Split Messages
|
||||
</button>
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
<input type="text" v-model="tbCarrierManual" placeholder="e.g., ⚙️ or ::tag::" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="generateTokenBomb" title="Build the tokenade with current settings">
|
||||
<i class="fas fa-hammer"></i> Generate Tokenade
|
||||
</button>
|
||||
@@ -118,9 +118,9 @@
|
||||
<!-- Text Payload Generator (simple) -->
|
||||
<div class="transform-section">
|
||||
<h4><i class="fas fa-font"></i> Text Payload Generator</h4>
|
||||
<label style="display: block; width: 100%; margin-bottom: 15px;">
|
||||
<label class="tokenade-field-label">
|
||||
Base text
|
||||
<input type="text" v-model="tpBase" placeholder="Enter base snippet (e.g., hello)" style="width: 100%;" />
|
||||
<input type="text" v-model="tpBase" placeholder="Enter base snippet (e.g., hello)" />
|
||||
</label>
|
||||
<div class="options-grid">
|
||||
<label>
|
||||
@@ -136,7 +136,7 @@
|
||||
<span>Add zero-width spacing</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="token-bomb-actions mutation-actions">
|
||||
<div class="tool-toolbar">
|
||||
<button type="button" class="transform-button tool-primary-btn" @click="generateTextPayload">
|
||||
<i class="fas fa-hammer"></i> Generate Text Payload
|
||||
</button>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<h3><i class="fas fa-layer-group"></i> Tokenizer Visualization <small>{{ tokenizerEngine }}</small></h3>
|
||||
<p>Paste text to see how different tokenizers segment it.</p>
|
||||
</div>
|
||||
<div class="options-grid" style="margin-bottom:8px;">
|
||||
<div class="options-grid u-mb-8">
|
||||
<label>
|
||||
Engine
|
||||
<select v-model="tokenizerEngine" @change="runTokenizer">
|
||||
@@ -33,11 +33,11 @@
|
||||
<small>{{ tokenizerTokens.length }} total · {{ tokenizerWordCount }} words · {{ tokenizerCharCount }} chars</small>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="token-tiles" v-if="tokenizerTokens.length" style="display:flex; flex-wrap:wrap; gap:6px;">
|
||||
<div v-for="(tok, i) in tokenizerTokens" :key="i" class="token-chip" style="background:var(--button-bg); border:1px solid var(--input-border); padding:6px 8px; border-radius:6px; font-family:'Fira Code', monospace;">
|
||||
<span style="opacity:.75; margin-right:6px;">{{ i }}</span>
|
||||
<div class="token-tiles tokenizer-tiles" v-if="tokenizerTokens.length">
|
||||
<div v-for="(tok, i) in tokenizerTokens" :key="i" class="token-chip token-chip--tokenizer">
|
||||
<span class="token-chip__idx">{{ i }}</span>
|
||||
<span>{{ tok.text }}</span>
|
||||
<span v-if="tok.id !== undefined" style="opacity:.6; margin-left:6px;">#{{ tok.id }}</span>
|
||||
<span v-if="tok.id !== undefined" class="token-chip__id">#{{ tok.id }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="output-instructions" v-else>
|
||||
|
||||
Reference in New Issue
Block a user