/* CyberNative Games — portal shell.
   Surface: Inked (CyberNative brand kit v1.3.2). Tokens: assets/tokens-inked.css.

   Drawing language, applied exactly: 2.5px Ink outlines, hard offset shadows
   with no blur, flat fills, Signal focus rings, no motion anywhere.

   The .entry / .catalog rules keep the growing title shelf consistent. The
   fixtures under test/fixtures/ are test-only and never enter a release. */

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/Fraunces144ptSoft-SemiBold.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-Medium.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-SemiBold.woff2") format("woff2");
}

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

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

body {
  background: var(--cn-color-canvas);
  color: var(--cn-color-ink);
  font-family: var(--cn-font-body);
  font-size: 1rem;
  line-height: 1.6;
  margin: 0;
}

/* No motion on this surface, including for anchored jumps. */
h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }

a { color: var(--cn-color-link); text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--cn-color-amber);
  outline-offset: 3px;
}

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

.skip {
  background: var(--cn-color-panel);
  border: var(--cn-stroke) solid var(--cn-color-ink);
  color: var(--cn-color-ink);
  font-weight: 600;
  left: var(--cn-space-4);
  padding: var(--cn-space-2) var(--cn-space-4);
  position: absolute;
  text-decoration: none;
  top: -6rem;
  z-index: 2;
}
.skip:focus { top: var(--cn-space-4); }

.wrap {
  margin: 0 auto;
  max-width: 74rem; /* 1184px page max */
  padding-inline: 20px;
}
@media (min-width: 48rem) { .wrap { padding-inline: 32px; } }

/* ---------- Type scale (brand kit § Type → Scale) ---------- */

.display-l {
  font-family: var(--cn-font-display);
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  font-weight: 600;
  line-height: 1;
  margin: 0;
  max-width: 18ch;
  text-wrap: balance;
}
/* The Inked headline setting. Required wherever the headline carries the Ink
   slab: at line-height 1 the slab of one line overlaps the descenders of the
   line above. 1.16 is what the kit specifies and what clears it. */
.headline-inked {
  font-family: var(--cn-font-display);
  font-size: clamp(2.125rem, 4.6vw, 3.375rem);
  font-weight: 600;
  line-height: 1.16;
  margin: 0;
  max-width: 20ch;
  text-wrap: balance;
}
.heading-m { font-family: var(--cn-font-display); font-size: 2rem; font-weight: 600; line-height: 1.1; }
.heading-s { font-family: var(--cn-font-body); font-size: 1.25rem; font-weight: 600; line-height: 1.25; }
.body-l { font-size: 1.25rem; line-height: 1.55; max-width: 60ch; }
.small { font-size: 0.875rem; font-weight: 500; line-height: 1.5; }
.label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.25;
  text-transform: uppercase;
}
.muted { color: var(--cn-color-muted); }

/* The one Ink slab permitted per page. */
.slab {
  background: var(--cn-color-ink);
  border-radius: 0.1em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  color: var(--cn-color-canvas);
  padding: 0.06em 0.22em;
}

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

.site-header {
  border-bottom: var(--cn-stroke) solid var(--cn-color-ink);
}
.site-header > .wrap {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--cn-space-3) var(--cn-space-6);
  justify-content: space-between;
  padding-block: var(--cn-space-4);
}
.brand {
  align-items: center;
  color: var(--cn-color-ink);
  display: flex;
  gap: var(--cn-space-3);
  text-decoration: none;
}
.brand img { height: 28px; width: 28px; }
.brand b { font-weight: 600; letter-spacing: 0; }
.brand span { color: var(--cn-color-muted); font-weight: 400; }

.site-nav { display: flex; flex-wrap: wrap; gap: var(--cn-space-2); list-style: none; margin: 0; padding: 0; }
.pill {
  background: var(--cn-color-panel);
  border: var(--cn-stroke) solid var(--cn-color-ink);
  border-radius: 999px;
  color: var(--cn-color-ink);
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.35rem var(--cn-space-4);
  text-decoration: none;
}
.pill:hover { background: var(--cn-color-leaf); }
.pill[aria-current="page"] { background: var(--cn-color-leaf); }

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

