/*
 * chrome.css — site header and footer.
 *
 * DELIBERATE DEVIATION FROM THE FRAME — header positioning.
 *
 * The Figma header positions its rows from the page edge with large, unequal
 * insets (logo at 19.44vw capped 336px, category nav at 14.87vw capped 257px,
 * 66px right and nothing left). At exactly 1728px that reads as intentional
 * asymmetry. At any other width it reads as a mistake: the logo drifts toward
 * the middle while the account controls stay pinned right, and the two rows
 * line up neither with each other nor with the page content below them.
 *
 * The header is therefore centred on a container, with both rows sharing one
 * inset. Colours, type and component shapes are unchanged — only the
 * positioning method differs.
 *
 * @package Uloominate
 */

/* ============================================================ HEADER == */

.ulm-header {
	position: relative;
	z-index: 40;
	width: 100%;
	background: var(--ulm-primary);
}

.ulm-header__inner {
	display: flex;
	flex-direction: column;
	max-width: 1440px;
	margin-inline: auto;
	padding-inline: clamp(20px, 3.4vw, 48px);
}

/* --- logo row --------------------------------------------------------- */

/*
 * Three tracks, with the outer two equal, so the search sits on the centre
 * line of the header rather than in the middle of whatever space the brand and
 * the account controls happen to leave. As a flex row with `margin-inline:auto`
 * it was centred within the slack — and since the actions side is wider than
 * the brand, that put it visibly left of centre on every page.
 */
.ulm-header__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(180px, 520px) minmax(0, 1fr);
	align-items: center;
	gap: clamp(16px, 2.4vw, 40px);
	min-height: 76px;
	padding-block: 12px;
}

.ulm-brand { justify-self: start; }
.ulm-header__actions { justify-self: end; }

/*
 * Pre-launch, with no search box in the middle.
 *
 * The three-track grid above reserves `minmax(180px, 520px)` for the search
 * whether or not one is rendered, so with it gone the account controls sat up
 * to 520px short of the right edge — the brand on the left, the buttons
 * floating in the middle, and half the bar empty to their right.
 *
 * Two tracks instead: the brand takes the slack, the controls take what they
 * need, and `justify-self: end` finally means the end of the row.
 */
.ulm-header__row--bare {
	grid-template-columns: minmax(0, 1fr) auto;
}

/*
 * The narrow-viewport rule further down pins the controls to column 3, which
 * does not exist here — grid would invent one and put the buttons back in the
 * middle of a row that is now wider than it should be.
 */
.ulm-header__row--bare .ulm-header__actions {
	grid-column: auto;
	justify-self: end;
}

/* --- brand lockup ----------------------------------------------------- */

.ulm-brand {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 0 0 auto;
	text-decoration: none;
}

/*
 * The supplied lockup — mark and wordmark in one image, 1600x291.
 *
 * Sized by height with `width: auto`, so the aspect ratio comes from the file
 * and never has to be restated here. It is a wide shape: every 4px of height
 * costs 22px of width, which is what drives the step-downs further down.
 */
.ulm-brand__logo {
	display: block;
	height: 42px;
	width: auto;
	max-width: 100%;
	object-fit: contain;
}

/*
 * The old pairing: mark image beside the site name as live text. Kept because
 * a logo set in the customiser still renders that way, and because the
 * dashboards use `.ulm-brand__mark` on their own sidebars.
 */
.ulm-brand__mark {
	display: block;
	width: 36px;
	height: 44px;
	object-fit: contain;
}

.ulm-brand__text {
	font-family: var(--ulm-font-wordmark);
	font-weight: var(--ulm-fw-medium);
	font-size: 27px;
	line-height: 1.2;
	/* Gold, not white. */
	color: var(--ulm-gold);
	white-space: nowrap;
}

/* The wordmark stays gold on hover. It is the brand mark, not a link that
 * needs to signal itself — turning it white made it read as a different
 * element from the one sitting there a moment earlier. */
.ulm-brand:hover .ulm-brand__text { color: var(--ulm-gold); }

/* A logo uploaded in the customiser, which supersedes both of the above. */
.ulm-brand > img:not(.ulm-brand__mark):not(.ulm-brand__logo) {
	height: 44px;
	width: auto;
}

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

.ulm-header__search {
	display: flex;
	align-items: center;
	gap: 8px;
	/* It owns the middle track outright, so it needs no flex basis and no
	   auto margins — the grid does the centring. */
	width: 100%;
	min-width: 0;
	height: 46px;
	padding: 0 8px 0 18px;
	background: var(--ulm-surface);
	border-radius: 28px;
}

.ulm-header__search svg { flex: 0 0 auto; }

.ulm-header__search input {
	flex: 1;
	min-width: 0;
	border: none;
	outline: none;
	background: transparent;
	font-family: var(--ulm-font);
	font-size: 15px;
	color: var(--ulm-ink);
}

.ulm-header__search input::placeholder { color: var(--ulm-m3-outline); }

