/*
 * base.css — reset, typography, layout primitives.
 *
 * Everything here applies site-wide. Component styles live in components.css;
 * screen-specific layout lives in screens/*.css. If a rule here is doing
 * something only one screen needs, it is in the wrong file.
 *
 * @package Uloominate
 */

/* ------------------------------------------------------------- reset -- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

/*
 * `hidden` has to actually hide.
 *
 * The browser's own rule is `[hidden] { display: none }`, and ANY author rule
 * that sets `display` on the same element beats it — author styles outrank the
 * UA stylesheet regardless of specificity. So a component styled
 * `.thing { display: flex }` ignores the attribute entirely, and every panel
 * this codebase opens and closes by toggling `hidden` was permanently open:
 * the moderation queue's bulk bar and its per-row decline form both sat there
 * with no way to close them.
 *
 * It was being patched one component at a time (`.ulm-account__menu[hidden]`,
 * `.ulm-auth__error[hidden]`, …), which only ever fixed the ones somebody had
 * noticed. `!important` is right here for the same reason it is wrong almost
 * everywhere else: this is not a style, it is the absence of one.
 */
[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }

	*,
	*::before,
	*::after {
		animation-duration: .001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .001ms !important;
		scroll-behavior: auto !important;
	}
}

body {
	margin: 0;
	/* Painted explicitly. The page must not borrow a colour from anywhere. */
	background: var(--ulm-surface);
	color: var(--ulm-ink);
	font-family: var(--ulm-font);
	font-size: var(--ulm-text-base);
	font-weight: var(--ulm-fw-regular);
	line-height: var(--ulm-leading-relaxed);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	/* The design is a fixed 1728px reference reflowed down; nothing should
	   ever push the page sideways. */
	overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 {
	margin: 0;
	color: var(--ulm-deep);
	font-weight: var(--ulm-fw-semibold);
	line-height: var(--ulm-leading-tight);
	letter-spacing: -.02em;
	text-wrap: balance;
}

p {
	margin: 0;
	text-wrap: pretty;
}

ul, ol {
	margin: 0;
	padding: 0;
}

img, svg, video, canvas {
	display: block;
	max-width: 100%;
}

img {
	height: auto;
}

a {
	color: var(--ulm-primary);
	text-decoration: none;
	transition: color var(--ulm-duration-fast) ease;
}

a:hover {
	color: var(--ulm-deep);
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

button {
	cursor: pointer;
	background: none;
	border: 0;
	padding: 0;
}

table {
	border-collapse: collapse;
	width: 100%;
}

/* ------------------------------------------------------- accessibility -- */

/*
 * Focus is visible and uses the brand colour (NFR-8). `:focus-visible` rather
 * than `:focus`, so a mouse click does not leave a ring behind but a keyboard
 * user always knows where they are.
 */
:focus-visible {
	outline: 2px solid var(--ulm-primary);
	outline-offset: 3px;
	border-radius: var(--ulm-radius-xs);
}

.ulm-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Skip link — hidden until focused, then pinned top-left. */
.ulm-skip-link {
	position: absolute;
	top: -100px;
	left: var(--ulm-space-4);
	z-index: var(--ulm-z-toast);
	padding: var(--ulm-space-3) var(--ulm-space-5);
	background: var(--ulm-primary);
	color: var(--ulm-ink-invert);
	border-radius: var(--ulm-radius-sm);
	font-weight: var(--ulm-fw-semibold);
	transition: top var(--ulm-duration-fast) ease;
}

.ulm-skip-link:focus {
	top: var(--ulm-space-4);
	color: var(--ulm-ink-invert);
}

/* ------------------------------------------------------------ layout -- */

/*
 * The design does not centre a container. It positions sections at specific
 * offsets from the page edge, which is why these use the inset tokens rather
 * than `margin: 0 auto`. Reverted to the file's real offsets at the client's
 * request (deviation D-1).
 */
.ulm-page {
	width: 100%;
	max-width: var(--ulm-page-max);
	margin-inline: auto;
}

.ulm-section {
	padding-inline: var(--ulm-inset-section);
}

.ulm-section--hero {
	padding-inline: var(--ulm-inset-hero);
}

.ulm-section--strip {
	padding-inline: var(--ulm-inset-strip);
}

/* A conventional centred container, for screens with no Figma frame of their
   own — dashboards, account, auth (gap G-2). */
.ulm-container {
	width: 100%;
	max-width: var(--ulm-container);
	margin-inline: auto;
	padding-inline: var(--ulm-gutter);
}

.ulm-stack > * + * {
	margin-block-start: var(--flow, var(--ulm-space-4));
}

.ulm-cluster {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--gap, var(--ulm-space-3));
}

.ulm-grid {
	display: grid;
	gap: var(--gap, var(--ulm-space-6));
	grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--min, 260px)), 1fr));
}

/* ------------------------------------------------------- section tints -- */