.btn {
  background: var(--cn-color-leaf);              /* Bio: fill only, Ink text on top */
  border: var(--cn-stroke) solid var(--cn-color-ink);
  border-radius: var(--cn-radius-control);
  box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-ink);
  color: var(--cn-color-ink);
  cursor: pointer;
  display: inline-block;
  font: inherit;
  font-weight: 600;
  padding: var(--cn-space-3) var(--cn-space-6);
  text-decoration: none;
}
.btn:hover { background: var(--cn-color-mint); }
.btn--quiet { background: var(--cn-color-panel); }
.btn--quiet:hover { background: var(--cn-color-mint); }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--cn-space-4) var(--cn-space-6); }

/* ---------- Rules and sections ---------- */

.rule { background: var(--cn-color-ink); border: 0; height: var(--cn-stroke); margin: 0; }
.section { padding-block: var(--cn-space-16); }
@media (min-width: 48rem) { .section { padding-block: var(--cn-space-24); } }

.section-head {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: var(--cn-space-2) var(--cn-space-6);
  justify-content: space-between;
  margin-bottom: var(--cn-space-8);
}

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

.hero { padding-block: var(--cn-space-8) var(--cn-space-6); }
@media (min-width: 48rem) { .hero { padding-block: var(--cn-space-16) var(--cn-space-16); } }
.hero .body-l { margin-block: var(--cn-space-4) var(--cn-space-6); }
@media (min-width: 48rem) { .hero .body-l { margin-block: var(--cn-space-6) var(--cn-space-8); } }
.hero-policy { margin-top: var(--cn-space-4); }
.hero-policy a { color: var(--cn-color-muted); font-weight: 600; }

/* Catalog follows the hero, so it does not need a second essay's top pad. */
#catalog { padding-block: var(--cn-space-8) var(--cn-space-16); }
@media (min-width: 48rem) { #catalog { padding-block: var(--cn-space-12) var(--cn-space-24); } }

/* ---------- Catalog ---------- */

/* On a phone the catalog is a shelf of covers, two across: the reading matter
   belongs on the title page, and eleven full cards put the last title eight
   screens down. From 48rem there is room for the description as well, and
   auto-fill — not auto-fit — keeps a single card at one column's width instead
   of stretching it across the row, so one title never reads as a broken hero.
   At every width the card carries only what differs between titles. */
.catalog { display: grid; gap: var(--cn-space-3); grid-template-columns: repeat(2, minmax(0, 1fr)); list-style: none; margin: 0; padding: 0; }
@media (min-width: 48rem) { .catalog { gap: var(--cn-space-6); grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); } }
.catalog:empty { display: none; }

.entry {
  align-content: start;
  background: var(--cn-color-panel);
  border: var(--cn-stroke) solid var(--cn-color-ink);
  border-radius: 0.5rem;
  box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-ink);
  display: grid;
  gap: var(--cn-space-2);
  overflow: hidden;
  padding: var(--cn-space-2);
  position: relative;                           /* anchors the whole-card tap target */
}
@media (min-width: 48rem) {
  .entry {
    border-radius: 0.75rem;                     /* 12px: this card holds a figure */
    gap: var(--cn-space-4);
    padding: var(--cn-space-6);
  }
}
.entry-shot {
  border: var(--cn-stroke) solid var(--cn-color-ink);
  border-radius: 0.5rem;
  overflow: hidden;
}
.entry-shot img { aspect-ratio: 960 / 560; height: auto; object-fit: cover; width: 100%; }

.entry-body { align-content: start; display: grid; gap: var(--cn-space-2); justify-items: start; }
.entry-index { color: var(--cn-color-muted); font-size: 0.5625rem; font-variant-numeric: tabular-nums; letter-spacing: 0.04em; }
.entry-title { font-family: var(--cn-font-display); font-size: 1.125rem; font-weight: 600; line-height: 1.15; }
.entry-title a { color: var(--cn-color-ink); text-decoration: none; }
.entry-title a:hover { text-decoration: underline; text-decoration-color: var(--cn-color-amber); text-decoration-thickness: 3px; }
/* No card carries a Play button at any width: the card itself is the link, the
   way a shelf works on itch.io or Newgrounds. The title anchor carries the
   accessible name, so stretching it over the card adds no second link. */
.entry-title a::after { content: ""; inset: 0; position: absolute; }
/* The affordance for that stretched target is a colour change, never motion:
   the offset shadow goes Leaf and the title underlines (see the rule above). */
.entry:hover,
.entry:focus-within { box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-leaf-strong); }
.entry-line { max-width: 46ch; }
.entry-meta { font-variant-numeric: tabular-nums; margin: 0; }

