/*
 * All Meetings.
 *
 * Prefixed mhub-am- and written flat, without the deep SCSS nesting the rest of
 * this screen uses, because these rules have to win against two stylesheets at
 * once: wp-admin's, and the plugin's own `meeting.scss`, which styles this page
 * by element under a long chain of ids.
 *
 * Two habits carried over from the Get Started and upgrade screens, both
 * load-bearing:
 *
 *   - Every link and anchor-styled button re-declares its colour on hover,
 *     focus and active. WordPress ships `a:hover, a:focus { color: <scheme
 *     blue> }` at specificity (0,1,1), which outranks a plain class, so a white
 *     label on a blue button turns admin-blue on hover in some colour schemes
 *     and not others.
 *
 *   - wp-admin's `a:focus` box-shadow is suppressed only where a real
 *     `:focus-visible` outline replaces it, since a shadow is not an outline
 *     and declaring one does not remove the other - it stacks two rings.
 *
 * The table is CSS grid with ARIA roles rather than a `<table>`. Each row needs
 * a title, a subtitle of tags, a time and a relative time stacked in two lines,
 * and grid gives that without nested tables while keeping the columns aligned.
 */

.mhub-am {
	--mhub-am-brand: #085df2;
	--mhub-am-brand-700: #0a4bc4;
	--mhub-am-brand-tint: #eef4ff;
	--mhub-am-brand-line: #cfe0ff;

	--mhub-am-good: #12805c;
	--mhub-am-good-tint: #e6f6f0;
	--mhub-am-warn: #a35b00;
	--mhub-am-warn-tint: #fdf3e4;
	--mhub-am-bad: #b42318;
	--mhub-am-bad-tint: #fdeceb;

	--mhub-am-panel: #ffffff;
	--mhub-am-line: #e2e8f0;

	/*
	 * A control's boundary, in two weights.
	 *
	 * Rest was #8492a6 for one pass, which is 3.16:1 and the lightest neutral
	 * that clears WCAG 1.4.11 outright. On a page of white cards on a near-white
	 * ground it read as heavy - the boxes drew more attention than what was in
	 * them - so the weight moved to where a boundary is actually needed. Slate-300
	 * at rest keeps the shape without shouting; #8492a6 arrives on hover, which
	 * is the moment somebody is asking "can I type here".
	 *
	 * The trade is stated rather than hidden: at rest the boundary is 1.48:1 and
	 * below the 3:1 floor. Same pair on the Add New Meeting inputs and on the
	 * frontend select, so no screen disagrees with another.
	 */
	--mhub-am-control-edge: #cbd5e1;
	--mhub-am-control-edge-hover: #8492a6;
	--mhub-am-line-soft: #f1f5f9;
	--mhub-am-ink: #0f172a;
	--mhub-am-ink-soft: #475569;

	/* Measured at 4.98:1 on white and 4.72:1 on the page grey, so it clears AA
	   at the 12px sizes it is used at. */
	--mhub-am-ink-faint: #64748b;

	--mhub-am-radius: 16px;
	--mhub-am-radius-sm: 10px;

	box-sizing: border-box;
	font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
	color: var( --mhub-am-ink );
	-webkit-font-smoothing: antialiased;
}

.mhub-am *,
.mhub-am *::before,
.mhub-am *::after {
	box-sizing: border-box;
}

.mhub-am :where( p, h1, h2, h3, ul, li ) {
	margin: 0;
	padding: 0;
}

.mhub-am a:focus,
.mhub-am button:focus,
.mhub-am-header a:focus,
.mhub-am-header button:focus {
	box-shadow: none;
	outline: 0;
}

.mhub-am a:focus-visible,
.mhub-am button:focus-visible,
.mhub-am input:focus-visible,
.mhub-am select:focus-visible,
.mhub-am-header a:focus-visible,
.mhub-am-header button:focus-visible {
	outline: 2px solid var( --mhub-am-brand );
	outline-offset: 2px;
	border-radius: 8px;
}

.mhub-am-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect( 0 0 0 0 );
	white-space: nowrap;
	border: 0;
}

/* ---------------------------------------------------------------- header - */

/*
 * Border-box, like .mhub-am below it.
 *
 * This element is a sibling of .mhub-am, not a child, so the `.mhub-am *` reset
 * never reached it and it stayed content-box. Both carry `max-width: 1420px`,
 * but on a content-box element that caps the content and the 40px gutters land
 * outside it - so the header measured 1500px against the body's 1420 and the
 * page title sat 40px to the left of the panels underneath it. Invisible until
 * the window is wide enough for the cap to bind.
 */
.mhub-am-header {
	box-sizing: border-box;
	font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
	margin-bottom: 20px;
}

.mhub-am-header__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
}

.mhub-am-header__title {
	font-size: 26px;
	line-height: 1.15;
	font-weight: 700;
	letter-spacing: -0.025em;
	color: #0f172a;
	margin: 0;
	padding: 0;
}

.mhub-am-header__actions {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
}

/* --------------------------------------------------------------- buttons - */

.mhub-am .mhub-am-btn,
.mhub-am-header .mhub-am-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;

	/*
	 * 44px, met with padding rather than a fixed height so a label can wrap
	 * without the control collapsing.
	 *
	 * It was 40, which is the height the form kit gives a select or a text
	 * input inside a settings row. That is the right number there and the wrong
	 * one here: these are page-level actions, and the wizard's own primary -
	 * BTN_PRIMARY in the form kit - is 44. A toolbar that sits four pixels
	 * under the plugin's other primary reads as a slightly different product,
	 * and 44 is also the touch floor.
	 *
	 * `.mhub-am-btn--row` sets its own 32px further down the file and keeps it:
	 * same specificity, later rule. That one is dense on purpose and buys its
	 * 44 back with an ::after.
	 */
	min-height: 44px;
	padding: 0 16px;

	border-radius: var( --mhub-am-radius-sm, 10px );
	border: 1px solid transparent;
	font-size: 13.5px;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, transform 120ms ease;
}

.mhub-am .mhub-am-btn:active,
.mhub-am-header .mhub-am-btn:active {
	transform: translateY( 1px );
}

.mhub-am .mhub-am-btn[disabled] {
	opacity: 0.5;
	cursor: not-allowed;
	transform: none;
}

.mhub-am .mhub-am-btn--primary,
.mhub-am .mhub-am-btn--primary:link,
.mhub-am .mhub-am-btn--primary:visited,
.mhub-am-header .mhub-am-btn--primary,
.mhub-am-header .mhub-am-btn--primary:link,
.mhub-am-header .mhub-am-btn--primary:visited {
	background: #085df2;
	border-color: #085df2;
	color: #ffffff;
}

.mhub-am .mhub-am-btn--primary:hover,
.mhub-am .mhub-am-btn--primary:focus,
.mhub-am .mhub-am-btn--primary:focus-visible,
.mhub-am .mhub-am-btn--primary:active,
.mhub-am-header .mhub-am-btn--primary:hover,
.mhub-am-header .mhub-am-btn--primary:focus,
.mhub-am-header .mhub-am-btn--primary:focus-visible,
.mhub-am-header .mhub-am-btn--primary:active {
	background: #0a4bc4;
	border-color: #0a4bc4;
	color: #ffffff;
}

.mhub-am .mhub-am-btn--quiet,
.mhub-am .mhub-am-btn--quiet:link,
.mhub-am .mhub-am-btn--quiet:visited,
.mhub-am-header .mhub-am-btn--quiet,
.mhub-am-header .mhub-am-btn--quiet:link,
.mhub-am-header .mhub-am-btn--quiet:visited {
	background: #ffffff;
	border-color: #e2e8f0;
	color: #0f172a;
}

.mhub-am .mhub-am-btn--quiet:hover,
.mhub-am .mhub-am-btn--quiet:focus,
.mhub-am .mhub-am-btn--quiet:focus-visible,
.mhub-am .mhub-am-btn--quiet:active,
.mhub-am-header .mhub-am-btn--quiet:hover,
.mhub-am-header .mhub-am-btn--quiet:focus,
.mhub-am-header .mhub-am-btn--quiet:focus-visible,
.mhub-am-header .mhub-am-btn--quiet:active {
	background: #eef4ff;
	border-color: #cfe0ff;
	color: #0a4bc4;
}

.mhub-am .mhub-am-btn--danger {
	background: #b42318;
	border-color: #b42318;
	color: #ffffff;
}

.mhub-am .mhub-am-btn--danger:hover,
.mhub-am .mhub-am-btn--danger:focus,
.mhub-am .mhub-am-btn--danger:focus-visible,
.mhub-am .mhub-am-btn--danger:active {
	background: #941a11;
	border-color: #941a11;
	color: #ffffff;
}

/* Row-level action: quiet until hovered, then it becomes the loud thing in the
   row. A row full of solid buttons reads as a wall of blue. */
/*
 * The row's own action, one step down from a button.
 *
 * It was an outlined blue pill, which is the weight a page's primary carries -
 * and this one repeats on every row of a list somebody is reading rather than
 * acting on. Ink instead of brand, no border, and the tint arrives when the
 * pointer or the keyboard does, so a scan down the list meets one colour
 * (the meeting titles) rather than twenty.
 */
.mhub-am .mhub-am-btn--row,
.mhub-am .mhub-am-btn--row:link,
.mhub-am .mhub-am-btn--row:visited {
	min-height: 32px;
	padding: 0 9px;
	font-size: 12.5px;
	font-weight: 600;
	background: transparent;
	border-color: transparent;

	/* #334155 on the row's white is 10.9:1; the hover pair below is 6.3:1. */
	color: #334155;
}

/*
 * 32 visible, 44 to the finger.
 *
 * The dots button next to this one already buys its 44 with `inset: -5px`;
 * this one had nothing, so it answered a tap over 31px of height on a row that
 * is 70px tall. Six pixels top and bottom close it without moving a pixel of
 * what is drawn, which is the point: the row's density is deliberate and the
 * control's weight was argued for above.
 *
 * Vertical only. Growing it sideways would push into the dots to its right and
 * the Join button that appears to its left on a live row, and the row has 19px
 * of clearance above and below to give, so there is no reason to.
 */
.mhub-am .mhub-am-btn--row {
	position: relative;
}

.mhub-am .mhub-am-btn--row::after {
	content: '';
	position: absolute;
	inset: -6px 0;
}

/* The pencil and the word travel together, and the icon never grows with the
   label - 14px against a 12.5px line is the ratio the wizard rail uses. */
.mhub-am .mhub-am-btn--row svg {
	flex: none;
	margin-right: 6px;
}

.mhub-am .mhub-am-btn--row:hover,
.mhub-am .mhub-am-btn--row:focus,
.mhub-am .mhub-am-btn--row:focus-visible,
.mhub-am .mhub-am-btn--row:active {
	background: #eef4fe;
	border-color: transparent;
	color: #0a52d0;
}

/* Live is the exception the quiet is measured against: it is the one row where
   something is happening now, and it keeps the filled treatment. */
.mhub-am .mhub-am-btn--row.is-live,
.mhub-am .mhub-am-btn--row.is-live:link,
.mhub-am .mhub-am-btn--row.is-live:visited {
	background: #085df2;
	border-color: #085df2;
	color: #ffffff;
	font-weight: 700;
}

.mhub-am .mhub-am-btn--row.is-live:hover,
.mhub-am .mhub-am-btn--row.is-live:focus-visible {
	background: #0a52d0;
	border-color: #0a52d0;
	color: #ffffff;
}

/* ------------------------------------------------------------- stats band - */

.mhub-am-band {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin-bottom: 20px;
}

/* The live strip's styling moved into the component, in Tailwind. What used to
   be here painted a whole panel in the accent colour, directly above a table
   row that painted itself the same - see LiveNow.js. */



/* The title, meta and actions rules that used to sit here were the previous
   design's, and they were overriding the rebuilt ones above purely by being
   later in the file - a 700 title, a grey meta at 4.26:1 on the green, and a
   34ch truncation. Declared once now, above. */

/* --------------------------------------------------------------- toolbar - */

.mhub-am-toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	flex-wrap: wrap;
	margin-bottom: 14px;
}

.mhub-am-tabs {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	/* 3, not 4. The tab inside is 34px and the search field, the platform select
	   and the Add new button beside the strip all measure 40, so 4px of padding
	   stood the strip at 42 and two pixels proud of the row it shares. Taking it
	   out of the padding rather than out of the tab keeps the click target the
	   size it was. */
	padding: 3px;
	border-radius: 12px;
	background: var( --mhub-am-line-soft );
}

.mhub-am-tab {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	min-height: 34px;
	padding: 0 12px;
	border: 0;
	border-radius: 9px;
	background: transparent;
	font-family: inherit;
	font-size: 13px;
	font-weight: 600;
	color: var( --mhub-am-ink-soft );
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}

.mhub-am-tab:hover,
.mhub-am-tab:focus-visible {
	background: rgba( 255, 255, 255, 0.7 );
	color: var( --mhub-am-ink );
}

.mhub-am-tab.is-active {
	background: var( --mhub-am-panel );
	color: var( --mhub-am-ink );
	box-shadow: 0 1px 2px rgba( 13, 21, 38, 0.08 );
}

.mhub-am-tab__count {
	font-size: 11.5px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: var( --mhub-am-ink-faint );
}

.mhub-am-tab.is-active .mhub-am-tab__count {
	color: var( --mhub-am-brand );
}

/* The attention tab colours only when it has something in it, so a clean list
   never shows a warning that is not one. */
