tinymux/client/web/css/titan.css
Stephen Dennis 1fa5282d54 Web client: triggers, auto-complete, reconnect, /commands
Trigger system: regex matching on incoming lines with gag, priority,
shot count. Trigger Manager dialog (Add/Edit/Delete) accessible from
toolbar button. Triggers persist to localStorage. /def, /undef, /list
commands work from the input line.

Incoming lines run through TriggerDB.check() before display — gagged
lines are suppressed, trigger actions execute as commands.

Input auto-complete: Tab key completes /commands from a built-in list.
Multiple matches shown in output, single match completes with space.

Reconnect button on disconnected tabs — italic styling with a green
recycle arrow that reconnects with the same host/port/ssl.

Slash commands: /connect, /disconnect, /worlds, /triggers, /find,
/clear, /def, /undef, /list, /help. Unknown /commands pass through
to the server (some MUDs use them).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 09:34:35 -06:00

266 lines
4.5 KiB
CSS

/* Titan web client stylesheet */
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #000000;
--fg: #c0c0c0;
--tab-bg: #303030;
--tab-active: #000000;
--tab-text: #a0a0a0;
--tab-active-text: #ffffff;
--status-bg: #000080;
--status-fg: #ffffff;
--input-bg: #202020;
--input-fg: #ffffff;
--accent: #ffc800;
--font: 'Consolas', 'Courier New', monospace;
--font-size: 14px;
}
html, body {
height: 100%;
background: var(--bg);
color: var(--fg);
font-family: var(--font);
font-size: var(--font-size);
overflow: hidden;
}
#app {
display: flex;
flex-direction: column;
height: 100vh;
}
/* Toolbar */
#toolbar {
display: flex;
align-items: center;
background: #252525;
padding: 2px 4px;
gap: 2px;
border-bottom: 1px solid #404040;
}
#toolbar button {
background: #3a3a3a;
color: #d0d0d0;
border: 1px solid #505050;
padding: 3px 10px;
cursor: pointer;
font-family: var(--font);
font-size: 12px;
border-radius: 2px;
}
#toolbar button:hover {
background: #4a4a4a;
}
.toolbar-sep {
width: 1px;
height: 18px;
background: #505050;
margin: 0 4px;
}
/* Tab bar */
#tabbar {
display: flex;
background: var(--tab-bg);
min-height: 28px;
overflow-x: auto;
user-select: none;
}
.tab {
padding: 4px 16px;
cursor: pointer;
color: var(--tab-text);
border-right: 1px solid #505050;
white-space: nowrap;
display: flex;
align-items: center;
gap: 6px;
}
.tab.active {
background: var(--tab-active);
color: var(--tab-active-text);
}
.tab .activity-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent);
display: none;
}
.tab.has-activity .activity-dot {
display: inline-block;
}
.tab .close-btn {
font-size: 12px;
opacity: 0;
cursor: pointer;
margin-left: 4px;
}
.tab:hover .close-btn {
opacity: 0.6;
}
.tab .close-btn:hover {
opacity: 1;
}
.tab.disconnected {
color: #806060;
font-style: italic;
}
.tab .reconnect-btn {
font-size: 14px;
cursor: pointer;
opacity: 0.6;
margin-left: 2px;
}
.tab .reconnect-btn:hover {
opacity: 1;
color: #55ff55;
}
/* Output pane */
#output {
flex: 1;
overflow-y: auto;
padding: 2px 4px;
font-family: var(--font);
font-size: var(--font-size);
line-height: 1.3;
white-space: pre-wrap;
word-wrap: break-word;
background: var(--bg);
color: var(--fg);
}
#output .line {
min-height: 1.3em;
}
#output .line.find-highlight {
background: #282850;
}
/* Input area */
#inputarea {
background: var(--input-bg);
padding: 2px 4px;
}
#inputline {
width: 100%;
background: var(--input-bg);
color: var(--input-fg);
border: none;
outline: none;
font-family: var(--font);
font-size: var(--font-size);
padding: 4px 2px;
}
/* Status bar */
#statusbar {
background: var(--status-bg);
color: var(--status-fg);
padding: 2px 8px;
font-size: 12px;
min-height: 22px;
user-select: none;
}
/* Dialogs */
dialog {
background: #2a2a2a;
color: #e0e0e0;
border: 1px solid #555;
border-radius: 4px;
padding: 16px;
min-width: 300px;
font-family: var(--font);
font-size: 13px;
}
dialog::backdrop {
background: rgba(0, 0, 0, 0.5);
}
dialog h3 {
margin-bottom: 12px;
font-size: 15px;
}
dialog label {
display: block;
margin-bottom: 8px;
}
dialog input[type="text"] {
background: #1a1a1a;
color: #e0e0e0;
border: 1px solid #555;
padding: 4px 6px;
font-family: var(--font);
font-size: 13px;
width: 200px;
margin-left: 8px;
}
dialog input[type="checkbox"] {
margin-right: 6px;
}
dialog select {
background: #1a1a1a;
color: #e0e0e0;
border: 1px solid #555;
width: 100%;
font-family: var(--font);
font-size: 13px;
margin-bottom: 8px;
}
dialog button {
background: #404040;
color: #e0e0e0;
border: 1px solid #555;
padding: 4px 16px;
cursor: pointer;
font-family: var(--font);
font-size: 13px;
margin-right: 4px;
}
dialog button:hover {
background: #505050;
}
.dialog-buttons {
margin-top: 12px;
}
.dialog-buttons-side {
display: flex;
gap: 4px;
margin-bottom: 8px;
}
/* ANSI color classes */
.ansi-bold { font-weight: bold; }
.ansi-underline { text-decoration: underline; }
.ansi-blink { animation: blink 1s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }
.ansi-inverse { filter: invert(1); }