/* cocks.io web chat — theme "cocks" for The Lounge 4.5.2.
 *
 * Loaded as `themes/cocks.css` via the `theme` config value. Discovery is
 * server/plugins/packages/themes.ts `loadLocalThemes()`, which readdirs
 * `<app>/public/themes/`, so this file is a real theme with no fork.
 *
 * Design language is taken from the cocks.io ZNC landing skin
 * (znc/skin/pub/main.css) and delta.cocks.io/style.css, which share one system:
 *
 *   --bg       #0a0a0c   near-black, slightly blue
 *   --raised   #121215   inputs, form chrome
 *   --inset    #141417   inline code, recessed blocks
 *   --line     #222227   hairline borders
 *   --line-2   #2a2a30   input borders
 *   --ink      #e8e6e1   body text (warm off-white)
 *   --ink-dim  #a7a6a1   muted body text
 *   --ink-mut  #63636b   uppercase mono eyebrows/labels
 *   --brand    #ff6a1a   THE single accent, used for focus + active only
 *
 * Type: Space Grotesk for UI, JetBrains Mono for every label, channel name,
 * timestamp and input value. Upstream ships -apple-system/Segoe UI at
 * 14px/16px; that is the single biggest reason this skin read as a generic
 * IRC client rather than cocks.io.
 *
 * SPECIFICITY NOTE (this is the bug that made the old skin look broken):
 * upstream bundles `.input{color:#222;background-color:#fff;…}` — a CLASS
 * selector, specificity (0,1,0). A theme rule targeting the bare element
 * (`input`, specificity 0,0,1) LOSES, so every connect-form field stayed
 * white-on-dark-junk while the surrounding chrome was dark. That is why the
 * live page showed white boxes on a black background. Every control rule below
 * therefore targets the CLASS (`.input`, `.btn`, …) or a compound
 * `#id .class` selector, never the bare element.
 */

/* ------------------------------------------------------------------ fonts -- */
/* Self-hosted WOFF2-free: The Lounge serves /fonts, but a theme CSS cannot add
 * binary files, so we use the same two families the cocks.io skin uses and let
 * the system fall back. JetBrains Mono ships on most desktops; Space Grotesk
 * is the display face. Both are listed with wide fallbacks so a missing font
 * degrades to the system mono rather than to a serif. */
@font-face {
	font-family: "cocks Sans";
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: local("Space Grotesk"), local("SpaceGrotesk");
	/* No remote src: the theme file must stay a single self-contained .css so it
	 * can be dropped into public/themes/ without a paired font directory. The
	 * families below fall back to the system stack. */
}

/* ---------------------------------------------------------------- palette -- */
:root {
	/* Text */
	--body-color: #e8e6e1;
	--body-color-muted: #a7a6a1;

	/* Chrome */
	--body-bg-color: #0a0a0c;
	--overlay-bg-color: rgb(0 0 0 / 78%);

	/* Surfaces */
	--window-bg-color: #0a0a0c;
	--form-bg-color: #121215;

	/* The one signal colour. cocks orange: focus, active, nothing else. */
	--button-color: #ff6a1a;
	--button-text-color-hover: #0a0a0c;
	--link-color: #ff8c42;
	--upload-progressbar-color: #ff6a1a;

	--window-heading-color: #63636b;
	--date-marker-color: rgb(255 106 26 / 30%);
	--unread-marker-color: rgb(255 106 26 / 16%);
	--highlight-bg-color: rgb(255 106 26 / 9%);
	--highlight-border-color: #ff6a1a;

	/* House tokens, mirroring the ZNC skin so both surfaces stay in step */
	--cocks-bg: #0a0a0c;
	--cocks-raised: #121215;
	--cocks-inset: #141417;
	--cocks-line: #222227;
	--cocks-line-2: #2a2a30;
	--cocks-ink: #e8e6e1;
	--cocks-ink-dim: #a7a6a1;
	--cocks-ink-mut: #63636b;
	--cocks-brand: #ff6a1a;
	--cocks-brand-hi: #ff8c42;

	/* Semantic colours.
	 *
	 * With only the ink greys and the brand orange, every kind of event looked
	 * the same: a join, a notice, an error and a warning were all orange or
	 * all grey, so the eye had nothing to separate them by. The slot page
	 * solves this with a second signal colour and it is the reason that page
	 * reads as composed rather than as a black field with orange in it.
	 *
	 * These are the slot page's own values, so the two surfaces speak the
	 * same visual language:
	 *
	 *   --cyan    notices, the "someone said something" colour
	 *   --green   confirmations, joins, "this worked"
	 *   --amber   warnings, the things that need attention but are not errors
	 *   --red     errors, refusals, anything that failed
	 */
	--cocks-cyan: #22d3ee;
	--cocks-green: #34d399;
	--cocks-amber: #f59e0b;
	--cocks-red: #ef6661;

	/* The glass and the radii are the slot page's own values, so the two
	 * surfaces read as one estate rather than as two separate products. */
	--cocks-glass: rgba(27, 27, 38, 0.55);
	--cocks-glass-strong: rgba(27, 27, 38, 0.78);
	--cocks-r-sm: 10px;
	--cocks-r: 16px;
	--cocks-r-lg: 22px;
	--cocks-shadow: 0 18px 48px -24px rgba(0, 0, 0, 0.9);

	--cocks-sans: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI",
		Roboto, Helvetica, Arial, sans-serif;
	--cocks-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono",
		Menlo, Consolas, "Liberation Mono", "DejaVu Sans Mono", monospace;
}

/* ------------------------------------------------------------------ type -- */
/* Upstream sets -apple-system/16px on body. cocks.io is a mono-labelled
 * terminal: labels, headings, nicks and values are monospace, prose is not. */
body {
	font-family: var(--cocks-sans);
	font-size: 14px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}

/* Every heading is a small uppercase mono eyebrow, never a 36px display size.
 * The old skin left `h1.title` at upstream 36px, which shouted on a page that
 * is otherwise a terminal. */
.window h1,
.window h2,
#connect .title,
#settings h2,
h1,
h2 {
	font-family: var(--cocks-mono);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 2.5px;
	text-transform: uppercase;
	color: var(--cocks-ink-mut);
	margin: 0;
	line-height: 1;
}

/* A TYPE SCALE, not one size for every heading.
 *
 * Every heading on the page was the same 11px mono eyebrow, so a section
 * title and a form section title looked identical and the eye had nothing
 * to hold on to. The slot page solves this with `clamp()`, which scales
 * with the viewport instead of jumping at a breakpoint - the same approach,
 * the same values.
 *
 *   h1  the page title      30px .. 54px
 *   h2  a section heading   20px .. 26px
 *   h3  a subsection        16px .. 18px
 *
 * The eyebrows stay 11px where they are labels rather than headings - a
 * mono label is a different thing from a heading, and shrinking it further
 * would only make it harder to read.
 */
.window h1,
h1 {
	font-size: clamp(30px, 5.4vw, 54px);
	font-weight: 700;
	letter-spacing: -0.03em;
	text-transform: none;
	color: var(--cocks-ink);
	line-height: 1.05;
}

.window h2,
h2 {
	font-size: clamp(20px, 3vw, 26px);
	font-weight: 700;
	letter-spacing: -0.02em;
	text-transform: none;
	color: var(--cocks-ink);
	line-height: 1.2;
}

.window h3,
h3 {
	font-size: clamp(16px, 2.2vw, 18px);
	font-weight: 600;
	letter-spacing: -0.01em;
	text-transform: none;
	color: var(--cocks-ink-dim);
	line-height: 1.3;
}

/* The page title is the one exception: it carries the brand, so it gets the
 * display face, real size, and the accent colour. */
#connect h1.title,
#connect .title {
	font-family: var(--cocks-sans);
	font-size: clamp(30px, 5.4vw, 54px);
	font-weight: 700;
	letter-spacing: -0.03em;
	text-transform: none;
	color: var(--cocks-ink);
}

label,
.connect-row label,
.check-label {
	font-family: var(--cocks-mono);
	font-size: 11px;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--cocks-ink-mut);
}

/* Field VALUES are mono — this is what makes the form read as a terminal
 * rather than as a web form. */
.input,
input.input,
#connect .input,
#settings .input {
	font-family: var(--cocks-mono);
	font-size: 13px;
	color: var(--cocks-ink);
}

