/* Giant Avocado Games · design system: DESIGN.md (repo root)
 * genre: editorial · ground: dark · type: Archivo variable, two widths
 * accent: brand purple, interactive only · lime, one meaning per screen
 * motion: response only — nothing plays on a timer
 * Audited 2026-07-30 against Hallmark. Structural findings fixed: card grid
 * replaced with a catalogue index, eyebrows removed, section rhythm varied.
 */
/* ---------------------------------------------------------------------------
   Giant Avocado Games — design tokens
   Brand purple carried over from the previous site; everything else is new.
   --------------------------------------------------------------------------- */

/* Typography is one superfamily at two widths — Archivo Expanded for display,
   Archivo for text. A single family carried across widths is a deliberate
   choice; the safe default would be two unrelated fonts. */
:root {
	--ga-purple: #4f39eb;
	--ga-purple-bright: #7b6bff;
	--ga-lime: #c9f24a;

	--ga-ink: #08080d;
	--ga-surface: #101017;
	--ga-surface-raised: #1d1d27;
	--ga-border: #26263a;

	/* One hue per game, measured from the caption ribbon on each game's own App
	   Store screenshots. The studio already made this decision three times, and
	   reading it beats inventing a fourth palette.

	   Measured from the whole artwork first, which returned violet for both Your
	   Balls and Endless Colonies — true of the pixels and useless as an answer,
	   because it described whichever UI covered the most area rather than the
	   game. The ribbon is the studio's own choice, per title. */
	--ga-yb: #e16046;   /* 10°  · street orange */
	--ga-ec: #ad46e1;   /* 280° · deep space violet */
	--ga-md: #467ae1;   /* 220° · turf blue, 77% of its band */

	/* The page's side margin, needed as a value rather than only as padding:
	   the screenshot rails break out of the column and have to put it back as
	   scroll padding to line up with everything else. */
	--ga-gutter: clamp(20px, 4vw, 40px);

	/* Body text sits at 12.9:1 on --ga-ink; the muted tone at 7.4:1. Both clear
	   WCAG AA comfortably — low-contrast grey body text is its own slop tell. */
	--ga-text: #f7f7fa;
	--ga-text-muted: #a8a8bb;
	--ga-prose: #d6d6e4;
	--ga-on-primary: #ffffff;

	/* Stage and status hues. These live here rather than inline because a hue
	   that exists only at its point of use is a hue nobody can change later —
	   and because two of them had already drifted: the soft-launch badge was
	   carrying #6d5cff against the system's #7b6bff, and the live badge
	   #b8f24a against #c9f24a. Near-misses of your own palette read as
	   sloppiness long before anyone can name why. */
	--ga-amber: #ffb020;
	--ga-amber-text: #ffcf80;
	--ga-danger: #ff5a5a;
	--ga-danger-text: #ff9d9d;
	--ga-archived: #6b6b85;

	/* The header sits over scrolling content, so its ground is ink at alpha. */
	--ga-header-bg: rgb(10 10 18 / 0.82);

	--ga-radius: 14px;
	--ga-radius-lg: 22px;
	--ga-max: 1220px;

	/* One family, one variable file. Archivo carries both the width and the
	   weight axis, so display type and body text are the same typeface set
	   differently rather than two typefaces that have to be made to agree.
	   The body token points at the display one instead of repeating it —
	   two identical declarations are two declarations that drift apart. */
	--ga-font: "Archivo", system-ui, -apple-system, sans-serif;
	--ga-font-body: var(--ga-font);
}

/* Display type runs wide, body runs normal. Same family, two voices. */
h1, h2, h3, h4 {
	font-variation-settings: "wdth" 118;
}

.ga-hero__title {
	font-variation-settings: "wdth" 125;
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	margin: 0;
	background: var(--ga-ink);
	color: var(--ga-text);
	font-family: var(--ga-font-body);
	font-size: 17px;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
	font-family: var(--ga-font);
	font-weight: 700;
	line-height: 1.1;
	letter-spacing: -0.02em;
	margin: 0 0 0.5em;
}

h1 { font-size: clamp(2.5rem, 6vw, 4.5rem); }
h2 { font-size: clamp(1.9rem, 4vw, 3rem); }
h3 { font-size: clamp(1.25rem, 2.5vw, 1.6rem); }

a {
	color: var(--ga-purple-bright);
	text-decoration: none;
}