.mhub-am-tab.is-warning .mhub-am-tab__count {
	padding: 1px 7px;
	border-radius: 999px;
	background: var( --mhub-am-bad-tint );
	color: var( --mhub-am-bad );
}

.mhub-am-tools {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
}

/*
 * The platform filter is a kit listbox, and the kit sizes it for a settings
 * row: 40px tall, 13px type. Both are right inside a form and wrong in a
 * toolbar, where it stands between a 44px search field and a 44px primary.
 *
 * Scoped to this toolbar rather than fixed in the kit, because the kit's own
 * number is not the mistake - every listbox on every form row wants to stay 40
 * beside the inputs it lines up with. Only the three controls up here are
 * page-level, so only they are raised.
 */
.mhub-am-tools [aria-haspopup='listbox'] {
	min-height: 44px;
	font-size: 13.5px;
}

/*
 * wp-admin puts `margin: 1px` on every input, from forms.css.
 *
 * On this toolbar that pixel sat between the search field and the platform
 * filter, so the flex `gap: 10px` painted as 11 on one side of the filter and
 * 10 on the other, and the field itself started one pixel left of where the
 * heading above it does. Nothing else in the row is an `<input>`, which is why
 * only this one edge was off.
 */
.mhub-am .mhub-am-search {
	margin: 0;
}

.mhub-am .mhub-am-search {
	/* 44, with the button beside it. See the note over `.mhub-am-btn`. */
	min-height: 44px;
	padding: 0 12px;
	/* --mhub-am-control-edge, not --mhub-am-line. A card hairline separates two
	   surfaces; this line tells the reader where a control they can type in
	   begins. The platform filter beside this field is built on the same pair,
	   so the two boxes on the toolbar row read as one. */
	border: 1px solid var( --mhub-am-control-edge );
	border-radius: var( --mhub-am-radius-sm );
	background: var( --mhub-am-panel );
	font-family: inherit;
	font-size: 13.5px;
	color: var( --mhub-am-ink );
	box-shadow: none;
}

.mhub-am .mhub-am-search {
	width: 240px;
	max-width: 100%;
}

/* Never resting-state only: a field that looks the same under the pointer as it
   does at rest gives no sign it can be typed in. */
.mhub-am .mhub-am-search:hover {
	border-color: var( --mhub-am-control-edge-hover );
}

.mhub-am .mhub-am-search:focus {
	border-color: var( --mhub-am-brand-line );
}

.mhub-am-bulk {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	flex-wrap: wrap;
	margin-bottom: 12px;
	padding: 10px 16px;
	border: 1px solid var( --mhub-am-brand-line );
	border-radius: var( --mhub-am-radius-sm );
	background: var( --mhub-am-brand-tint );
	font-size: 13px;
	font-weight: 600;
	color: var( --mhub-am-ink );
}

/* ----------------------------------------------------------------- table - */

/*
 * Establish a size container on the dashboard root.
 *
 * Every responsive rule for this table was written as a viewport `@media`, and
 * that is right in wp-admin where the table's width tracks the window. It is
 * wrong everywhere the dashboard mounts inside a fixed-width column that the
 * viewport does not predict - the Tutor / MultiVendorX / Dokan / WCFM vendor
 * dashboards, where the content area is ~820-880px on a full-width monitor. In
 * those the viewport is 1920, the wide-layout grid applies, and its fixed
 * middle columns push the actions cell out of the panel.
 *
 * `container-type: inline-size` lets the `@container` copies of the two
 * breakpoints below fire on the element's own width instead. The viewport
 * `@media` versions are kept as-is so nothing changes in wp-admin.
 */
.meeting-dashboard {
	container-type: inline-size;
	container-name: mhub-am;
}

.mhub-am-table {
	border: 1px solid var( --mhub-am-line );
	border-radius: var( --mhub-am-radius );
	background: var( --mhub-am-panel );
	overflow: hidden;
}

.mhub-am-head,
.mhub-am-row {
	display: grid;
	/* The columns are declared once, at the foot of this file, under "The table,
	   laid out around what a row actually contains". Not here: this rule is the
	   one people find first, and it spent a while describing a grid that a later
	   block was already overriding. */
	align-items: center;
	gap: 12px;
	padding: 0 18px;
}

.mhub-am-head {
	min-height: 42px;
	background: #fbfcfe;
	border-bottom: 1px solid var( --mhub-am-line );
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var( --mhub-am-ink-faint );
}

.mhub-am-row {
	min-height: 68px;
	padding-top: 12px;
	padding-bottom: 12px;
	border-bottom: 1px solid var( --mhub-am-line-soft );
	transition: background-color 150ms ease;
}

.mhub-am-row:last-child {
	border-bottom: 0;
}

.mhub-am-row:hover {
	background: #fafbfd;
}

/* A live row is marked on its left edge as well as by the dot beside its
   title, so it is findable while scrolling a long list. */
.mhub-am-row.is-live {
	background: #f6fbf9;
	box-shadow: inset 3px 0 0 var( --mhub-am-good );
}

.mhub-am-row.is-past .mhub-am-title,
.mhub-am-row.is-past .mhub-am-when {
	color: var( --mhub-am-ink-soft );
}

.mhub-am-cell {
	min-width: 0;
}