/* The phone card carries cover, date, title and genre. The description and the
   opens line are a tap away on the title page; eleven full cards put the last
   title eight screens down. */
.entry .entry-line,
.entry .entry-meta { display: none; }

@media (min-width: 48rem) {
  .entry-body { gap: var(--cn-space-4); }
  .entry-index { font-size: 0.75rem; letter-spacing: 0.08em; }
  .entry-title { font-size: 2rem; line-height: 1.1; }
  .entry .entry-line,
  .entry .entry-meta { display: block; }
}

.chips { display: flex; flex-wrap: wrap; gap: var(--cn-space-2); list-style: none; margin: 0; padding: 0; }
.chip {
  background: var(--cn-color-mint);             /* Wash fill, Ink text: 14.76:1 */
  border: var(--cn-stroke-small) solid var(--cn-color-ink);
  border-radius: var(--cn-radius-control);
  color: var(--cn-color-ink);
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.25;
  padding: 0.25rem 0.5rem;
  text-transform: uppercase;
}
.chip--quiet { background: var(--cn-color-panel); }

/* ---------- What gets published here ---------- */

.standard { display: grid; gap: var(--cn-space-6); list-style: none; margin: 0; padding: 0; }
@media (min-width: 52rem) { .standard { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.std-card {
  align-content: start;
  background: var(--cn-color-panel);
  border: var(--cn-stroke) solid var(--cn-color-ink);
  border-radius: var(--cn-radius-control);
  box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-ink);
  display: grid;
  gap: var(--cn-space-3);
  padding: var(--cn-space-6);
}
/* The three read as one row, so the offset alternates rather than repeating. */
.std-card:nth-child(2) { box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-leaf-strong); }
.std-card:nth-child(3) { box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-amber); }

/* ---------- Catalog empty state ---------- */

/* This is the shipped state of the catalog, so it carries the weight a card
   row would. Wash rather than Panel keeps it from reading as a missing card. */
.empty {
  align-content: start;
  background: var(--cn-color-panel);
  border: var(--cn-stroke) solid var(--cn-color-ink);
  border-radius: var(--cn-radius-control);
  box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-ink);
  display: grid;
  gap: var(--cn-space-4);
  padding: var(--cn-space-8) var(--cn-space-6);
}
@media (min-width: 48rem) { .empty { padding: var(--cn-space-12); } }
.empty p { max-width: 58ch; }
.empty-line {
  font-family: var(--cn-font-display);
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  font-weight: 600;
  line-height: 1.1;
}

/* ---------- Creators callout ---------- */

.callout {
  align-content: start;
  background: var(--cn-color-mint);             /* Wash, Ink text: 14.76:1 */
  border: var(--cn-stroke) solid var(--cn-color-ink);
  border-radius: var(--cn-radius-control);
  box-shadow: var(--cn-offset) var(--cn-offset) 0 var(--cn-color-leaf-strong);
  display: grid;
  gap: var(--cn-space-4);
  padding: var(--cn-space-6);
}
@media (min-width: 48rem) { .callout { padding: var(--cn-space-8); } }
.callout p { max-width: 62ch; }
.status {
  font-weight: 600;
}

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

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

.two-col { align-items: start; display: grid; gap: var(--cn-space-12); }
@media (min-width: 56rem) { .two-col { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--cn-space-16); } }

.prose { align-content: start; display: grid; gap: var(--cn-space-4); max-width: 62ch; }
.prose code, .std-card code, .callout code, .spec code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.92em;
}

.spec { display: grid; gap: var(--cn-space-3); margin: 0; padding-left: 1.25rem; }
.spec li { max-width: 62ch; }

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

.site-footer { border-top: var(--cn-stroke) solid var(--cn-color-ink); }
.site-footer > .wrap {
  display: grid;
  gap: var(--cn-space-4);
  padding-block: var(--cn-space-8);
}
@media (min-width: 48rem) {
  .site-footer > .wrap { align-items: baseline; grid-template-columns: minmax(0, 1fr) auto; }
}
.site-footer p { max-width: 60ch; }
.footer-links { display: flex; flex-wrap: wrap; gap: var(--cn-space-6); list-style: none; margin: 0; padding: 0; }

/* Fixture-only: stands in for a cover image so the layout can be judged with no
   product art. Never rendered on the served site — no shipped card uses it. */
.entry-placeholder { aspect-ratio: 960 / 560; background: var(--cn-color-mint); width: 100%; }