/* --------------------------------------------------------------- surfaces -- */
.window,
#connect,
#settings,
.card {
	background-color: var(--cocks-bg);
	border: 1px solid var(--cocks-line);
	border-radius: 0;
	box-shadow: none;
}

/* THE CONNECT WINDOW IS A COMPOSED PANEL, NOT A FULL-WIDTH STRIP.
 *
 * Measured before this change: `#connect` was 1220px wide at a 1440px
 * viewport, with the form sitting in 560px of it. The result was a page that
 * was mostly empty black, with a narrow form floating in the middle of it -
 * the thing that reads as "the chat window is broken".
 *
 * The panel now takes the form's width and sits in the middle of the viewport
 * with the ambient blobs behind it. The ambient blobs are on the BODY, so the
 * window has to be transparent for them to be visible at all - that is why
 * `#connect` does not paint its own background here.
 *
 * The glass and the shadow are the slot page's own values, so the two
 * surfaces read as one estate.
 */
#connect,
#settings {
	background: transparent;
	border: none;
	box-shadow: none;
	padding: 24px;
}

/* The panel is the form, and it is centred in the window.
 *
 * `margin: auto` on the form, in a block container, centres it both ways
 * without touching the window's own layout. The alternative - making the
 * window a flex container with `align-items: center` - moves the window's
 * `.header` (which holds the sidebar toggle, the burger button) into the flex
 * flow, and the header stops being a header: it ends up beside the form
 * instead of above it, and the burger button lands in the middle of the page.
 *
 * So the window stays a block, exactly as upstream has it, and only the form
 * is centred.
 */
#connect .container,
#settings .container {
	background: var(--cocks-glass, rgba(27, 27, 38, 0.55));
	-webkit-backdrop-filter: blur(20px) saturate(1.4);
	backdrop-filter: blur(20px) saturate(1.4);
	border: 1px solid var(--cocks-line);
	border-radius: var(--cocks-r-lg, 22px);
	box-shadow: 0 18px 48px -24px rgba(0, 0, 0, 0.9),
		inset 0 1px 0 rgba(255, 255, 255, 0.09);
	color: var(--cocks-ink);
	margin: auto;
}

/* Without backdrop-filter the glass is a translucent panel over a dark
 * background, which is unreadable. The fallback is an opaque one. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	#connect .container,
	#settings .container {
		background: #14141c;
	}
}

#sidebar {
	background-color: #0e0e11;
	border-right: 1px solid var(--cocks-line);
}

#chat {
	background-color: var(--cocks-bg);
}

#connect .header,
#settings .header,
.window .header {
	background-color: transparent;
	border-bottom: 1px solid var(--cocks-line);
}

/* The Lounge wordmark and the vertical logo are upstream branding. The
 * cocks.io brand is the window title, so both are dropped. */
#logo,
.logo,
.logo-inverted,
#loading .logo,
#loading .logo-inverted {
	display: none;
}

#loading .window {
	border: none;
	background-color: var(--cocks-bg);
}

/* ------------------------------------------------------------------ forms -- */
/* CLASS-first, never bare-element: see the specificity note at the top. */
.input,
#connect .input,
#settings .input,
#search-container .input {
	color: var(--cocks-ink) !important;
	background-color: var(--cocks-raised) !important;
	border: 1px solid var(--cocks-line-2) !important;
	border-radius: 0 !important;
	height: 34px;
	line-height: 34px;
	margin: 0 0 8px;
	padding: 0 12px;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.input:focus,
#connect .input:focus,
#settings .input:focus,
textarea#input:focus {
	outline: none;
	border-color: var(--cocks-brand) !important;
	box-shadow: 0 0 0 3px rgb(255 106 26 / 15%) !important;
}

.input::placeholder,
textarea#input::placeholder {
	color: #55555c;
}

.input:disabled,
.input[readonly] {
	color: var(--cocks-ink-mut) !important;
	background-color: #0e0e11 !important;
}

/* Checkboxes / radios: accent-coloured, square, matching the ZNC skin. */
#connect input[type="checkbox"],
#settings input[type="checkbox"],
#connect input[type="radio"],
#settings input[type="radio"] {
	appearance: none;
	-webkit-appearance: none;
	width: 14px;
	height: 14px;
	margin: 0 8px 0 0;
	border: 1px solid var(--cocks-line-2);
	background-color: var(--cocks-raised);
	cursor: pointer;
	flex: none;
}

#connect input[type="checkbox"]:checked,
#settings input[type="checkbox"]:checked,
#connect input[type="radio"]:checked,
#settings input[type="radio"]:checked {
	border-color: var(--cocks-brand);
	background-color: var(--cocks-brand);
}

#connect label.tls,
#settings label.tls,
#connect .check-label {
	display: flex;
	align-items: center;
	font-family: var(--cocks-mono);
	font-size: 11px;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--cocks-ink-dim);
}

/* Row rhythm: the upstream 2px/10px margins make the form float. One line
 * height between rows, label above value, reads as a terminal block. */
#connect .container,
#settings .container {
	padding: 28px 32px 32px;
	max-width: 560px;
}

.connect-row {
	display: flex;
	align-items: center;
	margin: 0 0 6px;
}

.connect-row > label {
	flex: none;
	width: 116px;
	padding-right: 12px;
}

.connect-row .input-wrap {
	display: flex;
	align-items: center;
	flex: 1;
	min-width: 0;
}

.input-wrap .input {
	margin-bottom: 0;
}

#connect:portseparator,
#connect .port-separator {
	color: var(--cocks-ink-mut);
	padding: 0 6px;
	font-family: var(--cocks-mono);
}

#connect h2 {
	margin: 28px 0 12px;
	padding-bottom: 8px;
	border-bottom: 1px solid var(--cocks-line);
	color: var(--cocks-brand);
}

/* ---------------------------------------------------------------- buttons -- */
.btn,
#connect .btn,
#settings .btn,
button,
.button {
	font-family: var(--cocks-mono);
	font-size: 12px;
	letter-spacing: 2px;
	text-transform: uppercase;
	border-radius: 0;
	background-color: transparent;
	color: var(--cocks-ink-dim);
	border: 1px solid var(--cocks-line-2);
	padding: 9px 18px;
	cursor: pointer;
	transition: border-color 0.15s, color 0.15s, background-color 0.15s;
}

.btn:hover,
button:hover,
.button:hover {
	color: var(--cocks-ink);
	border-color: var(--cocks-ink-mut);
}

#connect .btn,
#connect .container > div:last-child .btn,
#connect button.btn {
	background-color: var(--cocks-brand);
	color: var(--cocks-bg);
	border: 1px solid var(--cocks-brand);
	font-weight: 600;
	width: 100%;
	margin-top: 20px;
	padding: 12px 18px;
}

#connect .btn:hover,
#connect button.btn:hover {
	background-color: var(--cocks-brand-hi);
	border-color: var(--cocks-brand-hi);
	color: var(--cocks-bg);
}

/* The secondary/cancel button stays quiet. */
#connect .btn-cancel,
#connect .btn-cancel:hover {
	background-color: transparent;
	color: var(--cocks-ink-mut);
	border: 1px solid var(--cocks-line);
}

/* ------------------------------------------------------------ icon buttons -- */
/* The top-left menu / settings / help buttons are FontAwesome glyphs: colour
 * and box them like the rest of the chrome, no rounded blue-grey default. */
.lt,
#connect .header .lt,
.icon,
#sidebar .lt {
	background-color: transparent;
	color: var(--cocks-ink-dim);
	border: 0;
	border-radius: 0;
}

.lt:hover,
#connect .header .lt:hover,
.icon:hover {
	background-color: rgb(255 106 26 / 12%);
	color: var(--cocks-brand);
}

button.icon.connect.active,
#sidebar .connect.active {
	background-color: var(--cocks-brand);
	color: var(--cocks-bg);
}

/* --------------------------------------------------------------- sidebar -- */
#channel-list .network,
#channel-list .channel {
	font-family: var(--cocks-mono);
	font-size: 13px;
	border-radius: 0;
	padding: 3px 8px;
}

#channel-list .channel.active,
#channel-list .network.active {
	background-color: rgb(255 106 26 / 14%);
	color: var(--cocks-ink);
}

