@font-face {
	font-family: "matrix-font";
	src: url("../font/matrix-font.woff2") format('woff2');
	font-display: swap;
}

@font-face {
	font-family: "Montserrat";
	src: url("../font/montserrat-400.woff2") format('woff2');
	font-display: swap;
}

@font-face {
	font-family: "Montserrat";
	src: url("../font/montserrat-500.woff2") format('woff2');
	font-weight: 500;
	font-display: swap;
}

@font-face {
	font-family: "Montserrat";
	src: url("../font/montserrat-600.woff2") format('woff2');
	font-weight: 600;
	font-display: swap;
}

@font-face {
	font-family: "Roboto Mono";
	src: url("../font/roboto-mono-400.woff2") format('woff2');
	font-display: swap;
}

:root {
	--font-family: "Montserrat";
	--font-family-mono: "Roboto Mono";
	--font-size-body: 95%;
	--global-hue: 222;
	--global-sat: 1.0;
	--global-lit: 1.0;
	--font-hue: 0;
	--font-sat: 0;
	--font-lit: 1.0;
	--menu-bg-accent: hsl(var(--global-hue) calc(20% * var(--global-sat)) calc(28% * var(--global-lit)));
	--menu-bg-accent2: hsl(var(--global-hue) calc(20% * var(--global-sat)) calc(24% * var(--global-lit)));
	--breakdown-bg-accent: hsl(var(--global-hue) calc(21% * var(--global-sat)) calc(13% * var(--global-lit)));
	--btn-bg-accent: hsl(var(--global-hue) calc(20% * var(--global-sat)) calc(22% * var(--global-lit)));
	--btn-hover-accent: hsl(var(--global-hue) calc(13% * var(--global-sat)) calc(33% * var(--global-lit)));
	--btn-active-accent: hsl(var(--global-hue) calc(13% * var(--global-sat)) calc(39% * var(--global-lit)));
	--body-bg-accent: hsl(var(--global-hue) calc(22% * var(--global-sat)) calc(16% * var(--global-lit)));
	--query-bg-accent: hsl(var(--global-hue) calc(20% * var(--global-sat)) calc(19% * var(--global-lit)));
	--hist-header-gradient: hsl(var(--global-hue) calc(13% * var(--global-sat)) calc(10% * var(--global-lit)));
	--table-row-odd: hsl(var(--global-hue) calc(14% * var(--global-sat)) calc(14% * var(--global-lit)));
	--table-row-even: hsl(var(--global-hue) calc(12% * var(--global-sat)) calc(16% * var(--global-lit)));
	--input-bg-accent: hsl(var(--global-hue) calc(13% * var(--global-sat)) calc(13% * var(--global-lit)));
	--highlight-date: hsla(var(--global-hue) calc(30% * var(--global-sat)) calc(85% * var(--global-lit)) / 0.15);
	--drag-highlight: hsla(var(--global-hue) calc(80% * var(--global-sat)) calc(70% * var(--font-lit)) / 0.2);
	--drag-highlight-border: hsl(var(--global-hue) calc(80% * var(--global-sat)) calc(70% * var(--font-lit)));
	--placeholder-color: hsl(var(--global-hue) calc(20% * var(--global-sat)) calc(45% * var(--font-lit)));
	--checkmark-accent: hsl(var(--global-hue) calc(75% * var(--global-sat)) calc(85% * var(--font-lit)));
	--font-white-1: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(92% * var(--font-lit)));
	--font-white-2: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(82% * var(--font-lit)));
	--font-white-3: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(63% * var(--font-lit)));
	--font-white-4: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(30% * var(--font-lit)));
	--border-accent: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(41% * var(--font-lit)));
	--separator-accent: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(50% * var(--font-lit)));
	--separator-accent2: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(30% * var(--font-lit)));
	--border-dark-accent: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(23% * var(--font-lit)));
	--focus-outline: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(75% * var(--font-lit)));
	--break-val-accent: hsl(var(--font-hue) calc(100% * var(--font-sat)) calc(41% * var(--font-lit)));
	/* "something is new/unread" green - fixed, not tied to --global-hue like
	   the accents above, on purpose: this means the same thing (unread,
	   alive, new) no matter which colour a member has picked for the rest of
	   the UI, same reasoning as the chat glow and reaction-lit colours that
	   already used this exact hue before it had a variable of its own. Red is
	   reserved for errors, warnings and destructive actions - never this. */
	--notif-green: hsl(140 70% 40%);
	--notif-green-text: hsl(140 80% 78%);
}

html, body { /* full <body> height for <!DOCTYPE html> */
	height: 100%;
	min-height: 100%;
	padding: 0;
	margin: 0;
}

body { /* disable Chromium's Text Autosizer (mobile text inflation algorithm) */
	-webkit-text-size-adjust: none;
	-moz-text-size-adjust: none;
	text-size-adjust: none;
	font-size: var(--font-size-body);
}

/*               Text Selection               */
/* ########################################## */

::selection {
	color: rgb(23,23,23);
	background: rgb(158,158,158);
}

::-moz-selection {
	color: rgb(23,23,23);
	background: rgb(158,158,158);
}

::placeholder { /* input placeholder */
	color: var(--placeholder-color);
	opacity: 1;
}

a {
	text-decoration: none;
}
a:link {
	color: var(--font-white-2);
	border-bottom: 1px solid var(--font-white-2);
}
a:visited {
	color: var(--font-white-3);
	border-bottom: 1px solid var(--font-white-3);
}
a:hover {
	color: var(--font-white-1);
	border-bottom: 1px solid var(--font-white-1);
}
a:active{
	color: var(--font-white-2);
}

/*               Scrollbar Style              */
/* ########################################## */

#calcMain {
	overflow: overlay; /* prevent page scroll in Query Table */
	height: 100%;
}

#loader{ /* fade in on page load*/
	z-index: 101;
	display: block;
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	/* --rain-backdrop is set only once a rain colour has been picked, so the
	   chosen scheme still shows when the rain is off or running thin */
	background: var(--rain-backdrop, var(--body-bg-accent));
}

body {
	overflow: overlay;
}

::-webkit-scrollbar {
	width: 16px;
	height: 16px;
}

::-webkit-scrollbar-thumb {
	background: rgba(128, 128, 128, 0.5);
	/*border-radius: 20px;*/
}

::-webkit-scrollbar-track {
	background: rgba(0, 0, 0, 0.2);
}

::-webkit-scrollbar-corner
{
	background: rgba(0, 0, 0, 0.2);
}

/* ########################################## */

body {
	font-family: var(--font-family), "Arial", sans-serif;
	color: var(--font-white-2);
	background-color: var(--rain-backdrop, var(--body-bg-accent));
}

.gematroLogo {
	display: flex;
	justify-content: center;
	/*padding-bottom: 0.4em;*/
}
.gematroLogo svg {
	height: 10px !important;
	width: auto !important;
}
.gematroLogo svg path {
	fill: var(--font-white-2) !important;
}
.splitInterface {}
@media (min-width: 911px) { /* desktop */
	.splitInterface {
		width: 70%;
		position: absolute;
		top: 0;
		right: 0;
		overflow: auto;
		height: 100%;
	}
}
.colorControlsBG {
	position: relative;
	background-color: var(--menu-bg-accent);
	width: -webkit-fit-content;
	width: -moz-fit-content;
	padding: 0.5em 0em 0.75em 1em;
	margin: 0.5em 0em 0.5em 0em;
	border: 1px solid var(--border-dark-accent);
}
.colLabelSmall, .colLabelSmallEnc {
	font-size: 80%;
	font-weight: 500;
	text-align: right;
	padding: 0em 0.1em 0em 0.4em;
}
.colLabelSmallEnc {
	text-align: left;
}
.colLabel {
	font-size: 90%;
	font-weight: 500;
	color: var(--focus-outline);
	text-align: center;
	padding-right: 0.4em;
}
/*          Right-click Export Menu           */
/* ########################################## */

#ctxExportMenu {
	position: absolute;
	z-index: 120;
	min-width: 190px;
	background-color: var(--menu-bg-accent);
	border: 1px solid var(--border-dark-accent);
	box-shadow: 0 4px 14px rgba(0,0,0,0.45);
	padding: 0.25em 0em 0.3em 0em;
	font-family: var(--font-family), "Arial", sans-serif;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}
.ctxExportTitle {
	font-size: 74%;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--font-white-3);
	padding: 0.35em 0.9em 0.45em 0.9em;
}
.ctxExportItem {
	font-size: 90%;
	color: var(--font-white-2);
	padding: 0.35em 0.9em;
	cursor: pointer;
	white-space: nowrap;
}
.ctxExportItem:hover {
	background-color: var(--btn-hover-accent);
	color: var(--font-white-1);
}
.ctxExportDisabled {
	color: var(--font-white-4);
	cursor: default;
}
.ctxExportDisabled:hover {
	background-color: transparent;
	color: var(--font-white-4);
}
.ctxExportItem.ctxExportDanger { color: hsl(5 70% 68%); }
.ctxExportItem.ctxExportDanger:hover { background-color: hsla(5 60% 45% / 0.25); color: hsl(5 80% 78%); }
.ctxExportItem.ctxExportDanger.ctxExportDisabled { color: var(--font-white-4); }
/* armed: asked once, one more click does it */
.ctxExportItem.ctxExportArmed {
	background-color: hsla(5 60% 45% / 0.35);
	color: hsl(5 85% 82%);
	font-weight: 600;
}
.ctxExportSep {
	height: 1px;
	background-color: var(--separator-accent2);
	margin: 0.3em 0.7em;
}

/*             Astrology Panel                */
/* ########################################## */

.astroBG {
	/* colorControlsBG sets right padding to 0, which reads as content running off
	   the edge once the panel is as wide as this one. Match the left inset and
	   keep the whole thing inside the viewport on small screens. */
	max-width: 780px;
	box-sizing: border-box;
	padding-right: 1em;
	max-width: min(780px, calc(100vw - 1.5em));
	overflow-x: auto;
}
.astroBG table {
	max-width: 100%;
}
.astroIntro {
	font-size: 85%;
	color: var(--font-white-3);
	padding: 0em 0.5em 0.9em 0.5em;
	max-width: 46em;
}
/* .intBtn3.astroMyChartsBtn (not just .astroMyChartsBtn): .intBtn3's own
   width:85px rule (styles.css, further down) has equal specificity to a
   single-class selector, so whichever comes later in the file would win -
   the extra .intBtn3 here beats that on specificity instead of depending on
   source order. */
