/**
 * Copyright (c) 2014 The xterm.js authors. All rights reserved.
 * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
 * https://github.com/chjj/term.js
 * @license MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Originally forked from (with the author's permission):
 *   Fabrice Bellard's javascript vt100 for jslinux:
 *   http://bellard.org/jslinux/
 *   Copyright (c) 2011 Fabrice Bellard
 *   The original design remains. The terminal itself
 *   has been extended to include xterm CSI codes, among
 *   other features.
 */

/**
 *  Default styles for xterm.js
 */

.xterm {
    cursor: text;
    position: relative;
    user-select: none;
    -ms-user-select: none;
    -webkit-user-select: none;
}

.xterm.focus,
.xterm:focus {
    outline: none;
}

.xterm .xterm-helpers {
    position: absolute;
    top: 0;
    /**
     * The z-index of the helpers must be higher than the canvases in order for
     * IMEs to appear on top.
     */
    z-index: 5;
}

.xterm .xterm-helper-textarea {
    padding: 0;
    border: 0;
    margin: 0;
    /* Move textarea out of the screen to the far left, so that the cursor is not visible */
    position: absolute;
    opacity: 0;
    left: -9999em;
    top: 0;
    width: 0;
    height: 0;
    z-index: -5;
    /** Prevent wrapping so the IME appears against the textarea at the correct position */
    white-space: nowrap;
    overflow: hidden;
    resize: none;
}

.xterm .composition-view {
    /* TODO: Composition position got messed up somewhere */
    background: #000;
    color: #FFF;
    display: none;
    position: absolute;
    white-space: nowrap;
    z-index: 1;
}

.xterm .composition-view.active {
    display: block;
}

.xterm .xterm-viewport {
    /* On OS X this is required in order for the scroll bar to appear fully opaque */
    background-color: #000;
    overflow-y: scroll;
    cursor: default;
    position: absolute;
    right: 0;
    left: 0;
    top: 0;
    bottom: 0;
}

.xterm .xterm-screen {
    position: relative;
}

.xterm .xterm-screen canvas {
    position: absolute;
    left: 0;
    top: 0;
}

.xterm-char-measure-element {
    display: inline-block;
    visibility: hidden;
    position: absolute;
    top: 0;
    left: -9999em;
    line-height: normal;
}

.xterm.enable-mouse-events {
    /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
    cursor: default;
}

.xterm.xterm-cursor-pointer,
.xterm .xterm-cursor-pointer {
    cursor: pointer;
}

.xterm.column-select.focus {
    /* Column selection mode */
    cursor: crosshair;
}

.xterm .xterm-accessibility:not(.debug),
.xterm .xterm-message {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    z-index: 10;
    color: transparent;
    pointer-events: none;
}

.xterm .xterm-accessibility-tree:not(.debug) *::selection {
  color: transparent;
}

.xterm .xterm-accessibility-tree {
  font-family: monospace;
  user-select: text;
  white-space: pre;
}

.xterm .xterm-accessibility-tree > div {
  transform-origin: left;
  width: fit-content;
}

.xterm .live-region {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.xterm-dim {
    /* Dim should not apply to background, so the opacity of the foreground color is applied
     * explicitly in the generated class and reset to 1 here */
    opacity: 1 !important;
}

.xterm-underline-1 { text-decoration: underline; }
.xterm-underline-2 { text-decoration: double underline; }
.xterm-underline-3 { text-decoration: wavy underline; }
.xterm-underline-4 { text-decoration: dotted underline; }
.xterm-underline-5 { text-decoration: dashed underline; }

.xterm-overline {
    text-decoration: overline;
}

.xterm-overline.xterm-underline-1 { text-decoration: overline underline; }
.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }
.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }
.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }
.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }

.xterm-strikethrough {
    text-decoration: line-through;
}

.xterm-screen .xterm-decoration-container .xterm-decoration {
	z-index: 6;
	position: absolute;
}

.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer {
	z-index: 7;
}

.xterm-decoration-overview-ruler {
    z-index: 8;
    position: absolute;
    top: 0;
    right: 0;
    pointer-events: none;
}

.xterm-decoration-top {
    z-index: 2;
    position: relative;
}