a:hover { text-decoration: underline; }

img { max-width: 100%; height: auto; display: block; }

.ga-wrap {
	width: 100%;
	max-width: var(--ga-max);
	margin-inline: auto;
	padding-inline: 24px;
}

.ga-section { padding-block: clamp(56px, 9vw, 112px); }

/* One section on a lifted ground so the page has a rhythm instead of a
   metronome. The colour change is the divider — no rule needed with it. */
.ga-section--raised {
	background: var(--ga-surface);
	border-block: 1px solid var(--ga-border);
	padding-block: clamp(72px, 11vw, 140px);
}

/* The eyebrow is gone. It started as an all-caps lime badge above every H1,
   was softened to a sentence-case line, and an outside audit still flagged it:
   a label above every heading is a tic whether or not it shouts. Nothing here
   is ordinal, so nothing needs a marker. Kept as a no-op class so any stray
   markup degrades to plain muted text rather than breaking. */
.ga-eyebrow {
	color: var(--ga-text-muted);
	margin: 0 0 12px;
}

.ga-lede {
	font-size: clamp(1.05rem, 2vw, 1.25rem);
	color: var(--ga-text-muted);
	max-width: 60ch;
}

/* --- Header ------------------------------------------------------------- */

.ga-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: var(--ga-header-bg);
	backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--ga-border);
}

.ga-header__inner {
	display: flex;
	align-items: center;
	gap: 32px;
	min-height: 76px;
}

.ga-logo {
	display: flex;
	align-items: center;
	gap: 10px;
	font-family: var(--ga-font);
	font-weight: 700;
	font-size: 1.05rem;
	color: var(--ga-text);
	letter-spacing: -0.01em;
}

/* Height-constrained so any logo aspect ratio fits the header band. */
.ga-logo img {
	width: auto;
	height: 42px;
	max-width: 120px;
	object-fit: contain;
}

.ga-logo:hover { text-decoration: none; }

.ga-nav {
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: 28px;
}

.ga-nav ul {
	display: flex;
	gap: 28px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.ga-nav a {
	font-family: var(--ga-font);
	font-size: 0.9rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--ga-text-muted);
}

.ga-nav a:hover,
.ga-nav .current-menu-item a {
	color: var(--ga-text);
	text-decoration: none;
}

/* --- Buttons ------------------------------------------------------------ */

.ga-btn {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 13px 26px;
	border-radius: 999px;
	font-family: var(--ga-font);
	font-weight: 700;
	font-size: 0.95rem;
	border: 1px solid transparent;
	transition: transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.ga-btn:hover { text-decoration: none; transform: translateY(-2px); }

.ga-btn--primary {
	background: var(--ga-purple);
	color: var(--ga-on-primary);
}

.ga-btn--primary:hover { background: var(--ga-purple-bright); }

.ga-btn--ghost {
	border-color: var(--ga-border);
	color: var(--ga-text);
}

.ga-btn--ghost:hover { border-color: var(--ga-purple-bright); }

/* --- Hero --------------------------------------------------------------- */

/* No radial glow. The hero is a flat field with a single hard rule — closer to
   a printed poster than to a product landing page, which is the point. */
.ga-hero {
	position: relative;
	padding-block: clamp(64px, 11vw, 132px);
	border-bottom: 1px solid var(--ga-border);
}

/* Two columns where there is room: the studio's sentence, and the studio's
   character standing next to it. Below that, the character goes first — on a
   phone it is the thing worth leading with. */
.ga-hero__inner {
	display: grid;
	grid-template-columns: minmax(0, 1fr) clamp(200px, 26vw, 330px);
	align-items: center;
	gap: clamp(28px, 5vw, 72px);
}

.ga-hero__title {
	max-width: 16ch;
	text-wrap: balance;
}

@media (max-width: 860px) {
	.ga-hero__inner {
		grid-template-columns: minmax(0, 1fr);
		justify-items: start;
	}

	/* Two classes on purpose. `.ga-mascot { width: 100% }` is declared later in
	   this file, and at equal specificity the later rule wins — which handed the
	   mascot the whole column and pushed the headline off the first screen. */
	.ga-mascot.ga-hero__figure {
		order: -1;
		width: clamp(150px, 42vw, 220px);
	}
}

/* Springs sampled from a real damped oscillator (mass 1, stiffness 210,
   damping 20) rather than guessed with a bezier — the overshoot is what makes
   motion read as physical rather than eased. */
:root {
	--ga-spring: linear(0, 0.0254, 0.0907, 0.1814, 0.2862, 0.396, 0.5041, 0.6058, 0.698, 0.7789, 0.8477, 0.9047, 0.9502, 0.9854, 1.0114, 1.0296, 1.0412, 1.0476, 1.05, 1.0492, 1.0463, 1.042, 1.0368, 1.0314, 1.0259, 1.0208, 1.016, 1.0119, 1.0083, 1.0053, 1.0029, 1.0011, 0.9997, 0.9987, 0.998, 0.9977, 0.9975, 0.9975, 0.9976, 0.9978, 0.9981, 0.9984, 0.9986);
}

/* --- The mascot ----------------------------------------------------------
   The hero used to answer the pointer with the headline itself, every letter
   widening on its own spring. It was the better trick and it is gone, because
   two things reaching for the same gesture in one view means neither is read.
   The character wins that contest: variable-font kinetics are a technique
   anyone can apply, and this drawing belongs to one studio.

   Markup order is <img> first, canvas second. Without script, without canvas,
   or under reduced motion, the image is simply the logo and nothing runs. */
.ga-mascot {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 877 / 931;
	touch-action: none;
}

.ga-mascot.is-live {
	cursor: grab;
}

.ga-mascot.is-held {
	cursor: grabbing;
}

.ga-mascot img,
.ga-mascot__canvas {
	display: block;
	width: 100%;
	height: 100%;
}

/* The still is the fallback, so it is only hidden once the canvas is actually
   running — never by a rule that fires before the script proves itself. */
.ga-mascot.is-live img {
	visibility: hidden;
}

.ga-mascot__canvas {
	position: absolute;
	inset: 0;
}

.ga-hero__accent {
	color: var(--ga-purple-bright);
	display: block;
}

.ga-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin-top: 34px;
}