.intBtn3.astroMyChartsBtn {
	display: block;
	width: auto;
	margin: 0 0.5em 0.9em 0.5em;
	padding: 0.4em 0.8em;
	background: hsla(140 55% 45% / 0.16);
	border-color: hsl(140 50% 45%);
	color: var(--font-white-1);
	font-weight: 600;
}
.intBtn3.astroMyChartsBtn:hover { background: hsla(140 55% 45% / 0.28); }
.astroStep {
	font-size: 92%;
	font-weight: 600;
	color: var(--focus-outline);
	text-align: left;
	padding: 0.6em 0.5em 0.5em 0.5em;
	border-bottom: 1px solid var(--separator-accent2);
	margin-bottom: 0.7em;
}
.astroNote {
	font-size: 82%;
	color: var(--font-white-3);
	padding: 0.3em 0.5em;
}
.astroStepNote {
	font-size: 86%;
	font-weight: 500;
	color: var(--font-white-3);
	padding-left: 0.7em;
}
.astroSubNote {
	font-size: 80%;
	color: var(--font-white-3);
	padding: 0em 0.5em 0.5em 0.5em;
}
.astroAngles {
	margin-bottom: 0.9em;
}
.astroViewToggle {
	float: right;
	margin-top: -0.25em;
}
.astroViewBtn {
	width: 44px !important;
	font-size: 88% !important;
	margin: 0em 0.1em !important;
	padding: 0.1em 0.4em !important;
	opacity: 0.55;
}
.astroViewBtn.astroViewOn,
.astroHouseBtn.astroViewOn {
	opacity: 1;
	background-color: var(--btn-active-accent) !important;
}
.astroPlaceInput {
	width: 300px !important;
	font-family: var(--font-family), "Arial", sans-serif !important;
}
#astroGeoResults {
	padding: 0em 0.5em 0.5em 0.5em;
}
.astroGeoList {
	border: 1px solid var(--border-dark-accent);
	max-height: 190px;
	overflow-y: auto;
	background: var(--input-bg-accent);
}
.astroGeoHit {
	font-size: 85%;
	padding: 0.35em 0.6em;
	cursor: pointer;
	border-bottom: 1px solid var(--border-dark-accent);
	color: var(--font-white-2);
}
.astroGeoHit:last-child { border-bottom: none; }
.astroGeoHit:hover {
	background: var(--btn-hover-accent);
	color: var(--font-white-1);
}
.astroGeoCoords {
	display: block;
	font-family: var(--font-family-mono), monospace;
	font-size: 88%;
	color: var(--font-white-3);
}
.astroGeoNote {
	font-size: 82%;
	color: var(--font-white-3);
	padding: 0.35em 0.1em;
}
.astroZoomCtl {
	float: right;
	display: inline-flex;
	align-items: center;
	gap: 0.25em;
}
.astroZoomBtn {
	width: 26px !important;
	font-size: 90% !important;
	padding: 0.05em 0.2em !important;
	margin: 0em !important;
}
.astroZoomBtn.astroZoomReset {
	width: auto !important;
	padding: 0.05em 0.5em !important;
	font-size: 82% !important;
}
#astroZoomLabel {
	font-family: var(--font-family-mono), monospace;
	font-size: 90%;
	min-width: 3.6em;
	text-align: center;
	color: var(--font-white-2);
}
.astroHouseBtn {
	width: auto !important;
	font-size: 88% !important;
	padding: 0.15em 0.7em !important;
	margin: 0em 0.15em !important;
	opacity: 0.55;
}
.astroCanvasWrap {
	display: flex;
	justify-content: center;
	padding: 0.3em 0em 0.4em 0em;
}
#astroCanvas {
	width: 100%;
	max-width: 520px;
	height: 460px;
	background: var(--breakdown-bg-accent);
	border: 1px solid var(--border-dark-accent);
	cursor: grab;
	touch-action: none;
}
#astroCanvas:active {
	cursor: grabbing;
}
.astroSystemRow {
	display: flex;
	align-items: center;
	gap: 0.6em;
	flex-wrap: wrap;
	padding-bottom: 0.35em;
}
.astroSystemRow .colLabelSmall { padding: 0em; }
.astroSystemSelect {
	flex: 1 1 14em;
	min-width: 12em;
	max-width: 26em;
	cursor: pointer;
}
/* the line that says what is actually being calculated */
.astroSystemInfo {
	font-size: 85%;
	color: var(--font-white-2);
	padding: 0.1em 0em 0.5em 0em;
	letter-spacing: 0.02em;
}
.astroHouseBtn:disabled,
.astroHouseBtn.astroBtnLocked {
	opacity: 0.45;
	cursor: not-allowed;
}
/* the flat map's own controls: zoom, layers and the model note */
.feControls {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 0.3em;
	padding: 0.2em 0em 0.3em 0em;
}
/* the layer toggles carry words, not a symbol, so they size to their text
   rather than to the fixed width the zoom buttons use */
/* .astroZoomBtn pins its width with !important, the way .astroZoomReset
   already has to override; same trick, same reason */
.feControls .feWideBtn {
	width: auto !important;
	padding: 0.05em 0.6em !important;
	white-space: nowrap;
}
#feZoomLabel {
	font-family: var(--font-family-mono), monospace;
	font-size: 80%;
	color: var(--font-white-3);
	min-width: 3em;
	text-align: center;
}
.feAbout {
	font-size: 82%;
	line-height: 1.5em;
	color: var(--font-white-3);
	border-left: 2px solid var(--border-dark-accent);
	margin: 0.2em 0em 0.5em 0em;
	padding: 0.4em 0.6em;
}

/* what the camera is following, under the solar map */
.astroSelInfo {
	font-size: 85%;
	color: var(--font-white-2);
	text-align: center;
	padding: 0.15em 0.4em 0.35em 0.4em;
	min-height: 1.2em;
}
#astroCanvas:focus-visible {
	outline: 2px solid var(--focus-outline);
	outline-offset: 2px;
}
.astroNak { white-space: nowrap; }
.astroLord {
	color: var(--font-white-3);
	font-size: 88%;
	padding-left: 0.4em;
}
.astroWarn {
	color: hsl(35 80% 65%);
}
.astroInputTable td {
	padding: 0em 0.35em 0.4em 0em;
	text-align: left;
	vertical-align: middle;
}
.astroInput {
	width: 62px;
	font-size: 90%;
	color: var(--font-white-1);
	border: 1px solid var(--border-accent);
	box-sizing: border-box;
	font-family: var(--font-family-mono), monospace;
	background-color: var(--input-bg-accent);
	padding: 0.2em 0.3em;
	margin-left: 0.35em;
}
.astroTable {
	border-spacing: 0px;
	width: 100%;
	margin-bottom: 0.5em;
}
.astroTable td {
	padding: 0.28em 0.6em;
	font-size: 95%;
	border-bottom: 1px solid var(--border-dark-accent);
}
.astroHeadRow td {
	font-size: 78%;
	font-weight: 600;
	color: var(--font-white-3);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.astroTable tr:nth-child(odd) td {
	background: var(--table-row-odd);
}
.astroTable tr:nth-child(even) td {
	background: var(--table-row-even);
}
.astroTable tr.astroHeadRow td {
	background: var(--hist-header-gradient);
}
.astroExact td {
	background: var(--highlight-date) !important;
}
.astroGlyph {
	font-size: 125%;
	padding-right: 0.4em;
	vertical-align: -1px;
}
.astroBody, .astroSign, .astroAspName {
	font-weight: 500;
	white-space: nowrap;
}
.astroBody, .astroSign, .astroAspName, .astroPhaseName {
	cursor: pointer;
}
.astroBody:hover, .astroSign:hover, .astroAspName:hover, .astroPhaseName:hover {
	color: var(--font-white-1);
	text-decoration: underline;
}
.astroDeg {
	font-family: var(--font-family-mono), monospace;
	text-align: right;
	white-space: nowrap;
}
.astroEl, .astroMotion {
	font-size: 88%;
	color: var(--font-white-3);
}
.astroRetro {
	color: hsl(10 75% 68%);
	font-weight: 600;
}
.astroPhase {
	padding: 0.6em 0.5em 0.2em 0.5em;
}
.astroPhaseName {
	font-size: 115%;
	font-weight: 600;
	color: var(--font-white-1);
	padding-right: 0.8em;
}
.astroPhaseNum {
	font-size: 85%;
	color: var(--font-white-3);
	padding-right: 0.8em;
}

/*            Encoding Menu Steps             */
/* ########################################## */

.encIntro {
	font-size: 85%;
	color: var(--font-white-3);
	padding: 0em 0.5em 0.9em 0.5em;
	max-width: 46em;
}
.encStep {
	font-size: 92%;
	font-weight: 600;
	color: var(--focus-outline);
	text-align: left;
	padding: 0em 0.5em 0.5em 0.5em;
	border-bottom: 1px solid var(--separator-accent2);
	margin-bottom: 0.7em;
}
.encStepNote {
	font-size: 88%;
	font-weight: 500;
	color: var(--font-white-3);
	padding-left: 0.7em;
}
.encSubNote {
	font-size: 82%;
	color: var(--font-white-3);
	padding: 0em 0.5em 0.4em 0.5em;
	max-width: 40em;
	text-align: center;
}

/* ---- mobile nav: short labels, two rows ---- */
.labShort { display: none; }
@media (max-width: 911px) {
	.labFull { display: none; }
	.labShort { display: inline; }
	.dropbtn {
		padding: 0.35em 0.6em;
		font-size: 94%;
	}
	.dropbtn.bgToggleBtn { font-size: 78%; padding: 0.35em 0.5em; }
	#calcOptionsPanel { padding-top: 0.4em; }

}

/* ---- Numerology mode ---- */
.nW { white-space: nowrap; }
.gA { /* arrow between reduction steps */
	font-size: 68%;
	opacity: 0.45;
	padding: 0em 0.15em;
	vertical-align: 1px;
}
.gRoot { /* the final digital root, the number that actually matters */
	font-weight: 700;
}

/* ---- Find Matches tab flash ---- */
.dropbtn.findMatchesTab.findMatchesFlash {
	animation: findMatchesBtnFlash 0.7s ease-out;
}
@keyframes findMatchesBtnFlash {
	0%   { background-color: hsla(140 85% 55% / 0.55); color: #fff; }
	60%  { background-color: hsla(140 85% 55% / 0.22); }
	100% { background-color: transparent; }
}
@media (prefers-reduced-motion: reduce) {
	.dropbtn.findMatchesTab.findMatchesFlash { animation: none; background-color: hsla(140 85% 55% / 0.3); }
}

/* A first-time visitor has no reason to know Matches is a button rather than
   a label. The instruction used to live in a CSS-only hover tooltip on the
   button itself, but hovering the button is exactly what opens
   .dropdown-content (createFindMatchesMenu, calc.js) over that same spot, so
   the tooltip was never actually visible - it lives inside the open panel
   instead now (.findMatchesHint), not on the button.

   .dropdown-content .findMatchesHint, not .findMatchesHint alone:
   .dropdown-content's own text-align:left (styles.css, further down) has
   equal specificity to a single-class selector, so whichever rule came later
   in the file would win - the extra .dropdown-content here beats that on
   specificity instead of depending on source order (the same fix as
   .intBtn3.astroMyChartsBtn elsewhere in this file). */
.dropdown-content .findMatchesHint {
	font-size: 76%;
	font-weight: 500;
	color: var(--font-white-3);
	text-align: center;
	padding: 0.2em 0 0.9em 0;
	margin-bottom: 0.5em;
	border-bottom: 1px solid var(--separator-accent2);
}

/* ---- Find Matches sweep ---- */
.findMatchesFx {
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 3;
	background: linear-gradient(100deg,
		hsla(140 80% 55% / 0) 0%,
		hsla(140 85% 60% / 0.22) 45%,
		hsla(140 95% 70% / 0.38) 50%,
		hsla(140 85% 60% / 0.22) 55%,
		hsla(140 80% 55% / 0) 100%);
	background-size: 220% 100%;
	background-repeat: no-repeat;
	animation: findMatchesSweep 0.85s ease-out forwards;
}
@keyframes findMatchesSweep {
	from { background-position: -120% 0; opacity: 1; }
	to   { background-position: 220% 0;  opacity: 0; }
}
.HistoryTable tr.fxMatchPulse td {
	animation: fxMatchPulse 0.8s ease-out;
}
@keyframes fxMatchPulse {
	0%   { box-shadow: inset 0 0 0 0 hsla(140 90% 60% / 0); }
	30%  { box-shadow: inset 0 0 14px 0 hsla(140 90% 60% / 0.28); }
	100% { box-shadow: inset 0 0 0 0 hsla(140 90% 60% / 0); }
}
/* nothing matched: the same sweep in red, so the result reads at a glance */
.findMatchesFx.findMatchesFxNone {
	background: linear-gradient(100deg,
		hsla(5 80% 55% / 0) 0%,
		hsla(5 85% 60% / 0.20) 45%,
		hsla(5 95% 68% / 0.34) 50%,
		hsla(5 85% 60% / 0.20) 55%,
		hsla(5 80% 55% / 0) 100%);
	background-size: 220% 100%;
	background-repeat: no-repeat;
}
.HistoryTable tr.fxMatchPulseNone td {
	animation: fxMatchPulseNone 0.8s ease-out;
}
@keyframes fxMatchPulseNone {
	0%   { box-shadow: inset 0 0 0 0 hsla(5 90% 60% / 0); }
	30%  { box-shadow: inset 0 0 14px 0 hsla(5 90% 60% / 0.26); }
	100% { box-shadow: inset 0 0 0 0 hsla(5 90% 60% / 0); }
}
@media (prefers-reduced-motion: reduce) {
	.findMatchesFx,
	.HistoryTable tr.fxMatchPulse td,
	.HistoryTable tr.fxMatchPulseNone td { animation: none; }
}

.intBtn3.ciphToolBtn { /* Color Controls / Edit Ciphers / Encoding, in the Cyphers tab */
	width: auto;
	padding: 0.2em 0.7em;
	font-size: 88%;
	margin: 0.25em 0.1em 0em 0.1em;
}
.colCtrlHint {
	font-size: 82%;
	color: var(--font-white-3);
	padding: 0em 0.5em 0.2em 0.5em;
	max-width: 44em;
}
.colCtrlHead {
	font-size: 76%;
	font-weight: 600;
	color: var(--font-white-3);
	text-align: center;
	padding-bottom: 0.15em;
}
.cipherSwatch { /* live result colour, click to open the OS picker */
	width: 34px;
	height: 21px;
	padding: 0;
	border: 1px solid var(--border-accent);
	background-color: transparent;
	cursor: pointer;
	vertical-align: middle;
}
.cipherSwatch::-webkit-color-swatch-wrapper { padding: 1px; }
.cipherSwatch::-webkit-color-swatch { border: none; }
.cipherSwatch::-moz-color-swatch { border: none; }
#enabledCiphTable {
	width: 100%;
	padding: 1em 0em 0em 0em;
	display: flex;
	justify-content: center;
}
#inputArea {
	padding: 0.5em 0em 0em 0em;
	display: inline-flex;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}