/* Derived from vs/base/browser/ui/scrollbar/media/scrollbar.css */

/* xterm.js customization: Override xterm's cursor style */
.xterm .xterm-scrollable-element > .scrollbar {
    cursor: default;
}

/* Arrows */
.xterm .xterm-scrollable-element > .scrollbar > .scra {
	cursor: pointer;
	font-size: 11px !important;
}

.xterm .xterm-scrollable-element > .visible {
	opacity: 1;

	/* Background rule added for IE9 - to allow clicks on dom node */
	background:rgba(0,0,0,0);

	transition: opacity 100ms linear;
	/* In front of peek view */
	z-index: 11;
}
.xterm .xterm-scrollable-element > .invisible {
	opacity: 0;
	pointer-events: none;
}
.xterm .xterm-scrollable-element > .invisible.fade {
	transition: opacity 800ms linear;
}

/* Scrollable Content Inset Shadow */
.xterm .xterm-scrollable-element > .shadow {
	position: absolute;
	display: none;
}
.xterm .xterm-scrollable-element > .shadow.top {
	display: block;
	top: 0;
	left: 3px;
	height: 3px;
	width: 100%;
	box-shadow: var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset;
}
.xterm .xterm-scrollable-element > .shadow.left {
	display: block;
	top: 3px;
	left: 0;
	height: 100%;
	width: 3px;
	box-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;
}
.xterm .xterm-scrollable-element > .shadow.top-left-corner {
	display: block;
	top: 0;
	left: 0;
	height: 3px;
	width: 3px;
}
.xterm .xterm-scrollable-element > .shadow.top.left {
	box-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;
}
/*
YUI 3.18.1 (build f7e7bcb)
Copyright 2014 Yahoo! Inc. All rights reserved.
Licensed under the BSD License.
http://yuilibrary.com/license/
*/

/*
	TODO will need to remove settings on HTML since we can't namespace it.
	TODO with the prefix, should I group by selector or property for weight savings?
*/
html{
	color:#000;
	background:#FFF;
}
/*
	TODO remove settings on BODY since we can't namespace it.
*/
/*
	TODO test putting a class on HEAD.
		- Fails on FF.
*/
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
code,
form,
fieldset,
legend,
input,
textarea,
p,
blockquote,
th,
td {
	margin:0;
	padding:0;
}
table {
	border-collapse:collapse;
	border-spacing:0;
}
fieldset,
img {
	border:0;
}
/*
	TODO think about hanlding inheritence differently, maybe letting IE6 fail a bit...
*/
address,
caption,
cite,
code,
dfn,
em,
strong,
th,
var {
	font-style:normal;
	font-weight:normal;
}

ol,
ul {
	list-style:none;
}

caption,
th {
	text-align:left;
}
h1,
h2,
h3,
h4,
h5,
h6 {
	font-size:100%;
	font-weight:normal;
}
q:before,
q:after {
	content:'';
}
abbr,
acronym {
	border:0;
	font-variant:normal;
}
/* to preserve line-height and selector appearance */
sup {
	vertical-align:text-top;
}
sub {
	vertical-align:text-bottom;
}
input,
textarea,
select {
	font-family:inherit;
	font-size:inherit;
	font-weight:inherit;
	*font-size:100%; /*to enable resizing for IE*/
}
/*because legend doesn't inherit in IE */
legend {
	color:#000;
}

/* YUI CSS Detection Stamp */
#yui3-css-stamp.cssreset { display: none; }
/*
YUI 3.18.1 (build f7e7bcb)
Copyright 2014 Yahoo! Inc. All rights reserved.
Licensed under the BSD License.
http://yuilibrary.com/license/
*/