#channel-list .channel.unread,
#channel-list .network.unread {
	font-weight: 600;
}

#channel-list .channel.unread strong,
#channel-list .network.unread strong {
	color: var(--cocks-brand);
}

#channel-list .network .network-name,
#channel-list .channel .channel-name {
	font-family: var(--cocks-mono);
	letter-spacing: 0.5px;
}

/* ----------------------------------------------------------------- chat -- */
#viewport {
	padding: 0;
}

.window {
	border-radius: 0;
	box-shadow: none;
}

/* Message text: the only prose on the page, so it keeps the sans face. */
.msg .text,
.msg .from,
#chat .text {
	font-family: var(--cocks-sans);
	font-size: 14px;
	line-height: 1.5;
}

/* Nicks, channels, times, tags: mono, small, tabular. */
.time,
.userlist .user--mode .user-name,
.userlist .user-name,
.msg .from,
#chat .channel-name,
.tg,
.irc-formatted-prefix {
	font-family: var(--cocks-mono);
	font-variant-numeric: tabular-nums;
	font-size: 13px;
}

.time {
	color: var(--cocks-ink-mut);
}

.userlist .user-name {
	color: var(--cocks-ink-dim);
}

.msg--own .text {
	color: #fff;
}

.msg--highlight,
.msg--search,
.msg--highlight:hover {
	background-color: var(--cocks-highlight-bg, rgb(255 106 26 / 9%));
	box-shadow: inset 2px 0 0 var(--cocks-brand);
	color: var(--cocks-ink);
}

.msg .from {
	color: var(--cocks-brand-hi);
}

/* Unread / mention counters */
.userlist .user--mode + .user-badge,
#channel-list .badge {
	background-color: var(--cocks-brand);
	color: var(--cocks-bg);
	font-family: var(--cocks-mono);
	border-radius: 0;
}

/* ------------------------------------------------------------- input bar -- */
#input-container {
	background-color: var(--cocks-bg);
	border-top: 1px solid var(--cocks-line);
	padding: 0;
}

textarea#input,
#input-container textarea {
	background-color: var(--cocks-raised);
	color: var(--cocks-ink);
	border: 1px solid var(--cocks-line-2);
	border-radius: 0;
	font-family: var(--cocks-mono);
	font-size: 13px;
	line-height: 1.5;
	padding: 10px 12px;
	resize: none;
}

textarea#input:focus {
	border-color: var(--cocks-brand);
	box-shadow: none;
	outline: none;
}

#form .form-footer,
#form {
	background-color: var(--cocks-bg);
}

#search-container input,
#search form {
	background-color: var(--cocks-raised);
	color: var(--cocks-ink);
}

/* ------------------------------------------------------------------ misc -- */
/* The reconnect / close buttons and any other upstream default button. */
#connect .btn-cancel,
.settings .btn,
.close {
	background-color: transparent;
	color: var(--cocks-ink-mut);
	border: 1px solid var(--cocks-line);
}

a,
#connect a,
#settings a {
	color: var(--cocks-brand);
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

/* Scrollbars: thin, dark, orange thumb on hover. */
::-webkit-scrollbar {
	width: 10px;
	height: 10px;
}

::-webkit-scrollbar-track {
	background: var(--cocks-bg);
}

::-webkit-scrollbar-thumb {
	background: #222227;
	border: 2px solid var(--cocks-bg);
}

::-webkit-scrollbar-thumb:hover {
	background: var(--cocks-brand);
}

/* Focus ring: one consistent accent everywhere. */
:focus-visible {
	outline: 2px solid var(--cocks-brand);
	outline-offset: 1px;
}

/* ---------- cocks.io portal nav (injected into #footer by ck-portal-nav.js) ---------- */
/* The Lounge renders its footer at runtime and has no config key for extra
   links, so the row is appended by script and styled here. Same palette and
   type as the rest of the skin: mono, small, uppercase, one orange accent.
   `height: auto` is load-bearing: upstream pins #footer to a flat 45px, and the
   nav + Monero chip are ~85px, so with the fixed height the chip was laid out
   below the footer's own box and clipped at the bottom of the viewport. */
#footer {
	flex-wrap: wrap !important;
	height: auto !important;
	min-height: 45px;
}

.ck-portal {
	display: flex !important;
	flex-wrap: wrap !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 7px !important;
	/* The app's #footer is display:flex; flex-direction:row with the icon bar
	   as its children. flex-wrap:wrap + flex-basis:100% is what puts this row
	   ABOVE the icons without pushing them out of the bar; a 100%-basis child
	   in a nowrap row instead stretches the footer and shifts the icons left. */
	flex: 1 0 100% !important;
	width: 100% !important;
	order: -1 !important;
	margin: 0 0 8px !important;
	padding: 0 0 8px !important;
	border-bottom: 1px solid var(--cocks-line, #222227) !important;
	font-family: "JetBrains Mono", ui-monospace, monospace !important;
	font-size: 10.5px !important;
	line-height: 1 !important;
	letter-spacing: 1.4px !important;
	text-transform: uppercase !important;
	text-align: center !important;
}
.ck-portal a,
.ck-portal a:link,
.ck-portal a:visited {
	color: #8a8a94 !important;
	text-decoration: none !important;
	transition: color .15s ease !important;
}
.ck-portal a:hover,
.ck-portal a:focus-visible {
	color: var(--cocks-brand, #ff6a1a) !important;
}
.ck-portal a:focus-visible {
	outline: 2px solid var(--cocks-brand, #ff6a1a) !important;
	outline-offset: 2px !important;
}
.ck-portal-sep { color: #3a3a42 !important; }
/* ============================================================ APPEND: cocks.io
 * 30.09.2026 — Toti's round-2 complaints, one section each.
 * Appended rather than edited so every previous rule is preserved verbatim and
 * a revert is a single `head -n <line>`.
 *
 * Measurement discipline used throughout: every colour below was checked with
 * the WCAG relative-luminance formula against the surface it actually sits on.
 * Values are quoted inline as "ratio on #0a0a0c".
 */

/* ---------------------------------------------------------------------------
 * 1) "die server messages sind weiss"
 *
 * This was NOT a missing rule. Upstream hardcodes light-on-light for the
 * server/system message surfaces and a theme can only win by out-specifying
 * it, so each upstream declaration is quoted with its real value:
 *
 *   #chat .msg-statusmsg                  { color:#222; background:#ff9e18 }
 *   #chat .msg[data-type=monospace_block] .text { background:#f6f6f6 }
 *   #chat .toggle-content                 { background:#f6f6f6 }
 *   pre                                   { color:#333; background:#f5f5f5 }
 *   #chat .userlist .count                { background:#fafafa }
 *   #chat .msg.channel_list_loading .text { color:#999 }
 *   #chat .msg.channel_list_truncated .text { color:red }
 *   #settings .settings-sync-panel / #version-checker.*  { color:#31708f; background:#d9edf7 }
 *   #connect .connect-sasl-external       { color:#31708f; background:#d9edf7 }
 *   kbd                                   { color:#444; background:#fff }
 *   .context-menu / .textcomplete-menu    { background:#fff }
 *   .context-menu-item / .textcomplete-item { color:#333 }
 *   .channel-list-item .badge            { color:#afb6c0; background:#ffffff0f }
 *   .channel-list-item .badge.highlight  { color:#49505a; background:#fff }
 *
 * The MOTD arrives as data-type="monospace_block" (confirmed on the live
 * socket), which is why the channel welcome screen rendered as a white slab on
 * a near-black page. That is the specific thing Toti saw.
 * ------------------------------------------------------------------------ */

/* The status/notice pill: orange slab -> recessed cocks block.
 * #ff8c42 on #1c1409 = 7.87, was #222 on #ff9e18 = 7.69. Same legibility,
 * house palette, and it stops being a bright rectangle in a dark UI. */
#chat .msg-statusmsg,
#chat .msg-shown-in-active {
	color: var(--cocks-brand-hi) !important;
	background-color: #1c1409 !important;
	border: 1px solid rgb(255 106 26 / 28%);
	border-radius: 0;
	padding: 2px 5px;
}

/* The MOTD / paste block. This is the white slab. */
#chat .msg[data-type="monospace_block"] .text,
#chat .msg[data-type="monospace_block"] .content {
	background-color: var(--cocks-inset) !important;
	color: var(--cocks-ink) !important;
	border: 1px solid var(--cocks-line);
	border-left: 2px solid var(--cocks-brand);
	border-radius: 0;
	box-shadow: none;
}

/* "condensed" expansion of a join/part run. */
#chat .toggle-content {
	background: var(--cocks-inset) !important;
	border: 1px solid var(--cocks-line);
	border-radius: 0;
	color: var(--cocks-ink) !important;
}

/* The unread/"show more" counter badge. Verified white live: rgb(250,250,250). */
#chat .userlist .count {
	background: var(--cocks-raised) !important;
	color: var(--cocks-ink-mut);
	border-left: 1px solid var(--cocks-line);
}
#chat .count::before {
	color: var(--cocks-ink-mut) !important;
}