/* --- Game catalogue ------------------------------------------------------
   An index of rules and rows, not a grid of cards. The title carries the
   weight; the icon supports it. Nothing here is a box, so nothing has to be
   the same height as anything else. */

.ga-games-grid {
	margin-top: 40px;
	border-top: 1px solid var(--ga-border);
}

.ga-game-row {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 28px;
	padding: 26px 4px;
	border-bottom: 1px solid var(--ga-border);
	transition: background-color 0.2s ease;
}

.ga-game-row:hover { background: color-mix(in srgb, var(--ga-text) 2%, transparent); }

.ga-game-row__icon { display: block; line-height: 0; }

.ga-game-card__icon {
	width: 84px;
	height: 84px;
	border-radius: 19px;
	object-fit: cover;
	background: var(--ga-surface-raised);
	transition: transform 0.4s var(--ga-spring);
}

.ga-game-row:hover .ga-game-card__icon { transform: scale(1.05); }

.ga-game-row__title {
	font-family: var(--ga-font);
	font-size: clamp(1.4rem, 2.6vw, 2rem);
	font-weight: 700;
	font-variation-settings: "wdth" 112;
	line-height: 1.1;
	margin: 0 0 6px;
}

.ga-game-row__title a { color: var(--ga-text); }
.ga-game-row__title a:hover { color: var(--ga-purple-bright); text-decoration: none; }

.ga-game-row__tagline {
	font-size: 0.95rem;
	color: var(--ga-text-muted);
	margin: 0;
}

.ga-game-row__meta {
	display: flex;
	align-items: center;
	gap: 14px;
	flex-wrap: wrap;
	justify-content: flex-end;
}

.ga-game-card__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

@media (max-width: 760px) {
	.ga-game-row {
		grid-template-columns: auto minmax(0, 1fr);
		gap: 18px;
		row-gap: 16px;
	}

	.ga-game-row__meta {
		grid-column: 1 / -1;
		justify-content: flex-start;
	}
}

.ga-store-link {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 9px 16px;
	border-radius: 999px;
	background: var(--ga-surface-raised);
	border: 1px solid var(--ga-border);
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--ga-text);
}

.ga-store-link:hover {
	text-decoration: none;
	border-color: var(--ga-purple-bright);
}

/* --- Stage badge -------------------------------------------------------- */