/* base.css, part of YUI's CSS Foundation */
h1 {
	/*18px via YUI Fonts CSS foundation*/
	font-size:138.5%;
}
h2 {
	/*16px via YUI Fonts CSS foundation*/
	font-size:123.1%;
}
h3 {
	/*14px via YUI Fonts CSS foundation*/
	font-size:108%;
}
h1,h2,h3 {
	/* top & bottom margin based on font size */
	margin:1em 0;
}
h1,h2,h3,h4,h5,h6,strong {
	/*bringing boldness back to headers and the strong element*/
	font-weight:bold;
}
abbr,acronym {
	/*indicating to users that more info is available */
	border-bottom:1px dotted #000;
	cursor:help;
}
em {
	/*bringing italics back to the em element*/
	font-style:italic;
}
blockquote,ul,ol,dl {
	/*giving blockquotes and lists room to breath*/
	margin:1em;
}
ol,ul,dl {
	/*bringing lists on to the page with breathing room */
	margin-left:2em;
}
ol {
	/*giving OL's LIs generated numbers*/
	list-style: decimal outside;
}
ul {
	/*giving UL's LIs generated disc markers*/
	list-style: disc outside;
}
dd {
	/*providing spacing for definition terms*/
	margin-left:1em;
}
th,td {
	/*borders and padding to make the table readable*/
	border:1px solid #000;
	padding:.5em;
}
th {
	/*distinguishing table headers from data cells*/
	font-weight:bold;
	text-align:center;
}
caption {
	/*coordinated margin to match cell's padding*/
	margin-bottom:.5em;
	/*centered so it doesn't blend in to other content*/
	text-align:center;
}
p,fieldset,table,pre {
	/*so things don't run into each other*/
	margin-bottom:1em;
}
/* setting a consistent width, 160px;
   control of type=file still not possible
   *width is for ie7 (no ie6 fallback) */
input[type=text],input[type=password],textarea{width:12.25em;*width:11.9em;}

/* YUI CSS Detection Stamp */
#yui3-css-stamp.cssbase { display: none; }

html, body {
  height: 100%;
}

body {
  max-width: 1140px;
  min-width: 748px;
  margin: 0 auto;
  color: #333;
  font-family: 'Open Sans', sans-serif;
  font-size: 16px;
}

a,
a:visited {
  text-decoration: underline;
  color: black;
}

a:hover {
  color: #999;
}

.title a,
.title a:hover,
.title a:visited {
  text-decoration: none;
  color: black;
}

.wrapper {
  min-height: 100%;
  position: relative;
  margin: 0 auto;
}

.main {
  padding-bottom: 150px;
}

footer {
  position: absolute;
  bottom: 0;
  left: 0;
  margin-bottom: 0;
  margin-left: 0;
  color: #333333;
  width: 100%;
  margin: 2em 0;
  text-transform: uppercase;
  text-align: center;
  font-size: 0.7em;
}

.title {
  font-family: ‘Lucida Console’, Monaco, monospace;
}

.title-shell {
  font-weight: normal;
}

.title-share {
  font-weight: bold;
}

section {
  margin: 4em 0;
}

/* Phones: the desktop min-width would force horizontal panning of the
   whole page; let the layout shrink to the viewport instead */
@media (max-width: 47em) {
  body {
    min-width: 0;
  }

  section {
    margin: 2.5em 0;
  }
}


/* Inconsolata (SIL OFL 1.1), self-hosted. One file covering every
   codepoint the old fonts.googleapis.com stylesheet's latin, latin-ext
   and vietnamese subsets did. It is deliberately NOT unicode-range
   split: the subsets only ever shaved ~16 KB off ASCII sessions, while
   their lazy mid-stream loads fired font `loadingdone` -> a WebGL
   texture-atlas clear that, at fractional devicePixelRatio, repainted
   settled cells as black boxes. One eagerly-loaded face removes that
   whole class of glitch. */
@font-face {
  font-family: 'Inconsolata';
  font-style: normal;
  font-weight: 400;
  src: url('/font/Inconsolata.woff2?v=9cee11b4bac58941') format('woff2');
  font-display: swap;
}

/* Symbols-only Nerd Font fallback: broadcasters' shells often emit Nerd
   Font icons (Private Use Area codepoints) that Inconsolata lacks. The
   browser falls through to this font per-glyph, so text stays in
   Inconsolata and only the icons use it. */
@font-face {
  font-family: 'Symbols Nerd Font';
  src: url('/font/SymbolsNerdFontMono-Regular.woff2?v=a8e2fc5ae3c25258') format('woff2');
  font-display: swap;
}

