/**
 * portal.css — the portal's front end.
 *
 * Built to match the existing Welcome Break design: geometric sans, dark navy
 * text, white cards, pill-shaped controls, and tiles with the image on top and
 * a name and count beneath.
 *
 * Every colour and measurement is a variable in the block below, so putting
 * this on a differently-branded portal is one block to edit rather than a hunt
 * through the file. The font deliberately falls back to whatever the theme is
 * using rather than forcing a webfont — the theme already loads the right one.
 */

/*
 * On :root rather than .dmb-portal, because the theme's header, navigation
 * and footer sit outside the portal's own markup. Scoping them to .dmb-portal
 * meant the logout pill and nav links silently fell back to their defaults and
 * ignored the client's branding entirely.
 */
:root {
	--dmb-ink: #22384c;
	--dmb-muted: #6f8090;
	--dmb-line: #e6e9ec;
	--dmb-soft: #f6f8f9;
	--dmb-accent: #22384c;
	--dmb-grey: #8e9296;
	--dmb-grey-dark: #74787c;
	--dmb-radius: 10px;
	--dmb-radius-lg: 14px;
}

/*
 * A note on the accent above.
 *
 * The branding screen only writes out a variable when its value differs from
 * the default — sensible, but it means anything not declared here is simply
 * undefined on a portal using the default colours. --dmb-accent was the one
 * colour missing from this block, so the section rules and buttons fell back
 * to whatever was hardcoded in the rule, which was a different blue entirely.
 *
 * Every variable the branding screen can set now has a baseline here.
 */

.dmb-portal {
	color: var(--dmb-ink);
	font-size: 16px;
	line-height: 1.55;
}

.dmb-portal-inner {
	max-width: 1200px;
	margin: 0 auto;
	padding: 2rem 1.25rem 4rem;
}

/* ------------------------------------------------------------ breadcrumbs */

.dmb-crumbs {
	margin-bottom: 0.75rem;
	/* 14px to 16px — two points up, as asked. */
	font-size: 1rem;
	color: var(--dmb-muted);
}

.dmb-crumbs a {
	color: var(--dmb-muted);
	text-decoration: none;
}

.dmb-crumbs a:hover {
	color: var(--dmb-ink);
	text-decoration: underline;
}

.dmb-crumb-sep {
	margin: 0 0.5rem;
	opacity: 0.45;
}

.dmb-crumb-current {
	color: var(--dmb-ink);
	font-weight: 600;
}

.dmb-folder-header {
	margin-bottom: 1.75rem;
}

.dmb-folder-title {
	margin: 0 0 0.25rem;
	color: var(--dmb-ink);
	font-weight: 600;
}

.dmb-folder-desc {
	margin: 0;
	color: var(--dmb-muted);
}

/* ------------------------------------------------------------------ search */

.dmb-search {
	display: flex;
	align-items: stretch;
	max-width: 620px;
	margin: 0 0 1rem;
	/* The pill shape and the button sitting flush inside it, as on the
	   existing hero search. */
	background: var(--dmb-soft);
	border-radius: 999px;
	overflow: hidden;
	border: 1px solid var(--dmb-line);
}

.dmb-search input[type="search"] {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0.85rem 1.4rem;
	border: 0;
	background: transparent;
	font: inherit;
	color: var(--dmb-ink);
	outline: none;
	-webkit-appearance: none;
	appearance: none;
}

.dmb-search input[type="search"]::placeholder {
	color: var(--dmb-muted);
	opacity: 0.85;
}

.dmb-search button {
	flex: 0 0 auto;
	padding: 0.85rem 2rem;
	border: 0;
	background: var(--dmb-grey);
	color: #fff;
	font: inherit;
	font-weight: 500;
	cursor: pointer;
	transition: background 0.15s;
}

.dmb-search button:hover {
	background: var(--dmb-grey-dark);
}

.dmb-search-inline {
	margin-bottom: 1.5rem;
}

.dmb-filters {
	margin: 0 0 1.25rem;
}

.dmb-filters select {
	padding: 0.6rem 1rem;
	border: 1px solid var(--dmb-line);
	border-radius: 999px;
	background: #fff;
	font: inherit;
	font-size: 0.92rem;
	color: var(--dmb-ink);
	max-width: 340px;
}

/* ------------------------------------------------------------------- tiles */

.dmb-tiles {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: 2rem 1.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.dmb-tile a {
	display: block;
	text-decoration: none;
	color: inherit;
}

.dmb-tile-image {
	display: block;
	aspect-ratio: 4 / 3;
	background-color: var(--dmb-soft);
	background-size: cover;
	/* Same reasoning as the cards: a portrait cover image loses its top
	   otherwise, and a folder's cover is often a photograph of somebody. */
	background-position: center 25%;
	border-radius: var(--dmb-radius);
	transition: box-shadow 0.18s, transform 0.18s;
}

.dmb-tile a:hover .dmb-tile-image {
	box-shadow: 0 8px 24px rgba(34, 56, 76, 0.16);
	transform: translateY(-2px);
}

/* A folder with no image should still look deliberate rather than broken. */
.dmb-tile-image-empty {
	background-image: linear-gradient(135deg, #eef1f4 25%, #e5e9ee 25%, #e5e9ee 50%, #eef1f4 50%, #eef1f4 75%, #e5e9ee 75%);
	background-size: 20px 20px;
}

.dmb-tile-name {
	display: block;
	margin-top: 0.85rem;
	font-size: 1.12rem;
	font-weight: 600;
	color: var(--dmb-ink);
}

.dmb-tile-meta {
	display: block;
	margin-top: 0.15rem;
	font-size: 0.92rem;
	color: var(--dmb-muted);
}

/* -------------------------------------------------------------- asset grid */

.dmb-count {
	margin: 0 0 1rem;
	color: var(--dmb-muted);
	font-size: 0.95rem;
}

.dmb-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
	gap: 1.5rem 1.25rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.dmb-card {
	display: flex;
	flex-direction: column;
	background: #fff;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	overflow: hidden;
	transition: box-shadow 0.18s;
}

.dmb-card:hover {
	box-shadow: 0 6px 20px rgba(34, 56, 76, 0.12);
}

.dmb-card-media {
	display: block;
	aspect-ratio: 4 / 3;
	background: var(--dmb-soft);
	overflow: hidden;
}

.dmb-card-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	/*
	 * Crop from lower down rather than the middle.
	 *
	 * A portrait photograph in a 4:3 box is scaled to fill the width and then
	 * trimmed top and bottom equally — which takes the top off somebody's head,
	 * since that's what's at the top. Biasing the crop upwards keeps faces in
	 * and loses a little more floor, which nobody has ever complained about.
	 *
	 * Landscape photographs are unaffected: they're cropped left and right, and
	 * the vertical position does nothing.
	 */
	object-position: center 25%;
}

/* Non-images show their format rather than an empty box. */
.dmb-card-nopreview {
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--dmb-muted);
	font-size: 0.95rem;
	font-weight: 600;
	letter-spacing: 0.06em;
}

.dmb-card-body {
	flex: 1 1 auto;
	padding: 0.8rem 0.9rem;
}

.dmb-card-title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 0.92rem;
	font-weight: 600;
	color: var(--dmb-ink);
	word-break: break-word;
}

.dmb-card-desc {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin-top: 0.25rem;
	font-size: 0.85rem;
	color: var(--dmb-muted);
}

.dmb-card-download {
	display: block;
	padding: 0.65rem 0.9rem;
	border-top: 1px solid var(--dmb-line);
	font-size: 0.88rem;
	font-weight: 600;
	color: var(--dmb-ink);
	text-align: center;
	text-decoration: none;
}

.dmb-card-download:hover {
	background: var(--dmb-soft);
}

/* --------------------------------------------------------- empty + paging */

.dmb-empty,
.dmb-notice {
	padding: 1.25rem 1.5rem;
	background: var(--dmb-soft);
	border-radius: var(--dmb-radius);
	color: var(--dmb-muted);
}

.dmb-pagination {
	display: flex;
	justify-content: center;
	gap: 0.35rem;
	margin-top: 2.5rem;
	font-size: 0.92rem;
}

.dmb-pagination .page-numbers {
	display: inline-block;
	padding: 0.5rem 0.9rem;
	border-radius: 999px;
	color: var(--dmb-ink);
	text-decoration: none;
}

.dmb-pagination .page-numbers:hover {
	background: var(--dmb-soft);
}

.dmb-pagination .page-numbers.current {
	background: var(--dmb-ink);
	color: #fff;
}

@media (max-width: 640px) {
	.dmb-tiles {
		grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
		gap: 1.25rem 1rem;
	}

	.dmb-grid {
		grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
		gap: 1rem 0.85rem;
	}

	.dmb-tile-name {
		font-size: 1rem;
	}
}

/* =========================================================================
   Hero and landing
   ========================================================================= */

.dmb-hero {
	position: relative;
	min-height: 520px;
	display: flex;
	align-items: center;
	background-color: var(--dmb-soft);
	background-size: cover;
	background-position: center;
}

.dmb-hero-inner {
	width: 100%;
	max-width: 1400px;
	margin: 0 auto;
	padding: 3rem 1.5rem;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 2rem;
	align-items: center;
}

/*
 * The search pill.
 *
 * Rewritten small after four passes of adding things, each of which fixed one
 * artefact and caused another: a backdrop-filter that forced a compositing
 * layer and stair-stepped the curve; a zero-blur spread shadow that did the
 * same; a border whose inner curve didn't meet the button's own radius and
 * left a white crescent between them.
 *
 * What it actually needs is one thing — to be visible on a pale header image —
 * and shadows alone do that. Everything else was decoration that cost more
 * than it returned.
 *
 * No border, no ring, no filter. A solid fill, two blurred shadows, and the
 * children clipped to the shape so the button's end is the pill's end.
 */

.dmb-hero-search form {
	display: flex;
	align-items: stretch;
	max-width: 460px;
	margin: 0 auto;
	border: 0;
	border-radius: 999px;
	overflow: hidden;

	/*
	 * Fully opaque.
	 *
	 * It was 94%, which let 6% of the photograph through — invisible on most
	 * images and a faint dirty tint on a dark one. There is no reason for a
	 * control to be translucent when nothing behind it is meant to be read.
	 */
	background: #fff;

	/* Both layers blurred: a hard-edged shadow is what aliased the curve. */
	box-shadow:
		0 2px 6px rgba( 0, 0, 0, 0.14 ),
		0 14px 34px rgba( 0, 0, 0, 0.24 );
}

.dmb-hero-search form:focus-within {
	/*
	 * outline rather than a shadow or a border: it follows border-radius, the
	 * layout engine antialiases it, and it sits outside the box so nothing
	 * reflows and nothing meets the pill's edge to leave a seam.
	 */
	outline: 2px solid var( --dmb-accent, #22384c );
	outline-offset: 2px;
}

.dmb-hero-search input[type="search"] {
	flex: 1 1 auto;
	min-width: 0;
	padding: 1rem 1.5rem;
	border: 0;
	background: transparent;
	font: inherit;
	color: var(--dmb-ink);
	outline: none;
	-webkit-appearance: none;
	appearance: none;
}

.dmb-hero-search button {
	flex: 0 0 auto;
	padding: 1rem 2.25rem;
	border: 0;
	border-radius: 0;
	background: var(--dmb-grey);
	color: #fff;
	font: inherit;
	font-weight: 500;
	cursor: pointer;
}

.dmb-hero-search button:hover {
	background: var(--dmb-grey-dark);
}

.dmb-hero-panel {
	background: #fff;
	padding: 2.75rem 3rem;
	border-radius: 2px;
}

.dmb-hero-panel h1 {
	margin: 0 0 1.25rem;
	font-size: 2.4rem;
	font-weight: 700;
	line-height: 1.15;
	color: var(--dmb-ink);
}

.dmb-hero-panel p {
	margin: 0 0 1rem;
	font-size: 1.08rem;
	color: var(--dmb-ink);
}

.dmb-hero-panel p:last-child {
	margin-bottom: 0;
}

/*
 * The greeting opens the first paragraph rather than sitting on its own line,
 * so only the name is bold and the sentence carries on around it.
 */
.dmb-hero-panel .dmb-hero-hello strong {
	font-weight: 600;
}

@media (max-width: 900px) {
	.dmb-hero-inner {
		grid-template-columns: 1fr;
	}

	.dmb-hero-panel {
		padding: 1.75rem;
	}

	.dmb-hero-panel h1 {
		font-size: 1.8rem;
	}
}

/* --------------------------------------------------------------- storage */

/*
 * The storage bar on the Dashboard.
 *
 * Dark panel rather than the pale pill it was: it's the one thing on that page
 * that's about the account rather than the library, and it was disappearing
 * into a screen of white cards. Full width for the same reason.
 */
.dmb-storage {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem 1.1rem;
	margin: 0 0 2rem;
	padding: 1.05rem 1.4rem;
	background: #3f464e;
	color: #fff;
	border-radius: var( --dmb-radius-lg, 14px );
	font-size: 0.95rem;
}

.dmb-storage-label {
	color: rgba( 255, 255, 255, 0.72 );
	font-size: 0.88rem;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}

.dmb-storage-value {
	font-weight: 600;
	color: #fff;
	font-size: 1.05rem;
}

.dmb-storage-files {
	font-weight: 400;
	font-size: 0.9rem;
	color: rgba( 255, 255, 255, 0.62 );
}

/*
 * The track is a hole in the panel rather than a light bar on top of it, so the
 * fill reads as filling something.
 */
.dmb-storage-track {
	display: block;
	flex: 1 1 160px;
	max-width: 320px;
	height: 10px;
	border-radius: 999px;
	background: rgba( 0, 0, 0, 0.28 );
	overflow: hidden;
	margin-left: auto;
}

.dmb-storage-fill {
	display: block;
	height: 100%;
	border-radius: 999px;
	background: #45b06a;
	transition: width 0.3s ease;
}

/* Red at 90%: the point of a limit is knowing before you hit it. */
.dmb-storage-fill-full {
	background: #e2574c;
}

.dmb-storage-percent {
	font-size: 0.9rem;
	font-weight: 600;
	color: rgba( 255, 255, 255, 0.85 );
	font-variant-numeric: tabular-nums;
	min-width: 2.6em;
	text-align: right;
}

@media ( prefers-reduced-motion: reduce ) {
	.dmb-storage-fill {
		transition: none;
	}
}

@media ( max-width: 600px ) {
	.dmb-storage-track {
		flex-basis: 100%;
		max-width: none;
		margin-left: 0;
		order: 3;
	}

	.dmb-storage-percent {
		order: 4;
	}
}

/* =========================================================================
   Shared page furniture
   ========================================================================= */

.dmb-narrow {
	max-width: 760px;
}

.dmb-page-title {
	margin: 0 0 1.5rem;
	font-weight: 600;
	color: var(--dmb-ink);
}

.dmb-subtitle {
	margin: 2rem 0 0.5rem;
	font-size: 1.15rem;
	font-weight: 600;
}

.dmb-panel {
	background: #fff;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	padding: 1.75rem 2rem 2rem;
}

.dmb-field {
	margin-bottom: 1.35rem;
}

.dmb-field label {
	display: block;
	margin-bottom: 0.4rem;
}

.dmb-field input[type="text"],
.dmb-field input[type="email"],
.dmb-field input[type="password"],
.dmb-field select {
	width: 100%;
	padding: 0.75rem 1rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	font: inherit;
	color: var(--dmb-ink);
	background: #fff;
}

.dmb-hint {
	display: block;
	margin-top: 0.35rem;
	font-size: 0.88rem;
	color: var(--dmb-muted);
	font-weight: 400;
}

.dmb-radio {
	display: flex;
	align-items: flex-start;
	gap: 0.5rem;
	margin: 0.5rem 0;
	font-weight: 400;
}

.dmb-actions {
	margin: 1.5rem 0 0;
	display: flex;
	gap: 0.75rem;
	align-items: center;
	flex-wrap: wrap;
}

.dmb-button {
	padding: 0.85rem 2rem;
	border: 0;
	border-radius: 999px;
	background: var(--dmb-grey);
	color: #fff;
	font: inherit;
	font-weight: 500;
	cursor: pointer;
	transition: background 0.15s;
}

.dmb-button:hover:not(:disabled) {
	background: var(--dmb-grey-dark);
}

.dmb-button:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.dmb-button-quiet {
	background: transparent;
	color: var(--dmb-ink);
	border: 1px solid var(--dmb-line);
}

.dmb-button-quiet:hover:not(:disabled) {
	background: var(--dmb-soft);
}

.dmb-button-meta {
	display: block;
	font-size: 0.8rem;
	font-weight: 400;
	opacity: 0.8;
	margin-top: 2px;
}

.dmb-warn {
	margin: 0.6rem 0 0;
	font-size: 0.88rem;
	color: #8a6116;
}

.dmb-flash {
	margin-bottom: 1.5rem;
	padding: 1rem 1.25rem;
	border-radius: var(--dmb-radius);
	border: 1px solid;
}

.dmb-flash-ok {
	background: #f1f9f4;
	border-color: #b8e0c8;
}

.dmb-flash-error {
	background: #fdf3f2;
	border-color: #f0b3b0;
}

.dmb-table {
	width: 100%;
	border-collapse: collapse;
	margin-top: 0.75rem;
	font-size: 0.95rem;
}

.dmb-table th,
.dmb-table td {
	text-align: left;
	padding: 0.75rem 0.5rem;
	border-bottom: 1px solid var(--dmb-line);
}

.dmb-table th {
	font-weight: 600;
	color: var(--dmb-muted);
	font-size: 0.85rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/* =========================================================================
   The Dashboard / Requests & Links page
   =========================================================================
 *
 * Its own spacing, because it stacks more sections than any other screen —
 * requests, share links, four stat cards, two charts and a log. At the default
 * rhythm each heading sat almost on top of its table and the whole page read
 * as one block with words in it. Everything here is breathing room; nothing
 * changes what's on the page.
 */

.dmb-activity .dmb-page-title {
	margin-bottom: 2.25rem;
}

/*
 * The Dashboard hub.
 *
 * One tile per thing the portal can tell you about. Each carries a number, a
 * line explaining it, and — only when something is genuinely waiting — a
 * badge. That last restraint is the whole design: if every tile had a badge,
 * none of them would mean anything, and the page would be back to competing
 * with itself for attention.
 *
 * Filled and lifting on hover rather than quiet and outlined, because unlike
 * the pair of admin cards these replaced, the tiles ARE the page.
 */
.dmb-hub {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 250px, 1fr ) );
	gap: 1rem;
	margin: 0.5rem 0 1rem;
}

/*
 * Tinted at rest, white on hover.
 *
 * The inversion is the point. A white tile on a white page is an outline drawn
 * around nothing — the border does all the work and the tile reads as a shape
 * rather than an object. Filling it makes it a thing sitting on the page.
 *
 * Then hovering takes it the other way: the tile under the cursor becomes
 * brighter than the page around it and lifts, which reads as picking a card up
 * out of a stack rather than merely shading it. Doing it in this order costs
 * nothing and is the difference between a grid that looks clickable and one
 * that looks printed.
 */
/*
 * A column, so the last line of every tile sits on the same baseline.
 *
 * These were plain blocks, which meant each tile was exactly as tall as its
 * own contents and the "Review requests" line landed wherever the blurb above
 * it happened to stop — four tiles, four different heights, and a row that
 * reads as ragged even though the boxes themselves line up. The grid already
 * stretches every tile to the height of its row; making the tile a column and
 * pushing the action to the bottom is what actually uses that height.
 */
.dmb-hubtile {
	display: flex;
	flex-direction: column;
	padding: 1.25rem 1.4rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius-lg, 14px);
	text-decoration: none;
	color: inherit;
	background: var( --dmb-soft, #f6f8f9 );
	transition: background-color 0.15s, border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}

.dmb-hubtile:hover {
	background: #fff;
	border-color: var(--dmb-accent, #22384c);
	transform: translateY( -2px );
	box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.06 );
}

/*
 * Something is waiting.
 *
 * A coloured left edge rather than a coloured card: enough to catch the eye
 * scanning down the grid, not so much that the tile stops looking like its
 * neighbours.
 */
.dmb-hubtile-needs {
	border-left: 3px solid #e2574c;
}

.dmb-hubtile-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
}

.dmb-hubtile-title {
	font-weight: 600;
	font-size: 1.05rem;
}

.dmb-hubtile-badge {
	display: inline-block;
	min-width: 1.5rem;
	padding: 0.1rem 0.5rem;
	border-radius: 999px;
	background: #e2574c;
	color: #fff;
	font-size: 0.8rem;
	font-weight: 700;
	text-align: center;
	line-height: 1.5;
}

.dmb-hubtile-count {
	display: block;
	margin: 0.4rem 0 0.5rem;
	font-size: 1.6rem;
	font-weight: 700;
	line-height: 1.1;
	color: var(--dmb-accent, #22384c);
}

.dmb-hubtile-count span {
	display: inline-block;
	margin-left: 0.35rem;
	font-size: 0.85rem;
	font-weight: 400;
	color: var(--dmb-muted);
}

.dmb-hubtile-blurb {
	display: block;
	font-size: 0.88rem;
	color: var(--dmb-muted);
	line-height: 1.45;
}

/*
 * "Manage tags →", at the bottom of each tile.
 *
 * The tile was already a link and already lifted on hover, and it still wasn't
 * obvious. A panel with a big number on it reads as a statistic, and nobody
 * tries clicking a statistic. Naming the action is what makes it a door.
 */
.dmb-hubtile-do {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;

	/*
	 * auto, not a fixed gap. This is what pins the action to the foot of the
	 * tile regardless of how long the blurb above it runs — a one-line blurb
	 * and a three-line blurb now end at the same place.
	 *
	 * The padding-top keeps a minimum gap for the tile whose blurb is long
	 * enough to fill the height on its own, so it never sits jammed against
	 * the text above it.
	 */
	margin-top: auto;
	padding-top: 0.85rem;
	align-self: flex-start;
	font-size: 0.9rem;
	font-weight: 600;
	color: var( --dmb-accent, #22384c );
}

.dmb-hubtile-arrow {
	transition: transform 0.15s;
}

.dmb-hubtile:hover .dmb-hubtile-do {
	text-decoration: underline;
}

.dmb-hubtile:hover .dmb-hubtile-arrow {
	transform: translateX( 3px );
}

/* The feedback tile carries no number, so its blurb needs the room back. */
.dmb-hubtile-blurb:first-of-type {
	margin-top: 0.5rem;
}


@media ( prefers-reduced-motion: reduce ) {
	.dmb-hubtile {
		transition: background-color 0.15s;
	}

	.dmb-hubtile:hover {
		transform: none;
	}

	.dmb-hubtile-arrow,
	.dmb-hubtile:hover .dmb-hubtile-arrow {
		transition: none;
		transform: none;
	}
}

.dmb-activity .dmb-section-title {
	margin: 3.5rem 0 1.5rem;
}

.dmb-activity .dmb-section-head .dmb-section-title {
	margin-bottom: 1.5rem;
}

.dmb-activity .dmb-table {
	margin-top: 1.1rem;
}

.dmb-activity .dmb-statcol h3,
.dmb-activity .dmb-stat-subhead {
	margin-bottom: 1rem;
}

.dmb-activity .dmb-statgrid {
	margin: 1.75rem 0 2.75rem;
}

.dmb-activity .dmb-statcols {
	gap: 2.5rem;
	margin-bottom: 2.5rem;
}

.dmb-activity .dmb-empty {
	margin-top: 1rem;
}

/* =========================================================================
   Download stats
   ========================================================================= */

.dmb-stats {
	margin-top: 3rem;
}

.dmb-statgrid {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 190px, 1fr ) );
	gap: 1rem;
	margin: 1.25rem 0 2rem;
}

.dmb-stat {
	padding: 1.25rem 1.4rem;
	background: var(--dmb-soft);
	border-radius: var(--dmb-radius-lg, 14px);
}

.dmb-stat-value {
	display: block;
	font-size: 1.9rem;
	font-weight: 700;
	line-height: 1.1;
	color: var(--dmb-accent, #22384c);
}

.dmb-stat-label {
	display: block;
	margin-top: 0.35rem;
	font-size: 0.85rem;
	color: var(--dmb-muted);
}

.dmb-statcols {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 320px, 1fr ) );
	gap: 2rem;
	margin-bottom: 2rem;
}

.dmb-statcol h3,
.dmb-stat-subhead {
	margin: 0 0 0.5rem;
	font-size: 1rem;
	font-weight: 600;
}

.dmb-stat-subhead {
	margin-top: 2rem;
}

/*
 * The bar chart, built from two spans rather than a canvas or a charting
 * library. It's one number per row against the largest — a library for that
 * would be 60KB to draw a rectangle.
 */
.dmb-bars {
	list-style: none;
	margin: 0;
	padding: 0;
}

.dmb-bars li {
	display: grid;
	grid-template-columns: minmax( 90px, 1fr ) 2fr auto;
	align-items: center;
	gap: 0.75rem;
	padding: 0.4rem 0;
	font-size: 0.92rem;
}

.dmb-bar-name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.dmb-bar-track {
	display: block;
	height: 8px;
	border-radius: 999px;
	background: var(--dmb-soft);
	overflow: hidden;
}

