/* freegaming.buzz
 *
 * Dark arcade. The palette is lifted from Sturm Vektor so the portal and the
 * games it hosts read as one thing: NES blue, amber and cyan over near black.
 *
 * Contrast: every text and control pairing here clears WCAG AA against the
 * surface it sits on. Amber and cyan are used as backgrounds only with ink text,
 * and as text only on dark surfaces. Nothing is light on light or dark on dark.
 */

/* ==========================================================================
   Tokens
   ========================================================================== */

:root {
  /* Surfaces, darkest first */
  --ink:            #05060c;
  --surface:        #10121c;
  --surface-raised: #171a28;
  --surface-hover:  #1e2233;
  --line:           #2a2f45;

  /* Brand */
  --deep:   #201080;
  --deep-lift: #2d1aa8;
  --amber:  #f8b800;
  --amber-bright: #ffcc33;
  --cyan:   #3cbcfc;
  --cyan-bright: #7fd4ff;
  --red:    #d02000;

  /* Text. Muted still clears 7:1 on --surface. */
  --text:       #f0f0f0;
  --text-muted: #a8b0c8;
  --text-dim:   #7f88a3;

  --radius:    10px;
  --radius-lg: 16px;

  --shadow:    0 2px 8px rgba(0, 0, 0, .5);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, .6);

  --wrap:  1280px;
  --gap:   1.25rem;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Trebuchet MS", var(--font);

  --ease: cubic-bezier(.2, .7, .3, 1);
}

/* ==========================================================================
   Reset
   ========================================================================== */

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

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

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--ink);
  /* A single soft bloom at the top, the same trick the game cabinet uses. */
  background-image: radial-gradient(ellipse 90% 60% at 50% -10%, #161a3d 0%, transparent 70%);
  background-repeat: no-repeat;
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.2;
  margin: 0 0 .5em;
  font-weight: 700;
}

p { margin: 0 0 1rem; }
ul { margin: 0; padding: 0; list-style: none; }

a { color: var(--cyan); text-decoration: none; }
a:hover { color: var(--cyan-bright); text-decoration: underline; }

/* A visible focus ring on everything keyboard reachable, in a colour that
   stands out against every surface on the site. */
:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 2px;
  border-radius: 4px;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 1.25rem;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  padding: .75rem 1.25rem;
  background: var(--amber);
  color: var(--ink);
  font-weight: 700;
  border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus {
  left: 0;
  text-decoration: none;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(5, 6, 12, .92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 68px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--text);
  margin-right: auto;
}
.brand:hover { color: var(--text); text-decoration: none; }

.brand-mark {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border-radius: 9px;
  background: linear-gradient(145deg, var(--deep-lift), var(--deep));
  color: var(--amber);
  font-size: 1.05rem;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12);
}

.brand-accent { color: var(--amber); }

.primary-nav ul {
  display: flex;
  align-items: center;
  gap: .35rem;
}

.primary-nav a {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .6rem .9rem;
  border-radius: var(--radius);
  color: var(--text-muted);
  font-weight: 600;
  font-size: .95rem;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.primary-nav a:hover {
  background: var(--surface-hover);
  color: var(--text);
  text-decoration: none;
}
.primary-nav a[aria-current="page"] {
  background: var(--surface-raised);
  color: var(--amber);
  box-shadow: inset 0 0 0 1px var(--line);
}
.primary-nav i { font-size: .9em; }

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-raised);
  color: var(--text);
  font-size: 1.1rem;
  cursor: pointer;
}
.nav-toggle:hover { background: var(--surface-hover); }

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .8rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform .12s var(--ease), background .15s var(--ease), box-shadow .15s var(--ease);
}
.btn:hover { text-decoration: none; transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* Ink on amber. The highest contrast pairing available, reserved for the one
   action we most want taken on any given page. */
.btn-primary {
  background: var(--amber);
  color: var(--ink);
  box-shadow: 0 4px 14px rgba(248, 184, 0, .25);
}
.btn-primary:hover {
  background: var(--amber-bright);
  color: var(--ink);
  box-shadow: 0 6px 20px rgba(248, 184, 0, .35);
}

/* Outlined, for the secondary action beside it. Cyan on near black. */
.btn-secondary {
  background: var(--surface-raised);
  color: var(--cyan);
  border-color: var(--line);
}
.btn-secondary:hover {
  background: var(--surface-hover);
  color: var(--cyan-bright);
  border-color: var(--cyan);
}

.btn-lg { padding: 1rem 2rem; font-size: 1.075rem; }

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  padding: clamp(3rem, 8vw, 5.5rem) 0 clamp(2.5rem, 6vw, 4rem);
  overflow: hidden;
}