.mhub-am-cell--main {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.mhub-am-cell--when {
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.mhub-am-cell--platform {
	display: flex;
	align-items: center;
	gap: 9px;
}

.mhub-am-cell--actions {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 6px;
}

.mhub-am .mhub-am-title {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 0;
	border: 0;
	background: transparent;
	font-family: inherit;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
	text-align: left;
	color: var( --mhub-am-ink );
	cursor: pointer;
	transition: color 150ms ease;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.mhub-am .mhub-am-title:hover,
.mhub-am .mhub-am-title:focus-visible {
	color: var( --mhub-am-brand );
	text-decoration: underline;
}

.mhub-am-dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var( --mhub-am-good );
	flex: none;
}

.mhub-am-sub {
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
	font-size: 12px;
	color: var( --mhub-am-ink-faint );
}

.mhub-am-type {
	padding: 1px 7px;
	border-radius: 5px;
	background: var( --mhub-am-line-soft );
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var( --mhub-am-ink-soft );
}

.mhub-am-type.is-webinar {
	background: var( --mhub-am-brand-tint );
	color: var( --mhub-am-brand-700 );
}

/* Warnings are words, never a colour on its own. */
.mhub-am-flag {
	color: var( --mhub-am-warn );
	font-weight: 600;
}

.mhub-am-flag.is-clash {
	color: var( --mhub-am-bad );
}

/* An undated meeting says so once, in the quieter ink of something unset,
   rather than saying it and then captioning itself "not scheduled". */
.mhub-am-when.is-muted {
	font-weight: 500;
	color: var( --mhub-am-ink-faint );
}

.mhub-am-when {
	font-size: 13px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var( --mhub-am-ink );
}

.mhub-am-rel {
	font-size: 11.5px;
	color: var( --mhub-am-ink-faint );
}

.mhub-am-row.is-live .mhub-am-rel,
.mhub-am-rel.is-live {
	color: var( --mhub-am-good );
	font-weight: 700;
}

.mhub-am-mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	flex: none;
}

.mhub-am-mark svg {
	width: 100%;
	height: 100%;
	display: block;
}

/*
 * The platform cell holds the mark and nothing else.
 *
 * This selector used to style the platform-s printed name, which sat beside
 * its own logo. The name is still here as the accessible name and the tooltip;
 * it is only the visible second copy that is gone.
 */
.mhub-am-platform {
	display: inline-flex;
	align-items: center;
}

/* ------------------------------------------------------------- row menu - */

.mhub-am-menu {
	position: relative;
}

/*
 * A 34px face inside a 44px target.
 *
 * The painted button stays 34px: it is the quietest control in the row and a
 * bigger fill would shout. The pressable area is the 44px the row has to spare,
 * carried by a transparent pseudo-element rather than by the button's own box,
 * so growing the target does not grow the hover background with it.
 */
.mhub-am .mhub-am-menu__toggle {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 1px solid transparent;
	border-radius: 9px;
	background: transparent;
	font-size: 13px;
	line-height: 1;
	color: var( --mhub-am-ink-faint );
	cursor: pointer;
	transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

/* 34 + 5 on every side = 44. Five pixels, not six, so the area stops just
   short of the Join button that sits 6px to its left on a live row. */
.mhub-am .mhub-am-menu__toggle::after {
	content: '';
	position: absolute;
	inset: -5px;
}

.mhub-am .mhub-am-menu__toggle:hover,
.mhub-am .mhub-am-menu__toggle:focus-visible,
.mhub-am .mhub-am-menu__toggle[aria-expanded='true'] {
	background: var( --mhub-am-line-soft );
	border-color: var( --mhub-am-line );
	color: var( --mhub-am-ink );
}

.mhub-am-menu__panel {
	position: absolute;
	top: calc( 100% + 6px );
	right: 0;
	z-index: 20;
	min-width: 208px;
	padding: 6px;
	border: 1px solid var( --mhub-am-line );
	border-radius: 12px;
	background: var( --mhub-am-panel );
	box-shadow: 0 12px 32px rgba( 13, 21, 38, 0.14 );
}

.mhub-am .mhub-am-menu__panel button,
.mhub-am .mhub-am-menu__panel a {
	display: flex;
	align-items: center;
	width: 100%;
	min-height: 36px;
	padding: 0 10px;
	border: 0;
	border-radius: 8px;
	background: transparent;
	font-family: inherit;
	font-size: 13px;
	font-weight: 500;
	text-align: left;
	text-decoration: none;
	color: var( --mhub-am-ink );
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}

.mhub-am .mhub-am-menu__panel button:hover,
.mhub-am .mhub-am-menu__panel button:focus-visible,
.mhub-am .mhub-am-menu__panel a:hover,
.mhub-am .mhub-am-menu__panel a:focus,
.mhub-am .mhub-am-menu__panel a:focus-visible {
	background: var( --mhub-am-brand-tint );
	color: var( --mhub-am-brand-700 );
}

.mhub-am .mhub-am-menu__panel button.is-danger {
	color: var( --mhub-am-bad );
}

.mhub-am .mhub-am-menu__panel button.is-danger:hover,
.mhub-am .mhub-am-menu__panel button.is-danger:focus-visible {
	background: var( --mhub-am-bad-tint );
	color: var( --mhub-am-bad );
}

/* ---------------------------------------------------------- blanks, pager - */

/*
 * The empty state. One component, two sizes.
 *
 * Structure ported from DriveHub's common/EmptyState.jsx:
 *
 *     tile . title . description . action . secondary . footnote
 *
 * The tile is the part the first port dropped, and it was the part doing the
 * work. An empty state's actual problem is that a blank panel gives the eye
 * nowhere to start; without a mark at the top, the heading has to serve as both
 * anchor and sentence and manages neither. Everything else here is spacing.
 */

.mhub-am-blank {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	padding: 72px 24px 76px;
	border: 1px solid var( --mhub-am-line );
	border-radius: var( --mhub-am-radius );
	background: var( --mhub-am-panel );
}

/*
 * 56px, 16px radius, flat fill, hairline ring. DriveHub's exact tile, and its
 * reasoning holds: a flat tinted square at roughly three times the cap height
 * of the heading introduces the heading. A gradient orb twice the heading's
 * size competes with it.
 *
 * The ring is an inset shadow rather than a border so the tile's outer size is
 * the number written here, which is what keeps it square next to a glyph whose
 * own box may not be.
 */
.mhub-am-blank__tile {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-bottom: 18px;
	border-radius: 16px;
	box-shadow: inset 0 0 0 1px rgba( 15, 23, 42, 0.08 );
}

/*
 * Brand tint for an invitation to create something; grey for the result of a
 * search or a filter.
 *
 * Not decoration. A brand-tinted tile over a filtered-to-nothing list reads as
 * an invitation to do something the controls underneath do not offer, which is
 * the specific way empty states mislead.
 *
 * The tint is #085DF2 at 9% over white, resolved rather than left to
 * `color-mix`, so it lands identically on every browser wp-admin still runs in.
 */
.mhub-am-blank.is-brand .mhub-am-blank__tile {
	background: #e9f0fe;
	color: var( --mhub-am-brand );
}

.mhub-am-blank.is-neutral .mhub-am-blank__tile {
	background: #f1f5f9;

	/*
	 * 3.15:1 on the tile. The #94a3b8 this held measured 2.34:1, and the glyph
	 * in an empty state is not decoration - it is the first mark the eye lands
	 * on and the only picture of what the state means, so it owes the 3:1 a
	 * meaningful graphic owes. This tone is what All Meetings shows whenever a
	 * search matches nothing, so the failure was on a screen people reach by
	 * typing, not an edge case.
	 */
	color: #7d8ba1;
}

/*
 * 20px, not DriveHub's 17px, and 600 rather than the 700 the first port used.
 *
 * 17px is right for the narrow column DriveHub's file browser empties into. All
 * Meetings empties into a panel 1372px wide, where 17px reads as a bold
 * sentence rather than a heading: 3.5px larger than the line below it, and
 * separated from it mainly by weight. 700 at this size stops reading as
 * emphasis and starts reading as a heavier typeface.
 *
 * The compact variant keeps 17px, because that one really is a small in-panel
 * state and should match DriveHub exactly.
 */
.mhub-am-blank__title {
	margin: 0;
	padding: 0;
	font-size: 20px;
	font-weight: 600;
	line-height: 1.25;
	letter-spacing: -0.02em;
	color: var( --mhub-am-ink );

	/* Evens the line lengths instead of filling the first and orphaning the
	   rest. On a centre axis every uneven line shows as an asymmetric gap on
	   both sides. */
	text-wrap: balance;
}

.mhub-am-blank__desc {
	margin: 10px 0 0;
	max-width: 46ch;
	font-size: 14px;
	line-height: 1.65;
	color: var( --mhub-am-ink-faint );
	text-wrap: balance;
}

.mhub-am-blank__controls {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	margin-top: 26px;
}

/*
 * The quiet line under everything. Small, but not small enough to escape AA:
 * slate-500 on white measures 4.76:1, and at 12.5px it is body text, not large
 * text, so 4.5 is the bar it has to clear.
 */
.mhub-am-blank__note {
	margin: 22px 0 0;
	max-width: 52ch;
	font-size: 12.5px;
	line-height: 1.6;
	color: var( --mhub-am-ink-faint );
	text-wrap: balance;
}

/*
 * The platform strip: five marks where three lines of prose used to be.
 *
 * The sentence it replaces named all five products and then explained one of
 * them, which made the footnote longer than the description and the button and
 * left the primary control with more text below it than above. A logo is read
 * faster than the word it stands for, so the same answer costs one line here.
 *
 * 20px, because these have to read as a capability note under the button rather
 * than as five more things to click. They are not links and never were.
 */
.mhub-am-blank__logos {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 16px;
}

.mhub-am-blank__logo {
	display: inline-flex;
}

/*
 * Every mark to one 20px box. The five arrive at five sizes and five aspect
 * ratios with their own width and height attributes; setting both here lets
 * preserveAspectRatio letterbox each inside the square rather than stretching
 * it, which is what makes a row of other companies logos sit level.
 *
 * Slightly held back, because full-strength brand colour five times over pulls
 * harder than the one blue button this state is asking you to press.
 */
.mhub-am-blank__logo svg {
	display: block;
	width: 20px;
	height: 20px;
	opacity: 0.8;
}

/* The in-panel variant: a filtered list that came back with nothing, sitting
   under a toolbar that already names the page. Smaller on every axis. */
.mhub-am-blank--inline {
	padding: 52px 24px 56px;
}

.mhub-am-blank--inline .mhub-am-blank__tile {
	width: 44px;
	height: 44px;
	margin-bottom: 14px;
	border-radius: 13px;
}

.mhub-am-blank--inline .mhub-am-blank__title {
	font-size: 17px;
	line-height: 1.3;
}

.mhub-am-blank--inline .mhub-am-blank__desc {
	margin-top: 8px;
	max-width: 44ch;
	font-size: 13.5px;
	line-height: 1.6;
}

.mhub-am-blank--inline .mhub-am-blank__controls {
	margin-top: 20px;
}

.mhub-am-pager {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	margin-top: 18px;
}

.mhub-am-pager__label {
	font-size: 13px;
	font-variant-numeric: tabular-nums;
	color: var( --mhub-am-ink-faint );
}

/* ------------------------------------------------------------ responsive - */

/*
 * Narrow desktop: the platform column drops to the width of its mark.
 *
 * There is nothing left to hide here - the name went from the row entirely -
 * so this is now only a column width. The rule it replaces hid the printed
 * name at this breakpoint, and before that two contradictory rules hid the
 * whole cell, throwing away the fastest thing to scan in the row for the sake
 * of about sixty pixels.
 *
 * The header word is hidden rather than the mark: "Platform" is wider than the
 * 34px column it labels, and a heading that cannot fit its own column is worse
 * than no heading. It stays in the accessibility tree, so the column is still
 * announced.
 */
@media ( max-width: 1200px ) {

	/* The grid used to be redeclared here. It is not any more: the table gained
	   a status column, and its breakpoint is at 1100px in "The table, laid out
	   around what a row actually contains" at the foot of this file. Two
	   declarations for one grid, in two places, is how the column count and the
	   cell count drift apart - which is exactly what had already happened to
	   this table once. */

	/* Three rules are gone from here, and all three were the icon-only platform
	   column's, left behind when the column gained a name beside the logo.
	
	   They hid the header's text with `font-size: 0`, sr-only'd a
	   `.mhub-am-head__label` span the markup has never contained, and centred the
	   cell. Together they gave this breakpoint a blank space where every other
	   column has a label, with the logos centred under it while "Meeting" ran
	   left and "Starts" ran right - three alignments across five columns.
	
	   The column is 96 to 132px here and "Platform" sets at 55px, so it fits with
	   room to spare. Nothing to hide. */
}

@media ( max-width: 782px ) {
	/*
	 * The stacked row used to be declared here, at 782px, and it is now at
	 * 760px with the rest of the table's breakpoints.
	 *
	 * Leaving it here left a 22-pixel band - 761px to 782px - in which this
	 * block hid the header and asked for three columns while the breakpoint
	 * below asked for six, against six cells. That band is where the row fell
	 * apart: the time and the menu each wrapped to a line of their own and the
	 * row grew to 113px.
	 *
	 * The idea was right and is kept, in one place. What stays in this block is
	 * only what is not the table's grid.
	 */

	.mhub-am-toolbar {
		align-items: stretch;
		flex-direction: column;
	}

	/*
	 * `overflow-x: auto` on its own did nothing here.
	 *
	 * The strip had `max-width: none`, so it simply grew to its content: 414px
	 * of tabs inside a 390px screen, measured with scrollWidth equal to
	 * clientWidth, which is the shape of a box that is not scrolling at all.
	 * The overflow ran out to the document instead and the whole admin page
	 * scrolled sideways.
	 *
	 * Bounding the width gives the overflow somewhere to happen. The tabs
	 * themselves stop shrinking at the same time, because a tab squeezed until
	 * its label wraps is worse than a strip you push sideways, and the count
	 * beside each label is what would have been crushed first.
	 */
	.mhub-am-tabs {
		max-width: 100%;
		overflow-x: auto;

		/* No scrollbar drawn over the tabs; the strip is short and the edge
		   of a cut-off tab is the affordance. */
		scrollbar-width: none;
	}

	.mhub-am-tabs::-webkit-scrollbar {
		display: none;
	}

	.mhub-am-tab {
		flex: none;
	}

	.mhub-am .mhub-am-search {
		width: 100%;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.mhub-am *,
	.mhub-am *::before,
	.mhub-am *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}

	.mhub-am .mhub-am-btn:active {
		transform: none;
	}
}

/* ------------------------------------------------------------- page frame - */

/*
 * The screen's own gutters.
 *
 * Measured in the browser: the "Add new" button's right edge and
 * `#wpbody-content`'s right edge were both at 1585px, meaning the primary
 * control on the page sat flush against the edge of the content area with no
 * gutter at all. The legacy `meeting.scss` padding that used to provide it
 * computes to 0 here, so the two blocks of this screen carry their own rather
 * than depending on a rule that no longer lands.
 *
 * A max-width as well, because a meeting list stretched across a 2560px monitor
 * puts the title and its time at opposite ends of the desk.
 */
.mhub-am-header,
.mhub-am {
	/* border-box, to match .mhub-uc-align: on content-box the cap measures
	   1420px plus two gutters and the page misses the band by one gutter. */
	box-sizing: border-box;
	max-width: 1420px;
	margin-left: auto;
	margin-right: auto;
	padding-left: var( --mhub-page-gutter, 24px );
	padding-right: var( --mhub-page-gutter, 24px );
}

.mhub-am-header {
	padding-top: 24px;
}

.mhub-am {
	padding-bottom: 40px;
}

/* ------------------------------------------ measured contrast and targets - */

/*
 * Four defects found by measuring the rendered page rather than by eye, and
 * corrected here so the reason stays attached to the fix.
 */

/* The count on an inactive tab measured 4.44:1 against the tab strip's fill at
   11.5px. `--mhub-am-ink-soft` measures 7.3:1 on the same ground. */
.mhub-am .mhub-am-tab__count {
	color: var( --mhub-am-ink-soft );
}

/* The row title is the main way into a meeting and measured 19px tall - only as
   tall as its own text. The row around it is 68px, so most of what looked
   clickable was not. */
.mhub-am .mhub-am-title {
	min-height: 30px;
}

.mhub-am .mhub-am-cell--check {
	display: flex;
	align-items: center;
	min-height: 34px;
}

/*
 * Every checkbox on the screen, not only the ones inside a cell with the class
 * - the select-all in the header row carries no class of its own and was
 * measured still sitting at wp-admin's 16px.
 *
 * 20px is as far as a native checkbox goes without replacing it with a styled
 * span, and replacing it would cost the platform's own focus ring, its
 * indeterminate state and its high-contrast-mode rendering. The row around it
 * is 68px, which is what the pointer actually has to hit.
 */
.mhub-am input[type='checkbox'] {
	width: 20px;
	height: 20px;
	margin: 0;
}

/* ============================================================================
 * DriveHub design-system alignment
 *
 * MeetingHub and DriveHub are the same product family and were reading as two
 * different admins. What is shared here is structural - the surface recipe, the
 * radii, the type scale, the header grammar - and not the colour: DriveHub is
 * #007A56 and MeetingHub stays #085DF2. Consistency between sibling plugins
 * means recognisably the same hand, not the same hue.
 *
 * Ported from drivehub/js-src/admin/src/components/common/surfaces.js and
 * components/layout/PageHeader.jsx.
 * ========================================================================== */

.mhub-am,
.mhub-am-header {
	/*
	 * The neutral ramp is Tailwind's slate, which is what DriveHub's admin is
	 * built on. MeetingHub's own values were a half-step off it at every stop -
	 * close enough to look like a mistake rather than a decision when the two
	 * plugins sit in one menu.
	 */
	--mhub-am-radius-panel: 14px;
	--mhub-am-radius-control: 10px;
	--mhub-am-radius-tile: 16px;

	/*
	 * The seated panel: tables, toolbars, sections. A hairline and one short
	 * shadow - surfaces that hold content rather than asking for a decision.
	 *
	 * The hairline is an *inset shadow*, not a border, which is DriveHub's
	 * choice and worth keeping for two reasons: a soft shadow alone goes mushy
	 * at the edge against a pale ground, and a real border would stack a second
	 * harder edge on top of the ramp. It also means the hairline costs no
	 * layout, so a panel's outer size is its content's size.
	 *
	 * Tinted with MeetingHub's ink rather than DriveHub's green-black, which is
	 * the one value in the recipe that should follow the brand.
	 */
	--mhub-am-panel-shadow:
		inset 0 0 0 1px rgba( 15, 23, 42, 0.07 ),
		0 1px 2px rgba( 15, 23, 42, 0.04 );
}

/*
 * Panels lose their border and take the inset hairline instead. Declared
 * together so no surface is left half-converted with both a border and a ring.
 */
.mhub-am-table,
.mhub-am-blank {
	border: 0;
	border-radius: var( --mhub-am-radius-panel );
	box-shadow: var( --mhub-am-panel-shadow );
}

/* `.mhub-am-now.is-live` went with the class. The strip only ever renders for
   a live meeting, so the state was a modifier on a component that has no other
   state - and the left bar carries it now. */

.mhub-am .mhub-am-btn,
.mhub-am-header .mhub-am-btn,
.mhub-am .mhub-am-search,
.mhub-am .mhub-am-btn--row {
	border-radius: var( --mhub-am-radius-control );
}

/* ------------------------------------------------------------ page header - */

/*
 * DriveHub's header sits on the page's own ground rather than in a card - the
 * title is the page speaking, and the panels below carry its content.
 */
.mhub-am-header__bar {
	align-items: flex-end;
	gap: 16px;
	padding-bottom: 4px;
}

.mhub-am-header__text {
	min-width: 0;
}

/* 22px, rising to 25px on a wide screen. DriveHub's exact scale; MeetingHub was
   a flat 26px, which read a size larger than the sibling product at every
   width. */
.mhub-am-header__title {
	font-size: 22px;
	letter-spacing: -0.02em;
	font-weight: 600;
	color: #0f172a;
}

@media ( min-width: 1536px ) {
	.mhub-am-header__title {
		font-size: 25px;
	}
}

/*
 * One line, truncated. A description that wraps stops being a description, the
 * title stops being the biggest thing in its own block, and the header's height
 * changes from screen to screen - which is what makes headers look like
 * different components on different pages.
 */
.mhub-am-header__desc {
	margin-top: 6px;
	max-width: 92ch;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: 13.5px;
	line-height: 1.6;
	color: #64748b;
}

.mhub-am-header__actions {
	align-items: center;
	gap: 8px;
}

/*
 * The utility band: help links on their own row, ranged right.
 *
 * Right rather than left because the alternative puts three quiet grey links
 * directly above the page title, where they read as a breadcrumb trail the page
 * does not have. Over the action corner they read as what they are - the
 * persistent utility strip an admin console carries above its content.
 *
 * The negative right margin pulls the last link's padding box past the page
 * gutter so its *label* lands on the same edge as the "Add new" button below
 * it. Aligning the padding box instead would leave the text visibly short of
 * the column, which is the usual reason a header's right edge looks ragged.
 */
.mhub-am-header__utility {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	flex-wrap: wrap;
	gap: 2px;
	margin-right: -10px;
	margin-bottom: 2px;
}

/* The band takes over the space the header used to open with, so the title
   sits at the same distance from the top of the screen as before. */
.mhub-am-header {
	padding-top: 12px;
}

.mhub-am-help,
.mhub-am-help:link,
.mhub-am-help:visited {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 36px;
	padding: 0 10px;
	border-radius: var( --mhub-am-radius-control );
	font-size: 13px;

	/* Pins the label's line box to the icon's height. Without it the label
	   inherits wp-admin's `body { line-height: 1.4em }`, computes to 18.2px,
	   and the anchor ends up taller than the thing inside it. */
	line-height: 15px;
	font-weight: 500;
	text-decoration: none;
	color: #475569;
	transition: background-color 150ms ease, color 150ms ease;
}

.mhub-am-help:hover,
.mhub-am-help:focus,
.mhub-am-help:focus-visible,
.mhub-am-help:active {
	background: #f1f5f9;
	color: #0f172a;
	text-decoration: none;
}

/*
 * The icon is a step lighter than its label and darkens with it, driven from
 * the anchor. Setting the colour on the icon instead is the bug DriveHub
 * documents: a `:hover` colour on a parent never reaches a child that declares
 * its own, so the two halves of one control come apart at exactly the moment
 * the pointer says they are one thing.
 *
 * `translate-y-px` is measured, not taste. A line box is not symmetrical around
 * its letters - the ascent reserves room above the caps - so a perfectly
 * centred box puts the visible word about 1px low. One pixel down on the icon
 * puts the two optical centres on the same line.
 */
.mhub-am-help__icon {
	display: inline-flex;
	align-items: center;
	color: #94a3b8;
	transform: translateY( 1px );
	transition: color 150ms ease;
}

.mhub-am-help:hover .mhub-am-help__icon,
.mhub-am-help:focus-visible .mhub-am-help__icon {
	color: #475569;
}

/*
 * The label folds away only when the utility row itself would wrap, which on
 * its own row is not until about 400px. The accessible name is carried
 * separately, so the control never becomes an unlabelled icon even then.
 *
 * This breakpoint was 1080px while the links shared a line with the title and
 * the page actions: five controls plus a heading ran out of width early, and
 * the labels were what gave way. Three words disappearing on a 15in laptop is
 * a real cost - "Docs" is the one word a stuck first-run user is scanning for -
 * and it was paid for a crowding problem the second row has now removed.
 */
@media ( max-width: 400px ) {
	.mhub-am-help__label {
		display: none;
	}

	.mhub-am-help {
		padding: 0 8px;
	}

	/*
	 * The icon darkens once the label is gone. At its resting slate-400 it
	 * measures 2.39:1 on the page ground - fine while it is decoration beside a
	 * word that carries the meaning at 7.07:1, and a genuine WCAG 1.4.11 failure
	 * the moment it becomes the only visible affordance. Slate-500 measures
	 * 4.4:1, clear of the 3:1 required of a meaningful graphic.
	 */
	.mhub-am-help__icon {
		color: #64748b;
	}
}

/* -------------------------------------------------------- segmented tabs - */

/* DriveHub's Segmented: a slate-100 trough, a white pill for the active tab
   carrying a 1px ring and a short shadow, counts in the brand colour when
   active and slate-400 when not. */
.mhub-am-tabs {
	border-radius: 12px;
	background: #f1f5f9;
}

.mhub-am-tab.is-active {
	box-shadow:
		0 1px 2px rgba( 15, 23, 42, 0.08 ),
		0 0 0 1px rgba( 15, 23, 42, 0.04 );
}

/*
 * Slate-500 steps up to slate-600 on the page ground.
 *
 * Measured after adopting DriveHub's ramp: #64748b clears AA on a white panel
 * at 4.76:1, but the two pieces of text that sit on the *page* rather than in a
 * panel land on slate-50 and measure 4.44:1 - under the 4.5 line. Slate-600 on
 * the same ground measures 7.1:1.
 *
 * Worth recording that this is inherited, not introduced: DriveHub's own
 * PageHeader description is `text-slate-500` on a `bg-slate-50` header, so the
 * same pair fails there. Flagged for that repo rather than fixed silently in
 * this one.
 */
.mhub-am-header__desc,
.mhub-am-pager__label {
	color: #475569;
}

/* ------------------------------------------------- figures: tone, trend - */


/* ============================================================================
 * The list, as a list of things rather than a spreadsheet
 *
 * Four changes, and only the first is structural:
 *
 *   - The platform mark leads the row on a tile instead of holding a column at
 *     the far right. Five columns become four.
 *   - The hover is a rounded panel inset from the edges, not a full-bleed band.
 *   - The header stops shouting: no fill, lighter weight.
 *   - The two exceptions a row can carry become chips instead of coloured words
 *     in a run of grey ones.
 * ========================================================================== */

/* The grid that used to be redeclared here is gone with the checkbox column it
   led with. Declared once, at the foot of this file. */

/* The second copy of the same stale grid, removed for the reason given at the
   first: the table's columns are declared once, at the foot of this file. */

/* --------------------------------------------------------------- the row - */

/*
 * The hover is a pseudo-element rather than the row's own background, so it can
 * be inset from the panel edge and rounded. A band that runs wall to wall is
 * the older idiom: it reads as a highlighted spreadsheet line, where a rounded
 * panel reads as the row being picked up.
 *
 * `isolation: isolate` gives the row its own stacking context so the -1 sits
 * behind the row's content and still in front of the panel underneath.
 */
.mhub-am-row {
	position: relative;
	isolation: isolate;
	min-height: 72px;
}

.mhub-am-row::before {
	content: '';
	position: absolute;
	inset: 4px 8px;
	z-index: -1;
	border-radius: 12px;
	background: transparent;
	transition: background-color 150ms ease;
}

/* Replaces the full-bleed hover fill, which would otherwise paint underneath
   and around the rounded one. */
.mhub-am .mhub-am-row:hover {
	background: transparent;
}

.mhub-am .mhub-am-row:hover::before {
	background: #f5f8fc;
}

/* A row with the menu open stays lit, so the panel does not appear to float
   over nothing once the pointer moves off the row to reach it. */
.mhub-am .mhub-am-row:has( .mhub-am-menu__toggle[aria-expanded='true'] )::before {
	background: #f5f8fc;
}

@media ( prefers-reduced-motion: reduce ) {
	.mhub-am-row::before {
		transition: none;
	}
}

/* ------------------------------------------------------------ the avatar - */

/*
 * 34px, 10px radius, a flat tint and a hairline ring - the same recipe as the
 * platform cards on Add New Meeting, one size down.
 *
 * The tile is doing real work, not decoration. The five marks are other
 * companies' logos: Teams is a 16x16 square, Webex is 22x16, Google Meet is
 * 51x43, and they carry their own colour at their own weight. Dropped straight
 * onto the row they sit at five different optical sizes on five different
 * baselines. A common surface is what makes a column of them read as one thing.
 */
.mhub-am-avatar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	flex: none;
	border-radius: 10px;
	background: #f6f8fc;
	box-shadow: inset 0 0 0 1px rgba( 15, 23, 42, 0.06 );
}

.mhub-am-avatar .mhub-am-mark {
	width: 19px;
	height: 19px;
}

/*
 * The tile no longer reports state, so the live ring it used to take is gone.
 * That argument was written when status was carried by colour alone; the status
 * column now says "Live" in a word, and the row still carries a green bar down
 * its edge. A ring here would be the third channel for one fact, on the element
 * whose only job is to say which app this runs on.
 */

/* --------------------------------------------------------- the main cell - */

.mhub-am .mhub-am-cell--main {
	flex-direction: row;
	align-items: center;
	gap: 12px;
}

.mhub-am-main__text {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-width: 0;
}

/* ---------------------------------------------------------- the exceptions - */

/*
 * A chip, not a coloured word.
 *
 * "no password" set in amber inside a run of grey text is a colour difference
 * doing all the work, which is exactly what fails for anyone who cannot see the
 * difference. A chip has an edge and a fill, so it separates by shape first and
 * colour second - and it is the thing on the row worth spotting from across the
 * desk.
 *
 * Sentence case, not lower: these read as labels now, and a label that starts
 * mid-sentence looks like a typo.
 */
.mhub-am-flag {
	display: inline-flex;
	align-items: center;
	padding: 2px 8px;
	border-radius: 999px;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.5;
	letter-spacing: 0.01em;
	background: var( --mhub-am-warn-tint );
	color: var( --mhub-am-warn );
}

.mhub-am-flag.is-clash {
	background: var( --mhub-am-bad-tint );
	color: var( --mhub-am-bad );
}

/* ------------------------------------------------------------- the header - */

/*
 * No fill, lighter weight, one shade back.
 *
 * The grey bar and the 700-weight uppercase were the loudest row in the table,
 * and it is the one row carrying no data. A column heading only has to be
 * findable when looked for, not read on the way past.
 */
.mhub-am-head {
	min-height: 38px;
	background: transparent;
	border-bottom: 1px solid var( --mhub-am-line-soft );
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.05em;

	/* Slate-500. Slate-400 is the colour this wants to be and measures 2.5:1,
	   which is not a heading, it is a suggestion of one. */
	color: var( --mhub-am-ink-faint );
}

/* ----------------------------------------------------------- the checkbox - */

/* The one line that modernises a native checkbox without replacing it, and so
   without giving up its focus ring, its indeterminate state or its
   high-contrast rendering. */
.mhub-am input[type='checkbox'] {
	accent-color: var( --mhub-am-brand );
}

/* ------------------------------------------- when: ranged right, near its row - */

/*
 * The date sits at the right, against the actions, rather than starting a
 * column of its own in the middle of the row.
 *
 * Removing the platform column handed its width to the title, which did not
 * need it - most meeting names are two or three words - so the gap between a
 * name and its date grew instead of shrinking. Ranging the date right closes
 * that gap from the other side: the eye reads the name at one edge and finds
 * everything else grouped at the other, instead of crossing an empty middle to
 * a date floating on its own.
 */
.mhub-am-cell--when {
	align-items: flex-end;
	text-align: right;
}

.mhub-am-head .mhub-am-cell--when {
	text-align: right;
}

/* ----------------------------------------------------- avatar: card, not fill - */

/*
 * White with a hairline, rather than a tinted fill.
 *
 * Zoom and Jitsi both ship a rounded blue square, and a tinted rounded square
 * behind one reads as a square inside a square. On white the tile stops being a
 * second shape and becomes the surface the mark sits on - and it separates from
 * the row on hover, when the row goes grey and the tile stays paper.
 */
.mhub-am-avatar {
	background: #ffffff;
	box-shadow: inset 0 0 0 1px rgba( 15, 23, 42, 0.09 );
}

/* An icon inside a button never shrinks. Flex would otherwise squeeze it before
   the label when the row runs short, which bends the glyph out of square. */
.mhub-am .mhub-am-btn > svg,
.mhub-am-header .mhub-am-btn > svg {
	flex: none;
}

/* ============================================================================
 * Picking, without a checkbox column
 *
 * The table opened with a column of empty boxes down its left edge - the first
 * thing the eye met on a screen whose job is "show me my meetings", answering a
 * question ("which of these do you want to delete?") that nobody asks on
 * arrival. It also cost 44px and a gutter on every screen, forever, to hold a
 * control most sessions never touch.
 *
 * The column is gone. The row's platform tile is now the row's checkbox: at
 * rest it is the logo, and under the pointer, under keyboard focus, or once
 * anything is picked, it becomes a box. One 34px square, two jobs, nothing
 * moving when it swaps - which is the whole reason the two are stacked in one
 * slot rather than placed side by side.
 * ========================================================================== */

/*
 * Four columns, matching the four cells the markup actually renders.
 *
 * This table's columns had been declared in four different places in this one
 * file, and only the last of them was doing anything. The rule near the top
 * still listed five tracks against four cells, which is what it looked like was
 * rendering when read on its own - but a later block overrode it with a correct
 * four-track grid, so the phantom column never actually reached the screen.
 *
 * That is the argument for one declaration rather than four: a stylesheet where
 * the rule you find is not the rule that applies will be read wrongly by the
 * next person, and was. The columns are now declared once, at the foot of this
 * file, and nowhere else.
 */

/* ------------------------------------------------------------- the slot -- */

/*
 * The tile-swap is gone, and with it the rule that caused the bug it left
 * behind.
 *
 * This is where the platform tile used to fade out on hover so a checkbox could
 * take its square. The markup for that was removed when the checkbox went back
 * to a slot of its own - but this rule was not, so every hovered row still blanked
 * its own platform logo and the column went empty exactly when it was pointed at.
 *
 * Deleting markup and leaving the CSS that drove it is how a fix becomes a
 * different bug. What stays below is only what the checkbox needs in its own
 * slot, and nothing that reaches across to the tile.
 */

/*
 * A picked row keeps its tint after the pointer has gone, because the box alone
 * is 20px of signal on a 72px row and a list of eight picked meetings has to be
 * readable at a glance rather than by inspecting eight small squares.
 *
 * Painted on the row's `::before`, not its background. This table stopped using
 * the row background for state when hover moved to an inset, rounded
 * pseudo-element - `.mhub-am .mhub-am-row:hover` is explicitly `transparent`
 * now - so a background here would be drawn wall to wall underneath the rounded
 * hover panel and read as a second, squarer highlight behind the first.
 */
.mhub-am .mhub-am-row.is-picked::before {
	background: var( --mhub-am-brand-tint );
}

.mhub-am .mhub-am-row.is-picked:hover::before {
	background: #e3ecfe;
}

/* ---------------------------------------------------------- the checkbox - */

/*
 * A drawn checkbox rather than the native one.
 *
 * An earlier note in this file argued for keeping `appearance: auto`, on the
 * grounds that replacing it costs the platform's focus ring, its indeterminate
 * state and its high-contrast rendering. Each of those is answered below rather
 * than ignored: `:focus-visible` draws a real ring, `:indeterminate` has its
 * own mark, and `forced-colors` hands the whole control back to the platform.
 * What is bought with that is a 6px-radius box in the plugin's own blue instead
 * of wp-admin's 1px grey square, which is the difference between a control that
 * belongs to this screen and one that was inherited from it.
 */
.mhub-am .mhub-am-box {
	appearance: none;
	-webkit-appearance: none;
	box-sizing: border-box;

	/* #8492a6 on white measures 3.16:1, which is what a control's boundary
	   needs. wp-admin's own #8c8f94 is 2.85:1 and misses it. */
	border: 1.5px solid #8492a6;
	border-radius: 6px;
	background: #fff;
	cursor: pointer;
}

.mhub-am .mhub-am-box:hover {
	border-color: #5a6b85;
	background: #f8fafc;
}

.mhub-am .mhub-am-box:checked,
.mhub-am .mhub-am-box:indeterminate {
	border-color: var( --mhub-am-brand );
	background-color: var( --mhub-am-brand );
}

/*
 * The tick, as a mask rather than a background image, so its colour is a
 * property and not baked into the data URI. White on #085df2 is 5.44:1.
 */
.mhub-am .mhub-am-box:checked::after,
.mhub-am .mhub-am-box:indeterminate::after {
	content: '';
	position: absolute;
	inset: 0;
	background-color: #fff;
}

.mhub-am .mhub-am-box:checked::after {
	-webkit-mask: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E" ) center / 15px 15px no-repeat;
	mask: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E" ) center / 15px 15px no-repeat;
}

/* Some but not all of the page is picked. The header's select-all is the only
   box that can reach this state, and a dash is the one mark people read as
   "partly" without being taught it. */
.mhub-am .mhub-am-box:indeterminate::after {
	-webkit-mask: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E" ) center / 15px 15px no-repeat;
	mask: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E" ) center / 15px 15px no-repeat;
}

/* Checked stays visible whether or not the row is hovered, or a picked row
   would appear to empty itself the moment the pointer left it. */
.mhub-am .mhub-am-box:checked,
.mhub-am .mhub-am-box:indeterminate,
.mhub-am .mhub-am-box:focus-visible {
	opacity: 1;
	transform: translate( -50%, -50% ) scale( 1 );
}

.mhub-am .mhub-am-box:focus-visible {
	outline: 2px solid var( --mhub-am-brand );
	outline-offset: 2px;
}

/*
 * The 20px box is the mark, not the target. The row is 68px tall and the slot
 * is 34px, so the hit area is the slot: Fitts's, on a control people click
 * repeatedly when they are deleting several meetings at once.
 */
.mhub-am .mhub-am-box::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 34px;
	height: 34px;
	transform: translate( -50%, -50% );
}