#HistoryTableArea {
	padding-bottom: 0.1em;
}
#calcOptionsPanel {
	/* Side padding keeps the first and last tabs clear of .focusOptionsBtn and
	   .focusModeBtn, which are fixed in the two top corners over this row. The
	   row is centred and spans the full width, so without it the extra Numogram
	   tab pushes Cyphers and About straight underneath those icons. */
	padding: 0.6em 3.2em 0em 3.2em;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}
.ciphToggleContainer {
	display: inline-block;
	padding: 0.5em 0.5em 0.2em 0.5em;
	border-spacing: 0em;
	text-align: left;
}
.colSlider, .colSlider2 {
	width: 55px;
	font-size: 80%;
	color: var(--font-white-1);
	border: 2px solid var(--border-accent);
	box-sizing: border-box;
	font-family: var(--font-family-mono), monospace;
	line-height: 1.1em;
	background-color: var(--btn-bg-accent);
}
.colSlider2 {
	width: 65px;
}
@media (max-width: 911px) { /* mobile */
	.colSlider2 {
		width: 40px;
	}
}
.cipherColValueBox {
	width: 85px;
	font-size: 80%;
	color: var(--font-white-1);
	border: 2px solid var(--border-accent);
	font-family: var(--font-family-mono), monospace;
	line-height: 1.1em;
	background-color: var(--btn-bg-accent);
}
.globColCtrlTable {
	padding-right: 1.25em;
}
.phraseGemContainer {
	display: inline-block;
	border: 1px solid var(--border-dark-accent);
	border-spacing: 0px;
	text-align: center;
	font-weight: 500;
	line-height: 1.0em;
}
.phraseGemContainer tr:nth-child(odd) {
	background-color: var(--table-row-odd);
}
.phraseGemContainer tr:nth-child(even) {
	background-color: var(--table-row-even);
}
/* Wheel ciphers substitute symbols, so their result is a string as long as the
   phrase rather than a two or three digit number. At the numeric size it runs
   straight over the cipher name beside it, so it is set smaller and allowed to
   wrap inside its own cell. */
.phraseGemValueOdd .wheelVal, .phraseGemValueEven .wheelVal {
	display: inline-block;
	max-width: 100%;
	font-size: 60%;
	line-height: 1.15;
	overflow-wrap: anywhere;
	white-space: normal;
	vertical-align: middle;
}
.phraseGemValueOdd, .phraseGemValueEven {
	font-size: 180%;
	text-align: center;
	min-width: 80px;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	font-weight: 600;
	padding: 0em 0.1em 0em 0.1em;
}
.phraseGemCiphName {
	padding: 0.2em 0.5em;
	max-width: 115px; /* 110px */
	height: 32px;
	cursor: pointer;
}
.phraseGemCiphNameBlank {
	padding: 0.2em 0.5em;
	max-width: 115px; /* 110px */
	height: 32px;
}
#canv {
	margin: 0;
	padding: 0;
	position: fixed;
	touch-action: none;
	width: 100%;
	height: 100%;
	top:0;
	left:0;
	z-index : -1; /* behind all elements */
}

/* ---- background toggle (last item in the nav row) ---- */
.dropbtn.bgToggleBtn {
	font-size: 82%;
	opacity: 0.7;
	cursor: pointer;
	padding: 0.4em 0.8em;
}
.dropbtn.bgToggleBtn:hover {
	opacity: 1;
	background-color: var(--btn-hover-accent);
}
.dropbtn.bgToggleBtn.bgToggleOff {
	opacity: 0.45;
}
.dropbtn.bgToggleBtn.bgToggleRetro { /* third state, distinct from plain On */
	opacity: 1;
	color: var(--checkmark-accent);
}
/* ---- code rain intensity panel (hover on the toggle) ---- */
.rainTuneDropdown { position: relative; }
.rainTuneContent {
	width: 286px !important;
	right: 0;
	left: auto !important;
}
/* Held open by JS while the pointer is on its way to a control, or while the
   OS colour dialog has focus - see rainTuneOpen() in coderain.js */
.rainTuneDropdown.rainTuneStuck .rainTuneContent { display: block; }
.rainTunePanel { padding: 0.55em 0.7em 0.5em 0.7em; }
.rainTuneRow {
	display: flex;
	align-items: center;
	gap: 0.5em;
	padding: 0.25em 0em;
}
/* Wide enough for the longest label ("DENSITY"/"COLOUR") at this size, and
   fixed so it cannot be squeezed by the slider next to it - at 3.6em both of
   those overran their box and collided with the track. */
.rainTuneLabel {
	font-size: 80%;
	font-weight: 600;
	color: var(--font-white-3);
	width: 5.4em;
	flex: 0 0 auto;
	white-space: nowrap;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}
.rainTuneSlider {
	flex: 1;
	/* a range input has an intrinsic minimum width, and flex items refuse to
	   shrink past their content by default - together that pushed the row wider
	   than the panel on a narrow screen and the colour swatch was clipped off
	   the right edge */
	min-width: 0;
	-webkit-appearance: none;
	appearance: none;
	height: 3px;
	background: var(--border-accent);
	outline: none;
	cursor: pointer;
}
.rainTuneSlider::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 12px; height: 12px;
	border-radius: 50%;
	background: var(--checkmark-accent);
	cursor: pointer;
}
.rainTuneSlider::-moz-range-thumb {
	width: 12px; height: 12px;
	border: none;
	border-radius: 50%;
	background: var(--checkmark-accent);
	cursor: pointer;
}
.rainTuneVal {
	font-family: var(--font-family-mono), monospace;
	font-size: 78%;
	color: var(--font-white-2);
	width: 3.4em;
	flex: 0 0 auto;
	white-space: nowrap;
	text-align: right;
}
.rainTuneFoot {
	border-top: 1px solid var(--separator-accent2);
	margin-top: 0.35em;
	padding-top: 0.45em;
	justify-content: space-between;
}
/* hue slider painted with the full spectrum so it reads as a colour picker */
.rainHueSlider {
	background: linear-gradient(to right,
		hsl(0 80% 55%), hsl(60 80% 55%), hsl(120 80% 55%),
		hsl(180 80% 55%), hsl(240 80% 55%), hsl(300 80% 55%), hsl(359 80% 55%)) !important;
	height: 6px !important;
}
/* Native colour input, matched to the per-cipher swatches in Color Controls */
.rainColorPicker {
	-webkit-appearance: none;
	appearance: none;
	width: 26px;
	height: 15px;
	padding: 0;
	border: 1px solid var(--border-accent);
	background: none;
	vertical-align: middle;
	cursor: pointer;
}
.rainColorPicker::-webkit-color-swatch-wrapper { padding: 0; }
.rainColorPicker::-webkit-color-swatch { border: none; }
.rainColorPicker::-moz-color-swatch { border: none; }
.rainFollowLabel {
	font-size: 76%;
	color: var(--font-white-3);
	display: inline-flex;
	align-items: center;
	gap: 0.3em;
	cursor: pointer;
}
.rainFollowLabel input { margin: 0; }
.intBtn3.rainTuneReset { width: auto; padding: 0.1em 0.6em; font-size: 80%; margin: 0; }

.dropbtn.bgToggleBtn.bgToggleCCRU { /* fourth state */
	opacity: 1;
	color: hsl(320 70% 70%);
}
.dropbtn.bgToggleBtn.bgToggleMatrix { /* fifth state - the film's own green */
	opacity: 1;
	color: hsl(135 100% 62%);
	text-shadow: 0 0 6px hsl(135 100% 45% / 0.55);
}
/* Cypher search, under the filter row in the Cyphers panel */
.ciphSearchRow { position: relative; padding: 0.4em 0.3em 0em 0.3em; }
.ciphSearchBox {
	width: 100%;
	box-sizing: border-box;
	padding: 0.3em 1.6em 0.3em 0.5em;
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 88%;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	outline: none;
}
.ciphSearchBox:focus { border-color: var(--focus-outline); }
.ciphSearchBox::placeholder { color: var(--font-white-4); }
.ciphSearchClear {
	position: absolute;
	right: 0.7em;
	top: 50%;
	transform: translate(0, -40%);
	color: var(--font-white-3);
	cursor: pointer;
	font-size: 110%;
	line-height: 1;
}
.ciphSearchClear:hover { color: var(--font-white-1); }
/* which category a result came from - without it a flat list gives no clue
   why the same name appears more than once */
.ciphSearchCat {
	color: var(--font-white-4);
	font-size: 80%;
	padding-left: 0.6em;
}
.ciphSearchHit { color: var(--font-white-1); font-weight: 700; }
.ciphSearchNone {
	color: var(--font-white-3);
	font-size: 88%;
	padding: 0.8em 0.4em;
}

.ciphCheckbox {
}
.ciphCheckboxLabel {
	font-size: 85%;
	font-weight: 500;
	padding: 0em 0.6em 0em 0em;
	white-space: nowrap;
}
/* Cypher names in the Cyphers menu. nowrap used to clip anything wider than
   the column: .ciphersContent is overflow-x hidden, so a long name such as
   "Based Atlanteanism Denovated" simply had its tail cut off with no way to
   read it. Wrapping instead - the label already carries the left padding that
   makes room for the checkbox, so a second line lines up under the first
   rather than sliding back under the box. */
.ciphCheckboxLabel2 {
	font-size: 100%;
	font-weight: 500;
	padding: 0em 0em 0em 0.1em;
	white-space: normal;
	overflow-wrap: anywhere;
}
/* .custChkBox centres itself on the label (top:50% + translate), which is
   right while a label is one line and wrong the moment it is two: a wrapped
   name such as "Based Atlanteanism Denovated" left its box floating halfway
   down the pair, reading as though it belonged to neither line. Pinned to the
   first line here instead. Scoped to this label so every other checkbox in
   the app keeps centring, which is still correct for those. */
.ciphCheckboxLabel2 .custChkBox {
	top: 0.2em;
	transform: none;
}
.dragOver {
	border: 1px solid var(--drag-highlight-border) !important;
	background-color: var(--drag-highlight) !important;
}

/*  Word Breakdown, Cipher Table, Word Count  */
/* ########################################## */

#ChartSpot {
	/*min-height: 189px;*/ /* fix content shift */
	display: flex; /* vertically center */
	justify-content: center;
	align-items: center;
	width: -webkit-fit-content;
	width: -moz-fit-content;
	/*padding: 0.4em;*/
	border: 1px solid var(--border-dark-accent);
    /*margin-top: 1em;*/
	/*margin-bottom: 0.5em;*/
}
@media (max-width: 911px) { /* mobile */
	#ChartSpot {
		padding: 0em 0.8em !important;
	}
	#ChartSpotScroll {
		width: 90vw;
		overflow: auto;
	}
}
.ChartSpotScrollStop {
	width: unset !important;
	overflow: unset !important;
}
#BreakdownSpot {
	padding-bottom: 0.5em;
}
#BreakdownDetails {
	padding: 1em 1.5em 1em 1.5em;
	width: -webkit-fit-content;
	width: -moz-fit-content;
}
#SimpleBreak {
	max-width: 800px;
	margin: auto;
	padding-bottom: 1em;
	text-align: center;
}
/* inline-block, not block, so it can sit right after .BreakTableRowLast on
   the same line when there's room - only drops to a line of its own when
   there genuinely isn't, via ordinary inline wrapping. */
