Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/zshall/program-guide/llms.txt

Use this file to discover all available pages before exploring further.

Television Simulator ‘99 uses SCSS for all visual styling, compiled to a single output file at css/site.css. The SCSS source is organised into a main entry point that imports partials for the TV chrome, the scanlines overlay, and individual channel layouts. To change colours, fonts, screen dimensions, or per-channel visuals, you edit the SCSS source and recompile — the browser always reads the compiled css/site.css.

Entry point

scss/site.scss is the root file that pulls everything together. It declares colour variables, loads custom fonts, and imports every partial:
@font-face {
    font-family: VCR;
    src: url(fonts/VCR_OSD.ttf);
}

@font-face {
    font-family: PrevueGrid;
    src: url(fonts/PrevueGrid.ttf);
}

/* colors */
$yellow: #cccc00;
$white: #aaaaaa;
$gray: #555555;
$black: #111111;
$light-blue: #223388;
$dark-blue: #000055;
$darker-blue: #000033;

$blue-gradient: linear-gradient(to bottom, rgba(51,54,172,1) 0%,rgba(52,50,218,1) 30%,rgba(53,50,83,1) 100%);
$red-gradient: linear-gradient(to bottom, rgba(134,44,44,1) 0%, rgba(206,36,52,1) 30%, rgba(75,38,36,1) 100%);

@import 'core/scanlines';
@import 'core/tv';

.tv .screen {
    #ch-12 { @import 'channels/012'; }
}
All colour variables defined here are available throughout every imported partial.

Colour variables

Every colour in the interface maps to one of these SCSS variables. Changing a variable value and recompiling updates the colour everywhere it’s used.
VariableHex valueUsed for
$yellow#cccc00Active/hover links, channel numbers, clock text, on-screen messages
$white#aaaaaaDefault text colour, table borders (top/left sides)
$gray#555555Summary cell backgrounds
$black#111111Page background, table border (bottom/right sides), guide container background
$light-blue#223388Table header background, unvisited link colour
$dark-blue#000055Standard listing cell background
$darker-blue#000033Left info panel background (.video-left)
$blue-gradientMovie listing cell background (top-to-bottom gradient from #3336ac#3432da#353253)
$red-gradientNotice banner cell background (top-to-bottom gradient from #862c2c#ce2434#4b2624)

Typography

Three custom font files live in css/fonts/ and are used across the interface:
Font family nameFileUsed for
PrevueGridPrevueGrid.ttfThe default font for all body text, the channel listing grid, and the guide table. Declared in scss/site.scss and applied globally via * { font-family: "PrevueGrid"; } in scss/core/tv.scss.
PrevueListPrevueList.ttfAn alternate Prevue listing font. The file is present in css/fonts/ and can be declared as an additional @font-face if you want to use it in a custom channel’s layout.
VCRVCR_OSD.ttfOn-screen display messages: the channel number shown top-right when switching channels (#tvm-top-right) and the MUTING label shown bottom-left (#tvm-bottom-left). Declared in scss/site.scss.
To add PrevueList as a usable font, add a @font-face declaration to scss/site.scss:
@font-face {
    font-family: PrevueList;
    src: url(fonts/PrevueList.ttf);
}

Scanlines effect

The animated CRT scanlines overlay is defined in scss/core/scanlines.scss. It exposes a .scanlines CSS class that applies a repeating semi-transparent stripe pattern and an optional flicker animation to any element it’s placed on. The class is applied at runtime inside tv.js’s startUp() method, and only on non-mobile devices:
if (!Helpers.isMobile().any()) {
    $('.screen').addClass('scanlines');
}
Key SCSS variables inside scss/core/scanlines.scss that control the effect:
VariableDefaultDescription
$scan-width2pxHeight of each individual scanline stripe
$scan-colorrgba(#000, .18)Colour and opacity of the scanline stripes
$scan-crttrueEnables the step-based CSS animation that simulates a CRT refresh at $scan-fps frames per second
$scan-fps60Animation steps per second when $scan-crt is true
$scan-moving-linefalseEnables a single scanline that travels from bottom to top of the screen
$scan-z-index10Z-index of the overlay; set to 2147483648 or higher to enable scanlines over Chrome’s fullscreen mode

TV screen dimensions

The outer .tv element is defined in scss/core/tv.scss as a fixed 1200×900 px canvas, absolutely positioned and centred in the viewport:
.tv {
    position: absolute;
    width: 1200px;
    height: 900px;
    left: -webkit-calc(50% - 600px);
    transform-origin: top;
}
On smaller screens, handleResize() in tv.js scales the entire .tv element down uniformly using a CSS transform: scale(), calculated as:
scale = Math.min(width / this.maxWidth, height / this.maxHeight);
$('.tv').css({ 'transform': 'scale(' + scale + ')' });
The default maxWidth is 1200 and maxHeight is 1000, which are the constructor defaults for the TV class in tv.js. Note that maxHeight (1000) is intentionally larger than the actual CSS height of the .tv element (900px). These two values serve different purposes: the SCSS height: 900px sets the physical canvas size, while maxHeight is the threshold used in the scale calculation. You would need to update both values together if you change the canvas height.

Channel-specific styles

Each channel gets its own SCSS partial scoped tightly under .tv .screen #ch-{number}. Channel 12’s styles are in scss/channels/012.scss and imported in scss/site.scss like this:
.tv .screen {
    #ch-12 { @import 'channels/012'; }
}
The id attribute ch-{number} is set on .current-channel automatically by showChannel() in tv.js when a channel loads, so any selectors inside your partial are naturally scoped to that channel’s content only. To add styles for a new channel — say channel 5 — create scss/channels/005.scss and add an import to scss/site.scss:
.tv .screen {
    #ch-12 { @import 'channels/012'; }
    #ch-5  { @import 'channels/005'; }
}
Inside scss/channels/005.scss you can reference all the global colour variables:
.video-left {
    background: $darker-blue;
    text-align: center;
}

.info-panel {
    color: $yellow;
    font-family: VCR;
    font-size: 28px;
}

Compiling SCSS

The project uses node-sass to compile SCSS to CSS. Run the following command from the project root:
node-sass scss/site.scss css/site.css
The browser reads css/site.css, not the SCSS source files. Any change to .scss files has no effect until you recompile. Refresh the browser after each compile run to see your changes.
A VS Code task is also configured in .vscode/tasks.json: open the Command Palette, choose Tasks: Run Task, and select node-sass to compile without leaving the editor.
Use the --watch flag to recompile automatically whenever you save a SCSS file:
node-sass --watch scss/site.scss css/site.css
This is the fastest workflow when iterating on channel styles or colour adjustments, since any save to any imported partial triggers an immediate recompile.

Build docs developers (and LLMs) love