@media ( forced-colors: active ) {

	/*
	 * High contrast mode gets the platform's own checkbox back. A drawn control
	 * is drawn with colours the mode has deliberately overridden, so the mask
	 * and the fill both disappear and the box reads as empty whether or not it
	 * is ticked.
	 */
	.mhub-am .mhub-am-box {
		appearance: auto;
		-webkit-appearance: auto;
		opacity: 1;
		transform: none;
	}

	.mhub-am .mhub-am-box::after {
		display: none;
	}
}

@media ( prefers-reduced-motion: reduce ) {

	.mhub-am .mhub-am-box {
		transition: none;
	}
}

/* --------------------------------------------------------- no pointer --- */

/*
 * Without a pointer there is no hover, so a control that waits for one never
 * arrives. On a touch screen the box is simply always there, and the tile gives
 * up its square permanently rather than on a gesture that does not exist.
 *
 * The two grid breakpoints are edited in place above rather than restated here:
 * a rule appended at the end of this file would otherwise outrank the one
 * inside `@media ( max-width: 1200px )`, since a media query adds no
 * specificity and the later declaration wins.
 */
@media ( hover: none ) {

	.mhub-am .mhub-am-box {
		opacity: 1;
		transform: scale( 1 );
	}
}

/* ============================================================================
 * The row menu, and why it was painting underneath the rows below it
 *
 * Two separate faults, both visible at once as a dropdown with meeting rows
 * showing through it.
 *
 * 1. STACKING. `.mhub-am-row` carries `isolation: isolate`, which it needs so
 *    the hover pseudo-element at `z-index: -1` sits behind the row's own
 *    content instead of disappearing behind the panel. The cost is that every
 *    row becomes its own stacking context, and the menu's `z-index: 20` is then
 *    resolved *inside that row* rather than against the table. The row itself
 *    stayed at `z-index: auto`, so rows further down the DOM - painted later,
 *    at the same level - went straight over the top of it. Measured:
 *    `elementFromPoint` inside the open panel returned `DIV.mhub-am-row is-past`.
 *
 *    The fix is on the row, not the panel. No z-index on the panel can lift it
 *    out of a stacking context its own ancestor created; the ancestor has to
 *    rise instead.
 *
 * 2. CLIPPING. `.mhub-am-table` was `overflow: hidden`, to keep the head's fill
 *    and a live row's tint inside the panel's 14px corners. The menu on the
 *    last row opens downward and was measured running 145px past the table's
 *    bottom edge, so most of it was cut off - Delete included.
 *
 *    Clipping is now done by the two elements that actually have a fill to
 *    clip, which lets the table stop clipping its children altogether.
 * ========================================================================== */