#BreakSumLong {
	display: inline-block;
	vertical-align: bottom;
	padding: 0.5em 0 0.5em 0.6em;
}
.SimpleBreakChart {
	max-width: 800px;
}
.SimpleBreakChartLong {
	max-width: 720px;
	padding: 0.75em 1em 0.35em 1em;
	text-align: center;
}
#BreakTableContainer {
	position: relative;
	padding: 0.6em 0.8em;
	border: 1px solid transparent; /* visible only in the tinted look, see .breakdownTinted below - kept as a real (transparent) border rather than none so the box doesn't shift size when it toggles */
	width: -webkit-fit-content;
	width: -moz-fit-content;
	text-align: center; /* centers .BreakSumLong when it wraps onto a line by itself */
	cursor: pointer; /* the whole box toggles the tinted background - see onclick in breakdown.js */
	transition: background 0.25s ease, border-color 0.25s ease;
}
#BreakTableContainer.breakdownTinted {
	border-color: var(--border-dark-accent); /* same border #ChartSpot (the Cipher Chart) uses */
}
/* Whichever row of a long breakdown ends up last (tagged in breakdown.js,
   a plain string search rather than tracked through the LTR/RTL branches)
   switches from block to inline-table, so #BreakSumLong immediately after it
   can share its line when there is room instead of always starting a new
   one - ordinary inline wrapping drops it to its own line only when it
   genuinely does not fit. */
.BreakTableRowLast {
	display: inline-table;
	vertical-align: bottom;
}
.BreakRTL {
	padding: 0.4em 0.8em 0.4em 0.4em !important;
}
/* Letters take the current cypher's own colour (curCiphCol, set inline per
   cell in breakdown.js) in the plainer look. No background of their own by
   default; the plainer look (box unclicked) brings back a faint shared
   block behind each letter/value pair instead - table cells sit flush
   against each other (border-spacing: 0 below), so it reads as one quiet
   block behind each word rather than two separate rows. */
.BreakChar {
	font-size: 110%;
	font-weight: 500;
	padding: 3px 3px 1px 3px;
	font-family: var(--font-family-mono), "Arial", sans-serif;
}
#BreakTableContainer:not(.breakdownTinted) .BreakChar,
#BreakTableContainer:not(.breakdownTinted) .BreakVal,
#BreakTableContainer:not(.breakdownTinted) .BreakValDark {
	background: hsl(0 0% 100% / 0.05);
}
/* The classic gradient look (.breakdownTinted) keeps cypher-coloured letters
   on a short phrase (.BreakShort, breakdown.js) - that's the whole point of
   the tinted look - but a long phrase mostly green turns unreadable, so
   .BreakLong forces letters white there instead and the word sums carry
   green in their place. !important overrides the inline cypher colour
   breakdown.js sets on each letter cell - simpler than threading a second
   conditional through every render branch that builds one for the same
   result. The short-phrase total (.BreakPhraseSum) takes the cypher colour
   inline (breakdown.js); the long-phrase one (.breakSumDark) stays white
   regardless, since it sits over more green already. */
#BreakTableContainer.breakdownTinted.BreakLong .BreakChar {
	color: var(--font-white-1) !important;
}
/* word sums run the opposite of whichever colour the letters took, so the two
   never compete for the same colour: white letters (.BreakLong, above) get
   cypher-coloured sums (set inline in breakdown.js, wordSumColStyle) : green
   letters (.BreakShort) get white sums, which is just .BreakWordSum's base
   colour below with no override needed here. */
/* the cypher name under the grid - shown only in the classic (.breakdownTinted) look */
/* A derived cipher's breakdown (derivedBreakdownHtml, breakdown.js): the
   working that produced the total, in place of the letter/value grid.
   Monospace so the digits line up as an equation rather than drifting like
   prose, and sized to sit between the letters (110%) and the total (150%)
   the ordinary box uses. */
.BreakDerivation {
	text-align: center;
	padding: 0.35em 0.6em 0.1em 0.6em;
	font-family: var(--font-family-mono), "Arial", sans-serif;
	font-size: 125%;
	font-weight: 500;
	white-space: nowrap;
}
/* the operands, in the cypher's own colour (set inline, same as .BreakChar) */
.BreakDerivNum { font-weight: 600; }
/* brackets, minus, slash and equals - structure, not content, so they stay
   out of the way of the numbers they join */
.BreakDerivOp { color: var(--font-white-3); font-weight: 400; }
/* the answer, matching the scale the ordinary box gives its total */
.BreakDerivResult { font-size: 140%; font-weight: 700; }
/* the equation can outgrow a narrow screen; it shrinks rather than forcing
   the whole box to scroll sideways */
@media (max-width: 620px) {
	.BreakDerivation { font-size: 105%; }
	.BreakDerivResult { font-size: 130%; }
}

.BreakCipherName {
	text-align: center;
	font-size: 100%;
	font-weight: 600;
	padding-top: 0.3em;
}
.BreakEqualsSign {
	font-size: 60%;
	font-weight: 500;
	color: var(--font-white-3);
}
.breakCipher {
	font-size: 100%;
	font-weight: 500;
	display: inline-block;
}
.breakSum {
	font-size: 155%;
	color: var(--font-white-1);
	font-weight: 700;
}
/* the in-box long-phrase total - always white now (not cypher-coloured, see
   breakdown.js), same as .BreakPhraseSum below */
.breakSumDark {
	font-size: 115%;
	color: var(--font-white-1);
	font-weight: 700;
}
.breakPhrase {
	font-size: 125%;
	color: var(--font-white-2);
	font-weight: 500;
}
.breakPhraseChart {
	font-size: 120%;
	font-weight: 500;
	color: var(--font-white-2);
}
.breakPhraseChartCiphName {
	font-size: 115%;
	font-weight: 500;
	display: inline-block;
}
/* white by default (equation-line context etc); the tinted short-phrase look
   below overrides this with the cypher colour, set inline in breakdown.js */
.BreakPhraseSum {
	font-weight: 700;
	font-size: 115%;
	color: var(--font-white-1);
	padding-left: 10px;
	padding-right: 8px;
}
/* the tinted look drops the "=" (breakdown.js) and reads as a standalone
   result, so a short phrase's total (one row, nothing else competing for
   attention) can afford to be bigger than the letters feeding it - lighter
   than default bold, or it reads as too heavy at this size. Takes the cypher
   colour inline (breakdown.js). */
#BreakTableContainer.breakdownTinted .BreakPhraseSum {
	font-size: 150%;
	font-weight: 600;
}
/* a long phrase's total sits paired with the cypher name at the bottom of the
   box (breakdown.js), so it stays close to that name's scale rather than
   towering over it - stays white regardless of cypher colour, unlike the
   short-phrase total above. */
#BreakTableContainer.breakdownTinted .breakSumDark {
	font-size: 130%;
}
.BreakTable, .BreakTableRow {
	text-align: center;
	border-spacing: 0px;
	margin: auto;
	width: -webkit-fit-content;
	width: -moz-fit-content;
}
.BreakTable td, .BreakTableRow td {
	min-width: 14px;
}
.BreakTableRow {
	padding: 0em 0.75em;
}
.BreakWordSum {
	font-size: 108%;
	font-weight: 700;
	color: var(--font-white-1);
	padding-right: 5px;
	padding-left: 5px;
}
.BreakVal, .BreakValDark {
	color: var(--focus-outline);
    font-weight: 600;
	font-size: 68%;
	padding: 1px 3px 3px 3px;
}
.BreakValDark {
	color: var(--break-val-accent);
}
#ChartTable {
	border-spacing: 0px;
}
#ChartTable td {
	text-align: center;
	border: none;
	padding: 0.1em 0.25em 0.2em 0.25em;
	min-width: 22px;
}
@media (max-width: 911px) { /* mobile */
	#ChartTable td {
		padding: 0.1em 0.15em 0.2em 0.15em;
	}
}

/* ----- Bordered style for Cipher Table ---- */
.borderCipherTable {
	border-right: 1px solid var(--border-accent) !important;
	border-top: 1px solid var(--border-accent) !important;
}
.borderCipherTable td {
	border-left: 1px solid var(--border-accent) !important;
	border-bottom: 1px solid var(--border-accent) !important;
	padding-right: 5px !important;
	padding-left: 5px !important;
	padding-top: 1px !important;
	padding-bottom: 2px !important;
}
.borderClassGemCard {
	border: 1px solid var(--border-accent) !important;
}

.ChartChar {
	font-size: 140%;
}
.ChartVal {
	font-size: 120%;
}
@media (max-width: 911px) { /* mobile */
	.ChartChar {
		font-size: 118%;
	}
	.ChartVal {
		font-size: 100%;
	}
}
.LetterCounts {
	color: var(--font-white-2);
	font-size: 90%;
	font-weight: 500;
	text-align: center;
	padding-bottom: 1em;
}
.ChartChar, .ChartVal, #spaceChartBtn, #capsNameChartBtn, #backspaceChartBtn {
	cursor: pointer;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

/*        Buttons, Text Boxes, Controls       */
/* ########################################## */

#btn-clear-active-filter {
	position: relative;
	color: var(--font-white-1);
	font-weight: 500;
	margin-left: 0.25em;
	font-family: var(--font-family), "Arial", sans-serif;
	padding: 0.2em 0.55em 0.2em 0.55em;
	border: 1px solid var(--border-accent);
	background-color: var(--menu-bg-accent2);
	font-size: 100%;
	outline: none;
}

#btn-clear-active-filter:hover { background-color: var(--btn-hover-accent); }
#btn-clear-active-filter:active { background-color: var(--btn-active-accent); }

#highlightBox {
	background-color: var(--input-bg-accent);
	color: var(--font-white-1);
	font-weight: 500;
	border: 1px solid var(--border-accent);
	font-family: var(--font-family), "Arial", sans-serif;
	margin-left: 0.25em;
	font-size: 125%;
}
#phraseBox {
	background-color: var(--input-bg-accent);
	color: var(--font-white-1);
	font-weight: 500;
	border: 1px solid var(--border-accent);
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 125%;
}
@media (max-width: 911px) { /* mobile */
	#inputArea {
		max-width: 480px;
	}
	#phraseBox {
		width: 300px;
	}
	#highlightBox {
		width: none;
		max-width: 100px;
	}
}
@media (min-width: 911px) { /* desktop */
	#inputArea {
		max-width: none;
	}
	#phraseBox {
		width: 500px;
	}
	#highlightBox {
		width: 200px;
		max-width: 200px;
	}
}
#phraseBox:focus, #highlightBox:focus {
	outline: none !important;
	border:1px solid var(--focus-outline);
}

/*                History Table               */
/* ########################################## */