/* A faint scanline wash, the arcade cue, kept low enough that it never
   interferes with reading the text on top of it. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, .022) 0 1px,
    transparent 1px 3px
  );
}

.hero-inner {
  position: relative;
  z-index: 1;
  max-width: 760px;
}

.hero h1 {
  font-size: clamp(2.25rem, 6vw, 3.75rem);
  letter-spacing: -.5px;
  margin-bottom: .35em;
}
.hero h1 .accent { color: var(--amber); }

.hero-lead {
  font-size: clamp(1.05rem, 2.2vw, 1.25rem);
  color: var(--text-muted);
  margin-bottom: 2rem;
  max-width: 58ch;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .85rem;
  margin-bottom: 2rem;
}

.hero-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 2.25rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}
.hero-stat strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.75rem;
  color: var(--amber);
  line-height: 1.1;
}
.hero-stat span {
  font-size: .85rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .08em;
}

/* ==========================================================================
   Sections
   ========================================================================== */

.section { padding: clamp(2.5rem, 5vw, 3.5rem) 0; }

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}
.section-head h2 {
  font-size: clamp(1.4rem, 3vw, 1.85rem);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: .6rem;
}
.section-head h2 i { color: var(--amber); font-size: .85em; }
.section-head p {
  margin: .25rem 0 0;
  color: var(--text-muted);
  font-size: .95rem;
  width: 100%;
}
.section-link {
  font-weight: 600;
  font-size: .95rem;
  white-space: nowrap;
}

/* ==========================================================================
   Breadcrumb
   ========================================================================== */

.breadcrumb { margin-bottom: 1.25rem; }
.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  font-size: .88rem;
  color: var(--text-muted);
}
.breadcrumb li { display: inline-flex; align-items: center; gap: .5rem; }

/* Separator drawn in CSS so it is decoration, not something a screen reader
   reads out between every crumb. */
.breadcrumb li + li::before {
  content: "\f054"; /* fa-chevron-right */
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  font-size: .6em;
  color: var(--text-dim);
}
.breadcrumb a { color: var(--text-muted); }
.breadcrumb a:hover { color: var(--amber); }
.breadcrumb [aria-current="page"] { color: var(--text); font-weight: 600; }

/* ==========================================================================
   Game grid and cards
   ========================================================================== */

/* auto-fill rather than auto-fit: with a single game in the catalogue, auto-fit
   would stretch that one card the full width of the page. */
.game-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--gap);
}

.game-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform .18s var(--ease), border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.game-card:hover,
.game-card:focus-within {
  transform: translateY(-4px);
  border-color: var(--amber);
  box-shadow: var(--shadow-lg);
}

.game-card-media {
  position: relative;
  /* Declared up front so the browser reserves the space and the grid never
     jumps as thumbnails load. */
  aspect-ratio: 16 / 9;
  background: var(--surface);
  overflow: hidden;
}
.game-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .35s var(--ease);
}
.game-card:hover .game-card-media img { transform: scale(1.05); }

.game-card-body {
  padding: .9rem 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: .35rem;
  flex: 1;
}

.game-card h3 {
  margin: 0;
  font-size: 1.1rem;
}
.game-card h3 a {
  color: var(--text);
}
.game-card h3 a:hover { color: var(--amber); text-decoration: none; }

/* The whole card is clickable, but the accessible name and the focus target
   stay on the real link in the heading. */