.mhub-am-table {
	overflow: visible;
}

/* The head is the only child with a full-bleed fill at the top of the panel. */
.mhub-am-head {
	border-top-left-radius: var( --mhub-am-radius-panel );
	border-top-right-radius: var( --mhub-am-radius-panel );
}

/* And a live row is the only one with a full-bleed fill at the bottom - it
   still paints `#f6fbf9` plus an inset bar, which would square the corner it
   sits in. Applied to every last row rather than only the live one, so the rule
   does not have to be revisited the next time a row gains a background. */
.mhub-am-row:last-child {
	border-bottom-left-radius: var( --mhub-am-radius-panel );
	border-bottom-right-radius: var( --mhub-am-radius-panel );
}

/*
 * The open row outranks the rows after it.
 *
 * `:has()` on the toggle's own `aria-expanded`, which is the state the button
 * already publishes for assistive technology - so the styling and the
 * announcement cannot disagree. The same selector a few rules up keeps the row
 * lit while the menu is open, for the same reason.
 */
.mhub-am .mhub-am-row:has( .mhub-am-menu__toggle[aria-expanded='true'] ) {
	z-index: 3;
}

/* ============================================================================
 * The table, laid out around what a row actually contains
 *
 * The previous grid was `1fr 190px 104px`, and on a real list that produced a
 * ten-character title followed by roughly eight hundred pixels of nothing and
 * then a timestamp against the far edge. The layout had been designed for rows
 * carrying a webinar badge, a duration and two warning chips; most rows carry
 * none of those, so most rows were one short string alone in a very wide box.
 *
 * The answer is not a narrower column. It is that the row had things worth
 * saying and was not saying them - which platform it runs on was a picture
 * only, and its status was a pale tint only. Both are now words, in the space
 * that was empty.
 *
 * Written with Tailwind's `@apply` against the theme in tailwind.config.js for
 * anything that is a token, and plain declarations for geometry, matching the
 * approach in create-meeting.css. postcss-loader runs over this file.
 *
 * ---------------------------------------------------------------------------
 * The laws this leans on, and the move each one forces
 *
 *   Gestalt proximity  The platform name sits against the title, not in a
 *                      column of its own. Facts about one thing are read as one
 *                      thing when they are near each other, and as separate
 *                      things when they are not.
 *   Miller             Four zones - identity, status, when, actions - not the
 *                      seven columns this table used to carry. Four is inside
 *                      what anyone holds at a glance; seven is a form.
 *   Von Restorff       One saturated pill in the status column. If every state
 *                      were bright, the row that is happening right now would
 *                      not stand out from the four that are not.
 *   Fitts              Actions at a fixed right edge, so the pointer travels to
 *                      the same x on every row, and every target clears 44px.
 *   Hick               One action per row, and only when it exists: Join
 *                      appears on a live meeting and nowhere else.
 *   Jakob              It still reads as a table. The novelty is spent on the
 *                      checkbox that hides in the tile, and nowhere else.
 *   Doherty            Nothing transitions past 180ms.
 *   Aesthetic-usability
 *                      Tabular figures and a settled baseline grid are not
 *                      decoration: a column of times that does not align is a
 *                      column that has to be read rather than scanned.
 * ========================================================================== */

/*
 * meeting | status | when | actions
 *
 * The title is capped rather than elastic, and the actions cell takes the
 * slack. This is the fix for the defect that started this pass, and the first
 * attempt at it - adding the status column - did not touch it: measured
 * afterwards, the title track was still 836px holding an 82px title, leaving a
 * 724px hole between a meeting's name and its own status.
 *
 * The cause was `minmax( 0, 1fr )` on the title. A `1fr` title column hands all
 * the slack to the one column that is usually short, so the more room the
 * screen has, the further a meeting's facts are thrown from each other.
 *
 * Whitespace should separate things that are unrelated and get out of the way
 * between things that are not. Title, platform, status and time are four facts
 * about one meeting, so they pack together; the menu is a control rather than a
 * fact, so the gap falls in front of it, where the content genuinely ends.
 *
 * `460px` is the cap, not the width: the track is still `minmax`, so a long
 * title uses the room and a short one does not reserve it. Fitts is unharmed -
 * the actions cell is a fixed track that right-aligns its contents, so the menu
 * sits at the same x on every row.
 */
.mhub-am-head,
.mhub-am-row {
	/* The four-column grid this comment describes is gone: the table gained a
	   checkbox slot, a platform column and a type column in the pass below, and
	   the columns are declared there, once. The reasoning above is kept because
	   it is why the title is still capped rather than elastic. */
	gap: 16px;
	padding: 0 20px;
}

.mhub-am-head {
	min-height: 40px;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.07em;
	@apply mhub-text-slate-500;
}

/* The header sits over its column rather than beside it. A right-aligned
   heading above right-aligned figures is one edge; two alignments would read as
   two columns. */
.mhub-am-head .mhub-am-cell--when {
	text-align: right;
}

.mhub-am-row {
	min-height: 66px;
}

/* ------------------------------------------------------------- identity -- */

.mhub-am .mhub-am-cell--main {
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: 12px;
	min-width: 0;
}

.mhub-am-main__text {
	display: flex;
	flex-direction: column;
	gap: 1px;
	min-width: 0;
}

/*
 * The title is the row's own control - it opens the meeting - so it is the only
 * thing on the row set at full ink and weight. Everything else on the line is
 * support, and support that matches the thing it supports is noise.
 */
.mhub-am .mhub-am-title {
	display: block;
	width: 100%;
	min-height: 0;
	padding: 0;
	font-size: 14px;
	font-weight: 600;
	line-height: 20px;
	letter-spacing: -0.01em;
	text-align: left;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	@apply mhub-text-slate-900;
}

.mhub-am .mhub-am-title:hover {
	@apply mhub-text-brand;
}

.mhub-am .mhub-am-title:focus-visible {
	outline: 2px solid var( --mhub-am-brand );
	outline-offset: 3px;
	border-radius: 4px;
}

/*
 * The meta line. Slate-500 measures 4.76:1 on white, which clears AA for the
 * 12px it is set at - the obvious slate-400 is 2.94:1 and fails, and this line
 * is now the only place the platform's name is written.
 */
.mhub-am-sub {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px;
	font-size: 12px;
	line-height: 16px;
	@apply mhub-text-slate-500;
}

.mhub-am-sub__platform {
	font-weight: 500;
	@apply mhub-text-slate-600;
}

/* --------------------------------------------------------------- status -- */

/*
 * The status pill and its column were declared here.
 *
 * Removed with the column: four of its five states repeated the timestamp
 * beside them, and the fifth - Live - moved into the When cell as a caption.
 * The keyframes it used are kept below, because the live caption still breathes.
 */

@keyframes mhub-am-breathe {
	0% { opacity: 0.45; transform: scale( 0.6 ); }
	60%, 100% { opacity: 0; transform: scale( 2.2 ); }
}

/* ----------------------------------------------------------------- when -- */

.mhub-am .mhub-am-cell--when {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 1px;
	text-align: right;
}

/*
 * `tabular-nums` is the whole point of this column.
 *
 * Proportional digits put a 1 in less space than a 0, so "12:59 PM" and
 * "1:05 PM" do not line up and the column has to be read one row at a time.
 * Tabular figures give every digit the same advance, and the times stack into a
 * single edge that can be scanned in one pass.
 */
.mhub-am-when {
	font-size: 13px;
	font-weight: 500;
	line-height: 18px;
	font-variant-numeric: tabular-nums;
	font-feature-settings: 'tnum' 1;
	@apply mhub-text-slate-700;
}

/*
 * Slate-500, not slate-400.
 *
 * Slate-400 on white measures 2.56:1, and this is not decoration: it is the
 * cell's whole content on a row whose meeting has no date, and on Zoom Users it
 * is "Never signed in" and "Unknown", which are the two facts those columns
 * exist to report. AA asks 4.5:1 for text of any size; slate-500 measures 4.76
 * and is still two steps quieter than the slate-700 a real value is set in, so
 * the hierarchy the muted state was drawn for survives the fix.
 */