/* Page chrome follows the broadcast terminal's theme so a dark terminal
   never sits on a blinding white page (and a light theme like
   solarized-light gets a light page). The viewer script derives these
   custom properties from the theme's own background/foreground and sets
   them on <html>; the fallbacks here are the chrome the script computes
   for the default theme (tango), so the page already looks right before
   the first size message lands - no flash, even for the common case of a
   broadcast that took the default theme. The theme can't be known server
   side: this page is rendered once and shared across every room, and the
   theme only arrives later over the WebSocket.
   Scoped to the room page (this stylesheet) - the home page is untouched. */
html {
  background-color: var(--page-bg, #222324);
}

body {
  background-color: var(--page-bg, #222324);
  color: var(--page-fg, #cccccc);
}

/* Animate only live theme changes (the broadcaster re-themes mid-session),
   not the first paint - the initial apply must land instantly so there's
   no fade from the pre-size default into the real theme. */
body.theme-transitions {
  transition: background-color 0.2s ease, color 0.2s ease;
}

/* The fallbacks below are tango's accent (bright blue) and muted tone,
   matching the script's output for the default theme - see above. */
a,
a:visited {
  color: var(--page-accent, #729fcf);
}

a:hover {
  color: var(--page-muted, #787979);
}

.title a,
.title a:hover,
.title a:visited {
  color: var(--page-fg, #cccccc);
}

footer,
footer a,
footer a:visited {
  color: var(--page-muted, #787979);
}

/* div.online, not .online: the broadcast-status span also carries an
   `online` class when the broadcaster is live, and must not match */
div.online {
  order: 1;
  margin-right: 0.5rem;
}

/* Why an encrypted broadcast isn't rendering (missing/wrong key,
   insecure context): a card centred over the terminal, which is
   dimmed behind it to read as disabled. */
.crypto-notice {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;
  max-width: min(90%, 32ch);
  text-align: center;
  background-color: #1c1c1c;
  border: 1px solid #b8860b;
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.6);
  color: #ffd866;
  font-family: 'Inconsolata', monospace;
  line-height: 1.4;
  padding: 1em 1.25em;
}

#terminal.crypto-blocked .xterm {
  filter: blur(2px);
  opacity: 0.3;
  pointer-events: none;
}

.broadcast-status::before {
  content: "\25CF"; /* ● */
  /* Empty alt text: the visually hidden text inside the span carries
     the meaning, so screen readers shouldn't announce "black circle".
     Browsers without the alt syntax fall back to the line above. */
  content: "\25CF" / "";
  margin-right: 0.3em;
  color: #999;
}

.broadcast-status.online::before {
  color: #2ecc40;
}

.broadcast-status.offline::before {
  color: #cc4030;
}

/* Present for screen readers, invisible on screen */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  text-align: left;
}

/* Phones: pad the page chrome so it doesn't touch the screen edges.
   #terminal stays full-bleed on purpose - every pixel of width is a
   terminal column, and it scrolls horizontally when the broadcaster's
   grid is wider than the viewport. */
@media (max-width: 47em) {
  header {
    flex-wrap: wrap;
    padding: 0 0.75em;
  }

  footer {
    box-sizing: border-box;
    padding: 0 1em;
  }
}

.title {
  font-size: 2em;
  margin: 0;
}

/* The terminal itself (font, colors, sizing) is fully driven by
   xterm.js options in the viewer script; the container only frames
   it. Terminals wider than the page scroll horizontally instead of
   wrapping or clipping. */
#terminal {
  position: relative;
  background-color: black;
  padding: 5px;
  overflow-x: auto;
}

/* Hide the scrollback scrollbar: xterm handles wheel and touch
   scrolling itself, the native scrollbar is only a visual mirror
   (and Chrome draws it with the ugly default chrome) */
#terminal .xterm-viewport {
  scrollbar-width: none;
}

#terminal .xterm-viewport::-webkit-scrollbar {
  display: none;
}

/* Fullscreen toggle: hidden until the terminal is hovered or the
   button is focused */
#fullscreen-toggle {
  position: absolute;
  top: 8px;
  right: 8px;
  /* Must outrank xterm's pointer-capturing overlays, which share this
     stacking context: the link-layer canvas (z-index 2) and the helper
     textarea (z-index 5) both span the terminal and would otherwise win
     the hit-test for a tap landing on the button. A bare z-index: 2 tied
     the link layer, so which one received the tap was render-order
     dependent - it worked under one renderer and silently failed under
     another (e.g. the canvas fallback on GPU-less CI). Parked far above
     anything xterm uses so a future layer can't quietly tie it again. */
  z-index: 9999;
  width: 44px;
  height: 44px;
  padding: 11px;
  border: 0;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.45);
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease;
}

