/* Allfather's Mods - the one stylesheet all four pages share.

   It used to live inside the landing page, which was right while there was one
   page. With four it would be four copies to keep in step, and the browser can
   cache this once for the whole site. */

  /* Valheim's own text face, self-hosted rather than pulled from Google: a font
     request carries the visitor's address to whoever serves it, and the privacy
     page promises that nothing here does that.

     Averia Serif Libre by Dan Sayers, SIL Open Font License 1.1 - the licence
     travels with the files, in /fonts/OFL.txt. */
  @font-face {
    font-family: "Averia Serif Libre";
    src: url("/fonts/averia-serif-libre-regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
  }
  @font-face {
    font-family: "Averia Serif Libre";
    src: url("/fonts/averia-serif-libre-bold.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
  }
  @font-face {
    font-family: "Averia Serif Libre";
    src: url("/fonts/averia-serif-libre-italic.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
  }

  /* Valheim writes its window headers in Norse, and so do we.

     Served as the original .otf rather than converted to woff2: the licence
     forbids modifying the files, and a format conversion is a modification.
     Twelve kilobytes more than a woff2 - a fair price for not having to argue
     the point. Norse by Joel Carrouche, his free font licence, which travels
     with the files in /fonts/norse-license.txt. */
  @font-face {
    font-family: "Norse";
    src: url("/fonts/Norse.otf") format("opentype");
    font-weight: 400;
    font-display: swap;
  }
  @font-face {
    font-family: "Norse";
    src: url("/fonts/Norsebold.otf") format("opentype");
    font-weight: 700;
    font-display: swap;
  }

  /* Colours straight out of the logo: the same warm gold the mod already puts
     above a creature's head, on the dark blue-grey of a Valheim night. */
  :root {
    --gold: #ffcb52;
    --gold-soft: #d8ab48;
    --ink: #f1eadd;
    --muted: #b1a695;
    --bg: #0e0d0b;
    --panel: #16140f;
    --edge: rgba(255, 203, 82, 0.16);
    --edge-strong: rgba(255, 203, 82, 0.45);
  }

  * { box-sizing: border-box; }

  /* The base colour lives on <html>, not on <body>: a background set on body is
     propagated to the canvas and would paint straight over the scene below. */
  html {
    scroll-behavior: smooth;
    background: var(--bg);
  }

  body {
    margin: 0;
    background: transparent;
    color: var(--ink);
    font-family: "Averia Serif Libre", "Trebuchet MS", "Segoe UI", system-ui, serif;
    line-height: 1.65;
    font-size: 17px;

    /* Makes body the stacking context the two backdrop layers sit behind. */
    position: relative;
    z-index: 0;
  }

  /* ------------------------------------------------------------- the backdrop

     Two layers, and the difference between them is the whole point:

     .scene is fixed, so the fjord stays put while the page scrolls over it -
     and because it is sized to the viewport, an ultra-wide monitor gets the
     raven on the left and the hall on the right, which a 16:9 screen crops
     away. That is what the wide file is for.

     .veil scrolls with the document: clear over the hero, then settling at a
     single value and holding it to the bottom, so the fjord stands behind the
     whole page rather than sinking away under the first section. It scrolls
     rather than sits fixed because a fixed veil would leave its bright end at
     the top of the screen at every scroll position, directly under whatever
     paragraph happened to be there.

     0.36 is the most light the text can be given and still be read over the
     sunset, which is the brightest thing in the picture and passes behind the
     middle of the page as you scroll. */

  .scene {
    position: fixed;
    inset: 0;
    z-index: -2;
    background: url("/bg/fjord.webp") center center / cover no-repeat;
  }

  .veil {
    position: absolute;
    inset: 0;
    z-index: -1;
    /* The last stop carries on to the bottom of the page, however long it is. */
    background: linear-gradient(
      to bottom,
      rgba(14, 13, 11, 0.10) 0,
      rgba(14, 13, 11, 0.20) 42vh,
      rgba(14, 13, 11, 0.24) 78vh);
  }

  /* ----------------------------------------------------------------- the sheet

     The text needs ground of its own. Over the fjord alone the grey of the
     section intros disappears wherever the sunset passes behind it, and that
     is the brightest part of the picture and the part that moves through the
     middle of the page as you scroll.

     So: one column of warm dark, grained like vellum, running the length of
     the page - not a box per section, which would cut the picture into bands.
     It fades in over the hero rather than starting with an edge, so the logo
     keeps the open sky behind it and the page never shows a seam.

     The background sits on a pseudo-element rather than on .sheet itself
     because of the fade: a mask on .sheet would fade the text with it. */

  .sheet { position: relative; }

  .sheet::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: min(1040px, 100%);
    transform: translateX(-50%);
    z-index: -1;
    box-sizing: border-box;
    border-left: 1px solid rgba(255, 203, 82, 0.09);
    border-right: 1px solid rgba(255, 203, 82, 0.09);
    background:
      /* The grain, and under it the two things that keep a flat fill from
         looking like a flat fill: darker along both edges, as if the sheet
         curved away, over the warm dark itself. */
      url("/bg/grain.png") repeat,
      linear-gradient(to right,
        rgba(0, 0, 0, 0.32) 0,
        transparent 6%,
        transparent 94%,
        rgba(0, 0, 0, 0.32) 100%),
      linear-gradient(rgba(17, 14, 10, 0.90), rgba(17, 14, 10, 0.90));
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 24vh, #000 76vh);
    mask-image: linear-gradient(to bottom, transparent 0, transparent 24vh, #000 76vh);
  }

  /* A window taller than it is wide cannot show a 2.5:1 picture - cover would
     leave a slice about a fifth of it wide, with neither the raven nor the
     hall in it. The crop is the one column that still composes on end: rune
     stone, raven, banner, fire. */
  @media (max-aspect-ratio: 1/1) {
    .scene { background-image: url("/bg/fjord-portrait.webp"); }
  }

  /* Small landscape windows: half the pixels, 71 KB instead of 268. */
  @media (min-aspect-ratio: 1/1) and (max-width: 1000px) {
    .scene { background-image: url("/bg/fjord-1600.webp"); }
  }

  /* One language at a time. Elements keep their natural display when shown,
     which a [hidden]-style toggle on inline spans would not. */
  html[lang="de"] .en, html[lang="en"] .de { display: none !important; }

  a { color: var(--gold); }

  .wrap { max-width: 880px; margin: 0 auto; padding: 0 20px; }

  /* ---------------------------------------------------------- language switch */

  .langs {
    position: fixed;
    top: 14px;
    right: 14px;
    z-index: 10;
    display: flex;
    gap: 4px;
    padding: 4px;
    border: 1px solid var(--edge);
    border-radius: 999px;
    background: rgba(14, 13, 11, 0.85);
    backdrop-filter: blur(6px);
  }

  .langs button {
    padding: 5px 12px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
  }

  .langs button[aria-pressed="true"] { background: var(--gold); color: #17140d; }

  /* ------------------------------------------------------------------- hero */

  header {
    position: relative;
    padding: 72px 0 56px;
    text-align: center;
    overflow: hidden;

    /* Cover puts the sunset dead centre, which is exactly where the logo and
       the headline go. This pool of dark gives them something to stand on
       without hiding the fjord to either side. A background rather than a
       layer, so it stays behind the text by construction. */
    background: radial-gradient(
      ellipse 72% 78% at 50% 42%,
      rgba(14, 13, 11, 0.58) 0%,
      rgba(14, 13, 11, 0.28) 52%,
      transparent 78%);
  }

  /* A glow behind the logo instead of a background image: it is the same light
     the raven's eye gives off, and it costs nothing to load. */
  header::before {
    content: "";
    position: absolute;
    top: -180px;
    left: 50%;
    width: 760px;
    height: 620px;
    transform: translateX(-50%);
    background: radial-gradient(circle, rgba(255, 203, 82, 0.13) 0%, transparent 62%);
    pointer-events: none;
  }

  header img {
    position: relative;
    width: min(320px, 72vw);
    height: auto;
    filter: drop-shadow(0 8px 40px rgba(0, 0, 0, 0.7));
  }

  h1 {
    margin: 22px 0 6px;
    font-family: "Norse", "Averia Serif Libre", serif;
    font-weight: 700;
    font-size: clamp(34px, 6.8vw, 54px);
    letter-spacing: 0.03em;
    color: var(--gold);
    text-shadow: 0 2px 20px rgba(255, 203, 82, 0.2);
  }

  .tagline {
    margin: 0 auto 30px;
    max-width: 30em;
    /* Lifted off --muted: the faintest text on the page now has a lit sky
       behind it rather than flat dark. */
    color: #b6ab9a;
    font-size: clamp(18px, 2.8vw, 23px);
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.85);
  }

  /* The hook is one line; this is what the mod actually does. Narrower and
     quieter, so the eye reads the first line first and this one only if it
     was interested. */
  .tagline.more {
    max-width: 34em;
    margin-bottom: 30px;
    color: #9d9384;
    font-size: clamp(15px, 2.1vw, 17px);
  }

  .tagline + .tagline { margin-top: -18px; }

  .actions { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

  .btn {
    display: inline-block;
    padding: 12px 24px;
    border: 1px solid var(--gold);
    border-radius: 8px;
    background: var(--gold);
    color: #17140d;
    font-weight: 700;
    text-decoration: none;
  }

  .btn:hover { background: #ffd775; }

  .btn.ghost { background: transparent; color: var(--gold); border-color: var(--edge-strong); }
  .btn.ghost:hover { background: rgba(255, 203, 82, 0.1); }

  /* --------------------------------------------------------------- sections */

  section { padding: 56px 0; }

  h2 {
    margin: 0 0 10px;
    font-family: "Norse", "Averia Serif Libre", serif;
    font-weight: 700;
    /* A touch larger than the old sans at the same setting: Norse is narrow and
       light, and matched pixel for pixel it reads as a smaller heading. */
    font-size: clamp(25px, 4.1vw, 34px);
    letter-spacing: 0.02em;
    color: var(--gold);
  }

  /* Not "h2 + .lead": each lead exists twice, once per language, and the
     adjacent sibling is only ever the first of the pair - so in English the
     rule landed on the hidden German one and the visible text went unstyled. */
  .lead { margin: 0 0 28px; color: var(--muted); max-width: 46em; }

  h3 { margin: 0 0 6px; font-size: 18px; }

  .cards { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

  .card {
    padding: 20px;
    border: 1px solid rgba(255, 255, 255, 0.07);
    border-radius: 10px;
    background: rgba(255, 243, 222, 0.045);
  }

  .card p { margin: 0; color: var(--muted); font-size: 15px; }

  .quote {
    margin: 22px 0 0;
    padding: 14px 18px;
    border-left: 3px solid var(--gold);
    background: rgba(255, 203, 82, 0.05);
    font-style: italic;
    color: var(--ink);
  }

  /* ---------------------------------------------------------------- commands */

  table { width: 100%; border-collapse: collapse; font-size: 15px; }
  th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid rgba(255, 255, 255, 0.07); }
  th { color: var(--muted); font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em; }
  td code { color: var(--gold); font-size: 15px; }

  /* A heading inside a table, for the shop's three categories and the console's
     groups. */
  tr.group td {
    padding-top: 24px;
    color: var(--gold);
    font-weight: 700;
    border-bottom-color: rgba(255, 203, 82, 0.25);
  }

  tr.group:first-child td { padding-top: 10px; }

  td.num, th.num { text-align: right; white-space: nowrap; }

  /* The shop is thirty-two rows. Folded away by default so the page stays a
     page, and open for anybody who came looking for exactly this. */
  details.fold {
    margin: 22px 0 0;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.02);
  }

  details.fold > summary {
    padding: 14px 18px;
    color: var(--gold);
    cursor: pointer;
    font-weight: 600;
    list-style: none;
  }

  details.fold > summary::-webkit-details-marker { display: none; }

  details.fold > summary::before {
    content: "+ ";
    font-family: "Cascadia Mono", Consolas, monospace;
  }

  details.fold[open] > summary::before { content: "\2212 "; }

  details.fold > .body { padding: 0 18px 18px; }

  h3.cmd {
    margin: 40px 0 6px;
    color: var(--ink);
    font-size: 19px;
  }

  p.cmdnote { margin: 0 0 16px; color: var(--muted); font-size: 15px; }

  code {
    padding: 2px 7px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.07);
    font-family: "Cascadia Mono", Consolas, monospace;
    font-size: 14px;
  }

  /* ------------------------------------------------------------------- steps */

  ol.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }

  ol.steps li {
    position: relative;
    margin-bottom: 20px;
    padding-left: 48px;
    counter-increment: step;
  }

  ol.steps li::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: -1px;
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 1px solid var(--edge-strong);
    border-radius: 50%;
    color: var(--gold);
    font-weight: 700;
    font-size: 15px;
  }

  ol.steps p { margin: 4px 0 0; color: var(--muted); font-size: 15px; }

  /* ----------------------------------------------------------- screenshots */

  figure.shot { margin: 28px 0 0; }

  figure.shot img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    /* The screenshots are of a night in the Mountains: on the dark page they
       would otherwise bleed into the background at the edges. */
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
  }

  figure.shot figcaption {
    margin-top: 10px;
    color: var(--muted);
    font-size: 14px;
    text-align: center;
  }

  /* Two shots that tell one story: he calls out, you walk over and ask. */
  .shots {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    margin-top: 28px;
  }

  .shots figure.shot { margin: 0; }

  .note {
    margin-top: 28px;
    padding: 16px 18px;
    border: 1px solid var(--edge);
    border-radius: 10px;
    background: rgba(255, 203, 82, 0.04);
    font-size: 15px;
  }

  footer {
    padding: 40px 0 56px;
    color: var(--muted);
    font-size: 14px;
    text-align: center;
  }

  footer a { margin: 0 10px; }

  /* ------------------------------------------------------------------ phones */

  @media (max-width: 600px) {
    body { font-size: 16px; }
    .shots { grid-template-columns: 1fr; }

    /* A phone screen is one hero tall, so the veil has to arrive sooner. */
    .veil {
      background: linear-gradient(
        to bottom,
        rgba(14, 13, 11, 0.16) 0,
        rgba(14, 13, 11, 0.38) 55vh);
    }

    header { background: none; }

    .wrap { padding: 0 16px; }
    header { padding: 52px 0 40px; }
    section { padding: 40px 0; }

    .langs { top: 10px; right: 10px; }
    .langs button { padding: 4px 11px; font-size: 12px; }

    /* Full width beats two buttons squeezed side by side, and a thumb finds
       them without aiming. */
    .actions { flex-direction: column; }
    .btn { width: 100%; text-align: center; padding: 14px 20px; }

    /* A two-column table at 360px is two columns of nothing. Each row becomes
       its own little block: command first, then what it does. */
    table, tbody, tr, td { display: block; width: 100%; }
    thead { display: none; }

    tr {
      padding: 12px 0;
      border-bottom: 1px solid rgba(255, 255, 255, 0.07);
    }

    td { padding: 0; border: 0; }
    td:first-child { margin-bottom: 3px; }

    ol.steps li { padding-left: 42px; }
    ol.steps li::before { width: 28px; height: 28px; font-size: 14px; }

    .quote { margin-left: 0; margin-right: 0; }
  }

  /* Somebody reading in bright sunlight on a phone should not get animation
     they did not ask for either. */
  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
  }

