/* =====================================================================
   FINN-CLASSIC · BASE
   Reset · typography · the Thai contract · buttons · utilities · motion
   ===================================================================== */

*,*::before,*::after{ box-sizing:border-box; }

html{
	-webkit-text-size-adjust:100%;
	scroll-behavior:smooth;
}

body{
	margin:0;
	overflow-x:hidden;                 /* guarantees zero horizontal scroll at 320px */
	font-family:var(--font-body);
	font-size:var(--t-body);
	line-height:var(--lh-body);
	color:var(--color-text-primary);
	background:var(--color-bg-primary);
	-webkit-font-smoothing:antialiased;
}

img{ max-width:100%; display:block; }

/* ---------- Headings -------------------------------------------------- */
h1,h2,h3,.fc-display{
	font-family:var(--font-display);
	font-weight:700;
	line-height:var(--lh-display);
	letter-spacing:.02em;   /* Cinzel caps need it. Removed on Thai — see below. */
	margin:0;
}
h1{ font-size:var(--t-hero);    font-weight:900; }
h2{ font-size:var(--t-section); }
h3{ font-size:var(--t-tile);    }

/* =====================================================================
   THE THAI CONTRACT — three independent guarantees
   ---------------------------------------------------------------------
   Cinzel has no Thai glyphs. Without this block, a Thai heading either
   renders as tofu or falls back to a serif that clips its tone marks.

   1. Per-glyph fallback lives in --font-display (see fc-tokens.css).
   2. This :lang(th) block hard-swaps display headings to the Thai face
      and kills letter-spacing / uppercase, which mangle Thai.
      It fires because i18n.js sets document.documentElement.lang, and a
      pre-paint script in fc_head() sets it before first paint.
   3. line-height is never below 1.14 anywhere in this codebase.

   NOTE ON THE SELECTOR FORM: these use `h1:lang(th)`, NOT `:lang(th) h1`.
   The latter is a descendant combinator — with <html lang="th"> it would
   match EVERY h1 on the page, including the hero H1 that is explicitly
   marked lang="en", and force the Thai face onto a Latin display line.
   `h1:lang(th)` tests the element's OWN computed language, which inherits
   from <html> but is overridden by a local lang="en". That is what we want.
   ===================================================================== */
h1:lang(th),
h2:lang(th),
h3:lang(th),
.fc-display:lang(th){
	font-family:var(--font-body);
	font-weight:700;
	letter-spacing:0;
	text-transform:none;
	line-height:var(--lh-thai);
}
body:lang(th),
p:lang(th),
li:lang(th),
.btn:lang(th){
	letter-spacing:0;
	text-transform:none;
	word-break:normal;
}
p:lang(th),
li:lang(th){ line-height:var(--lh-thai); }

/* ---------- Eyebrow: 14px uppercase, LATIN ONLY ------------------------ */
.eyebrow{
	font-family:var(--font-body);
	font-size:var(--t-label);
	font-weight:600;
	letter-spacing:.10em;
	text-transform:uppercase;
	margin:0;
}
.eyebrow:lang(th){ letter-spacing:.02em; text-transform:none; }

/* ---------- Links ------------------------------------------------------ */
a{
	color:var(--color-blue);
	text-decoration-thickness:1px;
	text-underline-offset:3px;
}

/* ---------- Focus: visible everywhere. `outline:none` is forbidden. ----- */
:focus-visible{
	outline:3px solid var(--color-focus-light);
	outline-offset:3px;
	border-radius:2px;
}
.site-nav :focus-visible,
.hero :focus-visible,
.qa :focus-visible,
.status :focus-visible,
.site-foot :focus-visible{
	outline-color:var(--color-focus-dark);
}

/* ---------- Layout ------------------------------------------------------ */
.container{
	width:100%;
	max-width:var(--container-width);
	margin-inline:auto;
	padding-inline:var(--gutter);
}

.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{
	position:absolute; left:var(--space-4); top:-72px; z-index:200;
	background:var(--color-gold); color:var(--color-navy-ink);
	padding:12px 20px; border-radius:var(--radius-small);
	font-weight:600; text-decoration:none;
	transition:top var(--dur-fast) var(--ease-press);
}
.skip-link:focus{ top:var(--space-3); }

/* =====================================================================
   BUTTONS — the two loudest elements on the page.
   Both are SOLID FILLS. No ghost buttons: a ghost button forfeits the
   fight for attention, and Download / Register must win it.
   Each carries a 2px border so it has a real boundary on any surface
   (WCAG 1.4.11 — a gold fill alone is only 1.75:1 against cream).
   ===================================================================== */
.btn{
	display:inline-flex; align-items:center; justify-content:center;
	min-height:56px; min-width:224px;
	padding:0 var(--space-6);
	border-radius:var(--radius-medium);
	font-family:var(--font-body);
	font-size:1.0625rem;
	font-weight:600;
	line-height:var(--lh-button);   /* 1.35 — Thai tone marks survive */
	letter-spacing:.01em;
	text-align:center;
	text-decoration:none;
	cursor:pointer;
	transition:transform var(--dur-fast) var(--ease-press),
	           box-shadow var(--dur-fast) var(--ease-press),
	           background  var(--dur-fast) var(--ease-press);
}
.btn:lang(th){ letter-spacing:0; }