/* Inline code, <pre>, <code> and the custom-CSS textarea. */
#chat pre,
#chat code,
pre,
code,
#chat .msg .text pre,
.irc-monospace,
textarea#user-specified-css-input {
	background-color: var(--cocks-inset) !important;
	color: var(--cocks-ink) !important;
	border: 1px solid var(--cocks-line);
	border-radius: 0;
	box-shadow: none;
}

/* Keyboard-shortcut keys on the Help page. */
#help kbd,
kbd {
	color: var(--cocks-ink) !important;
	background-color: var(--cocks-raised) !important;
	background-image: none !important;
	text-shadow: none !important;
	border: 1px solid var(--cocks-line-2) !important;
	border-radius: 0;
	box-shadow: none;
	min-width: 22px;
}

/* Channel-list "loading" / "truncated" system lines. */
#chat .msg.channel_list_loading .text {
	color: var(--cocks-ink-mut) !important;
}
#chat .msg.channel_list_truncated .text {
	color: var(--cocks-brand-hi) !important;
}

/* Informational panels (SASL-EXTERNAL note, update banner, sync panel). */
#connect .connect-sasl-external,
#settings .settings-sync-panel,
#version-checker.loading,
#version-checker.error,
#version-checker.up-to-date {
	color: var(--cocks-ink-dim) !important;
	background-color: var(--cocks-raised) !important;
	border: 1px solid var(--cocks-line-2) !important;
	border-left: 2px solid var(--cocks-brand) !important;
	border-radius: 0;
}
#version-checker.up-to-date {
	border-left-color: #5fd97a;
}

/* Context menu / autocompletion popups.
 *
 * THE SELECTOR IS THE BUG. Upstream's rule is
 *
 *   #context-menu, .mentions-popup, .textcomplete-menu { background-color:#fff }
 *
 * and the element the client actually renders is
 *
 *   f(`ul`, { id:`context-menu`, ref:`contextMenu`, role:`menu`, ... })
 *
 * - it carries the ID and NO class at all. So a theme rule for
 * `.context-menu` never matches it, and the menu keeps upstream's white
 * background with the theme's near-white text on it: white-on-white, and
 * unreadable.
 *
 * Measured live before the fix: `ul#context-menu` computed to
 * `background-color: rgb(255, 255, 255)` while its text was
 * `rgb(232, 230, 225)`.
 *
 * So the ID has to be in the selector. The class stays for the other two
 * popups, which do carry it.
 */
#context-menu,
.context-menu,
.mentions-popup,
.textcomplete-menu {
	background-color: var(--cocks-raised) !important;
	border: 1px solid var(--cocks-line-2) !important;
	border-radius: 0;
	box-shadow: 0 6px 24px rgb(0 0 0 / 60%);
	color: var(--cocks-ink);
}

.context-menu-item,
.textcomplete-item {
	color: var(--cocks-ink) !important;
	border-radius: 0;
}
.context-menu-item:hover,
.context-menu-item.active,
.textcomplete-item:hover,
.textcomplete-item.active,
.textcomplete-item:focus {
	background-color: rgb(255 106 26 / 14%) !important;
	color: var(--cocks-ink) !important;
}
.textcomplete-item a {
	color: var(--cocks-ink) !important;
}

/* ---------------------------------------------------------------------------
 * THE IRC COLOUR CODES.
 *
 * Upstream ships the full mIRC palette as 198 rules - `.irc-bg0` through
 * `.irc-bg98` and the same for `.irc-fg`. Most of them are fine on a dark
 * background, but the LIGHT ones are not: `.irc-bg0` is `background: #fff`
 * and `.irc-bg98` is `background-color: #fff`, so a message carrying colour
 * code 0 or 98 renders as a white BLOCK on the dark chat.
 *
 * That is the "the menu is white" report. It is not a menu at all: it is an
 * IRC message with a light background colour, and the message text then sits
 * in upstream's light-on-light default.
 *
 * The fix has two halves, and the second is the one that matters:
 *
 *   1. the light backgrounds become the theme's raised surface, so a light
 *      colour code no longer produces a white block;
 *   2. the text on them becomes the theme's ink, because upstream's
 *      `.irc-fg0 { color: #000 }` on a light background is exactly the
 *      light-on-light that this theme exists to remove.
 *
 * The dark and mid-tone codes are left alone. They read fine on the dark
 * chat, and re-mapping 198 colours to a four-colour palette would throw away
 * the channel's own colour coding.
 * ------------------------------------------------------------------------- */

/* The light backgrounds: white, near-white and the light greys. */
.irc-bg0,
.irc-bg15,
.irc-bg89,
.irc-bg90,
.irc-bg91,
.irc-bg92,
.irc-bg93,
.irc-bg94,
.irc-bg95,
.irc-bg96,
.irc-bg97,
.irc-bg98 {
	background-color: var(--cocks-raised) !important;
}

/* And the text that upstream paints on them. */
.irc-fg0,
.irc-fg15,
.irc-fg89,
.irc-fg90,
.irc-fg91,
.irc-fg92,
.irc-fg93,
.irc-fg94,
.irc-fg95,
.irc-fg96,
.irc-fg97,
.irc-fg98 {
	color: var(--cocks-ink) !important;
}

/* The mid-light greys upstream uses as a foreground are too dim to read on
 * the dark surface - 1.6:1 against #0a0a0c, where the ink is 15.6:1. */
.irc-fg88,
.irc-fg89,
.irc-fg90,
.irc-fg91,
.irc-fg92 {
	color: var(--cocks-ink-dim) !important;
}

/* Sidebar badge: white text on a nearly transparent white wash. */
.channel-list-item .badge {
	color: var(--cocks-ink) !important;
	background: rgb(255 106 26 / 22%) !important;
	border-radius: 0;
}
.channel-list-item .badge.highlight {
	color: var(--cocks-bg) !important;
	background: var(--cocks-brand) !important;
}
#channel-list .badge {
	background-color: var(--cocks-brand);
	color: var(--cocks-bg);
	border-radius: 0;
}

/* Search box in the sidebar: measured rgb(183,197,209) inherited from upstream
 * #415364 -- a cold blue-grey, off-palette, and far brighter than anything
 * else in the cocks sidebar. */
#channel-list .search,
#channel-list .jump-to-input input,
#channel-search-input {
	color: var(--cocks-ink) !important;
	background-color: var(--cocks-raised) !important;
	border: 1px solid var(--cocks-line-2) !important;
	border-radius: 0;
}
#channel-list .search::placeholder {
	color: var(--cocks-ink-mut);
}

/* The sidebar's own text colour, which upstream sets to the stock #415364
 * header blue-grey. */
#sidebar .scrollable-area,
#sidebar .networks,
#sidebar .channels,
#sidebar .channel-list-item,
#sidebar .lobby-wrap {
	color: var(--cocks-ink-dim);
}
#sidebar .network-name,
#sidebar .channel-name {
	color: var(--cocks-ink-dim);
}
#sidebar .channel-list-item.active {
	background-color: rgb(255 106 26 / 12%) !important;   /* was rgb(48,62,74) */
	color: var(--cocks-ink) !important;
}
#sidebar .channel-list-item.unread .channel-name,
#sidebar .channel-list-item.unread .network-name {
	color: var(--cocks-brand) !important;
}