/* ======================================================= the hub and its tiles

   Only the front page and the three mod pages use what follows. It is the
   price of one stylesheet for the whole site, and a cheap one: the browser
   fetches this once and every page after that is html alone. */

/* The way back from a mod page to the other two. It sits opposite the language
   switch, which is fixed in the other corner. */
.backlink {
  position: fixed;
  top: 14px;
  left: 14px;
  z-index: 10;
  padding: 5px 14px;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: rgba(14, 13, 11, 0.85);
  backdrop-filter: blur(6px);
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}

.backlink:hover { color: var(--gold); border-color: var(--edge-strong); }

/* The logo carries the wordmark already, so the h1 is the picture rather than
   a heading set above one more copy of the same three syllables. The alt text
   is what a screen reader reads as the heading. */
h1.sitelogo { margin: 0 0 18px; }

h1.sitelogo img {
  width: min(560px, 86vw);
  height: auto;
  filter: drop-shadow(0 8px 44px rgba(0, 0, 0, 0.75));
}

/* Three tiles. auto-fit rather than a fixed three, so the row becomes two and
   then one without a breakpoint for each step. */
.mods {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin: 8px 0 0;
}

/* The whole tile is the link, not the name inside it: a target the size of a
   card is one nobody has to aim at. */
a.mod {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 26px 22px 22px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  background: rgba(255, 243, 222, 0.045);
  color: inherit;
  text-align: center;
  text-decoration: none;
  transition: border-color 120ms, background-color 120ms, transform 120ms;
}