.btn--primary,
.btn-primary{                                    /* legacy alias — sub-pages use .btn-primary */
	background:var(--color-gold);
	color:var(--color-navy-ink);                 /* 8.47:1 on the gold fill */
	border:2px solid var(--color-gold-ink);      /* 5.49:1 vs cream — the required boundary */
	box-shadow:var(--shadow-press-gold);
}
.btn--secondary{
	background:var(--color-blue);
	color:var(--color-text-on-dark-max);         /* 7.20:1 on the blue fill */
	border:2px solid var(--color-blue-deep);     /* 9.89:1 vs cream */
	box-shadow:var(--shadow-press-blue);
}

.btn:hover{ transform:translateY(-2px); }
.btn:active{ transform:translateY(3px); box-shadow:none; }   /* letterpress collapse */

/* The buttons sit on BOTH navy (hero, nav, footer) and cream (sub-pages), so a
   single-colour ring is invisible on one of them — a navy ring vanished against
   the navy hero. This is a two-tone ring: a white outline that reads on navy,
   plus a dark halo just outside it that reads on cream. One of the two is always
   visible, whatever the surface. */
.btn:focus-visible{
	outline:3px solid #FFFFFF;
	outline-offset:2px;
	box-shadow:0 0 0 6px rgba(11,27,56,.92);
}

.btn--sm{ min-height:44px; min-width:0; padding:0 var(--space-5); font-size:1rem; }
.btn--block{ width:100%; }

/* =====================================================================
   SECTION HEADINGS
   The mark is gold-ink on light (5.49:1) and gold on dark (9.07:1).
   Same ornament, two legal values — this is LAW 1 in practice.
   ===================================================================== */
.section-head{ margin-bottom:var(--space-7); }
.section-head__mark{
	display:block; width:40px; height:3px;
	background:var(--color-gold-ink);
	margin-bottom:var(--space-4);
}
.section-head__eyebrow{ color:var(--color-gold-ink); margin:0 0 6px; }
.section-head h2{ color:var(--color-text-primary); }
.section-head__sub{
	margin:var(--space-3) 0 0;
	color:var(--color-text-secondary);
	max-width:60ch;
}

.section-head--dark .section-head__mark   { background:var(--color-gold); }
.section-head--dark .section-head__eyebrow{ color:var(--color-gold); }
.section-head--dark h2                    { color:var(--color-text-on-dark); }
.section-head--dark .section-head__sub    { color:var(--color-text-on-dark-dim); }

/* =====================================================================
   MOTION — five animations for the whole page. Exactly one loops.
   ===================================================================== */
@keyframes hero-rise  { from{ opacity:0; transform:translateY(16px); } to{ opacity:1; transform:none; } }
@keyframes art-settle { from{ transform:scale(1.05); }                to{ transform:scale(1); } }
@keyframes reveal-up  { from{ opacity:0; transform:translateY(12px); } to{ opacity:1; transform:none; } }
@keyframes status-pulse{ 0%,100%{ opacity:1; } 50%{ opacity:.45; } }

/* Scroll reveal — section level only, one-shot.
   The starting opacity:0 is scoped to `.js`, which the inline pre-paint script
   in fc_head() adds. Without that guard, a JS failure (blocked file, parse
   error, scripting disabled) would leave Quick Access, Server Status and
   Highlights permanently invisible — the content would be gone, not just
   un-animated. Progressive enhancement: no JS, no hiding. */
.js [data-reveal]{ opacity:0; }
.js [data-reveal].is-in{ animation:reveal-up 500ms var(--ease-out) both; }

/* =====================================================================
   REDUCED MOTION
   Note: CSS cannot pause an animated GIF. The decorative monster sprites
   are therefore HIDDEN rather than frozen — every one of them is
   aria-hidden and purely ornamental, so nothing is lost.
   ===================================================================== */
@media (prefers-reduced-motion:reduce){
	*,*::before,*::after{
		animation-duration:.001ms !important;
		animation-iteration-count:1 !important;
		transition-duration:.001ms !important;
		scroll-behavior:auto !important;
	}
	[data-reveal],
	[data-reveal].is-in,
	.hero__col > *{
		opacity:1 !important;
		transform:none !important;
	}
	.hero__img{ transform:none !important; }
	.status__dot{ animation:none !important; opacity:1 !important; }
	/* Ambient hero life is decorative — freeze it flat, and hide the elements
	   that only exist to move (twinkles, drifting monsters). */
	.hero__crest,
	.hero__crest::before,
	.crest-shine,
	.hero__sparkles i,
	.hero__mob,
	.status__art{ animation:none !important; transform:none !important; }
	.crest-shine,
	.hero__sparkles,
	.hero__mob{ display:none !important; }
	/* Animated GIFs cannot be paused from CSS, so the decorative sprites are
	   hidden rather than frozen. Every one is aria-hidden and purely ornamental
	   (the sub-page monster cards keep their names), so no information is lost. */
	.qa__sprite,
	.tile__sprite,
	.foot-poring,
	.brand__mark,
	.mob-card .sprite img,
	.feature-icon-ro img,
	.coin-strip img,
	.pixel-tag img{ display:none !important; }
}
