/*
 * Stalls page (page-stalls.php) — map, legend, list and stall popup.
 *
 * Loaded only on the Stalls page, from the child theme's functions.php.
 * dist/all.min.css is untouched; nothing here overrides it, so no
 * !important is needed anywhere in this file.
 *
 * Conventions borrowed from the rest of the child theme: plain hex colours
 * (the theme defines no CSS custom properties), the brand red #e20213 and
 * blue #0086ca, and the three breakpoints dist/all.min.css already uses —
 * 1200px, 767px and 480px. The single structural breakpoint here is 767/768:
 * at 768px and up the popup is a centred modal, below it a bottom sheet. The
 * map itself is shown at every width.
 *
 * Type is the system UI stack rather than the theme's "brandon-grotesque",
 * which is a Typekit webfont: the numbers on the map and in the list are
 * small, and a face that arrives late reflows them. The one exception is the
 * facility marker, which stays serif — see .jm-stall-map__stall-label--facility.
 */

/* ---------------------------------------------------------------------------
   Type

   Setting the stack on each component was not enough: the child theme's
   style.css styles bare element names —

       h1, h2, h3, h4 { font-family: "brandon-grotesque", sans-serif; }
       p              { font-family: "brandon-grotesque", sans-serif; }

   — which reached the popup's <h2> title, the <p> inside its the_content
   markup, the <p> wrapping the nav-link button and the area <h2>s in the
   list, none of which carried a font-family of their own and so inherited
   nothing that could win.

   Those selectors have specificity (0,0,1). One class beats them, so a single
   scoped rule settles every descendant at once, including markup this
   stylesheet never sees (the_content inside the popup). No !important needed.

   Scoped strictly to the jm- roots: the page's hero, its own the_content and
   the footer are outside every selector here and keep the theme's own face.

   .jm-stall-tabs is listed in its own right rather than covered by
   .jm-stall-list, because it is that list's SIBLING, not its ancestor — one
   tab bar above three .jm-stall-list panels. Adding the tabs to the page
   without adding them here left them outside every selector in this block,
   and .jm-stall-tabs__tab's `font: inherit` (the usual <button> reset) then
   did the damage: with nothing else claiming the tab bar, that inherited the
   computed face of its parent, which is body's "brandon-grotesque"
   (style.css). Naming the container here settles it for the buttons too,
   since that is now what their `font: inherit` inherits.

   Keep this block first. The facility rules further down deliberately reassert
   a serif face, and each of them is written with two classes so it outranks
   `.jm-... *` regardless of order.
--------------------------------------------------------------------------- */

.jm-stall-map,
.jm-stall-map *,
.jm-stall-legend,
.jm-stall-legend *,
.jm-stall-tabs,
.jm-stall-tabs *,
.jm-stall-list,
.jm-stall-list *,
.jm-stall-credit,
.jm-stall-popup,
.jm-stall-popup * {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}

/* ---------------------------------------------------------------------------
   Map
--------------------------------------------------------------------------- */

/*
 * The window onto the map. Fixed height, so the square map below is cropped
 * top and bottom rather than dictating how tall the page is — 700px against a
 * 1000px-wide .container_box shows roughly the middle 70%, which is where the
 * stalls are (they span y=20-78% of the image).
 *
 * This 700 is the only place the frame height is defined; stalls.js reads it
 * back off the element rather than keeping a second copy of the number.
 */
.jm-stall-map__frame {
	position: relative;
	width: 100%;
	height: 700px;
	overflow: hidden;
	background-color: #f2f2f2;
}

/*
 * Narrow enough and the frame becomes square, so the map fills it exactly
 * instead of leaving bands of background above and below.
 *
 * The map is drawn at the frame's own width and is square, so its rendered
 * height is the frame's width. Once that width drops under 700px the fixed
 * 700px frame is taller than the picture in it. aspect-ratio ties the frame's
 * height to its own width, and max-height keeps the 700px ceiling for
 * everything wider — the switchover happens at whatever viewport width leaves
 * the frame exactly 700px, with no media query needing to know what that is.
 * This matters here because .container_box's padding steps from 50px to 25px
 * at 767px, so frame width is not monotonic in viewport width: a viewport
 * query would need an exception band around 751-767px, and would silently rot
 * if that padding ever changed.
 *
 * Nothing about the image's scale changes: the stage is still sized from the
 * frame's width alone (padding-bottom: 100% below), so the map is rendered at
 * exactly the same zoom as before — only the window onto it gets shorter.
 *
 * @supports so browsers without aspect-ratio (pre-2021) keep the plain 700px
 * frame they have today rather than collapsing to a height of 0, which is what
 * `height: auto` alone would give them: the stage inside is absolutely
 * positioned and contributes no height of its own.
 */