/* Nick colours upstream hardcodes: notice/wallops are #0074d9 = 4.24 on our
 * bg (fails AA for body text), and the green/red action icons are stock.
 *
 * The values are the semantic tokens now, so a colour means the same thing
 * everywhere on the site. The measured contrast on #0a0a0c:
 *
 *   --cocks-cyan   #22d3ee   10.71
 *   --cocks-green  #34d399    9.79
 *   --cocks-amber  #f59e0b    8.90
 *   --cocks-red    #ef6661    7.02
 *   --cocks-brand-hi #ff8c42  8.55
 */
#chat .msg[data-type="notice"] .content,
#chat .msg[data-type="notice"] .time,
#chat .msg[data-type="notice"] .user,
#chat .msg[data-type="wallops"] .content,
#chat .msg[data-type="wallops"] .time,
#chat .msg[data-type="wallops"] .user {
	color: var(--cocks-cyan) !important;
}
#chat .msg[data-type="error"],
#chat .msg[data-type="error"] .from {
	color: var(--cocks-red) !important;
}
#chat .msg[data-type="action"] .content,
#chat .msg[data-type="action"] .from,
#chat .msg[data-type="action"] .user {
	color: var(--cocks-brand-hi) !important;   /* stays in palette */
}

/* Joins, parts and quits are the "the room changed" family, and they were
 * all the same grey. A green join and a red part are readable at a glance,
 * and it is the colour - not the wording - that says what happened. */
#chat .msg[data-type="join"] .content,
#chat .msg[data-type="chghost"] .content {
	color: var(--cocks-green) !important;
}
#chat .msg[data-type="part"] .content,
#chat .msg[data-type="quit"] .content,
#chat .msg[data-type="kick"] .content {
	color: var(--cocks-amber) !important;
}

/* A mode change and a topic change are worth a second look - they are the
 * two events in a channel that everybody should notice. */
#chat .msg[data-type="mode"] .content,
#chat .msg[data-type="topic"] .content {
	color: var(--cocks-cyan) !important;
}

/* Away and back are the quiet family, and they stay quiet. */
#chat .msg[data-type="away"] .content,
#chat .msg[data-type="back"] .content,
#chat .msg[data-type="nick"] .content,
#chat .msg[data-type="condensed"] .content {
	color: var(--cocks-ink-dim) !important;
}
#chat .msg[data-type="unhandled"] .from {
	color: var(--cocks-ink-mut) !important;
}

/* ---------------------------------------------------------------------------
 * 2) Accessibility: the measured contrast failures
 *
 * Verified ratios (WCAG) on the surfaces they sit on:
 *   --cocks-ink-mut #63636b  on #0a0a0c = 3.32   FAILS AA (needs 4.5)
 *   --cocks-ink-mut #63636b  on #121215 = 3.14   FAILS AA
 *   placeholder #55555c       on #121215 = 2.53   FAILS
 *   #222 on #f5f5f5 pre      (upstream)  fine, but wrong hue for the house
 *   --cocks-line-2 #2a2a30   on #0a0a0c = 1.39   input border, WCAG 1.4.11
 *                                                  wants 3.0 for UI edges
 *
 * --cocks-ink-mut is now #82828c: 5.20 on bg, 5.07 on the sidebar, 4.92 on
 * raised -- passes AA everywhere while still reading as a dimmed mono eyebrow.
 * ------------------------------------------------------------------------ */
:root {
	--cocks-ink-mut: #82828c;
}

/* Placeholder text is still not body text, but 2.53 is unreadable in practice. */
.input::placeholder,
textarea#input::placeholder,
#channel-search-input::placeholder {
	color: #6e6e78;
}

/* Input borders: a hairline at 1.39 does not read as a control boundary for
 * low-vision users. Lifted to 2.1 -- visible, still recessive. */
.input,
#connect .input,
#settings .input,
#channel-search-input,
textarea#input {
	border-color: #3a3a44 !important;
}
.input:disabled,
.input[readonly] {
	border-color: var(--cocks-line) !important;
}

/* Focus visibility: the 15% brand ring composited to only 1.21 against the
 * field, which is invisible. A solid 2px brand ring is 6.53 and always shows. */
.input:focus,
#connect .input:focus,
#settings .input:focus,
#channel-search-input:focus,
textarea#input:focus {
	outline: 2px solid var(--cocks-brand) !important;
	outline-offset: 1px;
	border-color: var(--cocks-brand) !important;
	box-shadow: none !important;
}

/* Scrollbar thumb was #222227 = 1.25 -- effectively invisible against the
 * track. */
::-webkit-scrollbar-thumb {
	background: #3a3a44;
	border: 2px solid var(--cocks-bg);
}
::-webkit-scrollbar-thumb:hover {
	background: var(--cocks-brand);
}

/* Upstream's universal focus ring is 2px brand already, but it is authored at
 * the end of the old sheet; restate it after everything so nothing above can
 * weaken it. */
:focus-visible {
	outline: 2px solid var(--cocks-brand) !important;
	outline-offset: 1px;
}

/* A skip link, so the sidebar and its controls are not the first tab stop on
 * every page. #app is the SPA mount, so it is the natural target. */
#cocks-skip-link {
	position: absolute;
	top: -100px;
	left: 8px;
	z-index: 2000;
	padding: 10px 16px;
	background: var(--cocks-brand);
	color: var(--cocks-bg);
	font-family: var(--cocks-mono);
	font-size: 12px;
	letter-spacing: 2px;
	text-transform: uppercase;
	text-decoration: none;
	border: 1px solid var(--cocks-brand);
	transition: top 0.15s;
}
#cocks-skip-link:focus {
	top: 8px;
}

/* Respect the OS setting rather than forcing a terminal look on someone who
 * asked for less motion. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ---------------------------------------------------------------------------
 * 3) "leave message ausblenden fuer den user"
 *
 * The block is removed from the form's rendered output by the bundle patch
 * (a vnode that is never created), NOT by `display:none` in CSS. Hiding it with
 * CSS would keep the field in the tab order and still submit a value, which is
 * exactly the "it's still there, just invisible" failure. What remains is a
 * compact cocks.io info strip, added by the same patch, that states the facts
 * the field used to ask for.
 * ------------------------------------------------------------------------ */
#connect .cocks-join-info {
	margin: 0 0 14px;
	padding: 12px 14px;
	background: var(--cocks-raised);
	border: 1px solid var(--cocks-line-2);
	border-left: 2px solid var(--cocks-brand);
	border-radius: 0;
	font-family: var(--cocks-mono);
	font-size: 12px;
	line-height: 1.7;
	color: var(--cocks-ink-dim);
}
#connect .cocks-join-info b {
	color: var(--cocks-brand);
	font-weight: 600;
	letter-spacing: 1px;
}
#connect .cocks-join-info .cocks-join-title {
	display: block;
	margin-bottom: 6px;
	color: var(--cocks-ink);
	letter-spacing: 2px;
	text-transform: uppercase;
	font-size: 11px;
}
#connect .cocks-join-info code {
	background: var(--cocks-inset);
	border: 1px solid var(--cocks-line);
	padding: 1px 5px;
	color: var(--cocks-brand-hi);
}

/* If the bundle patch is ever reverted, the leave-message row is still hidden
 * rather than being left as a stray empty field. */
#connect:has(#connect\:leaveMessage) .connect-row:has(#connect\:leaveMessage) {
	display: none;
}

/* ---------------------------------------------------------------------------
 * 4) + 5) The cocks.io menu and the cocks.io help text
 *
 * Both are injected by the bundle patch as real DOM with real <a href>, so
 * they are keyboard reachable, crawlable, and have visible focus. Styling only.
 * ------------------------------------------------------------------------ */
#cocks-menu {
	margin-top: 6px;
	padding: 10px 12px 12px;
	border-top: 1px solid var(--cocks-line);
	background: #0c0c0f;
}
#cocks-menu .cocks-menu-title {
	display: block;
	margin-bottom: 8px;
	font-family: var(--cocks-mono);
	font-size: 10px;
	letter-spacing: 2.5px;
	text-transform: uppercase;
	color: var(--cocks-ink-mut);
}
#cocks-menu a {
	display: block;
	padding: 6px 8px;
	margin: 0 -8px;
	font-family: var(--cocks-mono);
	font-size: 12px;
	letter-spacing: 0.5px;
	color: var(--cocks-ink-dim);
	text-decoration: none;
	border-left: 2px solid transparent;
}
#cocks-menu a:hover,
#cocks-menu a:focus-visible {
	background: rgb(255 106 26 / 10%);
	color: var(--cocks-ink);
	border-left-color: var(--cocks-brand);
	text-decoration: none;
}
#cocks-menu a[aria-current="page"] {
	color: var(--cocks-brand);
	border-left-color: var(--cocks-brand);
}