#terminal:hover #fullscreen-toggle,
#fullscreen-toggle:focus-visible {
  opacity: 1;
}

/* Touch devices have no hover to reveal the button: keep it visible
   at rest */
@media (hover: none) {
  #fullscreen-toggle {
    opacity: 0.5;
  }
}

/* While fullscreen the button must stay reachable: touch devices have
   no hover (and the iOS fallback has no other way out), and the
   viewport anchoring keeps it in place when an oversized terminal
   scrolls */
#terminal.fullscreen #fullscreen-toggle {
  position: fixed;
  opacity: 0.4;
}

#terminal.fullscreen #fullscreen-toggle:hover,
#terminal.fullscreen #fullscreen-toggle:focus-visible {
  opacity: 1;
}

#fullscreen-toggle:hover {
  background: rgba(0, 0, 0, 0.7);
}

#fullscreen-toggle svg {
  display: block;
  width: 100%;
  height: 100%;
}

#fullscreen-toggle .icon-compress {
  display: none;
}

#terminal.fullscreen .icon-expand {
  display: none;
}

#terminal.fullscreen .icon-compress {
  display: block;
}

/* Fullscreen layout, driven by the class so it works both under the
   native Fullscreen API and as a fill-the-page fallback */
#terminal.fullscreen {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;
  overflow: auto;
  /* No padding while fullscreen: the viewer's font-fit measures the
     grid against the container's clientWidth/Height, which include
     padding, so restoring it would reintroduce overflow the fit loop
     then eats on every pass */
  padding: 0;
}

/* Immersive entry affordance for touch devices. Out of fullscreen, the
   whole terminal becomes one tap target with a centered prompt: the
   viewer sees a small fit-to-width preview (all columns visible, set by
   the viewer script) and taps to enter the readable landscape view. On
   touch this REPLACES the corner toggle as the entry point; the toggle
   returns inside fullscreen as the way out. Hidden on fine-pointer
   (desktop) devices, where hover + the corner toggle already work. */
#immersive-overlay {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 10;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1rem;
  border: 0;
  background: linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.55));
  color: rgba(255, 255, 255, 0.95);
  font-family: 'Open Sans', sans-serif;
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

#immersive-overlay .io-icon {
  box-sizing: border-box;
  width: 64px;
  height: 64px;
  padding: 14px;
  border: 2px solid rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
}

#immersive-overlay .io-label {
  font-size: 1.05rem;
  font-weight: 600;
}

#immersive-overlay .io-sub {
  margin-top: -0.4rem;
  font-size: 0.8rem;
  opacity: 0.8;
}

/* Rotate nudge: the honest fallback when we can't lock orientation
   (iOS, or Android where the lock was refused). Shown only while
   fullscreen AND the device is still portrait, so it disappears the
   instant the viewer rotates - no JS polling needed. */
#rotate-nudge {
  display: none;
  position: fixed;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 101;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  font-family: 'Open Sans', sans-serif;
  font-size: 0.85rem;
  padding: 0.5em 0.9em;
  border-radius: 999px;
}

@media (pointer: coarse) {
  #terminal:not(.fullscreen) #immersive-overlay {
    display: flex;
  }

  #terminal:not(.fullscreen) #fullscreen-toggle {
    display: none;
  }
}

@media (pointer: coarse) and (orientation: portrait) {
  #terminal.fullscreen #rotate-nudge {
    display: block;
  }
}

/* Already landscape: the preview fits the whole grid on screen (viewer
   script) and the "rotate to landscape" hint no longer applies, so drop
   it and leave just the tap-to-watch label. */
@media (pointer: coarse) and (orientation: landscape) {
  #immersive-overlay .io-sub {
    display: none;
  }
}

/* A blocked encrypted broadcast shows its explanatory notice instead;
   don't cover it with the tap-to-watch prompt. */
#terminal.crypto-blocked #immersive-overlay {
  display: none;
}
