/*
 * The annotator stage.
 *
 * The palette is the desktop viewer's, so a sample looks the same in either:
 * the stain is a deep blue-violet, and a lighter chrome around it shifts the
 * apparent colour of the tissue. Everything here is scoped to .phnuclei so a
 * theme's own rules cannot reach the canvas furniture, and vice versa.
 */

.phnuclei {
	--phnuclei-bg: #1b1b1b;
	--phnuclei-panel: #242424;
	--phnuclei-line: #3a3a38;
	--phnuclei-fg: #e8e8e8;
	--phnuclei-hint: #9a9a9a;
	--phnuclei-button: #333331;
	--phnuclei-button-hover: #444442;
	--phnuclei-height: min(78vh, 900px);

	/* The colour popover is placed against a swatch, so the stage has to be
	   the containing block for it. */
	position: relative;
	display: flex;
	align-items: stretch;
	box-sizing: border-box;
	width: 100%;
	height: var(--phnuclei-height);
	/* Only the block margin is set here: a full-width stage takes its inline
	   margins from the theme's own alignfull rule, and a shorthand would
	   silently reset those back to zero. */
	margin-block: 1.5rem;
	border: 1px solid var(--phnuclei-line);
	border-radius: 10px;
	overflow: hidden;
	background: var(--phnuclei-bg);
	color: var(--phnuclei-fg);
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	font-size: 14px;
	line-height: 1.4;

	/* A drag that leaves the canvas must not select the article around it. */
	user-select: none;
	-webkit-user-select: none;
}

.phnuclei *,
.phnuclei *::before,
.phnuclei *::after {
	box-sizing: border-box;
}

/*
 * The `hidden` attribute only carries `display: none` from the UA stylesheet,
 * which any author `display` here outranks -- the drop overlay and the step
 * arrows both set `display: grid`, so both were painted whatever the attribute
 * said. Everything in the component is toggled through `hidden`, so state it
 * once and mean it.
 */
.phnuclei [hidden] {
	display: none !important;
}

/* ------------------------------------------------------ the sample rail --- */

.phnuclei-films {
	flex: 0 0 218px;
	display: flex;
	flex-direction: column;
	min-height: 0;
	padding: 14px 0 0;
	border-right: 1px solid var(--phnuclei-line);
	background: var(--phnuclei-panel);
}

.phnuclei-film-list {
	flex: 1 1 auto;
	min-height: 0;
	margin: 8px 0 0;
	padding: 0 8px 8px;
	overflow-y: auto;
	list-style: none;
}

.phnuclei-film-empty {
	padding: 8px 6px;
	color: var(--phnuclei-hint);
	font-size: 12px;
}

.phnuclei-film { margin: 0 0 4px; }

