When I’m on calls with my therapist it has bugged me that I can’t actually go fullscreen with the video so I gave CGPT the code for the page and wrote up a script that expands the fullscreen video to actually be fullscreen.
Use either the console script or Tampermonkey script and try it out for yourself!


Console script
(() => {
const TOGGLE = 'tm-full-bleed-active';
const ROOT_SEL = 'div.bbwWj.video';
const PANEL_SEL = `${ROOT_SEL} > div.mljTO`;
const STREAM_CONTAINER_SEL = `${ROOT_SEL} .stream-container`;
const PARTICIPANT_SEL = `${ROOT_SEL} .participant-container`;
const VIDEO_SEL = `${ROOT_SEL} video`;
// --- style injection ---
const css = `
html.${TOGGLE}, body.${TOGGLE}{margin:0!important;padding:0!important;overflow:hidden!important}
html.${TOGGLE} ${PANEL_SEL}{
position:fixed!important;inset:0!important;width:100vw!important;height:100vh!important;
margin:0!important;padding:0!important;border:0!important;background:#000!important;
z-index:2147483647!important;box-shadow:none!important
}
html.${TOGGLE} ${STREAM_CONTAINER_SEL}, html.${TOGGLE} ${PARTICIPANT_SEL}{
position:absolute!important;inset:0!important;width:100%!important;height:100%!important;
margin:0!important;padding:0!important;border:0!important;max-width:none!important;max-height:none!important;overflow:hidden!important;background:transparent!important
}
html.${TOGGLE} ${VIDEO_SEL}{
position:absolute!important;inset:0!important;width:100%!important;height:100%!important;
object-fit:cover!important;object-position:center center!important;display:block!important;background:#000!important;border:0!important;box-shadow:none!important;transform:none!important
}
html.${TOGGLE} ${ROOT_SEL} .name, html.${TOGGLE} ${ROOT_SEL} .pin-button, html.${TOGGLE} ${ROOT_SEL} .more-button{
display:none!important;visibility:hidden!important;pointer-events:none!important
}
.tm-fb-btn{
position:fixed!important;right:14px;bottom:14px;z-index:2147483647!important;
font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
padding:10px 12px;border-radius:999px;background:rgba(0,0,0,.6);color:#fff;
border:1px solid rgba(255,255,255,.2);cursor:pointer;user-select:none;backdrop-filter:blur(4px)
}
.tm-fb-btn:hover{background:rgba(0,0,0,.75)}
`;
let style = document.getElementById('tm-fb-style');
if (!style) {
style = document.createElement('style');
style.id = 'tm-fb-style';
style.textContent = css;
document.head.appendChild(style);
}
// --- helpers ---
const $ = (s, r = document) => r.querySelector(s);
const nap = (ms) => new Promise(r => setTimeout(r, ms));
const waitFor = async (sel, tries = 200, step = 100) => {
while (tries-- > 0) { const el = $(sel); if (el) return el; await nap(step); }
return null;
};
// --- state ---
let btn;
const isActive = () =>
document.documentElement.classList.contains(TOGGLE) ||
document.body.classList.contains(TOGGLE);
const setActive = (on) => {
[document.documentElement, document.body].forEach(el => el && el.classList.toggle(TOGGLE, on));
if (btn) btn.textContent = on ? 'Exit Full-Bleed' : 'Full-Bleed';
};
const toggle = () => setActive(!isActive());
// --- UI button ---
const mountButton = () => {
if (btn && document.body.contains(btn)) return btn;
btn = document.createElement('button');
btn.className = 'tm-fb-btn';
btn.type = 'button';
btn.textContent = isActive() ? 'Exit Full-Bleed' : 'Full-Bleed';
btn.addEventListener('click', toggle);
document.body.appendChild(btn);
return btn;
};
// --- key bindings ---
const bindKeys = () => {
window.addEventListener('keydown', (e) => {
if (e.key === 'f' || e.key === 'F') { e.preventDefault(); toggle(); }
else if (e.key === 'Escape' && isActive()) { e.preventDefault(); setActive(false); }
}, { capture: true });
};
// --- dblclick on video ---
const bindVideoDblClick = (v) => {
if (!v || v.dataset.tmFbBound) return;
v.addEventListener('dblclick', (e) => { e.preventDefault(); toggle(); }, { capture: true });
v.dataset.tmFbBound = '1';
};
// --- observe dynamic DOM ---
const observe = () => {
const mo = new MutationObserver(() => {
const v = $(VIDEO_SEL);
if (v) bindVideoDblClick(v);
if (!btn && document.body) mountButton();
});
mo.observe(document.documentElement, { childList: true, subtree: true });
};
// --- bootstrap ---
(async () => {
await waitFor('body');
bindKeys();
observe();
const v = await waitFor(VIDEO_SEL, 120, 150);
if (v) bindVideoDblClick(v);
mountButton();
// Expose controls for manual use
window.tmFullBleed = { toggle, on: () => setActive(true), off: () => setActive(false) };
console.log('[tmFullBleed] Ready. Use tmFullBleed.toggle(), press F, double-click video, or use the button.');
})();
})();
Tampermonkey script
// ==UserScript==
// @name Full-Bleed Video (SimplePractice only)
// @namespace nic.tools.video
// @version 1.0.1
// @description Force main video to go true full-bleed (edge-to-edge) on SimplePractice video
// @author you
// @match https://video.simplepractice.com/*
// @run-at document-idle
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict';
// ---------- small utils ----------
const nap = (ms) => new Promise(r => setTimeout(r, ms));
const q = (sel, root = document) => root.querySelector(sel);
// Wait for an element or return null after tries*interval
const waitFor = async (fnOrSel, tries = 200, interval = 100) => {
while (tries-- > 0) {
let el = null;
try { el = typeof fnOrSel === 'function' ? fnOrSel() : q(fnOrSel); } catch {}
if (el) return el;
await nap(interval);
}
return null;
};
// ---------- selectors from provided markup ----------
const ROOT_SEL = 'div.bbwWj.video';
const PANEL_SEL = `${ROOT_SEL} > div.mljTO`;
const STREAM_CONTAINER_SEL = `${ROOT_SEL} .stream-container`;
const PARTICIPANT_SEL = `${ROOT_SEL} .participant-container`;
const VIDEO_SEL = `${ROOT_SEL} video`;
const TOGGLE_CLASS = 'tm-full-bleed-active';
// ---------- inject styles ----------
GM_addStyle(`
/* Full-bleed mode root locks */
html.${TOGGLE_CLASS}, body.${TOGGLE_CLASS} {
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
}
/* Pin the main panel to the viewport */
html.${TOGGLE_CLASS} ${PANEL_SEL} {
position: fixed !important;
inset: 0 !important;
width: 100vw !important;
height: 100vh !important;
margin: 0 !important;
padding: 0 !important;
border: 0 !important;
background: #000 !important;
z-index: 2147483647 !important;
box-shadow: none !important;
}
/* Ensure no intermediate wrapper constrains size */
html.${TOGGLE_CLASS} ${STREAM_CONTAINER_SEL},
html.${TOGGLE_CLASS} ${PARTICIPANT_SEL} {
position: absolute !important;
inset: 0 !important;
width: 100% !important;
height: 100% !important;
margin: 0 !important;
padding: 0 !important;
border: 0 !important;
max-width: none !important;
max-height: none !important;
overflow: hidden !important;
background: transparent !important;
}
/* Make the video fill and crop (letterboxing avoidance) */
html.${TOGGLE_CLASS} ${VIDEO_SEL} {
position: absolute !important;
inset: 0 !important;
width: 100% !important;
height: 100% !important;
object-fit: cover !important;
object-position: center center !important;
display: block !important;
background: #000 !important;
border: 0 !important;
box-shadow: none !important;
transform: none !important;
}
/* Hide overlays that might intrude (adjust as needed) */
html.${TOGGLE_CLASS} ${ROOT_SEL} .name,
html.${TOGGLE_CLASS} ${ROOT_SEL} .pin-button,
html.${TOGGLE_CLASS} ${ROOT_SEL} .more-button {
display: none !important;
visibility: hidden !important;
pointer-events: none !important;
}
/* On-screen toggle button */
.tm-fb-btn {
position: fixed !important;
right: 14px;
bottom: 14px;
z-index: 2147483647 !important;
font: 600 12px/1 system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
padding: 10px 12px;
border-radius: 999px;
background: rgba(0,0,0,0.6);
color: #fff;
border: 1px solid rgba(255,255,255,0.2);
cursor: pointer;
user-select: none;
backdrop-filter: blur(4px);
}
.tm-fb-btn:hover { background: rgba(0,0,0,0.75); }
`);
// ---------- toggle logic ----------
const setActive = (on) => {
const rootList = [document.documentElement, document.body].filter(Boolean);
rootList.forEach(el => el.classList.toggle(TOGGLE_CLASS, on));
if (btn) btn.textContent = on ? 'Exit Full-Bleed' : 'Full-Bleed';
};
const isActive = () =>
document.documentElement.classList.contains(TOGGLE_CLASS) ||
document.body.classList.contains(TOGGLE_CLASS);
const toggle = () => setActive(!isActive());
// ---------- button ----------
let btn;
const mountButton = () => {
if (btn && document.body.contains(btn)) return btn;
btn = document.createElement('button');
btn.className = 'tm-fb-btn';
btn.type = 'button';
btn.textContent = isActive() ? 'Exit Full-Bleed (f)' : 'Full-Bleed (f)';
btn.addEventListener('click', toggle);
document.body.appendChild(btn);
return btn;
};
// ---------- event bindings ----------
const bindKeys = () => {
window.addEventListener('keydown', (e) => {
if (e.key === 'f' || e.key === 'F') {
e.preventDefault();
toggle();
} else if (e.key === 'Escape' && isActive()) {
e.preventDefault();
setActive(false);
}
}, { capture: true });
};
const bindVideoDoubleClick = (video) => {
if (!video || video.dataset.tmFbBound) return;
video.addEventListener('dblclick', (e) => {
e.preventDefault();
toggle();
}, { capture: true });
video.dataset.tmFbBound = '1';
};
// ---------- observer to reapply on dynamic pages ----------
const observe = () => {
const mo = new MutationObserver(() => {
const video = q(VIDEO_SEL);
if (video) bindVideoDoubleClick(video);
if (!btn && document.body) mountButton();
});
mo.observe(document.documentElement, { childList: true, subtree: true, attributes: false });
};
// ---------- bootstrap ----------
(async () => {
await waitFor(() => document.body);
bindKeys();
observe();
const video = await waitFor(VIDEO_SEL, 120, 150);
if (video) bindVideoDoubleClick(video);
mountButton();
// Optional: expose console controls
window.tmFullBleed = { toggle, on: () => setActive(true), off: () => setActive(false) };
console.log('[tmFullBleed] Ready on SimplePractice. Use tmFullBleed.toggle(), press F, double-click video, or use the button.');
})();
})();
See my creation conversation with ChatGPT here:
https://chatgpt.com/share/68c89780-f700-8007-916b-2d707b1970a6