/* MinecraftHackedClients.com
 *
 * Palette, section colours and hover states are taken from the 2016 originals
 * (styles/stylesheet.css and the inline <style> in wizard.php). The layout
 * mechanics are not: the original used fixed-width tiles, a fixed-position
 * footer and a single 1280px breakpoint, which fell apart on a phone.
 */

@font-face {
  font-family: 'Raleway';
  src: url('/fonts/raleway.woff2') format('woff2');
  font-weight: 100 900;          /* v37 ships as a variable font */
  font-style: normal;
  font-display: swap;
}

/* Display face for the homepage tagline. Raleway at 600 was doing the job of a
   display type it was never cut for - it goes muddy at large sizes. Space
   Grotesk has actual character at display scale and its angular details suit
   the subject. Used in exactly one place, so it is preloaded on the homepage
   only rather than on all 118 pages. */
@font-face {
  font-family: 'Space Grotesk';
  src: url('/fonts/space-grotesk.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #272727;
  --bg-section: #323232;
  --ink: #ffffff;
  --ink-dim: #bfbfbf;
  --accent: #8b8be9;             /* homepage title purple */
  --accent-green: #54ffa4;       /* tagline + view counter green */
  --hover: #5278d8;              /* grid tile hover border */
  --red: #cd4e4e;                /* ABOUT band */
  --green: #227733;              /* CONTROLS band */
  --blue: #007290;               /* DOWNLOADS band */
  --bar: rgba(0, 0, 0, .7);
  --edge: rgba(255, 255, 255, .18);
  --shell: min(1180px, 92vw);
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: 'Raleway', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-weight: 300;
  font-size: clamp(15px, 1.05vw + 12px, 19px);
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; }
a { color: var(--accent); }
a:hover { color: var(--accent-green); }

:focus-visible {
  outline: 3px solid var(--accent-green);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: .7em 1.2em;
  background: var(--bg-section);
  z-index: 200;
}
.skip:focus { left: .5rem; top: .5rem; }

/* ------------------------------------------------------------------ header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--bar);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--edge);
  padding-top: env(safe-area-inset-top);
}

.site-header .inner {
  width: var(--shell);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: clamp(.5rem, 2vw, 1.5rem);
  min-height: 56px;
}

.site-header .brand { display: flex; align-items: center; flex: 0 0 auto; }
.site-header .brand img { height: 38px; width: auto; display: block; }

.site-nav { margin-left: auto; display: flex; gap: clamp(.15rem, 1.5vw, .6rem); }

.site-nav a {
  display: flex;
  align-items: center;
  min-height: 44px;                       /* touch target */
  padding: 0 clamp(.5rem, 2vw, .9rem);
  color: var(--ink);
  text-decoration: none;
  font-size: clamp(14px, .5vw + 12px, 17px);
  border-radius: 4px;
  transition: background-color .2s, color .2s;
}
.site-nav a:hover { background: rgba(255, 255, 255, .15); color: var(--ink); }
.site-nav a[aria-current='page'] { color: var(--accent-green); }

/* ------------------------------------------------------------------ footer */

/* Column flex so a full-bleed hero (the homepage splash) can grow to fill
   whatever height is left over rather than leaving a dead band above the
   footer on tall screens. */
main { flex: 1 0 auto; display: flex; flex-direction: column; }

.site-footer {
  flex-shrink: 0;
  background: var(--bar);
  border-top: 1px solid var(--edge);
  text-align: center;
  font-size: 14px;
  color: var(--ink-dim);
  padding: 1rem 1rem calc(1rem + env(safe-area-inset-bottom));
}
.site-footer a { color: var(--ink-dim); }

/* --------------------------------------------------------------- ad slots */

/* Empty and zero-height until tools/ads.json is switched on. */
.ad-slot:empty { display: none; }
.ad-slot {
  display: block;
  width: 100%;
  margin: 1.5rem auto;
  text-align: center;
  /* Ads arrive after paint; min-height is set per slot from ads.json so the
     surrounding content never jumps when they do. */
  overflow: hidden;
}
/* The caption stays hidden until an ad actually lands (app.js adds
   .ad-filled), so a blocked slot never advertises its own emptiness. It still
   occupies its box while waiting, so revealing it causes no shift. */
.ad-slot > .ad-label {
  display: block;
  font-size: 13px;
  letter-spacing: .18em;
  color: var(--ink-dim);
  margin-bottom: .6rem;
  opacity: 0;
  transition: opacity .2s;
}
.ad-slot.ad-filled > .ad-label { opacity: 1; }

/* Nothing arrived - blocked, or no fill. Collapse rather than leave a hole.
   With JavaScript disabled the ad scripts never run either, so no ad renders,
   the caption correctly stays hidden and the slot keeps its reserved box. */
.ad-slot.ad-empty { display: none; }
/* Ad iframes carry hardcoded width/height attributes; without this a 728x90
   forces a horizontal scrollbar on anything narrower than it. */
.ad-slot iframe,
.ad-slot img { max-width: 100%; }