.game-card h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.game-card p {
  margin: 0;
  font-size: .9rem;
  color: var(--text-muted);
}

.game-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-top: auto;
  padding-top: .7rem;
}

.tag {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  padding: .25rem .55rem;
  border-radius: 5px;
  background: var(--surface-hover);
  color: var(--text-muted);
  border: 1px solid var(--line);
}

/* Corner badges were removed. They overlapped the top left of every thumbnail,
   which is where the artwork carries the game's own title, so the label covered
   the thing it was meant to draw attention to. Which rail a game sits in already
   says whether it is featured or new. */

/* ==========================================================================
   Category tiles
   ========================================================================== */

.category-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--gap);
}

.category-tile {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: 1.35rem 1.25rem;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  color: var(--text);
  transition: transform .18s var(--ease), border-color .18s var(--ease), background .18s var(--ease);
}
.category-tile:hover {
  transform: translateY(-3px);
  border-color: var(--cyan);
  background: var(--surface-hover);
  color: var(--text);
  text-decoration: none;
}
.category-tile i {
  font-size: 1.5rem;
  color: var(--cyan);
  margin-bottom: .35rem;
}
.category-tile strong { font-size: 1.05rem; }
.category-tile span { font-size: .85rem; color: var(--text-muted); }

/* ==========================================================================
   Prose
   ========================================================================== */

/* Long form text pages. Measure is capped near 70 characters because a line of
   body copy running the full width of a desktop screen is genuinely harder to
   read: the eye loses its place on the return sweep. */
.prose {
  max-width: 70ch;
  font-size: 1.02rem;
  line-height: 1.75;
}

.prose h1 {
  font-size: clamp(1.9rem, 4.5vw, 2.5rem);
  margin-bottom: .3em;
}

.prose h2 {
  font-size: clamp(1.2rem, 2.6vw, 1.45rem);
  margin-top: 2.2em;
  margin-bottom: .6em;
  color: var(--amber);
}

.prose-meta {
  color: var(--text-dim);
  font-size: .9rem;
  margin-bottom: 2rem;
}

.prose .lead {
  font-size: 1.12rem;
  color: var(--text);
  border-left: 3px solid var(--cyan);
  padding-left: 1.1rem;
  margin-bottom: 2rem;
}

.prose p { color: var(--text-muted); }

.prose ul {
  list-style: disc;
  padding-left: 1.4rem;
  margin: 0 0 1rem;
  color: var(--text-muted);
}
.prose li { margin-bottom: .5rem; }
.prose li::marker { color: var(--cyan); }

/* Underlined by default in body copy: colour alone should not be the only thing
   distinguishing a link from the text around it. */