.dmb-bar-fill {
	display: block;
	height: 100%;
	border-radius: 999px;
	background: var(--dmb-accent, #22384c);
}

.dmb-bar-count {
	font-variant-numeric: tabular-nums;
	color: var(--dmb-muted);
	font-size: 0.88rem;
}

.dmb-table-compact th,
.dmb-table-compact td {
	padding: 0.55rem 0.5rem;
	font-size: 0.92rem;
}

@media ( max-width: 600px ) {
	.dmb-bars li {
		grid-template-columns: 1fr auto;
	}

	/* The bar is the first thing to go on a narrow screen: the name and the
	   number are the information, the bar is the comparison. */
	.dmb-bar-track {
		display: none;
	}
}

/* =========================================================================
   Uploading
   ========================================================================= */

.dmb-dropzone {
	margin: 1.5rem 0 1rem;
	padding: 3rem 1.5rem;
	border: 2px dashed var(--dmb-line);
	border-radius: var(--dmb-radius);
	text-align: center;
	cursor: pointer;
	background: var(--dmb-soft);
	transition: border-color 0.15s, background 0.15s;
}

.dmb-dropzone:hover,
.dmb-dropzone:focus,
.dmb-dropzone-active {
	border-color: var(--dmb-ink);
	outline: none;
}

.dmb-dropzone-main {
	margin: 0 0 0.35rem;
	font-size: 1.1rem;
}

.dmb-dropzone-sub {
	margin: 0;
	color: var(--dmb-muted);
	font-size: 0.9rem;
}

.dmb-link {
	text-decoration: underline;
}

.dmb-queue {
	max-height: 340px;
	overflow-y: auto;
}

.dmb-queue-count {
	margin: 0 0 0.5rem;
	font-weight: 600;
	font-size: 0.92rem;
}

.dmb-queue-row {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.5rem 0.25rem;
	border-bottom: 1px solid var(--dmb-line);
	font-size: 0.9rem;
}

.dmb-queue-icon {
	flex: 0 0 1.2rem;
	text-align: center;
	font-weight: 700;
}

.dmb-queue-done .dmb-queue-icon { color: #1a7f4b; }
.dmb-queue-failed .dmb-queue-icon { color: #b3261e; }
.dmb-queue-busy .dmb-queue-icon { color: var(--dmb-ink); }
.dmb-queue-waiting .dmb-queue-icon { color: var(--dmb-muted); }

.dmb-queue-name {
	flex: 1 1 auto;
	min-width: 0;
	word-break: break-all;
}

.dmb-queue-meta {
	flex: 0 0 auto;
	color: var(--dmb-muted);
	font-size: 0.85rem;
}

.dmb-queue-failed .dmb-queue-meta {
	color: #b3261e;
}

.dmb-progress-wrap {
	margin: 1.25rem 0;
}

.dmb-progress {
	height: 8px;
	background: var(--dmb-line);
	border-radius: 999px;
	overflow: hidden;
}

.dmb-progress-bar {
	height: 100%;
	width: 0;
	background: var(--dmb-ink);
	transition: width 0.2s ease;
}

.dmb-progress-text {
	margin: 0.5rem 0 0;
	font-size: 0.9rem;
	color: var(--dmb-muted);
}

.dmb-result {
	margin-top: 1.25rem;
	padding: 1rem 1.25rem;
	border-radius: var(--dmb-radius);
	border: 1px solid;
}

.dmb-result-ok { background: #f1f9f4; border-color: #b8e0c8; }
.dmb-result-warn { background: #fff8e6; border-color: #e6c65c; }
.dmb-result-error { background: #fdf3f2; border-color: #f0b3b0; }

/* =========================================================================
   Selection and bulk download
   ========================================================================= */

.dmb-check {
	position: absolute;
	top: 8px;
	left: 8px;
	z-index: 5;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	background: rgba(255, 255, 255, 0.94);
	border: 1px solid rgba(0, 0, 0, 0.12);
	border-radius: 5px;
	cursor: pointer;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.dmb-check input {
	width: 16px;
	height: 16px;
	margin: 0;
	cursor: pointer;
}

/* The card needs a positioning context for the checkbox to sit against. */
.dmb-card {
	position: relative;
}

.dmb-selected {
	outline: 3px solid var(--dmb-ink);
	outline-offset: 1px;
}

.dmb-select-all {
	margin: 0 0 1rem;
	font-size: 0.92rem;
}

.dmb-select-all label {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	cursor: pointer;
}

.dmb-download-folder {
	margin: 0 0 1.5rem;
}

/*
 * The folder toolbar: file count on the left, sort and "download all" on the
 * right.
 *
 * The folder download used to be a full-width outlined block above the count,
 * which gave the least-used action on the page the most weight on it. Same
 * button, one line, in the row where the other controls already are.
 */
.dmb-folderbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1rem;
	margin: 0 0 1rem;
}

.dmb-folderbar .dmb-count {
	margin: 0;
	margin-right: auto;
}

.dmb-folderbar .dmb-sortbar {
	margin: 0;
}

.dmb-download-folder-compact {
	margin: 0;
}

/*
 * Filled in the client's accent colour rather than outlined.
 *
 * The hover is derived with a brightness filter rather than a second colour
 * setting: one colour to choose on the branding screen, and no way to pick a
 * hover that clashes with the button it belongs to.
 */
.dmb-button-accent {
	background: var( --dmb-accent, #22384c );
	color: #fff;
	border: 0;
}

.dmb-button-accent:hover:not(:disabled) {
	background: var( --dmb-accent, #22384c );
	filter: brightness( 1.15 );
}

.dmb-button-accent:focus-visible {
	outline: 2px solid var( --dmb-accent, #22384c );
	outline-offset: 2px;
}

.dmb-button-small {
	padding: 7px 14px;
	font-size: 13px;
	line-height: 1.3;
	border-radius: 6px;
	display: inline-flex;
	align-items: baseline;
	gap: 0.45rem;
}

.dmb-button-meta-inline {
	font-size: 0.78rem;
	font-weight: 400;
	opacity: 0.75;
	white-space: nowrap;
}

@media ( max-width: 600px ) {
	/* Stacked, and the size drops off the button — the row is tight enough on a
	 * phone without it. */
	.dmb-folderbar {
		gap: 0.6rem;
	}

	.dmb-folderbar .dmb-count {
		width: 100%;
		margin-right: 0;
	}

	.dmb-button-meta-inline {
		display: none;
	}
}

.dmb-bar {
	position: fixed;
	left: 50%;
	bottom: 20px;
	transform: translateX(-50%);
	z-index: 9999;
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 12px 18px;
	background: #14181d;
	color: #fff;
	border-radius: 10px;
	box-shadow: 0 6px 28px rgba(0, 0, 0, 0.3);
	font-size: 0.92rem;
	max-width: calc(100vw - 32px);
}

/*
 * The browser's own [hidden] rule is display:none, from the user agent
 * stylesheet, and it loses to any display declared here. Without this a
 * hidden attribute on the bar or its buttons has no visible effect.
 */
.dmb-bar[hidden],
.dmb-bar .dmb-button[hidden] {
	display: none;
}

/*
 * Nothing selected yet. The bar stays put — it's the only thing telling
 * people that selecting several is possible — but recedes so it reads as an
 * invitation rather than a live selection.
 */
.dmb-bar-idle {
	background: rgba(20, 24, 29, 0.88);
	padding-top: 10px;
	padding-bottom: 10px;
}

.dmb-bar-idle .dmb-bar-text {
	font-size: 0.88rem;
	font-weight: 400;
	opacity: 0.9;
}

.dmb-bar-idle strong {
	font-weight: 400;
}

.dmb-bar-text {
	display: flex;
	flex-direction: column;
	line-height: 1.3;
	min-width: 0;
	/* Doesn't push the buttons onto a second line: with four of them there
	   isn't room for a full sentence and a wide count as well. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/*
 * Four buttons in a row that used to hold two.
 *
 * Tighter padding rather than smaller text: the bar sits over the content, so
 * height is what's expensive, and a two-line bar covers a row of photographs.
 */
.dmb-bar .dmb-button {
	padding: 0.6rem 1.1rem;
	font-size: 0.9rem;
	white-space: nowrap;
}

.dmb-bar-size {
	font-size: 0.8rem;
	opacity: 0.75;
}

.dmb-bar-over .dmb-bar-size {
	color: #ffb4ae;
	opacity: 1;
}

.dmb-bar .dmb-button-quiet {
	color: #fff;
	border-color: rgba(255, 255, 255, 0.3);
}

.dmb-bar .dmb-button-quiet:hover:not(:disabled) {
	background: rgba(255, 255, 255, 0.1);
}

/* =========================================================================
   Login
   ========================================================================= */

.dmb-login-screen {
	min-height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 3rem 1.5rem;
	background-color: var(--dmb-soft);
	background-size: cover;
	background-position: center;
}

.dmb-login-card {
	width: 100%;
	max-width: 420px;
	background: #fff;
	padding: 2.5rem;
	border-radius: var(--dmb-radius-lg);
	box-shadow: 0 10px 40px rgba(34, 56, 76, 0.18);
}

.dmb-login-logo {
	margin-bottom: 1.5rem;
}

.dmb-login-logo img {
	max-height: 56px;
	width: auto;
}

.dmb-login-card h1 {
	margin: 0 0 1.5rem;
	font-size: 1.4rem;
	font-weight: 600;
}

.dmb-login-card label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.92rem;
	font-weight: 500;
}

.dmb-login-card input[type="text"],
.dmb-login-card input[type="email"],
.dmb-login-card input[type="password"] {
	width: 100%;
	padding: 0.75rem 1rem;
	margin-bottom: 1rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	font: inherit;
}

.dmb-login-card .login-remember {
	font-weight: 400;
	font-size: 0.9rem;
	margin-bottom: 1rem;
}

.dmb-login-card input[type="submit"] {
	width: 100%;
	padding: 0.85rem;
	border: 0;
	border-radius: 999px;
	background: var(--dmb-grey);
	color: #fff;
	font: inherit;
	font-weight: 500;
	cursor: pointer;
}

.dmb-login-card input[type="submit"]:hover {
	background: var(--dmb-grey-dark);
}

.dmb-login-error {
	margin-bottom: 1.25rem;
	padding: 0.85rem 1rem;
	background: #fdf3f2;
	border: 1px solid #f0b3b0;
	border-radius: var(--dmb-radius);
	font-size: 0.92rem;
}

/*
 * The password screens, which share the login card.
 *
 * The button here is a real <button class="dmb-button"> rather than the
 * <input type="submit"> wp_login_form() produces, so it needs the same
 * full-width treatment to sit consistently with the login form.
 */
.dmb-login-lead {
	margin: 0 0 1.25rem;
	font-size: 0.95rem;
	color: var(--dmb-muted);
	line-height: 1.5;
}

.dmb-login-sent {
	margin: 0;
	padding: 0.9rem 1rem;
	background: #f1f7f2;
	border: 1px solid #bcd9c2;
	border-radius: var(--dmb-radius);
	font-size: 0.93rem;
	line-height: 1.5;
}

.dmb-login-hint {
	margin: -0.5rem 0 1rem;
	font-size: 0.85rem;
	color: var(--dmb-muted);
}

.dmb-login-card .dmb-button {
	width: 100%;
	text-align: center;
	display: block;
	text-decoration: none;
}

.dmb-login-card form p {
	margin: 0 0 0.25rem;
}

.dmb-login-lost {
	margin: 1.25rem 0 0;
	font-size: 0.9rem;
	text-align: center;
}

.dmb-login-lost a {
	color: var(--dmb-muted);
}

/*
 * The 520px bar rules that used to live here have gone.
 *
 * They set left, right, transform and flex-wrap, and every one of them is set
 * again by the 600px block further down — a wider range, declared later, so it
 * won everywhere the 520px one applied. Two blocks describing the same bar,
 * one of which never took effect, is how the wrong one gets edited.
 */

/* =========================================================================
   Tags, filters and per-file descriptions
   ========================================================================= */

/*
 * Checkbox-backed pills. They stay real checkboxes so keyboard and screen
 * reader users get proper behaviour, but read as toggles rather than the
 * CTRL-click multi-select the old portal used — which was the single most
 * confusing control on it.
 */
.dmb-tagpick,
.dmb-tagfilter {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	align-items: center;
}

.dmb-tagfilter {
	margin-top: 0.85rem;
}

.dmb-tagfilter-label {
	font-size: 0.88rem;
	color: var(--dmb-muted);
	margin-right: 0.25rem;
}

.dmb-tagpill {
	position: relative;
	display: inline-flex;
	align-items: center;
	padding: 0.4rem 0.95rem;
	border: 1px solid var(--dmb-line);
	border-radius: 999px;
	background: #fff;
	font-size: 0.88rem;
	cursor: pointer;
	user-select: none;
	transition: background 0.12s, border-color 0.12s;
}

.dmb-tagpill input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}

.dmb-tagpill:hover {
	border-color: var(--dmb-ink);
}

.dmb-tagpill input:focus-visible + span {
	outline: 2px solid var(--dmb-ink);
	outline-offset: 4px;
	border-radius: 2px;
}

/*
 * Selected state, driven by the checkbox itself.
 *
 * This was a class that JavaScript had to keep in step, bound to an ID that
 * existed on one screen only — so on any other screen the pills never lit up,
 * and a pre-ticked tag never showed as ticked because nothing set the initial
 * state.
 *
 * :has() lets the CSS read the checkbox directly. The state can't drift from
 * the data because it *is* the data, and it works on a screen nobody remembered
 * to wire up.
 */
.dmb-tagpill:has( input:checked ),
.dmb-tagpill-on {
	background: var(--dmb-ink);
	border-color: var(--dmb-ink);
	color: #fff;
}

.dmb-tagpill:has( input:checked ):hover {
	background: var(--dmb-accent);
	border-color: var(--dmb-accent);
}

.dmb-filterbar {
	margin-bottom: 1.75rem;
}

.dmb-queue-desc {
	display: block;
	width: 100%;
	margin: 0 0 0.5rem 1.95rem;
	padding: 0.45rem 0.7rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	font: inherit;
	font-size: 0.88rem;
	box-sizing: border-box;
}

.dmb-linkbutton {
	border: 0;
	background: none;
	padding: 0;
	font: inherit;
	font-size: 0.9rem;
	color: #b3261e;
	text-decoration: underline;
	cursor: pointer;
}

/* =========================================================================
   Polish
   -------------------------------------------------------------------------
   The pieces that make it read as a product rather than a set of working
   parts: section headings, quick links, video previews, better empty and
   loading states, and consistent vertical rhythm.
   ========================================================================= */

.dmb-section-title {
	margin: 2.5rem 0 1.25rem;
	font-size: 1.35rem;
	font-weight: 600;
	color: var(--dmb-ink);
}

.dmb-portal-inner > .dmb-section-title:first-child {
	margin-top: 0;
}

/*
 * The home page's section headings, a step up from everywhere else.
 *
 * Folders, Recently added and Most downloaded are the page's structure —
 * they're what someone scans to decide where to go. On the working screens a
 * heading only labels the thing under it, so it can be quieter.
 */
.dmb-home .dmb-section-title {
	font-size: 1.55rem;
}

@media ( max-width: 600px ) {
	.dmb-home .dmb-section-title {
		font-size: 1.35rem;
	}
}

.dmb-section-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
}

.dmb-section-head .dmb-section-title {
	margin-bottom: 1.25rem;
}

.dmb-seeall {
	font-size: 0.92rem;
	color: var(--dmb-muted);
	text-decoration: none;
	white-space: nowrap;
}

.dmb-seeall:hover {
	color: var(--dmb-ink);
	text-decoration: underline;
}

/* ------------------------------------------------------------- quick bar */

.dmb-quickbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	flex-wrap: wrap;
	padding: 1.1rem 1.4rem;
	margin-bottom: 1.75rem;
	background: var(--dmb-soft);
	border-radius: var(--dmb-radius-lg);
}

.dmb-quicklinks {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	flex-wrap: wrap;
}

.dmb-quicklabel {
	font-size: 0.88rem;
	color: var(--dmb-muted);
	margin-right: 0.15rem;
}

.dmb-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.45rem 1rem;
	background: #fff;
	border: 1px solid var(--dmb-line);
	border-radius: 999px;
	font-size: 0.9rem;
	font-weight: 500;
	color: var(--dmb-ink);
	text-decoration: none;
	transition: border-color 0.12s, box-shadow 0.12s;
}

.dmb-chip:hover {
	border-color: var(--dmb-ink);
	box-shadow: 0 2px 8px rgba(34, 56, 76, 0.08);
}

.dmb-chip-count {
	font-size: 0.78rem;
	color: var(--dmb-muted);
	background: var(--dmb-soft);
	padding: 0.05rem 0.45rem;
	border-radius: 999px;
}

/* ------------------------------------------------------ video and files */

.dmb-card-video {
	position: relative;
	background: #11161b;
}

.dmb-card-video video {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* A play badge, so a still frame reads as a video rather than a photo. */
.dmb-play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 52px;
	height: 52px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.92);
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
	pointer-events: none;
}

.dmb-play::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 54%;
	transform: translate(-50%, -50%);
	border-style: solid;
	border-width: 9px 0 9px 15px;
	border-color: transparent transparent transparent var(--dmb-ink);
}

.dmb-card-nopreview {
	display: flex;
	align-items: center;
	justify-content: center;
	text-decoration: none;
	background: var(--dmb-soft);
}

.dmb-fileicon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 64px;
	padding: 0.55rem 0.9rem;
	background: #fff;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	font-size: 0.82rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	color: var(--dmb-muted);
}

/* ---------------------------------------------------------- card detail */

.dmb-card-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	margin-top: 0.5rem;
}

.dmb-card-tag {
	font-size: 0.72rem;
	padding: 0.1rem 0.5rem;
	background: var(--dmb-soft);
	border-radius: 999px;
	color: var(--dmb-muted);
	white-space: nowrap;
}

/* --------------------------------------------------------------- filters */

/*
 * The filter bar reads as one control rather than a row of loose inputs —
 * which is most of the difference between "looks unfinished" and "looks
 * considered".
 */
.dmb-filterbar {
	padding: 1.25rem 1.4rem;
	background: var(--dmb-soft);
	border-radius: var(--dmb-radius-lg);
	margin-bottom: 1.75rem;
}

.dmb-filterbar .dmb-search {
	max-width: none;
	background: #fff;
	margin-bottom: 0.85rem;
}

.dmb-filterbar .dmb-filters {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
	align-items: center;
	margin: 0;
}

.dmb-filterbar select {
	max-width: none;
	min-width: 165px;
}

.dmb-filterbar .dmb-clear {
	margin-left: auto;
}

/*
 * The same bar on a folder page. The inline search box carries its own bottom
 * margin for standing alone, which is too much once it's the first row of a
 * panel.
 */
.dmb-filterbar-folder .dmb-search-inline {
	margin-bottom: 0.85rem;
}

/* -------------------------------------------------------------- spacing */

.dmb-page-title {
	margin: 0 0 0.5rem;
	font-size: 1.9rem;
	font-weight: 600;
}

.dmb-panel + .dmb-subtitle {
	margin-top: 2.5rem;
}

.dmb-storage {
	margin-bottom: 1.75rem;
}

/* Give the folder tiles room to breathe on their own page. */
.dmb-portal-inner > .dmb-tiles {
	margin-bottom: 1rem;
}

/* --- Video tiles ------------------------------------------------------- */

.dmb-card-video {
	position: relative;
	display: block;
	overflow: hidden;
	background: #14161a;
}

.dmb-card-video .dmb-thumb {
	display: block;
	width: 100%;
	height: 100%;
	background-color: #14161a;
	/* Biased upward, exactly as the photographs are: a portrait clip in a 4:3
	   box is trimmed equally top and bottom, and the head is what's at the top.
	   Landscape video is unaffected — it's cropped left and right, so the
	   vertical position does nothing to it. */
	background-position: center 25%;
	background-size: cover;
	background-repeat: no-repeat;
}

/* Until a frame has been grabbed, something better than a flat black box. */
.dmb-card-video:not(.has-thumb) .dmb-thumb {
	background-image: linear-gradient( 135deg, #23262c 0%, #14161a 100% );
}

.dmb-card-video .dmb-play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate( -50%, -50% );
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	padding-left: 4px; /* Optically centres the triangle. */
	border-radius: 50%;
	background: rgba( 0, 0, 0, 0.55 );
	color: #fff;
	font-size: 19px;
	line-height: 1;
	box-shadow: 0 2px 12px rgba( 0, 0, 0, 0.35 );
	transition: transform 0.15s ease, background 0.15s ease;
	pointer-events: none;
}

.dmb-card-video:hover .dmb-play,
.dmb-card-video:focus-visible .dmb-play {
	transform: translate( -50%, -50% ) scale( 1.08 );
	background: var( --dmb-accent, #22384c );
}

/* --- Lightbox ---------------------------------------------------------- */

body.dmb-lb-open {
	overflow: hidden;
}

.dmb-lightbox {
	position: fixed;
	inset: 0;
	z-index: 100000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 3vmin;
	background: rgba( 12, 14, 18, 0.92 );
	backdrop-filter: blur( 4px );
}

.dmb-lightbox[hidden] {
	display: none;
}

.dmb-lb-figure {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
	margin: 0;
	max-width: 100%;
	max-height: 100%;
}

.dmb-lb-stage {
	display: flex;
	align-items: center;
	justify-content: center;
	max-width: 100%;
	min-height: 0;
}

.dmb-lb-stage img,
.dmb-lb-stage video {
	display: block;
	max-width: min( 1400px, 92vw );
	max-height: 82vh;
	width: auto;
	height: auto;
	border-radius: 6px;
	box-shadow: 0 12px 48px rgba( 0, 0, 0, 0.5 );
	background: #000;
}

.dmb-lb-caption {
	color: rgba( 255, 255, 255, 0.85 );
	font-size: 14px;
	text-align: center;
	max-width: 70ch;
}

.dmb-lb-close,
.dmb-lb-nav {
	position: absolute;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	cursor: pointer;
	background: rgba( 255, 255, 255, 0.1 );
	color: #fff;
	border-radius: 50%;
	transition: background 0.15s ease;
}

.dmb-lb-close:hover,
.dmb-lb-nav:hover,
.dmb-lb-close:focus-visible,
.dmb-lb-nav:focus-visible {
	background: rgba( 255, 255, 255, 0.24 );
}

.dmb-lb-close {
	top: 18px;
	right: 18px;
	width: 42px;
	height: 42px;
	font-size: 26px;
	line-height: 1;
}

.dmb-lb-nav {
	top: 50%;
	transform: translateY( -50% );
	width: 48px;
	height: 48px;
	font-size: 32px;
	line-height: 1;
	padding-bottom: 4px;
}

.dmb-lb-nav[hidden] {
	display: none;
}

.dmb-lb-prev { left: 18px; }
.dmb-lb-next { right: 18px; }

@media ( max-width: 640px ) {
	.dmb-lb-nav {
		width: 40px;
		height: 40px;
		font-size: 26px;
	}

	.dmb-lb-prev { left: 6px; }
	.dmb-lb-next { right: 6px; }

	.dmb-lb-stage img,
	.dmb-lb-stage video {
		max-height: 70vh;
	}
}

/* --- Advanced search link ---------------------------------------------- */

.dmb-hero-advanced-row {
	margin: 10px 0 0;
	text-align: center;
}

/*
 * Sits on a hero image that's different for every client, so it can't rely on
 * the background being dark enough to read white text against. The pill brings
 * its own contrast with it instead of hoping the photo behind it cooperates.
 *
 * ---------------------------------------------------------------------------
 * The white border and the blur are gone
 * ---------------------------------------------------------------------------
 * This is the "Advanced search" link, and it is a second 999px pill sitting
 * directly under the search box. It had a white 25% border, which is a visible
 * white outline, and a backdrop-filter, which forces a compositing layer and
 * stair-steps a rounded edge — the two complaints exactly.
 *
 * Neither earns its place. The fill is dark enough at full opacity to carry
 * white text on any photograph, which is the whole job; the border was
 * separating it from a background it already contrasts with, and the blur was
 * softening a background that is no longer visible through it.
 */
.dmb-hero-advanced {
	display: inline-block;
	padding: 8px 16px;
	border-radius: 999px;
	border: 0;
	background: rgba( 17, 20, 26, 0.86 );
	color: #fff;
	font-size: 13px;
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	box-shadow: 0 1px 6px rgba( 0, 0, 0, 0.25 );
	transition: background 0.15s ease, transform 0.15s ease;
}

.dmb-hero-advanced:hover,
.dmb-hero-advanced:focus-visible {
	background: rgba( 17, 20, 26, 0.96 );
	color: #fff;
	transform: translateY( -1px );
}

.dmb-hero-advanced:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

/* Where backdrop-filter isn't supported the panel just goes fully opaque,
   which is less pretty and equally readable. */
@supports not ( backdrop-filter: blur( 6px ) ) {
	.dmb-hero-advanced {
		background: rgba( 17, 20, 26, 0.85 );
	}
}

/* --- Lightbox caption --------------------------------------------------- */

.dmb-lb-caption {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 8px 16px;
}

.dmb-lb-download {
	display: inline-block;
	padding: 7px 15px;
	border-radius: 999px;
	background: rgba( 255, 255, 255, 0.14 );
	color: #fff;
	font-size: 13px;
	text-decoration: none;
	white-space: nowrap;
	transition: background 0.15s ease;
}

.dmb-lb-download:hover,
.dmb-lb-download:focus-visible {
	background: var( --dmb-accent, #22384c );
	color: #fff;
}

/* --- Empty section ------------------------------------------------------ */

.dmb-section-empty {
	margin: 0 0 8px;
	padding: 22px 24px;
	border: 1px dashed var( --dmb-line );
	border-radius: 8px;
	background: var( --dmb-soft );
	color: var( --dmb-muted, #6b7280 );
	font-size: 14px;
	line-height: 1.55;
	max-width: 62ch;
}

/* --- Sort bar ----------------------------------------------------------- */

.dmb-sortbar {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 8px;
	margin: 0 0 14px;
}

.dmb-sortbar label {
	color: var( --dmb-muted, #6b7280 );
	font-size: 13px;
}

.dmb-sortbar select {
	padding: 7px 30px 7px 11px;
	border: 1px solid var( --dmb-line );
	border-radius: 6px;
	background-color: #fff;
	color: inherit;
	font-size: 13px;
	line-height: 1.3;
	cursor: pointer;
}

.dmb-sortbar select:focus-visible {
	outline: 2px solid var( --dmb-accent, #22384c );
	outline-offset: 1px;
}

@media ( max-width: 600px ) {
	.dmb-sortbar {
		justify-content: flex-start;
	}
}

/* --- Section separation -------------------------------------------------
 *
 * A hairline that starts after the heading and runs across to the "See all"
 * link, so each block reads as its own thing rather than one long scroll.
 *
 * Done with a flex pseudo-element and `order` rather than new markup: the rule
 * grows to fill whatever space is left, so it works whether or not a section
 * has a "See all", and adapts to the heading length without anything being
 * measured or hardcoded.
 * -------------------------------------------------------------------- */

.dmb-section-head {
	align-items: center;
	justify-content: flex-start;
	margin-top: 3.25rem;
	gap: 1.1rem;
}

/* First section on a page shouldn't be pushed down by that spacing. */
.dmb-portal-inner > .dmb-section-head:first-child,
.dmb-hero + .dmb-section-head {
	margin-top: 0;
}

.dmb-section-head .dmb-section-title {
	order: 0;
	margin-top: 0;
	margin-bottom: 0;
	flex: 0 0 auto;
}

.dmb-section-head::after {
	content: "";
	order: 1;
	flex: 1 1 auto;
	height: 1px;
	min-width: 2rem;
	background: linear-gradient(
		to right,
		var( --dmb-line ) 0%,
		var( --dmb-line ) 55%,
		transparent 100%
	);
}

.dmb-section-head .dmb-seeall {
	order: 2;
	flex: 0 0 auto;
}

/* A short accent tick above the heading — picks up the client's colour, so
   the separation is branded rather than generic grey. */
.dmb-section-head .dmb-section-title::before {
	content: "";
	display: block;
	width: 44px;
	height: 5px;
	margin-bottom: 0.7rem;
	border-radius: 3px;
	background: var( --dmb-accent, #22384c );
}

/* The grid that follows a section head gets a little more room. */
.dmb-section-head + .dmb-grid,
.dmb-section-head + .dmb-select-all {
	margin-top: 1.25rem;
}

@media ( max-width: 600px ) {
	.dmb-section-head {
		margin-top: 2.25rem;
		gap: 0.75rem;
	}

	/* On a narrow screen the rule costs more than it gives. */
	.dmb-section-head::after {
		display: none;
	}

	.dmb-section-head {
		justify-content: space-between;
	}
}

/* --- Movement ------------------------------------------------------------
 *
 * Restraint is the whole point. Everything below is a small transform on a
 * short timing curve — enough that the interface responds to you, not enough
 * to notice as animation. Anything that draws attention to itself will get
 * tiring on a page someone uses every week.
 *
 * One rule throughout: only ever animate transform and opacity. Those are
 * handled by the compositor, so a grid of thirty cards stays smooth. Animating
 * width, height, box-shadow spread or background-position forces layout or
 * paint on every frame and is where hover effects start to stutter.
 * -------------------------------------------------------------------- */

/* The image, inside its fixed-ratio frame. The frame already clips, so the
   picture grows without the card changing size or the grid reflowing. */
.dmb-card-media img,
.dmb-card-media .dmb-thumb {
	transition: transform 0.4s cubic-bezier( 0.2, 0.6, 0.2, 1 );
	will-change: transform;
}

.dmb-card:hover .dmb-card-media img,
.dmb-card:hover .dmb-card-media .dmb-thumb,
.dmb-card:focus-within .dmb-card-media img,
.dmb-card:focus-within .dmb-card-media .dmb-thumb {
	transform: scale( 1.045 );
}

/* The card itself lifts, matching the folder tiles above it — the two grids
   sit on the same page and behaving differently made them look unrelated. */
.dmb-card {
	transition: box-shadow 0.22s ease, transform 0.22s ease, border-color 0.22s ease;
}

.dmb-card:hover,
.dmb-card:focus-within {
	transform: translateY( -3px );
	border-color: rgba( 34, 56, 76, 0.16 );
}

/* Folder tiles: the image scales as well as lifting, so the two grids read as
   the same family. */
.dmb-tile-image {
	transition: box-shadow 0.22s ease, transform 0.22s ease;
	will-change: transform;
}

.dmb-tile a:hover .dmb-tile-image,
.dmb-tile a:focus-visible .dmb-tile-image {
	transform: translateY( -3px ) scale( 1.012 );
}

.dmb-tile-name,
.dmb-tile-meta {
	transition: color 0.22s ease;
}

.dmb-tile a:hover .dmb-tile-name {
	color: var( --dmb-accent );
}

/* The play badge grows a touch with its tile rather than sitting inert. */
.dmb-card-video .dmb-play {
	transition: transform 0.22s ease, background 0.22s ease;
}

.dmb-card:hover .dmb-card-video .dmb-play {
	transform: translate( -50%, -50% ) scale( 1.06 );
	background: var( --dmb-accent );
}

/* Per-card download button: present but quiet until the card is hovered. */
.dmb-card-download {
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.dmb-card-download:active {
	transform: scale( 0.97 );
}

/* Buttons and pills acknowledge the press. Small, but its absence is what
   makes an interface feel like a document rather than an application. */
.dmb-button,
.dmb-chip,
.dmb-seeall,
.dmb-sortbar select {
	transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.dmb-button:active,
.dmb-chip:active {
	transform: scale( 0.98 );
}

.dmb-chip:hover {
	transform: translateY( -1px );
}

/* The lightbox arrives rather than appearing. Backdrop fades, the image comes
   up very slightly — it reads as the picture stepping forward out of the grid. */
.dmb-lightbox:not( [hidden] ) {
	animation: dmb-fade 0.18s ease both;
}

.dmb-lightbox:not( [hidden] ) .dmb-lb-figure {
	animation: dmb-rise 0.26s cubic-bezier( 0.2, 0.7, 0.2, 1 ) both;
}

@keyframes dmb-fade {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes dmb-rise {
	from { opacity: 0; transform: translateY( 8px ) scale( 0.985 ); }
	to   { opacity: 1; transform: none; }
}

/* Grid items fade in on load, staggered just enough to feel like the page is
   settling. Capped at a handful of children: past that the last cards would
   visibly lag, which is worse than no effect at all. */
@media ( prefers-reduced-motion: no-preference ) {
	.dmb-grid > .dmb-card,
	.dmb-tiles > .dmb-tile {
		animation: dmb-rise 0.34s cubic-bezier( 0.2, 0.7, 0.2, 1 ) both;
	}

	.dmb-grid > .dmb-card:nth-child(1),  .dmb-tiles > .dmb-tile:nth-child(1)  { animation-delay: 0.00s; }
	.dmb-grid > .dmb-card:nth-child(2),  .dmb-tiles > .dmb-tile:nth-child(2)  { animation-delay: 0.03s; }
	.dmb-grid > .dmb-card:nth-child(3),  .dmb-tiles > .dmb-tile:nth-child(3)  { animation-delay: 0.06s; }
	.dmb-grid > .dmb-card:nth-child(4),  .dmb-tiles > .dmb-tile:nth-child(4)  { animation-delay: 0.09s; }
	.dmb-grid > .dmb-card:nth-child(5),  .dmb-tiles > .dmb-tile:nth-child(5)  { animation-delay: 0.12s; }
	.dmb-grid > .dmb-card:nth-child(6),  .dmb-tiles > .dmb-tile:nth-child(6)  { animation-delay: 0.15s; }
	.dmb-grid > .dmb-card:nth-child(7),  .dmb-tiles > .dmb-tile:nth-child(7)  { animation-delay: 0.18s; }
	.dmb-grid > .dmb-card:nth-child(8),  .dmb-tiles > .dmb-tile:nth-child(8)  { animation-delay: 0.21s; }
}

/*
 * Not decoration — for some people motion causes nausea or triggers migraine,
 * and the operating system already knows. Everything above collapses to a
 * plain state change; nothing is lost but the movement.
 */
@media ( prefers-reduced-motion: reduce ) {
	.dmb-card,
	.dmb-card-media img,
	.dmb-card-media .dmb-thumb,
	.dmb-tile-image,
	.dmb-card-video .dmb-play,
	.dmb-button,
	.dmb-chip,
	.dmb-seeall,
	.dmb-card-download,
	.dmb-sortbar select {
		transition: none;
	}

	.dmb-card:hover,
	.dmb-card:focus-within,
	.dmb-tile a:hover .dmb-tile-image,
	.dmb-card:hover .dmb-card-media img,
	.dmb-card:hover .dmb-card-media .dmb-thumb {
		transform: none;
	}

	.dmb-lightbox:not( [hidden] ),
	.dmb-lightbox:not( [hidden] ) .dmb-lb-figure,
	.dmb-grid > .dmb-card,
	.dmb-tiles > .dmb-tile {
		animation: none;
	}
}

/* --- Mobile --------------------------------------------------------------
 *
 * Two specific faults, both invisible at desktop width:
 *
 * 1. The hero was grid-template-columns: 1fr 1fr with no override. Grid items
 *    default to min-width: auto, which means they refuse to shrink below their
 *    content — so the search form pushed its column wider than the screen and
 *    the Search button was cut off. minmax(0, 1fr) is the fix for the general
 *    case; one column is the fix for a phone.
 *
 * 2. The download bar is a flex row that never wrapped. With no room the
 *    button simply overflowed the rounded panel it was supposed to sit inside.
 * -------------------------------------------------------------------- */

/* Never let a grid child's content dictate the column width. */
.dmb-hero-inner {
	grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1fr );
}

.dmb-bar {
	flex-wrap: wrap;
	justify-content: center;
	/* Clears the iPhone home indicator, and stays 20px elsewhere. */
	bottom: max( 20px, env( safe-area-inset-bottom ) );
}

.dmb-bar-text {
	min-width: 0;
}

@media ( max-width: 860px ) {
	.dmb-hero-inner {
		grid-template-columns: minmax( 0, 1fr );
		gap: 1.5rem;
	}
}

@media ( max-width: 600px ) {
	.dmb-hero {
		/* 520px was over half a phone screen before anything was read. */
		min-height: 0;
		padding: 2rem 0;
	}

	.dmb-hero-inner {
		padding: 1.5rem 1.25rem;
	}

	.dmb-hero-search form {
		max-width: none;
		width: 100%;
	}

	.dmb-hero-search input[type="search"] {
		padding: 0.85rem 1.1rem;
		font-size: 16px; /* Under 16px, iOS zooms the page on focus. */
	}

	.dmb-hero-search button {
		/* Was 2.25rem of side padding on a non-shrinking element — the single
		   biggest contributor to the overflow. */
		flex: 0 0 auto;
		padding: 0.85rem 1.25rem;
	}

	.dmb-hero-panel {
		padding: 1.25rem 1.35rem;
	}

	.dmb-hero-panel h1 {
		font-size: 1.5rem;
		line-height: 1.25;
	}

	/*
	 * The bar stays a bar.
	 *
	 * It was a full-width tray with every button stacked, which was the right
	 * answer when there were two of them. At six — count, Download, Share
	 * link, Send for review, More, Clear — it stood about 250px tall: most of
	 * a phone screen, sitting on top of the photographs it exists to act on.
	 *
	 * front.js moves Share link and Send for review into the More menu at this
	 * width, so what's left is a count, one action, More and Clear. That fits
	 * on one line, and one line is about 50px.
	 */
	.dmb-bar {
		left: 8px;
		right: 8px;
		transform: none;
		max-width: none;
		flex-direction: row;
		align-items: center;
		flex-wrap: nowrap;
		gap: 8px;
		padding: 8px 10px;
		border-radius: 12px;

		/*
		 * Closer to the bottom than the rule above puts it.
		 *
		 * That one sits the bar above the whole safe-area inset — 34px on a
		 * notched iPhone. Under a 50px bar that reads as floating, and it is
		 * more room than the thing it's avoiding needs: the inset is a
		 * generous band, and the home indicator itself is a 5px line sitting
		 * in roughly its lowest 13px. Taking 14px back clears the indicator
		 * and closes the gap.
		 *
		 * Where there is no inset — most Android phones, and any iPhone in a
		 * browser that doesn't report one — the subtraction goes negative and
		 * the 12px floor takes over.
		 *
		 *   notched iPhone   max( 12px, 34 - 14 ) = 20px
		 *   everything else  max( 12px, 0 - 14 )  = 12px
		 */
		bottom: max( 12px, calc( env( safe-area-inset-bottom, 0px ) - 14px ) );
	}

	/* The one thing that may shrink: a button that doesn't fit is a button
	   nobody can press, but a count can lose its last word and still count. */
	.dmb-bar-text {
		flex: 1 1 auto;
		min-width: 0;
		font-size: 0.8rem;
	}

	.dmb-bar .dmb-button {
		width: auto;
		flex: 0 0 auto;
		padding: 0.5rem 0.8rem;
		font-size: 0.82rem;
	}

	/* Full width inside the menu, which is a white sheet and not the bar. */
	.dmb-bar .dmb-bar-menu-item {
		width: 100%;
		padding: 0.55rem 0.7rem;
		font-size: 0.95rem;
	}

	/* Anchored to the right edge of a bar that now runs the whole width, so
	   the menu would otherwise hang off the screen on the left. */
	.dmb-bar-menu {
		right: 0;
		min-width: 11rem;
		max-width: calc( 100vw - 32px );
	}

	/* Cards need room for a two-up grid without the text crushing. */
	.dmb-grid {
		grid-template-columns: repeat( auto-fill, minmax( 150px, 1fr ) );
		gap: 1rem 0.75rem;
	}

	.dmb-card-title {
		font-size: 0.95rem;
	}

	.dmb-tiles {
		gap: 1rem 0.75rem;
	}

	/*
	 * Stop the fixed bar covering the last row of results.
	 *
	 * 9rem was the room a stacked tray of six buttons needed. The bar is one
	 * line now — around 50px, sitting 12 to 20px up — so most of that was
	 * empty space at the bottom of every page, which on a phone is a screenful
	 * of scrolling past nothing.
	 */
	.dmb-portal-inner {
		padding-bottom: 6rem;
	}

	.dmb-crumbs {
		font-size: 0.95rem;
	}
}

/* Very narrow: one column beats two crushed ones. */
@media ( max-width: 380px ) {
	.dmb-grid,
	.dmb-tiles {
		grid-template-columns: minmax( 0, 1fr );
	}
}

/* --- Requests and shared links ------------------------------------------ */

.dmb-note {
	margin: 0 0 1rem;
	padding: 12px 16px;
	border-left: 3px solid var(--dmb-accent);
	border-radius: 0;
	background: var(--dmb-soft);
	color: var(--dmb-ink);
	font-size: 0.92rem;
}

.dmb-request {
	margin: 0 0 1rem;
	padding: 1.1rem 1.25rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	background: #fff;
}

.dmb-request-pending  { border-left: 3px solid var(--dmb-accent); }
.dmb-request-approved { border-left: 3px solid #2e7d52; }
.dmb-request-declined,
.dmb-request-expired  { border-left: 3px solid var(--dmb-muted); opacity: 0.75; }

.dmb-request-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 0.5rem 1rem;
}

.dmb-request-meta {
	margin-left: 0.5rem;
	color: var(--dmb-muted);
	font-size: 0.88rem;
}

.dmb-request-status {
	font-size: 0.85rem;
	color: var(--dmb-muted);
	white-space: nowrap;
}

.dmb-request-note,
.dmb-request-reply {
	margin: 0.75rem 0 0;
	font-size: 0.93rem;
}

.dmb-request-reply {
	padding-left: 0.85rem;
	border-left: 2px solid var(--dmb-line);
	color: var(--dmb-muted);
}

.dmb-request-files {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0.9rem 0 0;
	padding: 0;
	list-style: none;
}

.dmb-request-files li {
	width: 46px;
	height: 46px;
	border-radius: 6px;
	overflow: hidden;
	background: var(--dmb-soft);
}

.dmb-request-files img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.dmb-request-more {
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--dmb-muted);
	font-size: 0.8rem;
}

.dmb-request-actions {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 1rem;
	padding-top: 1rem;
	border-top: 1px solid var(--dmb-line);
}

.dmb-request-actions input[type="text"] {
	flex: 1 1 180px;
	min-width: 0;
	padding: 8px 12px;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	font: inherit;
}

.dmb-request-days {
	display: flex;
	align-items: center;
	gap: 6px;
	font-size: 0.88rem;
	color: var(--dmb-muted);
	white-space: nowrap;
}

.dmb-request-days input {
	width: 62px;
	padding: 8px;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	font: inherit;
}

.dmb-request-download {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 1rem 0 0;
}

.dmb-shares {
	margin: 0;
	padding: 0;
	list-style: none;
}

.dmb-share-row {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
	padding: 0.9rem 0;
	border-bottom: 1px solid var(--dmb-line);
}

.dmb-share-row > div:first-child {
	flex: 1 1 220px;
	min-width: 0;
}

.dmb-share-row.is-dead {
	opacity: 0.55;
}

.dmb-share-link {
	flex: 1 1 260px;
	min-width: 0;
	padding: 8px 12px;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	background: var(--dmb-soft);
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.82rem;
}

/* The public share page: no navigation, so it needs its own top. */
.dmb-share-header {
	margin: 0 0 2rem;
	padding-bottom: 1.5rem;
	border-bottom: 1px solid var(--dmb-line);
}

.dmb-share-header img {
	max-width: 200px;
	height: auto;
	margin-bottom: 1.25rem;
}

.dmb-share-header h1 {
	margin: 0 0 0.35rem;
	font-size: 1.6rem;
}

.dmb-share-meta {
	margin: 0 0 1.25rem;
	color: var(--dmb-muted);
	font-size: 0.92rem;
}

.dmb-share-empty {
	max-width: 40rem;
	margin: 4rem auto;
	text-align: center;
}

body.dmb-share-page {
	margin: 0;
	background: #fff;
}

@media ( max-width: 600px ) {
	.dmb-request-actions {
		flex-direction: column;
		align-items: stretch;
	}

	.dmb-request-actions .dmb-button {
		width: 100%;
	}
}

/* --- Requests: table, detail, form -------------------------------------- */

.dmb-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 19px;
	height: 19px;
	margin-left: 5px;
	padding: 0 5px;
	border-radius: 999px;
	/* Red rather than the brand accent, and deliberately not a variable: this
	   is the one thing on screen that should look the same on every client's
	   portal. A count styled in the client's own colour reads as decoration
	   and gets scanned past. */
	background: #d43f3a;
	color: #fff;
	font-size: 11px;
	font-weight: 500;
	line-height: 1;
	vertical-align: 1px;
}

.dmb-note-good {
	border-left-color: #2e7d52;
}

.dmb-note a {
	margin-left: 0.4rem;
	color: inherit;
}

.dmb-table-wrap {
	overflow-x: auto;
	margin: 0 0 1.5rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	background: #fff;
}

.dmb-table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.93rem;
}

.dmb-table th {
	padding: 0.75rem 1rem;
	border-bottom: 1px solid var(--dmb-line);
	background: var(--dmb-soft);
	color: var(--dmb-muted);
	font-size: 0.8rem;
	font-weight: 500;
	text-align: left;
	white-space: nowrap;
}

.dmb-table td {
	padding: 0.85rem 1rem;
	border-bottom: 1px solid var(--dmb-line);
	vertical-align: middle;
}

.dmb-table tr:last-child td {
	border-bottom: 0;
}

.dmb-table-sub {
	display: block;
	color: var(--dmb-muted);
	font-size: 0.82rem;
}

.dmb-table-end {
	text-align: right;
	white-space: nowrap;
}

.dmb-decide-inline {
	display: flex;
	gap: 6px;
}

/*
 * Approve and Decline sit next to each other and one of them is hard to undo,
 * so they're deliberately not styled alike. Decline is quiet until you're on
 * it — the safer of two adjacent buttons should be the easier one to hit by
 * accident.
 */
.dmb-yes,
.dmb-no {
	padding: 6px 12px;
	border: 1px solid transparent;
	border-radius: 999px;
	font: inherit;
	font-size: 0.84rem;
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.dmb-yes {
	background: var(--dmb-accent);
	color: #fff;
}

.dmb-yes:hover {
	filter: brightness( 1.12 );
}

.dmb-no {
	background: transparent;
	border-color: var(--dmb-line);
	color: var(--dmb-muted);
}

.dmb-no:hover {
	border-color: #b3453f;
	color: #b3453f;
}

.dmb-detail {
	display: grid;
	grid-template-columns: minmax( 0, 10rem ) minmax( 0, 1fr );
	gap: 0.6rem 1.5rem;
	margin: 0 0 1.75rem;
	padding: 1.25rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	background: #fff;
	font-size: 0.94rem;
}

.dmb-detail dt {
	color: var(--dmb-muted);
	font-size: 0.85rem;
}

.dmb-detail dd {
	margin: 0;
}

.dmb-back {
	margin: 0 0 0.5rem;
	font-size: 0.9rem;
}

.dmb-back a {
	color: var(--dmb-muted);
	text-decoration: none;
}

.dmb-back a:hover {
	color: var(--dmb-ink);
}

.dmb-form {
	max-width: 46rem;
}

.dmb-form-lead {
	margin: 0 0 1.25rem;
	color: var(--dmb-muted);
}

.dmb-form select,
.dmb-form input[type="text"],
.dmb-form input[type="date"],
.dmb-form textarea {
	width: 100%;
	max-width: 28rem;
	padding: 0.6rem 0.8rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	background: #fff;
	font: inherit;
	font-size: 16px; /* Under 16px, iOS zooms the page on focus. */
}

.dmb-form textarea {
	max-width: 34rem;
	resize: vertical;
}

.dmb-request-files-lg {
	margin-bottom: 1.5rem;
}

.dmb-request-files-lg li {
	width: 62px;
	height: 62px;
}

@media ( max-width: 600px ) {
	.dmb-detail {
		grid-template-columns: minmax( 0, 1fr );
		gap: 0.15rem;
	}

	.dmb-detail dd {
		margin-bottom: 0.75rem;
	}

	.dmb-table th:nth-child(3),
	.dmb-table td:nth-child(3),
	.dmb-table th:nth-child(4),
	.dmb-table td:nth-child(4) {
		display: none;
	}

	.dmb-decide-inline {
		flex-direction: column;
	}
}

/* --- Approval dialog ----------------------------------------------------- */

.dmb-dialog {
	padding: 1.5rem;
}

.dmb-dialog-card {
	max-width: 26rem;
	width: 100%;
	padding: 1.75rem;
	border-radius: 14px;
	background: #fff;
	color: var(--dmb-ink);
	box-shadow: 0 18px 60px rgba( 0, 0, 0, 0.35 );
	text-align: center;
}

.dmb-dialog-title {
	margin: 0 0 0.6rem;
	font-size: 1.2rem;
	font-weight: 500;
}

.dmb-dialog-body {
	margin: 0 0 1.4rem;
	color: var(--dmb-muted);
	font-size: 0.95rem;
	line-height: 1.55;
}

.dmb-dialog-actions {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 8px;
}

.dmb-card-request {
	background: transparent;
	border: 1px solid var(--dmb-accent);
	color: var(--dmb-accent);
}

.dmb-card-request:hover {
	background: var(--dmb-accent);
	color: #fff;
}

@media ( max-width: 480px ) {
	.dmb-dialog-actions {
		flex-direction: column;
	}

	.dmb-dialog-actions .dmb-button {
		width: 100%;
	}
}

/* --- Idle selection bar --------------------------------------------------
 *
 * With nothing selected the bar is a prompt, so it should read as one line of
 * text. The buttons are hidden rather than disabled — disabled controls still
 * occupy the space, which is what made the resting state as tall as the
 * working one.
 * -------------------------------------------------------------------- */

.dmb-bar-idle {
	padding: 9px 16px;
}

.dmb-bar .dmb-button[hidden],
.dmb-bar button[hidden] {
	display: none;
}

@media ( max-width: 600px ) {
	/* Back to a single centred line on a phone, rather than a stacked tray
	   holding nothing. */
	.dmb-bar-idle {
		flex-direction: row;
		justify-content: center;
		padding: 9px 14px;
	}

	.dmb-bar-idle .dmb-bar-text {
		font-size: 0.82rem;
	}
}

/* --- Approve / decline ---------------------------------------------------
 *
 * Green for approve, and a deliberately plain outline for decline. The two sit
 * side by side and one of them is much harder to undo, so they shouldn't look
 * equally inviting — the destructive option earns its weight only once you're
 * on it.
 * -------------------------------------------------------------------- */

.dmb-yes {
	background: #2e7d52;
	border-color: #2e7d52;
	color: #fff;
}

.dmb-yes:hover,
.dmb-yes:focus-visible {
	background: #256743;
	border-color: #256743;
	filter: none;
}

.dmb-no {
	background: transparent;
	border-color: #4a4f55;
	color: #4a4f55;
}

.dmb-no:hover,
.dmb-no:focus-visible {
	background: #4a4f55;
	border-color: #4a4f55;
	color: #fff;
}

/* The same pairing on the detail screen, where they're full buttons. */
.dmb-request-actions button[value="approved"] {
	background: #2e7d52;
	border-color: #2e7d52;
	color: #fff;
}

.dmb-request-actions button[value="approved"]:hover {
	background: #256743;
	border-color: #256743;
}

.dmb-request-actions button[value="declined"] {
	background: transparent;
	border: 1px solid #4a4f55;
	color: #4a4f55;
}

.dmb-request-actions button[value="declined"]:hover {
	background: #4a4f55;
	color: #fff;
}

/* --- Prompt dialog ------------------------------------------------------- */

.dmb-dialog-form {
	text-align: left;
}

.dmb-dialog-label {
	display: block;
	margin: 0 0 6px;
	color: var(--dmb-muted);
	font-size: 0.85rem;
}

.dmb-dialog-input {
	width: 100%;
	padding: 0.65rem 0.85rem;
	margin: 0 0 1.25rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius);
	background: #fff;
	font: inherit;
	font-size: 16px; /* Under 16px, iOS zooms the page on focus. */
	color: var(--dmb-ink);
}

.dmb-dialog-input:focus {
	outline: 2px solid var(--dmb-accent);
	outline-offset: 1px;
	border-color: var(--dmb-accent);
}

.dmb-dialog-form .dmb-dialog-title,
.dmb-dialog-form .dmb-dialog-body {
	text-align: left;
}

.dmb-dialog-form .dmb-dialog-actions {
	justify-content: flex-start;
}

.dmb-dialog-body[hidden],
.dmb-dialog-label[hidden] {
	display: none;
}

/* --- Copy feedback ------------------------------------------------------- */

.dmb-share-link {
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease;
}

.dmb-share-link:hover {
	border-color: var(--dmb-accent);
	background: #fff;
}

/*
 * A fixed slot, always present. Using visibility rather than display, and a
 * width that doesn't depend on the text, means the message can appear without
 * anything moving — a row that reflows the instant you click it makes the click
 * feel like it went wrong.
 */
.dmb-copied {
	flex: 0 0 auto;
	width: 10.5rem;
	text-align: right;
	color: #2e7d52;
	font-size: 0.8rem;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	visibility: hidden;
	opacity: 0;
	transition: opacity 0.15s ease;
}

.dmb-copied.is-on {
	visibility: visible;
	opacity: 1;
}

@media ( max-width: 600px ) {
	.dmb-copied {
		width: 100%;
		text-align: left;
	}
}

/* --- Usage label and editing -------------------------------------------- */

.dmb-usage {
	display: inline-block;
	margin-top: 6px;
	padding: 2px 8px;
	border-radius: 999px;
	font-size: 0.72rem;
	font-weight: 500;
	letter-spacing: 0.01em;
}

.dmb-usage-internal {
	background: #fdf0e6;
	color: #8a4b12;
}

.dmb-card-edit {
	display: block;
	padding: 8px 12px;
	border-top: 1px solid var(--dmb-line);
	color: var(--dmb-muted);
	font-size: 0.82rem;
	text-align: center;
	text-decoration: none;
	transition: background 0.15s ease, color 0.15s ease;
}

.dmb-card-edit:hover {
	background: var(--dmb-soft);
	color: var(--dmb-ink);
}

.dmb-edit-preview {
	margin: 0 0 1.5rem;
}

.dmb-edit-preview img {
	max-width: 320px;
	height: auto;
	border-radius: var(--dmb-radius);
	border: 1px solid var(--dmb-line);
}

.dmb-editlist {
	display: grid;
	grid-template-columns: repeat( auto-fill, minmax( 130px, 1fr ) );
	gap: 12px;
	margin: 1.5rem 0 0;
	padding: 0;
	list-style: none;
}

.dmb-editlist a {
	display: block;
	color: inherit;
	text-decoration: none;
	font-size: 0.85rem;
}

.dmb-editlist img,
.dmb-editlist .dmb-request-file-none {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: var(--dmb-radius);
	background: var(--dmb-soft);
	margin-bottom: 6px;
}

.dmb-editlist a:hover span {
	color: var(--dmb-accent);
}

/* --- Usage: both states, coloured ---------------------------------------
 *
 * Green for cleared, amber for internal. Colour carries the meaning at a
 * glance, but the words are still there — about one man in twelve can't
 * reliably tell red-green apart, and "which of these can I send out" is not a
 * question to answer with hue alone.
 * -------------------------------------------------------------------- */

.dmb-usage-external {
	background: #e6f4ec;
	color: #1f5c3d;
}

/* --- Mobile hero order ---------------------------------------------------
 *
 * The welcome panel first, then the search bar under it. On a phone the panel
 * is what says where you are; leading with a search box asks a question before
 * saying what it's a question about.
 * -------------------------------------------------------------------- */

@media ( max-width: 860px ) {
	.dmb-hero-panel {
		order: 1;
	}

	.dmb-hero-search {
		order: 2;
	}
}

/* =========================================================================
   Restored styles
   -------------------------------------------------------------------------
   These rules were lost in 4.51.0. Rebuilding the Dashboard meant cutting the
   old admin-card block out of this file, and the cut ran further than it
   should have — taking the recycle bin, the consent panels and a handful of
   shared pieces with it. Nothing broke loudly, because every one of these
   elements still rendered; they just rendered unstyled, which is exactly the
   kind of fault that ships.

   Kept together and labelled rather than scattered back to where they came
   from, so that if any of them look wrong it's obvious which change to
   suspect.
   ========================================================================= */

/* The introductory line under a page title. */
.dmb-lede {
	margin: 0 0 1.5rem;
	max-width: 46rem;
	font-size: 1.05rem;
	line-height: 1.6;
	color: var(--dmb-muted);
}

/* A count beside a section heading — how many things are waiting. */
.dmb-count-pill {
	display: inline-block;
	margin-left: 0.5rem;
	padding: 0.1rem 0.6rem;
	border-radius: 999px;
	background: #e2574c;
	color: #fff;
	font-size: 0.8rem;
	font-weight: 600;
	vertical-align: middle;
}

/*
 * Destructive things are links and quiet buttons, never the main event.
 *
 * Deleting sits below Save on the edit screen, and giving it the same weight
 * as the thing people came to do would invite the mistake the recycle bin
 * exists to prevent.
 */
.dmb-linkbutton-danger {
	color: #c0392b;
}

.dmb-button-danger {
	border-color: #c0392b;
	color: #c0392b;
}

.dmb-button-danger:hover {
	background: #c0392b;
	border-color: #c0392b;
	color: #fff;
}

/* Delete in the selection bar: present, but not shouting. */
.dmb-bar-delete {
	color: #c0392b;
}

/* The delete form on a file's edit screen. */
.dmb-binform {
	margin-top: 1.75rem;
	padding-top: 1.25rem;
	border-top: 1px solid var(--dmb-line);
}

.dmb-binform .dmb-hint {
	display: block;
	margin-top: 0.35rem;
}

/* -------------------------------------------------------------------------
   The recycle bin
   ------------------------------------------------------------------------- */

.dmb-binlist {
	margin: 0.75rem 0 0;
}

.dmb-bintable td,
.dmb-bintable th {
	vertical-align: middle;
}

.dmb-bin-check {
	width: 2.25rem;
	text-align: center;
}

.dmb-bin-thumb {
	width: 3.5rem;
}

.dmb-bin-thumb img {
	display: block;
	width: 44px;
	height: 44px;
	object-fit: cover;
	border-radius: 6px;
}

/*
 * The two buttons live in a bar below the table, not in a cell.
 *
 * They were in a cell once, laid out with flex, which quietly stops a <td>
 * behaving like a table cell at all and pulled every row out of alignment.
 */
.dmb-binbar {
	display: flex;
	gap: 0.6rem;
	align-items: center;
	flex-wrap: wrap;
	margin-top: 0.9rem;
}

/* -------------------------------------------------------------------------
   Consent
   ------------------------------------------------------------------------- */

/*
 * Blue rather than green.
 *
 * Green already means "cleared for external use" on these cards, and consent
 * answers a different question — whether a person agreed to be photographed.
 * Two greens would read as the same badge said twice.
 */
.dmb-usage-consent {
	background: #e7eef6;
	color: #29527a;
}

/*
 * Partly covered: something on file, nobody has confirmed it covers everyone.
 *
 * Amber, not red. It isn't a breach, it's an unfinished job — usually a video
 * where two of the six releases are attached so far — and colouring unfinished
 * work as failure teaches people to stop reading the colour.
 */
.dmb-usage-consent-part {
	background: #fdf0d5;
	color: #8a6100;
}

.dmb-consentlist {
	list-style: none;
	margin: 0.35rem 0 0;
	padding: 0;
	font-size: 0.93rem;
}

.dmb-consentlist li {
	padding: 0.2rem 0;
}

.dmb-consent-expired td {
	opacity: 0.7;
}

.dmb-consentbox {
	margin-top: 1.75rem;
	padding-top: 1.25rem;
	border-top: 1px solid var(--dmb-line);
}

/* "Everyone in this file is covered." */
.dmb-consentdone {
	margin-top: 0.75rem;
	display: flex;
	gap: 0.6rem;
	align-items: center;
	flex-wrap: wrap;
}

.dmb-consentdone .dmb-tick {
	align-items: flex-start;
}

.dmb-consentdone .dmb-hint {
	flex: 1 1 100%;
	margin: 0;
}

/*
 * Two ways in, deliberately weighted. Linking someone who has already signed
 * is a dropdown and a button, because that's the common case. Uploading a new
 * release is a quiet link, because it means somebody has paper in their hand.
 */
.dmb-consentadd {
	display: flex;
	gap: 0.5rem;
	align-items: center;
	flex-wrap: wrap;
	margin-top: 0.65rem;
}

.dmb-consentadd select {
	flex: 1 1 16rem;
	min-width: 0;
	max-width: 24rem;
}

/* A small form sitting on the same line as the text it belongs to. */
.dmb-inlineform {
	display: inline;
	margin: 0 0 0 0.5rem;
}

/*
 * The consent reminder on the upload screens.
 *
 * Tinted, not shouted. Most uploads are logos and documents with nobody in
 * them, and a warning that fires every time is one people learn to skip.
 */
.dmb-consentnote {
	padding: 0.85rem 1rem;
	border-radius: var( --dmb-radius, 10px );
	background: #e7eef6;
	color: #29527a;
}

.dmb-consentnote .dmb-hint,
.dmb-consentnote .description {
	color: inherit;
	margin: 0.3rem 0 0;
}

/* -------------------------------------------------------------------------
   The Users table
   ------------------------------------------------------------------------- */

/*
 * The account type is a dropdown in the cell rather than an edit screen of its
 * own: there is exactly one thing to change about a person, and a whole page
 * to change one field is a page nobody enjoys.
 */
.dmb-rolepick {
	display: flex;
	gap: 0.4rem;
	align-items: center;
	flex-wrap: wrap;
	margin: 0;
}

.dmb-rolepick select {
	min-width: 10rem;
}

/* Remove, kept to the far side and quiet — the one thing here that another
   press won't undo. */
.dmb-usertable-end {
	text-align: right;
	white-space: nowrap;
}

/* -------------------------------------------------------------------------
   Odds and ends
   ------------------------------------------------------------------------- */

.dmb-right {
	text-align: right;
}

/* The caption under a picture in the lightbox. */
.dmb-lb-title {
	display: block;
	margin-top: 0.75rem;
	font-size: 0.95rem;
	color: #fff;
	text-align: center;
}

.dmb-login-form {
	margin: 0;
}

/*
 * Tagging a whole folder.
 *
 * A <details> rather than a panel: tidying up a folder's tags happens once,
 * usually long after the files went in, and a tag picker sitting open above
 * the photographs would be in the way on every visit that isn't about tagging.
 */
.dmb-foldertags {
	margin: 0 0 1.25rem;
	border: 1px solid var(--dmb-line);
	border-radius: var( --dmb-radius, 10px );
	background: var( --dmb-soft, #f6f8f9 );
}

.dmb-foldertags > summary {
	padding: 0.6rem 1rem;
	cursor: pointer;
	font-size: 0.92rem;
	font-weight: 600;
	color: var( --dmb-accent, #22384c );
	list-style: none;
}

.dmb-foldertags > summary::-webkit-details-marker {
	display: none;
}

.dmb-foldertags > summary::before {
	content: "+";
	display: inline-block;
	width: 1rem;
	font-weight: 700;
}

.dmb-foldertags[open] > summary::before {
	content: "−";
}

.dmb-foldertags form {
	padding: 0 1rem 1rem;
}

.dmb-foldertags .dmb-hint {
	margin: 0 0 0.75rem;
}

/* The folder picker in the move dialog. */
.dmb-move-pick {
	width: 100%;
	max-width: 26rem;
}

/*
 * Folder tools.
 *
 * Same folded-away treatment as the bulk tagger, and for the same reason:
 * renaming a folder or changing its cover happens once, and a panel of forms
 * sitting open above the photographs would be in the way every other time.
 */
/*
 * The folder's own bar: add files, and everything else folded away.
 *
 * "Add files here" is out in the open and the rest is behind the disclosure,
 * because they happen at completely different rates. Adding to a folder you
 * are already looking at is the ordinary reason to be here; renaming it is
 * once in its life.
 *
 * align-items: flex-start so the button stays put rather than stretching to
 * the height of the panel when somebody opens it.
 */
.dmb-folderbar {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin: 0 0 1.25rem;
}

/*
 * The button is built to be exactly as tall as the summary beside it.
 *
 * It can't simply be centred: align-items: center would centre it against the
 * whole <details>, so opening the panel would send it floating down the middle
 * of a tall box. And it can't stretch, for the same reason. What lines the two
 * middles up is making the two boxes the same height and leaving both at the
 * top.
 *
 * So this mirrors the summary's box rather than inventing a height:
 *
 *   0.6rem padding, twice                    19.2px
 *   0.92rem of text at the portal's 1.55     22.8px
 *   a 1px transparent border, twice           2.0px  — the panel has a real
 *                                                      border and the row
 *                                                      starts at its outer
 *                                                      edge, so without this
 *                                                      the button is 2px short
 *                                            ------
 *                                             44.0px
 *
 * Changing the summary's padding or size means changing these to match. They
 * are together here, and folderscreen.py fails if they drift apart.
 */
.dmb-folderbar-add {
	flex: 0 0 auto;
	white-space: nowrap;

	display: inline-flex;
	align-items: center;
	justify-content: center;

	padding: 0.6rem 1.15rem;
	border: 1px solid transparent;
	border-radius: var( --dmb-radius, 10px );
	font-size: 0.92rem;
	line-height: 1.55;
}

.dmb-foldertools {
	margin: 0 0 1.25rem;
	border: 1px solid var(--dmb-line);
	border-radius: var( --dmb-radius, 10px );
	background: var( --dmb-soft, #f6f8f9 );
}

/* Inside the bar the row owns the spacing, so the panel gives its own up. */
.dmb-folderbar > .dmb-foldertools {
	flex: 1 1 auto;
	min-width: 0;
	margin: 0;
}

@media ( max-width: 640px ) {
	.dmb-folderbar {
		flex-direction: column;
		align-items: stretch;
	}

	/* Stacked, there is no summary to line up with — it goes full width and
	 * centres its own label, which inline-flex is already doing. */
	.dmb-folderbar-add {
		width: 100%;
	}
}

.dmb-foldertools > summary {
	padding: 0.6rem 1rem;
	cursor: pointer;
	font-size: 0.92rem;
	font-weight: 600;
	color: var( --dmb-accent, #22384c );
	list-style: none;
}

.dmb-foldertools > summary::-webkit-details-marker {
	display: none;
}

.dmb-foldertools > summary::before {
	content: "+";
	display: inline-block;
	width: 1rem;
	font-weight: 700;
}

.dmb-foldertools[open] > summary::before {
	content: "−";
}

.dmb-foldertools-inner {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 260px, 1fr ) );
	gap: 1.25rem;
	padding: 0 1rem 1.25rem;
}

.dmb-foldertool label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.92rem;
}

.dmb-foldertool-row {
	display: flex;
	gap: 0.45rem;
	align-items: center;
	flex-wrap: wrap;
}

.dmb-foldertool-row input[type="text"],
.dmb-foldertool-row select {
	flex: 1 1 10rem;
	min-width: 0;
}

/* Deleting sits with the rest but reads as the odd one out, which it is. */
.dmb-foldertool .dmb-hint {
	display: block;
	margin-top: 0.35rem;
}

/* -------------------------------------------------------------------------
   The selection bar's More menu
   -------------------------------------------------------------------------
   Two actions stay on the bar and the occasional ones move in here. The bar had
   grown to six buttons, which wrapped onto two lines and stopped looking like a
   toolbar. Anything added from now on goes in the menu rather than the bar, so
   it can't creep back.
   ------------------------------------------------------------------------- */

.dmb-bar-more {
	position: relative;
}

.dmb-bar-menu {
	position: absolute;
	right: 0;
	bottom: calc( 100% + 0.5rem );
	min-width: 12rem;
	padding: 0.35rem;
	border: 1px solid var(--dmb-line);
	border-radius: var( --dmb-radius, 10px );
	background: #fff;
	box-shadow: 0 10px 30px rgba( 0, 0, 0, 0.14 );
	z-index: 5;
}

.dmb-bar-menu-item {
	display: block;
	width: 100%;
	padding: 0.5rem 0.7rem;
	border: 0;
	border-radius: 6px;
	background: none;
	font: inherit;
	font-size: 0.93rem;
	text-align: left;
	cursor: pointer;
	color: var( --dmb-ink, #22384c );
}

.dmb-bar-menu-item:hover,
.dmb-bar-menu-item:focus-visible {
	background: var( --dmb-soft, #f6f8f9 );
}

/*
 * Overrides the bar's own button colours, which are built for a dark bar and
 * would otherwise paint these white on white — which is exactly what happened.
 */
.dmb-bar .dmb-bar-menu-item,
.dmb-bar .dmb-bar-menu-item.dmb-button-quiet {
	color: var( --dmb-ink, #22384c );
	border: 0;
	background: none;
}

.dmb-bar .dmb-bar-menu-item:hover {
	background: var( --dmb-soft, #f6f8f9 );
}

.dmb-bar .dmb-bar-menu-danger,
.dmb-bar-menu-danger {
	color: #c0392b;
}

/* Named actions on a folded-away panel, so a closed one says what's in it. */
.dmb-foldertools-what {
	font-weight: 400;
	color: var(--dmb-muted);
}

/* The "can organise" tick in the Users table. */
.dmb-organise {
	display: flex;
	gap: 0.45rem;
	align-items: center;
	flex-wrap: wrap;
	margin: 0;
}

/* The folder a dragged-in file will land in, shown before it's uploaded. */
.dmb-queue-path {
	display: block;
	font-size: 0.8rem;
	color: var(--dmb-muted);
}

.dmb-dropzone-folder {
	margin: 0.75rem 0 0;
}

.dmb-dropzone-folder .dmb-hint {
	display: block;
	margin-top: 0.25rem;
}


/*
 * An ordinary tick box with a label beside it.
 *
 * Its own class rather than .dmb-check, which is the selection box that sits
 * absolutely positioned in the corner of a file card. Borrowing that name put
 * "Can organise" and the consent confirmation into the corner of whatever
 * happened to be positioned nearby, leaving a Save button on its own with
 * nothing to save — twice, in two different screens, before anyone spotted it.
 */
.dmb-tick {
	display: inline-flex;
	gap: 0.45rem;
	align-items: center;
	font-size: 0.93rem;
	line-height: 1.35;
	cursor: pointer;
}

.dmb-tick input {
	width: 16px;
	height: 16px;
	margin: 0;
	cursor: pointer;
	flex: none;
}

/* =========================================================================
 * Delivery mode
 *
 * Only ever rendered on a delivery portal, but kept in the one stylesheet
 * rather than a second file: two stylesheets means two things to enqueue, two
 * things to cache-bust and two places to look when something isn't styled.
 * ========================================================================= */

/*
 * The countdown.
 *
 * Deliberately not a warning colour at rest. For eleven of the fourteen days
 * this is a fact, not a problem, and a red panel above someone's finished film
 * is the wrong first impression. It changes only when it's genuinely nearly
 * over.
 */
.dmb-delivery-banner {
	margin: 0 0 1.5rem;
	padding: 1.1rem 1.3rem;
	border: 1px solid var(--dmb-line);
	border-left: 4px solid var(--dmb-accent);
	border-radius: var(--dmb-radius, 10px);
	background: var(--dmb-soft);
}

.dmb-delivery-banner-warn {
	border-left-color: #b45309;
	background: #fef6ec;
}

.dmb-delivery-when {
	margin: 0;
	font-size: 1.05rem;
}

.dmb-delivery-advice,
.dmb-delivery-note {
	margin: 0.4rem 0 0;
	color: var(--dmb-muted);
	font-size: 0.94rem;
}

.dmb-delivery-note {
	color: var(--dmb-ink);
	font-style: italic;
}

.dmb-delivery-ended {
	margin: 0 0 1.5rem;
	padding: 2rem 1.75rem;
	border: 1px solid var(--dmb-line);
	border-radius: var(--dmb-radius-lg, 14px);
	background: var(--dmb-soft);
	text-align: center;
}

.dmb-delivery-ended h2 {
	margin: 0 0 0.6rem;
}

.dmb-delivery-ended p {
	max-width: 34em;
	margin: 0 auto 1rem;
	color: var(--dmb-muted);
}

/* -------------------------------------------------------------------------
 * The pitch
 *
 * Set apart from the portal above it by a full-width tinted band rather than a
 * rule. A section that shares the page's background reads as more portal; this
 * has to read as a change of subject, because it is one — the reader has
 * finished collecting their assets and is now being spoken to rather than
 * served.
 *
 * ALIGNMENT, since it's easy to get wrong and obvious when it is:
 *   - the head and the closing offer are centred, and narrower than the rest
 *   - the three reasons and the feature tiles are left-aligned, because
 *     centred body copy in a column is hard to read
 *   - the label between them is centred, so the centre line runs head, label,
 *     offer down the page and the left-aligned blocks sit between them
 *   - every block shares one of two max-widths and is centred with auto
 *     margins, so their left edges line up exactly rather than nearly
 * ------------------------------------------------------------------------- */

/*
 * A palette for this section only.
 *
 * The portal itself is deliberately quiet — it's a working tool and colour
 * there is signal, not decoration. This is the one screen doing a different
 * job, so it gets four accents cycled across the tiles. Defined here rather
 * than inline so all of it can be changed in one place.
 */
.dmb-pitch {
	--dmb-p1: #2563eb;
	--dmb-p2: #7c3aed;
	--dmb-p3: #0d9488;
	--dmb-p4: #ea580c;

	margin: 3.5rem -2rem 0;
	padding: 3.5rem 2rem 3rem;
	border-top: 1px solid var(--dmb-line);

	/*
	 * Plain, like the sign-up page.
	 *
	 * Two overlapping radial washes behind white cards was a lot of weather
	 * for one page — the cards have their own colour on top, and the gradients
	 * left the section looking busy next to the calm grey the rest of the
	 * portal uses. The sign-up page works because there's one thing on it and
	 * nothing behind it.
	 */
	background: var(--dmb-soft);
}

/* ---- the head, centred ---- */
.dmb-pitch-head {
	max-width: 46em;
	margin: 0 auto 3rem;
	text-align: center;
}

/*
 * Says what this is before the headline sells it. Without it the pitch can read
 * as though the delivery itself came with strings attached, which is exactly the
 * wrong feeling at the end of a job.
 */
.dmb-pitch-eyebrow {
	display: inline-block;
	margin-bottom: 1rem;
	padding: 0.35rem 0.95rem;
	border-radius: 999px;
	background: linear-gradient( 90deg, var(--dmb-p1), var(--dmb-p2) );
	color: #fff;
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.dmb-pitch-title {
	margin: 0 0 1rem;
	font-size: clamp( 1.7rem, 3.6vw, 2.6rem );
	line-height: 1.12;
	letter-spacing: -0.025em;
	text-wrap: balance;
}

/*
 * --dmb-muted, not --dmb-grey-dark.
 *
 * --dmb-grey is the *button* colour in the branding settings, and its dark
 * variant was being used here as a text colour. On a portal branded with a
 * strong button colour the body copy of the whole sales section took that hue
 * — it read as though it had been styled by accident, because it had.
 *
 * --dmb-muted is the colour the palette provides for supporting text, which is
 * what this is. It's also very slightly darker than what it replaces, so the
 * default portal looks the same and a branded one stops looking odd.
 */
.dmb-pitch-lede {
	margin: 0;
	font-size: 1.08rem;
	line-height: 1.65;
	color: var(--dmb-muted);
}

/* ---- the three reasons, left-aligned inside a centred block ---- */

/*
 * Three, and never four.
 *
 * Three fits one row on a laptop and reads as a considered argument. Four wraps
 * to 3 + 1, which looks like a list that ran out, and by the fourth reason
 * nobody is still counting.
 */
/*
 * Two by two.
 *
 * auto-fit with a 250px floor put all four across at desktop width, which
 * squeezed each card to about 250px and left four columns of thin text — the
 * bit that stopped looking clean when the third point became a fourth. Two
 * rows of two gives each card room to be read.
 */
.dmb-pitch-points {
	display: grid;
	grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	gap: 1.25rem;
	max-width: 54em;
	margin: 0 auto 3.5rem;
	text-align: left;
}

@media ( max-width: 720px ) {
	.dmb-pitch-points {
		grid-template-columns: 1fr;
	}
}

/*
 * The same card as the sign-up page.
 *
 * That page reads well because of what it doesn't do: one white card, a
 * generous radius, and a shadow soft enough to lift it off the grey without
 * announcing itself. Borrowing it here makes the pitch look like the same
 * product rather than a section bolted to the bottom of it.
 */
.dmb-pitch-point {
	position: relative;
	padding: 1.7rem 1.6rem 1.55rem;
	border: 0;
	border-radius: 10px;
	background: #fff;
	box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.06 ), 0 12px 40px rgba( 34, 56, 76, 0.09 );
	transition: transform 0.22s ease, box-shadow 0.22s ease;
}

/* The same step-out as the tiles below, so the whole section behaves one way. */
.dmb-pitch-point:hover {
	transform: translateY( -5px );
	box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.06 ), 0 22px 52px rgba( 34, 56, 76, 0.16 );
}

.dmb-pitch-point:nth-child( 1 )::before {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	height: 3px;
	border-radius: 10px 10px 0 0;
	background: var(--dmb-p1);
}
.dmb-pitch-point:nth-child( 2 )::before {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	height: 3px;
	border-radius: 10px 10px 0 0;
	background: var(--dmb-p2);
}
.dmb-pitch-point:nth-child( 3 )::before {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	height: 3px;
	border-radius: 10px 10px 0 0;
	background: var(--dmb-p3);
}

/* --dmb-p4 was declared at the top of this block and never used, so the
 * fourth point turned up with no stripe while the other three had one. */
.dmb-pitch-point:nth-child( 4 )::before {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	height: 3px;
	border-radius: 10px 10px 0 0;
	background: var(--dmb-p4);
}

/*
 * The numbers are decoration doing a job: they tell the eye these three are one
 * argument in order rather than three unrelated claims. Large, pale, and behind
 * the words so they never compete with them.
 */
.dmb-pitch-num {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 1.5rem;
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.02em;
}

.dmb-pitch-point:nth-child( 1 ) .dmb-pitch-num { color: var(--dmb-p1); }
.dmb-pitch-point:nth-child( 2 ) .dmb-pitch-num { color: var(--dmb-p2); }
.dmb-pitch-point:nth-child( 3 ) .dmb-pitch-num { color: var(--dmb-p3); }
.dmb-pitch-point:nth-child( 4 ) .dmb-pitch-num { color: var(--dmb-p4); }

.dmb-pitch-point h3 {
	margin: 0 0 0.55rem;
	font-size: 1.12rem;
	line-height: 1.3;
	text-wrap: balance;
}

.dmb-pitch-point p {
	margin: 0;
	color: var(--dmb-muted);
	line-height: 1.6;
}

/* ---- the label between the two halves, centred with rules either side ---- */
.dmb-pitch-sub {
	display: flex;
	align-items: center;
	gap: 1rem;
	max-width: 64em;
	margin: 0 auto 1.25rem;
	color: var(--dmb-muted);
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.dmb-pitch-sub::before,
.dmb-pitch-sub::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--dmb-line);
}

/* ---- the feature grid, demoted to evidence ---- */

/*
 * It backs up the argument above rather than being the argument, so it's
 * tighter and quieter than the dashboard grid it borrows from. It still moves
 * on hover, because eight motionless panels in the middle of a pitch look like
 * a screenshot of something rather than a thing.
 */
/*
 * Flex rather than grid, so a short last row centres itself.
 *
 * A grid puts leftovers at the left-hand end, which with nine tiles across
 * four columns leaves one stranded under an empty three-quarters of a row.
 * Wrapping and centring means the bottom row sits under the middle of the
 * ones above whatever the count is — and the count changes every time a
 * feature is added or, as just happened, taken out.
 */
.dmb-hub-demo {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	max-width: 64em;
	margin: 0 auto 3rem;
	gap: 0.85rem;
}

.dmb-hub-demo .dmb-hubtile-off {
	flex: 1 1 210px;
	max-width: 260px;
}

@media ( max-width: 520px ) {
	.dmb-hub-demo .dmb-hubtile-off {
		flex-basis: 100%;
		max-width: none;
	}
}

.dmb-hubtile-off {
	position: relative;
	display: block;
	overflow: hidden;
	padding: 1.15rem 1.2rem;
	border: 0;
	border-radius: 10px;
	background: #fff;
	box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.05 ), 0 6px 20px rgba( 34, 56, 76, 0.06 );
	cursor: default;
	transition: transform 0.22s ease, box-shadow 0.22s ease;
}

.dmb-hubtile-off:hover {
	transform: translateY( -6px );
	box-shadow: 0 18px 36px rgba( 15, 23, 42, 0.13 );
	border-color: transparent;
	background: #fff;
}

/*
 * A colour bar that draws itself in from the left on hover.
 *
 * Cheaper than it looks — one transform, no repaint — and it's the thing that
 * makes eight identical panels feel like something you're moving through rather
 * than a table.
 */
.dmb-hubtile-bar {
	position: absolute;
	inset: 0 0 auto 0;
	height: 3px;
	transform: scaleX( 0 );
	transform-origin: left;
	transition: transform 0.28s ease;
}

.dmb-hubtile-off:hover .dmb-hubtile-bar {
	transform: scaleX( 1 );
}

.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 1 ) .dmb-hubtile-bar { background: var(--dmb-p1); }
.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 2 ) .dmb-hubtile-bar { background: var(--dmb-p2); }
.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 3 ) .dmb-hubtile-bar { background: var(--dmb-p3); }
.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 4 ) .dmb-hubtile-bar { background: var(--dmb-p4); }

.dmb-hubtile-off .dmb-hubtile-title {
	display: block;
	margin-bottom: 0.3rem;
	font-size: 0.98rem;
	transition: color 0.22s ease;
}

.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 1 ):hover .dmb-hubtile-title { color: var(--dmb-p1); }
.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 2 ):hover .dmb-hubtile-title { color: var(--dmb-p2); }
.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 3 ):hover .dmb-hubtile-title { color: var(--dmb-p3); }
.dmb-hub-demo .dmb-hubtile-off:nth-child( 4n + 4 ):hover .dmb-hubtile-title { color: var(--dmb-p4); }

.dmb-hubtile-off .dmb-hubtile-blurb {
	display: block;
	margin: 0;
	font-size: 0.86rem;
	line-height: 1.45;
	color: var(--dmb-muted);
}

/* -------------------------------------------------------------------------
 * The closing offer
 * ------------------------------------------------------------------------- */
.dmb-offer {
	position: relative;
	overflow: hidden;
	max-width: 46em;
	margin: 0 auto;
	padding: 2.5rem 2rem;
	border-radius: var(--dmb-radius-lg, 14px);
	background:
		radial-gradient( 600px 260px at 80% -20%, rgba( 124, 58, 237, 0.55 ), transparent 70% ),
		linear-gradient( 135deg, #111827, #1f2937 );
	color: #fff;
	text-align: center;
}

/* The one bit of colour that isn't behind anything, along the very top edge. */
.dmb-offer::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 4px;
	background: linear-gradient( 90deg, var(--dmb-p1), var(--dmb-p2), var(--dmb-p3), var(--dmb-p4) );
}

.dmb-offer-headline {
	margin: 0 0 0.7rem;
	font-size: clamp( 1.35rem, 2.5vw, 1.8rem );
	line-height: 1.18;
	letter-spacing: -0.02em;
	color: #fff;
	text-wrap: balance;
}

.dmb-offer-body {
	max-width: 34em;
	margin: 0 auto 1.6rem;
	line-height: 1.65;
	color: rgba( 255, 255, 255, 0.84 );
}

.dmb-offer-actions {
	display: flex;
	gap: 1.4rem;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
}

.dmb-button-big {
	padding: 1rem 2.5rem;
	font-size: 1.02rem;
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.dmb-button-big:hover {
	transform: translateY( -2px );
	box-shadow: 0 12px 26px rgba( 0, 0, 0, 0.35 );
}

.dmb-offer-ask {
	color: rgba( 255, 255, 255, 0.84 );
	text-decoration: underline;
	text-underline-offset: 3px;
	transition: color 0.18s ease;
}

.dmb-offer-ask:hover {
	color: #fff;
}

/*
 * A list rather than a run-on line of middots.
 *
 * Four claims separated by dots wrapped mid-claim on a phone, which read as one
 * long sentence that had gone wrong. As items they wrap between claims instead,
 * and each still gets its own tick.
 */
.dmb-offer-reassure {
	display: flex;
	gap: 0.5rem 1.5rem;
	justify-content: center;
	flex-wrap: wrap;
	margin: 1.75rem 0 0;
	padding: 1.4rem 0 0;
	border-top: 1px solid rgba( 255, 255, 255, 0.14 );
	list-style: none;
	font-size: 0.84rem;
	color: rgba( 255, 255, 255, 0.68 );
}

.dmb-offer-reassure li::before {
	content: "\2713";
	margin-right: 0.4rem;
	color: #34d399;
	font-weight: 700;
}

/* The band's negative margin has to come back on a narrow screen. */
@media ( max-width: 640px ) {
	.dmb-pitch {
		margin-left: -1rem;
		margin-right: -1rem;
		padding: 2.5rem 1rem 2.25rem;
	}

	.dmb-offer {
		padding: 2rem 1.25rem;
	}

	.dmb-offer-reassure {
		flex-direction: column;
		align-items: center;
	}
}

/*
 * Somebody who has asked their computer to stop things moving has asked for a
 * reason. The colour stays; only the motion goes.
 */
@media ( prefers-reduced-motion: reduce ) {
	.dmb-pitch-point,
	.dmb-hubtile-off,
	.dmb-hubtile-bar,
	.dmb-button-big {
		transition: none;
	}

	.dmb-pitch-point:hover,
	.dmb-hubtile-off:hover,
	.dmb-button-big:hover {
		transform: none;
	}

	.dmb-hubtile-bar {
		transform: scaleX( 1 );
	}
}

/* -------------------------------------------------------------------------
 * The team's list
 * ------------------------------------------------------------------------- */
.dmb-delivery-sub {
	display: block;
	margin-top: 0.15rem;
	color: var(--dmb-muted);
	font-size: 0.85rem;
}

.dmb-row-quiet {
	opacity: 0.6;
}

/*
 * "Collected" is the column this page exists for, so it's the only one with a
 * colour on it. Green because it means nothing further is needed; the "not yet"
 * is left plain rather than made red, because a client who hasn't downloaded
 * yet on day one isn't a problem.
 */
.dmb-collected {
	font-weight: 600;
	color: #15803d;
}

.dmb-uncollected {
	color: var(--dmb-muted);
}

.dmb-delivery-actions {
	white-space: nowrap;
}

.dmb-delivery-actions .dmb-inlineform {
	display: block;
	margin: 0 0 0.2rem;
}

/*
 * The demo grid runs a little tighter than the real one. There are eight tiles
 * and nothing to do on any of them, so they're a picture of a dashboard rather
 * than a dashboard, and a picture wants to fit on the screen.
 */


/*
 * Client first and widest, actions last and narrow. The two middle columns are
 * numbers, which read better right up against their heading than spread out.
 */
.dmb-deliveries th:first-child,
.dmb-deliveries td:first-child {
	width: 28%;
}

.dmb-deliveries td {
	vertical-align: top;
}

/* --- Declared use --------------------------------------------------------
 *
 * Two surfaces sharing one set of rules: the dialogue in the grid, and the
 * page the server renders when JavaScript isn't answering. They have to look
 * like the same question, because they are — and if they diverge, the version
 * people see when something has gone wrong is the one that looks broken.
 * ------------------------------------------------------------------------- */

.dmb-dialog-wide {
	max-width: 34rem;
	text-align: left;
}

.dmb-gate-choices {
	margin: 0 0 1.4rem;
	padding: 0;
	list-style: none;
	text-align: left;
}

.dmb-gate-choices li + li {
	margin-top: 2px;
}

.dmb-gate-choices label {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px 12px;
	border-radius: 8px;
	cursor: pointer;
	font-size: 0.95rem;
	transition: background 0.12s ease;
}

.dmb-gate-choices label:hover {
	background: rgba( 0, 0, 0, 0.04 );
}

.dmb-gate-choices input {
	margin: 0;
	flex: 0 0 auto;
}

/*
 * The list of offending files. Left-aligned and roomy on purpose: this is the
 * only part of the box anybody needs to actually read, and three filenames set
 * as a centred paragraph read as decoration.
 */
.dmb-gate-files {
	margin: 0 0 1.2rem;
	padding: 0.9rem 1rem;
	list-style: none;
	border-radius: 10px;
	background: rgba( 0, 0, 0, 0.04 );
	text-align: left;
}

.dmb-gate-files li + li {
	margin-top: 0.6rem;
	padding-top: 0.6rem;
	border-top: 1px solid rgba( 0, 0, 0, 0.07 );
}

.dmb-gate-file {
	display: block;
	font-size: 0.95rem;
}

.dmb-gate-why {
	display: block;
	margin-top: 2px;
	color: var( --dmb-muted );
	font-size: 0.82rem;
}

/*
 * The override, set apart and below. Reachable, never the obvious next click:
 * the quickest way out of this box should be the one that removes the files.
 */
.dmb-gate-override {
	margin-top: 1.4rem;
	padding-top: 1.2rem;
	border-top: 1px solid rgba( 0, 0, 0, 0.1 );
	text-align: left;
}

.dmb-gate-override label {
	display: block;
	margin-bottom: 0.5rem;
	font-size: 0.9rem;
}

.dmb-gate-override input[type="text"] {
	width: 100%;
	padding: 9px 11px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.95rem;
}

.dmb-gate-note {
	margin: 0.5rem 0 0.9rem;
	color: var( --dmb-muted );
	font-size: 0.82rem;
}

/* --- The server-rendered page -------------------------------------------- */

.dmb-gate-page {
	margin: 0;
	background: var( --dmb-bg, #f5f5f4 );
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	color: var( --dmb-ink, #1c1917 );
}

.dmb-gate {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 100vh;
	padding: 1.5rem;
}

.dmb-gate-card {
	max-width: 34rem;
	width: 100%;
	padding: 2rem;
	border-radius: 14px;
	background: #fff;
	box-shadow: 0 18px 60px rgba( 0, 0, 0, 0.12 );
}

.dmb-gate-title {
	margin: 0 0 0.5rem;
	font-size: 1.25rem;
	font-weight: 500;
	line-height: 1.35;
}

.dmb-gate-sub,
.dmb-gate-body {
	margin: 0 0 1.3rem;
	color: var( --dmb-muted, #78716c );
	font-size: 0.95rem;
	line-height: 1.55;
}

.dmb-gate-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

/* --- Downloads screen ---------------------------------------------------- */

.dmb-row-flagged {
	background: rgba( 180, 83, 9, 0.06 );
}

.dmb-flag {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 7px;
	border-radius: 999px;
	background: rgba( 180, 83, 9, 0.12 );
	color: #9a3412;
	font-size: 0.72rem;
	white-space: nowrap;
}

.dmb-stat-note {
	margin: 0 0 0.9rem;
	color: var( --dmb-muted );
	font-size: 0.88rem;
	line-height: 1.55;
}

.dmb-table-overrides td:nth-child(4) {
	max-width: 22rem;
}

.dmb-export {
	margin: 1.5rem 0 2rem;
	padding: 0.9rem 1rem;
	border: 1px solid rgba( 0, 0, 0, 0.09 );
	border-radius: 10px;
}

.dmb-export > summary {
	cursor: pointer;
	font-size: 0.95rem;
	font-weight: 500;
	list-style-position: outside;
}

.dmb-export[open] > summary {
	margin-bottom: 0.6rem;
}

.dmb-export-form {
	display: flex;
	align-items: flex-end;
	flex-wrap: wrap;
	gap: 12px;
}

.dmb-export-form label {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: 0.85rem;
	color: var( --dmb-muted );
}

.dmb-export-form input[type="date"] {
	padding: 8px 10px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.9rem;
}

/* --- "Something else", please specify ------------------------------------ */

.dmb-gate-detail {
	margin: -0.6rem 0 1.3rem;
	padding-left: 12px;
	text-align: left;
}

.dmb-gate-detail[hidden] {
	display: none;
}

.dmb-gate-detail label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.85rem;
	color: var( --dmb-muted );
}

.dmb-gate-detail input[type="text"] {
	width: 100%;
	padding: 9px 11px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.95rem;
}

/* Shown only after somebody has tried to get past it without answering. */
.dmb-gate-warn {
	color: #9a3412;
}

.dmb-gate-warn[hidden] {
	display: none;
}

/* --- Downloads screen, quieter ------------------------------------------- */

/*
 * The one tile that might mean somebody has to do something. Plain while it
 * reads zero, so that a portal in good order doesn't have a permanent red mark
 * on its dashboard — an alert that's always on is wallpaper.
 */
.dmb-stat-link {
	text-decoration: none;
	color: inherit;
	transition: border-color 0.12s ease, background 0.12s ease;
}

.dmb-stat-link:hover {
	border-color: rgba( 0, 0, 0, 0.2 );
}

.dmb-stat-alert {
	border-color: rgba( 180, 83, 9, 0.35 );
	background: rgba( 180, 83, 9, 0.05 );
}

.dmb-stat-alert .dmb-stat-value {
	color: #9a3412;
}

/* A count in the heading, so "is there anything to look at" is answered
 * without reading the section. */
.dmb-count-badge {
	display: inline-block;
	margin-left: 8px;
	padding: 1px 9px;
	border-radius: 999px;
	background: rgba( 180, 83, 9, 0.12 );
	color: #9a3412;
	font-size: 0.78rem;
	font-weight: 500;
	vertical-align: middle;
}

/* More air between sections, now that there's less text doing that job. */
.dmb-stats .dmb-stat-subhead {
	margin-top: 2.25rem;
}

/* --- Tabs, without JavaScript --------------------------------------------
 *
 * Radios and a sibling selector. The panels are all in the markup and the
 * browser decides which one is shown, so nothing here can fail to initialise
 * and leave two thirds of the screen unreachable.
 *
 * The radios are moved off-screen rather than display:none, because a radio
 * that isn't rendered can't take keyboard focus — and losing arrow-key
 * movement between tabs would be giving up the one accessibility win this
 * approach hands over for free.
 * ------------------------------------------------------------------------- */

.dmb-tabs {
	margin-top: 1.75rem;
}

.dmb-tabradio {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect( 0 0 0 0 );
	white-space: nowrap;
	border: 0;
}

/*
 * The tab strip carries the portal's colour rather than being grey until
 * clicked. An unselected tab that is the same weight as the page around it
 * doesn't read as a control — several people have looked at this strip and not
 * realised there was anything to press.
 */
.dmb-tablist {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	border-bottom: 2px solid var( --dmb-line );
}

.dmb-tablist label {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	padding: 10px 16px;
	margin-bottom: -1px;
	border: 1px solid transparent;
	border-bottom: 2px solid transparent;
	border-radius: 8px 8px 0 0;
	cursor: pointer;
	font-size: 0.95rem;
	font-weight: 500;

	/* Tinted rather than transparent, so the strip reads as a row of tabs. */
	background: var( --dmb-soft, #f6f8f9 );
	color: var( --dmb-accent, #22384c );
	white-space: nowrap;
	transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}

.dmb-tablist label:hover {
	color: var( --dmb-ink );

	/* The branding colour at a tenth, so it picks up whatever the portal is
	   set to rather than being a hard-coded blue. */
	background: color-mix( in srgb, var( --dmb-accent, #22384c ) 12%, #fff );
}

/* Panels are hidden by default and revealed by the checked radio. */
.dmb-tabpanel {
	display: none;
	padding-top: 1.5rem;
}

#dmb-dtab-overview:checked   ~ .dmb-tabpanel-overview,
#dmb-dtab-popular:checked    ~ .dmb-tabpanel-popular,
#dmb-dtab-activity:checked   ~ .dmb-tabpanel-activity,
#dmb-rtab-clearance:checked  ~ .dmb-tabpanel-rclearance,
#dmb-rtab-requests:checked   ~ .dmb-tabpanel-rrequests {
	display: block;
}

#dmb-dtab-overview:checked   ~ .dmb-tablist label[for="dmb-dtab-overview"],
#dmb-dtab-popular:checked    ~ .dmb-tablist label[for="dmb-dtab-popular"],
#dmb-dtab-activity:checked   ~ .dmb-tablist label[for="dmb-dtab-activity"],
#dmb-rtab-clearance:checked  ~ .dmb-tablist label[for="dmb-rtab-clearance"],
#dmb-rtab-requests:checked   ~ .dmb-tablist label[for="dmb-rtab-requests"] {
	/* The chosen tab is the accent colour, filled, and joined to the panel
	   below it by a border in the same colour as its own background. */
	background: var( --dmb-accent, #22384c );
	color: #fff;
	border-bottom-color: var( --dmb-accent, #22384c );
	font-weight: 600;
}

/* Focus has to be drawn on the label, since the radio itself is off-screen.
 *
 * Each radio matched to its own label by ID rather than by the shared class —
 * .dmb-tabradio:focus-visible would have lit all three at once, which tells
 * somebody arrowing through them exactly nothing. */
#dmb-dtab-overview:focus-visible   ~ .dmb-tablist label[for="dmb-dtab-overview"],
#dmb-dtab-popular:focus-visible    ~ .dmb-tablist label[for="dmb-dtab-popular"],
#dmb-dtab-activity:focus-visible   ~ .dmb-tablist label[for="dmb-dtab-activity"],
#dmb-rtab-clearance:focus-visible  ~ .dmb-tablist label[for="dmb-rtab-clearance"],
#dmb-rtab-requests:focus-visible   ~ .dmb-tablist label[for="dmb-rtab-requests"] {
	outline: 2px solid var( --dmb-accent );
	outline-offset: -2px;
}

@media ( max-width: 560px ) {
	.dmb-tablist label {
		flex: 1 1 auto;
		justify-content: center;
		padding: 10px 8px;
		font-size: 0.88rem;
	}
}

/* The tile is a label now, so it needs to look like the others rather than
 * like a form control. */
label.dmb-stat {
	cursor: pointer;
	margin: 0;
}

/* --- Clearance requests --------------------------------------------------- */

.dmb-waiting {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 12px;
	margin-bottom: 1.5rem;
	padding: 1rem 1.2rem;
	border: 1px solid rgba( 180, 83, 9, 0.3 );
	border-radius: 10px;
	background: rgba( 180, 83, 9, 0.05 );
}

.dmb-waiting p {
	margin: 0;
}

/*
 * One card per request, on the Requests screen. A card rather than a table
 * row because deciding needs the filenames, the reason, a duration and a
 * message box — none of which fit in a cell, and all of which are the point.
 */
.dmb-clearances {
	margin-top: 2rem;
}

.dmb-clearance {
	margin-bottom: 1.2rem;
	padding: 1.25rem 1.4rem;
	border: 1px solid rgba( 0, 0, 0, 0.1 );
	border-radius: 12px;
	background: #fff;
}

.dmb-clearance-who {
	margin: 0 0 0.9rem;
	font-size: 1.05rem;
	font-weight: 500;
	line-height: 1.4;
}

.dmb-clearance-note {
	margin: 0 0 1rem;
	font-size: 0.92rem;
	line-height: 1.55;
}

.dmb-clearance-controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 18px;
	margin-bottom: 1rem;
	font-size: 0.9rem;
}

.dmb-clearance-controls select {
	margin-left: 6px;
	padding: 6px 8px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.9rem;
}

.dmb-clearance-relabel {
	display: flex;
	align-items: center;
	gap: 8px;
	max-width: 30rem;
	line-height: 1.45;
}

.dmb-clearance-reply {
	display: block;
	margin-bottom: 1rem;
	font-size: 0.9rem;
}

.dmb-clearance-reply span {
	color: var( --dmb-muted );
}

.dmb-clearance-reply input {
	display: block;
	width: 100%;
	margin-top: 5px;
	padding: 9px 11px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.95rem;
}

/* The Requests queues sit right under the page title, so they need less air
 * above them than the Downloads tabs, which follow a row of tiles. */
.dmb-tabs-queues {
	margin-top: 0.5rem;
}

/* --- Approving and declining --------------------------------------------
 *
 * One pair of colours for every yes/no decision in the portal, wherever it
 * appears: approving a supplier's request, clearing a file for use outside
 * the organisation, and the compact buttons in the requests table.
 *
 * They were three different treatments before — accent-and-quiet in one
 * place, green-and-grey in another — which meant the same decision looked
 * like a different kind of decision depending on which screen you were on.
 *
 * Written here at the end rather than by editing the rules further up,
 * because .dmb-yes and .dmb-no are each declared twice in this file already
 * and adding a third variant mid-file would make it harder still to work out
 * which one actually wins.
 * ------------------------------------------------------------------------- */

.dmb-button-yes,
.dmb-yes {
	background: #2e7d52;
	border-color: #2e7d52;
	color: #fff;
}

.dmb-button-yes:hover:not(:disabled),
.dmb-yes:hover,
.dmb-yes:focus-visible {
	background: #256743;
	border-color: #256743;
	color: #fff;
	filter: none;
}

/*
 * Declining is outlined rather than filled.
 *
 * Two solid, saturated buttons side by side carry equal weight, and the one
 * you shouldn't press by accident is the irreversible one. Red on the border
 * and the text says "no" clearly enough; it fills on hover, so by the time
 * you're actually about to click it, it's unmistakable.
 */
.dmb-button-no,
.dmb-no {
	background: transparent;
	border-color: #c0392b;
	color: #c0392b;
}

.dmb-button-no:hover:not(:disabled),
.dmb-no:hover,
.dmb-no:focus-visible {
	background: #c0392b;
	border-color: #c0392b;
	color: #fff;
}

/* --- One meaning per colour ----------------------------------------------
 *
 * Three treatments, and a button gets one only if the choice it offers is
 * consequential:
 *
 *   green (.dmb-button-yes)  the safe, recommended, compliant action —
 *                            Approve, "Remove those files", "Download the
 *                            other 11"
 *
 *   red   (.dmb-button-no)   irreversible, or overriding a control —
 *                            Decline, Delete, Revoke, "Download anyway"
 *
 *   quiet (.dmb-button-quiet) neutral — Cancel, Go back
 *
 * Everything else keeps the plain accent: Save, Search, Upload, Send. That
 * restraint is what makes the coloured ones mean anything — if every button
 * on a screen is shouting, none of them is.
 *
 * Deliberately NOT red: "Ask for clearance". It's the behaviour the whole
 * feature exists to encourage, and painting it the same colour as Decline
 * would tell people that asking is the risky option.
 *
 * The two older danger classes are folded in here so there's one red in the
 * portal rather than three near-misses.
 * ------------------------------------------------------------------------- */

.dmb-button-danger {
	background: transparent;
	border-color: #c0392b;
	color: #c0392b;
}

.dmb-button-danger:hover:not(:disabled) {
	background: #c0392b;
	border-color: #c0392b;
	color: #fff;
}

.dmb-linkbutton-danger {
	color: #c0392b;
}

.dmb-linkbutton-danger:hover,
.dmb-linkbutton-danger:focus-visible {
	color: #96271b;
}

/*
 * Green and red need to survive being disabled without looking active, and
 * the shared .dmb-button rule sets its own background — so both variants
 * restate it rather than relying on inheritance.
 */
.dmb-button-yes:disabled,
.dmb-button-no:disabled {
	opacity: 0.55;
	cursor: default;
}

/* --- The conflict box, in two halves -------------------------------------
 *
 * The top half is the answer most people want: here are the files, remove
 * them, carry on. The bottom half is the other route — asking for clearance,
 * or on a Warn portal going ahead anyway.
 *
 * A hairline rule between them wasn't enough. Both halves sat on the same
 * white card, so the box read as one long list of five things to choose
 * between rather than "do this, or if you really need them, do that".
 *
 * The shading is doing the work a heading would otherwise have to. It bleeds
 * to the edges of the card, which is why the margins are negative and match
 * the card padding — an inset panel with a gap around it reads as a box
 * inside a box, and there are enough boxes already.
 * ------------------------------------------------------------------------- */

.dmb-gate-override {
	margin: 1.5rem -1.75rem -1.75rem;
	padding: 1.3rem 1.75rem 1.5rem;
	border-top: 1px solid rgba( 0, 0, 0, 0.09 );
	border-radius: 0 0 14px 14px;
	background: rgba( 0, 0, 0, 0.035 );
	text-align: left;
}

/* The server-rendered page uses a roomier card, so its bleed is wider. */
.dmb-gate-card .dmb-gate-override {
	margin: 1.6rem -2rem -2rem;
	padding: 1.4rem 2rem 1.6rem;
}

.dmb-gate-override label {
	color: var( --dmb-ink );
}

.dmb-gate-override input[type="text"] {
	background: #fff;
}

/*
 * The top half's actions get a little more room beneath them now that
 * something visibly different starts underneath.
 */
.dmb-dialog-wide .dmb-gate-actions,
.dmb-gate-card .dmb-gate-actions {
	margin-bottom: 0.25rem;
}

/* --- The one solid red ---------------------------------------------------
 *
 * Cancel and "Download anyway" are both red and mean different things: one
 * backs out, the other goes past the control. Outlined for backing out,
 * filled for going through.
 *
 * Filled is the heavier of the two on purpose. It's the only action in the
 * portal that deliberately overrides a check, and it should look like the
 * thing you meant to do rather than the thing you drifted into.
 * ------------------------------------------------------------------------- */

.dmb-button-no.dmb-button-fill {
	background: #c0392b;
	border-color: #c0392b;
	color: #fff;
}

.dmb-button-no.dmb-button-fill:hover:not(:disabled) {
	background: #96271b;
	border-color: #96271b;
	color: #fff;
}

/*
 * The action in the shaded half sits centred under its own field, so it reads
 * as belonging to that panel rather than as a fourth item in the row of
 * buttons above it. Same green as Approve — asking is the legitimate route
 * through, and the shading is what tells the two greens apart.
 */
.dmb-gate-override .dmb-button {
	display: block;
	margin-left: auto;
	margin-right: auto;
}

/* --- Versions -------------------------------------------------------------
 *
 * The badge on a card is deliberately restrained. Most files are v1 and always
 * will be, so a permanent version number on everything is noise that teaches
 * people to stop reading badges. It appears only once a file has actually been
 * replaced, and it says "Updated" for a fortnight afterwards — a temporary
 * fact, shown temporarily.
 * ------------------------------------------------------------------------- */

.dmb-usage-version {
	background: rgba( 0, 0, 0, 0.06 );
	color: var( --dmb-muted );
}

.dmb-usage-fresh {
	background: rgba( 46, 125, 82, 0.12 );
	color: #2e7d52;
	font-weight: 500;
}

.dmb-versions {
	margin-top: 2.5rem;
	padding-top: 1.75rem;
	border-top: 1px solid var( --dmb-line );
}

.dmb-version-now {
	display: inline-block;
	margin-left: 8px;
	padding: 1px 9px;
	border-radius: 999px;
	background: rgba( 0, 0, 0, 0.06 );
	color: var( --dmb-muted );
	font-size: 0.8rem;
	font-weight: 500;
	vertical-align: middle;
}

/* The replace form. Its own box, because uploading a new master is a
 * different weight of action from correcting a caption above it. */
.dmb-replace {
	margin-bottom: 1.75rem;
	padding: 1.25rem 1.4rem;
	border: 1px solid var( --dmb-line );
	border-radius: 12px;
	background: var( --dmb-soft, #f6f8f9 );
}

.dmb-replace label {
	display: block;
	margin-bottom: 1rem;
}

.dmb-replace label > span {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.9rem;
}

.dmb-replace label em {
	color: var( --dmb-muted );
	font-style: normal;
	font-size: 0.85rem;
}

.dmb-replace input[type="text"] {
	width: 100%;
	padding: 9px 11px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.95rem;
	background: #fff;
}

.dmb-replace-tell {
	display: flex !important;
	align-items: center;
	gap: 8px;
	font-size: 0.92rem;
}

.dmb-replace-tell input {
	margin: 0;
}

.dmb-replace-none {
	margin: 0 0 1rem;
	color: var( --dmb-muted );
	font-size: 0.88rem;
}

.dmb-version-actions {
	white-space: nowrap;
}

.dmb-version-actions a {
	margin-right: 10px;
}

.dmb-version-actions form {
	display: inline;
}

/* --- Review notes ---------------------------------------------------------
 *
 * The lightbox becomes two columns on a delivery portal: player on the left,
 * notes on the right. On anything narrower than a laptop they stack, because
 * a 300px-wide video with a comment box beside it is neither a review tool nor
 * a player.
 * ------------------------------------------------------------------------- */

.dmb-lb-notes {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	width: 340px;
	max-height: 100%;
	overflow-y: auto;
	padding: 1.25rem;
	border-radius: 12px;
	background: #fff;
	color: var( --dmb-ink );
}

.dmb-lb-notes[hidden] {
	display: none;
}

.dmb-note-loading,
.dmb-note-empty {
	margin: 0;
	color: var( --dmb-muted );
	font-size: 0.9rem;
	line-height: 1.55;
}

/* --- status ------------------------------------------------------------- */

.dmb-note-status {
	display: flex;
	gap: 4px;
	margin-bottom: 1.1rem;
}

.dmb-note-state {
	flex: 1 1 auto;
	padding: 7px 6px;
	border: 1px solid var( --dmb-line );
	border-radius: 8px;
	background: #fff;
	color: var( --dmb-muted );
	font: inherit;
	font-size: 0.78rem;
	cursor: pointer;
	transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.dmb-note-state:hover {
	border-color: var( --dmb-ink );
	color: var( --dmb-ink );
}

/*
 * The chosen status is filled, not merely outlined. This is the one thing on
 * the panel somebody scanning it needs to read without looking for it.
 */
.dmb-note-state.is-on {
	background: var( --dmb-accent );
	border-color: var( --dmb-accent );
	color: #fff;
	font-weight: 500;
}

/* --- the notes ---------------------------------------------------------- */

.dmb-note-list {
	flex: 1 1 auto;
	margin-bottom: 1rem;
}

.dmb-note {
	padding: 0.8rem 0;
	border-top: 1px solid rgba( 0, 0, 0, 0.08 );
}

.dmb-note:first-child {
	border-top: 0;
}

/*
 * Done, not gone — but told apart by more than opacity.
 *
 * A 55% fade left a resolved note looking much like an unresolved one at a
 * glance, which is the one distinction this list exists to make. A tint and a
 * green edge separate them without dimming the text, so a note you've dealt
 * with is still readable when you go back to check what was asked.
 */
.dmb-note.is-done {
	margin-left: -14px;
	margin-right: -14px;
	padding-left: 14px;
	padding-right: 14px;
	border-left: 3px solid #2e7d52;
	background: rgba( 46, 125, 82, 0.06 );
}

.dmb-note.is-done .dmb-note-body,
.dmb-note.is-done .dmb-note-who {
	color: var( --dmb-muted );
}

/*
 * The timecode stops shouting once the note is settled, but stays clickable.
 *
 * The colour has to be set as well as the background: "Whole film" carries
 * .dmb-note-general, which sets muted grey text for its own grey pill — and
 * grey on green was unreadable the moment that note was marked done.
 */
.dmb-note.is-done .dmb-note-at,
.dmb-note.is-done .dmb-note-general {
	background: rgba( 46, 125, 82, 0.8 );
	color: #fff;
}

.dmb-note header {
	display: flex;
	align-items: baseline;
	gap: 8px;
	margin-bottom: 0.35rem;
}

.dmb-note-at {
	padding: 1px 8px;
	border: 0;
	border-radius: 999px;
	background: var( --dmb-accent );
	color: #fff;
	font: inherit;
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
	cursor: pointer;
}

.dmb-note-general {
	background: rgba( 0, 0, 0, 0.08 );
	color: var( --dmb-muted );
	cursor: default;
}

.dmb-note-who {
	font-size: 0.82rem;
	font-weight: 500;
}

.dmb-note-when {
	margin-left: auto;
	color: var( --dmb-muted );
	font-size: 0.75rem;
	white-space: nowrap;
}

.dmb-note-body {
	margin: 0;
	font-size: 0.9rem;
	line-height: 1.5;
	white-space: pre-wrap;
}

.dmb-note-reply {
	margin: 0.6rem 0 0 0.9rem;
	padding-left: 0.8rem;
	border-left: 2px solid rgba( 0, 0, 0, 0.09 );
}

.dmb-note footer {
	display: flex;
	gap: 12px;
	margin-top: 0.5rem;
}

.dmb-note footer button {
	padding: 0;
	border: 0;
	background: none;
	color: var( --dmb-accent );
	font: inherit;
	font-size: 0.8rem;
	cursor: pointer;
}

.dmb-note footer button:hover {
	text-decoration: underline;
}

/*
 * Delete sits apart from the others and doesn't wear the accent colour.
 *
 * Reply and Mark done are the things you're meant to reach for; this one is
 * there for a mistake. Muted until hovered means it doesn't compete, and
 * turning red on hover says what it is before it's pressed rather than only in
 * the dialogue afterwards.
 */
.dmb-note-delete {
	margin-left: auto;
	color: var( --dmb-muted );
}

.dmb-note footer button.dmb-note-delete:hover {
	color: var( --dmb-bad, #a8382f );
}

.dmb-note-hint {
	display: block;
	margin-top: 6px;
	color: var( --dmb-muted );
	font-size: 0.72rem;
}

/* No room for it beside a thumb, and the phone keyboard's key already says
 * Send — so on a touch screen the hint is noise about a key that isn't there. */
@media ( max-width: 640px ) {
	.dmb-note-hint {
		display: none;
	}
}

/* --- adding one --------------------------------------------------------- */

.dmb-note-add {
	padding-top: 1rem;
	border-top: 1px solid rgba( 0, 0, 0, 0.1 );
}

.dmb-note-add label {
	display: block;
	margin-bottom: 0.4rem;
	font-size: 0.85rem;
}

.dmb-note-add textarea {
	width: 100%;
	padding: 9px 11px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.9rem;
	resize: vertical;
}

.dmb-note-whole {
	display: flex !important;
	align-items: center;
	gap: 7px;
	margin: 0.5rem 0 0.8rem;
	color: var( --dmb-muted );
	font-size: 0.8rem;
}

.dmb-note-add .dmb-button {
	width: 100%;
	padding: 0.6rem 1rem;
}



/* --- Notes, where you'd notice them --------------------------------------- */

.dmb-usage-notes {
	background: rgba( 180, 83, 9, 0.12 );
	color: #9a3412;
	font-weight: 500;
}

/* The pinned timecode on the add-a-note box. It follows the playhead until
 * somebody types, then holds — and looks different once it's holding, so it's
 * clear the number has stopped moving on purpose. */
.dmb-note-mark {
	padding: 1px 8px;
	border: 1px dashed var( --dmb-line );
	border-radius: 999px;
	background: transparent;
	color: var( --dmb-muted );
	font: inherit;
	font-size: 0.78rem;
	font-variant-numeric: tabular-nums;
	cursor: pointer;
}

.dmb-note-mark.is-pinned {
	border-style: solid;
	border-color: var( --dmb-accent );
	background: var( --dmb-accent );
	color: #fff;
}

/* --- The notes screen ----------------------------------------------------- */

/* Superseded by the collapsed row below — kept out of the way rather than
 * left to fight with it. */

.dmb-note-statuslabel {
	margin-left: auto;
	color: var( --dmb-muted );
	font-size: 0.8rem;
	font-weight: 400;
}

.dmb-notefile-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.dmb-notefile-list li {
	padding: 0.7rem 0;
	border-top: 1px solid rgba( 0, 0, 0, 0.07 );
}

.dmb-notefile-list li:first-child {
	border-top: 0;
}

.dmb-notefile-list .dmb-note-body {
	margin: 0.3rem 0 0;
}

/* --- Replying, in the thread ---------------------------------------------- */

.dmb-note-replybox {
	margin: 0.6rem 0 0 0.9rem;
	padding-left: 0.8rem;
	border-left: 2px solid var( --dmb-accent );
}

.dmb-note-replybox[hidden] {
	display: none;
}

.dmb-note-replybox textarea {
	width: 100%;
	padding: 7px 9px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 8px;
	font: inherit;
	font-size: 0.88rem;
	resize: vertical;
}

.dmb-note-replybox-actions {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-top: 0.45rem;
}

.dmb-note-replybox .dmb-button {
	padding: 6px 14px;
	font-size: 0.82rem;
}

.dmb-note-replybox-cancel {
	padding: 0;
	border: 0;
	background: none;
	color: var( --dmb-muted );
	font: inherit;
	font-size: 0.8rem;
	cursor: pointer;
}

.dmb-note-replybox-cancel:hover {
	color: var( --dmb-ink );
	text-decoration: underline;
}

/* --- The lightbox controls, with a panel in the way -----------------------
 *
 * Close and Next live at the right edge of the screen. The notes panel is now
 * also at the right edge, opaque and white — so the close button vanished
 * underneath it, and Next would have gone the same way on the first delivery
 * with two files in it.
 *
 * Two things wrong, so two fixes: lift them above the panel in the stacking
 * order, and move them clear of it so they aren't white-on-white when they get
 * there.
 * ------------------------------------------------------------------------- */

.dmb-lb-close,
.dmb-lb-nav {
	z-index: 3;
}

/*
 * Clear of the panel, derived from its width rather than guessed.
 *
 * This was a hard 372px for a 340px panel. Widening the panel to 420 left the
 * arrow sitting on top of the notes — two numbers that had to agree, in two
 * places, with nothing connecting them. Declared on the lightbox so both the
 * panel and the button can read it.
 */
.dmb-lightbox {
	--dmb-notes-w: 420px;
}

.dmb-lb-hasnotes .dmb-lb-next {
	right: calc( var( --dmb-notes-w ) + 32px );
}

/*
 * Darker than the default translucent white, so they read whichever side of
 * the boundary they end up on — over the dimmed backdrop, or over the panel
 * if a narrow window brings the two together.
 */
.dmb-lb-hasnotes .dmb-lb-close,
.dmb-lb-hasnotes .dmb-lb-nav {
	background: rgba( 20, 22, 26, 0.72 );
}

.dmb-lb-hasnotes .dmb-lb-close:hover,
.dmb-lb-hasnotes .dmb-lb-nav:hover,
.dmb-lb-hasnotes .dmb-lb-close:focus-visible,
.dmb-lb-hasnotes .dmb-lb-nav:focus-visible {
	background: rgba( 20, 22, 26, 0.9 );
}

/* Stacked layout: the panel is underneath, so the controls go back to the
 * corner where they belong. */
@media ( max-width: 1000px ) {
	.dmb-lb-hasnotes .dmb-lb-close,
	.dmb-lb-hasnotes .dmb-lb-next {
		right: 18px;
	}
}

@media ( max-width: 640px ) {
	.dmb-lb-hasnotes .dmb-lb-next {
		right: 6px;
	}
}

/* --- A wider panel, a smaller picture -------------------------------------
 *
 * Reviewing is reading and typing, not admiring. The film only has to be big
 * enough to judge, and the notes column was too narrow for a thread with
 * replies indented inside it.
 * ------------------------------------------------------------------------- */

.dmb-lb-notes {
	width: var( --dmb-notes-w );
}

/* The stage gives up the width the panel took. Without this the video keeps
 * its size and the two simply overlap on a 1440 screen. */
.dmb-lb-hasnotes .dmb-lb-figure {
	max-width: calc( 100% - ( var( --dmb-notes-w ) + 40px ) );
}

.dmb-lb-hasnotes .dmb-lb-stage video,
.dmb-lb-hasnotes .dmb-lb-stage img {
	max-height: 74vh;
}

/*
 * The close button goes back to the corner it has always been in.
 *
 * It sits over the panel now, which is fine because it's dark on white — the
 * earlier problem was that it was translucent white on white AND underneath.
 * Only the next arrow still moves, because that one lands in the middle of the
 * notes rather than in a margin.
 */
.dmb-lb-hasnotes .dmb-lb-close {
	right: 18px;
}

@media ( max-width: 1000px ) {
	.dmb-lb-notes {
		width: 100%;
	}

	.dmb-lb-hasnotes .dmb-lb-figure {
		max-width: 100%;
	}
}

/* --- Which cut ------------------------------------------------------------ */

.dmb-note-versions {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin-bottom: 0.9rem;
	padding-bottom: 0.9rem;
	border-bottom: 1px solid rgba( 0, 0, 0, 0.08 );
}

.dmb-note-version {
	padding: 5px 11px;
	border: 1px solid var( --dmb-line );
	border-radius: 999px;
	background: #fff;
	color: var( --dmb-muted );
	font: inherit;
	font-size: 0.78rem;
	cursor: pointer;
}

.dmb-note-version span {
	display: inline-block;
	margin-left: 5px;
	padding: 0 5px;
	border-radius: 999px;
	background: rgba( 0, 0, 0, 0.09 );
	font-size: 0.7rem;
}

.dmb-note-version:hover {
	border-color: var( --dmb-ink );
	color: var( --dmb-ink );
}

.dmb-note-version.is-on {
	border-color: var( --dmb-accent );
	background: var( --dmb-accent );
	color: #fff;
}

.dmb-note-version.is-on span {
	background: rgba( 255, 255, 255, 0.25 );
}

/* Reading an older cut. Said plainly, because the absence of an add box is
 * otherwise indistinguishable from something being broken. */
.dmb-note-readonly {
	margin: 0;
	padding: 0.8rem 0.9rem;
	border-radius: 8px;
	background: rgba( 0, 0, 0, 0.04 );
	color: var( --dmb-muted );
	font-size: 0.85rem;
	line-height: 1.5;
}

/* --- The panel scrolls in the middle, not as a whole ----------------------
 *
 * The whole panel scrolled, so on a film with twenty notes the box you write
 * in was somewhere below the fold and you had to scroll past everything anyone
 * had ever said to reach it.
 *
 * Now only the list moves. The version strip and status buttons stay at the
 * top, the add box stays at the bottom, and the notes run between them.
 *
 * min-height: 0 on the scrolling child is the part that's easy to miss: a flex
 * item defaults to min-height auto, which refuses to shrink below its content,
 * so the list would push the add box off the bottom and never scroll at all.
 * ------------------------------------------------------------------------- */

.dmb-lb-notes {
	overflow: hidden;
}

.dmb-note-versions,
.dmb-note-status {
	flex: 0 0 auto;
}

.dmb-note-list {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	margin-bottom: 0;

	/* Room so the last note isn't tight against the box below it, and a hint
	 * that there's more above when you've scrolled down. */
	padding-bottom: 0.8rem;
}

.dmb-note-add,
.dmb-note-readonly {
	flex: 0 0 auto;
	background: #fff;
}

/*
 * A hairline above the box rather than a hard rule, so a short list doesn't
 * look like it's been cut off.
 */
.dmb-note-add {
	margin-top: auto;
	border-top: 1px solid rgba( 0, 0, 0, 0.12 );
}

/* --- The close button, actually visible ----------------------------------
 *
 * It sits in the top-right corner, which on a review is over the white notes
 * panel. A 72%-opaque dark disc reads as a smudge there — the panel shows
 * through it and the edge is soft, so it stops looking like a control.
 *
 * Solid, ringed and shadowed instead. The ring is what separates it from white
 * without needing to move it, and the shadow gives it an edge on both
 * backgrounds it now has to work on.
 * ------------------------------------------------------------------------- */

.dmb-lb-hasnotes .dmb-lb-close {
	width: 44px;
	height: 44px;
	background: #14161a;
	border: 2px solid #fff;
	color: #fff;
	box-shadow: 0 2px 10px rgba( 0, 0, 0, 0.3 );
}

/*
 * Red on hover only — deliberately NOT on focus.
 *
 * The lightbox moves focus to this button when it opens, so a rule covering
 * :focus-visible turned it red the instant anything was opened, before anyone
 * had gone near it. Focus still needs to be visible for anyone driving this
 * from the keyboard, so it gets a ring instead of a fill.
 */
.dmb-lb-hasnotes .dmb-lb-close:hover {
	background: #c0392b;
	border-color: #fff;
}

.dmb-lb-hasnotes .dmb-lb-close:focus-visible {
	background: #14161a;
	outline: 3px solid rgba( 255, 255, 255, 0.9 );
	outline-offset: 2px;
}

/* Keyboard focus that has then been hovered should still read as hover. */
.dmb-lb-hasnotes .dmb-lb-close:focus-visible:hover {
	background: #c0392b;
}

/* --- Client notes: grouped, collapsed, with a picture ---------------------
 *
 * A row you can scan: thumbnail, name, how many notes, where it stands. Shut
 * until you open it, so four clients with three cuts each is a page you read
 * rather than a page you scroll.
 * ------------------------------------------------------------------------- */

.dmb-noteclient {
	margin-bottom: 2.25rem;
}

.dmb-noteclient-name {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 0.7rem;
	font-size: 1.05rem;
	font-weight: 600;
}

.dmb-notefile {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 8px;
	padding: 10px 14px;
	border: 1px solid var( --dmb-line );
	border-radius: 10px;
	background: #fff;
	color: inherit;
	text-decoration: none;
	transition: background 0.12s ease, border-color 0.12s ease;
}

.dmb-notefile:hover {
	border-color: var( --dmb-accent );
	background: var( --dmb-soft, #f6f8f9 );
}

.dmb-notefile-arrow {
	color: var( --dmb-accent );
	transition: transform 0.12s ease;
}

.dmb-notefile:hover .dmb-notefile-arrow {
	transform: translateX( 2px );
}

.dmb-notefile-thumb {
	flex: 0 0 auto;
	width: 64px;
	height: 40px;
	object-fit: cover;
	border-radius: 5px;
	background: rgba( 0, 0, 0, 0.08 );
}

/* No poster captured yet. A flat tile rather than a broken image or a
 * placeholder graphic that implies something is wrong. */
.dmb-notefile-nothumb {
	display: block;
}

.dmb-notefile-name {
	flex: 1 1 auto;
	min-width: 0;
	font-size: 0.95rem;
	font-weight: 500;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.dmb-notefile-meta {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 10px;
}

.dmb-notefile-list {
	margin: 0;
	padding: 0.4rem 1rem 0.6rem;
	list-style: none;
}

.dmb-notefile-go {
	margin: 0;
	padding: 0 1rem 1rem;
}

@media ( max-width: 560px ) {
	.dmb-notefile {
		flex-wrap: wrap;
	}

	.dmb-notefile-name {
		white-space: normal;
	}

	.dmb-notefile-meta {
		width: 100%;
		padding-left: 76px;
	}
}

/* A note that's been dealt with says so. The fade alone reads as "old" as
 * readily as "done", and those are different things when you're scanning a
 * thread to work out what's left. */
.dmb-note-done {
	padding: 0 7px;
	border-radius: 999px;
	background: rgba( 46, 125, 82, 0.14 );
	color: #2e7d52;
	font-size: 0.7rem;
	font-weight: 600;
	letter-spacing: 0.01em;
}

/* --- Outstanding notes, marked as such ------------------------------------
 *
 * Done notes had a green edge and a tint; unresolved ones had nothing, so the
 * contrast was between "marked" and "plain" rather than between two states.
 * Plain reads as neutral, and neutral is exactly what an outstanding note
 * isn't.
 *
 * The same amber the portal already uses for "somebody needs to deal with
 * this" — the flagged download rows and the note counts on cards — so it means
 * the same thing here as it does everywhere else.
 * ------------------------------------------------------------------------- */

.dmb-note:not( .is-done ) {
	margin-left: -14px;
	margin-right: -14px;
	padding-left: 14px;
	padding-right: 14px;
	border-left: 3px solid #b45309;
	background: rgba( 180, 83, 9, 0.05 );
}

/* The name of whoever is waiting on you, at full strength. */
.dmb-note:not( .is-done ) .dmb-note-who {
	color: var( --dmb-ink );
	font-weight: 600;
}

.dmb-note:not( .is-done ) .dmb-note-body {
	color: var( --dmb-ink );
}

/*
 * The separator between notes goes: two tinted blocks butted together already
 * read as separate, and a rule on top of that is a third line doing a job two
 * are already doing.
 */
.dmb-note {
	border-top: 0;
	margin-bottom: 6px;
	border-radius: 0 6px 6px 0;
}

/* --- Status: named, and coloured by what it means -------------------------
 *
 * Three buttons in a row with one filled is a control you have to think about.
 * A word above them says what the row is for, and colouring the chosen one by
 * meaning — green for approved, amber for changes wanted — means the answer
 * reads before the label does.
 *
 * Only the selected one is coloured. Three coloured buttons would be a
 * decision presented as a traffic light with every lamp lit.
 * ------------------------------------------------------------------------- */

.dmb-note-statushead {
	margin: 0 0 0.35rem;
	color: var( --dmb-muted );
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.dmb-note-state-approved.is-on {
	background: #2e7d52;
	border-color: #2e7d52;
}

.dmb-note-state-changes.is-on {
	background: #b45309;
	border-color: #b45309;
}

/* Viewing keeps the neutral accent — it isn't a verdict, it's the absence of
 * one, and colouring it would say something the client hasn't said. */

/* --- The same three states, on the dashboard ------------------------------ */

.dmb-note-statuslabel {
	padding: 2px 9px;
	border-radius: 999px;
	font-size: 0.74rem;
	font-weight: 500;
	white-space: nowrap;
}

.dmb-note-statuslabel-approved {
	background: rgba( 46, 125, 82, 0.14 );
	color: #2e7d52;
}

.dmb-note-statuslabel-changes {
	background: rgba( 180, 83, 9, 0.14 );
	color: #9a3412;
}

.dmb-note-statuslabel-viewing {
	background: rgba( 0, 0, 0, 0.06 );
	color: var( --dmb-muted );
}

/* --- A stage that doesn't move --------------------------------------------
 *
 * A <video> has no intrinsic size until its metadata arrives, so the browser
 * gives it a default box, then resizes it to the real aspect ratio the moment
 * playback starts. On a page where the whole layout is sized around it, that
 * reads as the player jumping when you press play.
 *
 * So on a review the stage gets a fixed box and the film sits inside it. The
 * box is 16:9 because that's what a delivery is; anything else letterboxes
 * within it, which costs a little space and buys a layout that never moves.
 *
 * Only in review mode. On an asset portal the lightbox holds photographs of
 * every shape, and a fixed frame there would crop the grid's whole point.
 * ------------------------------------------------------------------------- */

.dmb-lb-hasnotes .dmb-lb-stage {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	aspect-ratio: 16 / 9;
	max-height: 74vh;
	border-radius: 8px;
	background: #000;
	overflow: hidden;
}

.dmb-lb-hasnotes .dmb-lb-stage video {
	width: 100%;
	height: 100%;
	max-height: none;

	/* contain, not cover: a vertical cut letterboxes rather than having its
	 * top and bottom removed, which on a review would hide the thing being
	 * reviewed. */
	object-fit: contain;
}

/* The figure fills the space left beside the panel, so the stage has a width
 * to be a percentage of. */
.dmb-lb-hasnotes .dmb-lb-figure {
	width: 100%;
}

/*
 * A poster and a first frame are the same size now, so there's nothing left to
 * jump — but the transition would still animate the box if anything else moved
 * it, and an animated player is worse than an abrupt one.
 */
.dmb-lb-hasnotes .dmb-lb-stage,
.dmb-lb-hasnotes .dmb-lb-stage video {
	transition: none;
}

/* --- Uploading a recut, from the notes list -------------------------------- */

.dmb-notefile-replace {
	margin: -4px 0 14px;
	padding-left: 14px;
}

.dmb-notefile-replace > summary {
	display: inline-block;
	padding: 3px 0;
	color: var( --dmb-accent );
	font-size: 0.82rem;
	cursor: pointer;
	list-style: none;
}

.dmb-notefile-replace > summary::-webkit-details-marker {
	display: none;
}

.dmb-notefile-replace > summary::before {
	content: "\2191\00a0";
}

.dmb-notefile-replace > summary:hover {
	text-decoration: underline;
}

.dmb-notefile-replace[open] > summary {
	margin-bottom: 0.5rem;
}

.dmb-notefile-replace .dmb-replace {
	margin-bottom: 0;
}

.dmb-note-replace {
	display: block;
	margin: 0 0 12px;
	color: var( --dmb-accent );
	font-size: 0.8rem;
	text-decoration: none;
}

.dmb-note-replace::before {
	content: "\2191\00a0";
}

.dmb-note-replace:hover {
	text-decoration: underline;
}

/* --- The review player ----------------------------------------------------
 *
 * On a review the browser's controls come off and this replaces them, because
 * the scrubber has to do two jobs: seek, and mark the section a note is about.
 * A native <video> draws its scrubber in the shadow DOM, where it can't be
 * styled or dragged on — see the comment above playerBuild() in front.js.
 *
 * It sits over the bottom of the stage rather than under it. The stage is a
 * fixed 16:9 box and the film letterboxes inside it, so there is almost always
 * black to sit on; where there isn't, the scrim carries it.
 * ------------------------------------------------------------------------- */

.dmb-lb-hasnotes .dmb-lb-stage {
	position: relative;
}

.dmb-pl {
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 2;
	padding: 30px 14px 10px;

	/* The film runs underneath, so the controls need something to be legible
	 * against that isn't a solid bar eating the bottom of the frame. */
	background: linear-gradient( to top, rgba( 0, 0, 0, 0.85 ), rgba( 0, 0, 0, 0 ) );
}

.dmb-pl-track {
	position: relative;
	height: 12px;
	border-radius: 6px;
	background: rgba( 255, 255, 255, 0.22 );
	cursor: pointer;

	/* Padding can't grow the box without moving the fills, so the taller hit
	 * area comes from a border the same colour as nothing.
	 *
	 * Stated explicitly: under border-box the 16px of border would eat the
	 * 12px track down to nothing, and a theme setting border-box globally is
	 * a normal thing for a theme to do. */
	box-sizing: content-box;
	border-top: 8px solid transparent;
	border-bottom: 8px solid transparent;
	background-clip: padding-box;
	touch-action: none;
}

.dmb-pl-played {
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	width: 0;
	border-radius: 6px 0 0 6px;
	background: rgba( 255, 255, 255, 0.42 );
	pointer-events: none;
}

.dmb-pl-sel {
	position: absolute;
	top: -3px;
	bottom: -3px;
	border-radius: 4px;
	background: rgba( 214, 158, 46, 0.5 );
	box-shadow: inset 0 0 0 2px #d69e2e;
}

.dmb-pl-sel[hidden] {
	display: none;
}

/* --- The grips -------------------------------------------------------------
 *
 * Both ends move. A section drawn in one pass is roughly right at best, and
 * the alternative to grips is starting the drag again — which is why the
 * first version got the reply that you need to be able to move both ends.
 *
 * The visible grip is 8px so it reads as a handle; the hit area is stretched
 * to 22px by a transparent border, because an 8px drag target on a bar you're
 * already dragging on is a coin toss.
 * ------------------------------------------------------------------------- */

.dmb-pl-grip {
	position: absolute;
	top: 50%;
	width: 8px;
	height: 22px;
	border-radius: 3px;
	background: #d69e2e;
	box-shadow: 0 0 0 1px rgba( 0, 0, 0, 0.5 );
	transform: translateY( -50% );
	cursor: ew-resize;
}

.dmb-pl-grip::after {
	/* The hit area, invisible and centred on the grip.
	 *
	 * Kept within the track's own 8px border rather than the 8px it wanted:
	 * any taller and it reaches over the top edge of the play button, which
	 * is a press that goes nowhere and looks like a player that has locked
	 * up. Still a 26px target. */
	content: "";
	position: absolute;
	top: -2px;
	right: -7px;
	bottom: -2px;
	left: -7px;
}

.dmb-pl-grip[data-edge="a"] {
	left: -4px;
}

.dmb-pl-grip[data-edge="b"] {
	right: -4px;
}

.dmb-pl-grip:hover,
.dmb-pl.is-gripping .dmb-pl-grip {
	background: #f6ad55;
}

/* --- The marker lane -------------------------------------------------------
 *
 * Under the scrubber, not on it.
 *
 * A section note draws as a bar as wide as the section. On the track, that bar
 * is a click target covering its whole span — so a note on the middle third of
 * a film made the scrubber unusable across the middle third, every press
 * jumping back to the note instead of seeking. Down here they're still aligned
 * to the timeline and still clickable, and the scrubber is only the scrubber.
 * ------------------------------------------------------------------------- */

.dmb-pl-marks {
	position: relative;
	height: 9px;
	margin-top: 3px;
}

/* A moment: a dot. A section: a bar the length of the section. Same colour, so
 * the eye reads them as one kind of thing at two lengths. */
.dmb-pl-mark {
	position: absolute;
	top: 1px;
	width: 7px;
	height: 7px;
	margin-left: -3.5px;
	border-radius: 50%;
	background: #f6ad55;
	box-shadow: 0 0 0 1px rgba( 0, 0, 0, 0.55 );
	cursor: pointer;
}

.dmb-pl-mark.is-range {
	margin-left: 0;
	min-width: 6px;
	border-radius: 3px;
}

/* The lane is thin, so the target is grown downwards where there's nothing to
 * collide with rather than upwards into the scrubber. */
.dmb-pl-mark::after {
	content: "";
	position: absolute;
	top: -3px;
	right: -3px;
	bottom: -5px;
	left: -3px;
}

.dmb-pl-mark:hover {
	background: #fff;
}



/* Done notes stay on the bar but stop competing — the shape of the review is
 * still useful after the work is finished. */
.dmb-pl-mark.is-done {
	background: rgba( 255, 255, 255, 0.4 );
	box-shadow: 0 0 0 2px rgba( 0, 0, 0, 0.4 );
}

.dmb-pl-head {
	position: absolute;
	top: -5px;
	bottom: -5px;
	width: 2px;
	margin-left: -1px;
	background: #fff;
	box-shadow: 0 0 3px rgba( 0, 0, 0, 0.6 );
	pointer-events: none;
}

/* --- The button row -------------------------------------------------------- */

.dmb-pl-bar {
	/* Above anything the track spills past its own box. A control you can see
	 * but can't press is worse than one that isn't there. */
	position: relative;
	z-index: 1;

	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 4px;
	color: #fff;
	font-size: 0.78rem;
}

.dmb-pl-gap {
	flex: 1 1 auto;
}

.dmb-pl-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	padding: 0;
	border: 0;
	border-radius: 4px;
	background: none;
	color: #fff;
	cursor: pointer;
}

.dmb-pl-btn:hover {
	background: rgba( 255, 255, 255, 0.16 );
}

.dmb-pl-btn:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 1px;
}

.dmb-pl-btn svg {
	width: 20px;
	height: 20px;
	fill: currentColor;
}

.dmb-pl-time {
	font-variant-numeric: tabular-nums;

	/* Tabular figures alone don't stop the row shuffling when the minute digit
	 * appears, and a play button that moves is a play button you miss. */
	min-width: 92px;
}

.dmb-pl-info {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 2px 8px;
	border-radius: 10px;
	background: rgba( 214, 158, 46, 0.22 );
	color: #f6ad55;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.dmb-pl-info[hidden] {
	display: none;
}

.dmb-pl-playsel {
	padding: 1px 8px;
	border: 1px solid rgba( 246, 173, 85, 0.6 );
	border-radius: 9px;
	background: none;
	color: #f6ad55;
	font: inherit;
	font-size: 0.72rem;
	font-weight: 600;
	cursor: pointer;
}

.dmb-pl-playsel:hover {
	border-color: #f6ad55;
	background: rgba( 246, 173, 85, 0.18 );
}

.dmb-pl-clear {
	padding: 0;
	border: 0;
	background: none;
	color: rgba( 255, 255, 255, 0.75 );
	font: inherit;
	font-weight: 400;
	text-decoration: underline;
	cursor: pointer;
}

.dmb-pl-clear:hover {
	color: #fff;
}

.dmb-pl-vol {
	width: 72px;
	accent-color: #fff;
	cursor: pointer;
}

/* Fullscreen takes the whole lightbox, so the notes stay on screen with the
 * film. The stage can then use the height the browser chrome was occupying. */
.dmb-lightbox:fullscreen {
	background: #000;
}

.dmb-lightbox:fullscreen .dmb-lb-stage {
	max-height: 88vh;
}

/* A range badge carries two timecodes and an en dash, so it needs the room
 * that a single 0:00 didn't. */
.dmb-note-at.is-range,
.dmb-note-mark.is-range {
	white-space: nowrap;
}

@media ( max-width: 900px ) {
	.dmb-pl {
		padding: 24px 10px 8px;
	}

	.dmb-pl-bar {
		gap: 6px;
		font-size: 0.72rem;
	}

	/* First to go: the film, the clock and the way out matter more than fine
	 * volume control on a phone, which has hardware buttons for it anyway. */
	.dmb-pl-vol {
		display: none;
	}

	.dmb-pl-time {
		min-width: 78px;
	}
}

.dmb-note-tip {
	margin: 6px 0 0;
	color: var( --dmb-muted );
	font-size: 0.74rem;
	line-height: 1.5;
}

.dmb-note-tip kbd {
	display: inline-block;
	min-width: 1.1em;
	padding: 1px 4px;
	border: 1px solid var( --dmb-line );
	border-bottom-width: 2px;
	border-radius: 3px;
	background: #fff;
	color: var( --dmb-ink );
	font-family: inherit;
	font-size: 0.9em;
	text-align: center;
}

/* A note that will move the playhead says so — the pointer on the whole card,
 * not just on the timecode nobody thinks to click. */
.dmb-note.is-seekable {
	cursor: pointer;
}

.dmb-note.is-seekable:hover {
	background: rgba( 34, 56, 76, 0.05 );
}

/*
 * A done note keeps its green on hover.
 *
 * A flat grey hover would replace the tint that says "dealt with" at exactly
 * the moment the pointer is on it — which is the moment you're reading it to
 * find out. Same idea, one step stronger, rather than a different colour.
 */
.dmb-note.is-seekable.is-done:hover {
	background: rgba( 46, 125, 82, 0.13 );
}

/* The interactive parts keep their own cursor, so it stays obvious that Reply
 * replies rather than seeking. */
.dmb-note.is-seekable button,
.dmb-note.is-seekable a,
.dmb-note.is-seekable textarea,
.dmb-note.is-seekable input {
	cursor: auto;
}

.dmb-note.is-seekable button,
.dmb-note.is-seekable a {
	cursor: pointer;
}


/* --- "Why won't this play?" ------------------------------------------------
 * Shut by default and deliberately plain. It's for the day something is
 * wrong, and on that day the last thing wanted is styling in the way.
 * ------------------------------------------------------------------------- */

.dmb-diagnose {
	margin: 0 0 1.25rem;
}

.dmb-diagnose > summary {
	display: inline-block;
	padding: 3px 0;
	color: var( --dmb-muted );
	font-size: 0.82rem;
	cursor: pointer;
}

.dmb-diagnose > summary:hover {
	color: var( --dmb-ink );
	text-decoration: underline;
}

.dmb-diagnose[open] > summary {
	margin-bottom: 0.6rem;
}

.dmb-diagnose td small {
	color: var( --dmb-muted );
}

.dmb-pl-playsel[disabled] {
	opacity: 0.6;
	cursor: default;
}

/* --- The note you just asked about -----------------------------------------
 *
 * Pressing a marker moves the film, which says when but not which. A ring
 * rather than a background, so a note that is also marked done keeps its
 * green and doesn't have to choose between the two things it's saying.
 * ------------------------------------------------------------------------- */

.dmb-note.is-current {
	border-radius: 4px;
	box-shadow: 0 0 0 1px rgba( 214, 158, 46, 0.85 );
}

.dmb-note.is-current::before {
	/* A soft wash inside the ring, laid over whatever background the note
	 * already has rather than replacing it. */
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 4px;
	background: rgba( 214, 158, 46, 0.07 );
	pointer-events: none;
}

.dmb-note {
	position: relative;
}

/* --- Client, then project, on the upload screen ---------------------------- */

.dmb-pickrow {
	display: flex;
	align-items: center;
	gap: 10px;
}

.dmb-pickrow select {
	flex: 1 1 auto;
	min-width: 0;
}

.dmb-pickrow .dmb-button {
	flex: 0 0 auto;
	white-space: nowrap;
}

.dmb-pickhint {
	margin-top: 6px;
}

@media ( max-width: 600px ) {
	.dmb-pickrow {
		flex-wrap: wrap;
	}

	.dmb-pickrow select {
		flex-basis: 100%;
	}
}

/* --- A replacement film, on its way ---------------------------------------- */

.dmb-replace-progress {
	margin-top: 12px;
}

.dmb-replace-progress[hidden] {
	display: none;
}

.dmb-replace-bar {
	height: 8px;
	border-radius: 4px;
	background: rgba( 34, 56, 76, 0.12 );
	overflow: hidden;
}

.dmb-replace-bar span {
	display: block;
	width: 0;
	height: 100%;
	border-radius: 4px;
	background: #2e7d52;

	/* Eased, because the numbers arrive in lumps and an unsmoothed bar reads
	 * as a stuttering upload rather than a steady one. */
	transition: width 0.2s linear;
}

.dmb-replace-pct {
	margin: 6px 0 0;
	color: var( --dmb-muted );
	font-size: 0.78rem;
	font-variant-numeric: tabular-nums;
}

/* Deliveries now sit below the uploader on Add Files, so they need a line
 * between them and the panel above rather than the space a page title had. */
.dmb-delivery-head {
	margin-top: 2rem;
	padding-top: 1.5rem;
	border-top: 1px solid var( --dmb-line );
}

/* --- The delivery link, ready to copy -------------------------------------- */

.dmb-delivery-link {
	display: block;
	width: 100%;
	margin-top: 6px;
	padding: 4px 6px;
	border: 1px solid var( --dmb-line );
	border-radius: 4px;
	background: #fff;
	color: var( --dmb-muted );
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.7rem;
}

.dmb-delivery-link:focus {
	border-color: var( --dmb-accent );
	color: var( --dmb-ink );
	outline: none;
}

/* --- The join page ---------------------------------------------------------
 *
 * A page of its own rather than a portal screen: it's the first thing a client
 * ever sees, and at that moment they have no account, no navigation they could
 * use and no reason to care what else is here. One card, centred, saying what
 * is waiting and asking for three things.
 * ------------------------------------------------------------------------- */

body.dmb-joinpage {
	margin: 0;
	background: var( --dmb-soft, #f4f7f9 );
	color: var( --dmb-ink, #22384c );

	/*
	 * The portal's own font, named rather than inherited.
	 *
	 * Two goes at this. "inherit" resolved to the browser default — Times —
	 * because a standalone document has no theme above it to inherit from.
	 * Replacing it with a system stack then made things worse in a quieter
	 * way: body.dmb-joinpage outranks the theme's plain `body` rule, so this
	 * page was the one place in the portal that pointedly refused to use the
	 * portal's typeface.
	 *
	 * Poppins first, matching the theme, with the system stack behind it so
	 * the page still looks deliberate if the webfont hasn't arrived.
	 */
	font-family: 'Poppins', 'Montserrat', -apple-system, BlinkMacSystemFont,
		"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	font-size: 16px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}

.dmb-joinpage h1,
.dmb-joinpage p,
.dmb-joinpage label,
.dmb-joinpage input,
.dmb-joinpage button,
.dmb-joinpage a {
	font-family: inherit;
}

.dmb-join {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 100vh;
	padding: 32px 20px;
	box-sizing: border-box;
}

.dmb-join-card {
	width: 100%;
	max-width: 420px;
	padding: 36px 34px 30px;
	border-radius: 10px;
	background: #fff;
	box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.06 ), 0 12px 40px rgba( 34, 56, 76, 0.09 );
	box-sizing: border-box;
}

.dmb-join-logo {
	margin-bottom: 22px;
}

.dmb-join-logo img {
	max-width: 170px;
	height: auto;
}

.dmb-join-wordmark {
	margin: 0 0 22px;
	color: var( --dmb-muted );
	font-size: 0.82rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.dmb-join-card h1 {
	margin: 0 0 6px;
	font-size: 1.4rem;
	line-height: 1.25;
}

.dmb-join-lead {
	margin: 0 0 14px;
	color: var( --dmb-muted );
	font-size: 0.9rem;
}

/* The note is from a person, so it reads as one. */
.dmb-join-note {
	margin: 0 0 14px;
	padding: 10px 12px;
	border-left: 3px solid var( --dmb-accent );
	border-radius: 0 4px 4px 0;
	background: var( --dmb-soft );
	font-size: 0.88rem;
	line-height: 1.5;
}

.dmb-join-until {
	margin: 0 0 22px;
	padding-bottom: 18px;
	border-bottom: 1px solid var( --dmb-line );
	color: var( --dmb-muted );
	font-size: 0.82rem;
}

.dmb-join-form label {
	display: block;
	margin-bottom: 4px;
	font-size: 0.82rem;
	font-weight: 600;
}

.dmb-join-form input {
	width: 100%;
	margin-bottom: 14px;
	padding: 9px 11px;
	border: 1px solid var( --dmb-line );
	border-radius: 5px;
	font: inherit;
	font-size: 0.92rem;
	box-sizing: border-box;
}

.dmb-join-form input:focus {
	border-color: var( --dmb-accent );
	outline: 2px solid rgba( 34, 56, 76, 0.12 );
	outline-offset: 0;
}

/* Sits under the field it belongs to, so it isn't mistaken for the next
 * label down. */
.dmb-join-form .dmb-join-small {
	display: block;
	margin: -10px 0 18px;
}

.dmb-join-form button {
	width: 100%;
	padding: 11px;
	font-size: 0.95rem;
}

.dmb-join-small {
	color: var( --dmb-muted );
	font-size: 0.76rem;
	line-height: 1.5;
}

.dmb-join-foot {
	margin: 18px 0 0;
	padding-top: 16px;
	border-top: 1px solid var( --dmb-line );
}

.dmb-joinpage .dmb-notice {
	margin-bottom: 16px;
}

@media ( max-width: 480px ) {
	.dmb-join {
		padding: 0;
	}

	.dmb-join-card {
		max-width: none;
		min-height: 100vh;
		padding: 28px 22px;
		border-radius: 0;
		box-shadow: none;
	}
}

/* --- The delivery link, beside the upload ---------------------------------- */

.dmb-deliverylink[hidden] {
	display: none;
}

.dmb-deliverylink-body .dmb-delivery-link {
	margin-top: 0;
	font-size: 0.75rem;
}

.dmb-deliverylink-body .dmb-hint {
	margin-top: 6px;
}

.dmb-deliverylink-body .dmb-button {
	margin-top: 6px;
}

/* --- Who has this delivery ------------------------------------------------- */

.dmb-delivery-who > summary {
	color: var( --dmb-muted );
	font-size: 0.78rem;
	cursor: pointer;
}

.dmb-delivery-who > summary:hover {
	color: var( --dmb-ink );
}

.dmb-delivery-people {
	margin: 6px 0 0;
	padding: 0;
	list-style: none;
}

.dmb-delivery-people li {
	padding: 6px 0;
	border-top: 1px solid var( --dmb-line );
	font-size: 0.78rem;
	line-height: 1.45;
}

.dmb-delivery-people li:first-child {
	border-top: 0;
}

.dmb-delivery-people span {
	display: block;
	color: var( --dmb-muted );
}

/* Removing somebody sits with their name, not in a column of its own. */
.dmb-delivery-drop {
	display: inline;
	margin-left: 6px;
}

.dmb-linkbutton-no {
	color: #b3261e;
}

.dmb-linkbutton-no:hover {
	text-decoration: underline;
}

/* The delivery link is a copy target, so it should look like one. */
.dmb-delivery-link {
	cursor: pointer;
}

.dmb-delivery-link:hover {
	border-color: var( --dmb-accent );
	color: var( --dmb-ink );
}

/* --- The signpost, inside the banner ---------------------------------------
 *
 * A line at the foot of the countdown box pointing at the pitch below the
 * folders.
 *
 * Third attempt at making it visible. As its own strip above the folders it
 * was one more panel on a page of panels and got skipped. Moved into the
 * banner as a hairline-topped line, it did the opposite — it took the box's
 * grey background and its ordinary text colour and disappeared into it.
 *
 * So it's white on the banner's grey. A card sitting on a card: same family,
 * clearly a separate thing, and the only white rectangle in that part of the
 * page. The cue is a filled pill because a line of text with an arrow after
 * it reads as decoration, and this is the one thing on the page we want them
 * to press.
 * ------------------------------------------------------------------------- */

.dmb-signpost {
	display: flex;
	align-items: center;
	gap: 14px;
	margin: 1rem 0 0;
	padding: 0.85rem 1rem;
	border-radius: 8px;
	background: #fff;
	box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.05 ), 0 6px 18px rgba( 34, 56, 76, 0.07 );
	color: var( --dmb-ink );
	font-size: 0.86rem;
	line-height: 1.5;
	text-decoration: none;
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.dmb-signpost:hover,
.dmb-signpost:focus-visible {
	transform: translateY( -2px );
	box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.05 ), 0 12px 28px rgba( 34, 56, 76, 0.13 );
}

.dmb-signpost-text {
	flex: 1 1 auto;
}

/* The opening clause carries the idea, so it gets the colour and the weight
 * rather than being one more bold run in a paragraph. */
.dmb-signpost-text strong {
	color: var( --dmb-accent );
}

.dmb-signpost-cue {
	flex: 0 0 auto;
	padding: 0.45rem 0.9rem;
	border-radius: 999px;
	background: var( --dmb-accent );
	color: #fff;
	font-size: 0.78rem;
	font-weight: 600;
	white-space: nowrap;
}

/*
 * Scrolled to rather than jumped to, so the movement shows it came from
 * further down the same page — and honoured only where motion is welcome.
 */
@media ( prefers-reduced-motion: no-preference ) {
	html {
		scroll-behavior: smooth;
	}
}

#dmb-more {
	scroll-margin-top: 24px;
}

@media ( max-width: 640px ) {
	.dmb-signpost {
		flex-direction: column;
		align-items: flex-start;
		gap: 10px;
	}
}


/* --- The numbers, removed ---------------------------------------------------
 *
 * Four counting figures used to sit above the pitch points. Gone, along with
 * render_stats() and the ninety lines of JavaScript that animated them.
 *
 * Worth recording why this block is not simply deleted quietly: it redefined
 * .dmb-stats, .dmb-stat and .dmb-stat-label, and it sat *after* the Download
 * stats rules near the top of this file. Same specificity, later in the
 * cascade, so it won. The Downloads dashboard's own .dmb-stats section — a
 * heading followed by a grid — was being laid out as a four-column grid,
 * centred, capped at 54em, which put its heading in one column and its figures
 * in the next. Removing this returns that screen to the design it was written
 * with.
 * ------------------------------------------------------------------------- */

/* --- Cards arriving --------------------------------------------------------
 *
 * Written so that doing nothing is the finished state. The card is only moved
 * and faded once .dmb-reveal-ready is on it, which the script adds to the page
 * before it starts watching — so if the script never runs, or motion is turned
 * down, every card is simply where it should be.
 *
 * The other way round — hide by default, reveal with a class — leaves a page
 * of invisible content the moment anything goes wrong with the script.
 * ------------------------------------------------------------------------- */

.dmb-reveal-ready .dmb-pitch-point,
.dmb-reveal-ready .dmb-hubtile-off {
	opacity: 0;

	/*
	 * Far enough to be noticed.
	 *
	 * Fourteen pixels over half a second is the sort of tasteful that nobody
	 * can tell happened — and "it isn't more dynamic" is a fair verdict on an
	 * animation you have to be told about. Twenty-eight and a slight scale
	 * reads as arriving; the easing curve does the rest.
	 */
	transform: translateY( 28px ) scale( 0.97 );
	transition: opacity 0.55s ease, transform 0.55s cubic-bezier( 0.16, 0.84, 0.44, 1 );
}

.dmb-reveal-ready .dmb-pitch-point.dmb-reveal,
.dmb-reveal-ready .dmb-hubtile-off.dmb-reveal {
	opacity: 1;
	transform: none;
}

/* The lift on hover is a separate transform, so it needs to survive the
 * reveal having set one. */
.dmb-reveal-ready .dmb-pitch-point.dmb-reveal:hover {
	transform: translateY( -5px );
}

/* Says plainly that this is a preview, so nobody mistakes it for something a
 * client is being shown right now. */
.dmb-preview-flag {
	margin: 0 auto 1.5rem;
	max-width: 54em;
	padding: 0.6rem 0.9rem;
	border-radius: 6px;
	background: #fef6ec;
	color: #7c4a03;
	font-size: 0.8rem;
	text-align: center;
}

.dmb-preview-build {
	display: block;
	margin-top: 4px;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.72rem;
	opacity: 0.8;
}

/* --- Where you are, in the menu -------------------------------------------
 *
 * In the plugin rather than the theme: this stylesheet loads on every
 * front-end page the moment the plugin is active, and a visual change that
 * needs two packages updated in step will be half-applied somewhere.
 *
 * Three selectors because there are three ways the nav can be built:
 *   .is-here            the plugin's own fallback navigation
 *   .current-menu-item  a WordPress menu assigned to the theme location
 *   .current_page_item  the same, on themes using the page-based class
 *
 * ---------------------------------------------------------------------------
 * Why a rounded tab rather than a capsule
 * ---------------------------------------------------------------------------
 * A tinted capsule reads well on its own and badly two links from Logout,
 * which is a capsule too. Same silhouette, so the eye has to stop and work out
 * which of them is pressable — and the one that is, is the one you least want
 * somebody hitting by accident.
 *
 * Shape carries the difference instead of colour: 6px corners for a state,
 * a full 999px capsule for the button. Weight backs it up — a pale tint
 * against a solid grey fill. And a hairline before Logout puts it in its own
 * group, which is what it is.
 * ------------------------------------------------------------------------- */

.site-nav a.is-here,
.site-nav .current-menu-item > a,
.site-nav .current_page_item > a {
	padding: 0.45rem 0.9rem;
	border-radius: 999px;
	color: var( --dmb-accent, #22384c );
	font-weight: 600;
	opacity: 1;

	/*
	 * A tint of the accent, not --dmb-soft.
	 *
	 * --dmb-soft is the page background: #f6f8f9, three points off white.
	 * The header is white, so the tab was drawn in a colour that differs from
	 * what it sits on by almost nothing. It wasn't too pale as a matter of
	 * taste — it was the wrong variable, picked because "soft" sounded like
	 * the right word for a soft fill.
	 *
	 * The literal comes first so browsers without color-mix keep a real
	 * colour; the mix then reproduces it from whatever accent the portal is
	 * branded with, so a client with a red or green accent gets a tab in
	 * their colour rather than in ours.
	 */
	background: #d7dbdf;
	background: color-mix( in srgb, var( --dmb-accent, #22384c ) 18%, #fff );

	/*
	 * Nothing drawn along the bottom edge.
	 *
	 * A line appeared under the tab that isn't drawn by this stylesheet or by
	 * the theme's — I looked. Which leaves the ways a line can arrive without
	 * anyone asking for one: a browser's default underline on an anchor if the
	 * active theme never removes it, a WordPress admin or block stylesheet
	 * loading after this one, or a menu plugin styling the current item.
	 *
	 * Rather than guess which, close all of them. These are the only four
	 * properties that can put a rule under this element, so setting them here
	 * makes the tab's bottom edge the tab's own business regardless of what
	 * else is loaded. Cheap, and it can't regress: there is no state in which
	 * this element is supposed to have a line under it.
	 */
	text-decoration: none;
	border: 0;
	border-bottom: 0;
	box-shadow: none;
}

/*
 * The list item too, where the menu is a real WordPress menu.
 *
 * wp_nav_menu wraps each link in an <li class="current-menu-item">, and the
 * tint above lands on the <a> inside it. A border on the <li> would therefore
 * sit outside the pill and read as a line beneath it.
 */
.site-nav li.current-menu-item,
.site-nav li.current_page_item {
	border: 0;
	box-shadow: none;
	background: none;
}

/*
 * ---------------------------------------------------------------------------
 * The underline, third attempt — and this time for the right reason
 * ---------------------------------------------------------------------------
 * A line kept appearing under the current-page tab. Twice I assumed it was a
 * border and closed off border, border-bottom, box-shadow and text-decoration.
 * Twice it survived, which was the answer: a property I'd already set to zero
 * cannot be what's drawing it. It's a pseudo-element — the standard way themes
 * and menu plugins mark the current item, because it can be animated and a
 * border can't.
 *
 * `content: none` is what removes one. Setting width or background on it does
 * nothing if the rule that creates it is more specific, whereas `content:
 * none` stops it existing at all.
 *
 * !important, which this stylesheet otherwise uses twice in nine thousand
 * lines. The rule to beat is in a stylesheet I can't see and can't predict the
 * specificity of, and the alternative is guessing at selector weight for a
 * fourth round. It's narrow — eight selectors, all inside .site-nav, all on
 * the current item — and there is no state in which this element is meant to
 * have a pseudo-element, so nothing legitimate can be broken by it.
 * ------------------------------------------------------------------------- */

.site-nav a.is-here::before,
.site-nav a.is-here::after,
.site-nav .current-menu-item > a::before,
.site-nav .current-menu-item > a::after,
.site-nav .current_page_item > a::before,
.site-nav .current_page_item > a::after,
.site-nav li.current-menu-item::before,
.site-nav li.current-menu-item::after,
.site-nav li.current_page_item::before,
.site-nav li.current_page_item::after {
	content: none !important;
	display: none !important;
}

/* The logout pill is a button and must never wear the current-page tint —
 * it would look pressed rather than pressable. */
.site-nav .nav-logout.is-here,
.site-nav .nav-logout {
	padding: 0.7rem 1.9rem;
	border-radius: 999px;
	background: var( --dmb-grey, #8e9296 );
	color: #fff;
	font-weight: 500;
}

/*
 * Set apart, so it reads as its own group rather than the last of the
 * navigation links.
 *
 * Space only. The previous version drew the divider with a box-shadow given a
 * large negative spread — the usual trick for a hairline without an extra
 * element. It can't work here: a shadow takes the border-radius of the element
 * casting it, and this element is a 999px pill, so shrinking it by its spread
 * produced a small round blob rather than a line. It was also painted in
 * --dmb-line, which each portal sets to its own colour, so on a portal with a
 * warm palette the blob came out orange. Neither the shape nor the colour was
 * what the rule asked for, and a gap separates the button just as well.
 */
.site-nav .nav-logout {
	margin-left: 1.5rem;
	border-left: 0;
	box-shadow: none;
}

@media ( max-width: 900px ) {
	/* Stacked, where a tab sitting inside the column reads better full-width
	 * than as a floating chip. */
	.site-nav a.is-here,
	.site-nav .current-menu-item > a,
	.site-nav .current_page_item > a {
		display: block;
		border-radius: var( --dmb-radius, 10px );
	}

	/* The dropdown panel is white too, so the same tint holds up. */

	.site-nav .nav-logout {
		margin-left: 0;
	}
}

/* -------------------------------------------------------------------------
 * Guest uploads
 *
 * Two surfaces: the /send/ page a photographer with no account sees, and the
 * inbox where the client files what arrives. The send page reuses the join
 * page's card so a stranger's first sight of the portal is the same object a
 * client sees when they sign up.
 * ---------------------------------------------------------------------- */

.dmb-send-card {
	max-width: 34rem;
}

.dmb-send-form .dmb-field {
	margin-bottom: 1rem;
	text-align: left;
}

.dmb-send-form input[type="text"],
.dmb-send-form input[type="email"],
.dmb-send-form textarea {
	width: 100%;
}

.dmb-optional {
	font-weight: 400;
	color: var( --dmb-muted, #6b7580 );
	font-size: 0.85em;
}

.dmb-send-list:empty {
	display: none;
}

.dmb-send-list {
	margin: 1rem 0;
	text-align: left;
}

.dmb-send-row {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 0.15rem 0.75rem;
	padding: 0.5rem 0;
	border-top: 1px solid var( --dmb-line, #e6e9ec );
	font-size: 0.9rem;
}

.dmb-send-rowname {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.dmb-send-rowsize {
	color: var( --dmb-muted, #6b7580 );
}

.dmb-send-bar {
	grid-column: 1 / -1;
	height: 4px;
	border-radius: 999px;
	background: var( --dmb-line, #e6e9ec );
	overflow: hidden;
}

.dmb-send-fill {
	display: block;
	width: 0;
	height: 100%;
	background: var( --dmb-accent, #22384c );

	/*
	 * No transition on width.
	 *
	 * Pieces land every second or two on a slow connection and every few
	 * milliseconds on a fast one. An eased bar on the fast case lags behind
	 * the truth and finishes visibly after the upload has, which reads as the
	 * last file having stalled.
	 */
}

.dmb-send-row.is-done .dmb-send-fill {
	background: var( --dmb-good, #2e7d5b );
}

.dmb-send-row.is-failed .dmb-send-fill {
	background: var( --dmb-bad, #a8382f );
}

.dmb-send-why {
	grid-column: 1 / -1;
	color: var( --dmb-bad, #a8382f );
	font-size: 0.85rem;
}

.dmb-send-status:empty {
	display: none;
}

.dmb-send-status {
	margin-top: 0.75rem;
	font-size: 0.9rem;
	color: var( --dmb-muted, #6b7580 );
}

.dmb-send-status.is-bad {
	color: var( --dmb-bad, #a8382f );
}

.dmb-send-foot {
	margin-top: 1.25rem;
	font-size: 0.85rem;
	color: var( --dmb-muted, #6b7580 );
}

/* The inbox ---------------------------------------------------------------- */

.dmb-batch {
	margin-bottom: 1.25rem;
}

.dmb-batch-head h3 {
	margin: 0 0 0.25rem;
}

.dmb-batch-meta {
	margin: 0 0 0.75rem;
	font-size: 0.9rem;
	color: var( --dmb-muted, #6b7580 );
}

.dmb-batch-when::before {
	content: "·";
	margin: 0 0.4rem;
}

.dmb-batch-notes {
	margin: 0 0 1rem;
	padding: 0.5rem 0 0.5rem 0.9rem;
	border-left: 3px solid var( --dmb-line, #e6e9ec );
	border-radius: 0;
	color: var( --dmb-ink, #1e2a35 );
	font-style: italic;
}

.dmb-batch-files {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
	margin: 0 0 1rem;
	padding: 0;
	list-style: none;
}

.dmb-batch-files li {
	width: 5.5rem;
	font-size: 0.7rem;
	color: var( --dmb-muted, #6b7580 );
}

.dmb-batch-files img,
.dmb-batch-nofile {
	display: block;
	width: 5.5rem;
	height: 5.5rem;
	object-fit: cover;
	border-radius: var( --dmb-radius, 10px );
	background: var( --dmb-soft, #f6f8f9 );
}

.dmb-batch-name {
	display: block;
	margin-top: 0.25rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.dmb-batch-more {
	align-self: center;
}

.dmb-batch-file {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 1rem;
	padding-top: 1rem;
	border-top: 1px solid var( --dmb-line, #e6e9ec );
}

.dmb-batch-file .dmb-field {
	margin: 0;
	min-width: 14rem;
}

.dmb-tagpick {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem 0.9rem;
	max-width: 28rem;
}

.dmb-tagpick-one {
	font-size: 0.9rem;
	font-weight: 400;
}

.dmb-batch-actions {
	margin: 0;
}

.dmb-batch-reject {
	margin-top: 0.75rem;
}

.dmb-intake-new .dmb-field {
	max-width: 30rem;
}

.dmb-field-narrow {
	max-width: 12rem;
}

.dmb-intake-table .dmb-share-link {
	display: block;
	width: 100%;
	margin-top: 0.35rem;
	font-size: 0.85rem;
}

/*
 * The row you just made, marked for a moment.
 *
 * The table is ordered newest first, so the new link is already at the top —
 * but "at the top" is only obvious if you know the order, and the person has
 * just been told to copy something. This says which one.
 */
.dmb-row-fresh > td {
	background: color-mix( in srgb, var( --dmb-accent, #22384c ) 7%, #fff );
}

/* -------------------------------------------------------------------------
 * Form controls inherit the portal's typeface
 *
 * Browsers do not give form controls the page's font. Left alone, a <textarea>
 * renders in the browser's default monospace and a file input's button in the
 * operating system's UI font — which is why the message box and the "Choose
 * files" button looked like they belonged to a different website. This has
 * come up three times now on three different screens, so it's fixed once here
 * for every control rather than per-form as each one is noticed.
 *
 * `font: inherit` rather than `font-family: inherit`: size, weight and
 * line-height come from the same place, and a textarea inheriting the family
 * but keeping its 13px default is only half-fixed.
 * ---------------------------------------------------------------------- */

.dmb-portal input,
.dmb-portal textarea,
.dmb-portal select,
.dmb-portal button,
.dmb-join input,
.dmb-join textarea,
.dmb-join select,
.dmb-join button {
	font: inherit;
}

/*
 * The file input's button is a shadow-DOM part and needs naming separately —
 * `font: inherit` on the input styles the "no file chosen" text beside it, not
 * the button itself. Two vendor spellings because Safari has never adopted the
 * standard one.
 */
.dmb-portal input[type="file"]::file-selector-button,
.dmb-join input[type="file"]::file-selector-button {
	font: inherit;
	padding: 0.45rem 0.9rem;
	margin-right: 0.75rem;
	border: 1px solid var( --dmb-line, #e6e9ec );
	border-radius: 999px;
	background: var( --dmb-soft, #f6f8f9 );
	color: var( --dmb-ink, #1e2a35 );
	cursor: pointer;
}

.dmb-portal input[type="file"]::-webkit-file-upload-button,
.dmb-join input[type="file"]::-webkit-file-upload-button {
	font: inherit;
	padding: 0.45rem 0.9rem;
	margin-right: 0.75rem;
	border: 1px solid var( --dmb-line, #e6e9ec );
	border-radius: 999px;
	background: var( --dmb-soft, #f6f8f9 );
	color: var( --dmb-ink, #1e2a35 );
	cursor: pointer;
}

.dmb-portal input[type="file"]::file-selector-button:hover,
.dmb-join input[type="file"]::file-selector-button:hover {
	border-color: var( --dmb-accent, #22384c );
}

/* -------------------------------------------------------------------------
 * The offer's one button
 *
 * .dmb-button paints itself in --dmb-grey, the branding button colour, which
 * is chosen to work on the portal's pale background. The offer panel is nearly
 * black, so a mid-grey button on it reads as disabled — the one control in the
 * section, looking like the one thing you can't press.
 *
 * White fill and dark text instead. That's legible on any panel colour, it
 * doesn't depend on the client's branding to be readable, and it's the
 * strongest contrast available at the point of the page that's asking for a
 * reply.
 * ---------------------------------------------------------------------- */

.dmb-offer .dmb-button-onDark {
	background: #fff;
	color: #16202b;
	font-weight: 600;
}

.dmb-offer .dmb-button-onDark:hover:not(:disabled) {
	background: rgba( 255, 255, 255, 0.88 );
	color: #16202b;
}

/* Sole action now, so it doesn't need to share a row. */
.dmb-offer-actions {
	gap: 1rem;
}


/* --- Stacked, on anything smaller than a laptop ---------------------------
 *
 * This claimed to stack and didn't. .dmb-lightbox is display: flex with no
 * flex-direction, so it is a row — always was. Setting the notes to width:100%
 * inside a row doesn't put them underneath anything; it just gives two
 * children an impossible instruction and lets them squeeze each other. On a
 * phone that left a sliver of video beside a panel, which is what "doesn't
 * display well on mobile" looks like.
 *
 * The direction has to change for the stacking to happen at all.
 *
 * Only when there are notes. Without them the lightbox is a photograph on a
 * dark backdrop, centred, and a column would push it to the top for no reason.
 * ------------------------------------------------------------------------- */

@media ( max-width: 1000px ) {
	.dmb-lightbox.dmb-lb-hasnotes {
		flex-direction: column;
		align-items: stretch;
		justify-content: flex-start;

		/*
		 * The whole thing scrolls as one page rather than two nested
		 * scrollers. A panel with its own scrollbar inside a page that also
		 * scrolls is the single most awkward thing to operate with a thumb.
		 */
		padding: 0;
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
	}

	/* Full width, hard against the edges — there's no room on a phone to
	 * spend on a margin around a video. */
	.dmb-lb-hasnotes .dmb-lb-figure {
		width: 100%;
		max-width: none;
		flex: 0 0 auto;
		gap: 0;

		/*
		 * The film stays put while you read and write about it, which is the
		 * whole point of reviewing. Sticky rather than fixed so it gives the
		 * space back at the top of the list.
		 */
		position: sticky;
		top: 0;
		z-index: 3;
		background: #000;
	}

	.dmb-lb-hasnotes .dmb-lb-stage {
		max-height: none;
		border-radius: 0;
	}

	.dmb-lb-hasnotes .dmb-lb-caption {
		padding: 8px 14px;
	}

	.dmb-lb-hasnotes .dmb-lb-notes {
		width: 100%;
		max-width: none;

		/* No inner scroller: the page is the scroller now. */
		max-height: none;
		overflow: visible;
		border-radius: 0;
	}

	.dmb-lb-hasnotes .dmb-note-list {
		overflow: visible;
		min-height: 0;
	}

	/*
	 * The controls leave the flow.
	 *
	 * They were absolutely positioned against a lightbox that didn't scroll.
	 * Now that it does, absolute means they scroll away with the top of the
	 * page — so close is pinned to the viewport, and the arrows are pinned
	 * over the video: a full-width 16:9 film is 56vw tall, so 28vw is its
	 * middle.
	 */
	.dmb-lb-hasnotes .dmb-lb-close {
		position: fixed;
		top: 10px;
		right: 10px;
		z-index: 4;
	}

	.dmb-lb-hasnotes .dmb-lb-nav {
		position: fixed;
		top: min( 28vw, 30vh );
		z-index: 4;
	}

	.dmb-lb-hasnotes .dmb-lb-prev {
		left: 6px;
	}

	.dmb-lb-hasnotes .dmb-lb-next {
		right: 6px;
	}

	/*
	 * The controls come out from over the film and sit under it.
	 *
	 * On a desktop the stage is around 74vh tall and the overlay costs it a
	 * seventh. On a phone the same overlay is unchanged at roughly 114px —
	 * 30px of scrim, a 28px track, the marks, and a 30px button row — while
	 * the film full-width at 16:9 is only about 56vw, near 220px. Over half
	 * the frame was controls, which is what "sits quite high and covers the
	 * video" describes.
	 *
	 * There is no shortage of vertical space here, only of frame, so the
	 * overlay stops being an overlay. The stage drops its fixed 16:9 box and
	 * lets the film take its own shape at full width, and the controls flow
	 * underneath on the figure's black.
	 */
	.dmb-lb-hasnotes .dmb-lb-stage {
		display: block;
		aspect-ratio: auto;
		overflow: visible;
	}

	.dmb-lb-hasnotes .dmb-lb-stage video,
	.dmb-lb-hasnotes .dmb-lb-stage img {
		width: 100%;
		height: auto;
		max-height: none;
		border-radius: 0;
		box-shadow: none;
	}

	.dmb-lb-hasnotes .dmb-pl {
		position: static;

		/* Nothing to be legible against any more — it has its own black. */
		padding: 8px 12px 10px;
		background: #000;
	}

	/* And the pieces come down to a size that suits a thumb rather than a
	 * pointer: a shorter track, no volume slider (the phone has buttons for
	 * that), and a clock that doesn't reserve 92px it no longer needs. */
	.dmb-lb-hasnotes .dmb-pl-track {
		height: 6px;
		border-top-width: 9px;
		border-bottom-width: 9px;
	}

	.dmb-lb-hasnotes .dmb-pl-vol,
	.dmb-lb-hasnotes .dmb-pl-mute {
		display: none;
	}

	.dmb-lb-hasnotes .dmb-pl-time {
		min-width: 0;
	}

	.dmb-lb-hasnotes .dmb-pl-bar {
		gap: 6px;
	}
}



/* A textarea sizes itself from its cols attribute, not its container, and
 * under content-box the padding and border are added on top of width:100%.
 * Belt and braces against the same cut-off edges. */
.dmb-note-add textarea,
.dmb-note-replybox textarea {
	max-width: 100%;
	box-sizing: border-box;
}

/* --- A person's files, grouped by the release covering them ----------------
 *
 * Small tiles rather than the full asset card: this is a paperwork screen, and
 * the question it answers is "which files does this release cover" — enough
 * picture to recognise a shot, not enough to browse in.
 * ------------------------------------------------------------------------- */

.dmb-personfiles {
	display: grid;
	grid-template-columns: repeat( auto-fill, minmax( 110px, 1fr ) );
	gap: 0.9rem 0.75rem;
	margin: 0.9rem 0 0;
	padding: 0;
	list-style: none;
}

.dmb-personfile a {
	display: block;
	color: inherit;
	text-decoration: none;
}

.dmb-personfile-image {
	display: block;
	aspect-ratio: 4 / 3;
	background-color: var( --dmb-soft );
	background-size: cover;
	background-position: center 25%;
	border-radius: var( --dmb-radius, 10px );
}

.dmb-personfile-name {
	display: block;
	margin-top: 0.4rem;
	font-size: 0.82rem;
	line-height: 1.35;
	color: var( --dmb-muted );

	/* Two lines, then stop. A long original filename would otherwise set the
	   height of every row it happens to land in. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.dmb-personfile a:hover .dmb-personfile-name {
	color: var( --dmb-ink );
}

/* An expired release keeps its files visible — they are still there and still
   the thing being talked about — but the panel says so at a glance. */
.dmb-panel.dmb-consent-expired {
	border-left: 3px solid #b91c1c;
}

/* --- One release on a person's page ---------------------------------------
 *
 * Well apart from the next one. Each of these is a separate shoot with its own
 * dates and its own standing, and run together they read as one long list of
 * photographs with headings in it — which is the reading that makes somebody
 * think a later release covers an earlier shoot.
 * ------------------------------------------------------------------------- */

.dmb-personrelease {
	margin-bottom: 2.75rem;
	padding-bottom: 1.75rem;
}

.dmb-personrelease:last-child {
	margin-bottom: 0;
}

/* The folder is the heading, because the folder is what somebody recognises:
   "Autumn 2026" is the shoot, where a date is just a date. */
.dmb-personrelease-where {
	margin-bottom: 0.15rem;
}

.dmb-personrelease-when {
	margin: 0 0 0.9rem;
	color: var( --dmb-muted );
	font-size: 0.92rem;
}

/* A video needs the same badge the cards use, or a still frame looks like a
   photograph until you click it. Centred on the picture, which is why the
   badge lives inside that span rather than in the anchor beside the filename. */
.dmb-personfile-image {
	position: relative;
}

.dmb-personfile-play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate( -50%, -50% );
	width: 34px;
	height: 34px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: rgba( 0, 0, 0, 0.55 );
	color: #fff;
	font-size: 13px;
	padding-left: 2px;
	pointer-events: none;
}

/* A field whose value was chosen for you, above. Still submitted — see the
   note in front.js about readonly versus disabled — so it reads as settled
   rather than as broken. */
.dmb-form input[type="text"].is-locked {
	background: var( --dmb-soft, #f6f8f9 );
	color: var( --dmb-muted );
	cursor: default;
}

/* --- Adding a tag from the upload screen ----------------------------------
 *
 * Sits under the pills it adds to, and reads as part of that field rather than
 * as a second one. Deliberately quieter than the upload button: adding a tag is
 * a small aside in the middle of a bigger job.
 * ------------------------------------------------------------------------- */

.dmb-tagnew {
	display: flex;
	gap: 8px;
	margin-top: 0.7rem;
	max-width: 26rem;
}

.dmb-tagnew input[type="text"] {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0.45rem 0.7rem;
	border: 1px solid var( --dmb-line );
	border-radius: 6px;
	font: inherit;
	font-size: 0.9rem;
}

.dmb-tagnew .dmb-button {
	flex: 0 0 auto;
}

.dmb-tagnew-bad {
	color: #b91c1c;
}

/*
 * --- Touch: the box you type in -------------------------------------------
 *
 * iOS zooms the page when you focus an input whose font-size is under 16px,
 * and it does not zoom back out. Everything then overflows a viewport that is
 * suddenly narrower than the layout — "the page goes wider and the comment
 * box spreads out and the edges are cut off".
 *
 * The hero search input already carries a 16px for exactly this reason. These
 * two were missed. Scoped to coarse pointers so the desktop panel keeps its
 * smaller type, and by pointer rather than by width because an iPad in
 * portrait is 1024px wide and zooms just the same.
 *
 * KEPT LAST IN THIS FILE, AND IT HAS TO BE.
 *
 * A media query carries no extra specificity, so this wins against the rules
 * it lifts only while it comes after them. The tag box on the upload screen
 * was appended below this block and its 0.9rem quietly won — the field was
 * listed here and the page still zoomed. Anything new goes above this block;
 * player-tests/mobile.py fails if it doesn't.
 * ------------------------------------------------------------------------- */

@media ( pointer: coarse ) {
	.dmb-note-add textarea,
	.dmb-note-replybox textarea,

	/* Not reported, but found by sweeping every typeable box in the file
	 * rather than fixing the two that were: the reason for the download, the
	 * detail behind it, and the name of a replacement file. All 0.95rem —
	 * 15.2px — and all reached from a phone. */
	.dmb-gate-override input[type="text"],
	.dmb-gate-detail input[type="text"],
	.dmb-replace input[type="text"],
	.dmb-tagnew input[type="text"] {
		font-size: 16px;
	}
}

/* --- Analytics ------------------------------------------------------------
 *
 * The period control sits with the heading rather than above the tiles, so it
 * reads as belonging to the whole screen — every figure below it answers for
 * the same window.
 * ------------------------------------------------------------------------- */

.dmb-stats-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
}

.dmb-period {
	display: flex;
	align-items: center;
	gap: 8px;
}

.dmb-period select {
	padding: 0.4rem 0.6rem;
	border: 1px solid var( --dmb-line );
	border-radius: 6px;
	font: inherit;
	font-size: 0.9rem;
}

/* --- Twelve months, as bars -----------------------------------------------
 *
 * Drawn with the months as flex children and the bar height as a percentage,
 * rather than with a charting library. It is twelve numbers; a 90KB dependency
 * to draw twelve numbers is a dependency to keep up to date for ever.
 * ------------------------------------------------------------------------- */

.dmb-trend {
	display: flex;
	align-items: flex-end;
	gap: 6px;
	height: 170px;
	margin: 0.8rem 0 1.4rem;
	padding: 0;
	list-style: none;
}

.dmb-trend > li {
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-end;
	height: 100%;
	min-width: 0;
}

.dmb-trend-bar {
	display: block;
	width: 100%;
	max-width: 42px;
	border-radius: 4px 4px 0 0;
	background: var( --dmb-accent, #22384c );

	/* Ordered so the bar grows from the baseline rather than the middle. */
	margin-top: auto;
}

.dmb-trend-count {
	order: -1;
	font-size: 0.72rem;
	color: var( --dmb-muted );
	margin-bottom: 0.25rem;
}

.dmb-trend-month {
	margin-top: 0.4rem;
	font-size: 0.72rem;
	color: var( --dmb-muted );
	white-space: nowrap;
}

.dmb-untouched {
	margin: 0.6rem 0 0.4rem;
	padding-left: 1.1rem;
	color: var( --dmb-muted );
	font-size: 0.9rem;
}

@media ( max-width: 640px ) {
	/* Six months rather than twelve would need a second query; hiding the
	   count above each bar is enough to stop them overlapping. */
	.dmb-trend-count {
		display: none;
	}

	.dmb-trend {
		height: 130px;
	}
}

/* The analytics head with no heading in it: the page's h1 says "Analytics", so
   only the period control is left and it belongs on the right. */
.dmb-stats-head-bare {
	justify-content: flex-end;
}

/* --- The users table ------------------------------------------------------
 *
 * Four columns of plain text now. It carried three forms as well, and six
 * columns of controls overlapped at anything narrower than a desktop — which
 * is why changing somebody moved to their own page.
 * ------------------------------------------------------------------------- */

.dmb-usertable {
	table-layout: fixed;
	width: 100%;
}

.dmb-usertable th:nth-child(1), .dmb-usertable td:nth-child(1) { width: 28%; }
.dmb-usertable th:nth-child(2), .dmb-usertable td:nth-child(2) { width: 32%; }
.dmb-usertable th:nth-child(3), .dmb-usertable td:nth-child(3) { width: 22%; }
.dmb-usertable th:nth-child(4), .dmb-usertable td:nth-child(4) { width: 18%; }

/* An email has no spaces to break at, so without this one long address pushes
   the table wider than the page instead of wrapping. */
.dmb-usertable-email {
	overflow-wrap: anywhere;
}

/* Last signed in: a fact you scan down rather than read, so it stays quiet. */
.dmb-usertable .dmb-lastseen {
	font-size: 0.9rem;
	color: var( --dmb-muted );
}

@media ( max-width: 640px ) {
	/* Four text columns fit a phone once the type and date give up a little
	   size. No sideways scrolling needed now the controls have gone. */
	.dmb-usertable th,
	.dmb-usertable td {
		padding: 0.6rem 0.35rem;
		font-size: 0.9rem;
	}

	.dmb-usertable .dmb-lastseen {
		font-size: 0.82rem;
	}
}