@supports (aspect-ratio: 1 / 1) {
	.jm-stall-map__frame {
		height: auto;
		aspect-ratio: 1 / 1;
		max-height: 700px;
	}
}

/*
 * The square the map image occupies: as tall as the frame is wide, via
 * padding-bottom rather than aspect-ratio so no browser is left out. Panzoom
 * owns this element's transform — nothing here may set one, or it would be
 * overwritten on the first pan.
 *
 * touch-action: none hands every touch gesture to Panzoom instead of the
 * browser — one-finger pan and pinch-zoom both work, at the cost of a touch
 * starting on the map never scrolling the page. That trade is fine on a
 * desktop-width window where the map is one element among many; it is not on a
 * phone, where the map is most of the screen and a reader who touches it can
 * no longer scroll past it. See the media query below.
 */
.jm-stall-map__stage {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 0;
	padding-bottom: 100%;
	touch-action: none;
}

/*
 * Small screens: one finger belongs to the page, not the map.
 *
 * pan-y lets the browser scroll vertically from a touch that starts on the
 * map, which is the whole point. Two-finger panning is then handled in
 * stalls.js, which preventDefault()s those gestures so they do not scroll the
 * page as well — see the touchstart/touchmove handlers there. Panzoom's own
 * pan and pinch are switched off at this width in the same place, so a
 * one-finger drag cannot move the map even for a frame before the browser
 * takes the gesture over.
 *
 * 768px, not the 767px used elsewhere in this file: the brief is one-finger
 * scrolling "at 768px and below".
 */
@media only screen and (max-width: 768px) {
	.jm-stall-map__stage {
		touch-action: pan-y;
	}
}

.jm-stall-map__svg {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: block;
}

/* Panzoom sets its own cursor (grab/grabbing) on the stage once it takes
   over; this is what the map looks like if the CDN never answered. */
.jm-stall-map__stage {
	cursor: default;
}

/* ---------------------------------------------------------------------------
   Zoom controls — inside the frame, over the map
--------------------------------------------------------------------------- */

.jm-stall-map__zoom {
	position: absolute;
	right: 12px;
	bottom: 12px;
	display: flex;
	flex-direction: column;
	gap: 8px;
	z-index: 2;
}

.jm-stall-map__zoom[hidden] {
	display: none;
}

/* 44px is the smallest comfortable touch target; the buttons keep that size
   at every breakpoint. */