/* --- actions ---------------------------------------------------------- */

/*
 * A single small gap, not a viewport-scaled one.
 *
 * At `clamp(12px, 1.4vw, 22px)` the cart and the bell drifted 22px apart on a
 * wide screen while the avatar pill beside them kept its own padding, so the
 * three read as two separate groups rather than one control cluster.
 */
.ulm-header__actions {
	display: flex;
	align-items: center;
	gap: 6px;
	flex: 0 0 auto;
}

/* The pill carries its own shape, so it gets the breathing room instead. */
.ulm-header__actions > .ulm-account,
.ulm-header__actions > .ulm-header__pill { margin-inline-start: 6px; }

.ulm-header__link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	color: var(--ulm-ink-invert);
	font-size: 15px;
	font-weight: var(--ulm-fw-medium);
	white-space: nowrap;
}

.ulm-header__link:hover { color: var(--ulm-gold); }

/* ----------------------------------------------- account dropdown -- */

/*
 * Everything a signed-in person can do lives here rather than spread across
 * the header bar. An administrator has five destinations and three carry queue
 * counts; as separate links that is clutter, and the counts are the point.
 */
.ulm-account {
	position: relative;
	flex: 0 0 auto;
}

/*
 * The whole pill is the button — the click handler is bound to this element,
 * not to the chevron inside it. The chevron is a hint that the pill opens
 * something, nothing more.
 */
.ulm-account__trigger {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	height: 48px;
	padding: 4px 14px 4px 4px;
	border-radius: 100px;
	border: 0;
	background: var(--ulm-gold);
	color: var(--ulm-primary);
	cursor: pointer;
	transition: filter var(--ulm-duration-fast) ease;
}

.ulm-account__trigger:hover { filter: brightness(.96); }

.ulm-account__trigger svg {
	transition: transform var(--ulm-duration-fast) ease;
}

.ulm-account__trigger[aria-expanded="true"] svg { transform: rotate(180deg); }


.ulm-account__avatar {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--ulm-primary);
	color: var(--ulm-ink-invert);
	font-size: 14px;
	font-weight: var(--ulm-fw-semibold);
	letter-spacing: .02em;
	flex: 0 0 auto;
}

.ulm-account__name {
	font-size: 16px;
	font-weight: var(--ulm-fw-semibold);
	white-space: nowrap;
}

/* A quiet dot when something is waiting, so the count is discoverable
   without opening the menu. */
.ulm-account__dot {
	position: absolute;
	top: 6px;
	right: 34px;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--ulm-danger);
	border: 2px solid var(--ulm-gold);
}

.ulm-account__menu {
	position: absolute;
	inset-block-start: calc(100% + 10px);
	inset-inline-end: 0;
	z-index: var(--ulm-z-dropdown);
	min-width: 288px;
	padding: 8px 0;
	background: var(--ulm-surface);
	border: 1px solid var(--ulm-border);
	border-radius: 14px;
	box-shadow: var(--ulm-shadow-lg);
	animation: ulm-rise var(--ulm-duration-fast) ease both;
}

.ulm-account__menu[hidden] { display: none; }

.ulm-account__identity {
	padding: 12px 20px 14px;
	border-bottom: 1px solid var(--ulm-border);
}

.ulm-account__fullname {
	font-size: 16px;
	font-weight: var(--ulm-fw-semibold);
	color: var(--ulm-deep);
}

.ulm-account__role {
	font-size: 14px;
	color: var(--ulm-ink-muted);
}

.ulm-account__links {
	list-style: none;
	padding: 8px 0;
	border-bottom: 1px solid var(--ulm-border);
}

.ulm-account__links a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 10px 20px;
	font-size: 15px;
	font-weight: var(--ulm-fw-medium);
	color: var(--ulm-deep);
	transition: background var(--ulm-duration-fast) ease;
}

.ulm-account__links a:hover {
	background: var(--ulm-tint-mint);
	color: var(--ulm-deep);
}

.ulm-account__count {
	display: grid;
	place-items: center;
	min-width: 24px;
	height: 24px;
	padding-inline: 7px;
	border-radius: 100px;
	background: var(--ulm-primary);
	color: var(--ulm-ink-invert);
	font-family: var(--ulm-font-numeric);
	font-size: 12px;
	font-weight: var(--ulm-fw-bold);
}

.ulm-account__signout {
	display: block;
	padding: 12px 20px 8px;
	font-size: 15px;
	font-weight: var(--ulm-fw-semibold);
	color: var(--ulm-danger);
}

.ulm-account__signout:hover { color: var(--ulm-danger); text-decoration: underline; }