.mhub-am-when.is-muted {
	font-weight: 400;
	@apply mhub-text-slate-500;
}

.mhub-am-rel {
	font-size: 11.5px;
	line-height: 15px;
	font-variant-numeric: tabular-nums;
	@apply mhub-text-slate-500;
}

/* A past meeting's time recedes; it is still there to be read, never to be
   scanned for. Slate-500 is 4.76:1, so receding does not mean failing. */
.mhub-am-row.is-past .mhub-am-when {
	@apply mhub-text-slate-500;
}

/* -------------------------------------------------------------- actions -- */

.mhub-am .mhub-am-cell--actions {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 4px;
}

/*
 * The menu button only needs its transition here.
 *
 * This block used to hide it until the row was hovered, and further down the
 * file a later pass sets `opacity: 1` again with the better argument: the menu
 * is the only route to a meeting's shortcode, its link and its delete, and a
 * sole route should not have to be discovered by hovering. That rule wins on
 * order, so the hide here never applied to anything and the reveal rules under
 * it could not fire. Keeping dead declarations that contradict the live ones is
 * how the next person reads the file and believes the wrong thing.
 */
.mhub-am .mhub-am-menu__toggle {
	transition: opacity 150ms ease, background-color 150ms ease;
}

/* ------------------------------------------------------------- the rows -- */

/*
 * A past row is quieter, and quieter is the whole treatment - no tint, no bar.
 * The status column already says Done, and a greyed fill on top of the word
 * would be the same fact told twice in two channels.
 */
.mhub-am-row.is-past {
	background: transparent;
}

/*
 * A live row keeps its left edge but loses its fill.
 *
 * The fill, the bar, the ringed tile and the green relative caption were four
 * signals for one state. The pill replaced the caption; the fill goes here. The
 * bar stays because it is the only one findable while scrolling at speed, which
 * is what it is for.
 */
.mhub-am-row.is-live {
	background: transparent;
	box-shadow: none;
}

/*
 * A live row is tinted, not painted, and carries no bar.
 *
 * It had the full green tint plus `inset 3px 0 0` in solid green, directly
 * under a strip doing exactly the same thing - two slabs of one hue for one
 * fact, which is colour used as decoration rather than as information. At about
 * 4% the tint still finds the row while scrolling, and leaves the green dot
 * beside "Live now" as the thing actually being read.
 */
.mhub-am .mhub-am-row.is-live::before {
	background: rgba( 18, 128, 92, 0.045 );
}

.mhub-am .mhub-am-row.is-live:hover::before {
	background: rgba( 18, 128, 92, 0.075 );
}

/* Picked outranks live: one is what the meeting is doing, the other is what the
   reader is doing, and while picking, what the reader is doing is the subject. */
.mhub-am .mhub-am-row.is-picked.is-live::before {
	background: var( --mhub-am-brand-tint );
}

@media ( prefers-reduced-motion: reduce ) {

	.mhub-am .mhub-am-menu__toggle {
		animation: none;
		transition: none;
	}
}

/*
 * The three-column breakpoint from the first table pass has been removed.
 *
 * It hid the status column from 1100px down, which the second pass's own
 * breakpoints - 1200, 900, 760 - no longer expect. The two disagreed at 900px:
 * that rule declared six tracks while this one had already hidden a cell, so
 * one track sat empty and every column after it was drawn in the wrong place.
 *
 * Exactly the fault this file has now had three times, and always the same
 * cause: two rules describing one grid. The breakpoints live together, below.
 */

/* ============================================================================
 * The table, second pass: a checkbox of its own, and the columns the rows knew
 * about and would not print
 *
 * 1. THE CHECKBOX IS BACK IN ITS OWN SLOT. It spent a version inside the
 *    platform tile, swapping the logo out on hover. That saved a column and
 *    cost the column's whole purpose: the instant you reached for a row, the
 *    one mark telling you which app it runs on vanished under your pointer. A
 *    control should not be built out of the information sitting next to it.
 *
 *    It still hides at rest, which was the original ask. An empty 32px slot
 *    costs nothing to look at; a column of empty boxes is the first thing the
 *    eye meets.
 *
 * 2. THE ROW SAYS WHAT IT KNOWS. Platform was a logo with no name. Whether a
 *    thing was a meeting or a webinar was a chip that only appeared on
 *    webinars. Whether it repeats was not on the screen at all, though every
 *    platform form has had the field for years.
 *
 * Column count went from four to six, which is over the three-to-four this
 * table was held to before. That is a deliberate trade: Miller's limit is about
 * choices to make, and these are facts to read. A dense table that answers a
 * question in one pass beats a sparse one that sends you into a row to find out
 * what it is.
 * ========================================================================== */

/*
 * check | meeting | platform | type | starts | actions
 *
 * The slack moved out of the actions column and into the title.
 *
 * It used to sit the other way round - the title capped at 360px and the
 * actions cell holding `1fr` - on the reasoning that a fixed title keeps a
 * meeting's facts near each other. Measured at 1600px it produced the opposite:
 * the actions track resolved to 351px for content that needs 164, so every row
 * carried a 190px void before the menu, and a second 170px void between the
 * type chip and the start time. Two canyons through the middle of a row with
 * everything crushed against the two edges is what reads as an unfinished
 * layout rather than as a table.
 *
 * So the four middle columns are fixed at what their content actually measures
 * - Microsoft Teams is the widest platform name at 131px, `Webinar` the widest
 * chip at 62px, `Thu, Sep 3, 4:41 AM` the widest time at about 130px - the
 * actions cell is fixed at a Join button plus three icon targets, and the title
 * takes whatever is left. The page band is already capped at 1420px, so the
 * title cannot run away on an ultrawide monitor; at that cap it resolves to
 * 646px, which the longer meeting names use.
 *
 * This also makes the base grid agree with the 1200px breakpoint below, which
 * has always given the title `minmax( 0, 1fr )`. The two disagreeing was why
 * the row changed character at that boundary.
 */
.mhub-am-head,
.mhub-am-row {
	grid-template-columns:
		32px

		/*
		 * The title still takes the slack, but not all of it any more.
		 *
		 * At the 1420px band cap this track was resolving to about 720px, which
		 * is far more than any meeting name uses: the text ended and the rest of
		 * the column was empty, pushing platform, type and the start time out to
		 * the right where they read as a separate cluster rather than as facts
		 * about the meeting on their left. Capping it at 520px - comfortably
		 * past the longest title this screen has shown - brings the four columns
		 * after it back toward the middle, and the surplus goes to the actions
		 * track below, which now has controls to put in it.
		 */
		minmax( 200px, 520px )
		148px
		96px
		178px

		/*
		 * Takes the slack the title gave up, with a floor at what the controls
		 * actually measure: Join at 44, three 32px icon targets, and the 8px
		 * gaps between them, which is 188.
		 *
		 * It was 140px for a text button and a menu toggle. Copy link is on the
		 * row again, so there are four controls on a live row, and the cluster
		 * is right-aligned: any extra width lands as space between the start
		 * time and the buttons, which is the breathing room this cell was short
		 * of rather than a void it has to fill.
		 */
		minmax( 188px, 1fr );
	gap: 14px;
	padding: 0 18px;
}

/* ---------------------------------------------------------- the header --- */

/*
 * Sentence case at 12px, not 11px uppercase with letterspacing.
 *
 * Uppercase micro-caps are harder to read at exactly the size they are usually
 * set, because capitals lose the ascender and descender pattern that word
 * shapes are recognised by. At six columns that cost is paid six times. The
 * header is a label, and a label that has to be decoded is doing the opposite
 * of its job.
 */
.mhub-am-head {
	min-height: 42px;
	background: transparent;
	border-bottom: 1px solid var( --mhub-am-line );
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0;
	text-transform: none;
	@apply mhub-text-slate-500;
}

.mhub-am-head .mhub-am-cell--when {
	text-align: right;
}

/* ----------------------------------------------------------- the check --- */

/*
 * The slot is 32px and always there. Only the box inside it hides, so nothing
 * on the row moves when it appears - which is the one thing the tile version
 * did get right.
 */
.mhub-am .mhub-am-cell--check {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 32px;
}

/*
 * No width or height here on purpose.
 *
 * `.mhub-am input[type='checkbox']` further up sets 20px, and at (0,2,1) it
 * outranks this rule's (0,2,0) - so an 18px declared here was measured
 * rendering at 20px and was simply a lie in the source. 20px is the better
 * number anyway: it is as large as a native checkbox goes before it has to be
 * redrawn, and the 32px slot around it is the real target.
 */
.mhub-am .mhub-am-box {
	position: static;
	margin: 0;
	transform: scale( 0.9 );
	opacity: 0;
	transition: opacity 140ms ease, transform 140ms cubic-bezier( 0.2, 0.8, 0.3, 1.3 ),
		background-color 140ms ease, border-color 140ms ease;
}

.mhub-am-row:hover .mhub-am-box,
.mhub-am-row:focus-within .mhub-am-box,
.mhub-am-head:hover .mhub-am-box,
.mhub-am-head:focus-within .mhub-am-box,
.mhub-am-table.is-picking .mhub-am-box,
.mhub-am .mhub-am-box:checked,
.mhub-am .mhub-am-box:indeterminate,
.mhub-am .mhub-am-box:focus-visible {
	opacity: 1;
	transform: scale( 1 );
}

/* The 18px box is the mark; the 32px slot is the target. */
.mhub-am .mhub-am-box::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 32px;
	height: 32px;
	transform: translate( -50%, -50% );
}

.mhub-am .mhub-am-box {
	position: relative;
}

/* -------------------------------------------------------- the platform --- */

.mhub-am .mhub-am-cell--platform {
	display: flex;
	align-items: center;
	gap: 9px;
	min-width: 0;
}

/* 28px, down from 34px. The tile no longer has to be big enough to hold a
   checkbox, and beside a name it is a mark rather than the subject. */
.mhub-am-cell--platform .mhub-am-avatar {
	width: 28px;
	height: 28px;
	border-radius: 8px;
}

.mhub-am-cell--platform .mhub-am-avatar .mhub-am-mark {
	width: 16px;
	height: 16px;
}

/* Slate-700 on white measures 10.35:1. The name is the fact in this cell, so it
   is set at the weight of a fact and not of a caption. */
.mhub-am-platform__name {
	font-size: 13px;
	font-weight: 500;
	line-height: 18px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	@apply mhub-text-slate-700;
}

/* ------------------------------------------------------------ the type --- */

.mhub-am .mhub-am-cell--type {
	display: flex;
	align-items: center;
	gap: 6px;
	min-width: 0;
}

/*
 * Meeting and Webinar are the same shape as each other, which is the point: the
 * cell is read by its word, not by its colour. Only the webinar is tinted,
 * because it is the exception - if both were tinted the column would be two
 * colours of noise, and if neither were, the exception would not be findable.
 */
.mhub-am-kind {
	display: inline-flex;
	align-items: center;
	padding: 2px 8px;
	border-radius: 6px;
	font-size: 11.5px;
	font-weight: 600;
	line-height: 16px;
	white-space: nowrap;
	box-shadow: inset 0 0 0 1px var( --mhub-am-line );
	@apply mhub-text-slate-600;
}

/* #6D28D9 on #F3EEFE measures 6.87:1. Violet rather than the brand blue, so a
   webinar never reads as something that has been selected. */
.mhub-am-kind.is-webinar {
	background: #f3eefe;
	color: #6d28d9;
	box-shadow: inset 0 0 0 1px rgba( 109, 40, 217, 0.18 );
}

/*
 * The repeat glyph is gone.
 *
 * It sat beside the type chip at the size of a button, with no label, and read
 * as something to press - people were being invited to click a statement of
 * fact. It also only ever said "this repeats" and never how often.
 *
 * It is now words under the start time: see `.mhub-am-rel.is-repeat` below.
 */

/* ------------------------------------------------------------- the sub --- */

/* Only the duration and the two warnings are left down here. */
.mhub-am-sub__muted {
	@apply mhub-text-slate-400;
}

/* ---------------------------------------------------------- the actions --- */

/*
 * The menu button stops hiding.
 *
 * It was revealed on hover in the pass before this, on the same argument as the
 * checkbox. The argument does not hold as well here: the checkbox is one of a
 * column of identical controls and the menu is the only way to reach a
 * meeting's shortcode, its link and its delete. A control that is the sole
 * route to three actions should not require a person to discover that hovering
 * a row reveals it.
 *
 * It is quiet instead of hidden - slate-400 at rest, full ink on hover.
 */
.mhub-am .mhub-am-menu__toggle {
	opacity: 1;

	/* Slate-500, 4.76:1 on white. Slate-400 was measured at 2.56:1 here, which
	   misses the 3:1 an icon needs - and this icon is the only route to a row's
	   shortcode, its link and its delete. */
	@apply mhub-text-slate-500;
}

.mhub-am-row:hover .mhub-am-menu__toggle,
.mhub-am .mhub-am-menu__toggle:hover,
.mhub-am .mhub-am-menu__toggle:focus-visible,
.mhub-am .mhub-am-menu__toggle[aria-expanded='true'] {
	@apply mhub-text-slate-600;
}

/* ------------------------------------------------------- the narrow view - */