/* The cocks.io help block on the Help view. */
#help .cocks-about {
	margin: 0 0 28px;
	padding: 18px 20px;
	background: var(--cocks-raised);
	border: 1px solid var(--cocks-line-2);
	border-left: 2px solid var(--cocks-brand);
	border-radius: 0;
}
#help .cocks-about h2 {
	margin: 0 0 4px;
	font-family: var(--cocks-sans);
	font-size: 17px;
	font-weight: 700;
	letter-spacing: -0.3px;
	text-transform: none;
	color: var(--cocks-ink);
}
#help .cocks-about p {
	margin: 0 0 10px;
	font-family: var(--cocks-sans);
	font-size: 14px;
	line-height: 1.6;
	color: var(--cocks-ink-dim);
	max-width: 68ch;
}
#help .cocks-about dl {
	margin: 0 0 12px;
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 4px 14px;
	font-family: var(--cocks-mono);
	font-size: 12px;
}
#help .cocks-about dt {
	color: var(--cocks-ink-mut);
	letter-spacing: 1.5px;
	text-transform: uppercase;
	font-size: 10px;
	align-self: center;
}
#help .cocks-about dd {
	margin: 0;
	color: var(--cocks-ink);
}
#help .cocks-about .cocks-hosts {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 12px;
	padding: 0;
	list-style: none;
}
#help .cocks-about .cocks-hosts a {
	display: inline-block;
	padding: 7px 12px;
	background: var(--cocks-inset);
	border: 1px solid var(--cocks-line-2);
	color: var(--cocks-brand);
	font-family: var(--cocks-mono);
	font-size: 12px;
	letter-spacing: 0.5px;
	text-decoration: none;
}
#help .cocks-about .cocks-hosts a:hover,
#help .cocks-about .cocks-hosts a:focus-visible {
	border-color: var(--cocks-brand);
	background: rgb(255 106 26 / 10%);
}

/* ============================================================== v11: 2026-10-06
 * Modernisation pass. Four things, each measured on the live page first:
 *
 *  1. THE FONT NEVER LOADED. `document.fonts` reported the file's own
 *     @font-face as "cocks Sans / unloaded" and the computed stack resolved to
 *     the system default, because the @font-face at the top of this file has
 *     `src: local(...)` only — it can alias an installed face, it cannot fetch
 *     one. The families are now actually fetched: index.html carries the same
 *     Google Fonts stylesheet the slot page uses (added by seo-inject.cjs), and
 *     the CSP already allows it (`style-src 'self' https:` / `font-src 'self'
 *     https:`). A @import cannot be used here: it must precede every rule and
 *     this section is appended.
 *
 *  2. THE CONNECT FORM OVERFLOWED ITS COLUMN, BOTH AXES. Measured at 1024x800:
 *       form.container      left 382  right 862  width 480
 *       div.connect-row     left 414  right 830  width 416  (flex-wrap: nowrap)
 *       label.tls  [0]      left 518  right 830  width 312
 *       label.tls  [1]      left 830  right 1142 width 312   <-- 118px past the viewport
 *     The two TLS checkboxes are siblings inside ONE `.input-wrap`, each sized
 *     `width: 100%` by upstream and laid out on one line because the theme sets
 *     `.input-wrap { display: flex }`. 312 + 312 = 624 in a 312 box, so the row
 *     is 624 wide inside a 480 container and the second label is clipped by the
 *     viewport ("ONLY ALLOW TRUSTED C…"). At 360 the same container is a fixed
 *     480 wide, so `margin: 0 auto` centres it at left -60 and the LEFT edge is
 *     cut instead ("onnect", "cks.io"). Fixes: the container takes the width it
 *     is given, and the two checkboxes stack, which is the only arrangement that
 *     cannot exceed the column at any width.
 *
 *  3. THREE LIGHT SURFACES WERE STILL UPSTREAM. `#form #nick` is
 *     `color:#666; background:#f6f6f6` — the white chip in the composer, and the
 *     thing that reads as "a white skin". `#chat .content` carries a 1px
 *     `#f6f6f6` left border on every message, `#chat .header` a 1px `#e7e7e7`
 *     bottom border. All three are out-specified below.
 *
 *  4. GLASS. The ambient blobs, the translucent panels and the `@supports`
 *     fallback follow the start page's cocks v10 block, same tokens and same
 *     rule: every glass surface keeps an opaque fill in its own rule so a
 *     browser without `backdrop-filter` still gets the dark panel.
 * ------------------------------------------------------------------------ */

/* ------------------------------------------------- 1. the connect form ---- */
/* Width, not max-width: upstream ships `#connect .container { width: 480px }`,
 * which is a hard 480 on a 360 phone. `width: auto` + `max-width: min(560px,
 * 100%)` lets it shrink to the viewport and still cap at the desktop size. */
#connect .container,
#settings .container {
	width: auto !important;
	max-width: min(560px, 100%) !important;
	min-width: 0 !important;
}

#connect .connect-row,
#settings .connect-row {
	max-width: 100%;
	min-width: 0;
}

#connect .connect-row .input-wrap,
#settings .connect-row .input-wrap {
	min-width: 0;
	flex-wrap: wrap;
}

/* Stacked, one per line. Side by side they need 478px of the 312px the row
 * actually gives them, which is what produced the 624px row. */
#connect label.tls,
#settings label.tls {
	width: auto !important;
	flex: 1 1 100% !important;
	min-width: 0 !important;
	white-space: normal;
}

/* Long labels ("REAL NAME", "USERNAME") get their own line on a phone rather
 * than a 116px column plus a squeezed field. */
@media (max-width: 720px) {
	#connect .connect-row,
	#settings .connect-row {
		flex-direction: column;
		align-items: stretch;
	}

	#connect .connect-row > label,
	#settings .connect-row > label {
		width: auto !important;
		padding-right: 0;
		margin-bottom: 5px;
	}

	#connect .container,
	#settings .container {
		padding: 20px 16px 24px !important;
	}

	/* The port field and its ":" separator are one control, not two rows. */
	#connect .connect-row .input-wrap {
		width: 100%;
	}
}

/* The connect card is the one place a wider column is free, so let it breathe
 * on desktop without ever exceeding the viewport. */
@media (min-width: 721px) {
	#connect .container,
	#settings .container {
		padding: 30px 34px 34px !important;
	}
}

/* --------------------------------------------- 2. remaining light leaks ---- */
/* #form #nick: upstream is `.public #form #nick { display:block }` with
 * `#form #nick { color:#666; background:#f6f6f6 }` — specificity (2,1,0), so a
 * plain `#form #nick` loses. The white chip in the composer. */
#form #nick {
	color: var(--cocks-ink) !important;
	background-color: var(--cocks-raised) !important;
	border: 1px solid var(--cocks-line-2) !important;
	border-radius: 0 !important;
	margin: 4px 6px 4px 0 !important;
	padding: 0 8px !important;
	font-family: var(--cocks-mono) !important;
	font-size: 12px !important;
	line-height: 22px !important;
	letter-spacing: 0.5px;
}

/* Every message carries a 1px #f6f6f6 rule on its left edge. */
#chat .content {
	border-left-color: var(--cocks-line) !important;
}

/* The channel header's bottom rule, upstream #e7e7e7. */
#chat .header {
	border-bottom: 1px solid var(--cocks-line) !important;
}

/* The header/sidebar icon buttons, upstream #607992 (a cold blue-grey that
 * belongs to no surface here). */
#chat button.close,
#chat button.mentions,
#chat button.menu,
#chat button.search,
#viewport .lt,
#viewport .rt {
	color: var(--cocks-ink-dim) !important;
}

/* The "show more"/toggle caret and the unread counter glyph. */
#chat .count:before,
#chat .toggle-button:after {
	color: var(--cocks-ink-mut) !important;
}

/* The channel-topic save button, same upstream blue-grey. */
#chat .topic-container .save-topic span {
	color: var(--cocks-ink-dim) !important;
}