a.mod:hover {
  border-color: var(--edge-strong);
  background: rgba(255, 203, 82, 0.07);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  a.mod { transition: none; }
  a.mod:hover { transform: none; }
}

a.mod img {
  width: 128px;
  height: 128px;
  border-radius: 14px;
  filter: drop-shadow(0 6px 22px rgba(0, 0, 0, 0.55));
}

a.mod h2 {
  margin: 0;
  font-size: clamp(22px, 3.4vw, 27px);
}

a.mod p {
  margin: 0;
  color: var(--muted);
  font-size: 15px;
}

/* Reads as a link without being a second one inside the first. */
a.mod .more {
  margin-top: auto;
  padding-top: 6px;
  color: var(--gold);
  font-size: 14px;
  font-weight: 700;
}

/* The icon again at the top of a mod's own page, where the hero would
   otherwise open with the site logo and say nothing about which mod this is. */
header img.modicon {
  width: min(168px, 40vw);
  border-radius: 18px;
}

/* Four cards on a grid that fits three leave one of them standing by itself on
   a second row. Four wants two by two. Only the front page needs this, so it is
   a modifier rather than a change to .cards, where it would reshape the twos
   and threes on the mod pages. */
.cards.two { grid-template-columns: repeat(2, 1fr); }

@media (max-width: 600px) {
  .cards.two { grid-template-columns: 1fr; }
}