.HistoryTable tr, .HistoryTable td {
	border-bottom: 1px solid var(--border-dark-accent);
	border-left: 1px solid var(--border-dark-accent);
}
.cH { /* cipher header bar, history table */
	background: -webkit-linear-gradient(0deg, var(--hist-header-gradient), transparent); /*20,23,27*/
	background: -moz-linear-gradient(0deg, var(--hist-header-gradient), transparent);
	background: -o-linear-gradient(0deg, var(--hist-header-gradient), transparent);
	background: linear-gradient(0deg, var(--hist-header-gradient), transparent);
}
.HistoryTable {
	text-align: center;
	border-spacing: 0px;
	border-top: 1px solid var(--border-dark-accent);
	border-right: 1px solid var(--border-dark-accent);
	margin: 0.5em 1em 2.4em 1em;
}
.HistoryTable tr:nth-child(odd) {
	background-color: var(--table-row-odd);
}
.HistoryTable tr:nth-child(even) {
	background-color: var(--table-row-even);
}
#QueryTable {
	table-layout: fixed;
	width: 100%;
	word-break: break-all;
	margin: auto;
	float: right;
	border-top: none;
}
.hC { /* history table header, cipher name cell */
	min-width: 80px;
	max-width: 80px;
	font-size: 85%;
	padding: 5px 3px 5px 3px;
	text-align: center;
	font-weight: 500;
	word-break: break-word; /* affects table performance */
}
.hCV, .hCVQ { /* vertical history table header, cipher name cell */
	font-size: 85%;
	height: 180px;
	text-align: center;
	vertical-align: bottom;
	font-weight: 500;
}
.hCVQ { /* vertical query table header, cipher name cell */
	width: 55px;
}
.hCV2 {
	transform: rotate(-90deg);
	transform-origin: left;
	white-space: nowrap;
	display: inline-block;
	width: 20px;
	margin-left: 1.6em;
}
.hP { /* history phrase */
	text-align: right;
	padding: 0em 0.5em 0em 0.5em;
	font-size: 110%;
}
@media (min-width: 911px) { /* desktop */
	.hP { /* single line history phrase */
		white-space: nowrap; /* affects table performance */
	}
}
.hPQ { /* history phrase - query table*/
	text-align: right;
	padding: 0em 0.5em 0em 0.5em;
	font-size: 110%;
}
/* Per-row delete x. .histRow carries position:relative so this positions
   against the whole row (true top-right corner of the entry) even though it
   lives inside .hP - .hP itself is left position:static on purpose, or the
   containing block would be just that cell. position:absolute takes it out
   of flow entirely, so revealing it never moves, resizes or reflows the
   table - see updateHistoryTable() in calc.js. */
.histRow { position: relative; }
/* themed rather than left as the browser default blue ring, but still a
   real outline - tapping/tabbing to an entry should look focused, not just
   quietly reveal a × with no other feedback. .hP (per-row) and .histClearTab
   (the header row's whole-table equivalent, see updateHistoryTable()) are
   the two tabindex holders this can land on. */
.hP:focus,
.histClearTab:focus {
	outline: 2px solid var(--focus-outline);
	outline-offset: -2px;
}
.histDelX {
	position: absolute;
	top: -0.4em;
	right: -0.4em;
	z-index: 1;
	background: var(--menu-bg-accent);
	border: 1px solid var(--border-dark-accent);
	border-radius: 50%;
	color: hsl(5 70% 68%);
	cursor: pointer;
	font-size: 85%;
	line-height: 1;
	/* the hit area is a generous touch target; the glyph inside it stays small */
	width: 1.7em;
	height: 1.7em;
	opacity: 0;
	/* auto, not none, even while invisible - hovering this exact spot (the
	   far right of the row, where it sits) is what reveals it below. A plain
	   opacity-only hide would leave it unreachable by the mouse until already
	   visible, which never happens. */
	pointer-events: auto;
	transition: opacity 0.12s ease;
}
/* Hovering the x's own spot at the far right of the row reveals it - not
   hovering anywhere in the row, which read as it popping up unpredictably
   while just mousing over phrase or cypher values. Keyboard focus (Tab, or
   a tap on a touch device - .hP or .histClearTab has tabindex="0", see
   updateHistoryTable()) still reveals it too, since there is no separate
   control for a phone to reach it with any more. Scoped to .histRow, not
   the specific tabindex holder, so the same rule covers both the per-row x
   and the header row's whole-table x. */
.histDelX:hover,
.histRow:focus-within .histDelX {
	opacity: 1;
}
.histDelX:hover { background-color: hsla(5 60% 45% / 0.3); color: hsl(5 70% 78%); }
/* armed: the next tap deletes. Same idea and colour as .profileArmed - one
   more click carries it out, rather than leaning on window.confirm(), which
   browsers can silently suppress. */
.histDelX.profileArmed {
	width: auto;
	border-radius: 4px;
	padding: 0.2em 0.5em;
	background-color: hsl(5 60% 42%);
	border-color: hsl(5 65% 58%);
	color: #fff;
	font-weight: 600;
	font-size: 78%;
}
.mP, .mPQ { /* history table - top left cell */
	font-weight: 500;
	font-size: 125%;
}
/* The caption is a label for the table, not a heading over it - at 125% it
   read larger than the cipher names it sits beside. Only .mP is changed so
   the query table's corner cell keeps its original size. */
.mP {
	font-size: 88%;
	line-height: 1.25;
	overflow-wrap: anywhere;
	cursor: text;
}
/* While editing, the cell grows with what is typed rather than forcing the
   text to wrap inside the old corner width - the field is sized in JS from its
   own content. */
.mPEdit {
	box-sizing: content-box;
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 100%;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.15em 0.35em;
	outline: none;
	text-align: center;
	min-width: 6em;
	max-width: 22em;
}
.mPQ { /* query table - top left cell */
	/*width: 300px;*/
	height: 150px;
}
.gV, .gVQ { /* gematria value in history/query table */
	font-size: 125%;
	font-weight: 500;
	cursor: pointer;
}
/* Wheel cipher values: same look, but deliberately not .gV/.gVQ so the
   number-properties tooltip never fires on a symbol string. No pointer either,
   since there is nothing to open. */
.gVW, .gVQW {
	font-size: 100%;
	font-weight: 500;
	overflow-wrap: anywhere;
}
.gV, .gVW {
	padding: 0em 0.2em;
}
.pCHT { /* phrase comment - history table */
	font-size: 75%;
	font-weight: 500;
	/*color: hsl(0 0% 30% / 1);*/
	color: var(--font-white-4);
	padding-right: 0.35em;
}

/* -------------- Highlighting -------------- */
.highlightCipherTable {
	background: rgba(192,192,192,0.15);
}
.hideValue {display: none !important;}
@keyframes blink {
	0% {
		opacity: 0.0;
	}
	25% {
		opacity: 1.0;
	}
	75% {
		opacity: 1.0;
	}
	100% {
		opacity: 0.0;
	}
}
.highlightValueBlink {
	animation: blink 500ms linear infinite;
	z-index: 99;
}
.selectedPhrase {
	background-color: hsla(var(--global-hue) 15% 50% / 0.2)
}

/*                Options Menu                */
/* ########################################## */

.intBtn { /* Big Buttons */
	display: inline-block;
	color: var(--font-white-1);
	color: var(--font-white-2);
	padding: 0.4em 0.75em;
	border: 1px solid var(--border-accent);
	width: 100%;
	font-size: 100%;
	font-weight: 500;
	font-family: var(--font-family), "Arial", sans-serif;
	outline: none;
	background-color: var(--btn-bg-accent);
	/*background-color: transparent;*/
}
.intBtn2, .ciphEditBtn { /* Cipher Categories */
    display: inline-block;
    color: var(--font-white-1);
    color: var(--font-white-2);
    padding: 0.15em 0.6em; /* Padding for breathing room */
    margin: 0.1em 0.05em; /* Margin for subtle spacing */
    border: 1px solid var(--border-accent);	  
    width: 100%;
    font-size: 100%;
    font-weight: 500;
    font-family: var(--font-family), "Arial", sans-serif;
    outline: none;
    background-color: var(--btn-bg-accent);

    /* Default behavior for short text (no wrapping) */
    white-space: nowrap; /* Prevent wrapping by default */
    overflow-wrap: normal; /* Don't break words unnecessarily */
    text-align: center; /* Center-align the text */
    line-height: 1.2; /* Line height for readability */
    min-height: auto; /* Allow dynamic height */
}

/* Cyphers menu: category list beside the cypher checkboxes, tools underneath.
   The columns were inline percentage floats, which on a narrow screen left the
   category column too small for its own labels. A min-width keeps the names
   readable and the detail column takes whatever is left. */
.ciphersContent { width: 380px; }
.ciphCatCol {
	float: left;
	width: 30%;
	min-width: 108px;
}
.ciphDetailCol {
	float: left;
	width: 70%;
}
/* blank gap between the category groups - see createCiphersMenu() in calc.js */
.ciphCatDivider { height: 0.6em; }
.ciphDetailCol #menuCiphCatDetailsArea { margin: 0em 0.25em 0em 1.25em; }
/* per-category lead-in note text, also reused between the pinned-cypher
   tables further down the same list - see cipherCatSpecial in calc.js */
.ciphCatNote {
	font-style: italic;
	font-size: 85%;
	color: var(--separator-accent);
	padding-bottom: 0.5em;
}
.ciphCatNote:not(:first-child) { margin-top: 0.5em; }
.ciphToolRow {
	clear: both;
	padding-top: 0.5em;
	margin-top: 0.4em;
	border-top: 1px solid var(--separator-accent2);
}

@media (max-width: 911px) { /* mobile */
	/* Use the width that is actually available rather than shrink-to-fit, so
	   the category column gets its min-width instead of being squeezed.
	   Qualified with .dropdown-content to outrank the generic mobile rule
	   below, which sets width:auto !important at the same specificity and
	   would otherwise win by coming later in the file. */
	.dropdown-content.ciphersContent {
		width: calc(100vw - 1em) !important;
		max-width: calc(100vw - 1em) !important;
	}
	.ciphCatCol { width: 38%; }
	.ciphDetailCol { width: 62%; }
	.ciphDetailCol #menuCiphCatDetailsArea { margin-left: 0.6em; }
}

/* Long category names, sized down just enough to fit the fixed-width column */
.intBtn2.ciphCatLong {
    font-size: 90%;
    padding-left: 0.35em;
    padding-right: 0.35em;
}

/* Special class for "Gematria Club" that needs wrapping */
.intBtn2.gematriaClub {
    white-space: normal; /* Allow wrapping */
    overflow-wrap: break-word; /* Break words if necessary */
    font-size: 90%; /* Slightly smaller text */
    padding: 0.15em 0.5em; /* Adjust padding for longer text */
    max-width: 180px; /* Optional: Limit the width */
}

.ciphEditBtn {
	width: auto;
	margin: 0.75em 0.5em 0em 0.5em;
}
.intBtn3, .intBtnResetDate, #queryDBbtn, #enterPhraseBtn { /* Empty, Default, All */
	display: inline-block;
	color: var(--font-white-1);
	color: var(--font-white-2);
	padding: 0.2em 0.75em;
	margin: 0em 0.1em 0.5em 0.1em;
	border: 1px solid var(--border-accent);
	width: 85px;
	font-size: 100%;
	font-weight: 500;
	font-family: var(--font-family), "Arial", sans-serif;
	outline: none;
	background-color: var(--btn-bg-accent);
	/*background-color: transparent;*/
}
@media (max-width: 911px) { /* mobile */
	#queryDBbtn {
		min-width: 30px !important;
		width: 30px !important;
	}
}
.closeMenuBtn {
	position: absolute;
	right: -29px;
	top: -5px;
	width: 30px;
	height: 30px;
	border: none;
	outline: none;
	padding: none;
	font-size: 150%;
	font-weight: 600;
	font-family: var(--font-family), "Arial", sans-serif;
	color: var(--border-accent);
	background-color: transparent;
	cursor: pointer;
}
@media (max-width: 911px) { /* mobile */
	.closeMenuBtn {
		right: 0px !important;
		top: 0px !important;
	}
}
.intBtnResetDate {
	font-size: 80%;
	width: auto;
	margin: 0em;
	padding: 0.3em 0.6em 0.3em 0.6em;
}
#queryDBbtn {
	background-color: var(--input-bg-accent);
	padding: 0em;
	margin: 0em 0.3em;
	width: 75px;
}
#enterPhraseBtn {
	background-color: var(--input-bg-accent);
	padding: 0em;
	margin: 0em 0em 0em 0.3em;
	min-width: 30px;
	max-width: 30px;
	/* was --border-accent, which is the colour of the outline around it - the
	   glyph inside was as dim as the box it sat in and read as decoration */
	color: var(--font-white-3);
	cursor: pointer;
	line-height: 0;
	vertical-align: middle;
}
#enterPhraseBtn:hover { color: var(--font-white-1); }
#enterPhraseBtn svg {
	width: 17px;
	height: 17px;
	display: inline-block;
	vertical-align: middle;
}
#calcNotification {
	position: absolute;
	left: 50%;
	transform: translate(-50%, 0);
	bottom: 40px;
	background: var(--menu-bg-accent);
	border: 1px solid var(--border-dark-accent);
	padding: 1em 1.5em;
	font-size: 125%;
	font-weight: 500;
	border-radius: 15px;
	text-align: center;
	z-index: 1000;
}
.intBtn:hover, .intBtn2:hover, .ciphEditBtn:hover, .intBtn3:hover, .intBtnResetDate:hover, #queryDBbtn:hover, #enterPhraseBtn:hover, .queryPageBtn:hover {
	background-color: var(--btn-hover-accent);
}
.intBtn:active, .intBtn2:active, .ciphEditBtn:active, .intBtn3:active, .intBtnResetDate:active, #queryDBbtn:active, #enterPhraseBtn:active, .queryPageBtn:active {
	background-color: var(--btn-active-accent);
}