/* Gold buttons for the signed-out entry points. */
/*
 * Brand green on the gold pills.
 *
 * Settled 26 Aug 2026 after trying white: #FFFFFF on --ulm-gold (#FEDC97) is
 * 1.32:1 and was close to invisible. --ulm-primary is 3.43:1 — still under the
 * 4.5:1 WCAG AA wants for 15px text (NFR-8), but far more legible, and it is
 * what the vendor pill always used.
 *
 * If AA ever has to be met here, the lever is the background, not the ink:
 * --ulm-deep on this gold is 7.62:1, or a darker gold token (#8A6414) carries
 * white at 5.37:1. Every gold in the current palette is too light for AA with
 * anything but a dark ink.
 */
.ulm-header__pill {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	height: 42px;
	padding: 0 18px;
	border-radius: 100px;
	background: var(--ulm-gold);
	color: var(--ulm-primary);
	font-weight: var(--ulm-fw-semibold);
	font-size: 15px;
	line-height: 1;
	white-space: nowrap;
	transition: filter var(--ulm-duration-fast) ease;
}

.ulm-header__pill:hover {
	color: var(--ulm-primary);
	filter: brightness(.96);
}

.ulm-header__pill--vendor { color: var(--ulm-primary); }
.ulm-header__pill--vendor:hover { color: var(--ulm-primary); }

/* --- cart -------------------------------------------------------------- */

/*
 * The bare icon controls in the bar. The cart has always been one; the sign-in
 * icon joins it below the breakpoint, where a pill saying "Login" beside one
 * saying "Become a Vendor" is what was pushing the cart on top of the wordmark.
 */
.ulm-header__icon {
	display: none;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	color: var(--ulm-ink-invert);
}

.ulm-header__icon:hover {
	background: rgb(255 255 255 / 12%);
	color: var(--ulm-ink-invert);
}

/*
 * The wishlist and the cart are the same control twice: a round icon button in
 * the green bar carrying a count. One rule for both rather than a copy under a
 * second name — they sit side by side, and two sets of numbers for the same
 * shape is how they end up a pixel apart.
 */
.ulm-header__cart,
.ulm-header__wish {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	color: var(--ulm-ink-invert);
	transition: background .18s ease;
}

.ulm-header__cart:hover,
.ulm-header__wish:hover {
	background: rgba(255, 255, 255, .14);
	color: var(--ulm-ink-invert);
}

.ulm-header__cart-count,
.ulm-header__wish-count {
	position: absolute;
	top: 0;
	right: 0;
	min-width: 19px;
	height: 19px;
	padding: 0 5px;
	border-radius: 10px;
	background: var(--ulm-gold);
	color: var(--ulm-primary);
	font-size: 11px;
	font-weight: var(--ulm-fw-bold);
	line-height: 19px;
	text-align: center;
}

/* --- category nav (inside the green bar) ------------------------------ */

/*
 * Centred, wrapping, and NOT a scroll container.
 *
 * It used to be `overflow-x: auto` with auto margins on the first and last
 * link to fake the centring. Two things went wrong with that. The auto margins
 * were keyed to `.ulm-header__nav-link`, and a category with children renders
 * as `.ulm-header__nav-item` instead — so the moment sub-categories existed the
 * hack stopped applying and the row sat hard left. And a scroll container
 * clips its own children, so the dropdown panel could not escape it: opening
 * one scrolled the header strip instead of covering the page.
 *
 * Wrapping rather than scrolling, because below 980px the strip is gone
 * entirely and the drawer carries the categories.
 */
.ulm-header__nav {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 6px clamp(18px, 2vw, 32px);
	padding-bottom: 14px;
}

.ulm-header__nav-link {
	/* 15px, not the frame's 18px. At 18px ten categories overflow the row and
	   the strip visually outweighs the brand above it. */
	font-size: 15px;
	line-height: 22px;
	font-weight: var(--ulm-fw-medium);
	color: rgba(255, 255, 255, .88);
	white-space: nowrap;
	padding-bottom: 4px;
	border-bottom: 2px solid transparent;
	transition: border-color var(--ulm-duration-fast) ease, color var(--ulm-duration-fast) ease;
}

.ulm-header__nav-link:hover {
	color: var(--ulm-ink-invert);
	border-bottom-color: var(--ulm-gold);
}

.ulm-header__nav-link[aria-current="page"] {
	color: var(--ulm-ink-invert);
	font-weight: var(--ulm-fw-semibold);
	border-bottom-color: var(--ulm-gold);
}

/* --- the drawer trigger ------------------------------------------------ */

/*
 * Present in the markup at every width and shown only below the breakpoint.
 * One header with one set of controls: a second, narrow-only markup path is
 * how a button ends up fixed in one of them and broken in the other.
 */
.ulm-header__burger {
	display: none;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	margin-inline-start: -9px;
	padding: 0;
	border: 0;
	border-radius: var(--ulm-radius-sm, 8px);
	background: none;
	color: var(--ulm-ink-invert);
	cursor: pointer;
}

.ulm-header__burger:hover { background: rgba(255, 255, 255, .12); }

.ulm-header__burger:focus-visible {
	outline: 2px solid var(--ulm-gold);
	outline-offset: 2px;
}

/* --- the category strip and its backdrop ------------------------------- */