.jm-stall-map__zoom-btn {
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid #d0d0d0;
	border-radius: 4px;
	background-color: #ffffff;
	color: #1a1a1a;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
	font-size: 2.4rem;
	line-height: 1;
	cursor: pointer;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.jm-stall-map__zoom-btn:hover {
	background-color: #f2f2f2;
}

.jm-stall-map__zoom-btn:focus-visible {
	outline: 2px solid #1a1a1a;
	outline-offset: 2px;
}

.jm-stall-map__zoom-btn:disabled {
	color: #b0b0b0;
	cursor: default;
	box-shadow: none;
}

.jm-stall-map__zoom-btn:disabled:hover {
	background-color: #ffffff;
}

.jm-stall-map__stall {
	cursor: pointer;
}

.jm-stall-map__stall-rect {
	stroke: #ffffff;
	stroke-width: 3;
}

/* Focus lands on the <g>, which stalls.js makes keyboard-operable. The ring
   is drawn on the rect inside it because an outline on an SVG group is
   inconsistent across browsers. */
.jm-stall-map__stall:focus {
	outline: none;
}

.jm-stall-map__stall:focus .jm-stall-map__stall-rect,
.jm-stall-map__stall:hover .jm-stall-map__stall-rect {
	stroke: #1a1a1a;
	stroke-width: 6;
}

/*
 * SVG user units, not CSS pixels: the viewBox is 2500 wide, so 42 here is
 * 42/2500 of the rendered map whatever size it ends up. Same starting value
 * as the nav site uses on the same map.
 */
.jm-stall-map__stall-label {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
	font-size: 42px;
	font-weight: 700;
	fill: #ffffff;
	pointer-events: none;
	text-anchor: middle;
}

/* A facility shows one letter rather than a number. A sans-serif capital "I"
   at this size is a bare vertical stroke; a serif face keeps it readable as a
   letter. */
.jm-stall-map .jm-stall-map__stall-label--facility {
	font-family: Georgia, "Times New Roman", serif;
	font-size: 50px;
}

/* ---------------------------------------------------------------------------
   Legend — full width at every size
--------------------------------------------------------------------------- */

/* Sits directly under the map it is the key to, so the top margin is the
   tighter of the two — see the note on .jm-stall-nav-link (style.css) for the rhythm. */
.jm-stall-legend {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px 20px;
	margin: 24px 0 32px;
	padding: 0;
	list-style: none;
}

.jm-stall-legend__item {
	display: flex;
	align-items: center;
	font-size: 1.5rem;
	line-height: 1.4;
}

.jm-stall-legend__swatch {
	display: inline-block;
	width: 16px;
	height: 16px;
	margin-right: 8px;
	border-radius: 3px;
	flex-shrink: 0;
}

/* ---------------------------------------------------------------------------
   List tabs — By Area / By Category / All
--------------------------------------------------------------------------- */

/*
 * The underline is on the bar, the highlight is the same line redrawn in
 * brand red under the current tab: the tab's own 3px bottom border is pulled
 * down by exactly its width so it lands on top of the bar's, rather than
 * beside it.
 *
 * flex: 1 1 0 gives the three tabs equal thirds regardless of label length, so
 * "All" gets the same target as "By Category" — these are thumbed on a phone
 * standing in a crowd.
 */
.jm-stall-tabs {
	display: flex;
	margin: 0 0 24px;
	border-bottom: 3px solid #e6e6e6;
}

/*
 * The full button reset, not a partial one: the theme's dist/all.min.css
 * styles bare <button>, and .jm-stall-list__item below does the same for the
 * same reason.
 */
.jm-stall-tabs__tab {
	flex: 1 1 0;
	background: none;
	border: 0;
	border-bottom: 3px solid transparent;
	margin-bottom: -3px;
	padding: 12px 8px;
	font: inherit;
	font-size: 1.7rem;
	font-weight: 700;
	line-height: 1.3;
	color: #666666;
	cursor: pointer;
	white-space: nowrap;
}

.jm-stall-tabs__tab:hover {
	color: #1a1a1a;
}

.jm-stall-tabs__tab:focus-visible {
	outline: 2px solid #1a1a1a;
	outline-offset: -2px;
}

/*
 * Paired with aria-selected="true" on the same element (js/stalls.js sets
 * both), so the state a sighted reader sees and the one a screen reader is
 * told are never out of step.
 */
.jm-stall-tabs__tab.is-current {
	color: #e20213;
	border-bottom-color: #e20213;
}

@media only screen and (max-width: 480px) {
	.jm-stall-tabs__tab {
		padding: 10px 4px;
		font-size: 1.5rem;
	}
}

/* ---------------------------------------------------------------------------
   Stall list
--------------------------------------------------------------------------- */

.jm-stall-list__area {
	margin-bottom: 40px;
}

/*
 * #1a1a1a, the body colour, rather than the brand red these started as. With
 * three tabs above them the headings are structure, not emphasis, and a column
 * of red competed with the one thing on each row that is meant to carry
 * colour — its category badge.
 *
 * Colour is left alone everywhere it still means something: the badges, the
 * legend swatches, the map rects and the per-row category names all keep their
 * category colours. .jm-stall-list__area-count keeps its own lighter grey.
 */
.jm-stall-list__area-name {
	color: #1a1a1a;
	font-size: 2.6rem;
	margin: 0 0 16px;
	text-transform: uppercase;
}

/*
 * text-transform: none against the heading's uppercase, so the All panel reads
 * "(64 stalls, A-Z)" rather than shouting it. The area and category names
 * above stay uppercase as they were.
 */
.jm-stall-list__area-count {
	font-size: 0.8em;
	font-weight: 400;
	color: #666666;
	text-transform: none;
	white-space: nowrap;
}

.jm-stall-list__items {
	margin: 0;
	padding: 0;
	list-style: none;
}

.jm-stall-list__items li + li {
	border-top: 1px solid #e6e6e6;
}

/*
 * Two columns from 768px up, filled top-to-bottom: the left column takes the
 * first half of a section's stalls, the right column the rest.
 *
 * All three tab panels get this, and get it for free: every list in every
 * panel is a .jm-stall-list__items, so there is one rule rather than one per
 * panel and they cannot drift apart.
 *
 * CSS multi-column rather than grid. Reading order here runs down one column
 * and then down the next, which is what multicol does natively and what grid
 * only does via grid-auto-flow: column — and that needs an explicit row count,
 * which would have to be recalculated per section (North Terrace has 27
 * stalls, East Square 8, the All panel 64). Multicol also leaves the source
 * order alone, so the DOM the keyboard and a screen reader walk is still the
 * order the panel was built in — stall number, or A-Z.
 *
 * The rule goes on the <ul>, not the <section>: that leaves the <h2> outside
 * the multi-column container altogether, so every heading spans the full width
 * by construction rather than by a column-span declaration that Safari was
 * late to support.
 */
.jm-stall-list__item {
	display: flex;
	align-items: center;
	width: 100%;
	background: none;
	border: 0;
	padding: 12px 4px;
	text-align: left;
	cursor: pointer;
	font: inherit;
	color: inherit;
}

.jm-stall-list__item:hover,
.jm-stall-list__item:focus {
	background-color: #f6f6f6;
}

.jm-stall-list__item:focus-visible {
	outline: 2px solid #1a1a1a;
	outline-offset: -2px;
}

/*
 * A pill, not a square, because the label is no longer always the same length:
 * By Category and All interleave all four areas, so a column of badges runs
 * N1, SE12, W7, E3. A box sized to its own content would start every stall
 * name at a different x; min-width holds them level at the widest label and
 * width: auto lets a longer one grow rather than clip.
 *
 * 56px is measured, not inherited. nav uses 42px, which covers its widest
 * label ("SE10", 41.93px) in 12px Brandon. This list sets 1.8rem — 18px, the
 * theme's html font-size being 62.5% — in the system UI stack, where the same
 * label measures 54.99px. 42px here would have been overrun by roughly twenty
 * of the 64 labels, which is the misalignment the min-width exists to prevent.
 * The 480px block below re-measures for 1.6rem (SE10, 50.65px).
 *
 * border-radius: 4px, matching the popup's badge and the rest of the theme's
 * corners. A small fixed length rather than a percentage: a percentage radius
 * is resolved against each axis separately, so a badge wider than it is tall
 * would round unevenly. Only the corner treatment changed here — the
 * min-width that does the aligning is untouched.
 */
.jm-stall-list__number {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 56px;
	width: auto;
	height: 40px;
	padding: 0 6px;
	margin-right: 14px;
	border-radius: 4px;
	color: #ffffff;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
	font-size: 1.8rem;
	font-weight: 700;
	flex-shrink: 0;
}

.jm-stall-list__item--facility .jm-stall-list__number {
	font-family: Georgia, "Times New Roman", serif;
}

.jm-stall-list__text {
	display: flex;
	flex-direction: column;
	flex-grow: 1;
	min-width: 0;
}

.jm-stall-list__title {
	font-size: 1.8rem;
	line-height: 1.35;
}

.jm-stall-list__categories {
	display: flex;
	flex-wrap: wrap;
	gap: 2px 12px;
	margin-top: 2px;
}

.jm-stall-list__category {
	font-size: 1.3rem;
	line-height: 1.4;
}

.jm-stall-list__congestion {
	margin-left: 12px;
	padding: 3px 8px;
	border-radius: 3px;
	font-size: 1.2rem;
	line-height: 1.4;
	white-space: nowrap;
	flex-shrink: 0;
	background-color: #f0a000;
	color: #ffffff;
}

.jm-stall-list__congestion--very_busy {
	background-color: #c40a1a;
}

@media only screen and (min-width: 768px) {
	.jm-stall-list__items {
		column-count: 2;
		column-gap: 32px;
	}

	/*
	 * A row is a fixed unit — a number badge beside a name that may wrap to two
	 * lines — and must not be split across the column break. The -webkit- and
	 * page- forms are for Safari and for older engines that only implemented
	 * the paged-media property.
	 */
	.jm-stall-list__items li {
		-webkit-column-break-inside: avoid;
		page-break-inside: avoid;
		break-inside: avoid;
	}

	/*
	 * Every row gets its rule, not just the ones after a sibling. In a single
	 * column `li + li` puts a line between rows and none above the first; in
	 * two columns it also puts one above the right column's first row, because
	 * that row does have a preceding sibling in source order. Giving every row
	 * a top border makes both columns start the same way instead.
	 */
	.jm-stall-list__items li {
		border-top: 1px solid #e6e6e6;
	}

	/*
	 * No vertical margin on a row, and this is what keeps the two columns
	 * level.
	 *
	 * The theme's style.css carries `ul li, ol li { margin: 8px 0 }`, which
	 * applies to every row here. A margin at the very start of a column box is
	 * truncated by the fragmentation rules, but only in the columns after the
	 * first — measured: the left column's first row sat 8px below the list's
	 * top edge while the right column's first row sat at 0, so the two columns
	 * (and their rules) were 8px out of step. Nothing about the markup differed;
	 * it was the same 8px being honoured in one column and dropped in the other.
	 *
	 * Zeroing it removes the discrepancy at its source rather than nudging one
	 * column to compensate. The 8px of breathing room it provided moves into the
	 * row's own padding below, which is inside the border and so is never
	 * truncated — the rows keep the spacing they had, and the rule now sits
	 * centred between them instead of hugging the row above.
	 */
	.jm-stall-list__items li {
		margin-top: 0;
		margin-bottom: 0;
	}

	/* 12px + the 8px inherited from the margin above, split either side of the
	   rule: the row pitch is unchanged from the single-column list. */
	.jm-stall-list__item {
		padding-top: 16px;
		padding-bottom: 16px;
	}
}

@media only screen and (max-width: 480px) {
	/* Only the floor and the type size move here. Height, padding and corners
	   are deliberately NOT restated: the 40px height is declared once in the base
	   rule above and inherited at every width, so the badge cannot end up two
	   different heights. The floor is the widest label at 1.6rem (SE10, 50.65px
	   measured). */
	.jm-stall-list__number {
		min-width: 52px;
		margin-right: 10px;
		font-size: 1.6rem;
	}

	.jm-stall-list__title {
		font-size: 1.6rem;
	}

	.jm-stall-list__congestion {
		margin-left: 8px;
	}
}

/* ---------------------------------------------------------------------------
   Photo credit — under the lists, above the footer
--------------------------------------------------------------------------- */

/* A note rather than content: the category labels' size and the area
   counts' grey. No margin of its own, so every gap around it is one that
   already existed — above, the last .jm-stall-list__area's 40px
   margin-bottom (the same spacing as between areas); below, .stalls_main's
   padding and the footer's, untouched. */
.jm-stall-credit {
	margin: 0;
	color: #666666;
	font-size: 1.3rem;
	line-height: 1.4;
	text-align: center;
}

/* ---------------------------------------------------------------------------
   Popup — centred modal at 768px and up, bottom sheet below
--------------------------------------------------------------------------- */

.jm-stall-popup-overlay {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background-color: rgba(0, 0, 0, 0.55);
	z-index: 1040;
}

.jm-stall-popup {
	position: fixed;
	z-index: 1050;
	background-color: #ffffff;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
}

/* [hidden] is only display:none at the UA default, which any display
   declaration on the same element would override. Restating it here keeps the
   flex/block rules below from re-showing a closed dialog. */
.jm-stall-popup[hidden],
.jm-stall-popup-overlay[hidden] {
	display: none;
}

.jm-stall-popup__close {
	position: absolute;
	top: 8px;
	right: 8px;
	width: 40px;
	height: 40px;
	background-color: #ffffff;
	border: 1px solid #d0d0d0;
	border-radius: 4px;
	font-size: 3rem;
	line-height: 1;
	color: #1a1a1a;
	cursor: pointer;
	z-index: 1;
}

.jm-stall-popup__close:focus-visible {
	outline: 2px solid #1a1a1a;
	outline-offset: -2px;
}

/*
 * text-align: left, and it has to be said out loud here.
 *
 * dist/all.min.css (imported by the child theme's style.css, line 12) carries
 *
 *     html, body { ... text-align: center; }
 *
 * which lands after Bootstrap's own `body { text-align: left }` and wins, so
 * the whole document inherits centred text. Everything else on this page
 * happens to re-assert its own alignment somewhere — .jm-stall-list__item
 * below sets left, the theme's content blocks set their own — so the centring
 * only shows up where nothing overrides it. The popup is exactly that place:
 * it is built at body level, outside .container_box and every other wrapper,
 * so its title, categories, description and links inherited the centre
 * straight from <body>.
 *
 * On __body rather than on .jm-stall-popup, deliberately: the close button is
 * a SIBLING of this element, not a child, so scoping it here cannot reach the
 * ×, which keeps the centring its own rule and the UA give it. The number
 * badge is likewise unaffected — .jm-stall-popup__number centres its label
 * with flexbox (justify-content), which text-align has no say over.
 *
 * A block-editor alignment inside the_content (.has-text-align-center and
 * friends) still wins on specificity, so a paragraph the author deliberately
 * centred stays centred.
 */
.jm-stall-popup__body {
	padding: 28px 24px 32px;
	text-align: left;
}

/* Desktop: centred modal */
@media only screen and (min-width: 768px) {
	.jm-stall-popup {
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		width: 90%;
		max-width: 620px;
		max-height: 85vh;
		border-radius: 6px;
	}
}

/* Mobile: bottom sheet */
@media only screen and (max-width: 767px) {
	.jm-stall-popup {
		right: 0;
		bottom: 0;
		left: 0;
		max-height: 88vh;
		border-radius: 14px 14px 0 0;
	}

	.jm-stall-popup__body {
		padding: 24px 18px 28px;
	}

	/* The grab handle is decorative — the sheet is not draggable; the ×,
	   the overlay and Esc are the ways out. */
	.jm-stall-popup::before {
		content: "";
		display: block;
		width: 40px;
		height: 4px;
		margin: 10px auto 0;
		border-radius: 2px;
		background-color: #d8d8d8;
	}
}

/* Popup contents (built by stalls.js) */

/* Sits after the description (js/stalls.js, render()), so it is spaced from
   what is above it — the same 18px the links below use. */
.jm-stall-popup__image {
	margin-top: 18px;
}

.jm-stall-popup__image img {
	display: block;
	width: 100%;
	height: auto;
}

.jm-stall-popup__heading {
	display: flex;
	align-items: center;
	margin-bottom: 10px;
	padding-right: 44px;
}

/*
 * Already a rounded square, so the corner never changed — but the label it
 * holds did. This badge now shows prefixed_label ("SE10") rather than the bare
 * number, and 42px of fixed width could not hold it: measured, the widest
 * label wants 59.34px at this size (2rem = 20px bold, plus the 12px of
 * padding), and the box was clipping it.
 *
 * So the same treatment the list badge already had — a floor, not a fixed
 * width. 60px covers the widest label with a little to spare; width: auto
 * lets anything longer grow instead of being cut off. The height and type
 * size are the popup's own and are left alone: this is a heading beside a
 * stall's name, not a row in a list.
 */
.jm-stall-popup__number {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 60px;
	width: auto;
	height: 42px;
	padding: 0 6px;
	margin-right: 14px;
	border-radius: 4px;
	color: #ffffff;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
	font-size: 2rem;
	font-weight: 700;
	flex-shrink: 0;
}

.jm-stall-popup .jm-stall-popup__number--facility {
	font-family: Georgia, "Times New Roman", serif;
}

.jm-stall-popup__title {
	font-size: 2.2rem;
	line-height: 1.3;
	margin: 0;
}

.jm-stall-popup__categories {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 14px;
	margin-bottom: 10px;
}

.jm-stall-popup__category {
	font-size: 1.4rem;
	line-height: 1.4;
}

.jm-stall-popup__congestion {
	display: inline-block;
	margin-bottom: 12px;
	padding: 4px 10px;
	border-radius: 3px;
	font-size: 1.3rem;
	background-color: #f0a000;
	color: #ffffff;
}

.jm-stall-popup__congestion--very_busy {
	background-color: #c40a1a;
}

.jm-stall-popup__content {
	font-size: 1.6rem;
	line-height: 1.7;
}

.jm-stall-popup__content p {
	margin: 0 0 1em;
}

.jm-stall-popup__content p:last-child {
	margin-bottom: 0;
}

.jm-stall-popup__links {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 18px;
}

.jm-stall-popup__link {
	display: inline-block;
	background-color: #0086ca;
	color: #ffffff;
	font-size: 1.5rem;
	line-height: 1.4;
	padding: 10px 18px;
	border-radius: 3px;
	text-decoration: none;
}

.jm-stall-popup__link:hover,
.jm-stall-popup__link:focus {
	color: #ffffff;
	opacity: 0.85;
}

/* Locks the page behind an open popup. Applied to <body> by stalls.js. */
.jm-stall-popup-open {
	overflow: hidden;
}
