/*
 * The satellite page — search above, chart below.
 *
 * Colours come from the platform's tokens (mena-theme.css) with light-theme
 * fallbacks, so the guide follows the site's light/dark switch instead of
 * assuming the dark palette the tables were first written against.
 */

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

.sat-find__bar {
	position: relative;
	display: flex;
	align-items: center;
}

/*
 * Two class names deep on purpose.
 *
 * The theme has its own .search-bar rule at the same weight as a single class
 * here, and it loads after this file — so `padding: 8px` from the theme was
 * winning and the magnifier ended up sitting on top of the placeholder. The
 * input no longer carries .search-bar at all, and this selector is specific
 * enough that it would not matter if something put it back.
 */
.sat-find .sat-find__input {
	width: 100%;
	box-sizing: border-box;
	margin: 0;
	/* Room for the magnifier at the leading edge, in both writing directions. */
	padding-inline-start: 44px;
	padding-inline-end: 14px;
	height: 46px;
	font-family: inherit;
	font-size: 15px;
	line-height: 1.4;
	color: var(--mena-text, #1a1a1a);
	/* No fill: the field is drawn by its outline and sits on whatever the page
	   is, rather than as a panel laid on top of it. */
	background: transparent;
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 999px;
	outline: none;
	transition: border-color .18s ease, box-shadow .18s ease;
}

/*
 * Search, then Position / Satellite / Beam, on one line.
 *
 * The search takes the room (flex 3); the three selects share the rest and
 * never shrink below what their placeholder needs. On a phone the search keeps
 * a line of its own and the three selects sit side by side underneath it.
 *
 * Like .sat-field select, these leave the theme's background (its chevron)
 * alone and set only size, shape and colour — see the note above that rule.
 */
.sat-find__row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

.sat-find__row .sat-find__bar {
	flex: 3 1 260px;
	min-width: 0;
}

.sat-find .sat-find__pick {
	flex: 1 1 120px;
	min-width: 0;
	max-width: 220px;
	box-sizing: border-box;
	height: 46px;
	margin: 0;
	padding-inline-start: 16px;
	font-family: inherit;
	font-size: 14px;
	color: var(--mena-text, #1a1a1a);
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 999px;
	text-overflow: ellipsis;
}

/* The empty option reads as a placeholder, not as a value. */
.sat-find .sat-find__pick.is-empty { color: var(--mena-muted, #8898aa); }
.sat-find .sat-find__pick option { color: var(--mena-text, #1a1a1a); }

.sat-find .sat-find__pick:focus {
	outline: none;
	border-color: var(--mena-gold, #ffd014);
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .22);
}

@media (max-width: 640px) {
	.sat-find__row .sat-find__bar { flex-basis: 100%; }
	.sat-find .sat-find__pick {
		flex: 1 1 0;
		max-width: none;
		height: 42px;
		padding-inline-start: 12px;
		padding-inline-end: 22px;
		font-size: 13px;
		background-position: right 8px center;
	}
}

.sat-find .sat-find__input:focus {
	border-color: var(--mena-gold, #ffd014);
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .22);
}

/* The magnifier, and the spinner — one drawing.
   Positioned rather than laid out, so it does not take part in the flex row and
   cannot push the input around. */
.sat-ico {
	position: absolute;
	inset-inline-start: 14px;
	/*
	 * Centred explicitly rather than left to the flex line's static position.
	 * Inside wp:post-content the line box is set from a 1.6rem font, so the
	 * icon's hypothetical position was well below the middle of the input and
	 * it came out sitting on the bottom edge.
	 */
	top: 50%;
	transform: translateY(-50%);
	width: 20px;
	height: 20px;
	pointer-events: none;
	color: var(--mena-muted, #8898aa);
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
}

.sat-ico__sweep {
	/* Invisible until a search is running: a full ring drawn over the lens. */
	opacity: 0;
	stroke: var(--mena-gold-text, #ffd014);
	/* r = 6.6 → circumference ≈ 41.5. A 10-unit dash is a quarter of the ring. */
	stroke-dasharray: 10 31.5;
	transform-origin: 11px 11px;
}

.is-busy .sat-ico { color: var(--mena-gold-text, #ffd014); }
.is-busy .sat-ico__lens { opacity: .25; }
.is-busy .sat-ico__stem { opacity: .55; }

.is-busy .sat-ico__sweep {
	opacity: 1;
	animation: sat-sweep .9s linear infinite;
}

@keyframes sat-sweep {
	to { transform: rotate(360deg); }
}

/* A search that is running should still say so where motion is turned off. */
@media (prefers-reduced-motion: reduce) {
	.is-busy .sat-ico__sweep { animation: none; stroke-dasharray: none; opacity: .5; }
	.sat-skel__bar, .sat-skel__head { animation: none !important; }
}

/*
 * Air between the field and its answers.
 *
 * The theme's .search-bar carried margin-bottom: 20px and that class is gone
 * from this input, so the results ended up sitting directly under the box.
 * Stated here instead, where it belongs to the widget rather than to a class
 * borrowed from the theme's own search form.
 */
[data-sat-results] { margin-top: 20px; }
[data-sat-results]:empty { margin-top: 0; }

/* -------------------------------------------------------------- the blocks */

/*
 * Each frequency is a card.
 *
 * An outline and a radius, with overflow clipped so the header bar inside
 * follows the corner rather than cutting across it. This is the border the
 * removed background used to imply — the blocks were only readable as separate
 * things because they were filled, and once the fill went they needed an edge
 * of their own.
 */
/*
 * A heading present for a screen reader and absent to the eye.
 *
 * clip-path rather than display:none or width:0 — both of those take the text
 * out of the accessibility tree along with the layout, which is the opposite of
 * the point. This is the pattern WordPress's own .screen-reader-text uses; it
 * is restated here rather than borrowed, because whether a theme defines that
 * class is not something this plugin gets to assume.
 */
.sat-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * Square, not rounded.
 *
 * A transponder block is a section of a long table rather than a card, and a
 * radius on it made every one read as a separate object stacked on the last.
 */
.freq-block {
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 0;
	overflow: hidden;
}

.freq-block + .freq-block { margin-top: 18px; }

/*
 * The block header: satellite · tuning · everything else.
 *
 * 1fr auto 1fr, so the tuning figures sit at the true centre of the bar no
 * matter how long the satellite name or the beam description is. Centring the
 * middle cell inside a row of three auto columns would have moved it every time
 * one of the sides changed, and these bars stack — the figures need to line up
 * down the page, which is the whole reason for putting them in the middle.
 */
.freq-head {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: baseline;
	gap: 14px;
	margin: 0;
	padding: 10px 14px;
	background: var(--mena-surface-2, #eff0f4);
	color: var(--mena-text, #1a1a1a);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.5;
}

.freq-head__sat {
	text-align: left;
	font-weight: 800;
	font-size: 15px;
}

/*
 * One run of text, one typeface.
 *
 * This used to set the figures in tabular numerals, which widen the gaps
 * between digits to give every numeral the same advance — so "11180 V 27500"
 * sat noticeably looser than the "FEC 3/4" beside it. Proportional figures and
 * one weight throughout: the spacing and the letterforms match now.
 *
 * The FEC keeps a colour of its own. That was never the problem — it separates
 * the error-correction ratio from the tuning figures without breaking the line
 * into two typefaces.
 */
.freq-head__tune {
	text-align: center;
	white-space: nowrap;
	font-variant-numeric: normal;
	letter-spacing: normal;
}

.freq-head__tune em {
	font-style: normal;
	font-weight: inherit;
	color: var(--mena-muted, #8898aa);
}

.freq-head__more {
	text-align: right;
	font-size: 12.5px;
	font-weight: 500;
	color: var(--mena-text-2, #3f4650);
}

/* -------------------------------------------------------------- the rows */

/*
 * Only the two header bars are filled — the block header above and the column
 * header below it. Everything under them sits on the page.
 *
 * The block used to carry a surface colour, so every row of data was painted
 * on a slab and the whole thing read as one object. Left transparent, the two
 * bars do the work of saying where a block starts and the rows are just rows.
 */
.freq-block { background: transparent; }

/*
 * The row's own border is turned off, not just the last one's.
 *
 * The theme puts a dotted border-bottom on the <tr> and the separators are on
 * the <td> now. Both were drawing: the cell's dashed line won the collapse on
 * every row except the last, where the cell border is removed — leaving the
 * row's dotted line to sit directly on top of the card's outline and read as a
 * thick bottom edge.
 *
 * Two classes deep, because the theme states this at the same weight and its
 * stylesheet loads after this one.
 */
.freq-block .sat-table tbody tr {
	background: transparent;
	border-bottom: 0;
}

/*
 * Dashed, and on the cells rather than the row.
 *
 * A border on a <tr> is the first thing border-collapse drops when it resolves
 * a conflict with the cells inside it, which is why these read as solid in some
 * blocks and absent in others. Put on the td, it wins and it is consistent.
 */
.freq-block .sat-table tbody td {
	border-bottom: 1px dashed var(--mena-border, #e6e6ec);
}

.freq-block .sat-table tbody tr:last-child td { border-bottom: 0; }

/* Still worth showing which row the pointer is on. */
.freq-block .sat-table tbody tr:hover { background: var(--mena-surface, #f7f7f9); }

/*
 * Two header bars, one step apart.
 *
 * The block header and the column header both took --mena-surface-2 and merged
 * into a single tall band. The block header keeps the stronger tone because it
 * names the transponder; the column header steps back to --mena-surface, which
 * is one notch closer to the page in light and one notch away from it in dark.
 */
/*
 * The column header, a clear step darker than the rows under it.
 *
 * --mena-border reads as a line everywhere else in this file; as a fill it is
 * the one token that is decidedly not the page in either theme — #e6e6ec on
 * white, #3c3c3c on near-black — which is what a table head needs to be.
 *
 * Two classes deep, because the theme sets this at .sat-table-heading th and
 * its stylesheet loads after this one; a matching weight would lose.
 */
.freq-block .sat-table-heading th {
	background: var(--mena-border, #e6e6ec);
	color: var(--mena-text, #1a1a1a);
}

/*
 * The theme puts a 3px rule down the leading edge of the header row, which on
 * the flat table lands against the Satellite column and reads as a stray mark
 * rather than as part of anything.
 */
.freq-block .sat-table-heading tr { border-left: 0; }

/* Stacked and centred where there is no room for three columns. The theme
   turns every span in a block into a block at this width; this keeps the
   header a deliberate stack rather than three left-aligned lines. */
@media (max-width: 768px) {
	.freq-head {
		grid-template-columns: 1fr;
		gap: 3px;
		text-align: center;
	}

	.freq-head__sat,
	.freq-head__tune,
	.freq-head__more { text-align: center; }
}

/* ------------------------------------------------------------ table columns */

/*
 * One column grid for every block on the page.
 *
 * Each frequency renders its own <table>, and an auto-layout table sizes its
 * columns from its own contents — so a block whose channels have short names
 * gave a narrow first column and the block underneath it a wide one, and the
 * page read as a stack of unrelated tables rather than one chart.
 *
 * table-layout: fixed takes the widths from the header row and applies them
 * whatever is inside, so every block lines up. The first column is the only one
 * left on auto: channel names are the variable part and they get the remainder.
 *
 * Desktop only. Under 768px the theme unpacks these tables into stacked blocks
 * with data-label captions, where fixed columns would mean nothing.
 */
@media (min-width: 769px) {
	.sat-table { table-layout: fixed; }

	/*
	 * Except the full table, which is one table and has nothing to line up
	 * with.
	 *
	 * Fixed layout reads the widths off the header row and stops there: a
	 * min-width on a column means nothing to it, and when the declared widths
	 * came to more than the container the name column — the one left on auto —
	 * was handed the negative remainder and rendered at zero, one letter to a
	 * line. Auto layout honours the same declared widths when there is room
	 * for them, and treats them as preferences rather than orders when there
	 * is not. At full width the two lay out identically, column for column.
	 */
	[data-sat-table] .sat-table--flat { table-layout: auto; }

	/* A long name wraps inside its column rather than pushing the row wider. */
	.sat-table td, .sat-table th { overflow-wrap: anywhere; }

	/*
	 * The chart: Channel · guide · live · lock · Encryption · RES · Video ·
	 * VPID · Audio.
	 *
	 * By class, not by position. These were th:nth-child() rules and they were
	 * correct exactly until a column was inserted — two were, for the guide and
	 * the live link, and every width landed two places along. The columns left
	 * without a rule then divided up the remainder between them, which is how a
	 * VPID column ended up wider than the channel names it was sitting beside.
	 *
	 * :not(.sat-table--flat) is still load-bearing: the flat view carries
	 * .sat-table too and has its own widths for the same class names.
	 *
	 * Everything here is fixed and Channel is left auto, so the name — the one
	 * genuinely variable field, and the one people are reading — takes whatever
	 * is left rather than being squeezed by a column of six-digit PIDs.
	 */
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--ch   { width: auto; }

	/*
	 * And a floor under the whole table, so "whatever is left" is never
	 * nothing.
	 *
	 * Every column but the name is a fixed width, so the name column is a
	 * subtraction — and in a container narrower than those fixed widths add up
	 * to, the subtraction goes to zero. At 808px it came out at 8px: the
	 * heading printed as C-H-A-N-N-E-L down the page, one letter a line, and
	 * the channel names under it did the same.
	 *
	 * The floor cannot be a min-width on the column itself. These tables are
	 * table-layout: fixed — they have to be, or all ninety blocks on the page
	 * would size their columns independently and no two would line up — and
	 * fixed layout reads a column's width and ignores its min-width entirely.
	 * The table is the only box left that can carry it: 640px of fixed columns
	 * plus 190 for a name, and .freq-scroll moves what will not fit.
	 */
	.freq-scroll .sat-table:not(.sat-table--flat) { min-width: 830px; }
	/* Sized to the mark inside them now that they carry no caption. */
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--epg  { width: 42px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--live { width: 50px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--lock { width: 34px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--enc  { width: 100px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--res  { width: 52px; }

	/*
	 * Video takes what Audio was hoarding.
	 *
	 * "MPEG-4/AVC/H-264" is one token to a reader and it was breaking across
	 * two lines in a 92px column, on every row, while Audio sat at 190 for a
	 * string that is usually half that. The codec is fixed-length and common to
	 * whole transponders; the audio line is the one that can be trimmed.
	 */
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--vid  { width: 132px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--vpid { width: 60px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--aud  { width: 150px; }

	/* The search: Channel · guide · live · Satellite · Frequency · FEC · Beam ·
	   RES · Video — same rule, same reason. */
	[data-sat-results] .sat-table .sat-col--ch   { width: auto; }
	[data-sat-results] .sat-table .sat-col--epg  { width: 56px; }
	[data-sat-results] .sat-table .sat-col--live { width: 62px; }
	[data-sat-results] .sat-table .sat-col--sat  { width: 125px; }
	[data-sat-results] .sat-table .sat-col--tune { width: 140px; }
	[data-sat-results] .sat-table .sat-col--fec  { width: 60px; }
	[data-sat-results] .sat-table .sat-col--beam { width: 130px; }
	[data-sat-results] .sat-table .sat-col--res  { width: 56px; }
	[data-sat-results] .sat-table .sat-col--vid  { width: 92px; }
}

/* --------------------------------------------------------------- the chart */

/* ------------------------------------------------------------ the controls */

/*
 * One panel, one question: where the dish is pointed.
 *
 * This was three stacked form fields with labels floating above them, which
 * read as a form to fill in rather than as filters to flick through. A bordered
 * bar with the label in its own column gives the whole thing one edge against
 * the page and puts the layout picker at the far end, where it cannot be
 * mistaken for one of the choices.
 */
.sat-bar {
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 12px;
	background: var(--mena-surface, #f7f7f9);
	margin-bottom: 14px;
	overflow: hidden;
}

.sat-bar__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: 10px 14px;
	padding: 11px 14px;
}

/* The label and the tags. Carries the 78px column the row used to, so this row
   and .sat-sats below it still line up down the page. */
.sat-bar__pos {
	display: grid;
	grid-template-columns: 78px minmax(0, 1fr);
	align-items: center;
	gap: 10px 14px;
	min-width: 0;
}

/*
 * The satellites, outside the bar.
 *
 * Same label column so the two rows still line up down the page, but no panel
 * around them: this narrows the answer the bar gives rather than asking a
 * question of its own, and it is rebuilt every time the positions change.
 */
.sat-sats {
	display: grid;
	grid-template-columns: 78px minmax(0, 1fr);
	align-items: center;
	gap: 10px 14px;
	padding: 0 4px;
	margin-bottom: 18px;
}

@media (max-width: 700px) {
	.sat-sats { grid-template-columns: minmax(0, 1fr); }
}

.sat-bar__label {
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--mena-muted, #8898aa);
	line-height: 1.3;
}

.sat-bar__end {
	display: flex;
	align-items: center;
	gap: 8px;
	justify-content: flex-end;
}


@media (max-width: 700px) {
	.sat-bar__row {
		grid-template-columns: minmax(0, 1fr);
		gap: 8px;
	}

	.sat-bar__end { justify-content: flex-start; }
}

.sat-field > span {
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: .01em;
	color: var(--mena-muted, #8898aa);
}

/*
 * The theme already styles every <select> on the site — height, border, radius,
 * and a chevron baked into a data: URL as a background-image, positioned once
 * in the base rule and swapped for a lighter one under
 * :root[data-mena-theme="dark"] select.
 *
 * That last selector outweighs a single class here, which is what turned these
 * two dropdowns into a wall of arrows: `background:` shorthand in this file
 * reset background-repeat and background-position to their defaults, then the
 * theme's more specific rule put the image back — with nothing left to say
 * "once, on the right". A tiled chevron, exactly as drawn.
 *
 * So this no longer touches the background at all, and leaves the theme's
 * padding alone so the text still clears the arrow. Only the two things the
 * theme cannot know are set: the width in this layout, and a size that does not
 * inherit wp:post-content's 1.6rem.
 */
.sat-field select {
	width: 100%;
	box-sizing: border-box;
	font-family: inherit;
	font-size: 14px;
}

.sat-field select:disabled { opacity: .55; }

.sat-stamp {
	margin: 0 0 10px;
	text-align: center;
	font-size: 12px;
	font-style: italic;
	color: var(--mena-gold-text, #ffd014);
}

/* ---------------------------------------------------------------- the tags */

/*
 * Positions and satellites as checkable tags.
 *
 * Both are multi-select now — a dish on 25.5°E sees 26°E as well — and a list
 * of chips says "several of these" in a way a dropdown never can. They wrap
 * rather than scroll: a hidden option is an option nobody picks.
 */
.sat-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
	min-height: 34px;
}

.sat-tags__wait {
	font-size: 12.5px;
	color: var(--mena-muted, #8898aa);
}

.sat-tag { position: relative; display: flex; }

/* Same reason as the switch above: the theme's own input rule would otherwise
   leave this in flow at 20px and pad every tag by that much. */
.sat-tags .sat-tag input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

.sat-tag span {
	display: block;
	padding: 7px 13px;
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 999px;
	background: var(--mena-control-bg, #fff);
	color: var(--mena-text-2, #3f4650);
	font-size: 13px;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
	transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.sat-tag:hover span { border-color: var(--mena-faint, #c1c7d2); }

.sat-tag input:checked + span {
	background: var(--mena-gold, #ffd014);
	border-color: var(--mena-gold, #ffd014);
	color: #1a1a1a;
}

/*
 * The divider between one group of slots and the next.
 *
 * Positions within SAT_SPAN of each other are seen by one dish; the divider is
 * where that stops being true. Drawn rather than implied, so the grouping is
 * legible before anything is clicked — clicking across it is allowed and drops
 * the other side.
 */
.sat-tags__sep {
	width: 1px;
	align-self: stretch;
	min-height: 22px;
	margin: 0 4px;
	background: var(--mena-border, #e6e6ec);
}

.sat-tag input:focus-visible + span {
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .35);
}

/* --------------------------------------------------------- the checkboxes */

/*
 * Satellites read as a list of things to include, so they are checkboxes
 * rather than pills — a tick says "and this one" where a filled capsule says
 * "this one instead". Drawn rather than native: a browser checkbox cannot take
 * the site's gold, and the theme has already stripped its appearance anyway.
 */
.sat-check {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 5px 11px 5px 7px;
	border: 1px solid transparent;
	border-radius: 8px;
	cursor: pointer;
	transition: background .15s ease, border-color .15s ease;
}

.sat-check:hover { background: var(--mena-surface-2, #eff0f4); }

/*
 * The native box, hidden from sight but not from the keyboard.
 *
 * [type="checkbox"] is here to out-weigh the theme's own
 * `input[type="checkbox"] { position: relative; width: 20px }`, which loads
 * after this file — scoped to .sat-checks it lost inside the dialog, and every
 * row drew a browser checkbox beside the one this file draws.
 */
.sat-check input[type="checkbox"] {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
	appearance: none;
	-webkit-appearance: none;
}

/*
 * [hidden] is a display:none from the browser's own stylesheet, and .sat-check
 * sets display:inline-flex — which wins. The filter set the property on every
 * row that did not match and none of them went anywhere.
 */
.sat-check[hidden] { display: none !important; }

.sat-check__box {
	display: grid;
	place-items: center;
	width: 18px;
	height: 18px;
	flex: none;
	border: 1.5px solid var(--mena-control-border, #cfd4dd);
	border-radius: 5px;
	background: var(--mena-control-bg, #fff);
	color: transparent;
	transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.sat-check__box svg {
	width: 12px;
	height: 12px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.6;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.sat-check__text {
	font-size: 13px;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
	color: var(--mena-text-2, #3f4650);
}

.sat-check input:checked ~ .sat-check__box {
	background: var(--mena-gold, #ffd014);
	border-color: var(--mena-gold, #ffd014);
	color: #1a1a1a;
}

.sat-check input:checked ~ .sat-check__text { color: var(--mena-text, #1a1a1a); }

.sat-check input:focus-visible ~ .sat-check__box {
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .35);
}

.sat-checks {
	display: flex;
	flex-wrap: wrap;
	gap: 2px 6px;
	align-items: center;
	min-height: 34px;
}

/* ------------------------------------------------------- the view switcher */

/* The picker sits in .sat-bar__end now; nothing to push. */
.sat-switch {
	display: inline-flex;
	gap: 0;
	padding: 2px;
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 9px;
	background: var(--mena-surface, #f7f7f9);
}

.sat-switch__ico {
	width: 19px;
	height: 19px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.6;
	stroke-linejoin: round;
}

/*
 * display:flex, and it matters.
 *
 * The label is a block box whose only visible child is the 34px icon square,
 * but the newlines around that child in the markup are text nodes — and inside
 * wp:post-content they inherit a 25.6px font, so each one generated an
 * anonymous line box and the 40px control came out 71px tall. Flex containers
 * do not render whitespace between their items.
 */
.sat-switch__opt {
	position: relative;
	display: flex;
}

/*
 * The radio is the control — hidden from sight, not from the keyboard, so
 * focus and arrow-key navigation still work.
 *
 * Two classes deep. The theme sets `input[type="checkbox"], input[type="radio"]
 * { position: relative; width: 20px }` at the same weight as .sat-switch__opt
 * input, and its stylesheet loads after this one — so the radio stayed in flow
 * at 20px wide and every 30px chip came out 50px. Which is where the padding
 * that looked like padding was coming from.
 */
.sat-switch .sat-switch__opt input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

.sat-switch__opt span {
	display: grid;
	place-items: center;
	width: 30px;
	height: 30px;
	border-radius: 7px;
	color: var(--mena-text-2, #3f4650);
	transition: background .16s ease, color .16s ease;
}

.sat-switch__opt:hover span { color: var(--mena-text, #1a1a1a); }

.sat-switch__opt input:checked + span {
	background: var(--mena-gold, #ffd014);
	color: #1a1a1a;
}

.sat-switch__opt input:focus-visible + span {
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .35);
}

/* --------------------------------------------------------- the flat table */

/* The flat view is a grid, not a card — square, edge to edge. */
.freq-block--flat { border-radius: 0; }

/* Everything on a row sits on its centre line, spanned cells included. */
.sat-table--flat tbody td { vertical-align: middle !important; }

/*
 * A smaller name in the flat view than in a transponder block.
 *
 * The flat table carries three more columns in the same width, so its rows are
 * tighter — a 15px name there wrapped onto two lines for anything longer than
 * "LBCI International HD" and pushed the row to double height.
 */
.sat-table--flat .ch-name { font-size: 13px !important; }

/*
 * The three spanned columns.
 *
 * They describe a transponder, so they are written once and held down the
 * channels that share it.
 */
.sat-span {
	border-right: 1px solid var(--mena-border, #e6e6ec);
	/*
	 * A wash rather than a slab.
	 *
	 * These three columns run the full height of a transponder group, so at the
	 * surface colour they were the heaviest thing on the page — a grey block
	 * beside the rows people are actually reading. Mixed down to a quarter, they
	 * still group the rows and no longer compete with them.
	 */
	background: color-mix(in srgb, var(--mena-surface, #f7f7f9) 45%, transparent);
	font-size: 14px;
	line-height: 1.45;
}

/* No color-mix: the surface colour, unmixed, is close enough. */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
	.sat-span { background: var(--mena-surface, #f7f7f9); }
}

/*
 * One fact per line.
 *
 * Frequency, polarisation and symbol rate ran together as "11180 V 27500", so
 * the eye had to parse a string to find one of the three. On their own lines
 * they are found by position — and down a column of transponders the
 * frequencies stack under each other, which is how they get compared.
 */
.sat-line { display: block; }

/*
 * Regular, not bold.
 *
 * The satellite and the tuning figures are reference — read once when the group
 * is found, and then not again. Bold made every group heading shout over the
 * channel names beside it, which are what the page is for.
 */
.sat-table--flat td.sat-span--sat { font-weight: 400; text-align: center; }

/*
 * The tuning column is a two-line stack, centred on both axes.
 *
 * Two classes and an element, not one class. These rules used to be
 * `.sat-span--tune` — (0,1,0) — and every theme states something about
 * `.sat-table td`, which is (0,1,1) and loads after this file. So the centring
 * these columns were written to have has quietly been losing that fight, and
 * they have been rendering left aligned under centred headers. Qualifying by
 * the table as well takes them to (0,2,1), where source order stops deciding
 * it — the same depth the row-border rules above already had to go to.
 */
.sat-table--flat td.sat-span--tune {
	text-align: center;
	white-space: nowrap;
}

/* A step down from the channel name: it is a reference, not a title. */
.sat-line--tune {
	font-weight: 400;
	font-size: 13px;
}

.sat-line--fec {
	color: var(--mena-muted, #8898aa);
	font-size: 11.5px;
}

/* Centred, like the tuning beside it. */
/*
 * The beam, allowed to break.
 *
 * `.sat-line` makes each part its own block, and the parts themselves may now
 * wrap inside those blocks rather than forcing the column wide enough to hold
 * the longest one. `balance` splits a two-line break evenly instead of leaving
 * one word stranded underneath.
 */
.sat-table--flat td.sat-span--beam {
	text-align: center;
	white-space: normal;
	overflow-wrap: anywhere;
	text-wrap: balance;
	line-height: 1.45;
}

/* The same, in the search results, where the beam is one cell of plain text. */
[data-sat-results] .sat-col--beam {
	white-space: normal;
	overflow-wrap: anywhere;
	line-height: 1.45;
}

/*
 * The carrier line.
 *
 * Nothing is clipped here. It was briefly held to one line with an ellipsis,
 * which hid the end of "DVB-S2 PLS: Gold+253312 8PSK Stream 48" — the part
 * that distinguishes one carrier from another. The column is sized for that
 * string instead, so it fits without being cut and without wrapping the block
 * to a third line.
 */
.sat-line--sub {
	color: var(--mena-text-2, #3f4650);
	font-size: 11.5px;
	line-height: 1.4;
}

/*
 * The rule where one transponder ends and the next begins.
 *
 * Thicker and darker than the dashed line between channels — that one is
 * deliberately quiet, and without something with weight at the boundary a table
 * of six transponders reads as one long list.
 */
.sat-table--flat tbody tr.sat-group td {
	border-top: 2px solid var(--mena-control-border, #cfd4dd);
}

.sat-table--flat tbody tr:first-child td { border-top: 0; }

/*
 * The full table moves, not the page.
 *
 * At every width, because the band between a phone and a wide laptop is not
 * the only place this table outgrows its container — with a floor under the
 * name column it can do so anywhere below about 1300px — and a table that
 * overflows a box with visible overflow takes the whole page sideways with it.
 * When it fits, auto draws nothing.
 *
 * Both views. The blocks view has a floor under its table too now, and a floor
 * without a scroller is a table that hangs out of the page instead of moving
 * inside it. When the table fits — which on a desktop it always does — auto
 * draws nothing and costs nothing.
 */
.freq-scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

/* A frequency with nothing on it. */
.sat-quiet {
	text-align: center;
	font-size: 12px;
	color: var(--mena-muted, #8898aa);
	padding: 10px 5px;
}

/*
 * Widths by class, not by position.
 *
 * The satellite column is dropped when one satellite is chosen — the dropdown
 * above already says which — so every column after it shifts by one. nth-child
 * would have quietly handed the frequency column the satellite's width and
 * pushed the whole row along.
 */
@media (min-width: 769px) {
	/*
	 * A heading is the one thing in the column that must not break.
	 *
	 * Every width below is a preference the table is free to shrink when the
	 * screen is narrow, and the first thing to give was the headings —
	 * "ENCRYPTIO / N" over a column of one-word values. Held on one line they
	 * set a floor for their own column, and what will not fit after that is
	 * what .freq-scroll moves sideways.
	 */
	[data-sat-table] .sat-table--flat thead th { white-space: nowrap; }

	[data-sat-table] .sat-table--flat .sat-col--sat  { width: 105px; }
	[data-sat-table] .sat-table--flat .sat-col--tune { width: 128px; }

	/*
	 * The beam wraps now, and is a third narrower for it.
	 *
	 * It was 255px so the longest carrier string could never break — which
	 * bought one unbroken line at the cost of a quarter of the table, taken
	 * from the channel names. A beam is read once per transponder group and a
	 * name is read on every row; the space belongs to the name, and two short
	 * lines of "MENA / DVB-S2 8PSK" read no worse than one long one.
	 */
	[data-sat-table] .sat-table--flat .sat-col--beam { width: 130px; }

	[data-sat-table] .sat-table--flat .sat-col--epg  { width: 42px; }
	[data-sat-table] .sat-table--flat .sat-col--live { width: 50px; }
	/*
	 * The name column takes what is left — and needs a floor under it.
	 *
	 * "What is left" is a subtraction, and on a laptop the eleven fixed
	 * columns come to more than the container: the subtraction went negative
	 * and the column rendered at zero, one letter to a line all the way down.
	 * A minimum turns that into the table being wider than its box, which is
	 * what .freq-scroll is for.
	 */
	[data-sat-table] .sat-table--flat .sat-col--ch   { width: auto; min-width: 190px; }

	/*
	 * Centred, because they are centred underneath.
	 *
	 * The tuning and beam cells are two-line stacks with text-align:center; the
	 * headers above them were left-aligned, so each column read as slightly out
	 * of true all the way down.
	 */
	[data-sat-table] .sat-table--flat th.sat-col--tune,
	[data-sat-table] .sat-table--flat th.sat-col--beam { text-align: center; }
	[data-sat-table] .sat-table--flat .sat-col--lock { width: 28px; }
	[data-sat-table] .sat-table--flat .sat-col--enc  { width: 88px; }
	[data-sat-table] .sat-table--flat .sat-col--res  { width: 48px; }

	/*
	 * Twelve columns in the width the blocks view spends on nine.
	 *
	 * Everything here is trimmed to the shortest it can be and still hold its
	 * own content, because the name column is what is left over — and at the
	 * old widths "left over" came to 138px, which wraps anything longer than a
	 * three-word name onto a second line. Video is the exception and grows: the
	 * codec string is one token and was breaking mid-word.
	 */
	[data-sat-table] .sat-table--flat .sat-col--vid  { width: 118px; }
	[data-sat-table] .sat-table--flat .sat-col--vpid { width: 56px; }
	[data-sat-table] .sat-table--flat .sat-col--aud  { width: 130px; }
}

/*
 * Below the theme's breakpoint every cell becomes a block and rowspan stops
 * meaning anything, so the three leading cells are drawn as a caption above the
 * group they head rather than as three stray lines inside the first channel.
 */
@media (max-width: 768px) {
	.sat-span {
		border-right: 0;
		border-bottom: 1px solid var(--mena-border, #e6e6ec);
	}

	.sat-span--sat { font-size: 14px; }
}

.sat-empty {
	padding: 22px 16px;
	text-align: center;
	font-size: 14px;
	color: var(--mena-muted, #8898aa);
}

/* ------------------------------------------------------------- the skeleton */

/*
 * The shape of what is coming, not a spinner.
 *
 * Both of these queries join two tables and can take a second or more; a
 * spinner in that gap says only "wait", and the page reads as broken. A
 * skeleton says how much is coming and holds the space, so nothing jumps when
 * the rows land.
 *
 * The tints are the platform's own placeholder tokens — translucent rather than
 * solid, so one pair works on the page, on a card and inside a dialog.
 */
.sat-skel { display: grid; gap: 18px; }

.sat-skel__block {
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 10px;
	overflow: hidden;
}

.sat-skel__head,
.sat-skel__bar {
	background: linear-gradient(
		90deg,
		var(--mena-skel-a, rgba(0, 0, 0, .055)) 25%,
		var(--mena-skel-b, rgba(0, 0, 0, .105)) 37%,
		var(--mena-skel-a, rgba(0, 0, 0, .055)) 63%
	);
	background-size: 400% 100%;
	animation: sat-shimmer 1.4s ease-in-out infinite;
	border-radius: 4px;
}

.sat-skel__head {
	height: 38px;
	border-radius: 0;
}

.sat-skel__row {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 11px 14px;
	border-top: 1px solid var(--mena-border-soft, #f0f0f4);
}

.sat-skel__bar { height: 10px; flex: 0 0 auto; }
.sat-skel__bar--sm { width: 64px; }
.sat-skel__bar--xs { width: 34px; margin-inline-start: auto; }

@keyframes sat-shimmer {
	0%   { background-position: 100% 50%; }
	100% { background-position: 0 50%; }
}

/* The screen-reader label on either skeleton, for themes that do not ship one
   — and the dialog's does not inherit the theme's, so without this the words
   "جارٍ التحميل" were printed across the top of the form. */
.sat-skel .screen-reader-text,
.sat-skel-f .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* ------------------------------------------------------------ contributing */

.sat-contribute {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	height: 36px;
	padding: 0 14px;
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 9px;
	background: var(--mena-control-bg, #fff);
	color: var(--mena-text, #1a1a1a);
	font: inherit;
	font-size: 13px;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	transition: border-color .15s ease, background .15s ease;
}

.sat-contribute:hover {
	border-color: var(--mena-gold, #ffd014);
	background: var(--mena-surface-2, #eff0f4);
}

.sat-contribute svg {
	width: 15px;
	height: 15px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
}


/* -------------------------------------------------------------- the dialog */

/*
 * A native <dialog>: the backdrop, the focus trap and Escape all come with it,
 * and none of them are worth writing again.
 *
 * A column, not a scroller. The whole dialog used to scroll, which took the
 * title and the kind chooser away with it and left the reader unsure what they
 * were filling in; worse, it clipped the combobox menus, so on a short window a
 * list of sixty transponders opened *inside* the scroll box and showed two.
 * Only the middle scrolls now, and the menus float over the lot.
 *
 * direction: rtl explicitly. The chart around it is forced to LTR by the theme
 * — the tables are columns of Latin numerals — and the dialog inherited that,
 * which put every Arabic full stop at the wrong end of its sentence.
 */
.sat-modal {
	direction: rtl;
	text-align: right;
	/*
	 * Wide enough for a row of four.
	 *
	 * At 720 the optional details wrapped country, category and package onto a
	 * line that then had a quarter of itself empty, and a list of channels with
	 * their transponders beside them had nowhere to put the transponder. The
	 * cap is on the viewport rather than the number, so a laptop gets the whole
	 * 940 and a phone still gets its twelve pixels of margin.
	 */
	width: min(940px, calc(100vw - 24px));
	max-height: min(760px, calc(100dvh - 40px));
	/* The border counts. Without this the dialog is 942 on a 960 viewport and
	   the 12px of margin the calc() promised is 11. */
	box-sizing: border-box;
	padding: 0;
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 16px;
	background: var(--mena-elevated, #fff);
	color: var(--mena-text, #1a1a1a);
	overflow: visible;
	font-size: 14px;
}

/*
 * Opening and closing, animated.
 *
 * A dialog appearing instantly reads as a page change rather than as something
 * laid over the page. The two allow-discrete transitions are what make it work
 * on a native <dialog>: display and overlay are discrete properties, and
 * without them the element is simply gone before any fade can run.
 * @starting-style supplies the "from" — an element that did not exist a frame
 * ago has no previous value to transition out of.
 */
.sat-modal {
	opacity: 0;
	transform: translateY(10px) scale(.985);
	transition:
		opacity .2s ease,
		transform .2s cubic-bezier(.2, .8, .3, 1),
		overlay .2s allow-discrete,
		display .2s allow-discrete;
}

.sat-modal[open] {
	opacity: 1;
	transform: none;
	display: flex;
	flex-direction: column;
}

@starting-style {
	.sat-modal[open] {
		opacity: 0;
		transform: translateY(10px) scale(.985);
	}
}

.sat-modal::backdrop {
	background: var(--mena-scrim, rgba(20, 22, 26, .45));
	opacity: 0;
	transition: opacity .2s ease, display .2s allow-discrete, overlay .2s allow-discrete;
}

.sat-modal[open]::backdrop { opacity: 1; }

@starting-style {
	.sat-modal[open]::backdrop { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.sat-modal,
	.sat-modal::backdrop { transition: none; }
	.sat-modal { transform: none; }
}

/* ------------------------------------------------------------------- head */

.sat-modal__head {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 16px 22px 0;
}

.sat-modal__title {
	margin: 0;
	font-size: 17px;
	font-weight: 800;
	line-height: 1.35;
}


.sat-modal__x { margin: 0; }

.sat-modal__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: var(--mena-muted, #8898aa);
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
}

.sat-modal__close:hover { background: var(--mena-surface-2, #eff0f4); color: var(--mena-text, #1a1a1a); }

/*
 * The four kinds, as one control.
 *
 * Four loose pills read as four buttons that each do something; a single track
 * with one lit segment reads as one question with four answers, which is what
 * it is.
 *
 * The lit segment is its own element behind the row rather than a background on
 * the chosen button — a background cannot travel, and the travel is the whole
 * point: a pill that slides from one word to the next says the four answers
 * belong to one question. Each carries a glyph as well as a word, because four
 * grey labels distinguished only by shade is a row nobody reads.
 */
.sat-modal__kinds {
	position: relative;
	flex: none;
	display: flex;
	gap: 2px;
	margin: 16px 22px 0;
	padding: 4px;
	border-radius: 14px;
	background: var(--mena-surface-2, #eff0f4);
	box-shadow: inset 0 0 0 1px var(--mena-line, rgba(16, 24, 40, .07));
}

/* The travelling pill. Placed by the script from the chosen button's own box,
   so it is right at any width and in either direction without a second set of
   numbers to keep in step. It starts unplaced and invisible — a pill sitting at
   the corner of the track for one frame is worse than no pill. */
.sat-kinds__ink {
	position: absolute;
	top: 4px;
	bottom: 4px;
	left: 0;
	width: 0;
	border-radius: 10px;
	background: var(--mena-elevated, #fff);
	box-shadow: 0 1px 2px rgba(16, 24, 40, .1), 0 2px 8px rgba(16, 24, 40, .07);
	opacity: 0;
	transform: translateX(0);
	transition: transform .34s cubic-bezier(.22, 1, .36, 1),
				width .34s cubic-bezier(.22, 1, .36, 1),
				opacity .18s ease;
	pointer-events: none;
}

.sat-modal__kinds.is-set .sat-kinds__ink { opacity: 1; }

/* The first placement must not slide in from nowhere. */
.sat-modal__kinds.is-jump .sat-kinds__ink { transition: opacity .18s ease; }

.sat-kind {
	position: relative;
	z-index: 1;
	/*
	 * Basis auto, not zero.
	 *
	 * Four equal quarters is the tidier arrangement and it truncated the longest
	 * label to "…nsponder update" — four names of four different lengths do not
	 * fit four equal boxes. Each takes the room its own words need and the
	 * leftover is shared, so the row still fills the track and nothing is cut.
	 */
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	padding: 9px 10px;
	border: 0;
	border-radius: 10px;
	background: transparent;
	color: var(--mena-text-2, #3f4650);
	font: inherit;
	font-size: 13px;
	font-weight: 600;
	line-height: 1.4;
	white-space: nowrap;
	cursor: pointer;
	transition: color .18s ease;
}

.sat-kind__i {
	flex: none;
	width: 17px;
	height: 17px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
	opacity: .75;
	transition: opacity .18s ease, transform .28s cubic-bezier(.22, 1, .36, 1);
}

.sat-kind__t {
	overflow: hidden;
	text-overflow: ellipsis;
}

.sat-kind:hover { color: var(--mena-text, #1a1a1a); }
.sat-kind:hover .sat-kind__i { opacity: 1; }

.sat-kind:focus-visible {
	outline: 2px solid var(--mena-gold, #ffd014);
	outline-offset: 1px;
}

.sat-kind[aria-selected="true"] {
	color: var(--mena-text, #1a1a1a);
	font-weight: 700;
}

.sat-kind[aria-selected="true"] .sat-kind__i {
	opacity: 1;
	transform: scale(1.06);
}

/*
 * Below a phone's width four labels do not fit, and shrinking the type to make
 * them fit makes four things nobody can read. The word goes and the glyph
 * stays, with the name still on the button for a screen reader and a hover.
 */
@media (max-width: 560px) {
	.sat-kind { padding: 10px 6px; }
	.sat-kind__i { width: 19px; height: 19px; }
	.sat-kind__t {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		padding: 0;
		overflow: hidden;
		clip: rect(0 0 0 0);
		clip-path: inset(50%);
		white-space: nowrap;
	}
}

@media (prefers-reduced-motion: reduce) {
	.sat-kinds__ink,
	.sat-kind,
	.sat-kind__i { transition: none; }
}

/* ------------------------------------------------------------------- body */

.sat-modal__body {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 4px 22px 18px;
}

/*
 * Where, then what.
 *
 * Two numbered steps rather than one wall of boxes: the first asks which
 * transponder, the second asks about it. The number is not decoration — it is
 * what tells a reader the second block is waiting on the first, which is
 * exactly what it does.
 */
.sat-step { margin-top: 18px; }

.sat-step__hd {
	display: flex;
	align-items: center;
	gap: 9px;
	margin: 0 0 10px;
	font-size: 13.5px;
	font-weight: 700;
}

.sat-step__n {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 21px;
	height: 21px;
	border-radius: 999px;
	background: var(--mena-gold, #ffd014);
	color: #1a1a1a;
	font-size: 11.5px;
	font-weight: 800;
}

.sat-step__hd em {
	font-style: normal;
	font-weight: 500;
	font-size: 12px;
	color: var(--mena-muted, #8898aa);
}

/*
 * The form, before it exists.
 *
 * Same shimmer as the chart's skeleton, in the shape of the panel that is about
 * to replace it: a step heading, a pair of pickers, a heading, three fields.
 * Holding roughly the right height is the point — the dialog does not resize
 * under the cursor the moment the fetch lands.
 */
.sat-skel-f { padding: 4px 0 8px; }

.sat-skel-f__hd { margin: 18px 0 10px; }
.sat-skel-f__hd .sat-skel__bar { display: block; width: 130px; height: 13px; }

.sat-skel-f__row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
	gap: 12px;
}

.sat-skel-f__row--3 { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

.sat-skel-f__box {
	height: 42px;
	border-radius: 9px;
	background: linear-gradient(
		90deg,
		var(--mena-skel-a, rgba(0, 0, 0, .055)) 25%,
		var(--mena-skel-b, rgba(0, 0, 0, .105)) 37%,
		var(--mena-skel-a, rgba(0, 0, 0, .055)) 63%
	);
	background-size: 400% 100%;
	animation: sat-shimmer 1.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
	.sat-skel-f__box { animation: none; }
}

/* ----------------------------------------------------------------- fields */

.sat-row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 12px;
}

.sat-row + .sat-row,
.sat-row + .sat-opt { margin-top: 12px; }

/* Two questions that are one question: the satellite and its transponder sit
   side by side at any width above a phone, because choosing the first is what
   fills the second. */
.sat-row--pair { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

/* The satellite on a line of its own, filling it. Capped at a field's width it
   sat in the corner of an empty row, which read as a layout that had failed to
   fill rather than as the one choice everything below it depends on. */
.sat-row--one { grid-template-columns: minmax(0, 1fr); }

/* A name is longer than a type and gets the room to match. Fixed proportions
   rather than auto-fit, because auto-fit would give the two boxes equal widths
   and a three-letter <select> does not need half a row. */
.sat-row--name { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }

@media (max-width: 480px) {
	.sat-row--name { grid-template-columns: minmax(0, 1fr); }
}

.sat-f { display: grid; gap: 5px; min-width: 0; align-content: start; }
.sat-f--wide { grid-column: span 2; }

/*
 * The whole line, whatever the line turned out to be.
 *
 * Encryption is a box of chips, not a word: squeezed into a quarter of a row it
 * was a strip barely wider than one tag, and a second system pushed the field
 * to two lines while its neighbours stayed at one. `1 / -1` is the only way to
 * say "all of it" to a grid whose column count is decided at render time by
 * auto-fit.
 */
.sat-f--full { grid-column: 1 / -1; }

/*
 * A value shown rather than asked for.
 *
 * The frequency and polarity of a transponder being corrected are what say
 * which transponder it is, so they are printed instead of offered — drawn at
 * the height of the boxes beside them so the row still reads as one row, but
 * flat, with no border and no cursor, because nothing about them should look
 * like it can be typed into.
 */
.sat-fixed {
	display: flex;
	align-items: center;
	min-height: 42px;
	margin: 0;
	padding: 0 11px;
	border-radius: 9px;
	background: var(--mena-surface-2, #eff0f4);
	color: var(--mena-text-2, #3f4650);
	font-size: 13.5px;
	font-weight: 600;
	line-height: 1.9;
}

@media (max-width: 520px) {
	.sat-f--wide { grid-column: auto; }
}

.sat-f > span {
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: .02em;
	color: var(--mena-muted, #8898aa);
}

.sat-req {
	font-style: normal;
	color: var(--mena-rose, #f5365c);
}

/*
 * line-height is not cosmetic here.
 *
 * An input clips to its line box, and `normal` on a fallback sans is about
 * 1.15em — enough for Latin, and not enough for Arabic, whose descenders (ج،
 * ل، ي) and the hamza above an alif sit outside that band. "إختر القمر الصناعي"
 * came out shaved top and bottom. Given room the glyphs are whole, and the
 * field is a little taller to carry it.
 */
.sat-modal input[type="text"],
.sat-modal input[type="search"],
.sat-modal input[type="number"] {
	width: 100%;
	box-sizing: border-box;
	/*
	 * A floor, not a height.
	 *
	 * A fixed 42 with a line-height of 1.9 says "the text gets 25.65px and the
	 * box gets 40" — and if the font in use draws taller than that, the field
	 * clips it, bottom first, because Arabic faces carry far more below the
	 * baseline than Latin ones. Which font is in use is not knowable from here:
	 * the theme may load one, the reader's browser may substitute another, and
	 * the two have different vertical metrics.
	 *
	 * So the box is told its minimum and left to grow. The line box is generous
	 * enough for any Arabic face; the padding guarantees clear air above and
	 * below it whatever that turns out to be; and `height: auto` means the field
	 * accommodates the result instead of cropping it. On the fonts in use here
	 * this lands within a pixel of the 42 it replaces.
	 */
	height: auto;
	min-height: 42px;
	padding: 8px 11px;
	font: inherit;
	font-size: 13.5px;
	line-height: 1.95;
	color: var(--mena-text, #1a1a1a);
	background: var(--mena-control-bg, #fff);
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 9px;
	outline: none;
}

/*
 * A hint is not an answer, and should not be set like one.
 *
 * At the field's own size a placeholder reads as text already typed — the eye
 * takes "إختر القمر الصناعي" for a chosen satellite until it notices the
 * colour. A step down in size puts it in the same register as the label above
 * it: something the form is saying, rather than something the reader said.
 */
.sat-modal input::placeholder,
.sat-modal textarea::placeholder {
	color: var(--mena-faint, #c1c7d2);
	font-size: 12px;
	/*
	 * Size only. A line-height here would give the hint a line box of its own,
	 * computed from its own smaller font — narrower than the field's, and the
	 * one the browser then clips to. Left alone it sits in the field's line box,
	 * which is already sized for text a point and a half bigger.
	 */
	opacity: 1;
}

/* A frequency, a PID, a FEC — Latin numerals, which RTL reorders into nonsense
   the moment there is a letter among them. */
.sat-modal input.is-ltr { direction: ltr; text-align: right; }

/* The spinner arrows on a number field are 8px of hit area nobody wants, and
   they collide with the chevron on the fields beside them. */
.sat-modal input[type="number"] { -moz-appearance: textfield; }
.sat-modal input[type="number"]::-webkit-outer-spin-button,
.sat-modal input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/*
 * A text box that carries a datalist.
 *
 * It has to read as "pick or type", and a bare input reads as "type" — the
 * suggestions are then never found. The chevron borrows the select's own
 * language so the two sit together without explanation.
 *
 * Only the background longhands are set. The `background` shorthand would
 * reset repeat and position, and the theme's dark-mode rule puts an image back
 * with neither — which is how these fields filled with tiled chevrons twice
 * already.
 */
.sat-modal .sat-f--list input {
	padding-inline-end: 30px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238898aa' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: left 11px center;
	background-size: 10px 6px;
	cursor: pointer;
}

[dir="ltr"] .sat-modal .sat-f--list input {
	background-position: right 11px center;
}

/* Chrome draws its own arrow inside a field that carries a list, at the far
   end, in its own colour — two chevrons on one control, one of them not ours.
   Hidden; the click still opens the list, because showPicker() does that. */
.sat-modal .sat-f--list input::-webkit-calendar-picker-indicator {
	display: none !important;
}

/*
 * A <select> gets width and size and nothing else.
 *
 * The theme draws the dropdown arrow as a background-image and swaps it for a
 * lighter one under :root[data-mena-theme="dark"] select — which outweighs a
 * single class here. Using the `background` shorthand resets repeat and
 * position, the theme's rule puts the image back with neither, and the field
 * fills with tiled chevrons. Its padding is left alone too, since that is what
 * keeps the text clear of the arrow.
 */
/* A select cannot grow the way an input can — the UA lays its text out — so it
   is given the same floor and the same air, and the chevron's room besides. */
.sat-modal select {
	width: 100%;
	box-sizing: border-box;
	/* 44, so a select and the input beside it are the same height once both are
	   given room for a descender. */
	min-height: 44px;
	padding-block: 8px;
	font-family: inherit;
	font-size: 13.5px;
	line-height: 1.95;
}

.sat-modal input:focus,
.sat-modal select:focus {
	border-color: var(--mena-gold, #ffd014);
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .22);
}

/* What was asked for and not given. Set on send, cleared as soon as the field
   is answered — an error that stays lit after it is fixed is worse than none. */
.sat-f.is-bad input,
.sat-f.is-bad select,
.sat-f.is-bad .sat-pick__input {
	border-color: var(--mena-rose, #f5365c);
	box-shadow: 0 0 0 3px rgba(245, 54, 92, .16);
}

/*
 * The rest of a transponder, folded away.
 *
 * FEC, beam, standard and modulation are four fields a reader looking at a
 * receiver usually cannot answer, and a form that demands nine boxes to report
 * one change is a form that does not get filled in. They are here for anyone
 * who has them, and they open by themselves when there is already something in
 * them to see.
 */
.sat-opt {
	margin-top: 12px;
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 11px;
	background: var(--mena-surface, #f7f7f9);
}

.sat-opt > summary {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 10px 14px;
	font-size: 12.5px;
	font-weight: 700;
	color: var(--mena-text-2, #3f4650);
	cursor: pointer;
	list-style: none;
}

.sat-opt > summary::-webkit-details-marker { display: none; }

.sat-opt > summary::before {
	content: "";
	width: 9px;
	height: 9px;
	border-inline-end: 1.8px solid currentColor;
	border-block-end: 1.8px solid currentColor;
	/* Closed it points the way the text runs; open it points down at what it
	   revealed. Both are logical, so the closed arrow flips with the language. */
	transform: rotate(45deg);
	transition: transform .15s ease;
	opacity: .6;
}

.sat-opt[open] > summary::before { transform: rotate(-45deg); }

.sat-opt > summary span {
	font-weight: 500;
	font-size: 11.5px;
	color: var(--mena-muted, #8898aa);
}

.sat-opt > summary:hover { color: var(--mena-text, #1a1a1a); }

/* Not `>`: the script folds everything after the summary into a wrapper it can
   give a height to, so what used to be a child of the <details> is now a
   grandchild. */
.sat-opt .sat-row { padding: 2px 14px 14px; }

/*
 * A disclosure that moves.
 *
 * <details> is instant by design: the browser flips display and the page jumps
 * by the height of whatever was inside. Four fields appearing under the cursor
 * with no travel reads as the form having reloaded. The script wraps the
 * contents, measures them and animates the wrapper's height, so opening looks
 * like the panel it is; this class is what it sets while that is running.
 */
.sat-opt__in { overflow: hidden; }

.sat-opt.is-moving > .sat-opt__in { overflow: hidden; }

/*
 * Everything that arrives after the first paint arrives the same way.
 *
 * A panel swapped in on a tab, a channel's fields appearing once its
 * transponder is known, one more channel row — all of them are content the
 * reader did not ask to have appear silently. A short rise and fade is what
 * connects the click to the thing that changed; without it the eye has to hunt
 * for what is new.
 */
@keyframes sat-rise {
	from { opacity: 0; transform: translateY(8px); }
	to   { opacity: 1; transform: none; }
}

.sat-in { animation: sat-rise .26s cubic-bezier(.22, 1, .36, 1) both; }

/* The steps come in one after the other rather than together, which reads as
   an order — first the transponder, then what is on it. */
.sat-modal__body > .sat-step.sat-in:nth-child(2) { animation-delay: .05s; }

@keyframes sat-pop {
	from { opacity: 0; transform: scale(.9); }
	to   { opacity: 1; transform: none; }
}

.sat-modal .sat-chip { animation: sat-pop .18s cubic-bezier(.22, 1, .36, 1) both; }

@media (prefers-reduced-motion: reduce) {
	.sat-in,
	.sat-modal .sat-chip { animation: none; }
}

/* ----------------------------------------------------------------- chips */

/*
 * Several encryption systems in one field.
 *
 * A channel carried on two conditional-access systems is stored as one cell
 * joined by <br/>, so a single box asked the reader to type a tag. Here it is
 * chips: pick or type one at a time, and the field posts the joined form.
 */
.sat-modal .sat-chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 5px;
	width: 100%;
	box-sizing: border-box;
	/* Level with the plain fields beside it, and grown the same way: the floor
	   is a floor, and a second chip wraps the box taller rather than cropping
	   the first. */
	min-height: 44px;
	padding: 6px 8px;
	background: var(--mena-control-bg, #fff);
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 9px;
	cursor: text;
}

.sat-modal .sat-chips:focus-within {
	border-color: var(--mena-gold, #ffd014);
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .22);
}

.sat-modal .sat-chip {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	max-width: 100%;
	padding: 3px 4px 3px 9px;
	border-radius: 999px;
	background: var(--mena-surface-2, #eff0f4);
	color: var(--mena-text, #1a1a1a);
	font-size: 12.5px;
	font-weight: 600;
	line-height: 1.5;
	direction: ltr;
}

.sat-modal .sat-chip > span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.sat-modal .sat-chip__x {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: var(--mena-muted, #8898aa);
	font-size: 14px;
	line-height: 1;
	cursor: pointer;
}

.sat-modal .sat-chip__x:hover { background: var(--mena-rose, #f5365c); color: #fff; }

/* The typing field is the rest of the box rather than a box inside it. */
.sat-modal .sat-chips .sat-chips__in {
	flex: 1 1 90px;
	min-width: 90px;
	width: auto;
	/* Not a fixed 28: the hint inside it is Arabic, and a box that cannot grow
	   is a box that crops. */
	height: auto;
	min-height: 30px;
	padding: 2px;
	line-height: 1.95;
	border: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none !important;
	outline: none;
}

/* --------------------------------------------------------- channel blocks */

.sat-chanrows { display: grid; gap: 12px; }

.sat-chanrow {
	position: relative;
	padding: 14px;
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 12px;
	background: var(--mena-elevated, #fff);
}

.sat-chanrow__x {
	position: absolute;
	inset-block-start: 8px;
	inset-inline-end: 8px;
}

.sat-drop {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: var(--mena-muted, #8898aa);
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
}

.sat-drop:hover { background: rgba(245, 54, 92, .12); color: var(--mena-rose, #f5365c); }

.sat-more { margin-top: 12px; }

/*
 * The audio tracks.
 *
 * A channel can carry six of them and the column stores all six run together
 * as "PID:101;Language:Arabic;Audio:MPEG<br>PID:102;…". Asked for as a small
 * repeating row instead: a PID, a language, a codec, and a cross to drop it.
 * The grid is fixed rather than auto-fit so the three columns stay under the
 * same three headings down the stack — a PID that has wrapped under a language
 * on the row above is unreadable.
 */
.sat-trks {
	margin: 4px 14px 0;
	padding-top: 12px;
	border-top: 1px dashed var(--mena-border, #e6e6ec);
}

.sat-trks__t {
	margin: 0 0 8px;
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: .02em;
	color: var(--mena-muted, #8898aa);
}

.sat-trk {
	display: grid;
	grid-template-columns: 88px minmax(0, 1fr) minmax(0, 1.4fr) 26px;
	align-items: end;
	gap: 10px;
}

.sat-trk + .sat-trk { margin-top: 8px; }

/* The label row is printed once, on the first track — repeating "PID / اللغة /
   الترميز" above every line turns four fields into a wall of captions. */
.sat-trk + .sat-trk .sat-f > span { display: none; }

.sat-trk__x { margin-bottom: 1px; }

.sat-trks__add { margin: 10px 14px 14px; }

@media (max-width: 560px) {
	.sat-trk {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 26px;
	}

	.sat-trk > .sat-f:first-child { grid-column: 1 / -1; }
	.sat-trk + .sat-trk .sat-f > span { display: block; }
	.sat-trk + .sat-trk { margin-top: 14px; padding-top: 12px; border-top: 1px dotted var(--mena-border, #e6e6ec); }
}

/*
 * The tick list, and the box that narrows it.
 *
 * The filter sits outside the scroller rather than sticky inside it: a sticky
 * search field inside a 300px box overlaps the first row every time the list is
 * scrolled back to the top, and the row it hides is the one just ticked.
 */
.sat-picklist {
	display: grid;
	gap: 2px;
	max-height: 260px;
	margin-top: 8px;
	padding: 4px;
	overflow-y: auto;
	overscroll-behavior: contain;
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 11px;
	background: var(--mena-surface, #f7f7f9);
}

.sat-picklist__rows { display: grid; gap: 2px; }

.sat-listq {
	width: 100%;
	box-sizing: border-box;
	height: auto;
	min-height: 42px;
	padding: 8px 11px;
	font: inherit;
	font-size: 13px;
	line-height: 1.95;
	color: var(--mena-text, #1a1a1a);
	background: var(--mena-control-bg, #fff);
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 9px;
	outline: none;
}

.sat-listq:focus {
	border-color: var(--mena-gold, #ffd014);
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .22);
}

/* Inside the dialog the checkbox is a list item, not a filter chip. */
.sat-check--plain { padding: 7px 9px; border-radius: 8px; }
.sat-check--plain:hover { background: var(--mena-surface-2, #eff0f4); }

/* The one that was searched for, lit so the eye finds it among its neighbours.
   It arrives ticked; this says which of the ticks the reader did not make. */
.sat-check--plain.is-found {
	background: var(--mena-gold-soft, rgba(255, 208, 20, .14));
	box-shadow: inset 0 0 0 1px var(--mena-gold, #ffd014);
}

/* --------------------------------------------------- finding by name */

/*
 * The second way to answer "which transponder".
 *
 * Set below the two pickers and separated by a rule, because it is an
 * alternative to them rather than a third question: answering here fills them
 * in. Quieter than they are — smaller label, no border until it is used —
 * since most readers know their transponder and should not be made to read
 * past this to reach it.
 */
.sat-hunt {
	margin-top: 16px;
	padding-top: 14px;
	border-top: 1px dashed var(--mena-border, #e6e6ec);
}

.sat-hunt__t {
	margin: 0 0 7px;
	font-size: 12px;
	font-weight: 600;
	color: var(--mena-muted, #8898aa);
}

.sat-hunt__in {
	width: 100%;
	box-sizing: border-box;
	height: auto;
	min-height: 42px;
	padding: 8px 11px;
	font: inherit;
	font-size: 13px;
	line-height: 1.95;
	color: var(--mena-text, #1a1a1a);
	background: var(--mena-control-bg, #fff);
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 9px;
	outline: none;
}

.sat-hunt__in:focus {
	border-color: var(--mena-gold, #ffd014);
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .22);
}

.sat-hunt__out:not(:empty) { margin-top: 8px; }

.sat-hunt__none {
	margin: 0;
	padding: 10px 2px;
	font-size: 12.5px;
	color: var(--mena-muted, #8898aa);
}

/* The hits scroll rather than push the two steps below them off the screen. */
.sat-hits {
	display: grid;
	gap: 3px;
	max-height: 232px;
	padding: 4px;
	overflow-y: auto;
	overscroll-behavior: contain;
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 11px;
	background: var(--mena-surface, #f7f7f9);
}

/*
 * A hit is the name and where it was found, on two lines.
 *
 * The transponder is the half of this that matters — the name is what was
 * typed, and four rows carrying the same name differ only in the line beneath
 * it. So the two are separated rather than run together, and the frequency is
 * forced LTR: "11180 V 27500" is a number, a letter and a number, and an RTL
 * run reorders it to something no receiver ever showed.
 */
.sat-hit {
	display: grid;
	gap: 2px;
	width: 100%;
	padding: 8px 10px;
	border: 0;
	border-radius: 8px;
	background: transparent;
	color: inherit;
	font: inherit;
	text-align: inherit;
	cursor: pointer;
	transition: background .14s ease;
}

.sat-hit:hover,
.sat-hit:focus-visible {
	background: var(--mena-surface-2, #eff0f4);
	outline: none;
}

.sat-hit__n {
	font-size: 13px;
	font-weight: 700;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.sat-hit__m {
	display: flex;
	align-items: center;
	gap: 7px;
	font-size: 11.5px;
	color: var(--mena-muted, #8898aa);
}

/*
 * The dot between the satellite and its transponder, as its own element.
 *
 * It began as a ::before on the frequency, and the frequency carries dir="ltr"
 * so a transponder reads as a transponder — which made the dot's inline-start
 * the left edge of a span sitting at the left end of an RTL line, and put it
 * outside the pair it was meant to divide. A flex item of its own has no
 * direction to be wrong about: it is simply the middle one of three.
 */
.sat-hit__dot {
	flex: none;
	width: 3px;
	height: 3px;
	border-radius: 50%;
	background: currentColor;
	opacity: .55;
}

.sat-hit__s {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.sat-hit__f { flex: none; font-weight: 600; }

/* ------------------------------------------------------------- the picker */

/*
 * Type to narrow, click or arrow-key to pick.
 *
 * This replaced a filter box sitting above a <select>, which asked for two
 * gestures to make one choice and, on a phone, opened a full-screen wheel of
 * sixty numbers as the second. Here the field is the search and the answer both
 * — what was chosen stays legible in it without opening anything.
 */
.sat-pick__box { position: relative; }

/*
 * Two classes deep, and logical padding.
 *
 * The general `.sat-modal input[type="text"]` rule above outweighs a plain
 * `.sat-modal .sat-pick__input`, so the padding stated here lost and the caret
 * was drawn on top of the first letters of the satellite's name. Matching the
 * attribute too puts this ahead of it. The gap is on the inline-end side
 * because that is where a <select> puts its arrow in this direction, and the
 * two controls share rows.
 */
.sat-modal .sat-pick input[type="text"] {
	width: 100%;
	box-sizing: border-box;
	/* A floor and room to grow, for the reason given on the plain fields above:
	   a fixed height plus a fixed line box crops whatever font turns out to be
	   in use, and it crops the descenders first. */
	height: auto;
	min-height: 42px;
	padding-block: 8px;
	padding-inline-start: 11px;
	padding-inline-end: 36px;
	font: inherit;
	line-height: 1.95;
	font-size: 13.5px;
	color: var(--mena-text, #1a1a1a);
	background: var(--mena-control-bg, #fff);
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 9px;
	outline: none;
	cursor: pointer;
}

.sat-pick__input:focus {
	border-color: var(--mena-gold, #ffd014);
	box-shadow: 0 0 0 3px rgba(255, 208, 20, .22);
	cursor: text;
}

.sat-pick__input:disabled {
	opacity: 1;
	color: var(--mena-muted, #8898aa);
	background: var(--mena-surface, #f7f7f9);
	cursor: default;
}

/* A transponder reads left to right — "10922 V 27500" is a number, a letter and
   a number, and the RTL dialog was reordering it to "V 27500 10922". */
.sat-pick--ltr .sat-pick__input { direction: ltr; text-align: right; }
.sat-pick--ltr .sat-pick__input::placeholder { direction: rtl; }

/* The chevron sits under the clear button and swaps out for it. Same corner,
   so the control has one affordance at a time rather than two competing. */
.sat-pick__caret {
	position: absolute;
	inset-inline-end: 10px;
	top: 50%;
	transform: translateY(-50%);
	width: 18px;
	height: 18px;
	padding: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
}

/*
 * Down is down in both directions.
 *
 * These were logical borders — inline-end and block-end — which in an Arabic
 * dialog resolve to the left and bottom edges, and a left-and-bottom corner
 * turned forty-five degrees points sideways. The chevron on both pickers was a
 * "‹" where a "v" belonged, hidden until now only because a clear button that
 * should not have been there was sitting on top of it. A caret says which way
 * the menu opens, and the menu opens downwards whatever the language.
 */
.sat-pick__caret::before {
	content: "";
	position: absolute;
	inset-inline-start: 4px;
	top: 4px;
	width: 8px;
	height: 8px;
	border-right: 1.7px solid var(--mena-muted, #8898aa);
	border-bottom: 1.7px solid var(--mena-muted, #8898aa);
	transform: rotate(45deg);
	transition: transform .15s ease;
}

.sat-pick.is-open .sat-pick__caret::before { transform: rotate(-135deg) translate(-2px, -2px); }

.sat-pick__clear {
	position: absolute;
	inset-inline-end: 8px;
	top: 50%;
	transform: translateY(-50%);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: var(--mena-surface-2, #eff0f4);
	color: var(--mena-muted, #8898aa);
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
	z-index: 1;
}

.sat-pick__clear:hover { color: var(--mena-text, #1a1a1a); }

/*
 * `hidden` is a display:none the UA sets, so any author `display` beats it.
 *
 * This is why a clear button appeared on both pickers before anything had been
 * chosen: the script set `hidden`, and `display: inline-flex` two rules above
 * quietly overrode it — a × offering to erase an empty field, sitting where the
 * chevron that opens the list should have been. The rule has to be stated for
 * every element given a display of its own; nothing else re-hides it.
 */
.sat-modal .sat-pick__clear[hidden] { display: none; }

/* The chevron gives way to the × rather than sitting under it. */
.sat-pick__box:has(.sat-pick__clear:not([hidden])) .sat-pick__caret { opacity: 0; }

/*
 * The list is being fetched.
 *
 * A picker whose transponders are still on their way used to say so in the
 * placeholder — a line of Arabic in a box that looked ready to type in. A
 * turning ring in the corner where the chevron sits is the same statement in
 * the place the reader is already looking, and it cannot be mistaken for a
 * value.
 */
.sat-pick.is-busy .sat-pick__caret::before { display: none; }

.sat-pick.is-busy .sat-pick__caret::after {
	content: "";
	position: absolute;
	inset: 1px;
	border-radius: 50%;
	border: 1.8px solid var(--mena-line, rgba(16, 24, 40, .14));
	border-top-color: var(--mena-gold, #ffd014);
	animation: sat-spin .7s linear infinite;
}

@keyframes sat-spin { to { transform: rotate(360deg); } }

/*
 * A spinner for anything else that is in flight.
 *
 * The dialog's first paint is covered by a form-shaped skeleton, which is right
 * for a shape that is known. Everything after it — a transponder's channels, a
 * report on its way to the server — is a wait of unknown length in a place that
 * already has content, and there a ring with a word beside it says "working"
 * without pretending to know what is coming.
 */
.sat-busy {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	padding: 26px 0;
	color: var(--mena-muted, #8898aa);
	font-size: 13px;
	font-weight: 600;
}

.sat-busy::before {
	content: "";
	flex: none;
	width: 17px;
	height: 17px;
	border-radius: 50%;
	border: 2px solid var(--mena-line, rgba(16, 24, 40, .14));
	border-top-color: var(--mena-gold, #ffd014);
	animation: sat-spin .7s linear infinite;
}

/* The send button, while the report is being posted. The label stays — a button
   that empties itself mid-click reads as a button that has broken. */
.sat-btn.is-busy { pointer-events: none; opacity: .75; }

.sat-btn.is-busy::before {
	content: "";
	width: 14px;
	height: 14px;
	margin-inline-end: 7px;
	border-radius: 50%;
	border: 2px solid rgba(0, 0, 0, .18);
	border-top-color: currentColor;
	animation: sat-spin .7s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
	.sat-pick.is-busy .sat-pick__caret::after,
	.sat-busy::before,
	.sat-btn.is-busy::before { animation-duration: 2s; }
}

/*
 * The menu floats, and belongs to the dialog rather than to the field.
 *
 * Absolutely positioned under its input it was clipped by the first ancestor
 * that scrolled — which, in a dialog whose body scrolls, is always. Fixed to
 * the viewport it escapes the scroll box; parented to the <dialog> it stays in
 * the top layer, where anything hung off <body> would paint behind the
 * backdrop. The script places it and flips it above the field when the room
 * below has run out.
 */
.sat-pick__menu {
	position: fixed;
	/* border-box, because the script sets max-height from the pixels actually
	   left below the field — padding and border on top of that is the overflow
	   it was measuring to avoid. */
	box-sizing: border-box;
	z-index: 10;
	max-height: 260px;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 5px;
	border: 1px solid var(--mena-border, #e6e6ec);
	border-radius: 11px;
	background: var(--mena-elevated, #fff);
	box-shadow: var(--mena-shadow-lg, 0 12px 48px rgba(16, 24, 40, .18));

	/*
	 * It grows out of the field rather than appearing over it.
	 *
	 * `hidden` is overridden back to a real display so the box has somewhere to
	 * animate from and to — a menu that only animates open flickers shut, which
	 * reads worse than no movement at all. `visibility` is what actually takes
	 * it out of the page: it flips at the end of the fade, so the box is gone
	 * from the pointer and from a screen reader the moment it stops being seen.
	 *
	 * The origin is the top edge, because that is where the menu is anchored;
	 * flipped above the field it gets the other origin to match.
	 */
	opacity: 1;
	visibility: visible;
	transform: translateY(0) scaleY(1);
	transform-origin: top center;
	transition: opacity .16s ease,
				transform .16s cubic-bezier(.22, 1, .36, 1),
				visibility .16s;
}

.sat-pick__menu--up { transform-origin: bottom center; }

.sat-pick__menu[hidden] {
	display: block;
	opacity: 0;
	visibility: hidden;
	transform: translateY(-4px) scaleY(.97);
	pointer-events: none;
}

.sat-pick__menu--up[hidden] { transform: translateY(4px) scaleY(.97); }

@media (prefers-reduced-motion: reduce) {
	.sat-pick__menu { transition: none; }
	.sat-pick__menu[hidden] { display: none; }
}

.sat-pick__opt {
	padding: 9px 10px;
	border-radius: 8px;
	font-size: 13px;
	cursor: pointer;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.sat-pick__menu--ltr .sat-pick__opt { direction: ltr; text-align: right; }

.sat-pick__opt.is-on { background: var(--mena-gold, #ffd014); color: #1a1a1a; }

.sat-pick__none {
	padding: 12px;
	font-size: 12.5px;
	color: var(--mena-muted, #8898aa);
	text-align: center;
}

/* -------------------------------------------------------------- the reply */

.sat-modal__hint {
	margin: 0;
	padding: 14px;
	border: 1px dashed var(--mena-border, #e6e6ec);
	border-radius: 11px;
	font-size: 12.5px;
	color: var(--mena-muted, #8898aa);
	text-align: center;
}

.sat-modal__said {
	flex: none;
	margin: 0 22px;
	padding: 10px 13px;
	border-radius: 9px;
	font-size: 13px;
}

.sat-modal__said.is-ok  { background: var(--mena-info-bg, #e3edf2); color: var(--mena-info-text, #325867); }
.sat-modal__said.is-bad { background: rgba(245, 54, 92, .12); color: var(--mena-rose, #f5365c); }

.sat-modal__foot {
	flex: none;
	display: flex;
	justify-content: flex-end;
	gap: 8px;
	margin-top: 14px;
	padding: 14px 22px;
	border-top: 1px solid var(--mena-border, #e6e6ec);
	background: var(--mena-elevated, #fff);
	border-radius: 0 0 16px 16px;
}

.sat-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 40px;
	padding: 0 20px;
	border: 1px solid var(--mena-control-border, #cfd4dd);
	border-radius: 999px;
	background: var(--mena-control-bg, #fff);
	color: var(--mena-text, #1a1a1a);
	font: inherit;
	font-size: 13.5px;
	font-weight: 600;
	cursor: pointer;
	transition: background .15s ease, border-color .15s ease, transform .12s ease;
}

.sat-btn:active { transform: translateY(1px); }

.sat-btn--ghost { background: transparent; }
.sat-btn--sm { height: 32px; padding: 0 14px; font-size: 12.5px; }

.sat-btn--go {
	background: var(--mena-gold, #ffd014);
	border-color: var(--mena-gold, #ffd014);
	color: #1a1a1a;
}

.sat-btn:disabled { opacity: .55; cursor: default; }
.sat-btn:disabled { opacity: .55; cursor: default; }

/* The date at the foot of a satellite cell: current or not, asked and answered. */
.sat-when {
	font-style: italic;
	font-size: 11px;
	font-weight: 500;
	color: var(--mena-muted, #8898aa);
}

/* ============================ the control bar, on a phone */

/*
 * Below the breakpoint the panel is the question, and the answers to it are
 * outside.
 *
 * On a wide screen one bordered row holds all three: where the dish points,
 * the button that adds an update, and the picker for how to read the chart.
 * Stacked on a phone they become three lines inside a box, and a box around
 * three unrelated lines reads as one long question. So the bar stops being a
 * panel and hands the card treatment to the positions alone — the button and
 * the picker then sit on the page, which is where controls that act on
 * everything below them belong.
 */
@media (max-width: 700px) {
	.sat-bar {
		border: 0;
		border-radius: 0;
		background: none;
		overflow: visible;
		margin-bottom: 12px;
	}

	.sat-bar__row {
		grid-template-columns: minmax(0, 1fr);
		gap: 10px;
		padding: 0;
	}

	/* The panel, now that the bar is not one. */
	.sat-bar__pos {
		grid-template-columns: minmax(0, 1fr);
		gap: 8px;
		padding: 11px 14px;
		border: 1px solid var(--mena-border, #e6e6ec);
		border-radius: 12px;
		background: var(--mena-surface, #f7f7f9);
	}

	/*
	 * Above the positions, not below them.
	 *
	 * Source order puts the controls last because on a wide screen they are the
	 * far end of the same row. Stacked, last means underneath — and both of
	 * them act on everything on the page, including the panel they were sitting
	 * under. Reordered rather than moved, so the markup and the desktop row
	 * stay as they are.
	 *
	 * The button takes the room, the picker takes the corner. Two controls of
	 * equal width would read as a pair of alternatives, which they are not —
	 * one adds something, the other changes how the page looks.
	 */
	.sat-bar__end {
		order: -1;
		justify-content: space-between;
		gap: 10px;
		padding-inline: 2px;
	}

	.sat-contribute {
		flex: 1 1 auto;
		justify-content: center;
	}

	.sat-switch { flex: none; }
}

/* ================== the frequency layout, on a phone */

/*
 * :not(.freq-block--flat) on every selector below, and it is not decoration.
 *
 * Both views draw their tables inside a .freq-block — the full table is one
 * block for the whole position — so an unqualified .freq-block .sat-table rule
 * reaches the other view as well. Unscoped, the accordion collapsed the full
 * table's satellite, frequency and beam cells to nothing and hung a chevron off
 * every channel in it.
 *
 * One card per frequency, not a card of cards.
 *
 * Below 768px the theme turns every table on the site into blocks and gives
 * each row a border and a 15px gap — right for a table standing on its own,
 * doubled up inside .freq-block, which already draws a border around the whole
 * transponder. The result was an outer rule, an inner rule and a channel of
 * white between the two. The rows give theirs up: the block is the card and the
 * channels are its rows.
 */
@media (max-width: 768px) {
	.freq-block:not(.freq-block--flat) .sat-table tr {
		margin-bottom: 0;
		border: 0;
		background: transparent;
	}

	.freq-block:not(.freq-block--flat) .sat-table tbody tr + tr {
		border-top: 1px solid var(--mena-border, #e6e6ec);
	}

	.freq-block:not(.freq-block--flat) .sat-table td { border-bottom: 0; }

	/* The note on a transponder carrying nothing. It is a statement about the
	   whole block, so it sits under the middle of it rather than at one end. */
	.freq-block:not(.freq-block--flat) .sat-quiet {
		display: block;
		justify-content: center;
		text-align: center;
		padding: 14px;
	}

	/*
	 * Each channel opens and closes.
	 *
	 * A transponder can carry forty channels and each one stacks into seven
	 * labelled lines on a phone — three hundred rows to scroll past to reach
	 * the next frequency. Closed, the block is its list of channels; the row a
	 * reader taps is the one that expands. The name, the lock and the quality
	 * badge stay on the header line, which is everything needed to pick one.
	 *
	 * Closed is the CSS default rather than a state applied by script, so rows
	 * arriving from a filter change are closed the moment they render, with no
	 * frame of everything open first.
	 */
	/*
	 * :not(.sat-quiet) matters. A transponder carrying nothing renders one row
	 * whose only cell is the note — no channel name, so no header to open it
	 * from. Treated as a detail it would be collapsed to nothing and the block
	 * would become a title with empty space under it.
	 *
	 * The animation is max-height, not display, and not the 0fr-to-1fr grid
	 * trick used elsewhere in this codebase. That trick needs the collapsing
	 * box and the clipping box to be two elements: the item shrinks to nothing
	 * only with min-height:0 and overflow:hidden on it, and with both set the
	 * track can no longer measure the content it is supposed to size itself to
	 * — it resolves to the padding and the row opens to a twelfth of its
	 * height. There is no wrapper to add here; a <td> is what a table row can
	 * hold. So each cell is capped instead, generously enough for the two lines
	 * any of these fields can run to, with the audio cell — several tracks, one
	 * per line — given room of its own.
	 *
	 * The padding goes with it. A cell clipped to zero still lays out its own
	 * padding, and eight of them at 5px top and bottom is 80px of closed row,
	 * which is what a shut accordion must not be.
	 */
	.freq-block:not(.freq-block--flat) .sat-table tbody tr > td:not(.ch-name):not(.sat-quiet):not(.lock-cell):not(.qlty-cell):not(:empty) {
		display: flex;
		overflow: hidden;
		max-height: 0;
		padding-block: 0;
		opacity: 0;
		background: var(--mena-surface-2, #eff0f4);
		transition:
			max-height .26s cubic-bezier(.22, 1, .36, 1),
			padding .26s cubic-bezier(.22, 1, .36, 1),
			opacity .18s ease;
	}

	.freq-block:not(.freq-block--flat) .sat-table tbody tr.is-open > td:not(.ch-name):not(.sat-quiet):not(.lock-cell):not(.qlty-cell):not(:empty) {
		max-height: 4rem;
		padding-block: 5px;
		opacity: 1;
	}

	.freq-block:not(.freq-block--flat) .sat-table tbody tr.is-open > td.audio-cell { max-height: 14rem; }

	/*
	 * The lock and the quality badge are already on the name line, and the
	 * theme hides both at this width. They are excluded from the rules above
	 * rather than hidden again after them: a :not() costs nothing, while a
	 * second display:none would have to out-specify the first rule to win —
	 * which is exactly the way round it went the first time, and the open row
	 * grew two empty captions saying LOCK and RES.
	 */

	.freq-block:not(.freq-block--flat) .sat-table tbody tr.is-open > td + td:not(.lock-cell):not(.qlty-cell) {
		border-top: 1px solid var(--mena-border-soft, #f0f0f4);
	}

	/*
	 * An empty cell is not a row.
	 *
	 * The guide and live columns are filled only for channels the platform
	 * knows about; for the rest the server emits <td></td>, which stacked
	 * became a caption with nothing after it — two blank lines in every one of
	 * these that opened. :empty is exact here because those cells really are
	 * empty: no text, no whitespace, nothing.
	 *
	 * It is a rule of its own rather than another :not() because the selector
	 * above is already carrying five, and display:none has to win against it —
	 * which a shorter selector cannot do.
	 */
	.freq-block:not(.freq-block--flat) .sat-table tbody tr > td:empty { display: none; }

	/*
	 * The name is a label, not a headline. Bold was the theme's treatment for a
	 * table cell standing in for a heading; here the row IS the heading and the
	 * weight was making a list of forty channels shout.
	 *
	 * White, too. It was the theme's grey, which put the header and the details
	 * on two shades of the same colour and left the reader working out which
	 * band went with which. The card is white and the detail rows are tinted;
	 * the name line belongs to the card.
	 */
	.freq-block:not(.freq-block--flat) .sat-table td.ch-name {
		font-weight: 400;
		background: var(--mena-elevated, #fff);
	}

	.freq-block:not(.freq-block--flat) .sat-table td.ch-name {
		position: relative;
		padding-inline-end: 34px;
		cursor: pointer;
		user-select: none;
		-webkit-tap-highlight-color: transparent;
	}

	/* A chevron drawn from two borders: no glyph to load, and it turns rather
	   than being swapped for a different mark. */
	.freq-block:not(.freq-block--flat) .sat-table td.ch-name::after {
		content: "";
		position: absolute;
		inset-inline-end: 13px;
		top: 50%;
		width: 7px;
		height: 7px;
		margin-top: -5px;
		border-right: 2px solid var(--mena-muted, #8898aa);
		border-bottom: 2px solid var(--mena-muted, #8898aa);
		transform: rotate(45deg);
		transform-origin: center;
		transition: transform .2s ease;
	}

	.freq-block:not(.freq-block--flat) .sat-table tbody tr.is-open td.ch-name::after {
		margin-top: -2px;
		transform: rotate(225deg);
	}

	.freq-block:not(.freq-block--flat) .sat-table td.ch-name:focus-visible {
		outline: 2px solid var(--mena-gold-text, #a97d00);
		outline-offset: -2px;
	}
}

@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
	.freq-block:not(.freq-block--flat) .sat-table td.ch-name::after { transition: none; }
}

/* ============ the tables scroll rather than crush their columns */

/*
 * Between the phone layout and a comfortable desktop there is a band where the
 * blocks view has nine fixed columns and not enough room for them. The name
 * column is the one left on auto, so it absorbs the shortfall and collapses —
 * at 800px the header came out as CHA/NNE/L, one letter a line, and the channel
 * names underneath it did the same. Below the theme's own breakpoint the table
 * is stacked and none of this applies.
 */
@media (min-width: 769px) and (max-width: 1080px) {
	/*
	 * The fixed columns are trimmed first, and only what will not fit after
	 * that scrolls.
	 *
	 * A scrollbar on a table that almost fits is worse than a slightly tighter
	 * Encryption column, and every width here is set for a desktop where there
	 * are 1200px to spend. Cut to what each field actually needs, the nine
	 * columns leave the names something like 280px instead of the 90 they had
	 * — which is the difference between two words on a line and one letter.
	 */
	/*
	 * Written twice, once per view, and that is not an oversight.
	 *
	 * These started as one set on `.sat-table` — simpler to read, and it
	 * silently did nothing. The general widths above are written
	 * `.sat-table:not(.sat-table--flat)`, and a :not() counts as a class: they
	 * score higher than a bare `.sat-table` here, both media queries match in
	 * this band, and the wider desktop widths won every time. The trims have
	 * to match the specificity of what they are trimming.
	 */
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--epg  { width: 36px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--live { width: 42px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--lock { width: 28px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--enc  { width: 84px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--res  { width: 44px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--vid  { width: 112px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--vpid { width: 52px; }
	[data-sat-table] .sat-table:not(.sat-table--flat) .sat-col--aud  { width: 112px; }

	[data-sat-table] .sat-table--flat .sat-col--epg  { width: 36px; }
	[data-sat-table] .sat-table--flat .sat-col--live { width: 42px; }
	[data-sat-table] .sat-table--flat .sat-col--lock { width: 28px; }
	[data-sat-table] .sat-table--flat .sat-col--enc  { width: 84px; }
	[data-sat-table] .sat-table--flat .sat-col--res  { width: 44px; }
	[data-sat-table] .sat-table--flat .sat-col--vid  { width: 112px; }
	[data-sat-table] .sat-table--flat .sat-col--vpid { width: 52px; }
	[data-sat-table] .sat-table--flat .sat-col--aud  { width: 112px; }

	/*
	 * And the three the full table carries on its own. They were left out
	 * when this band was written for the blocks view, which does not have
	 * them — so the one view that was actually short of room was the one that
	 * kept its desktop widths.
	 */
	[data-sat-table] .sat-table--flat .sat-col--sat  { width: 92px; }
	[data-sat-table] .sat-table--flat .sat-col--tune { width: 112px; }
	[data-sat-table] .sat-table--flat .sat-col--beam { width: 112px; }

	/* The floor. Below this the columns have been trimmed as far as they read,
	   and the table moves sideways rather than shrinking further. */
	.freq-scroll {
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	/*
	 * 640 was the sum of the fixed columns and nothing else, which is the one
	 * number that guarantees a zero-width name column. The columns are trimmed
	 * in this band, so the same 190px of name costs less here than it does
	 * above it.
	 */
	.freq-scroll .sat-table:not(.sat-table--flat) { min-width: 780px; }

	/* The full table's own floor. Auto layout will otherwise keep squeezing
	   past the trimmed widths above rather than letting the table move, and
	   the codec column reads no better at 66px than the names did at zero. */
	.freq-scroll .sat-table--flat { min-width: 1000px; }
}

/* The combined transponder column exists only for the narrow layout. */
.sat-span--all,
th.sat-col--all { display: none; }

/* ------------------------------- the full table, on a phone */

/*
 * The full table stays a table.
 *
 * Everywhere else on the site the theme unpacks a table into stacked blocks on
 * a phone, and for the blocks view that is right — each channel becomes a card.
 * This view exists to be read across: a transponder, then every channel on it,
 * with the figures lining up down the columns. Stacked, that is precisely what
 * is lost. So it keeps its shape and moves sideways instead, with the columns
 * naming the transponder pinned so a row scrolled halfway across still says
 * what it belongs to.
 *
 * No !important anywhere below: .freq-block--flat in front of each selector is
 * one class more than the theme's, which is all it takes.
 */
@media (max-width: 768px) {
	.freq-block--flat .freq-scroll {
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	/* No min-width: with four columns the table fits, and a table that fits is
	   one nobody has to drag sideways to finish reading. */
	.freq-block--flat .sat-table--flat { display: table; min-width: 0; width: 100%; }
	.freq-block--flat .sat-table--flat thead,
	.freq-block--flat .sat-table--flat .sat-table-heading { display: table-header-group; }
	.freq-block--flat .sat-table--flat tbody { display: table-row-group; }

	.freq-block--flat .sat-table--flat tr {
		display: table-row;
		margin: 0;
		border: 0;
		background: transparent;
	}

	.freq-block--flat .sat-table--flat td,
	.freq-block--flat .sat-table--flat th {
		display: table-cell;
		text-align: start;
		vertical-align: middle;
	}

	/* The captions belong to the stacked layout; here the header row says it. */
	.freq-block--flat .sat-table--flat td::before { content: none; }

	.freq-block--flat .sat-table--flat td.ch-name {
		display: table-cell;
		font-size: 13px;
		font-weight: 400;
		line-height: 1.4;
		background: transparent;
	}

	/* A list of forty names wants air between them more than it wants to fit
	   two more on the screen. */
	.freq-block--flat .sat-table--flat > tbody > tr > td.ch-name { padding-block: 9px; }
	.freq-block--flat .sat-table--flat .sat-span--all { padding-block: 10px; }

	/*
	 * Two columns, and the rest on demand.
	 *
	 * Thirteen columns on a 375px screen were a hundred pixels of table and
	 * six hundred of sideways scrolling — a row you could read a third of at a
	 * time and never against its own heading. What is left is what picks a
	 * channel out of a list: which transponder it is on, and its name. The
	 * guide and live marks went with the rest into the panel: they belong to
	 * four channels in six hundred, and holding two columns open across every
	 * row for them cost the names more width than the marks were worth.
	 *
	 * Written as an exclusion rather than a list of columns to hide, so a
	 * column added by another plugin lands in the panel instead of quietly
	 * widening the table again. Both halves matter: a heading with no cells
	 * under it is still a column, and every column after it would line up one
	 * place off from its own row.
	 *
	 * Child combinators throughout: the panel these columns move into is
	 * itself a small table, and an unscoped descendant selector reached into
	 * it and hid its heading row and its values — the panel opened to
	 * thirteen pixels of nothing.
	 */
	.freq-block--flat .sat-table--flat > tbody > tr:not(.sat-flat-more) > td:not(.sat-span):not(.ch-name):not(.sat-quiet),
	.freq-block--flat .sat-table--flat > thead > tr > th:not(.sat-col--all):not(.sat-col--ch) { display: none; }


	/*
	 * The pinned columns.
	 *
	 * border-collapse is collapse on this table, and a collapsed border does
	 * not travel with a sticky cell — it belongs to the table's border grid and
	 * stays where it was drawn. The divider at the pinned edge is a box-shadow
	 * for that reason. It is a physical -1px because the shadow has to fall on
	 * the side the rest of the table scrolls under, which in this right-to-left
	 * table is the left.
	 */
	.freq-block--flat .sat-table--flat .sat-span,
	.freq-block--flat .sat-table--flat th.sat-col--sat,
	.freq-block--flat .sat-table--flat th.sat-col--tune,
	.freq-block--flat .sat-table--flat th.sat-col--beam {
		position: sticky;
		z-index: 2;
		background: var(--mena-elevated, #fff);
		font-size: 11px;
	}

	.freq-block--flat .sat-table--flat th.sat-col--sat,
	.freq-block--flat .sat-table--flat th.sat-col--tune,
	.freq-block--flat .sat-table--flat th.sat-col--beam {
		background: var(--mena-surface-2, #eff0f4);
		z-index: 3;
	}

	/*
	 * One pinned column, not three.
	 *
	 * Three of them came to 238px of a 375px screen and left about a hundred
	 * to scroll in, which is a pinned column that has eaten the thing it was
	 * pinned beside. The same three facts stack inside one cell instead — the
	 * satellite, the tuning, the beam — at 118px and a size down, so two thirds
	 * of the screen is the part that moves.
	 */
	.freq-block--flat .sat-table--flat .sat-span--sat,
	.freq-block--flat .sat-table--flat .sat-span--tune,
	.freq-block--flat .sat-table--flat .sat-span--beam,
	.freq-block--flat .sat-table--flat th.sat-col--sat,
	.freq-block--flat .sat-table--flat th.sat-col--tune,
	.freq-block--flat .sat-table--flat th.sat-col--beam { display: none; }

	.freq-block--flat .sat-table--flat .sat-span--all,
	.freq-block--flat .sat-table--flat th.sat-col--all {
		display: table-cell;
		position: sticky;
		inset-inline-start: 0;
		z-index: 2;
		/* border-box, so the declared width is the rendered one — these cells
		   carry 5px of padding a side, and the table scrolls under this edge. */
		box-sizing: border-box;
		width: 118px;
		min-width: 118px;
		background: var(--mena-elevated, #fff);
		font-size: 10.5px;
		box-shadow: -1px 0 0 var(--mena-border, #e6e6ec);
	}

	.freq-block--flat .sat-table--flat th.sat-col--all {
		background: var(--mena-surface-2, #eff0f4);
		z-index: 3;
	}

	.freq-block--flat .sat-table--flat .sat-span {
		border-bottom: 1px solid var(--mena-border, #e6e6ec);
	}

	.freq-block--flat .sat-table--flat .sat-line {
		display: block;
		line-height: 1.5;
	}

	.freq-block--flat .sat-table--flat .sat-line--sat { font-weight: 700; }
	.freq-block--flat .sat-table--flat .sat-line--sub { color: var(--mena-muted, #8898aa); }

	/*
	 * The empty-transponder note travels with the pinned column.
	 *
	 * Its cell spans every scrolling column, so on a phone the sentence began
	 * about 120px in and ran off the right edge — a note nobody scrolls
	 * sideways to finish reading. Sticking it beside the pinned cell and
	 * capping it at what is left of the screen keeps it where it is read.
	 */
	.freq-block--flat .sat-table--flat td.sat-quiet {
		text-align: start;
		font-size: 11px;
	}

	/*
	 * The span carries the stickiness, not the cell: a table cell in an
	 * auto-layout table ignores max-width, so capping the td did nothing and
	 * the sentence kept its full 562px. An inline-block inside it obeys both.
	 */
	.freq-block--flat .sat-table--flat td.sat-quiet .sat-quiet__txt {
		display: inline-block;
		position: sticky;
		/* 118px: clear of the pinned column, which is what it would otherwise
		   sit underneath — a sticky offset is measured from the scrollport. */
		inset-inline-start: 118px;
		box-sizing: border-box;
		/*
		 * 175px is the page gutter on both sides plus the pinned column plus
		 * the cell padding. A sticky box cannot leave its own cell, and at the
		 * far end of the scroll the cell's right edge is the one that arrives —
		 * a wider span would be shoved back under the pinned column there.
		 */
		max-width: calc(100vw - 175px);
		white-space: normal;
	}

	/*
	 * The name line is the control that opens the row.
	 *
	 * Same chevron as the frequency layout, drawn from two borders: no glyph
	 * to load, and it turns rather than being swapped for a different mark.
	 * 12.5px and a lighter weight because this column is now the narrow one —
	 * the transponder beside it is pinned at 118px — and a bold 13px name set
	 * every second channel on two lines.
	 */
	.freq-block--flat .sat-table--flat td.ch-name {
		position: relative;
		font-size: 12.5px;
		padding-inline-end: 54px;
		cursor: pointer;
		user-select: none;
		-webkit-tap-highlight-color: transparent;
	}

	/*
	 * The quality badge and the chevron end the row, not the name.
	 *
	 * The theme folds the lock and the badge into the name cell as a block, so
	 * they landed under the name — and under a name that wrapped they landed a
	 * line lower still, which put the badge in a different place on every row.
	 * Taken out of the flow they sit against the end of the row, one under the
	 * other down the list, and the name wraps in the space left in front of
	 * them.
	 */
	.freq-block--flat .sat-table--flat td.ch-name .mobile-only {
		position: absolute;
		inset-inline-end: 22px;
		top: 50%;
		transform: translateY(-50%);
		display: flex;
		align-items: center;
		margin: 0;
		line-height: 1;
	}

	.freq-block--flat .sat-table--flat td.ch-name::after {
		content: "";
		position: absolute;
		inset-inline-end: 6px;
		top: 50%;
		width: 6px;
		height: 6px;
		margin-top: -5px;
		border-right: 2px solid var(--mena-muted, #8898aa);
		border-bottom: 2px solid var(--mena-muted, #8898aa);
		transform: rotate(45deg);
		transform-origin: center;
		transition: transform .2s ease;
	}

	.freq-block--flat .sat-table--flat tr.is-open td.ch-name::after {
		margin-top: -2px;
		transform: rotate(225deg);
	}

	.freq-block--flat .sat-table--flat td.ch-name:focus-visible {
		outline: 2px solid var(--mena-gold-text, #a97d00);
		outline-offset: -2px;
	}

	/*
	 * The row that opens underneath.
	 *
	 * A real <tr>, inserted by script and counted into the transponder cell's
	 * rowspan, rather than a box inside the name cell: the panel has to reach
	 * across the columns beside the name, and a cell cannot grow past its own
	 * column. The cell holds no padding of its own — the animation is on the
	 * div inside it, because a cell clipped to zero height still lays out its
	 * padding, and that padding is the shut accordion's height.
	 */
	.freq-block--flat .sat-table--flat tr.sat-flat-more > td {
		padding: 0;
		background: var(--mena-surface-2, #eff0f4);
		border-top: 1px solid var(--mena-border-soft, #f0f0f4);
	}

	/*
	 * Its own height, not a guess at a ceiling.
	 *
	 * max-height to a fixed 22rem meant a four-line panel crossed its real
	 * height in the first fifty milliseconds and then sat still for the rest
	 * of the duration — an open that snapped and a close that hung. Script
	 * measures the panel and publishes it as --sat-h on the row, so the
	 * distance travelled is the distance there is and the easing is felt over
	 * all of it. The fallback is only for the frame before script gets there.
	 */
	.freq-block--flat .sat-table--flat .sat-more {
		overflow: hidden;
		height: 0;
		transition: height .3s cubic-bezier(.22, 1, .36, 1);
	}

	.freq-block--flat .sat-table--flat tr.sat-flat-more.is-open .sat-more {
		height: var(--sat-h, auto);
	}

	/*
	 * The contents arrive a moment behind the box that holds them, and from
	 * slightly above it. A panel whose full contents are already painted at
	 * the first pixel of the opening reads as a jump-cut with a wipe over it;
	 * letting them fade down into the space as it appears is what makes the
	 * two read as one movement.
	 */
	.freq-block--flat .sat-table--flat .sat-more__in {
		opacity: 0;
		transform: translateY(-6px);
		transition:
			opacity .2s ease .04s,
			transform .3s cubic-bezier(.22, 1, .36, 1) .04s;
	}

	.freq-block--flat .sat-table--flat tr.sat-flat-more.is-open .sat-more__in {
		opacity: 1;
		transform: none;
	}

	/*
	 * One heading row over one row of values — not a stack of caption-and-value
	 * lines. Four fields read across in the order the wide table has them is
	 * three lines of panel; the same four stacked is eight, and the panel is
	 * then taller than the list it opened out of.
	 *
	 * table-layout: fixed shares the width out evenly and, more to the point,
	 * stops a long video codec from widening the column and taking the whole
	 * table with it — there is no room here for the table to grow into.
	 */
	.freq-block--flat .sat-table--flat .sat-more__tbl {
		display: table;
		/*
		 * Fixed, now that the fields come three to a line rather than all on
		 * one. Six of them shared across a 217px cell was 36px a column and
		 * every value broken to a glyph a line; three is 72px, which holds
		 * ENCRYPTION on one line and lets the codec string wrap like prose.
		 * Fixed also means no value can widen the panel — there is nothing
		 * here for it to widen into.
		 */
		table-layout: fixed;
		width: 100%;
		min-width: 0;
		border-collapse: collapse;
	}

	/* The theme unpacks tables into blocks at this width, and the rules that
	   put the full table back together are written for that one alone. */
	.freq-block--flat .sat-table--flat .sat-more__tbl tbody { display: table-row-group; }
	.freq-block--flat .sat-table--flat .sat-more__tbl tr {
		display: table-row;
		margin: 0;
		border: 0;
		background: transparent;
	}

	.freq-block--flat .sat-table--flat .sat-more__tbl th,
	.freq-block--flat .sat-table--flat .sat-more__tbl td {
		display: table-cell;
		padding: 2px 6px;
		text-align: start;
		vertical-align: top;
	}

	.freq-block--flat .sat-table--flat .sat-more__tbl th {
		padding-top: 8px;
		font-size: 8.5px;
		font-weight: 600;
		letter-spacing: .02em;
		text-transform: uppercase;
		color: var(--mena-muted, #8898aa);
	}

	/* The last line of values, and the panel wants a floor under it. */
	.freq-block--flat .sat-table--flat .sat-more__tbl tr.sat-more__vals:last-child td {
		padding-bottom: 9px;
	}

	/*
	 * A rule between one line of fields and the next, drawn under the values
	 * rather than over the headings: the gap above a heading belongs to the
	 * block it introduces, and a line there would have cut it off from it.
	 */
	.freq-block--flat .sat-table--flat .sat-more__tbl tr.sat-more__vals:not(:last-child) td {
		border-bottom: 1px solid var(--mena-border-soft, #f0f0f4);
	}

	/*
	 * break-word, not anywhere. `anywhere` lets the browser count a column's
	 * minimum width as one character, so every column shrank to its heading
	 * and "152 AR" came out as four lines of one glyph. break-word keeps the
	 * word as the unit and only breaks one that genuinely does not fit.
	 */
	.freq-block--flat .sat-table--flat .sat-more__tbl td {
		word-break: normal;
		overflow-wrap: break-word;
	}

	.freq-block--flat .sat-table--flat .sat-more__tbl td {
		font-size: 11px;
		line-height: 1.45;
		color: var(--mena-text, #1a1a1a);
	}

	/*
	 * Audio arrives as one row per track, packed to the end of its line — the
	 * theme lays it out that way for a column that is right-aligned in the
	 * wide table. Here it is a field in a panel among five others that start
	 * at the left, and one of the six ending at the right read as a mistake.
	 * Only the packing is overridden: the display is the theme's, with an
	 * !important on it, and it is the correct display anyway.
	 */
	.freq-block--flat .sat-table--flat .sat-more__tbl .aud-trk {
		justify-content: flex-start;
		gap: 3px;
	}
}

@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
	.freq-block--flat .sat-table--flat td.ch-name::after,
	.freq-block--flat .sat-table--flat .sat-more,
	.freq-block--flat .sat-table--flat .sat-more__in { transition: none; }

	.freq-block--flat .sat-table--flat .sat-more__in {
		opacity: 1;
		transform: none;
	}
}

/* ------------------------------------------------- the "what changed" dialog */

/*
 * The same bulletin the home page shows, in a box on this page.
 *
 * .mw-sat--bare drops the panel chrome the home card brings — the border, the
 * surface, the padding — because the dialog is already all three. Without it
 * the list arrives as a card inside a card, which reads as a mistake even when
 * nobody can say what it is.
 */
.sat-modal--log { max-width: 620px; width: min(620px, calc(100vw - 32px)); }

/*
 * The rows keep the dialog's own gutter.
 *
 * .mw-sat__row is inset by 2px, which is right in the home page's narrow rail
 * and is nothing at all in a 620px dialog — the text ran into the edge on one
 * side and the date into the other. Restoring the body's horizontal padding
 * lines every row up with the title above it and the button below it, which is
 * the alignment the eye is already using.
 */
.sat-modal--log .sat-modal__body { padding: 4px 22px 18px; }

/* A little more air than the rail gives them: there is room here, and these
   are separate events rather than a dense list to scan. */
.sat-modal--log .mw-sat__row { padding: 11px 2px; }

/*
 * !important, to answer !important.
 *
 * .mw-sat defends its two horizontal rules that way — they are the only lines
 * in the home page bulletin and it has to beat the news list around it. Inside
 * a dialog those rules are a line hard against the header and another hard
 * against the footer, so they have to go, and the only thing that reaches them
 * is the same weight they were set with.
 */
/*
 * No `padding` here, deliberately.
 *
 * This is the same element as .sat-modal__body — it carries both classes — and
 * an equally specific `padding: 0` further down the file quietly undid the
 * gutter set above it. .mw-sat has no padding of its own to strip anyway; what
 * needed stripping was the border and the background.
 */
.sat-modal--log .mw-sat--bare {
	border-top: 0 !important;
	border-bottom: 0 !important;
	background: none;
	box-shadow: none;
}

/* The count on the button, in the same pill the rest of the bar uses. */
.sat-contribute__n {
	min-width: 20px;
	padding: 1px 6px;
	border-radius: 999px;
	background: var(--mena-gold, #ffd014);
	color: var(--mena-on-gold, #1a1a1a);
	font-size: 11.5px;
	font-weight: 800;
	font-variant-numeric: tabular-nums;
	line-height: 1.6;
}

/* Reading, not writing: the log button is quieter than "add an update". */
.sat-contribute--log {
	background: var(--mena-surface, #f7f7f9);
	color: var(--mena-text, #1a1a1a);
}

.sat-log__note {
	margin-inline-end: auto;
	color: var(--mena-muted, #8898aa);
	font-size: 12px;
}