.ulm-tint-mint   { background: var(--ulm-tint-mint); }
.ulm-tint-lilac  { background: var(--ulm-tint-lilac); }
.ulm-tint-peach  { background: var(--ulm-tint-peach); }
.ulm-tint-sky    { background: var(--ulm-tint-sky); }
.ulm-tint-cream  { background: var(--ulm-tint-cream); }
.ulm-tint-header { background: var(--ulm-tint-header); }

/* -------------------------------------------------------- typography -- */

.ulm-eyebrow {
	margin: 0;
	color: var(--ulm-gold-ink);
	/*
	 * 14px, set here rather than on --ulm-text-md: that token is 18px and is
	 * shared with body-scale text elsewhere, so moving it would resize things
	 * that have nothing to do with eyebrows. An eyebrow is a label above a
	 * heading — at 18px uppercase it read as a heading of its own.
	 */
	font-size: 14px;
	font-weight: var(--ulm-fw-semibold);
	line-height: 1.5;
	letter-spacing: .06em;
	text-transform: uppercase;
}

.ulm-h1 { font-size: var(--ulm-text-hero); }
.ulm-h2 { font-size: var(--ulm-text-section); }
.ulm-h3 { font-size: var(--ulm-text-3xl); }
.ulm-h4 { font-size: var(--ulm-text-xl); }

.ulm-lede {
	font-size: var(--ulm-text-lede);
	line-height: var(--ulm-leading-normal);
	color: var(--ulm-ink);
}

.ulm-muted { color: var(--ulm-ink-muted); }
.ulm-faint { color: var(--ulm-ink-faint); }

.ulm-numeric {
	font-family: var(--ulm-font-numeric);
	font-variant-numeric: tabular-nums;
}

/*
 * The gold highlight behind "Free Until January 1st, 2027" on the landing
 * page. Drawn as a positioned block behind the text rather than a background,
 * because the design's bar sits low and overhangs the text on the right.
 */
.ulm-highlight {
	position: relative;
	display: inline-block;
	width: max-content;
	max-width: 100%;
	font-weight: var(--ulm-fw-bold);
	color: var(--ulm-primary);
}

.ulm-highlight::before {
	content: "";
	position: absolute;
	inset-inline: -3px -14px;
	bottom: 6px;
	height: 27px;
	background: var(--ulm-gold);
	border-radius: 2px;
	z-index: 0;
}

.ulm-highlight > span {
	position: relative;
	z-index: 1;
}

/* --------------------------------------------------------- animation -- */

@keyframes ulm-rise {
	from { opacity: 0; transform: translateY(14px); }
	to   { opacity: 1; transform: none; }
}

.ulm-rise {
	animation: ulm-rise var(--ulm-duration-slow) ease both;
}

/* ------------------------------------------------------------ print -- */

@media print {
	.ulm-site-header,
	.ulm-site-footer,
	.ulm-no-print {
		display: none !important;
	}

	body {
		color: #000;
		background: #fff;
	}
}

/* --------------------------------------------------------- error pages -- */

/*
 * `.ulm-section` insets a full-bleed page — clamp(20px, 9.5vw, 220px), sized
 * against the 1729px frame. On a box already narrowed to 640px that is not an
 * inset, it is most of the box: at 1600px it left 288px for the text, which
 * wrapped the title onto two lines and the body onto four. The block keeps its
 * 640px cap; only what it reserves inside that cap changes.
 */
.ulm-error-page {
	max-width: 640px;
	padding-top: 56px;
	padding-bottom: 72px;
	padding-inline: var(--ulm-gutter);
	margin: 0 auto;
	text-align: center;
}

/*
 * `.ulm-main` is `flex: 1 0 auto` inside a 100vh column, so on a short page it
 * stretches to hold the footer down — and an error page, which is the shortest
 * page there is, sat at the top of it under 300px of blank white. Centring is
 * the whole fix; the main area is already the right height.
 *
 * Scoped with `:has()` so no other screen becomes a flex container. Anything
 * that does not support it renders exactly as before, top-aligned.
 */
.ulm-main:has(> .ulm-error-page) {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.ulm-error-page__code {
	margin: 0 0 12px;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.16em;
	color: var(--ulm-danger, #c0392b);
	text-transform: uppercase;
}

.ulm-error-page__ref {
	margin: 20px 0 0;
	font-size: 12.5px;
	color: var(--ulm-ink-faint, #666);
}

.ulm-error-page__ref code {
	padding: 2px 7px;
	font-family: var(--ulm-font-numeric);
	background: var(--ulm-surface-alt, #f3f4f6);
	border-radius: 5px;
}

/* ----------------------------------------------------------- page frame -- */

/*
 * The outer wrappers. They carried no rules at all, so a short page left the
 * footer floating partway up the viewport instead of sitting at the bottom.
 */

.ulm-site {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.ulm-main {
	flex: 1 0 auto;
	min-width: 0;
}