/*
 * Nothing folds away until it genuinely will not fit.
 *
 * The six columns need 32 + 180 + 132 + 104 + 104 + 150 + 84, plus six 14px
 * gaps and 36px of padding: about 906px. A 1280px laptop gives this admin
 * roughly 1100px of content, so every column survives the screen most people
 * are on. An earlier draft of this block started folding at 1400px, which would
 * have hidden the platform column - the thing this pass exists to add - on
 * nearly every laptop it shipped to.
 */
/* ----------------------------------------------------------------------------
 * The middle bands, sized from measurement rather than from arithmetic
 *
 * These were fixed pixel tracks, and a sweep from 1440px down to 700px found
 * the table overflowing its own panel at 1040px, 1000px and 920px. The cause is
 * not the viewport - it is that wp-admin's sidebar is 160px wide until 960px
 * and 36px below it, so the width this table actually gets does not fall
 * smoothly as the window narrows. It jumps: 792px of table at a 1040px window,
 * then 836px at 960px. No viewport breakpoint can predict that, which is why
 * fixed columns kept missing.
 *
 * So the middle band stops declaring widths it cannot guarantee. Every track is
 * a range: it takes the space it would like and gives it back rather than
 * pushing the row wider than the panel. Minimum total is 504px against a table
 * that is never narrower than 643px in this range, so the overflow cannot
 * return.
 *
 * Type is dropped here rather than lower down. It is the column whose value is
 * the same on almost every row, so it is the one whose absence costs least.
 * -------------------------------------------------------------------------- */

@media ( max-width: 1200px ) {

	/*
	 * The actions track is a fixed 164px, not `minmax( 72px, auto )`.
	 *
	 * Each row is its own grid container - that is what lets a row carry a hover
	 * panel and a divider of its own - so a content-sized track resolves against
	 * that row's content and nothing else. The header's actions cell holds only
	 * a screen-reader label, so its `auto` measured near zero and collapsed to
	 * the 72px floor, while a row holding a Join button and three icons measured
	 * 160. Every column in the header therefore sat 88px to the right of the
	 * column it labelled: "Starts" over the gap after the times, "Platform" over
	 * the gap after the logos.
	 *
	 * No content-sized track can appear in this grid for that reason. 164px is
	 * what the row actually needs - a Join button, three 32px icon targets and
	 * the 6px gaps between them - and it is the same number the wide layout uses,
	 * so the actions column does not move across the breakpoint either.
	 */
	.mhub-am-head,
	.mhub-am-row {
		grid-template-columns:
			32px
			minmax( 0, 1fr )
			minmax( 96px, 132px )
			minmax( 140px, 176px )

			/* The same 188px floor as the wide layout, so the actions cluster
			   does not change size across this boundary now that it holds four
			   controls rather than two. */
			188px;
		gap: 12px;
	}

	.mhub-am-head .mhub-am-cell--type,
	.mhub-am-row .mhub-am-cell--type {
		display: none;
	}

	.mhub-am-platform__name {
		font-size: 12.5px;
	}
}

/* ----------------------------------------------------------------------------
 * Narrow: one deliberate stacked row, not two half-designs fighting
 *
 * This is what was breaking. An older block further up already had a narrow
 * design - hide the header, drop the row to `32px minmax( 0, 1fr ) auto`, let
 * the time wrap under the title - and this breakpoint had been written as if
 * that did not exist, declaring four tracks for the same rows. The two disagreed
 * on how many columns there were, so the time and the menu each wrapped onto a
 * line of their own and the row grew to 113px of mostly nothing.
 *
 * The older design was the right one; it just was not finished. Placement is
 * explicit now, by area, so the number of columns and the number of cells
 * cannot drift apart again the way they have repeatedly in this file.
 * -------------------------------------------------------------------------- */

@media ( max-width: 860px ) {

	.mhub-am-row {
		grid-template-columns: 32px minmax( 0, 1fr ) auto;
		grid-template-areas:
			'check main   actions'
			'.     when   actions';
		row-gap: 2px;
		min-height: 76px;
	}

	.mhub-am-row .mhub-am-cell--check {
		grid-area: check;
		align-self: start;
		margin-top: 2px;
	}

	.mhub-am-row .mhub-am-cell--main {
		grid-area: main;
	}

	/*
	 * The time moves under the title and reads left-to-right with it. Kept
	 * right-aligned it would sit against the menu on a second line, which is
	 * where the eye has no reason to look.
	 */
	.mhub-am-row .mhub-am-cell--when {
		grid-area: when;
		flex-direction: row;
		align-items: baseline;
		justify-content: flex-start;
		gap: 8px;
		text-align: left;
	}

	.mhub-am-row .mhub-am-cell--actions {
		grid-area: actions;
		align-self: center;
	}

	/*
	 * Copy link goes; edit, the menu and Join stay.
	 *
	 * The actions column is `auto` here, so every control in it is taken out of
	 * the title's width. With three of them plus Join the title fell to about
	 * six characters - "[QA] Li..." - and a row whose whole job is naming a
	 * meeting stopped naming it. The buttons were wider than the thing they act
	 * on, which inverts the row.
	 *
	 * Copy is the one to drop rather than an arbitrary third, on the same
	 * reasoning the Zoom Users list already uses: it puts a URL on a clipboard,
	 * and the places that URL is pasted are desktop work. Edit and the menu are
	 * the two that make sense with a thumb, and the menu still carries the link
	 * for anyone who wants it here. Join is never dropped: it is the only
	 * urgent thing on the row and it appears on almost none of them.
	 */
	.mhub-am-row .mhub-am-cell--actions .mhub-am-btn--icon:first-of-type {
		display: none;
	}

	/* Nothing is reserving Join's width once the row is this narrow: the column
	   is content-sized, so a hidden placeholder would only take the title's
	   space back again for no alignment gain. */
	.mhub-am-row .mhub-am-join-slot {
		display: none;
	}

	/* Platform, type and status have no room, and each is one tap away in the
	   meeting itself. The header goes with them - a column label with no column
	   under it is just a word. */
	.mhub-am-head,
	.mhub-am-row .mhub-am-cell--platform,
	.mhub-am-row .mhub-am-cell--type {
		display: none;
	}
}

/* ----------------------------------------------------------------------------
 * The same two breakpoints, keyed to the container instead of the viewport.
 *
 * `.meeting-dashboard` is a `container-type: inline-size` context (declared up
 * by `.mhub-am-table`). In wp-admin its width and the viewport fall together,
 * so these add nothing there. Inside a vendor / LMS dashboard the viewport is
 * wide but this element is ~820-880px, so only these fire - and they carry the
 * exact column sets the viewport versions above use, so the layout matches
 * whichever way it is reached.
 *
 * Container-query units are avoided; the values are the same literals as above.
 * -------------------------------------------------------------------------- */

@container mhub-am ( max-width: 1200px ) {

	.mhub-am-head,
	.mhub-am-row {
		grid-template-columns:
			32px
			minmax( 0, 1fr )
			minmax( 96px, 132px )
			minmax( 140px, 176px )
			188px;
		gap: 12px;
	}

	.mhub-am-head .mhub-am-cell--type,
	.mhub-am-row .mhub-am-cell--type {
		display: none;
	}

	.mhub-am-platform__name {
		font-size: 12.5px;
	}
}

@container mhub-am ( max-width: 860px ) {

	.mhub-am-row {
		grid-template-columns: 32px minmax( 0, 1fr ) auto;
		grid-template-areas:
			'check main   actions'
			'.     when   actions';
		row-gap: 2px;
		min-height: 76px;
	}

	.mhub-am-row .mhub-am-cell--check {
		grid-area: check;
		align-self: start;
		margin-top: 2px;
	}

	.mhub-am-row .mhub-am-cell--main {
		grid-area: main;
	}

	.mhub-am-row .mhub-am-cell--when {
		grid-area: when;
		flex-direction: row;
		align-items: baseline;
		justify-content: flex-start;
		gap: 8px;
		text-align: left;
	}

	.mhub-am-row .mhub-am-cell--actions {
		grid-area: actions;
		align-self: center;
	}

	.mhub-am-row .mhub-am-cell--actions .mhub-am-btn--icon:first-of-type {
		display: none;
	}

	.mhub-am-row .mhub-am-join-slot {
		display: none;
	}

	.mhub-am-head,
	.mhub-am-row .mhub-am-cell--platform,
	.mhub-am-row .mhub-am-cell--type {
		display: none;
	}
}

/* ============================================================================
 * The dividers, and why there appeared to be so many
 *
 * They were never dark - `--mhub-am-line-soft` is #f1f5f9, a hairline at
 * 1.06:1. What made them read as a stack of rules was that they disagreed with
 * the row they were separating: the border ran wall to wall while the hover
 * panel is inset 8px and rounded 12px, so a hovered row was a rounded card with
 * two straight lines cutting across its ends. Two geometries in one list is
 * what registers as clutter, not the number of lines.
 *
 * So the line stops being a border and becomes a pseudo-element on the same
 * inset as the panel. It then also gets to disappear where a border cannot:
 *
 *   - on the hovered row, so the panel's own edge is the only edge, and
 *   - on the row directly above it, using `:has( + ... )`, because otherwise a
 *     rule sits tight against the panel's rounded top corner and reads as a
 *     seam. This is the detail that separates a list that looks designed from
 *     one that looks ruled.
 *
 * Same for a picked row, for the same reason.
 * ========================================================================== */

.mhub-am-row {
	border-bottom: 0;
}

.mhub-am-row::after {
	content: '';
	position: absolute;
	right: 8px;
	bottom: 0;
	left: 8px;
	height: 1px;

	/* A touch above slate-100, so it is still a hairline once it is only 1300px
	   long instead of the full panel width. */
	background: #edf1f6;
	transition: opacity 150ms ease;
}

.mhub-am-row:last-child::after,
.mhub-am-row:hover::after,
.mhub-am-row:focus-within::after,
.mhub-am-row.is-picked::after,
.mhub-am-row:has( + .mhub-am-row:hover )::after,
.mhub-am-row:has( + .mhub-am-row:focus-within )::after,
.mhub-am-row:has( + .mhub-am-row.is-picked )::after {
	opacity: 0;
}

/*
 * The header's rule is the one line that stays, and it stays full width.
 *
 * It is not separating two rows, it is separating the labels from the data -
 * a different job, and the only place in this list where a hard edge is the
 * right answer. Keeping it full-bleed is what makes the inset row lines below
 * read as a lighter rank rather than as the same line drawn badly.
 */
.mhub-am-head {
	border-bottom: 1px solid var( --mhub-am-line );
}

/* A little more air per row, now that nothing is drawing a boundary for free. */
.mhub-am-row {
	min-height: 70px;
}

@media ( prefers-reduced-motion: reduce ) {

	.mhub-am-row::after {
		transition: none;
	}
}

/* ============================================================================
 * wp-admin was drawing its own tick inside ours
 *
 * WordPress ships this, and it is not optional on any admin screen:
 *
 *   input[type=checkbox]:checked::before      { content: url( <tick svg> ); }
 *   input[type=checkbox]:indeterminate::before { content: url( <dash svg> ); }
 *
 * That selector measures (0,2,2). The rule that was meant to own this
 * pseudo-element, `.mhub-am .mhub-am-box::before`, measures (0,2,1) - fewer
 * element-level parts - so wp-admin won and `content: ''` never applied.
 *
 * Two consequences, both visible: a replaced pseudo-element sizes to its own
 * content, so the 32px hit area became a 21px image and stopped being a hit
 * area; and wp-admin's tick was painted on top of the one this file draws in
 * `::after`, at a size and shape that matched neither the box nor the row
 * checkboxes. The select-all in the header was the worst of it - a 28px glyph
 * where its column expects a 20px square.
 *
 * The fix is specificity, not `!important`: adding the class alongside the
 * attribute makes this (0,3,2), which outranks wp-admin without taking the
 * pseudo-element away from anything else that may want it later.
 * ========================================================================== */

.mhub-am input[type='checkbox'].mhub-am-box::before,
.mhub-am input[type='checkbox'].mhub-am-box:checked::before,
.mhub-am input[type='checkbox'].mhub-am-box:indeterminate::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 32px;
	height: 32px;
	margin: 0;
	padding: 0;
	transform: translate( -50%, -50% );

	/* wp-admin sets a font and a size on this pseudo-element for its dashicon
	   variant. Neither matters once the content is empty, but leaving them
	   would make the box's height depend on a line box it never uses. */
	font: inherit;
	line-height: 0;
	background: none;
}

/*
 * The mark this file does draw, restated at the same weight so it cannot lose
 * to wp-admin either. `::after` is not contested today; it is matched here so
 * the two halves of one control are declared at one specificity.
 */
.mhub-am input[type='checkbox'].mhub-am-box:checked::after,
.mhub-am input[type='checkbox'].mhub-am-box:indeterminate::after {
	content: '';
	position: absolute;
	inset: 0;
	background-color: #fff;
}

/*
 * And the box itself, so the header's select-all and a row's checkbox are the
 * same object. wp-admin sets `width`, `height`, `min-width` and `border-radius`
 * on `input[type=checkbox]` at (0,1,1); this is (0,3,1).
 */
.mhub-am input[type='checkbox'].mhub-am-box {
	width: 20px;
	height: 20px;
	min-width: 20px;
	border-radius: 6px;
}