.ga-badge {
	display: inline-block;
	padding: 4px 11px;
	border-radius: 999px;
	font-family: var(--ga-font);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.ga-badge--live        { background: color-mix(in srgb, var(--ga-lime) 16%, transparent); color: var(--ga-lime); }
.ga-badge--soft_launch { background: color-mix(in srgb, var(--ga-purple-bright) 20%, transparent);  color: var(--ga-purple-bright); }
.ga-badge--in_dev      { background: color-mix(in srgb, var(--ga-text) 8%, transparent); color: var(--ga-text-muted); }
.ga-badge--prototype   { background: color-mix(in srgb, var(--ga-amber) 16%, transparent); color: var(--ga-amber); }
.ga-badge--archived    { background: color-mix(in srgb, var(--ga-text) 5%, transparent); color: var(--ga-archived); }
/* A superseded release. Dimmer than in_dev on purpose: an old version is not
   work in progress, it is history, and should recede behind the live row. */
.ga-badge--old         { background: color-mix(in srgb, var(--ga-text) 5%, transparent); color: var(--ga-text-muted); opacity: 0.75; }

/* --- Internal (team-only) tables ---------------------------------------- */

.ga-team-note {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 14px 18px;
	border-radius: var(--ga-radius);
	background: color-mix(in srgb, var(--ga-amber) 10%, transparent);
	border: 1px solid color-mix(in srgb, var(--ga-amber) 30%, transparent);
	color: var(--ga-amber-text);
	font-size: 0.9rem;
	margin-bottom: 28px;
}

.ga-table-scroll { overflow-x: auto; }

.ga-table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.92rem;
	min-width: 720px;
}

.ga-table th,
.ga-table td {
	text-align: left;
	padding: 14px 16px;
	border-bottom: 1px solid var(--ga-border);
	vertical-align: middle;
}

.ga-table th {
	font-family: var(--ga-font);
	font-size: 0.72rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ga-text-muted);
	font-weight: 700;
}

.ga-table tbody tr:hover { background: color-mix(in srgb, var(--ga-text) 2%, transparent); }

/* --- Support page + contact form ---------------------------------------- */

/* --- Studio chronology ---------------------------------------------------
   The year is the anchor, set at heading size, because the point of the list
   is the span it covers. Same rules-and-rows construction as the games
   catalogue — the site should recognise itself. */
.ga-chronology {
	list-style: none;
	margin: 40px 0 0;
	padding: 0;
	border-top: 1px solid var(--ga-border);
}

.ga-chronology__item {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: baseline;
	gap: 32px;
	padding: 26px 4px;
	border-bottom: 1px solid var(--ga-border);
}

.ga-chronology__year {
	font-size: clamp(1.4rem, 2.6vw, 2rem);
	font-weight: 700;
	font-variation-settings: "wdth" 112;
	color: var(--ga-text-muted);
	font-variant-numeric: tabular-nums;
}

.ga-chronology__title {
	font-size: clamp(1.1rem, 2vw, 1.35rem);
	margin: 0 0 6px;
}

.ga-chronology__title a { color: var(--ga-text); text-decoration: none; }
.ga-chronology__title a:hover { color: var(--ga-purple-bright); }

.ga-chronology__note {
	margin: 0;
	color: var(--ga-text-muted);
	max-width: 62ch;
}

@media (max-width: 700px) {
	.ga-chronology__item { grid-template-columns: auto minmax(0, 1fr); gap: 20px; }
	.ga-chronology__item .ga-badge { grid-column: 2; justify-self: start; }
}

.ga-support-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
	gap: 56px;
	margin-top: 56px;
	align-items: start;
}

.ga-support-aside h3 {
	font-size: 1rem;
	letter-spacing: 0;
	text-transform: none;
	color: var(--ga-text);
	margin: 30px 0 6px;
	padding-top: 14px;
	border-top: 1px solid var(--ga-border);
}

.ga-support-aside h3:first-child { margin-top: 0; }
.ga-support-aside p { color: var(--ga-text-muted); margin: 0; }

.ga-form { margin-top: 8px; }

.ga-form__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 18px;
}

.ga-form__field { margin-bottom: 18px; }

.ga-form__field label {
	display: block;
	font-family: var(--ga-font);
	font-size: 0.8rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ga-text-muted);
	margin-bottom: 7px;
}

.ga-form__field input,
.ga-form__field textarea,
.ga-form__field select {
	width: 100%;
	padding: 13px 16px;
	border-radius: 12px;
	background: var(--ga-surface);
	border: 1px solid var(--ga-border);
	color: var(--ga-text);
	font-family: inherit;
	font-size: 1rem;
	transition: border-color 0.15s ease;
}