/* -------------------------------------------------------- 3. glass + ambient */
/* Two dim blurred blobs behind the app, transform-only so they never trigger
 * layout, hidden from print and switched off under prefers-reduced-motion.
 * Pseudo-elements on body: no DOM, so nothing extra is announced or focusable. */
body::before,
body::after {
	content: "";
	position: fixed;
	z-index: 0;
	pointer-events: none;
	border-radius: 50%;
	filter: blur(90px);
}

body::before {
	width: 520px;
	height: 520px;
	top: -200px;
	left: -140px;
	background: radial-gradient(circle, rgb(255 106 26 / 20%), transparent 70%);
}

body::after {
	width: 460px;
	height: 460px;
	bottom: -180px;
	right: -160px;
	background: radial-gradient(circle, rgb(34 211 238 / 12%), transparent 70%);
}

/* The app must sit above the blobs. */
#viewport,
#loading {
	position: relative;
	z-index: 1;
}

@media print {
	body::before,
	body::after {
		display: none;
	}
}

/* Glass, with the opaque fallback left in place above. `backdrop-filter` is the
 * only thing that makes it glass: a translucent fill on its own is just a
 * different colour. */
@supports ((backdrop-filter: blur(6px)) or (-webkit-backdrop-filter: blur(6px))) {
	#connect.window,
	#settings.window,
	.window {
		background-color: rgb(12 12 15 / 72%) !important;
		-webkit-backdrop-filter: blur(18px) saturate(1.15);
		backdrop-filter: blur(18px) saturate(1.15);
		border: 1px solid var(--cocks-line);
	}

	#sidebar {
		background-color: rgb(14 14 17 / 78%) !important;
		-webkit-backdrop-filter: blur(18px) saturate(1.1);
		backdrop-filter: blur(18px) saturate(1.1);
	}

	#form {
		background-color: rgb(10 10 12 / 82%) !important;
		-webkit-backdrop-filter: blur(14px) saturate(1.1);
		backdrop-filter: blur(14px) saturate(1.1);
	}

	#chat .header {
		background-color: rgb(10 10 12 / 76%) !important;
		-webkit-backdrop-filter: blur(14px) saturate(1.1);
		backdrop-filter: blur(14px) saturate(1.1);
	}
}

/* The connect card gets the same 16px radius and top hairline the cocks.io
 * cards use, so the form reads as one of the estate's panels.
 *
 * `overflow: hidden` was here to clip the card's corners to its radius. It
 * also removed the SCROLLBAR, and that is what made the Connect button
 * unreachable on a phone:
 *
 *   upstream `.window` is `overflow-y: auto`, so the form scrolls inside the
 *   window. At 360x740 the form is 1172px tall and the Connect button sits at
 *   top 1138 - below the fold. With the scrollbar gone, documentElement
 *   reported scrollHeight === clientHeight === 740 and the button was simply
 *   cut off with no way to reach it.
 *
 * `overflow-y: auto` keeps the scroll and still clips the corners, because
 * `overflow-x` stays `hidden` and the radius clips both axes. `auto` on the
 * y-axis only shows a scrollbar when there is something to scroll to, which
 * is exactly the behaviour wanted: no scrollbar on a short form, one on a
 * long one.
 */
/* The connect card gets the same radius as the other cocks.io cards, so the
 * form reads as one of the estate's panels.
 *
 * `overflow: hidden` was here to clip the card's corners to its radius. It
 * also removed the SCROLLBAR, and that is what made the Connect button
 * unreachable on a phone:
 *
 *   upstream `.window` is `overflow-y: auto`, so the form scrolls inside the
 *   window. At 360x740 the form is 1172px tall and the Connect button sits at
 *   top 1138 - below the fold. With the scrollbar gone, documentElement
 *   reported scrollHeight === clientHeight === 740 and the button was simply
 *   cut off with no way to reach it.
 *
 * The scroll now lives in the PANEL - the `.container` - because that is the
 * element that carries the radius and the form. `overflow-x` stays `hidden`
 * so the radius still clips the sides, and `overflow-y: auto` only shows a
 * scrollbar when there is something to scroll to.
 */
#connect.window,
#settings.window {
	border-radius: 0;
	overflow: visible;
}

#connect .container,
#settings .container {
	overflow-x: hidden;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
}

/* The scroll container needs the bottom padding back, because the button sits
 * at the very end of the form and `scroll-padding` keeps it clear of the
 * browser's own bottom edge on iOS. */
#connect .container,
#settings .container {
	padding-bottom: max(24px, env(safe-area-inset-bottom));
}

/* THE CONNECT BUTTON MUST BE REACHABLE ON A PHONE.
 *
 * With the scrollbar restored the button is reachable, but only by scrolling
 * past the whole form - on a 360x740 screen it sits at top 919 while the
 * viewport ends at 740. A visitor who opened the page to press "Connect" has
 * to scroll through seven rows first, and the button is the only thing they
 * came for.
 *
 * So on a phone the button is pinned to the bottom of the window as a bar.
 * It is still the same <button> in the same <form>, it still submits the
 * form, and it is still in the tab order - it is only positioned differently.
 * The form gets the padding it needs so the pinned button never covers the
 * last row.
 *
 * `position: sticky` rather than `fixed`: sticky keeps the button in the
 * flow, so the layout does not jump when the form is taller than the
 * viewport, and the browser keeps it above the safe-area inset on iOS.
 */
@media (max-width: 720px) {
	#connect .container,
	#settings .container {
		padding-bottom: 92px;
	}

	#connect .btn,
	#settings .btn {
		position: sticky;
		bottom: 0;
		z-index: 5;
		width: 100%;
		margin-top: 20px;
		box-shadow: 0 -10px 30px -12px rgba(0, 0, 0, 0.9);
	}

	/* The button lives in its own <div> at the end of the form; make that
	 * wrapper stick instead, so the button is never clipped by it. */
	#connect .container > div:last-child,
	#settings .container > div:last-child {
		position: sticky;
		bottom: 0;
		z-index: 5;
		padding-bottom: env(safe-area-inset-bottom);
		background: linear-gradient(to top,
			var(--cocks-bg) 62%,
			rgb(10 10 12 / 0%));
	}
}

/* The primary button is the page's only filled control: give it the estate's
 * height and radius rather than the 2px upstream border.
 *
 * And it gets the estate's hover: the slot page lifts its button by a pixel
 * and lets the gradient shift, which is what makes a flat rectangle feel
 * like a control rather than a coloured block.
 */
#connect .btn,
#settings .btn {
	min-height: 46px;
	border-radius: 10px;
	transition: transform .15s ease, background .15s ease,
		border-color .15s ease, box-shadow .15s ease;
}

#connect .btn:hover:not(:disabled),
#settings .btn:hover:not(:disabled) {
	transform: translateY(-1px);
	box-shadow: 0 6px 18px -8px rgb(255 106 26 / 55%);
}

#connect .btn:active:not(:disabled),
#settings .btn:active:not(:disabled) {
	transform: translateY(0);
}

#connect .btn:disabled,
#settings .btn:disabled {
	opacity: .55;
	cursor: not-allowed;
}

/* The secondary buttons - every one of them is a ghost button upstream, a
 * rectangle with a 2px border and no depth. */
.btn:not(#connect .btn):not(#settings .btn) {
	border-radius: 10px;
	transition: transform .15s ease, border-color .15s ease,
		background .15s ease, color .15s ease;
}

.btn:not(#connect .btn):not(#settings .btn):hover:not(:disabled) {
	transform: translateY(-1px);
	border-color: var(--cocks-brand);
	color: var(--cocks-brand-hi);
}

/* The join strip and the help/about blocks already carry a 2px brand edge;
 * match the card radius so nothing is the odd one out. */
#connect .cocks-join-info,
#help .cocks-about {
	border-radius: 12px;
}

/* -------------------------------------------------------------- 4. mobile --- */
/* The composer must not be covered by the on-screen keyboard. The document
 * already declares `interactive-widget=resizes-content`, which is what shrinks
 * the visual viewport on Chrome for Android; this keeps the bar above the home
 * indicator as well. */
#form {
	padding-bottom: max(6px, env(safe-area-inset-bottom));
}