/* ============================================================================
 * The divider starts where the content starts
 *
 * It ran from 8px to 8px - the panel's own edge, near enough - which made it
 * the widest line on the screen and gave it no relationship to anything in the
 * row it was separating.
 *
 * It now begins at the title's left edge and ends at the content's right edge:
 * measured, 64px in from the row and 18px in from the right. The checkbox slot
 * sits outside it, which is the point - the line separates two meetings, and
 * the control for picking them is not part of either.
 *
 * This is the older inset-divider idiom, and it reads as shorter without
 * reading as broken, because both of its ends now land on something: the title
 * above it, and the menu button beside it.
 *
 * The inset is a custom property rather than a repeated literal because it is
 * derived from three values that change at the breakpoint - the row's padding,
 * the checkbox track, and the column gap. Written out, it would be one more
 * number that drifts when one of those moves.
 * ========================================================================== */

.mhub-am-head,
.mhub-am-row {
	/* 18px padding + 32px checkbox track + 14px gap. */
	--mhub-am-line-inset: 64px;
}

.mhub-am-row::after {
	left: var( --mhub-am-line-inset );
	right: 18px;
}

@media ( max-width: 1200px ) {

	.mhub-am-head,
	.mhub-am-row {
		/* The gap tightens to 12px here, so the content starts 2px earlier. */
		--mhub-am-line-inset: 62px;
	}
}

/* ============================================================================
 * "Add new" joins the toolbar
 *
 * It had a row of its own in the header while search and the platform filter
 * had another, with the tab strip between them - three controls acting on one
 * list, spread over two lines. They are one group now, right-aligned, and the
 * page is one row shorter.
 *
 * No new sizing: `.mhub-am-btn`, `.mhub-am-search` and the platform filter were
 * already 40px on the same radius, so they sit on one baseline without being
 * told to.
 * ========================================================================== */

/*
 * The tabs take the slack so the three controls stay against the right edge,
 * and the toolbar keeps a floor under it: below that the group wraps rather
 * than crushing the search field, which is what `flex-wrap` on `.mhub-am-tools`
 * is already there for.
 */
.mhub-am-toolbar {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
}

/*
 * `0 1 auto`, not `1 1 auto`. The tab strip carries its own tinted pill, so
 * letting it grow stretched that pill 300px past its last tab and made the
 * group look like an empty input. The toolbar's own `space-between` is what
 * holds the two apart; the tabs only need to be allowed to shrink.
 */
.mhub-am-toolbar .mhub-am-tabs {
	flex: 0 1 auto;
	min-width: 0;
}

/*
 * No `margin-left: auto` here, and that is the whole rule.
 *
 * It did the same job as the toolbar's `space-between` while the two groups fit
 * on one line, and the wrong job the moment they did not: below about 1150px
 * the tools wrap to a line of their own, and the auto margin pinned them to the
 * far right of an otherwise empty line, 300px from the tabs they belong beside.
 * `space-between` puts a lone item at the start of its line, so the group stays
 * together when it wraps and still splits when it fits.
 */
.mhub-am-toolbar .mhub-am-tools {
	flex: 0 0 auto;
}

/* The one filled control in the group, so it still reads as the primary action
   rather than as a third filter sitting beside two hollow ones. */
.mhub-am .mhub-am-tools__add {
	flex: none;
}

@media ( max-width: 782px ) {

	/* Stacked, the button goes full width like the field above it. */
	.mhub-am-toolbar .mhub-am-tools {
		margin-left: 0;
		width: 100%;
	}

	.mhub-am .mhub-am-tools__add {
		justify-content: center;
		width: 100%;
	}
}

/* ============================================================================
 * The row's own actions, out of the menu
 *
 * Copy link and View page were both three interactions deep - find the dots,
 * open the menu, read four labels, choose - for the two things people do to a
 * row most. They are buttons now. Copy shortcode and Delete stayed behind, the
 * first because embedding is occasional and deliberate, the second because a
 * destructive control sitting on the row is one slip from a mistake.
 *
 * Quiet by default and never hidden. These are not the row's subject, so they
 * sit at slate-500 and take ink on hover; but a control that only exists once
 * the pointer finds it is a control people do not know they have, and that was
 * the argument for bringing them out of the menu in the first place.
 * ========================================================================== */

.mhub-am .mhub-am-iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	flex: none;
	padding: 0;
	border: 0;
	border-radius: 9px;
	background: transparent;

	/* Slate-500, 4.76:1 on white - an icon needs 3:1, and these are the only
	   label these controls have on screen. */
	@apply mhub-text-slate-500;

	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}

.mhub-am .mhub-am-iconbtn:link,
.mhub-am .mhub-am-iconbtn:visited {
	@apply mhub-text-slate-500;

	text-decoration: none;
}

/*
 * Re-declared on every state, `a` included. wp-admin ships
 * `a:hover, a:focus { color: <scheme blue> }` at (0,1,1), which would otherwise
 * repaint the View link on hover and leave the two buttons a different colour
 * from each other mid-gesture.
 */
.mhub-am .mhub-am-iconbtn:hover,
.mhub-am .mhub-am-iconbtn:focus,
.mhub-am .mhub-am-iconbtn:focus-visible,
.mhub-am .mhub-am-iconbtn:active {
	background: rgba( 15, 23, 42, 0.06 );

	/* Slate-700, 10.35:1. */
	@apply mhub-text-slate-700;

	text-decoration: none;
	box-shadow: none;
}

.mhub-am .mhub-am-iconbtn:focus-visible {
	outline: 2px solid var( --mhub-am-brand );
	outline-offset: 2px;
}

.mhub-am .mhub-am-iconbtn:active {
	background: rgba( 15, 23, 42, 0.1 );
}

/*
 * The 34px face sits inside a 44px target. Peak-end: the copy confirms in the
 * mark itself - the chain becomes a tick and the tooltip becomes "Link copied"
 * - rather than in a toast that appears somewhere else on the screen.
 */
.mhub-am .mhub-am-iconbtn::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 44px;
	height: 44px;
	transform: translate( -50%, -50% );
}

.mhub-am .mhub-am-iconbtn {
	position: relative;
}

.mhub-am .mhub-am-iconbtn.is-done,
.mhub-am .mhub-am-iconbtn.is-done:hover {
	background: var( --mhub-am-good-tint );

	/* #0B6B4B on #E6F6F0 measures 5.84:1. */
	color: #0b6b4b;
}

/*
 * The actions cell holds three controls, so it needs its own rhythm rather than
 * the row's 14px column gap.
 *
 * It was 2px, which is not a gap so much as the absence of one: Join, Edit and
 * the dots read as a single blob of controls, and on a live row that blob was
 * 151px of content in a 140px column, so it broke out past the column's own
 * left edge. 8px separates them without spending the width the column has.
 */
.mhub-am .mhub-am-cell--actions {
	gap: 8px;
}

/*
 * The reserved Join slot.
 *
 * Takes exactly the width the real button takes, in whatever language, and
 * nothing else: no paint, no pointer, no place in the accessibility tree or the
 * tab order. It exists so Edit and the dots hold still while you read down the
 * column.
 */
.mhub-am .mhub-am-join-slot {
	visibility: hidden;
	pointer-events: none;
}

/*
 * Edit, with the pencil carrying the meaning on its own.
 *
 * Square, so it sits with the dots button beside it rather than reading as a
 * third, wider shape. The 44px target the row buttons already buy with an
 * ::after covers the height; this covers the width, which a 32px square would
 * otherwise leave 12px short.
 */
.mhub-am .mhub-am-btn--icon {
	width: 32px;
	min-width: 32px;
	padding: 0;
}

.mhub-am .mhub-am-btn--icon::after {
	inset: -6px;
}

/*
 * Copy link, for the moment after it worked.
 *
 * The tick replaces the chain and the colour goes green, because a copy leaves
 * nothing else behind: the clipboard changed and the screen did not, which is
 * the case where a control most needs to say it did something. It holds the
 * hover colours off for the second and a half it lasts, or moving the pointer
 * away and back would repaint it blue and undo the confirmation.
 *
 * #0B6B4B on white measures 6.9:1, and the same green the Live pill uses.
 */
.mhub-am .mhub-am-btn--icon.is-copied,
.mhub-am .mhub-am-btn--icon.is-copied:hover,
.mhub-am .mhub-am-btn--icon.is-copied:focus-visible {
	background: #e6f6f0;
	color: #0b6b4b;
}

@media ( prefers-reduced-motion: reduce ) {

	.mhub-am .mhub-am-iconbtn {
		transition: none;
	}
}

/* ============================================================================
 * "Repeats weekly", where the relative caption used to go
 *
 * Set one step firmer than a plain relative label - slate-600 at 500 rather
 * than slate-500 at 400 - because it is a property of the meeting rather than
 * a restatement of the date above it, and because it is now the only place the
 * fact appears. Still type, not a chip and not a control: the complaint that
 * started this was a mark that looked pressable, and a badge with a border
 * would have been the same mistake in a different shape.
 * ========================================================================== */

.mhub-am .mhub-am-rel.is-repeat {
	font-weight: 500;

	/* Slate-600, 7.58:1 on white. */
	@apply mhub-text-slate-600;
}

/* On a past row everything recedes together, so the cadence does not end up
   the loudest thing left on a meeting that already happened. */
.mhub-am .mhub-am-row.is-past .mhub-am-rel.is-repeat {
	font-weight: 400;
	@apply mhub-text-slate-500;
}

/* ============================================================================
 * Live, as the caption it always should have been
 *
 * Status and Starts were two columns that agreed with each other. "Today" sat
 * beside "Today, 8:41 AM"; "Done" sat beside a date six days past; "Upcoming"
 * sat beside "Tomorrow". Four of the five pills were the timestamp restated in
 * a rounded box, spending 130px of every screen to do it.
 *
 * "Live" was the exception, and it is the exception for a reason worth keeping:
 * running *now* cannot be read off a start time alone, it needs the duration
 * too. So it stays - not as a column, but as the caption under the time it
 * qualifies, where the eye is already looking.
 *
 * Von Restorff, but earned rather than decorated: there is now exactly one
 * coloured thing in this column, and it is the one row you might have to do
 * something about in the next few minutes.
 * ========================================================================== */

.mhub-am .mhub-am-rel.is-live {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-weight: 600;

	/* #0B6B4B on the row's own live tint measures 5.84:1, and 6.99:1 on white
	   for the moment before the row tint paints. */
	color: #0b6b4b;
}

.mhub-am .mhub-am-rel__dot {
	position: relative;
	width: 6px;
	height: 6px;
	flex: none;
	border-radius: 50%;
	background: currentColor;
}

/*
 * The one animated thing left in the table. Four seconds reads as a pulse;
 * quicker reads as a blink and pulls the eye off whatever is being read.
 */
.mhub-am .mhub-am-rel__dot::after {
	content: '';
	position: absolute;
	inset: -3px;
	border-radius: 50%;
	background: currentColor;
	opacity: 0.45;
	animation: mhub-am-breathe 4s ease-out infinite;
}

@media ( prefers-reduced-motion: reduce ) {

	.mhub-am .mhub-am-rel__dot::after {
		animation: none;
	}
}

/* ============================================================================
 * Vertical rhythm: which things belong together
 *
 * Measured on the rendered page, the stack read as:
 *
 *   header bottom  168
 *   live strip     188 - 260     20px below the header
 *   toolbar        260 - 302      0px below the strip
 *   table          316 - 918     14px below the toolbar
 *
 * Zero. The live card's bottom edge and the tab strip's top edge were the same
 * pixel, so a white panel with rounded bottom corners sat flush against a
 * slate-100 pill with rounded top corners and the two corners cut into each
 * other. That is what "overlapping" was.
 *
 * The grouping was also inverted. The tabs, the search field and the platform
 * select all act on the table; the live card is a separate object that happens
 * to be above them. With no gap above and 14px below, proximity said the
 * opposite - the toolbar looked welded to the card and detached from the list
 * it filters. Gestalt does not care what the markup nests.
 *
 * So the space above the toolbar is now larger than the space below it, and the
 * two gaps are set from the same pair of values rather than from whichever
 * margin happened to be written first.
 * ========================================================================== */

.mhub-am {
	/* Between separate objects, and inside one group. */
	--mhub-am-gap-block: 24px;
	--mhub-am-gap-tight: 12px;
}

/*
 * The strip carries the gap below itself rather than the toolbar carrying one
 * above, so that when nothing is live and `LiveNow` renders nothing at all, the
 * space goes with it instead of leaving a hole under the page header.
 */
.mhub-am .mhub-am-live {
	margin-bottom: var( --mhub-am-gap-block );
}

.mhub-am .mhub-am-toolbar {
	margin-bottom: var( --mhub-am-gap-tight );
}

/* --------------------------------------------------------- search icon --- */

/*
 * A magnifier in the search field.
 *
 * A background image rather than an element beside the input, because the
 * toolbar row is a flex line and wrapping the field in a positioned box would
 * change how it shares that line with the platform filter next to it. The icon
 * is decorative: the placeholder and the `aria-label` already say what the
 * field is, so nothing is lost by it being unreachable.
 *
 * slate-400 at 16px, sitting 12px in, with the text pushed to 36px so the two
 * never touch. It does not brighten on focus - the border already does that,
 * and a second thing changing at the same moment reads as a flicker.
 */
.mhub-am .mhub-am-search {
	padding-left: 36px;
	background-image: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: left 12px center;
}

/* The field is `type="search"`, and WebKit reserves room on the right for its
   own clear button. Left padding is ours; this keeps the right side honest. */
.mhub-am .mhub-am-search::-webkit-search-cancel-button {
	cursor: pointer;
}

@media ( max-width: 782px ) {

	.mhub-am .mhub-am-search {
		background-position: left 10px center;
		padding-left: 32px;
	}
}