.dropbtn {
	background-color: transparent;
	color: var(--font-white-1);
	color: var(--font-white-2);
	padding: 0.4em 1.1em;
	border: none;
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 100%;
	font-weight: 500;
	outline: none;
}
.optionElementTable {
	border-spacing: 0;
	text-align: center;
	margin: 1em;
	border: 1px solid var(--border-accent);
	border-bottom: none;
	text-align: center;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	font-weight: 500;
	width: 87%;
}
.optionElementTable td {
	border-bottom: 1px solid var(--border-accent);
	padding: 0.3em;
}
.enterAsWordsLimit {
	text-align: right;
	border: 1px solid var(--border-accent);
	background-color: var(--btn-bg-accent);
	color: var(--font-white-2);
	font-weight: 500;
	width: 100%;
	box-sizing: border-box;
	border-top: none;
	padding-bottom: 0.1em;
}
.dbOptionsBox {
	margin: auto;
	border: 1px solid var(--border-accent);
	text-align: right;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	font-weight: 500;
	width: 200px;
	box-sizing: border-box;
	border-top: none;
	padding-bottom: 0.1em;
}
.optionTableLabel {
	font-size: 80%;
}
#phrLimitBox, #dbPageItemsBox, #dbScrollItemsBox, #iScaleBox {
	width: 50px;
	border: none;
	color: var(--font-white-2);
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 85%;
	outline: none;
	background-color: transparent;
	text-align: center;
	font-weight: 500;
}
.optionElement {
	margin: 0.3em 1em;
	white-space: nowrap; /* text on one line */
}
.optionElementLabel {
	margin: 0em 0.4em 0em 0.3em;
	color: var(--font-white-2);
	font-weight: 500;
}
.dropdown {
	position: relative;
	display: inline-block;
}
.dropdown-content, .dropdown-content-opt {
	display: none;
	position: absolute;
	left: -10px;
	z-index: 200; /* above other elements */
	padding: 1em;
	text-align: left;
	background-color: var(--menu-bg-accent2);
	border: 1px solid var(--border-dark-accent); /* --body-bg-accent */
	/*border-top: none;*/
}
@media (max-width: 911px) { /* mobile */
	.dropdown {
		position: unset !important;
	}
	.dropdown-content, .dropdown-content-opt {
		left: 50% !important;
		transform: translateX(-50%);
		/* the centring above was already right; what was missing is a width cap.
		   Menus keep their desktop pixel widths, so the longest labels ran off
		   the screen edge. Cap to the viewport and scroll instead. */
		width: auto !important;
		min-width: 0 !important;
		max-width: calc(100vw - 1em) !important;
		max-height: calc(100vh - var(--navH, 58px) - 1.5em);
		overflow-y: auto;
		overflow-x: hidden;
		box-sizing: border-box;
	}
	/* About used to opt out of the shared centring with transform: none, which
	   left it starting at the middle of the screen and running off the right
	   edge. It centres like every other menu now. */
	/* The rain panel pins itself to the toggle's right edge on desktop. On
	   mobile that fights the centring above - right:0 stayed set while left
	   became 50%, so the box was measured from the wrong side and the colour
	   swatch fell off the screen. Centre it like every other menu. */
	.rainTuneContent {
		right: auto !important;
		width: auto !important;
		max-width: calc(100vw - 1em) !important;
		box-sizing: border-box;
	}
	.rainTunePanel { min-width: 0; }
}
.dropdown-content-opt {
	padding: 0.5em;
}
/* Heading inside the About menu, separating the Cyphers links from other
   people's calculators. A rule above it rather than a gap, because the buttons
   are already spaced and another gap would not read as a break. */
.aboutGroupLabel {
	margin: 0.9em 0 0.55em 0;
	padding-top: 0.7em;
	border-top: 1px solid var(--separator-accent2);
	font-size: 85%;
	font-weight: 600;
	color: var(--font-white-3);
	text-align: center;
}

/* The Matches panel took on the old Options tab's contents, so it is the one
   dropdown long enough to run past the bottom of a short window. */
.findMatchesContent {
	max-height: calc(100vh - 4.5em);
	overflow-y: auto;
}

.dropdown:hover .dropdown-content, .dropdown:hover .dropdown-content-opt {display: block;}
/* forces a dropdown open for a tour step (calc/tour.js) that needs a button
   or field inside it visible on a device with no hover at all - the Matches
   dropdown for "Enter As Words", the Cyphers dropdown for the cypher search
   box. Any future tour step over another dropdown gets the same behaviour
   for free by adding its own :has() clause here. */
body.tourForceDropdown .dropdown:has(.findMatchesTab) .dropdown-content,
body.tourForceDropdown .dropdown:has(.ciphersContent) .dropdown-content { display: block !important; }

.dropdown:hover .dropbtn {background-color: var(--btn-active-accent);}

/*             Print Image Preview            */
/* ########################################## */

.printImageContainer {
	background-color: var(--menu-bg-accent2);
	color: var(--font-white-2);
	background-color: black;
	border: 1px solid var(--border-dark-accent);
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 100%;
	position: absolute;
	top: 15%;
	left: 15%;
	height: 77%;
	width: 70%;
	overflow: auto;
	z-index: 1000;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}
@media (max-width: 911px) { /* mobile */
	.printImageContainer {
		top: 50% !important;
		left: 50% !important;
		transform: translateX(-50%) translateY(-50%);
		width: 90% !important;
		height: 80% !important;
	}
}
#downImgBtn, .refreshImgBtn {
    font-size: 125%;
    font-weight: 500;
    color: var(--font-white-2);
    background-color: var(--menu-bg-accent2);
    text-decoration: none;
    padding: 0.35em 1em;
    border: none;
    outline: none;
    border-radius: 20px;
	margin: 1.35em 0.3em 0em 0.3em;
}
#imgData {
	padding: 1.5em 2em;
}
.prevBtnArea {
	display: inline-block;
}
.imgDataArea {
	display: grid;
	place-items: center;
	overflow: auto;
}
.imgDataArea img { /* wide breakdowns used to overflow the preview and get clipped */
	max-width: 100%;
	height: auto;
}

/*        Word Breakdown Export Styling       */
/* ########################################## */

.breakExportHeader {
	text-align: center;
	padding: 0.2em 1em 0.9em 1em;
}
.breakExportPhrase {
	font-size: 155%;
	font-weight: 600;
	color: var(--font-white-1);
	line-height: 1.25em;
	max-width: 34em; /* wraps between words instead of running off the image */
	margin: 0 auto;
	overflow-wrap: break-word;
}
.breakExportMeta {
	padding-top: 0.35em;
}
.breakExportTotal {
	font-size: 175%;
	font-weight: 600;
	color: var(--font-white-1);
	padding-right: 0.4em;
}
.breakExportCiph {
	font-size: 120%;
	font-weight: 500;
}
.breakExportMode { /* applied to #BreakdownSpot only while the image is captured */
	background-color: var(--body-bg-accent); /* solid, so the PNG is not transparent */
	padding: 1.1em 1.4em 1.2em 1.4em;
	border: 1px solid var(--border-dark-accent);
}
.breakExportMode .BreakVal,
.breakExportMode .BreakValDark { /* dim grey values were the main legibility complaint */
	color: var(--font-white-2);
	font-size: 80%;
}
.breakExportMode .BreakChar {
	font-size: 125%;
}
.breakExportMode .LetterCounts {
	padding-bottom: 0.4em;
}
#downImgBtn:hover, .refreshImgBtn:hover { background-color: var(--btn-hover-accent); }
#downImgBtn:active, .refreshImgBtn:active { background-color: var(--btn-active-accent); }

/*              Number Properties             */
/* ########################################## */

.numProp {
	cursor:pointer;
}
.numPropPopoverShell {
	max-width: calc(100vw - 1em);
	width: max-content;
	position: absolute;
	z-index: 101;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
}
.numPropTooltip {
	max-width: min(350px, calc(100vw - 1em));
	max-height: calc(100vh - 1em);
	width: max-content;
	margin: 0;
	padding: 0.75em 1em 1em 1em;
	background-color: var(--menu-bg-accent);
	font-family: var(--font-family), "Arial", sans-serif;
	border: 1px solid var(--border-dark-accent);
	box-sizing: border-box;
	overflow: auto;
	overscroll-behavior: contain;
}
.numPropPopoverShell[data-variant="alternate"] .numPropTooltip {
	max-width: min(44rem, calc(100vw - 1em));
}
.numPropPopoverShell[data-mode="pinned"] .numPropTooltip {
	max-height: calc(100vh - 1em - 44px);
}
.numPropPopoverClose {
	width: 44px;
	height: 44px;
	padding: 0;
	margin: 0 0 -1px 0;
	border: 1px solid var(--border-dark-accent);
	background: var(--menu-bg-accent2);
	color: var(--font-white-1);
	font: 700 1.4rem/1 var(--font-family), "Arial", sans-serif;
	cursor: pointer;
}
.numPropPopoverClose:hover {
	background: var(--btn-hover-accent);
}
.numPropPopoverClose:focus-visible {
	outline: 2px solid var(--font-white-1);
	outline-offset: 2px;
}
.numPropTable {
	text-align: center;
}
.numPropLabel {
	color: var(--font-white-1);
	font-size: 115%;
	font-weight: 500;
}
.numValLabel {
	color: var(--font-white-2);
	font-size: 180%;
	font-weight: 600;
	padding: 0em;
}
.numPropCenter {
	text-align: center;
}
.numPropSeparator {
	background-color: var(--separator-accent);
	border: none;
	height: 2px;
}
.numPropBaseLabel {
	font-size: 90%;
	text-align: left;
	margin-left: 0.4em;
}
.numPropBaseValue {
	font-size: 110%;
	font-family: var(--font-family-mono), sans-serif;
}
.numTicXeno {
	/*font-size: 85%;*/
	/*font-family: var(--font-family-mono), sans-serif;*/
	font-size: 100%;
	font-family: var(--font-family), "Arial", sans-serif;
	font-weight: 500;
}
.numPropValPad {
	margin-right: 0.4em;
	margin-left: 0.4em;
}
.npSmall {
	font-size: 70%;
	font-weight: 500;
	color: var(--separator-accent);
}
.npLine {
	line-height: 0.9em;
}

/*              Edit Ciphers Menu             */
/* ########################################## */