.prose a {
  color: var(--cyan);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.prose a:hover { color: var(--cyan-bright); }

/* ==========================================================================
   Forms
   ========================================================================== */

.form { margin-top: 2rem; }

.field { margin-bottom: 1.4rem; }

.field label {
  display: block;
  font-weight: 600;
  color: var(--text);
  margin-bottom: .4rem;
}

.req { color: var(--amber); }

/* Inputs are darker than the page, not lighter. A pale field on a dark page is the
   single most common way a dark theme ends up with grey text on near white. */
.field input,
.field textarea {
  width: 100%;
  padding: .75rem .9rem;
  font: inherit;
  color: var(--text);
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.field textarea { resize: vertical; min-height: 9rem; }

.field input::placeholder,
.field textarea::placeholder { color: var(--text-dim); }

.field input:hover,
.field textarea:hover { border-color: var(--text-dim); }

.field input:focus,
.field textarea:focus {
  outline: none;                      /* replaced, not removed */
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px rgba(60, 188, 252, .28);
}
/* Keyboard users still get the standard ring on top of the field styling. */
.field input:focus-visible,
.field textarea:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 2px;
}

.hint {
  margin: .45rem 0 0;
  font-size: .87rem;
  color: var(--text-dim);
}
.prose .hint a { color: var(--cyan); }

/* The honeypot. Off screen rather than display:none, because some bots skip
   anything explicitly hidden but will happily fill a field they can still find. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================================
   Alerts
   ========================================================================== */

.alert {
  padding: 1.1rem 1.25rem;
  border-radius: var(--radius);
  border: 1px solid;
  margin-bottom: 1.75rem;
}
.alert p { margin: 0 0 .5rem; }
.alert p:last-child { margin-bottom: 0; }
.alert ul {
  list-style: disc;
  padding-left: 1.3rem;
  margin: .5rem 0 0;
}
.alert i { margin-right: .4rem; }

/* Each state carries an icon as well as a colour, so the meaning survives for
   anyone who cannot separate the two. */
.alert-ok {
  background: #0d1f14;
  border-color: #2f7d4f;
  color: #b6f0cc;
}
.alert-ok i { color: #56d98a; }

.alert-warn {
  background: #241c06;
  border-color: #8a6d16;
  color: #f5e2ab;
}
.alert-warn i { color: var(--amber); }

.alert-error {
  background: #24100d;
  border-color: #9c3226;
  color: #f7c4bc;
}
.alert-error i { color: #ff7c66; }

/* Turnstile draws nothing until it runs, so this only takes space when it has to. */
.cf-turnstile:not(:empty) { margin-bottom: 1.4rem; }

/* ==========================================================================
   Empty state
   ========================================================================== */

.empty-state {
  padding: 3rem 1.5rem;
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text-muted);
}
.empty-state i {
  font-size: 2rem;
  color: var(--text-dim);
  margin-bottom: .75rem;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  margin-top: 3rem;
  border-top: 1px solid var(--line);
  background: var(--surface);
}

.footer-inner {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 2.5rem;
  padding-block: 3rem 2rem;
}

.footer-brand .brand-text {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
}
.footer-brand p {
  margin-top: .6rem;
  color: var(--text-muted);
  font-size: .92rem;
  max-width: 42ch;
}

.footer-nav h2 {
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--text-dim);
  margin-bottom: .9rem;
}
.footer-nav li { margin-bottom: .5rem; }
.footer-nav a { color: var(--text-muted); font-size: .93rem; }
.footer-nav a:hover { color: var(--amber); }

.footer-legal {
  padding-block: 1.25rem;
  border-top: 1px solid var(--line);
}
.footer-legal p {
  margin: 0;
  font-size: .85rem;
  color: var(--text-dim);
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 900px) {
  .footer-inner { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 760px) {
  .nav-toggle { display: inline-flex; }

  /* The nav becomes a panel under the header bar rather than a drawer: fewer
     moving parts, and it never traps focus. */
  .primary-nav {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow-lg);
    padding: .75rem 1.25rem 1rem;
  }
  .primary-nav.is-open { display: block; }
  .primary-nav ul { flex-direction: column; align-items: stretch; gap: .2rem; }
  .primary-nav a { padding: .85rem 1rem; font-size: 1rem; }

  .game-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 1rem; }
  .category-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1rem; }

  .hero-stats { gap: 1.5rem; }
  .hero-actions .btn { flex: 1 1 100%; }
}

@media (max-width: 420px) {
  .game-grid { grid-template-columns: 1fr 1fr; }
  .game-card-body { padding: .7rem .8rem .9rem; }
  .game-card h3 { font-size: .98rem; }
  .game-card p { display: none; }
}

/* ==========================================================================
   Accessibility preferences
   ========================================================================== */

/* Respect the system setting. Nothing on this site depends on motion to be
   understood, so it can all be switched off. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .game-card:hover { transform: none; }
  .game-card:hover .game-card-media img { transform: none; }
  .btn:hover { transform: none; }
}

/* When the user asks for more contrast, drop the mid greys and firm up borders. */
@media (prefers-contrast: more) {
  :root {
    --text-muted: #d4d9e8;
    --text-dim:   #b9c0d4;
    --line:       #4a5270;
  }
  .game-card, .category-tile, .btn { border-width: 2px; }
}

@media print {
  .site-header, .site-footer, .hero-actions, .nav-toggle { display: none; }
  body { background: #fff; color: #000; }
}