/*
 * The containing block for the full-width dropdown panels. They are positioned
 * against this, not against the item that opens them.
 */
.ulm-header__navwrap { position: relative; }

/*
 * The backdrop. Fixed to the viewport so it covers the whole page rather than
 * the header's own box, which is the difference between a menu that reads as
 * being over the site and one that reads as part of the bar.
 *
 * Driven by `:has()` so a pointer needs no script. `.is-open` is the script's
 * hook for taps and keyboards, and appears in the same rule so both routes
 * light the same backdrop.
 */
.ulm-header__scrim {
	position: fixed;
	inset: 0;
	z-index: 40;
	background: rgb(18 24 22 / 42%);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;

	/* The same closing delay the panel uses. Without it the backdrop lifts
	   while the menu is still on screen, which reads as a flicker. */
	transition: opacity var(--ulm-duration-fast, .15s) ease, visibility var(--ulm-duration-fast, .15s) ease;
	transition-delay: .35s;
}

.ulm-header:has(.ulm-header__nav-item:hover) .ulm-header__scrim,
.ulm-header:has(.ulm-header__nav-item:focus-within) .ulm-header__scrim,
.ulm-header:has(.ulm-header__nav-item.is-open) .ulm-header__scrim {
	opacity: 1;
	visibility: visible;
	transition-delay: 0s;
}

/* The bar itself has to sit above its own backdrop. */
.ulm-header { position: relative; z-index: 50; }


/* --- responsive -------------------------------------------------------- */

@media (max-width: 1100px) {
	/*
	 * Narrow enough that a centred search would leave the brand and the
	 * account controls fighting over what is left. Two columns with the search
	 * dropped onto its own row underneath, which is the same arrangement the
	 * flex version wrapped into.
	 */
	.ulm-header__row {
		grid-template-columns: auto 1fr;
		row-gap: 12px;
	}

	.ulm-header__search {
		order: 3;
		grid-column: 1 / -1;
	}

	.ulm-header__actions { justify-self: end; }
}

/*
 * The mobile header proper.
 *
 * Three things change together at this width, and they are one decision rather
 * than three: the trigger appears, the brand takes the middle, and the search
 * drops to a full-width row of its own. Splitting them across breakpoints
 * produces a state where the trigger is showing but the brand is still hard
 * left, which reads as a layout that has half-finished loading.
 */
@media (max-width: 979px) {
	.ulm-header__row {
		grid-template-columns: auto 1fr auto;
		align-items: center;
		row-gap: 14px;
		min-height: 64px;
	}

	.ulm-header__burger { display: flex; }

	/*
	 * Sits directly after the drawer trigger, not centred between it and the
	 * account controls. Centring made the lockup's position depend on how many
	 * icons happened to be on the right — so it shifted between the signed-out
	 * and signed-in headers, and again whenever the cart count appeared.
	 */
	.ulm-brand {
		grid-column: 2;
		justify-self: start;
	}

	.ulm-header__search {
		grid-column: 1 / -1;
		width: 100%;
		height: 44px;
	}

	.ulm-header__actions {
		grid-column: 3;
		justify-self: end;
	}

	/*
	 * The brand must be allowed to shrink.
	 *
	 * A grid item's default `min-width: auto` refuses to go below its content,
	 * so the wordmark held its full width and shoved the cart and the bell into
	 * itself instead of yielding — which is what the icons-on-the-logo overlap
	 * actually was. Nothing here is a fix for the symptom; this is the cause.
	 */
	.ulm-brand { min-width: 0; }

	/* Pills out, single icon in. */
	.ulm-header__pill { display: none; }
	.ulm-header__icon--signin { display: inline-flex; }

	/*
	 * The gold stays; the lozenge does not.
	 *
	 * With the name hidden at this width the pill was a long gold shape around
	 * a single letter, so it was stripped back to nothing — which took the
	 * brand colour out of the header along with it. It is a gold circle now
	 * instead: same size as the cart and the bell beside it, and the avatar's
	 * own green sits inside it as a ring.
	 */
	.ulm-account__trigger {
		width: 42px;
		height: 42px;
		padding: 3px;
		gap: 0;
		border-radius: 50%;
		background: var(--ulm-gold);
	}

	.ulm-account__avatar {
		width: 100%;
		height: 100%;
	}

	/*
	 * Name and chevron both go. The trigger is a circle the size of the cart
	 * and the bell here, and neither would fit beside the avatar — the chevron
	 * stays on tablet and desktop, where the pill is wide enough to carry it.
	 */
	.ulm-account__name,
	.ulm-account__trigger svg { display: none; }

	/*
	 * The category strip goes entirely, drawer and all.
	 *
	 * It was left in place at first and that was wrong: the same categories
	 * were then in two places at once, one of them a cramped row that needed
	 * sideways scrolling to read. The drawer shows the whole tree, parents and
	 * children together, which the strip could never do at this width — so the
	 * strip has nothing left to contribute and is removed rather than shrunk.
	 */
	.ulm-header__navwrap { display: none; }
}