.editCiphersContainer {
	position: relative;
	margin: 0.5em 0em 0.5em 0em;
	padding: 1em;
	background: var(--menu-bg-accent);
	width: -webkit-fit-content;
	width: -moz-fit-content;
	border: 1px solid var(--border-dark-accent);
}
.custCipherMainTable {
	margin: 0.5em 0em 0.5em 0em;
	/*width: 570px;*/
}
.custCipherTable {
	/*margin: 0em 0em 0.75em 0em;*/
}
#custCipherNameInput, #custCipherCatInput {
	background: var(--btn-bg-accent);
	font-size: 125%;
	color: var(--font-white-2);
	font-family: var(--font-family), "Arial", sans-serif;
	font-weight: 500;
	text-align: center;
	width: 100%;
	box-sizing: border-box;
	border: 1px solid var(--border-dark-accent);
}
#custCipherAlphabet, #custCipherGlobVals {
	background: var(--btn-bg-accent);
	font-size: 125%;
	color: var(--font-white-2);
	font-family: var(--font-family), "Arial", sans-serif;
	font-weight: 500;
	width: 500px;
	text-align: center;
	resize: none;
	width: 100%;
	box-sizing: border-box;
	border: 1px solid var(--border-dark-accent);
}
#custCipherGlobVals {
	font-size: 100%;
	height: 40px;
}
#custCipherAlphabet:focus, #custCipherGlobVals:focus,
#custCipherNameInput:focus, #custCipherCatInput:focus {
	outline: none;
	border: 1px solid var(--border-dark-accent);
}
.custCharInd:focus, .custCharIndValue:focus {
	outline: none;
	border: none;
}
#diacrChkbox, #caseSensChkbox {
	display: inline-flex;
	padding: 0em 1em 0.75em 1em;
}
.custCharIndTable {
	width: 40px;
	border-spacing: 0px;
	border: none;
}
.custCharIndLabel {
	text-align: center;
	background: var(--btn-bg-accent);
	height: 38px;
	box-sizing: border-box;
	border: 1px solid var(--border-dark-accent);
}
.custCharInd {
	width: 40px;
	text-align: center;
	font-weight: 500;
	font-size: 150%;
	font-family: var(--font-family), "Arial", sans-serif;
	border: none;
	background: transparent;
	color: var(--font-white-2);
}
.custCharIndValue {
	width: 40px;
	text-align: center;
	font-weight: 500;
	font-size: 100%;
	padding: 0.2em 0.2em 0.2em 0.2em;
	font-family: var(--font-family), "Arial", sans-serif;
	border: none;
	background: transparent;
	color: var(--font-white-2);
}
@media (max-width: 911px) { /* mobile */
	.custCharInd, .custCharIndValue {
		width: 30px !important;
	}
}

/*               Date Calculator              */
/* ########################################## */

.dateCalcContainer {
	position: relative;
	margin: 0.5em 0em 0.5em 0em;
	padding: 1em;
	background: var(--menu-bg-accent);
	width: -webkit-fit-content;
	width: -moz-fit-content;
	display: flex;
	height: 340px;
	border: 1px solid var(--border-dark-accent);
}
@media (max-width: 911px) { /* mobile */
	.dateCalcContainer {
		display: block;
		height: unset !important;
	}
}
.dateCalcTable, .dateCalcTable2 {
	text-align: center;
}
.dateCalcTable {
	margin: auto;
}
.dateCalcTable2 { /* the From/to results box, sized up for readability */
	line-height: 1.05em;
	padding: 1em 1em 0.9em 1em;
	background: var(--btn-bg-accent);
}
.dateCalcTable2 .dateDescription { /* "From" / "to" labels */
	font-size: 100%;
}
.dateCalcTable2 .dateDetailsText { /* the dates themselves and the duration lines */
	font-size: 118%;
	font-weight: 500;
}
.elemBorderScr {
	border: 1px solid var(--border-dark-accent);
}
.dateCalcBg {
	min-width: 370px;
	margin: 0em 0em 0em 0.9em;
	background: var(--btn-bg-accent);
	display: flex;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--border-dark-accent);
	box-sizing: border-box;
}
@media (max-width: 911px) { /* mobile */
	.dateCalcBg {
		margin: 1em 0em 0em 0em !important;
		/* was a fixed 350px, which flex-centred a much shorter table and left a
		   dead gap above it; and a 370px min-width that ignored the container */
		height: auto;
		min-width: 0;
		width: 100%;
		padding: 0.6em 0em;
	}
	.dateCalcTable2 {
		width: 100%;
		box-sizing: border-box;
	}
}
.dateInputLabel {
	font-weight: 500;
	font-size: 80%;
	color: var(--focus-outline);
}
.dateNthLabel, .dateOffsetLabel {
	color: var(--separator-accent);
	font-size: 68%;
}
.dateOffsetLabel {
	font-weight: 500;
}
.dateDescription {
	box-sizing: border-box;
	width: 100%;
	background: var(--btn-bg-accent);
	color: var(--font-white-2);
	outline: none;
	border: none;
	text-align: center;
	font-family: var(--font-family), "Arial", sans-serif;
	font-weight: 600;
	font-size: 80%;
	padding: 0em;
	line-height: normal !important;
}
.dateFullTable2 {
	font-weight: 600;
	font-size: 128%;
	color: var(--font-white-2);
}
.dateInput, .dateInputYear, .offsetDateInput, #queryPosInput {
	text-align: center;
	width: 60px;
	font-size: 150%;
	color: var(--font-white-1);
	border: 2px solid var(--border-accent);
	box-sizing: border-box;
	font-family: var(--font-family), "Arial", sans-serif;
	font-weight: 500;
	line-height: 1.1em;
	background-color: var(--btn-bg-accent);
}
.offsetDateInput {
	font-size: 80%;
	font-weight: 600;
	color: var(--focus-outline);
	padding: 0.2em 0em;
}
.dateInputYear {
	width: 110px;
}
.dateDetailsText {
}
#d1full, #d2full {
	font-weight: 600;
}
.endDateLabel {
	font-size: 85%;
	margin: 0em 0.4em 0em 0.3em;
	color: var(--font-white-2);
	font-weight: 500;
}
.weekDayLabel {
	font-weight: 400;
	font-size: 108%;
	color: var(--font-white-3);
}
.durVal {
	font-weight: 600;
	color: var(--font-white-2);
}
.dOfYear {
	font-weight: 600;
	color: var(--font-white-3);
}
#dateDurValues {
	line-height: 1.1em;
	color: var(--font-white-3);
}
.dateDurLine {
	font-size: 80%;
	font-weight: 500;
}
.highlightDurLine {
	background: var(--highlight-date);
	padding: 0em 0.5em;
}

/*                Query Table                 */
/* ########################################## */

#queryArea {
	width: 30%;
	position: absolute;
	/* border-right: 1px solid var(--border-accent); */
	top: 45px;
	left: 100px;
	overflow: auto;
	max-height: 92%;
	border: 1px solid var(--border-accent);
	/* background-color: var(--query-bg-accent); */
	resize: horizontal;
}
@media (max-width: 911px) { /* mobile */
	#queryArea {
		left: 40px !important;
	}
}
.queryPageBtn {
	font-size: 100%;
	color: var(--font-white-2);
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-dark-accent);
	padding: 0em 0.35em;
}
#queryMinBtn {
	position: absolute;
	width: 24px;
	left: calc(100% - 24px);
	height: 24px;
	text-align: center;
	box-sizing: border-box;
	color: var(--border-accent);
	background: var(--hist-header-gradient);
	border: 1px solid var(--border-accent);
	border-bottom: 2px solid var(--border-accent);
	cursor: pointer;
	user-select: none;
}
#queryMinBtn:hover {
	background-color: var(--btn-bg-accent);
}
#queryMinBtn:active {
	background-color: var(--btn-hover-accent);
}
.queryTextResult {
	padding: 1em;
	line-height: 2em;
}
.qSlider {
	-webkit-appearance: none;
	width: calc(100% - 24px);
	height: 24px;
	background: var(--hist-header-gradient);
	outline: none;
	margin: 0;
	border: 1px solid var(--border-accent);
	border-bottom: 2px solid var(--border-accent);
	display: block;
	box-sizing: border-box;
}
.qSlider:hover {
	opacity: 1;
}
.qSlider::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 12px;
	height: 24px;
	background: var(--border-dark-accent);
	cursor: pointer;
}
.qSlider::-moz-range-thumb {
	width: 12px;
	height: 24px;
	background: var(--border-accent);
	cursor: pointer;
}
#queryPosInput {
	width: 95px;
	font-size: 100%;
	/* background: transparent; */
	/* border: none; */
	outline: none; 
	color: var(--font-white-2);
	caret-color: transparent !important;
	background-color: var(--body-bg-accent);
	border: 1px solid var(--border-dark-accent);
	border-left: none;
	border-right: none;
}
#queryPosInput:focus {
	border: 1px solid var(--focus-outline);
}
#querySearchInput {
	text-align: center;
	width: 100%;
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 125%;
	font-weight: 500;
	line-height: 1.1em;
	color: var(--font-white-2);
	background-color: var(--body-bg-accent);
	box-sizing: border-box;
	border: 1px solid var(--border-dark-accent);
	border-top: none;
	outline: none;
	padding: 0.3em 0em;
}
.minimizeQuery {
	resize: none !important;
	transition: 0.2s;
	transform: translate(calc(-87% - 100px), 0);
}
@media (max-width: 911px) { /* mobile */
	.minimizeQuery {
		transform: translate(calc(-87% - 40px), 0) !important;
	}
}
.minimizeLabel {
	position: absolute;
	margin: 0.3em 1em 0.15em 0.15em;
	right: 24px;
	user-select: none;
	pointer-events: none;
	font-size: 75%;
	font-weight: 600;
	color: var(--border-accent);
}

/*              Quick Start Guide             */
/* ########################################## */

#darkOverlay {
	background-color: rgba(0,0,0,0.5);
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
	z-index: 999;
}
.quickGuide {
	background-color: var(--menu-bg-accent2);
	color: var(--font-white-2);
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 100%;
	padding: 1em 2em 1em 2em;
	position: absolute;
	top: 10%;
	left: 30%;
	height: 80%;
	width: 40%;
	overflow: auto;
	z-index: 1000;
	border: 1px solid var(--border-dark-accent);
}
@media (max-width: 911px) { /* mobile */
	.quickGuide {
		top: 50% !important;
		left: 50% !important;
		transform: translateX(-50%) translateY(-50%);
		width: 80% !important;
		height: 80% !important;
	}
	/* the contact form is short, so it should not be stretched to 80% of the
	   screen with the rest left empty */
	.quickGuide.contactPanel {
		height: auto !important;
		max-height: 80% !important;
	}
}
/* Quickstart Guide topic picker */
.qgIntro {
	font-size: 88%;
	color: var(--font-white-3);
	margin: 0.1em 0 0.7em 0;
}
.qgTopicBar {
	display: flex;
	flex-wrap: wrap;
	gap: 0.3em;
	padding-bottom: 0.7em;
	border-bottom: 1px solid var(--separator-accent2);
}
.intBtn3.qgTopicBtn {
	width: auto;
	margin: 0;
	padding: 0.25em 0.7em;
	font-size: 88%;
	flex: 0 0 auto;
}
.intBtn3.qgTopicBtn.qgTopicOn {
	background-color: var(--btn-active-accent);
	color: var(--font-white-1);
	font-weight: 600;
}
/* The chosen topic scrolls on its own, so the credits underneath stay put
   instead of being pushed off the bottom by a long section. */
.qgBody {
	max-height: 46vh;
	overflow-y: auto;
	padding: 0.2em 0.1em 0.4em 0.1em;
}

/* Contact panel - reuses the guide's overlay, but it is a short form so it
   sizes to its content instead of filling the screen */
.quickGuide.contactPanel {
	height: auto;
	max-height: 80%;
	top: 12%;
}
/* balance stops the last line of a short paragraph being a single stranded
   word, which is what these are: two or three lines each */
.contactPanel .qgIntro,
.contactPanel .contactFoot,
.contactPanel .contactLabel {
	text-wrap: pretty;
	text-wrap: balance;
	max-width: 46ch;
}
/* Gematro credit - two short paragraphs, so it sizes to them rather than
   being stretched down 80% of the screen with the rest left empty */
.quickGuide.creditPanel {
	height: auto;
	max-height: 80%;
	top: 14%;
}
@media (max-width: 911px) { /* mobile - matches the contact panel's exception */
	.quickGuide.creditPanel {
		height: auto !important;
		max-height: 80% !important;
	}
}
.creditPanel p {
	text-wrap: pretty;
	text-wrap: balance;
	max-width: 46ch;
}
.creditPanel a { color: var(--font-white-1); }

/* Cyphers (Info) - no topic bar or Special Thanks footer eating into the
   panel's height here, so its body can use nearly all of it. */
.cyphersInfoBody {
	max-height: 68vh;
}