/* 728x90 does not fit a phone. Until there is a 320x50 unit to swap in, these
   slots are hidden below the breakpoint. */
.ad-slot--desktop { display: none; }
@media (min-width: 900px) {
  .ad-slot--desktop { display: block; }
}

/* ------------------------------------------------------------------- home */

.splash {
  position: relative;
  flex: 1 0 auto;
  display: grid;
  place-items: center;
  padding: clamp(2rem, 8vh, 6rem) 1rem;
  overflow: hidden;
  isolation: isolate;
}

.splash-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  background: #000 center/cover no-repeat;
}
.splash-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.splash::after {                       /* the scrim from the original */
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  /* The original used .7, but that frame of the loop is a pale grey and the
     purple title sat on it at poor contrast. .78 plus a shadow fixes that
     without changing the look. */
  background: rgba(0, 0, 0, .78);
}

.splash-copy { text-align: center; max-width: min(92vw, 900px); }
.splash-copy h1 {
  margin: 0;
  font-weight: 300;
  /* "MinecraftHackedClients.com" is one 26-character unbreakable word, so the
     floor here is set by what fits a 375px screen, not by taste. */
  font-size: clamp(1.05rem, 4.6vw, 2.6rem);
  color: var(--accent);
  text-wrap: balance;
  /* Same bloom treatment as the tagline, in the purple, so the two read as
     one lockup rather than two unrelated lines. */
  text-shadow:
    0 0 34px rgba(139, 139, 233, .28),
    0 2px 14px rgba(0, 0, 0, .85);
}
/* Keep a heart from being orphaned onto its own line. */
.splash-copy h1 .heart { color: var(--accent); white-space: nowrap; }

/* The hook. Given a display face, a tighter measure so it breaks into two
   balanced lines rather than three ragged ones, and a soft green bloom that
   reads as neon against the darkened video without hurting legibility - the
   black shadow underneath is what actually keeps the contrast. */
.splash-copy p {
  margin: 1.15rem auto 0;
  max-width: 22ch;
  font-family: 'Space Grotesk', 'Raleway', system-ui, sans-serif;
  font-weight: 500;
  font-size: clamp(1.15rem, 3vw, 1.9rem);
  line-height: 1.22;
  letter-spacing: -.015em;
  color: var(--accent-green);
  text-wrap: balance;
  text-shadow:
    0 0 38px rgba(84, 255, 164, .30),
    0 0 12px rgba(84, 255, 164, .22),
    0 2px 16px rgba(0, 0, 0, .9);
}
.splash-copy .cta {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  margin-top: 2.15rem;
  padding: 0 1.7rem;
  border: 2px solid rgba(255, 255, 255, .85);
  color: var(--ink);
  text-decoration: none;
  font-family: 'Space Grotesk', 'Raleway', system-ui, sans-serif;
  font-weight: 500;
  font-size: 1.02rem;
  letter-spacing: .02em;
  backdrop-filter: blur(2px);
  transition: background-color .2s, color .2s, border-color .2s;
}
.splash-copy .cta:hover { background: var(--ink); color: var(--bg); }

/* ------------------------------------------------------------ client grid */

.shell { width: var(--shell); margin-inline: auto; padding: clamp(1.5rem, 4vw, 3rem) 0; }

.page-head { text-align: center; margin-bottom: clamp(1.5rem, 4vw, 2.5rem); }
.page-head h1 {
  margin: 0;
  font-weight: 300;
  font-size: clamp(1.7rem, 5vw, 2.8rem);
}
.page-head p { margin: .5rem 0 0; color: var(--ink-dim); }

.client-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: clamp(.9rem, 2vw, 1.5rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

.client-card a {
  display: block;
  text-decoration: none;
  color: var(--ink);
  border: 2px solid var(--ink);
  transition: border-color .2s, transform .2s;
}
.client-card a:hover,
.client-card a:focus-visible { border-color: var(--hover); transform: translateY(-2px); }

.client-card .shot {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: #111;
}
.client-card .meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: .75rem;
  padding: .6rem .75rem;
  background: var(--bg-section);
}
.client-card .name { font-size: 1rem; }
.client-card .views { font-size: .8rem; color: var(--accent-green); white-space: nowrap; }

/* ----------------------------------------------------- wizard client page */

.wizard-hero {
  position: relative;
  text-align: center;
  padding: clamp(2.5rem, 8vw, 5rem) 1rem;
  background: var(--bg-section) url('/images/wiz-clientbg.webp') center/cover fixed no-repeat;
  isolation: isolate;
}
.wizard-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(0, 0, 0, .55);
}
.wizard-hero img {
  width: clamp(110px, 18vw, 150px);
  height: auto;
  margin-bottom: 1.5rem;
}
.wizard-hero h1 {
  margin: 0;
  font-weight: 300;
  font-size: clamp(1.8rem, 6vw, 3rem);
}
.wizard-hero .byline { margin: .6rem 0 0; color: var(--ink-dim); }
.wizard-hero .counter-line { margin: 1.2rem 0 0; color: var(--accent-green); }