.phnuclei-film-button {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	padding: 4px;
	border: 1px solid transparent;
	border-radius: 6px;
	background: none;
	color: var(--phnuclei-fg);
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.phnuclei-film-button:hover { background: #2c2c2c; }
.phnuclei-film-button:focus-visible { outline: 2px solid #4f7dff; outline-offset: -2px; }

.phnuclei-film.is-current .phnuclei-film-button {
	border-color: #4f7dff;
	background: #2f3550;
}

.phnuclei-film-thumb {
	flex: 0 0 auto;
	width: 52px;
	height: 52px;
	border-radius: 4px;
	background: #141414;
	object-fit: cover;
}

.phnuclei-film-thumb.is-missing { opacity: 0.25; }

.phnuclei-film-meta {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.phnuclei-film-name {
	overflow: hidden;
	font-size: 12px;
	line-height: 1.25;
	/* Two lines, then an ellipsis: these names are long and nearly identical
	   until the end, so a single truncated line tells the reader nothing. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow-wrap: anywhere;
}

.phnuclei-film-count { font-size: 11px; color: var(--phnuclei-hint); }
.phnuclei-film-count.is-empty { opacity: 0.65; font-style: italic; }

/* ------------------------------------------------------------- uploads --- */

.phnuclei-upload {
	flex: 0 0 auto;
	padding: 8px 10px 12px;
	border-top: 1px solid var(--phnuclei-line);
}

.phnuclei-upload-button {
	width: 100%;
	padding: 7px 10px;
	border: 0;
	border-radius: 4px;
	background: var(--phnuclei-button);
	color: var(--phnuclei-fg);
	font: inherit;
	font-size: 12px;
	cursor: pointer;
}

.phnuclei-upload-button:hover { background: var(--phnuclei-button-hover); }

.phnuclei-queue {
	margin: 0 0 8px;
	padding: 0;
	max-height: 132px;
	overflow-y: auto;
	list-style: none;
}

.phnuclei-queue-row {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 2px 6px;
	margin-bottom: 6px;
	font-size: 11px;
	color: var(--phnuclei-hint);
}

.phnuclei-queue-name {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.phnuclei-queue-pct { font-variant-numeric: tabular-nums; }

.phnuclei-queue-bar {
	grid-column: 1 / -1;
	height: 3px;
	border-radius: 2px;
	background: #3a3a38;
	overflow: hidden;
}

.phnuclei-queue-bar > span {
	display: block;
	height: 100%;
	background: #4f7dff;
	transition: width 120ms linear;
}

.phnuclei-queue-row.is-done .phnuclei-queue-bar > span { background: #34c759; }
.phnuclei-queue-row.is-failed { color: #ff8a8a; }
.phnuclei-queue-row.is-failed .phnuclei-queue-bar > span { background: #ff3b30; }

/* The overlay only appears while files are actually over the stage. */
.phnuclei-drop {
	position: absolute;
	inset: 12px;
	display: grid;
	place-items: center;
	z-index: 15;
	border: 2px dashed #4f7dff;
	border-radius: 10px;
	background: rgba(24, 28, 48, 0.82);
	color: var(--phnuclei-fg);
	font-size: 15px;
	pointer-events: none;
}

/* ----------------------------------------------------------- the stage --- */

.phnuclei-stage {
	position: relative;
	flex: 1 1 auto;
	min-width: 0;
	background: var(--phnuclei-bg);
}

.phnuclei-canvas {
	display: block;
	width: 100%;
	height: 100%;
	cursor: crosshair;
	outline: none;
	touch-action: none;   /* the wheel and drag handlers own the gestures */
}

/* Nothing to draw, so the pointer advertises the one gesture that is left. */
.is-readonly .phnuclei-canvas { cursor: grab; }
.is-readonly .phnuclei-canvas:active { cursor: grabbing; }

.phnuclei-canvas:focus-visible {
	outline: 2px solid #4f7dff;
	outline-offset: -2px;
}

/* The two floating step buttons. Drawn as real buttons rather than on the
   canvas so they stay reachable from the keyboard. */
.phnuclei-arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	display: grid;
	place-items: center;
	width: 58px;
	height: 58px;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.28);
	border-radius: 50%;
	background: rgba(18, 18, 18, 0.41);
	color: #fff;
	cursor: pointer;
	transition: background 120ms ease, border-color 120ms ease;
}

.phnuclei-arrow:hover,
.phnuclei-arrow:focus-visible {
	background: rgba(18, 18, 18, 0.75);
	border-color: rgba(255, 255, 255, 0.45);
}

.phnuclei-arrow svg { width: 24px; height: 24px; }
.phnuclei-prev { left: 26px; }
.phnuclei-next { right: 26px; }

/* ------------------------------------------------------- the class panel --- */

.phnuclei-panel {
	flex: 0 0 310px;
	display: flex;
	flex-direction: column;
	min-height: 0;
	padding: 14px 0 12px;
	border-left: 1px solid var(--phnuclei-line);
	background: var(--phnuclei-panel);
}

.phnuclei-panel-title {
	margin: 0 14px 2px;
	padding: 0;
	font-size: 14px;
	font-weight: 700;
	color: var(--phnuclei-fg);
	border: 0;
}

.phnuclei-panel-hint {
	margin: 0 14px 8px;
	font-size: 12px;
	color: var(--phnuclei-hint);
}

.phnuclei-classes {
	flex: 1 1 auto;
	min-height: 0;
	margin: 0;
	padding: 0 10px;
	overflow-y: auto;
	list-style: none;
}

.phnuclei-class {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 2px 0;
	padding: 3px 0;
}

/* The swatch is a button so recolouring is one click, as on the desktop. */
.phnuclei-swatch {
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	padding: 0;
	border: 0;
	border-radius: 4px;
	cursor: pointer;
}

.phnuclei-swatch:focus-visible { outline: 2px solid var(--phnuclei-fg); outline-offset: 2px; }
.is-readonly .phnuclei-swatch { cursor: default; }

.phnuclei-class-label {
	display: flex;
	align-items: center;
	gap: 8px;
	flex: 1 1 auto;
	min-width: 0;
	cursor: pointer;
	color: var(--phnuclei-fg);
}

.phnuclei-class-label input { margin: 0; flex: 0 0 auto; accent-color: #4f7dff; }
.phnuclei-class-name { overflow-wrap: anywhere; }
.phnuclei-class-count { color: var(--phnuclei-hint); }

.phnuclei-class-key {
	flex: 0 0 auto;
	width: 18px;
	text-align: right;
	font-size: 12px;
	color: var(--phnuclei-hint);
}

.phnuclei-panel-buttons {
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 12px 10px 0;
}

.phnuclei-panel-buttons button,
.phnuclei-popover button {
	padding: 6px 10px;
	border: 0;
	border-radius: 4px;
	background: var(--phnuclei-button);
	color: var(--phnuclei-fg);
	font: inherit;
	font-size: 12px;
	cursor: pointer;
}

.phnuclei-panel-buttons button:hover:not(:disabled),
.phnuclei-popover button:hover { background: var(--phnuclei-button-hover); }

.phnuclei-panel-buttons button:disabled { opacity: 0.4; cursor: default; }
.is-readonly .phnuclei-panel-buttons { display: none; }

/* ---------------------------------------------------------- the palette --- */

.phnuclei-popover {
	position: absolute;
	z-index: 20;
	padding: 12px;
	border: 1px solid var(--phnuclei-line);
	border-radius: 8px;
	background: var(--phnuclei-panel);
	box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
}

.phnuclei-swatches {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 6px;
}

.phnuclei-swatches button {
	width: 38px;
	height: 30px;
	padding: 0;
	border: 2px solid transparent;
	border-radius: 4px;
	color: #000;
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
}

.phnuclei-swatches button[aria-pressed="true"] { border-color: var(--phnuclei-fg); }

.phnuclei-popover-row {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 10px;
}

.phnuclei-custom {
	display: flex;
	align-items: center;
	gap: 6px;
	font-size: 12px;
	color: var(--phnuclei-fg);
	cursor: pointer;
}

.phnuclei-custom input {
	width: 28px;
	height: 24px;
	padding: 0;
	border: 1px solid var(--phnuclei-line);
	border-radius: 4px;
	background: none;
	cursor: pointer;
}

/* ------------------------------------------------------------- the page --- */

/* Let the stage use the window when the page is only there to hold it. */
.phnuclei-page .phnuclei { --phnuclei-height: min(86vh, 1100px); }

/*
 * Full width.
 *
 * A block theme constrains every child of `.is-layout-constrained` to the
 * content size and centres it; `alignfull` on the element is what releases it,
 * and the theme's own rule cancels the wrapper's global padding too. All this
 * has to add is dropping the max-width for a classic theme, which has no such
 * rule, and the side borders, which look like a mistake edge to edge.
 */
.phnuclei.is-full {
	/* `width: auto`, not 100%: the theme stretches the box with negative inline
	   margins, and an explicit width over-constrains the box model, so the
	   element would slide left and overflow rather than widen. */
	width: auto;
	max-width: none;
	border-inline: 0;
	border-radius: 0;
}

/* A classic theme has no alignfull rule, so its fixed-width container needs
   the viewport escape instead: `width="breakout"` on the shortcode. It is not
   the default because 100vw includes the scrollbar, which costs a horizontal
   one on any page long enough to scroll. */
.phnuclei.is-full.is-breakout {
	width: 100vw;
	margin-inline: calc(50% - 50vw);
}

@media (max-width: 900px) {
	/* The rail turns into a strip along the top, so the stage keeps its width. */
	.phnuclei { flex-wrap: wrap; }

	.phnuclei-films {
		flex: 1 0 100%;
		flex-direction: row;
		align-items: center;
		gap: 10px;
		max-height: 116px;
		padding: 8px 10px;
		border-right: 0;
		border-bottom: 1px solid var(--phnuclei-line);
	}

	.phnuclei-films .phnuclei-panel-title { display: none; }

	.phnuclei-film-list {
		display: flex;
		gap: 6px;
		margin: 0;
		padding: 0;
		overflow-x: auto;
		overflow-y: hidden;
	}

	.phnuclei-film { margin: 0; }
	.phnuclei-film-button { width: auto; flex-direction: column; gap: 4px; }
	.phnuclei-film-meta { max-width: 84px; }
	.phnuclei-film-name { -webkit-line-clamp: 1; }

	.phnuclei-upload {
		flex: 0 0 auto;
		padding: 0;
		border-top: 0;
		width: 150px;
	}

	.phnuclei-queue { max-height: 56px; }
}

@media (max-width: 782px) {
	.phnuclei {
		flex-direction: column;
		flex-wrap: nowrap;
		--phnuclei-height: min(80vh, 720px);
	}

	.phnuclei-films { flex: 0 0 auto; }

	.phnuclei-panel {
		flex: 0 0 auto;
		max-height: 40%;
		border-left: 0;
		border-top: 1px solid var(--phnuclei-line);
	}

	.phnuclei-arrow { width: 44px; height: 44px; }
	.phnuclei-prev { left: 10px; }
	.phnuclei-next { right: 10px; }
}

@media (prefers-reduced-motion: reduce) {
	.phnuclei-arrow,
	.phnuclei-queue-bar > span { transition: none; }
}
