/* ============================================================
   Game Twin, ASCII game-manual stylesheet.
   Monospace only, no external font requests (GDPR-friendly).
   Themeable via :root[data-theme] and :root[data-font].
   ============================================================ */

/* Self-hosted pixel/terminal font (VT323). Downloaded at build time and served
   from this origin, so the page makes no third-party font request. */
@font-face {
  font-family: "GT Pixel";
  src: url("assets/fonts/vt323.woff2") format("woff2");
  font-display: swap;
}

/* --fs scales every px font size on the page. VT323 draws small for its point
   size, so the pixel preset asks for a size bump the other fonts do not need. */
:root { --fs: 1; }
:root[data-font="mono"]    { --font: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", Menlo, Consolas, monospace; }
:root[data-font="courier"] { --font: "Courier New", Courier, monospace; }
:root[data-font="gothic"]  { --font: "MS Gothic", "Osaka-Mono", "IBM Plex Mono", Menlo, monospace; }
:root[data-font="pixel"]   { --font: "GT Pixel", "VT323", ui-monospace, monospace; --fs: 1.28; }

/* --app-icon swaps the logo emblem per theme (used by the header logo, the
   hero mark, and the blurred hero backdrop). */
/* --app-icon swaps the logo emblem per theme; --logo-zoom tunes how tightly the
   header/hero logo crops it (the 4:3 default needs less than the square icons). */
:root[data-theme="twin"]    { --bg:#150e2b; --box:#1d1440; --ink:#ece7fb; --dim:#a99ccf; --accent:#6ee7c4; --line:#3a2d6e; --app-icon:url("assets/app-icon.jpg"); --logo-zoom:122%; }
:root[data-theme="dark"]    { --bg:#1b1b1b; --box:#141414; --ink:#c8c8c8; --dim:#8a8a8a; --accent:#eef2f8; --line:#3a3a3a; --app-icon:url("assets/tier-noire.jpg"); --logo-zoom:142%; }
:root[data-theme="light"]   { --bg:#ece3d0; --box:#f6efe0; --ink:#2b2622; --dim:#6a5f4c; --accent:#111111; --line:#c4b79a; --app-icon:url("assets/tier-adventure.jpg"); --logo-zoom:120%; }
:root[data-theme="console"] { --bg:#020a03; --box:#010700; --ink:#33ff66; --dim:#1f9d43; --accent:#7dff8a; --line:#13401f; --app-icon:url("assets/tier-cyber.jpg"); --logo-zoom:142%; }
:root[data-theme="amber"]   { --bg:#140d02; --box:#0c0800; --ink:#ffb000; --dim:#a06f00; --accent:#ffd27f; --line:#3a2600; --app-icon:url("assets/tier-gold.jpg"); --logo-zoom:142%; }

/* Default theme/font if the pre-paint script did not run (JS off) = Twin. */
:root:not([data-theme]) { --bg:#150e2b; --box:#1d1440; --ink:#ece7fb; --dim:#a99ccf; --accent:#6ee7c4; --line:#3a2d6e; --app-icon:url("assets/app-icon.jpg"); --logo-zoom:122%; }
:root:not([data-font])  { --font: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace; }

* { box-sizing: border-box; margin: 0; padding: 0; }
/* scroll-padding keeps in-page anchor targets clear of the sticky masthead. */
html { scroll-behavior: smooth; scroll-padding-top: 64px; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.5;
  font-size: calc(15px * var(--fs));
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 980px; margin: 0 auto; padding: 0 16px; }
img { max-width: 100%; display: block; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* Responsive ASCII: JS sizes [data-fit] precisely; this is the JS-off fallback.
   overflow hidden so the logo never shows a scrollbar. */
pre[data-fit] {
  font-family: var(--font);
  white-space: pre;
  line-height: 1.1;
  color: var(--accent);
  font-size: clamp(4px, 2.2vw, 15px);
  overflow: hidden;
  margin: 0 auto;
  /* Disable ligatures so glyph pairs like __ and |_ never merge and skew
     the monospace columns of the ASCII art. */
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "calt" 0;
  letter-spacing: 0;
  /* Left-align the art internally; the parent's text-align:center would
     otherwise centre each line independently and stagger the rows. The
     block itself is still centred because it is inline-block in a centred parent. */
  display: inline-block;
  text-align: left;
}

/* ---- Masthead ---- */
.masthead {
  position: sticky; top: 0; z-index: 10;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
/* Single line at every width: brand left, actions right, never wraps. */
.masthead .wrap {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: nowrap; padding-top: 8px; padding-bottom: 8px;
}
.brand { display: inline-flex; align-items: center; gap: 8px; font-weight: bold; color: var(--ink); letter-spacing: 1px; white-space: nowrap; }
.brand .ver { color: var(--dim); }
.brand-logo { width: 32px; height: 32px; border-radius: 7px; display: block; flex: 0 0 auto; background: var(--app-icon) center / auto var(--logo-zoom, 130%) no-repeat; box-shadow: 0 0 0 1px var(--line); }
.actions { display: flex; gap: 8px; align-items: center; margin-left: auto; flex-wrap: nowrap; }

.btn {
  display: inline-block; border: 1px solid var(--line);
  color: var(--ink); background: var(--box);
  padding: 5px 9px; white-space: nowrap; cursor: pointer;
  font-family: var(--font); font-size: calc(14px * var(--fs));
}
.btn:hover { border-color: var(--accent); text-decoration: none; }
/* Download is the loudest (filled), Support the first-class outline beside it. */
.btn-primary { border-color: var(--accent); background: var(--accent); color: var(--bg); }
.btn-primary:hover { text-decoration: none; filter: brightness(1.08); }
.btn-support { border-color: var(--accent); color: var(--accent); }

/* ---- Theme switcher ---- */
.switcher { position: relative; }
.switcher > summary { list-style: none; }
.switcher > summary::-webkit-details-marker { display: none; }
.switcher-panel {
  position: absolute; right: 0; top: calc(100% + 6px);
  background: var(--box); border: 1px solid var(--line);
  padding: 10px; width: max-content; min-width: 180px; max-width: min(260px, 92vw); z-index: 20;
}
.switcher fieldset { border: 1px solid var(--line); padding: 6px 8px; margin-bottom: 8px; }
.switcher legend { color: var(--dim); padding: 0 4px; }
.switcher label { display: block; padding: 2px 0; cursor: pointer; }

/* ---- Sections ---- */
section { padding: 34px 0; border-bottom: 1px solid var(--line); }
h2 { font-size: calc(18px * var(--fs)); margin-bottom: 12px; }
h2::before { content: "== "; color: var(--accent); }
h2::after  { content: " =="; color: var(--accent); }
.box { border: 1px solid var(--line); background: var(--box); padding: 14px; }

/* ---- Footer ---- */
.site-footer { padding: 28px 0; color: var(--dim); font-size: calc(13px * var(--fs)); }
.site-footer a { color: var(--dim); }
.foot-grid { display: flex; gap: 40px; flex-wrap: wrap; margin-bottom: 18px; }
.foot-grid h4 { color: var(--ink); margin-bottom: 6px; }
.foot-grid .col a { display: block; padding: 2px 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

/* Keep the header on one line down to small phones: show just the Game Twin
   logo, collapse Theme and Support to icons, and keep a wide labelled Download. */
@media (max-width: 620px) {
  .masthead .wrap { gap: 8px; }
  .brand-name, .brand .ver { display: none; }
  .actions { gap: 6px; }
  .actions .btn { padding: 5px 7px; }
  .actions .lbl { display: none; }
  .actions .btn-primary { padding: 5px 18px; }
  .actions .btn-primary .lbl { display: inline; }
  /* Pin the settings panel across the viewport so wider fonts never overflow. */
  .switcher-panel { position: fixed; top: 52px; right: 8px; left: 8px; width: auto; min-width: 0; max-width: none; }
}

.hero { text-align: center; position: relative; overflow: hidden; }
/* Blurred app icon behind the wordmark, to carry the app's aesthetic. */
.hero-bg {
  position: absolute; inset: -80px; z-index: 0;
  background: var(--app-icon) center / cover no-repeat;
  filter: blur(64px) saturate(1.35);
  opacity: .32;
}
.hero .wrap { position: relative; z-index: 1; }
.hero-mark {
  width: 160px; height: 160px; border-radius: 30px;
  margin: 6px auto 12px;
  background: var(--app-icon) center / auto var(--logo-zoom, 130%) no-repeat;
  box-shadow: 0 12px 38px rgba(0, 0, 0, .5), 0 0 0 1px var(--line);
}
.hero .logo { color: var(--accent); margin: 4px auto 16px; }
/* The dark presets draw a glowing wordmark on near-black. Light puts the same
   hairline strokes on a pale, busy backdrop, so there they go pure black and
   the backdrop fades back to stay out of their way. */
:root[data-theme="light"] .hero .logo { color: #000; }
:root[data-theme="light"] .hero-bg { opacity: .16; }
.hero .tagline { color: var(--dim); margin-bottom: 16px; }
.hero-blurb { text-align: left; max-width: 760px; margin: 0 auto 18px; }
.hero-blurb p + p { margin-top: 10px; }
.blurb-title { font-size: calc(16px * var(--fs)); margin: 0 0 8px; }
.hero-cta { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.hero-cta .btn { padding: 8px 14px; }
.hero-support { margin-top: 14px; display: flex; gap: 10px; align-items: center; justify-content: center; flex-wrap: wrap; color: var(--dim); }
.hero-support .btn { padding: 8px 14px; }
/* The heart stays red in every theme. */
.heart { color: #ff4d4d; }

.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;
}

/* ---- Features: tab bar + copy panel ---- */
.tabbar { display: flex; flex-wrap: wrap; gap: 4px; margin: 14px 0 18px; justify-content: center; }
.tabbar button {
  font-family: var(--font); font-size: calc(14px * var(--fs)); cursor: pointer;
  background: var(--box); color: var(--dim);
  border: 1px solid var(--line); padding: 5px 9px;
}
.tabbar button:hover { border-color: var(--accent); }
.tabbar button[aria-selected="true"] { color: var(--accent); border-color: var(--accent); }

/* Min-height keeps the tab bar still while switching between a short blurb and
   a long one, instead of the page jumping under the pointer. */
.showcase-copy { min-height: 190px; }
.showcase-copy h3 { font-size: calc(20px * var(--fs)); margin-bottom: 10px; }
.showcase-copy h3::before { content: "> "; color: var(--accent); }
.showcase-copy p { color: var(--ink); max-width: 70ch; }

/* Feature cards: lead paragraph plus ASCII-marked points. */
.feature-points { list-style: none; margin-top: 10px; max-width: 70ch; }
.feature-points li { color: var(--dim); margin-top: 6px; padding-left: 16px; text-indent: -16px; }
.feature-points li::before { content: "+ "; color: var(--accent); }

.feature-item { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.feature-item:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.feature-item h3 { margin-bottom: 8px; }
.feature-item h3::before { content: "> "; color: var(--accent); }
.feature-item p { color: var(--ink); max-width: 760px; }


/* ---- Special editions ---- */
/* Each edition is a self-contained card: its emblem art, price, and a direct
   Buy button. Every edition unlocks the same in-app extras, so they differ only
   by aesthetic; the card just presents each as its own product. */
/* The three cards line up row for row: art with art, name with name, price
   with price. Two things are needed for that.

   minmax(0, 1fr), not 1fr: a plain 1fr track never shrinks below its content's
   min-content width, and .btn is white-space: nowrap, so the longest Buy label
   ("[ Buy Noire-Adventurer Edition ]") widened its own column and squeezed the
   others. Unequal columns shrank one card's tiles and put its body out of step.

   subgrid: each card adopts the grid's five rows instead of packing its own, so
   every row is as tall as the tallest card needs and the other two match it.
   Reserved min-heights were tried first and are not enough, because how many
   lines a name or a description takes depends on the column width and on which
   of the four font presets is active. Subgrid needs no guess about either. */
.edition-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(4, auto);
  column-gap: 16px; row-gap: 0;
  max-width: 840px; margin: 24px auto 0; align-items: stretch;
}
.edition {
  display: grid; grid-row: span 4; grid-template-rows: subgrid;
  text-align: center;
  border: 1px solid var(--line); background: var(--box); padding: 16px 16px 18px;
}
/* One tile size for every card, at every width. The solo card used to size its
   single emblem to 148px against the pairs' 108px, so its art row stood 40px
   taller than theirs. Sizing every tile to half the row (less the gap) and
   capping it at 112px keeps the solo tile in step: a pair has to shrink to fit
   a narrow card, and this makes the lone tile shrink by exactly as much. */
.edition-emblems {
  display: flex; gap: 10px; justify-content: center; align-items: center;
  margin-bottom: 14px;
}
.edition-emblems .tier-thumb { flex: 0 0 auto; width: min(112px, calc((100% - 10px) / 2)); }
.edition-name { font-size: calc(15px * var(--fs)); margin-bottom: 4px; }
/* Gold has nothing to include, so its copy of this row is empty. It still has
   to exist: the three cards share a subgrid, and a card with one row fewer
   pushes its button out of line with the others. */
.edition-incl { color: var(--dim); font-size: calc(12px * var(--fs)); margin-bottom: 10px; min-height: 1em; }
/* The label may wrap here, unlike the nowrap buttons elsewhere, because the
   column no longer widens to fit it. The button stretches to its subgrid row,
   which is as tall as the longest label needs, so all three are the same
   height and the text is centred in each. */
.edition .btn {
  white-space: normal; text-wrap: balance;
  display: flex; align-items: center; justify-content: center;
}

/* What every unlocked logo changes in-app. */
.edition-note { max-width: 560px; margin: 22px auto 0; color: var(--dim); font-size: calc(13px * var(--fs)); text-align: center; }
.edition-note p { margin: 0; }
.edition-perks {
  list-style: none; display: inline-flex; flex-wrap: wrap; gap: 6px 22px;
  justify-content: center; margin: 8px 0;
}
.edition-perks li { color: var(--ink); }
.edition-perks li::before { content: "\2726 "; color: var(--accent); }

.video-wrap { max-width: 720px; margin: 0 auto; }
.video-facade {
  position: relative; border: 1px solid var(--line); background: var(--box);
  cursor: pointer; aspect-ratio: 16 / 9; overflow: hidden;
}
.video-facade img { width: 100%; height: 100%; object-fit: cover; opacity: .82; }
.video-facade:hover img { opacity: .95; }
.video-facade iframe { width: 100%; height: 100%; border: 0; display: block; }
.video-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--font); font-size: calc(18px * var(--fs)); color: var(--accent);
  background: transparent; border: 0; cursor: pointer;
}
.video-play span { border: 1px solid var(--accent); padding: 8px 16px; background: var(--box); }
.video-play:hover span { border-color: var(--ink); color: var(--ink); }

/* Emblem art tiles, zoomed a touch so the artwork fills the rounded frame. */
.tier-thumb {
  display: block; overflow: hidden; aspect-ratio: 1;
  border: 1px solid var(--line); border-radius: 14px;
}
.tier-thumb img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.16); display: block; }

@media (max-width: 620px) {
  /* One column: the cards are stacked, so there is no neighbour to line up
     with and the 14px gap between cards is itself a row gap. Subgrid would
     apply that gap between the rows inside each card instead, so the cards go
     back to being plain flex columns here. */
  .edition-grid {
    grid-template-columns: 1fr; grid-template-rows: none;
    gap: 14px; max-width: 380px;
  }
  .edition { display: flex; flex-direction: column; grid-row: auto; }
  .edition .btn { margin-top: auto; }
}

.privacy ul { list-style: none; display: flex; flex-wrap: wrap; gap: 6px 28px; }
.privacy li::before { content: "[x] "; color: var(--accent); }
@media (max-width: 480px) { .privacy ul { flex-direction: column; } }

/* ============================================================
   Legal pages: Impressum, Datenschutz, and the two app policies.
   These are plain prose with no <section> or .box wrapper to space
   them out, and the global reset zeroes every margin, so without
   their own rhythm they render as one unbroken block with the list
   markers clipped outside the padding-less <ul>.
   ============================================================ */
.legal-page { max-width: 820px; padding-top: 28px; padding-bottom: 44px; }
.legal-page h1 { font-size: calc(24px * var(--fs)); margin: 12px 0 6px; }
.legal-page h2 { font-size: calc(17px * var(--fs)); color: var(--accent); margin: 28px 0 10px; }
.legal-page h3 { font-size: calc(15px * var(--fs)); margin: 22px 0 8px; }
.legal-page p { margin-bottom: 12px; }
.legal-page ul { margin: 0 0 12px; padding-left: 22px; }
.legal-page li { margin-bottom: 4px; }
.legal-page .updated { color: var(--dim); margin-bottom: 22px; }
/* Placeholders had no rule at all, so an unfilled [Angabe] rendered as ordinary
   body text with nothing marking it unfinished. Nothing should ship with one,
   and check-site.mjs now fails the build if anything does, but if one ever
   slips through it should be impossible to miss. */
.legal-page .placeholder { color: #ff4d4d; font-weight: bold; }

.back-link { display: inline-block; color: var(--dim); }
.lang-switch { color: var(--dim); margin: 10px 0 0; }
.lang-switch .lang-current { color: var(--ink); }