/* the three addresses at the top of the Contact panel - see contactEmailList() */
.contactEmails {
	display: flex;
	flex-direction: column;
	gap: 0.35em;
	padding: 0.2em 0 1em 0;
	margin-bottom: 0.8em;
	border-bottom: 1px solid var(--separator-accent2);
}
.contactEmailRow { display: flex; align-items: baseline; gap: 0.6em; font-size: 92%; }
.contactEmailLabel {
	flex: 0 0 7em;
	font-weight: 600;
	color: var(--font-white-3);
}
.contactEmailRow a { color: var(--font-white-1); }
.contactEmailRow a:hover { text-decoration: underline; }
@media (max-width: 911px) { /* mobile: label above address rather than a cramped row */
	.contactEmailRow { flex-direction: column; gap: 0.1em; }
	.contactEmailLabel { flex-basis: auto; }
}

.contactField { padding-bottom: 0.8em; }
.contactLabel {
	display: block;
	font-size: 88%;
	font-weight: 600;
	color: var(--font-white-2);
	padding-bottom: 0.3em;
}
.contactSelect, .contactTextarea {
	width: 100%;
	box-sizing: border-box;
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 95%;
	color: var(--font-white-1);
	background-color: var(--input-bg-accent);
	border: 1px solid var(--border-accent);
	padding: 0.4em 0.5em;
	outline: none;
}
.contactTextarea { resize: vertical; min-height: 5em; }
.contactActions {
	display: flex;
	gap: 0.5em;
	flex-wrap: wrap;
	padding-top: 0.2em;
}
.contactActions .intBtn3 { width: auto; margin: 0; padding: 0.3em 0.8em; }
.contactFoot { padding-top: 0.9em; }

.qgBold, .qgBold2 {
	font-size: 100%;
	font-weight: 500;
	color: var(--font-white-1);
}
.qgBold2 {
	font-size: 150%;
}
.qgMedium {
	font-size: 125%;
}
.qgNote {
	font-style: italic;
	font-size: 85%;
	color: var(--separator-accent);
}
.qgLink{
	font-size: 100%;
	color: var(--font-white-1);
}
.noScroll {
	overflow: hidden;
}

/* Cipher Information & Suggested Bibliography, inside the Ciphers guide topic
   - see quickGuideTopics in quick-guide.js. Native <details>/<summary>, not a
   custom widget: no JS needed for the expand/collapse itself, it is keyboard
   operable for free, and it is the closest thing to an existing "accordion"
   this guide has to be consistent with. */
.qgAcc {
	border: 1px solid var(--border-dark-accent);
	border-radius: 4px;
	margin-bottom: 0.6em;
	padding: 0.3em 0.7em;
}
.qgAcc summary {
	cursor: pointer;
	font-weight: 600;
	font-size: 95%;
	color: var(--font-white-1);
	padding: 0.3em 0;
	list-style: revert;
}
.qgAcc summary::marker { color: var(--font-white-3); }
.qgAcc[open] summary { border-bottom: 1px solid var(--separator-accent2); margin-bottom: 0.5em; }
.qgAccBody { font-size: 92%; padding: 0.2em 0 0.4em 0; }
.qgAccBody p { margin: 0.3em 0 0.6em 0; }
.qgAccBody ul { margin: 0.3em 0; padding-left: 1.2em; }
.qgAccBody li { margin-bottom: 0.7em; }
.qgAccBody .qgNote { display: block; margin-top: 0.15em; }

/* per-cypher toggle nested inside a category's .qgAcc, in "Cyphers (Info)" -
   smaller and less boxy than its parent so the category/cypher hierarchy
   stays readable at a glance. */
.qgAccNested {
	border-color: var(--separator-accent2);
	margin: 0.4em 0;
	padding: 0.15em 0.6em;
}
.qgAccNested summary { font-size: 90%; font-weight: 500; padding: 0.2em 0; }
.qgAccNested .qgAccBody { font-size: 95%; }
.qgBold, .qgBold2, .qgBoldCoin {
	font-size: 100%;
	font-weight: 500;
	color: var(--font-white-1);
}
.qgBold2 {
	font-size: 150%;
}

/*                    About                   */
/* ########################################## */

.contactInfo {
	background-color: var(--menu-bg-accent2);
	color: var(--font-white-2);
	font-family: var(--font-family), "Arial", sans-serif;
	font-size: 100%;
	text-align: center;
	padding: 1em 2em 1em 2em;
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	height: 560px;
	width: 480px;
	overflow: auto;
	z-index: 1000;
	border: 1px solid var(--border-dark-accent);
}
@media (max-width: 911px) { /* mobile */
	.contactInfo {
		width: 400px !important;
		height: 80% !important;
		max-height: 560px !important;
	}
}
.qgBoldCoin {
	font-size: 150%;
	margin: 1em 0em 0.3em 0em;
}
.qgAddr {
	font-family: var(--font-family-mono), monospace;
	color: var(--font-white-1);
}
.qrImg {
	margin: 1em 0em 2.5em 0em;
}

/*               Custom Checkbox              */
/* ########################################## */

.chkLabel {
	display: block;
	position: relative;
	padding-left: 28px;
	cursor: pointer;
}
/* hide default checkbox */
input[type=checkbox] {
	visibility: hidden;
}
/* custom checkbox */
.custChkBox {
	position: absolute;
	top: 50%;
	transform: translate(0, -50%);
	left: 0;
	height: 16px;
	width: 16px;
	background-color: var(--btn-bg-accent);
	border: 1px solid var(--border-accent);
}
.chkLabel:hover input ~ .custChkBox {
	background-color: var(--btn-hover-accent);
}
.chkLabel input:active ~ .custChkBox {
	background-color: var(--btn-active-accent);
}
.chkLabel:hover input:checked ~ .custChkBox {
	background-color: var(--btn-hover-accent);
}
.chkLabel input:checked ~ .custChkBox {
	background-color: var(--btn-bg-accent);
	/*background-color: var(--btn-hover-accent);*/
}
/* show checkmark in checkbox when checked*/
.custChkBox:after {
	content: "";
	position: absolute;
	display: none;
}
.chkLabel input:checked ~ .custChkBox:after {
	display: block;
}
.chkLabel input[type="checkbox"]:disabled ~ .custChkBox, .colSlider:disabled, #queryDBbtn:disabled {
	background-color: var(--btn-hover-accent);
}
/* checkmark style */
.chkLabel .custChkBox:after {
	left: 4px;
	bottom: 4px;
	width: 0px;
	height: 0px;
	border: solid 4px var(--checkmark-accent);
}

/* ===================== Focus mode (screenshot-friendly) =====================
   #focusModeBtn is a fixed element outside #calcMain (index.html) so it is
   never wiped by a menu rebuild and stays reachable even once the nav row
   underneath it is hidden. toggleFocusMode() (calc.js) just flips one class
   on <body> - nothing here deletes or resets anything, so turning it back
   off restores the page exactly as it was. */
.focusModeBtn {
	position: fixed;
	top: 0.6em;
	right: 0.6em;
	z-index: 600;
	width: 2.2em;
	height: 2.2em;
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: none;
	color: var(--font-white-2);
	cursor: pointer;
	opacity: 0.55;
	transition: opacity 0.2s ease, color 0.2s ease;
	filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6)); /* keeps the glyph readable over light rain/backdrops, background stays transparent */
}
.focusModeBtn svg { width: 65%; height: 65%; }
.focusModeBtn:hover { opacity: 1; }
body.focusMode .focusModeBtn {
	opacity: 0.85;
	color: var(--focus-outline);
}

/* Mirrors .focusModeBtn on the opposite corner - opens #focusOptionsPanel,
   which now holds the everyday display toggles (breakdown, cipher chart,
   gradients, live database) as well as the Focus Mode picks, so it is on
   permanently rather than only once Focus Mode is entered. */
.focusOptionsBtn {
	display: flex;
	position: fixed;
	top: 0.6em;
	left: 0.6em;
	z-index: 600;
	width: 2.2em;
	height: 2.2em;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: none;
	color: var(--font-white-2);
	cursor: pointer;
	opacity: 0.85;
	transition: opacity 0.2s ease, color 0.2s ease;
	filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
}
.focusOptionsBtn svg { width: 65%; height: 65%; }
.focusOptionsBtn:hover { opacity: 1; }
body.focusMode .focusOptionsBtn { opacity: 0.85; }

.focusOptionsPanel {
	position: fixed;
	top: 3em;
	left: 0.6em;
	z-index: 601;
	background: var(--menu-bg-accent2);
	border: 1px solid var(--border-dark-accent);
	border-radius: 6px;
	padding: 0.6em 0.9em;
	min-width: 185px;
	/* Taller now that the display toggles moved in from Options - cap it to
	   the viewport and scroll rather than running off the bottom on short
	   windows and phones. */
	max-height: calc(100vh - 4em);
	overflow-y: auto;
}
.focusOptionsTitle {
	font-size: 85%;
	font-weight: 600;
	color: var(--font-white-2);
	padding-bottom: 0.4em;
	margin-bottom: 0.3em;
	border-bottom: 1px solid var(--separator-accent2);
}
/* Second and later group headings in the panel - same look as the first, but
   spaced away from the rows above so the groups read as separate. */
.focusOptionsTitle + .focusOptionRow { margin-top: 0; }
.focusOptionsPanel .focusOptionsTitle ~ .focusOptionsTitle { margin-top: 0.7em; }
/* combined with .chkLabel, which sets display/position/padding-left for the
   custom checkbox - only adding vertical spacing here so that is not undone */
.focusOptionRow {
	font-size: 90%;
	padding-top: 0.25em;
	padding-bottom: 0.25em;
}

body.focusMode #calcOptionsPanel,
body.focusMode #inputArea {
	display: none !important;
}
body.focusMode #calcMain {
	display: flex;
	flex-direction: column;
	justify-content: center;
}
body.focusMode #BreakdownDetails {
	transform: scale(1.12);
}
@media (max-width: 600px) {
	body.focusMode #BreakdownDetails { transform: scale(1.05); }
}

/* The enabled-cyphers badges and letter/word count are noise next to the
   result no matter what else is showing, so those stay hidden
   unconditionally. Everything else is opt-in per #focusOptionsPanel, toggled
   by the focusHide* classes below (applyFocusModeVisibility() in calc.js):
     - "Word sums" is the equation line - "phrase = total (cipher)" - not
       the in-grid per-word totals (52, 71, 37), which are part of
       "Breakdown" below along with the letters and grid total.
     - "Breakdown" is the whole letter-by-letter grid: letters, their
       values, the per-word totals, and the grid's own total.
   Defaults match what Focus Mode always showed before this panel existed
   (word sums shown, breakdown hidden), so nobody sees a change until they
   open it. */
body.focusMode #enabledCiphTable,
body.focusMode .LetterCounts {
	display: none !important;
}
body.focusMode #BreakTableContainer {
	border: none;
	box-shadow: none;
	background: none;
	padding: 0;
	cursor: default;
}
body.focusMode.focusHideWordSums #SimpleBreak,
body.focusMode.focusHideWordSums .SimpleBreakChart,
body.focusMode.focusHideWordSums .SimpleBreakChartLong {
	display: none !important;
}
/* #BreakSumLong (the grid's own total, long phrases) and .BreakCipherName (the
   cypher name under it) are "the grid's own total" per the comment above -
   Breakdown's job, not Word sums' - so they hide with the rest of the grid.
   Left out of this list before, a long phrase with Breakdown off still showed
   its total and cypher name sitting there with nothing above it. */
body.focusMode.focusHideBreakdown #BreakTableContainer .BreakChar,
body.focusMode.focusHideBreakdown #BreakTableContainer .BreakVal,
body.focusMode.focusHideBreakdown #BreakTableContainer .BreakValDark,
body.focusMode.focusHideBreakdown #BreakTableContainer .BreakWordSum,
body.focusMode.focusHideBreakdown #BreakTableContainer .BreakPhraseSum,
body.focusMode.focusHideBreakdown #BreakSumLong,
body.focusMode.focusHideBreakdown .BreakCipherName {
	display: none !important;
}
body.focusMode.focusHideCipherChart #ChartSpotScroll {
	display: none !important;
}
body.focusMode.focusHideHistoryTable #HistoryTableArea {
	display: none !important;
}