/* ============================================================= DRAWER == */

/*
 * Hidden outright above the breakpoint. `display:none` rather than merely
 * translating it off-screen: an off-screen panel is still in the tab order and
 * still read out, so a desktop visitor would tab from the logo into an entire
 * duplicate navigation nobody can see.
 */
.ulm-drawer { display: none; }

@media (max-width: 979px) {
	.ulm-drawer:not([hidden]) {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 120;
	}

	.ulm-drawer__scrim {
		position: absolute;
		inset: 0;
		background: rgb(18 24 22 / 55%);
	}

	.ulm-drawer__panel {
		position: absolute;
		inset-block: 0;
		inset-inline-start: 0;
		display: flex;
		flex-direction: column;
		width: min(86vw, 340px);
		background: var(--ulm-surface);
		box-shadow: 0 0 40px rgb(0 0 0 / 28%);
		overflow-y: auto;
		overscroll-behavior: contain;
		animation: ulm-drawer-in .22s ease;
	}

	@keyframes ulm-drawer-in {
		from { transform: translateX(-100%); }
		to   { transform: translateX(0); }
	}

	@media (prefers-reduced-motion: reduce) {
		.ulm-drawer__panel { animation: none; }
	}

	.ulm-drawer__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		padding: 16px 18px;
		border-bottom: 1px solid var(--ulm-line, #e4eae7);
		background: var(--ulm-primary);
		color: var(--ulm-ink-invert);
	}

	.ulm-drawer__title {
		font-size: 16px;
		font-weight: var(--ulm-fw-semibold, 600);
	}

	.ulm-drawer__close {
		display: grid;
		place-items: center;
		width: 36px;
		height: 36px;
		padding: 0;
		border: 0;
		border-radius: 8px;
		background: none;
		color: inherit;
		cursor: pointer;
	}

	.ulm-drawer__close:hover { background: rgb(255 255 255 / 15%); }

	.ulm-drawer__nav {
		display: flex;
		flex-direction: column;
		padding: 8px 0;
	}

	/*
	 * The parent stays a link and the disclosure sits beside it, so the row has
	 * two targets rather than one that has to guess which was meant.
	 */
	.ulm-drawer__group {
		display: grid;
		grid-template-columns: 1fr auto;
		align-items: center;
	}

	.ulm-drawer__link {
		padding: 13px 18px;
		font-size: 15px;
		font-weight: var(--ulm-fw-medium, 500);
		color: var(--ulm-deep);
		text-decoration: none;
	}

	.ulm-drawer__link--all {
		font-weight: var(--ulm-fw-semibold, 600);
		color: var(--ulm-primary);
	}

	.ulm-drawer__link[aria-current="page"] {
		color: var(--ulm-primary);
		font-weight: var(--ulm-fw-semibold, 600);
	}

	.ulm-drawer__expand {
		display: grid;
		place-items: center;
		width: 44px;
		height: 44px;
		margin-inline-end: 6px;
		padding: 0;
		border: 0;
		border-radius: 8px;
		background: none;
		color: var(--ulm-ink-muted);
		cursor: pointer;
		transition: transform .18s ease;
	}

	.ulm-drawer__expand[aria-expanded="true"] { transform: rotate(180deg); }

	.ulm-drawer__sub {
		grid-column: 1 / -1;
		display: flex;
		flex-direction: column;
		padding-bottom: 6px;
		background: var(--ulm-tint-mint, #f2faf7);
	}

	.ulm-drawer__sub[hidden] { display: none; }

	.ulm-drawer__sublink {
		display: flex;
		align-items: center;
		padding: 11px 18px 11px 32px;
		font-size: 14px;
		color: var(--ulm-ink-muted);
		text-decoration: none;
	}

	.ulm-drawer__sublink[aria-current="page"] {
		color: var(--ulm-primary);
		font-weight: var(--ulm-fw-semibold, 600);
	}

	/*
	 * A sub-category that is a shelf rather than a destination — "Elementary
	 * math", "By topic". Set as a heading so the subjects indented beneath it
	 * read as belonging to it, and still a link, because it has an archive of
	 * its own.
	 */
	.ulm-drawer__sublink--group {
		margin-top: 4px;
		font-size: 12px;
		font-weight: var(--ulm-fw-semibold, 600);
		letter-spacing: .04em;
		text-transform: uppercase;
		color: var(--ulm-ink-muted);
	}

	.ulm-drawer__sublink--deep {
		padding-left: 46px;
		color: var(--ulm-ink);
	}

	.ulm-drawer__foot {
		display: flex;
		flex-direction: column;
		gap: 8px;
		margin-top: auto;
		padding: 16px 18px 22px;
		border-top: 1px solid var(--ulm-line, #e4eae7);
	}

	.ulm-drawer__action {
		display: flex;
		align-items: center;
		gap: 10px;
		height: 44px;
		padding: 0 14px;
		border: 1px solid var(--ulm-line, #e4eae7);
		border-radius: 10px;
		font-size: 15px;
		font-weight: var(--ulm-fw-medium, 500);
		color: var(--ulm-deep);
		text-decoration: none;
	}

	.ulm-drawer__action--primary {
		border-color: var(--ulm-primary);
		background: var(--ulm-primary);
		color: var(--ulm-ink-invert);
	}

	/* The page behind must not scroll while the panel is open. */
	body.ulm-drawer-open { overflow: hidden; }
}

@media (max-width: 640px) {
	.ulm-brand__logo { height: 34px; }
	.ulm-brand__mark { width: 30px; height: 36px; }

	/* Labels drop, icons stay — the row would otherwise wrap twice. */
	.ulm-header__link span { display: none; }

	.ulm-account__dot { right: 4px; }
	.ulm-account__menu { min-width: 260px; }
}

/*
 * The wordmark stays at every width. It is the brand, and a header that drops
 * its own name to make room for three icons has its priorities backwards.
 *
 * So the room comes from everything else instead: the mark, the type and the
 * icon controls all step down together. Measured against the tightest case —
 * a 360px screen with a burger, cart, bell and avatar all present.
 */
@media (max-width: 560px) {
	.ulm-brand { gap: 7px; }
	.ulm-brand__logo { height: 30px; }
	.ulm-brand__text { font-size: 18px; }
	.ulm-brand__mark { width: 26px; height: 31px; }

	.ulm-header__burger { width: 38px; height: 38px; }

	.ulm-header__icon,
	.ulm-header__cart,
	.ulm-header__wish,
	.ulm-account__trigger {
		width: 38px;
		height: 38px;
	}
	/* The bell steps down too, but its rule has to live beside its own
	   component further down this file — see the note there. */

	.ulm-header__row { gap: 8px; }
	.ulm-header__actions { gap: 2px; }
	.ulm-header__actions > .ulm-account { margin-inline-start: 2px; }

	/*
	 * The wishlist icon comes out down here, and it is the right one to lose.
	 *
	 * The sizing above was measured against a 360px screen carrying a burger,
	 * a cart, a bell and an avatar — four controls, which is what fits beside a
	 * wordmark that is not allowed to disappear. The wishlist would be a fifth,
	 * and something has to give; of the five it is the only one that is neither
	 * navigation, nor a live count of somebody else's action, nor the way in
	 * and out of an account.
	 *
	 * It is not lost: the drawer carries "Saved resources" at this width, which
	 * is where the rest of the navigation already went.
	 */
	.ulm-header__wish { display: none; }
}

/*
 * Below 380px nothing more can be taken from the icons without them becoming
 * hard to hit, so the name is the one thing left that can yield — and it
 * yields by ellipsis rather than by disappearing, which keeps the lockup
 * reading as a lockup.
 */
@media (max-width: 380px) {
	.ulm-brand__logo { height: 26px; }

	.ulm-brand__text {
		font-size: 17px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
}

/* ============================================================ FOOTER == */

.ulm-site-footer {
	/* margin-block-start: var(--ulm-space-16); */
	background: var(--ulm-tint-cream);
	border-top: 1px solid var(--ulm-border);
}

.ulm-site-footer__inner {
	display: grid;
	/* The design puts the link columns beside the logo rather than in an even
	   grid, so the brand column is wider. */
	grid-template-columns: minmax(280px, 1.6fr) repeat(3, minmax(140px, 1fr));
	gap: var(--ulm-space-12);
	max-width: 1440px;
	margin-inline: auto;
	padding-inline: clamp(20px, 3.4vw, 48px);
	padding-block: 64px 40px;
}

.ulm-site-footer__brand {
	display: flex;
	flex-direction: column;
	gap: var(--ulm-space-3);
	max-width: 42ch;
}

/* The footer runs the same lockup in the deep green, slightly larger mark. */
.ulm-brand--footer .ulm-brand__logo {
	height: 46px;
}

.ulm-brand--footer .ulm-brand__mark {
	width: 40px;
	height: 49px;
}

.ulm-brand--footer .ulm-brand__text {
	font-size: 26px;
	color: var(--ulm-deep);
}

.ulm-brand--footer:hover .ulm-brand__text { color: var(--ulm-primary); }

.ulm-site-footer__tagline {
	font-family: var(--ulm-font-tagline);
	font-size: var(--ulm-text-2xs);
	color: var(--ulm-ink-muted);
	letter-spacing: .04em;
}

.ulm-site-footer__blurb {
	font-size: var(--ulm-text-sm);
	line-height: var(--ulm-leading-normal);
	color: var(--ulm-ink-muted);
}

.ulm-site-footer__heading {
	margin-block-end: var(--ulm-space-4);
	font-size: var(--ulm-text-sm);
	font-weight: var(--ulm-fw-semibold);
	color: var(--ulm-deep);
	letter-spacing: .04em;
	text-transform: uppercase;
}

.ulm-site-footer__column ul {
	display: flex;
	flex-direction: column;
	gap: var(--ulm-space-3);
	list-style: none;
}

.ulm-site-footer__column a {
	color: var(--ulm-ink-muted);
	font-size: var(--ulm-text-sm);
}

.ulm-site-footer__column a:hover { color: var(--ulm-primary); }

.ulm-site-footer__bar {
	border-top: 1px solid var(--ulm-border);
}

.ulm-site-footer__bar-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--ulm-space-4);
	max-width: 1440px;
	margin-inline: auto;
	padding-inline: clamp(20px, 3.4vw, 48px);
	padding-block: var(--ulm-space-5);
	font-size: var(--ulm-text-2xs);
	color: var(--ulm-ink-muted);
}

.ulm-site-footer__standard {
	max-width: 52ch;
}

@media (max-width: 1024px) {
	.ulm-site-footer__inner {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--ulm-space-8);
	}

	.ulm-site-footer__brand { grid-column: 1 / -1; }
}

@media (max-width: 640px) {
	.ulm-site-footer__inner { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------ notification bell -- */

/*
 * FR-11. Rendered server-side with its contents already in place, so it opens
 * instantly and works with the script absent.
 */

.ulm-bell {
	position: relative;
	flex: 0 0 auto;
}

.ulm-bell__trigger {
	display: grid;
	position: relative;
	place-items: center;
	width: 42px;
	height: 42px;
	color: var(--ulm-deep);
	cursor: pointer;
	background: transparent;
	border: 0;
	border-radius: 50%;
	transition: background .18s ease;
}

.ulm-bell__trigger:hover,
.ulm-bell__trigger[aria-expanded="true"] {
	background: var(--ulm-tint-header, #eaf7f1);
}

/*
 * In the green bar the bell is painted like the cart it sits beside: a white
 * glyph taking a faint white wash on hover. It was using the dark-on-light
 * treatment everywhere, which is right in the vendor and admin shells and made
 * it the odd one out in a row of three white icons on the storefront.
 *
 * Scoped to .ulm-header rather than changed outright — the same component
 * renders on the light dashboard headers, where white would be invisible.
 */
.ulm-header .ulm-bell__trigger {
	color: var(--ulm-ink-invert);
}

.ulm-header .ulm-bell__trigger:hover,
.ulm-header .ulm-bell__trigger:focus-visible,
.ulm-header .ulm-bell__trigger[aria-expanded="true"] {
	background: rgba(255, 255, 255, .14);
	color: var(--ulm-ink-invert);
}

/* .ulm-bell__count {
	position: absolute;
	top: 3px;
	right: 2px;
	min-width: 17px;
	height: 17px;
	padding: 0 4px;
	font-family: var(--ulm-font-numeric);
	font-size: 10px;
	font-weight: 700;
	line-height: 17px;
	color: #fff;
	text-align: center;
	background: var(--ulm-danger, #c0392b);
	border: 2px solid #fff;
	border-radius: 9999px;
} */

.ulm-bell__count {
    position: absolute;
    top: 2px;
    right: 0px;
    min-width: 20px;
    height: 17px;
    padding: 4px;
    font-family: var(--ulm-font-numeric);
    font-size: 10px;
    font-weight: 700;
    /* line-height: 10px; */
    color: #fff;
    text-align: center;
    background: var(--ulm-danger, #c0392b);
    /* border: 2px solid #fff; */
    border-radius: 9999px;
    font-weight: 400;
    height: 20px;
    width: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ulm-bell__menu {
	position: absolute;
	top: calc(100% + 10px);
	right: 0;
	z-index: 60;
	width: min(340px, calc(100vw - 32px));
	overflow: hidden;
	background: #fff;
	border: 1px solid var(--ulm-border, #edf0ee);
	border-radius: 14px;
	box-shadow: 0 24px 48px -28px rgb(41 72 60 / 40%);
}

.ulm-bell__head {
	display: flex;
	gap: 12px;
	align-items: center;
	justify-content: space-between;
	padding: 14px 16px;
	border-bottom: 1px solid var(--ulm-border, #edf0ee);
}

.ulm-bell__title {
	font-size: 14px;
	font-weight: 600;
	color: var(--ulm-deep);
}

.ulm-bell__readall {
	padding: 0;
	font-family: inherit;
	font-size: 12.5px;
	color: var(--ulm-primary);
	cursor: pointer;
	background: none;
	border: 0;
}

.ulm-bell__empty {
	margin: 0;
	padding: 24px 16px;
	font-size: 13px;
	line-height: 1.7;
	color: var(--ulm-ink-muted);
	text-align: center;
}

.ulm-bell__list {
	max-height: 380px;
	padding: 0;
	margin: 0;
	overflow-y: auto;
	list-style: none;
}

.ulm-bell__item {
	border-bottom: 1px solid var(--ulm-border, #edf0ee);
}

.ulm-bell__item:last-child { border-bottom: 0; }

/*
 * The row's own control. A link where the notification has somewhere to go, a
 * button where it has not — both are the target that marks the row read, so
 * both carry the row's padding and hover.
 *
 * A button rather than the plain <span> that used to sit here: a row you can
 * click to mark read has to be reachable by keyboard and announced as
 * something that does anything, and a span is neither.
 */
.ulm-bell__item a,
.ulm-bell__item > button {
	display: block;
	width: 100%;
	padding: 13px 16px;
	border: 0;
	background: none;
	font: inherit;
	color: inherit;
	text-align: left;
	text-decoration: none;
	cursor: pointer;
}

.ulm-bell__item a:hover,
.ulm-bell__item > button:hover { background: var(--ulm-tint-mint, #f2faf7); }

.ulm-bell__item a:focus-visible,
.ulm-bell__item > button:focus-visible {
	outline: 2px solid var(--ulm-primary);
	outline-offset: -2px;
}

/* An unread marker in the gutter, so the list is scannable at a glance. */
.ulm-bell__item--unread { position: relative; }

.ulm-bell__item--unread::before {
	position: absolute;
	top: 19px;
	left: 6px;
	width: 6px;
	height: 6px;
	background: var(--ulm-primary);
	border-radius: 50%;
	content: "";
}

.ulm-bell__itemtitle {
	display: block;
	font-size: 13.5px;
	font-weight: 600;
	line-height: 1.45;
	color: var(--ulm-deep);
}

.ulm-bell__itembody {
	display: block;
	margin-top: 2px;
	font-size: 12.5px;
	line-height: 1.55;
	color: var(--ulm-ink-muted);
}

.ulm-bell__itemago {
	display: block;
	margin-top: 4px;
	font-size: 11.5px;
	color: var(--ulm-ink-faint, #666);
}

@media (max-width: 640px) {
	.ulm-bell__menu {
		position: fixed;
		top: auto;
		right: 12px;
		left: 12px;
		width: auto;
	}
}

/*
 * The bell matches the other header controls at the narrowest width.
 *
 * It has to be stated here rather than with the rest of the header's mobile
 * rules, which sit some 400 lines above: a media query adds no specificity, so
 * `.ulm-bell__trigger { width: 42px }` further down the file would simply win
 * and the bell would stay a size larger than everything beside it.
 */
@media (max-width: 560px) {
	.ulm-bell__trigger {
		width: 38px;
		height: 38px;
	}
}


/* ------------------------------------------- account menu: dash variant -- */

/*
 * The storefront pill is gold on a green bar. The dashboards put the same
 * component on a white header, where gold would shout louder than the page
 * title next to it, so this variant is quiet until you touch it.
 */
.ulm-account--dash .ulm-account__trigger {
	height: 44px;
	padding: 4px 12px 4px 4px;
	background: var(--ulm-surface);
	border: 1px solid var(--ulm-border);
	color: var(--ulm-deep);
}

.ulm-account--dash .ulm-account__trigger:hover {
	filter: none;
	background: var(--ulm-tint-mint);
	border-color: var(--ulm-border-strong);
}

.ulm-account--dash .ulm-account__avatar {
	width: 32px;
	height: 32px;
	font-size: 12.5px;
}

.ulm-account--dash .ulm-account__name {
	font-size: 14.5px;
	max-width: 150px;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* The dot is positioned against the taller storefront pill. */
.ulm-account--dash .ulm-account__dot {
	top: 4px;
	right: 28px;
	border-color: var(--ulm-surface);
}

/* On a narrow dashboard header the name is the first thing worth dropping —
   the avatar still identifies who is signed in. */
@media (max-width: 720px) {
	.ulm-account--dash .ulm-account__name { display: none; }
}

/* --- the address, under the role ---------------------------------------- */

.ulm-account__email {
	margin-top: 2px;
	font-size: 13px;
	color: var(--ulm-ink-muted);
	overflow-wrap: anywhere;
}

/* --- sign out ------------------------------------------------------------ */

.ulm-account__signout {
	display: flex;
	align-items: center;
	gap: 10px;
}

/* --- opening on hover ---------------------------------------------------- */

/*
 * The menu sits 10px clear of its trigger, and that gap is not part of either
 * of them — crossing it with the pointer would fire mouseleave and close the
 * menu on the way to using it. This bridges the gap so the whole path from
 * trigger to first item stays inside the component.
 *
 * Hover is an addition, not the mechanism: the click handler still opens it,
 * which is what a touch screen and a keyboard use.
 */
.ulm-account__menu::before {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 100%;
	height: 12px;
}

/*
 * The pre-launch footer: brand, tagline and the legal bar, with the three link
 * columns withheld from the public. Without this the brand block stayed pinned
 * to the first cell of a four-column grid, leaving three quarters of the footer
 * as empty space — the layout looked broken rather than deliberate.
 */
.ulm-site-footer__inner--bare {
	grid-template-columns: minmax(0, 1fr);
}