/* A native select ignores the styling above without this, and would render as a
   pale system control in the middle of a dark form. */
.ga-form__field select {
	appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23a8a8bb' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	padding-right: 42px;
	cursor: pointer;
}

.ga-form__field textarea { resize: vertical; min-height: 150px; }

.ga-form__field input:focus,
.ga-form__field textarea:focus,
.ga-form__field select:focus {
	outline: none;
	border-color: var(--ga-purple-bright);
}

/* Off-screen rather than display:none — some bots skip hidden fields. */
.ga-form__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.ga-form__notice {
	padding: 15px 20px;
	border-radius: var(--ga-radius);
	margin-bottom: 24px;
	font-size: 0.95rem;
}

.ga-form__notice--ok {
	background: color-mix(in srgb, var(--ga-lime) 12%, transparent);
	border: 1px solid color-mix(in srgb, var(--ga-lime) 35%, transparent);
	color: var(--ga-lime);
}

.ga-form__notice--error {
	background: color-mix(in srgb, var(--ga-danger) 10%, transparent);
	border: 1px solid color-mix(in srgb, var(--ga-danger) 32%, transparent);
	color: var(--ga-danger-text);
}

@media (max-width: 860px) {
	.ga-support-grid { grid-template-columns: 1fr; gap: 40px; }
	.ga-form__row { grid-template-columns: 1fr; gap: 0; }
}

/* --- Single game hero --------------------------------------------------- */

.ga-game-hero {
	display: flex;
	align-items: flex-start;
	gap: 30px;
	flex-wrap: wrap;
}

.ga-game-hero__icon {
	width: 116px;
	height: 116px;
	border-radius: 26px;
	border: 1px solid var(--ga-border);
	flex-shrink: 0;
}

.ga-game-hero > div { flex: 1 1 340px; }


/* --- Screenshot galleries ------------------------------------------------
   Editors add these with the core gallery block, so the theme only supplies
   the styling. Phone screenshots and landscape captures land in the same
   block, hence the aspect-ratio reset rather than a fixed crop. */

/* Core already lays these out — it sizes each figure as a percentage of the
   gallery row. An earlier attempt replaced that with a grid, which broke the
   sizing: the percentage then resolved against the grid cell instead of the
   row, so every screenshot rendered at a quarter of its column. The layout
   belongs to core; the theme only supplies the chrome. It also means the
   column count an editor picks in the block actually takes effect. */
.wp-block-gallery.has-nested-images {
	margin: 32px 0 0;
	gap: 16px;
}

.wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image) {
	overflow: hidden;
	border-radius: var(--ga-radius);
	border: 1px solid var(--ga-border);
	background: var(--ga-surface);
}

/* --- Content pages ------------------------------------------------------ */

/* The block itself spans the column so galleries and images use the full page;
   the measure is applied to running text only.

   Not in `ch`: that unit follows the element's own font, and the display face
   runs wide — 68ch on a heading resolved to 2350px, constraining nothing. */
.ga-prose { max-width: none; }

.ga-prose p,
.ga-prose ul,
.ga-prose ol {
	color: var(--ga-prose);
	max-width: 660px;
}

.ga-prose h2 {
	margin-top: 1.8em;
	max-width: 660px;
}

/* Spacing above a prose block belongs to whatever contains it. Without this,
   a block that opens with a heading sits lower than the column beside it. */
.ga-prose > :first-child { margin-top: 0; }

.ga-prose h3 { max-width: 660px; }

/* --- Footer ------------------------------------------------------------- */

.ga-footer {
	border-top: 1px solid var(--ga-border);
	padding-block: 48px;
	color: var(--ga-text-muted);
	font-size: 0.9rem;
}

.ga-footer__inner {
	display: flex;
	flex-wrap: wrap;
	gap: 20px;
	align-items: center;
	justify-content: space-between;
}

.ga-footer a { color: var(--ga-text-muted); }
.ga-footer a:hover { color: var(--ga-text); }

