/**
* ANSI Terminal CSS Styles
* For rendering ANSI escape sequences in web display
*
* awehttam@gmail.com
*/
/* DOS VGA font for authentic CP437 ANSI art rendering.
Place the TTF file at public_html/fonts/PerfectDOSVGA437.ttf */
@font-face {
font-family: 'Perfect DOS VGA 437';
src: url('/fonts/PerfectDOSVGA437.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: block;
}
/* Optional Amiga-style font for alternate art profiles.
Place the TTF file at public_html/fonts/TopazPlus.ttf if available. */
@font-face {
font-family: 'Topaz Plus';
src: url('/fonts/TopazPlus.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Topaz Unicode KS13';
src: url('/fonts/topaz_unicode_ks13_regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Topaz Unicode KS13';
src: url('/fonts/topaz_unicode_ks13_bold.ttf') format('truetype');
font-weight: bold;
font-style: normal;
font-display: swap;
}
/* PETSCII / C64-style font for PETSCII message rendering. */
@font-face {
font-family: 'Pet Me 64';
src: url('/fonts/PetMe64.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* PETSCII / C128-style font for alternate PETSCII rendering. */
@font-face {
font-family: 'Pet Me 128';
src: url('/fonts/PetMe128.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* Container for ANSI art */
.ansi-art-container {
overflow-x: auto;
background-color: #000;
border-radius: 4px;
padding: 8px;
line-height: 1em;
}
/* Fixed-width character cell: forces each glyph to occupy exactly 1ch of horizontal
space, preventing misalignment caused by box-drawing/block characters rendering in
a fallback font with different metrics than the primary monospace font. */
.ansi-c {
display: inline-block;
width: 1ch;
overflow: visible;
}
/* Ensure pre elements inside container don't wrap */
.ansi-art-container pre {
font-family: monospace;
font-size: 16px;
line-height: 16px;
white-space: pre;
margin: 0;
padding: 0;
color: #aaa;
background-color: #000;
display: inline-block;
text-align: left;
min-width: max-content;
}
/* Mobile: scale down ANSI art to fit screen */
@media (max-width: 768px) {
.ansi-art-container pre {
font-size: 8px;
line-height: 8px;
}
}
@media (max-width: 480px) {
.ansi-art-container pre {
font-size: 6px;
line-height: 6px;
}
}
.ansi-art {
font-family: monospace;
font-size: 16px !important;
line-height: 16px !important;
letter-spacing: 0;
margin: 0;
padding: 0;
white-space: pre;
color: #aaa;
background-color: #000;
display: block;
}
.ansi-art-container.art-format-amiga-ansi,
.ansi-art.art-format-amiga-ansi {
background-color: #06090f;
color: #cfd8ff;
}
.ansi-art-container.art-format-amiga-ansi pre,
.ansi-art.art-format-amiga-ansi {
font-family: 'Topaz Unicode KS13', 'Topaz Plus', 'Courier New', monospace;
letter-spacing: 0.01em;
}
.ansi-art-container.art-format-petscii,
.ansi-art.art-format-petscii {
background-color: #1e1e7a;
color: #8cc7ff;
}
.ansi-art-container.art-format-petscii pre,
.ansi-art.art-format-petscii {
font-family: 'Pet Me 64', "Courier New", Consolas, monospace;
}
.ansi-art-container.art-format-petscii.petscii-c128 pre,
.ansi-art.art-format-petscii.petscii-c128 {
font-family: 'Pet Me 128', "Courier New", Consolas, monospace;
}
/* Exact C64 color palette (16 fg + 16 bg) for screen RAM rendering */
.c64-fg-0 { color: #000000; } .c64-fg-1 { color: #ffffff; }
.c64-fg-2 { color: #880000; } .c64-fg-3 { color: #aaffee; }
.c64-fg-4 { color: #cc44cc; } .c64-fg-5 { color: #00cc55; }
.c64-fg-6 { color: #0000aa; } .c64-fg-7 { color: #eeee77; }
.c64-fg-8 { color: #dd8855; } .c64-fg-9 { color: #664400; }
.c64-fg-10 { color: #ff7777; } .c64-fg-11 { color: #333333; }
.c64-fg-12 { color: #777777; } .c64-fg-13 { color: #aaff66; }
.c64-fg-14 { color: #0088ff; } .c64-fg-15 { color: #bbbbbb; }
.c64-bg-1 { background-color: #ffffff; } .c64-bg-2 { background-color: #880000; }
.c64-bg-3 { background-color: #aaffee; } .c64-bg-4 { background-color: #cc44cc; }
.c64-bg-5 { background-color: #00cc55; } .c64-bg-6 { background-color: #0000aa; }
.c64-bg-7 { background-color: #eeee77; } .c64-bg-8 { background-color: #dd8855; }
.c64-bg-9 { background-color: #664400; } .c64-bg-10 { background-color: #ff7777; }
.c64-bg-11 { background-color: #333333; } .c64-bg-12 { background-color: #777777; }
.c64-bg-13 { background-color: #aaff66; } .c64-bg-14 { background-color: #0088ff; }
.c64-bg-15 { background-color: #bbbbbb; }
/* Standard ANSI foreground colors (0-7) */
.ansi-black { color: #000; }
.ansi-red { color: #aa0000; }
.ansi-green { color: #00aa00; }
.ansi-yellow { color: #aa5500; }
.ansi-blue { color: #0000aa; }
.ansi-magenta { color: #aa00aa; }
.ansi-cyan { color: #00aaaa; }
.ansi-white { color: #aaaaaa; }
/* Bright ANSI foreground colors (8-15) */
.ansi-bright-black { color: #555555; }
.ansi-bright-red { color: #ff5555; }
.ansi-bright-green { color: #55ff55; }
.ansi-bright-yellow { color: #ffff55; }
.ansi-bright-blue { color: #5555ff; }
.ansi-bright-magenta { color: #ff55ff; }
.ansi-bright-cyan { color: #55ffff; }
.ansi-bright-white { color: #ffffff; }
/* Standard ANSI background colors (0-7) */
.ansi-bg-black { background-color: #000; }
.ansi-bg-red { background-color: #aa0000; }
.ansi-bg-green { background-color: #00aa00; }
.ansi-bg-yellow { background-color: #aa5500; }
.ansi-bg-blue { background-color: #0000aa; }
.ansi-bg-magenta { background-color: #aa00aa; }
.ansi-bg-cyan { background-color: #00aaaa; }
.ansi-bg-white { background-color: #aaaaaa; }
/* Bright ANSI background colors (8-15) */
.ansi-bg-bright-black { background-color: #555555; }
.ansi-bg-bright-red { background-color: #ff5555; }
.ansi-bg-bright-green { background-color: #55ff55; }
.ansi-bg-bright-yellow { background-color: #ffff55; }
.ansi-bg-bright-blue { background-color: #5555ff; }
.ansi-bg-bright-magenta { background-color: #ff55ff; }
.ansi-bg-bright-cyan { background-color: #55ffff; }
.ansi-bg-bright-white { background-color: #ffffff; }
/* Text attributes */
.ansi-bold { font-weight: bold; }
.ansi-dim { opacity: 0.7; }
.ansi-italic { font-style: italic; }
.ansi-underline { text-decoration: underline; }
.ansi-blink { animation: ansi-blink 1s step-end infinite; }
.ansi-reverse { filter: invert(1); }
.ansi-hidden { visibility: hidden; }
.ansi-strike { text-decoration: line-through; }
@keyframes ansi-blink {
0%, 50% { opacity: 1; }
50.01%, 100% { opacity: 0; }
}
/* Bold + color combinations for bright colors */
.ansi-bold.ansi-black { color: #555555; }
.ansi-bold.ansi-red { color: #ff5555; }
.ansi-bold.ansi-green { color: #55ff55; }
.ansi-bold.ansi-yellow { color: #ffff55; }
.ansi-bold.ansi-blue { color: #5555ff; }
.ansi-bold.ansi-magenta { color: #ff55ff; }
.ansi-bold.ansi-cyan { color: #55ffff; }
.ansi-bold.ansi-white { color: #ffffff; }
/* In message bodies: keep overflow scrolling but remove the black box */
.message-text .ansi-art-container {
background: transparent;
border-radius: 0;
padding: 0;
overflow-x: auto !important;
overflow-y: hidden !important;
}
.message-text .ansi-art-container pre,
.message-text .ansi-art {
background: transparent;
border: none !important;
white-space: pre !important;
overflow: visible !important;
}
|