.band { padding: clamp(2rem, 6vw, 3.75rem) 1rem; }
.band.about { background: var(--red); }
.band.media { background: transparent; }
.band.controls { background: var(--green); }
.band.downloads { background: var(--blue); }
.band.plain { background: var(--bg-section); }

.band .inner { width: var(--shell); margin-inline: auto; text-align: center; }
.band h2 {
  margin: 0 0 1.5rem;
  font-weight: 300;
  font-size: clamp(1.3rem, 3.5vw, 2rem);
  letter-spacing: .14em;
  text-transform: uppercase;
}
.band h3 {
  margin: 2rem 0 .75rem;
  font-weight: 300;
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  color: rgba(255, 255, 255, .85);
}
.band p { margin: 0 auto; max-width: 62ch; }

/* Tables become label/value rows on narrow screens instead of scrolling. */
.kv { width: 100%; max-width: 640px; margin: 0 auto; border-collapse: collapse; }
.kv caption { position: absolute; left: -9999px; }
.kv td { padding: .55rem .75rem; border-bottom: 1px solid rgba(255, 255, 255, .22); }
.kv td:first-child { text-align: left; }
.kv td:last-child { text-align: right; }
.kv tr:last-child td { border-bottom: 0; }
.kv a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.kv a:hover { color: #a1e1ff; }

.dl-note {
  margin-top: 1.25rem;
  font-size: .85rem;
  color: rgba(255, 255, 255, .8);
}

.socials { display: flex; justify-content: center; gap: .9rem; flex-wrap: wrap; margin-top: 1.5rem; }
.socials a {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  filter: grayscale(1);
  transition: border-radius .2s, filter .2s;
}
.socials a:hover { border-radius: 14px; filter: grayscale(0); }
.socials img { width: 26px; height: 26px; }

.layout-toggle { margin-top: 2rem; font-size: .9rem; }
.layout-toggle a { color: rgba(255, 255, 255, .85); }

/* ---------------------------------------------------- classic client page */

.classic { text-align: center; }
.classic .logo { width: clamp(130px, 22vw, 240px); margin: 0 auto; }
.classic h1 {
  margin: 2rem 0 0;
  font-weight: 300;
  font-size: clamp(1.8rem, 6vw, 3rem);
}
.classic .authors { margin: .6rem 0 0; color: var(--ink-dim); }
.classic .description { margin: 2.5rem auto 0; max-width: 62ch; }
.classic .views { margin: 2.5rem 0 0; color: var(--accent-green); font-size: 1.15rem; }

.classic .buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .75rem;
  margin-top: 1.75rem;
}
.classic .buttons a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  min-width: 150px;
  padding: 0 1rem;
  background: #333;
  color: var(--ink);
  border: 2px solid #999;
  text-decoration: none;
  transition: background-color .2s, color .2s;
}
.classic .buttons a:hover { background: var(--ink); color: #333; }

.classic .tables {
  display: grid;
  gap: 2.5rem;
  margin-top: 3rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.classic .tables h2 {
  font-weight: 300;
  font-size: 1.2rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin: 0 0 1rem;
  color: var(--ink-dim);
}

/* ------------------------------------------------------- youtube  facade */

/* Nothing is requested from YouTube until the visitor clicks. The still is the
   client's own thumbnail, so the page makes zero third-party requests on load. */
.video {
  position: relative;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  background: #000;
  border: 0;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  display: block;
}
.video img, .video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}
.video .play {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  width: 74px;
  height: 52px;
  border-radius: 12px;
  background: rgba(0, 0, 0, .72);
  display: grid;
  place-items: center;
  transition: background-color .2s;
}
.video:hover .play { background: #cc0000; }
.video .play::after {
  content: '';
  border-style: solid;
  border-width: 11px 0 11px 19px;
  border-color: transparent transparent transparent #fff;
}
.video .cap {
  position: absolute;
  left: -9999px;
}

/* -------------------------------------------------------------- tutorial */

.tutorial { text-align: center; }
.tutorial h1 { font-weight: 300; font-size: clamp(1.6rem, 5vw, 2.5rem); margin: 0 0 2rem; }

/* ------------------------------------------------------------------- 404 */

.notfound { text-align: center; }
.notfound h1 { font-weight: 300; font-size: clamp(1.8rem, 6vw, 2.8rem); margin: 0 0 1rem; }
.notfound img { width: min(320px, 70vw); margin: 2rem auto; }

/* --------------------------------------------------------- accessibility */

/* The neon bloom is decoration. For anyone who has asked for more contrast it
   is the opposite of helpful - soft coloured haloes reduce edge definition -
   so drop it to a plain hard shadow and let the text carry itself. */
@media (prefers-contrast: more) {
  .splash-copy h1,
  .splash-copy p {
    text-shadow: 0 2px 6px rgba(0, 0, 0, 1);
  }
  .splash::after { background: rgba(0, 0, 0, .88); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
  .client-card a:hover { transform: none; }
}

/* Fixed-attachment backgrounds are janky on touch and cost a lot on mobile. */
@media (max-width: 900px), (hover: none) {
  .wizard-hero { background-attachment: scroll; }
}