.ga-footer__links {
	display: flex;
	flex-wrap: wrap;
	gap: 22px;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* --- Screenshot strip ---------------------------------------------------- */

/* The strip breaks out of the page gutter so the shots run to both edges, and
   the gutter is restored as scroll padding — otherwise the first shot starts
   flush against the window and reads as cropped rather than as a row. */
.ga-shots {
	margin-inline: calc(50% - 50vw);
	/* Top only. The section below opens with its own padding, and adding a
	   bottom here as well left the strip floating in the middle of a gap
	   almost twice the size of the one above it. */
	padding-block: clamp(28px, 5vw, 56px) 0;
}

.ga-shots__strip {
	display: flex;
	gap: 16px;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory;
	padding-inline: max(24px, calc(50vw - (var(--ga-max) / 2)));
	scroll-padding-inline: max(24px, calc(50vw - (var(--ga-max) / 2)));
	padding-block: 4px;
}

/* Uniform height, width from the artwork. The games are not the same shape —
   one is played in landscape and two in portrait — and matching on height is
   what lets all three sit in the same row without cropping any of them. */
.ga-shots__shot {
	flex: none;
	height: clamp(320px, 52vh, 560px);
	width: auto;
	/* The global `img { max-width: 100% }` has to be lifted here. With the
	   height fixed and the width capped at the container, the browser honours
	   both and drops the aspect ratio — a landscape shot arrived 780px wide
	   and was squeezed into 342. Only phones were narrow enough to trigger it,
	   which is why it looked fine on every desktop check. */
	max-width: none;
	border-radius: var(--ga-radius);
	border: 1px solid var(--ga-border);
	background: var(--ga-surface);
	scroll-snap-align: start;
}

/* On a phone the two orientations cannot share a height. Your Balls is played
   in landscape; at a height that makes it readable it is twice as wide as the
   screen, while the portrait games at that same height fit comfortably. So the
   constraint here is a box rather than a line: each shot fills as much of it as
   its own shape allows, and both orientations stay honest. */
@media (max-width: 700px) {
	.ga-shots__shot {
		height: auto;
		max-height: 62vh;
		max-width: 88vw;
	}
}

.ga-shots__strip:focus-visible {
	outline: 2px solid var(--ga-purple-bright);
	outline-offset: 4px;
}

/* --- Utility ------------------------------------------------------------ */

.ga-empty {
	padding: 40px;
	border: 1px dashed var(--ga-border);
	border-radius: var(--ga-radius);
	color: var(--ga-text-muted);
	text-align: center;
}

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

@media (max-width: 720px) {
	.ga-nav ul { gap: 18px; }
	.ga-header__inner { min-height: 64px; gap: 16px; }
	.ga-nav a { font-size: 0.8rem; }
}

@media (prefers-reduced-motion: reduce) {
	* { transition: none !important; }
}

/* --- Internal tools: filters and dense metric tables --------------------- */

/* The team and partner pages are working screens, not marketing ones. They
   need a tighter control row and a table that stays readable at fourteen
   columns, which the page-level button and table styles are not built for. */

.ga-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
	margin: 0 0 14px;
}

.ga-toolbar__label {
	font-size: 0.72rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ga-text-muted);
	font-weight: 700;
	margin-right: 2px;
}

/* A chip is a ga-btn at working-screen scale: same pill, same motion, but
   sized for a row of eight rather than a call to action. */