@media (max-width: 700px) {
	/* Upstream `#form,.messages .msg,.userlist { font-size: 14px }` and a
	 * 15px override later; 14px is the readable floor here, not smaller. */
	#form,
	.messages .msg,
	.userlist {
		font-size: 14px;
	}

	#chat .header {
		height: 42px;
		line-height: 42px;
	}

	/* The portal row is the widest thing in the sidebar footer; let it wrap
	 * instead of pushing the icon bar off the edge. */
	.ck-portal {
		font-size: 10px !important;
		gap: 6px !important;
	}

	#form #nick {
		display: none !important;
	}
}

/* Nothing in the app may scroll the page sideways. The sidebar is an off-canvas
 * drawer at `left: -220px` on purpose; everything else stays inside. */
#viewport {
	max-width: 100vw;
	overflow-x: hidden;
}

/* ----------------------------------------------------- 5. clipped strings --- */
/* Long topics, channel names and nicks were hard-cut mid-word. The upstream
 * `mask-image` fade on .topic/.name stays; this adds the ellipsis for the
 * elements that clip without one. */
.header .topic {
	text-overflow: ellipsis;
}

#chat .msg .from {
	text-overflow: ellipsis;
}

/* ----------------------------------------------------------- 6. a11y extras -- */
/* The message list is given role="log" and an aria-label by ck-portal-nav.js,
 * which is where a live region has to be declared (CSS cannot). The ring below
 * makes that region visible when it is reached by keyboard. */
#chat:focus-visible,
#chat-container:focus-visible {
	outline: 2px solid var(--cocks-brand) !important;
	outline-offset: -2px;
}

/* Windows High Contrast / forced colours: the gradients and translucent fills
 * disappear, so pin the text to the system colours. */
@media (forced-colors: active) {
	body::before,
	body::after {
		display: none;
	}

	#connect.window,
	#settings.window,
	.window,
	#sidebar,
	#form,
	#chat .header {
		background-color: Canvas !important;
		backdrop-filter: none !important;
		-webkit-backdrop-filter: none !important;
	}
}

/* ============================================================== Monero dialog
 *
 * The donation dialog's own styles.
 *
 * These used to live in an inline <style> element created by
 * ck-portal-nav.js, and the textContent of that element was set to a
 * string that itself began with "<style>" and ended with "</style>".
 * The textContent of a <style> element must be CSS - tags inside it are
 * not markup, they are invalid CSS - so the browser discarded the whole
 * block.
 *
 * The visible symptom was a dialog that opened and then rendered at The
 * Lounge's upstream width: measured 1413px wide instead of the intended
 * 400px panel, with the upstream background and no rounded corners. The
 * rules were there and simply never applied.
 *
 * They live in the theme now, where they are served with it.
 * ---------------------------------------------------------------------- */

.ck-xmr-modal { position: fixed !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important; z-index: 9995 !important; box-sizing: border-box !important; width: min(400px, calc(100vw - 32px)) !important; max-width: none !important; max-height: calc(100vh - 48px) !important; max-height: calc(100dvh - 48px) !important; margin: auto !important; padding: 22px 22px 18px !important; overflow-y: auto !important; overscroll-behavior: contain !important; -webkit-overflow-scrolling: touch !important; background: #0d0d10 !important; color: #e8e6e1 !important; border: 1px solid #222227 !important; border-radius: 16px !important; box-shadow: 0 24px 60px rgba(0,0,0,.7) !important; font-family: "Space Grotesk", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important; text-align: left !important; }
.ck-xmr-modal:not([open]) { display: none !important; }
.ck-xmr-modal::backdrop { background: rgba(10, 10, 12, 0.8) !important; -webkit-backdrop-filter: blur(2px) !important; backdrop-filter: blur(2px) !important; }

.ck-xmr-x { position: absolute !important; top: 13px !important; right: 13px !important; z-index: 2 !important; width: 32px !important; height: 32px !important; display: grid !important; place-items: center !important; margin: 0 !important; padding: 0 !important; background: #141417 !important; border: 1px solid #222227 !important; border-radius: 9px !important; color: #e8e6e1 !important; cursor: pointer !important; -webkit-tap-highlight-color: transparent !important; }
.ck-xmr-x:hover { background: #1c1c21 !important; border-color: #2a2a30 !important; }
.ck-xmr-x:focus-visible { outline: 3px solid #ff6a1a !important; outline-offset: 2px !important; }
.ck-xmr-x svg { display: block !important; width: 13px !important; height: 13px !important; }

.ck-xmr-kicker { margin: 0 40px 3px 0 !important; font-family: "JetBrains Mono", monospace !important; font-size: 10px !important; font-weight: 600 !important; letter-spacing: 3px !important; text-transform: uppercase !important; color: #ff6600 !important; }
.ck-xmr-title { margin: 0 40px 12px 0 !important; font-family: "Space Grotesk", sans-serif !important; font-size: 18px !important; font-weight: 700 !important; line-height: 1.25 !important; color: #e8e6e1 !important; }

.ck-xmr-body { margin: 0 0 9px !important; font-size: 13px !important; line-height: 1.55 !important; color: #9a9aa4 !important; }
.ck-xmr-body strong { color: #e8e6e1 !important; font-weight: 600 !important; }

.ck-xmr-qr { width: 140px !important; max-width: 100% !important; margin: 14px auto 13px !important; border-radius: 9px !important; overflow: hidden !important; line-height: 0 !important; }
.ck-xmr-qr svg { display: block !important; width: 100% !important; height: auto !important; }

.ck-xmr-addr { margin: 0 !important; padding: 10px 11px !important; background: #141417 !important; border: 1px solid #222227 !important; border-radius: 9px !important; font-family: "JetBrains Mono", monospace !important; font-size: 11.5px !important; line-height: 1.6 !important; color: #e8e6e1 !important; word-break: break-all !important; user-select: all !important; -webkit-user-select: all !important; }
.ck-xmr-copy { display: block !important; width: 100% !important; min-height: 44px !important; margin: 9px 0 0 !important; padding: 0 14px !important; background: #141417 !important; color: #e8e6e1 !important; border: 1px solid #2a2a30 !important; border-radius: 9px !important; font-family: "Space Grotesk", sans-serif !important; font-size: 14px !important; font-weight: 500 !important; line-height: 1 !important; cursor: pointer !important; -webkit-tap-highlight-color: transparent !important; }
.ck-xmr-copy:hover { border-color: #3a3a42 !important; }
.ck-xmr-copy:focus-visible { outline: 3px solid #ff6a1a !important; outline-offset: 2px !important; }
.ck-xmr-copy.ck-xmr-done { color: #7de2a0 !important; border-color: #24402f !important; }

.ck-xmr-state { min-height: 15px !important; margin: 7px 0 0 !important; font-family: "JetBrains Mono", monospace !important; font-size: 10.5px !important; line-height: 1.4 !important; color: #6a6a74 !important; }
.ck-xmr-state.ck-xmr-done { color: #7de2a0 !important; }
.ck-xmr-sig { margin: 12px 0 0 !important; padding-top: 11px !important; border-top: 1px solid #1a1a1f !important; font-family: "JetBrains Mono", monospace !important; font-size: 10px !important; letter-spacing: 1.5px !important; color: #55555c !important; text-align: center !important; }
.ck-xmr-sig .ck-xmr-ninja { color: #ff9a5c !important; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
.ck-xmr-sig .ck-xmr-ninja { background-image: linear-gradient(90deg,#ff6a1a,#22d3ee) !important; -webkit-background-clip: text !important; background-clip: text !important; -webkit-text-fill-color: transparent !important; color: transparent !important; }
}

@media (max-width: 480px) {
	.ck-xmr-modal { width: calc(100vw - 16px) !important; padding: 20px 18px 16px !important; max-height: calc(100vh - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)) !important; max-height: calc(100dvh - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)) !important; }
	.ck-xmr-qr { width: 124px !important; margin: 12px auto 11px !important; }
}
/* Landscape phones: drop the QR before the copy, never the copy. */
@media (max-height: 620px) {
	.ck-xmr-qr { display: none !important; }
	.ck-xmr-body { font-size: 12.5px !important; line-height: 1.5 !important; }
}
@media (prefers-reduced-motion: reduce) {
	.ck-xmr-modal { animation: none !important; transition: none !important; }
}