.ga-chip {
	display: inline-flex;
	align-items: center;
	padding: 7px 16px;
	border-radius: 999px;
	border: 1px solid var(--ga-border);
	font-family: var(--ga-font);
	font-weight: 700;
	font-size: 0.82rem;
	color: var(--ga-text);
	transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.ga-chip:hover { text-decoration: none; border-color: var(--ga-purple-bright); }

.ga-chip[aria-current="true"] {
	background: var(--ga-purple);
	border-color: var(--ga-purple);
	color: var(--ga-on-primary);
}

.ga-select {
	appearance: none;
	padding: 7px 34px 7px 14px;
	border-radius: 999px;
	border: 1px solid var(--ga-border);
	background-color: transparent;
	color: var(--ga-text);
	font-family: var(--ga-font);
	font-weight: 700;
	font-size: 0.82rem;
	/* Chevron drawn in the background so the control keeps the pill shape
	   instead of falling back to the platform select widget. */
	background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}

.ga-select:focus-visible { outline: 2px solid var(--ga-purple-bright); outline-offset: 2px; }

/* Numbers, many columns, read down a single row. Narrower padding and tabular
   figures keep the digits aligned so a column can be scanned. */
.ga-table--metrics { font-size: 0.86rem; }

.ga-table--metrics th,
.ga-table--metrics td { padding: 11px 12px; }

.ga-table--metrics td.ga-num,
.ga-table--metrics th.ga-num {
	text-align: right;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.ga-table--metrics th.ga-num { letter-spacing: 0.06em; }

/* The version column stays put while the numbers scroll, otherwise a row on
   the right of a fourteen-column table belongs to no visible version. */
.ga-table--metrics th.ga-sticky,
.ga-table--metrics td.ga-sticky {
	position: sticky;
	left: 0;
	background: var(--ga-bg);
	z-index: 1;
}

/* A rule above each new version turns a flat list into groups you can read
   down: this version, then the one before it. */
.ga-table--metrics tbody tr.ga-version-start td,
.ga-table--metrics tbody tr.ga-version-start th {
	border-top: 1px solid color-mix(in srgb, var(--ga-purple-bright) 45%, transparent);
}

.ga-table--metrics tbody tr.ga-version-start:first-child td { border-top: 0; }

.ga-metric-legend {
	margin-top: 12px;
	font-size: 0.78rem;
	color: var(--ga-text-muted);
}

/* --- Team hub ------------------------------------------------------------ */

.ga-hub__row {
	padding: 22px 4px;
	border-bottom: 1px solid var(--ga-border);
}

.ga-hub__row:first-child { border-top: 1px solid var(--ga-border); }

.ga-hub__head {
	display: flex;
	align-items: center;
	gap: 14px;
	flex-wrap: wrap;
}

.ga-hub__title {
	font-size: clamp(1.15rem, 2.2vw, 1.5rem);
	margin: 0;
}

.ga-hub__meta {
	margin: 6px 0 14px;
	color: var(--ga-text-muted);
	font-size: 0.85rem;
	font-variant-numeric: tabular-nums;
}

.ga-hub__actions { margin: 0; }

/* Leaving the site reads differently from moving inside it. */
.ga-chip--out {
	border-style: dashed;
	color: var(--ga-text-muted);
}

.ga-chip--out:hover { color: var(--ga-text); }

/* An em dash standing in for absent data. Dimmed so a table of real values
   reads as content with gaps, not as a table half full of punctuation. */
.ga-muted {
	color: var(--ga-text-muted);
	opacity: 0.6;
}

/* --- Game list (metrics catalogue) -------------------------------------- */

/* Icon beside name, stacked vertically. The icon does real work here: a
   partner scanning for a title recognises the store artwork before the text. */
.ga-gamelist { margin-top: 28px; }

.ga-gamerow {
	display: flex;
	gap: 20px;
	align-items: flex-start;
	padding: 22px 0;
	border-top: 1px solid var(--ga-hairline, rgba(255,255,255,0.08));
}
.ga-gamerow:last-child { border-bottom: 1px solid var(--ga-hairline, rgba(255,255,255,0.08)); }

.ga-gamerow__icon { flex: 0 0 auto; }
.ga-gamerow__icon img,
.ga-gamerow__placeholder {
	display: block;
	width: 72px;
	height: 72px;
	border-radius: 16px;
	object-fit: cover;
	background: color-mix(in srgb, var(--ga-text) 8%, transparent);
}

.ga-gamerow__body { flex: 1 1 auto; min-width: 0; }

.ga-gamerow__head {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
}
.ga-gamerow__title {
	margin: 0;
	font-size: clamp(1.1rem, 2.2vw, 1.4rem);
	overflow-wrap: anywhere;
}
.ga-gamerow__meta {
	margin: 6px 0 0;
	color: var(--ga-text-muted);
	font-size: 0.92rem;
}
.ga-gamerow__actions { margin-top: 14px; }

/* The one button that leads somewhere new on this page, so it carries weight
   the outbound store links deliberately do not. */
.ga-chip--primary {
	background: var(--ga-purple-bright);
	border-color: var(--ga-purple-bright);
	color: #fff;
}
.ga-chip--primary:hover { color: #fff; opacity: 0.9; }

@media (max-width: 560px) {
	.ga-gamerow { gap: 14px; }
	.ga-gamerow__icon img,
	.ga-gamerow__placeholder { width: 56px; height: 56px; border-radius: 13px; }
}

/* --- Internal tool chrome ------------------------------------------------ */

/* The team pages share the site's glass panel but not its contents: the mark
   leads inward, the nav is the tool's own, and the right-hand side says who is
   signed in. `.head__in` is already a space-between flex row, so the identity
   block simply becomes its third child. */

.head--team .head__word {
	font-size: 0.72rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--ga-text-muted);
}

.head--team nav {
	min-width: 0;
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scrollbar-width: none;
}

.head--team nav::-webkit-scrollbar {
	display: none;
}

.head--team nav a {
	flex: none;
	white-space: nowrap;
}

.head__who {
	display: flex;
	align-items: center;
	gap: 12px;
	flex: none;
	font-size: 0.76rem;
}

.head__user {
	color: var(--ga-text-muted);
	white-space: nowrap;
}

.head__out {
	color: var(--ga-text);
	text-decoration: none;
	padding: 7px 12px;
	border-radius: 999px;
	border: 1px solid var(--ga-border, rgba(255,255,255,0.14));
	white-space: nowrap;
}
.head__out:hover { background: rgb(255 255 255 / 0.09); }

/* The current page, marked in the tool nav. Weight rather than colour, so it
   still reads when the accent is doing other work on the page below. */
.head--team nav a[aria-current="page"] {
	color: var(--ga-text);
	background: rgb(255 255 255 / 0.09);
}

/* Nothing to sell at the bottom of a build table. */

/* Below 700px the identity block is the first thing that can go: the nav is
   how you move, the name is only who you are, and it is one tap away in the
   log-out link that stays. */
@media (max-width: 700px) {
	.head__user { display: none; }

	/* The wordmark gives way only when a full nav is competing for the panel.
	   A partner sees one page and no menu, so their header keeps its name —
	   which on a phone is the only thing telling them where they are. */
	.head--team:not(.head--solo) .head__word { display: none; }
}

/* --- Sign in ------------------------------------------------------------- */

/* A small panel, not a page-wide form. It sits under the heading of whichever
   gated page you asked for, so signing in feels like passing a door rather
   than being sent somewhere else and bounced back. */
.ga-signin {
	margin-top: 32px;
	max-width: 380px;
	padding: 28px;
	border: 1px solid var(--ga-border, rgba(255,255,255,0.14));
	border-radius: 18px;
	background: color-mix(in srgb, var(--ga-text) 4%, transparent);
}

.ga-signin__title { margin: 0 0 6px; font-size: 1.15rem; }

.ga-signin__note,
.ga-signin__foot {
	margin: 0 0 18px;
	color: var(--ga-text-muted);
	font-size: 0.85rem;
	line-height: 1.5;
}
.ga-signin__foot { margin: 18px 0 0; }

/* Failure is one message for every cause, so it never says which half was
   wrong. Coloured, not shouted. */
.ga-signin__error {
	margin: 0 0 16px;
	padding: 10px 12px;
	border-radius: 10px;
	font-size: 0.85rem;
	background: color-mix(in srgb, var(--ga-amber, #e0a458) 14%, transparent);
	color: var(--ga-amber, #e0a458);
}

.ga-signin__form { display: grid; gap: 14px; }

.ga-signin__field { display: grid; gap: 6px; }
.ga-signin__field span {
	font-size: 0.72rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ga-text-muted);
}
.ga-signin__field input {
	width: 100%;
	padding: 11px 13px;
	border-radius: 10px;
	border: 1px solid var(--ga-border, rgba(255,255,255,0.16));
	background: rgb(0 0 0 / 0.25);
	color: var(--ga-text);
	font: inherit;
	font-size: 0.95rem;
}
.ga-signin__field input:focus-visible {
	outline: 2px solid var(--ga-purple-bright);
	outline-offset: 1px;
}

.ga-signin__remember {
	display: flex;
	align-items: center;
	gap: 9px;
	font-size: 0.85rem;
	color: var(--ga-text-muted);
}
.ga-signin__remember input { accent-color: var(--ga-purple-bright); }

.ga-signin .ga-btn { justify-self: start; }

@media (max-width: 480px) {
	.ga-signin { padding: 22px; max-width: none; }
}

/* site.css hides the wordmark below 560px for the public header, where a full
   nav is competing for the panel. The partner header has no nav at all, and on
   a phone that name is the only thing telling them which place they are in —
   so the solo header keeps it. Higher specificity than the rule it overrides,
   which is what decides this rather than load order. */
@media (max-width: 560px) {
	.head--team.head--solo .head__word { display: inline; }
}
