/* =====================================================================
   Anthemon Fellowship — PAGINE LIBRO — dasos.php, mosses.php
   ---------------------------------------------------------------------
   Mobile-first: le regole base valgono per gli schermi piccoli, i blocchi
   @media (min-width: …) aggiungono quelle per i grandi.

   Contenuto:
     10b. Fasce, blocchi di download e form delle pagine interne
    10c. Pagine libro: hero, il mondo, citazioni, sfoglia-pagine, galleria,
         carosello, pannello vendita, copertine

   L'ORDINE DEI FILE CONTA. Questo foglio era uno solo e la cascata ne
   dipende: piu' di una regola vince per posizione, non per specificita'.
   I file vanno caricati nell'ordine del numero in testa al nome, ed e'
   quello che fa includes/header.php. Vedi css/README.md prima di
   aggiungerne, rinominarne o riordinarne uno.
   ===================================================================== */
/* ---------- 10b. INNER PAGES: BANDS, DOWNLOAD BLOCKS & FORMS ---------- */
/* Background utilities for alternating light sections on inner pages */
.bg-ivory { background: var(--ivory); }
.bg-warm  { background: var(--warm-white); }

/* Compact page hero band (free-material, grazie, contact):
   light, centered, roughly 45vh, sitting under the fixed navbar */
.page-band {
  background: var(--ivory);
  min-height: 45vh;
  display: flex;
  align-items: center;
  text-align: center;
  padding: calc(var(--header-h) + 3.5rem) 0 3.5rem;
}
.page-band .container { width: min(880px, 92%); }
.page-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.25rem, 5vw, 3rem);
  letter-spacing: 0.08em;
  line-height: 1.2;
  margin: 0 0 0.75rem;
}
.page-line {
  font-style: italic;
  font-size: 1.1875rem;
  opacity: 0.85;
  margin: 0;
}

/* Download blocks (free-material): reuse the magnet grid inside these */
.dl-section { padding-block: var(--section-pad); }

/* --- Subscribe form (posts to subscribe.php → MailerLite) --- */
.subscribe-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  max-width: 26rem;
  margin: 0.5rem auto 0; /* centered on mobile… */
  text-align: left;
}
@media (min-width: 900px) {
  .magnet-body .subscribe-form { margin-inline: 0; } /* …left-aligned on desktop */
}

.form-row { display: flex; flex-direction: column; gap: 0.4rem; }
.form-row label {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--bronze);
}
.form-row input,
.newsletter-field input {
  font-family: var(--font-ui);
  font-size: 1rem;
  color: var(--ink);
  background: var(--warm-white);
  border: 1px solid rgba(184, 152, 104, 0.55);
  border-radius: var(--radius-soft);
  padding: 0.8em 1em;
}
.form-row input:focus-visible,
.newsletter-field input:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Consent checkbox: box and text aligned on the first line */
.form-consent {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  cursor: pointer;
}
.form-consent input {
  width: 1rem;
  height: 1rem;
  margin-top: 0.25em;
  flex-shrink: 0;
  accent-color: var(--gold); /* gold check on supporting browsers, harmless elsewhere */
}

.subscribe-form .btn { align-self: flex-start; }

/* Honest-exchange microcopy under the submit button */
.form-microcopy {
  font-style: italic;
  font-size: 0.9375rem;
  opacity: 0.75;
  margin: 0;
}

/* Kind inline error (shown when subscribe.php redirects back with ?err=1) */
.form-error {
  max-width: 26rem;
  margin: 0 auto 1.25rem;
  font-family: var(--font-ui);
  font-size: 0.9375rem;
  color: var(--mosses-wine);
  background: rgba(142, 77, 102, 0.08);
  border: 1px solid rgba(142, 77, 102, 0.45);
  border-radius: var(--radius-soft);
  padding: 0.8em 1.1em;
}
@media (min-width: 900px) {
  .magnet-body .form-error { margin-inline: 0; }
}

/* Honeypot: parked far off-screen. Humans never see or reach it
   (tabindex -1), bots fill it and subscribe.php discards them. */
.hp-field { position: absolute; left: -9999px; }

/* --- 10c. NEWSLETTER BAND (homepage, between Community and the footer) ---
   Deliberately slim: it is a quiet last offer, not a second lead magnet.
   Warm white keeps the alternation going (ivory Community → this → dark
   footer) without repeating the same light. */
.newsletter {
  background: var(--warm-white);
  padding-block: clamp(3rem, 6vw, 4.5rem);
  text-align: center;
}
.newsletter .eyebrow { margin-bottom: 0.6rem; }
.newsletter-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.25rem, 2.4vw, 1.65rem);
  letter-spacing: 0.06em;
  margin: 0 0 0.6rem;
}
.newsletter-line {
  max-width: 46ch;
  margin: 0 auto 1.75rem;
  font-size: 1rem;
  opacity: 0.85;
}
.newsletter-form {
  max-width: 34rem;
  margin-inline: auto;
}
/* Email + button on one line; the input takes the slack. Below ~26rem the
   flex-basis stops fitting and the button wraps to its own full-width row. */
.newsletter-field {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.newsletter-field input {
  flex: 1 1 14rem;
  min-width: 0;    /* lets the input actually shrink inside the flex row */
}
.newsletter-field .btn {
  flex: 0 0 auto;
  padding-inline: 1.6em;
}
@media (max-width: 460px) {
  .newsletter-field .btn { flex: 1 1 100%; text-align: center; }
}
/* Consent sits under the row, left-aligned against the input above it */
.newsletter-consent {
  margin-top: 1rem;
  text-align: left;
  font-size: 0.875rem;
  opacity: 0.8;
}

/* --- Coming-soon shelf (free-material) --- */
.coming-soon {
  padding-block: var(--section-pad);
  text-align: center;
}
.shelf-card {
  max-width: 34rem;
  margin: 2rem auto 0;
  background: var(--ivory);
  border: 1px solid rgba(184, 152, 104, 0.4);
  border-radius: var(--radius-card);
  padding: 2rem 2.25rem;
}
.shelf-card h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.125rem;
  letter-spacing: 0.08em;
  margin: 0 0 0.4rem;
}
.shelf-card p { margin: 0; opacity: 0.75; }

/* --- Thank-you page (grazie.php) --- */
.thanks { min-height: 72vh; }
.thanks .logo-mark {
  width: 44px;
  height: 28px;
  margin: 0 auto 1.5rem;
  color: var(--gold);
}
.thanks-text {
  max-width: 58ch;
  margin: 0 auto 2.25rem;
}
/* Smaller than the 320px the lead-magnet blocks use: here the cover is a
   token above the download button, not the thing being sold. */
.cover-ph--sm { max-width: 190px; }
.thanks .cover-ph { margin-bottom: 2rem; }
.thanks .ornament { margin-block: 2.75rem; }
.thanks-secondary { margin: 0 0 1.5rem; font-style: italic; opacity: 0.85; }
.thanks-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 1.5rem;
}

/* ---------- 10c. BOOK PAGES (dasos.php, mosses.php) ---------- */

/* Solid gold button — the strongest CTA (book hero, get-it row) */
.btn-gold-solid {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--ink);
}
.btn-gold-solid:hover {
  background: #c9ab7c; /* a touch brighter on hover */
  border-color: #c9ab7c;
  color: var(--ink);
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(184, 152, 104, 0.35);
}

/* Left-aligned ornament variant (book hero lockups) */
.ornament--start { margin-inline: 0; }

/* --- Book hero: full-bleed artwork, ~70vh, world scrim, text left --- */
.book-hero {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  color: var(--warm-white);
  min-height: 70vh;  /* fallback for browsers without svh units */
  min-height: 70svh;
  padding: calc(var(--header-h) + 3rem) 0 4rem;
  background-size: cover;
  background-position: center;
}
/* Same scrim pattern as the place sections: world color from the left */
.book-hero::before {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background: linear-gradient(90deg,
    rgba(var(--place-rgb), 0.9) 0%,
    rgba(var(--place-rgb), 0.55) 45%,
    rgba(var(--place-rgb), 0.15) 80%);
}
.book-hero .container { position: relative; z-index: 1; }
.book-hero-content { max-width: 38rem; }

/* Per-book artwork + palette. */
.bh-dasos {
  /* Deeper and bluer than the section's forest green. The druid artwork is
     a bright misty green almost edge to edge, and the world colour laid
     over it read as a wash of the same hue: no separation, and the white
     title sat in it rather than on it. Pulling the veil toward the blue end
     and darkening it puts the type back in front. */
  --place-rgb: 12, 30, 34;
  background-image:
    url("../assets/img/book-hero-dasos.webp"),
    radial-gradient(ellipse at 75% 25%, rgba(178, 202, 107, 0.25), transparent 60%),
    linear-gradient(150deg, #10231a, var(--dasos) 55%, var(--dasos-teal));
}
.bh-dasos .eyebrow { color: var(--dasos-lime); }
.bh-mosses {
  --place-rgb: 49, 57, 110;
  background-image:
    url("../assets/img/book-hero-mosses.webp"),
    radial-gradient(ellipse at 75% 25%, rgba(144, 88, 209, 0.3), transparent 60%),
    linear-gradient(150deg, #1d2347, var(--mosses) 55%, var(--mosses-purple));
  /* The artwork is 2.5:1 with the figure hard right, so a portrait window
     centred on it would show nothing but the empty field. Anchored right of
     centre on phones; from 700px up the frame is wide enough for center. */
  background-position: 74% center;
}
@media (min-width: 700px) {
  .bh-mosses { background-position: center; }
}
/* The veil.
   The left two thirds of this painting are already a flat field of the
   world's own indigo — sampled off the file it is rgb(47, 54, 106), which is
   --mosses to within a couple of points, so the default hero scrim laid the
   same colour over itself and did nothing but flatten the smoke on the right.
   What the type needs here is not contrast (white on that field is already
   about 11:1) but a floor: a darker, slightly bluer wash that sinks the left
   edge and lets the title sit on top of it. It is fully gone by 70%, before
   the smoke starts, so the colours of the artwork are never touched. */
.bh-mosses::before {
  background: linear-gradient(90deg,
    rgba(16, 19, 48, 0.72) 0%,
    rgba(16, 19, 48, 0.52) 32%,
    rgba(16, 19, 48, 0.22) 54%,
    rgba(16, 19, 48, 0) 70%);
}
/* On a phone the copy runs the full width and would cross into the smoke,
   so the veil turns vertical there — the same move the place sections make. */
@media (max-width: 699px) {
  .bh-mosses::before {
    background: linear-gradient(180deg,
      rgba(16, 19, 48, 0.55), rgba(16, 19, 48, 0.86));
  }
}
.bh-mosses .eyebrow { color: var(--mosses-azure); }

.book-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 5.5vw, 3.25rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.15;
  margin: 0;
}
/* A louder book title, for a page whose hero carries no ornament under it
   (mosses.php): the type has to hold the space on its own. */
.book-title--xl {
  font-size: clamp(2.6rem, 8vw, 4.75rem);
  line-height: 1.05;
}
.book-hero .ornament--start { margin-block: 1.25rem 1.5rem; }
.book-pitch {
  font-size: clamp(1.125rem, 2vw, 1.3125rem);
  max-width: 34rem;
  margin: 0 0 2.25rem;
  opacity: 0.94;
}
/* With no ornament between them, the title and the pitch need their own air */
.book-title--xl + .book-pitch { margin-top: 1.5rem; }

/* --- The world: lore paragraphs + rounded side image --- */
.lore { padding-block: var(--section-pad); }
/* Dasos' "Il mondo" runs a little shallower than the site default: the
   cover is tall and the section was left with more air than it needed. */
.lore--books { padding-block: calc(var(--section-pad) - 1.5rem); }
.lore-grid { display: grid; gap: 2.5rem; align-items: center; }
.lore-text p { margin: 0 0 1.25rem; }
/* The closing one-liner of the lore ("The tales begin here.") */
.lore-kicker {
  font-style: italic;
  font-size: 1.25rem;
  color: var(--bronze);
}

/* --- Pull quote: someone speaking, inside a light section ---
   A gold rule down the left rather than a boxed card: the site has enough
   bordered rectangles, and a rule reads as "voice" more than a panel does. */
.pull-quote {
  margin: 2rem 0 0;
  padding: 0.25rem 0 0.25rem 1.5rem;
  border-left: 3px solid var(--gold);
}
.pull-quote p {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1.125rem;
  line-height: 1.7;
  margin: 0;
}
/* Curly quotes drawn in, so they never have to be typed into the copy */
.pull-quote p::before { content: "\201C"; }
.pull-quote p::after  { content: "\201D"; }
.pull-quote-cite {
  display: block;
  margin-top: 0.9rem;
  font-family: var(--font-ui);
  font-style: normal;
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--bronze);
}
.pull-quote-cite::before { content: "\2014\00A0"; }
.side-art {
  aspect-ratio: 4 / 5;
  max-width: 420px;
  margin-inline: auto;
  border-radius: var(--radius-card);
  background-size: cover;
  background-position: center;
  box-shadow: 0 24px 48px rgba(31, 46, 53, 0.18);
}
/* Il mondo, mosses: the two books, as a mockup ---------------------------
   The file is a render with its own backdrop, its own rounded edges and its
   own shadow already in it, on transparency. Left in the .side-art tile it
   would have been a rounded rectangle with a drop shadow sitting inside a
   second rounded rectangle with a drop shadow — the same doubling .lore-cover
   on the Dasos page exists to avoid. So the tile is dropped here too: no
   background colour, no radius, no box-shadow, the image drawn whole with a
   shadow that follows what is actually in it.
   Ratio is the file's own (900x1000), so the space is held before it loads. */
.sa-mosses {
  aspect-ratio: 9 / 10;
  max-width: 460px;
  background-image: url("../assets/img/lore-mosses.webp");
  background-size: contain;
  background-repeat: no-repeat;
  border-radius: 0;
  box-shadow: none;
  filter: drop-shadow(0 22px 34px rgba(31, 46, 53, 0.28));
}
@media (min-width: 900px) {
  .lore-grid { grid-template-columns: 1.1fr 0.9fr; gap: 4rem; }
  .side-art { margin-inline: 0 auto; }
  /* Dasos puts the cover first, so the columns swap: the narrower one is on
     the left and carries the book, the prose takes the wider one. */
  .lore--books .lore-grid { grid-template-columns: 0.9fr 1.1fr; }
  /* Flush with the container's left edge — the same rule .naos-cover
     follows, which is what puts the two books at an identical distance from
     the edge of the page as you scroll from one to the other. */
  .lore--books .lore-cover { margin-inline: 0 auto; }
}

/* --- Il mondo, dasos: the cover, on its own ------------------------------
   It used to stand on a gradient tile with the Naos volume beside it. With
   a single book the tile was a rectangle drawn around a rectangle, and the
   cover already has its own edges and its own shadow — so the tile went and
   the cover grew into the space it was taking. */
.lore-cover {
  aspect-ratio: 3 / 5;
  width: min(100%, 340px);
  margin-inline: auto;
  background-image: url("../assets/img/mockup-dasos.webp");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  /* drop-shadow follows the cover's silhouette; box-shadow would draw a
     rectangle around a cut-out */
  filter: drop-shadow(0 20px 34px rgba(31, 46, 53, 0.34));
}

/* --- Inside the book: dark world section with feature mini-cards --- */
.inside {
  padding-block: var(--section-pad);
  color: var(--warm-white);
  text-align: center;
}
/* A gradient rather than the flat world colour: this section is a long run
   of small cards, and a flat field behind them made the whole block read as
   one grey slab. The radials sit off-axis so the light never lines up with
   the card grid. */
/* The stone path, seen from above, exported rotated: the source is 1:2
   portrait and this section is wide, so upright it was cropped to a sliver.
   The gradient over it is light enough now to let the path read — the
   contrast the white text needs comes from the cards themselves, which are
   frosted glass rather than a hairline box (see .inside-dasos .feature-card).
   Without that the copy would be sitting straight on the photograph. */
.inside-dasos {
  background-color: var(--dasos);
  background-image:
    radial-gradient(ellipse 60% 50% at 18% 8%, rgba(178, 202, 107, 0.16), transparent 66%),
    radial-gradient(ellipse 55% 55% at 88% 72%, rgba(77, 128, 152, 0.26), transparent 68%),
    linear-gradient(168deg, rgba(14, 32, 21, 0.80) 0%, rgba(28, 58, 43, 0.72) 46%, rgba(20, 48, 38, 0.82) 100%),
    url("../assets/img/inside-dasos-bg.webp");
  background-size: auto, auto, auto, cover;
  background-position: center;
}
/* The alchemist's hut at night. Same construction as Dasos above: the
   painting at the bottom, a veil in the world's colour over it, two
   off-axis radials on top so the light never lines up with the card grid.
   The veil runs top-to-bottom rather than on the diagonal Dasos uses, and
   that is not a style choice. The moon in this painting sits just left of
   centre and about a third of the way down — which, once `cover` has scaled
   the picture, is exactly where the section title lands. A diagonal veil left
   white type on a pale moon. Weighted down the vertical instead, the band the
   title occupies is the darkest part, the middle opens up behind the cards
   where the picture is worth seeing, and the foot closes again to meet the
   ivory section below. It also holds at any window height, which no amount of
   background-position tuning would have. */
.inside-mosses {
  background-color: var(--mosses);
  background-image:
    radial-gradient(ellipse 58% 50% at 16% 10%, rgba(144, 88, 209, 0.20), transparent 66%),
    radial-gradient(ellipse 55% 55% at 84% 66%, rgba(135, 214, 252, 0.18), transparent 68%),
    linear-gradient(180deg,
      rgba(14, 18, 48, 0.88) 0%,
      rgba(28, 34, 78, 0.62) 24%,
      rgba(28, 34, 78, 0.56) 62%,
      rgba(15, 19, 50, 0.80) 100%),
    url("../assets/img/inside-mosses-bg.webp");
  background-size: auto, auto, auto, cover;
  background-position: center;
}
.feature-grid {
  display: grid;
  gap: 1.1rem;
  margin-top: 2.5rem;
}
.feature-card {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(184, 152, 104, 0.35);
  border-radius: var(--radius-card);
  background: rgba(252, 249, 245, 0.04);
  padding: 1.6rem 1.5rem;
  text-align: left;
  transition: border-color 0.5s var(--ease-soft);
}
/* The hidden image. It is the ::before, so no extra markup: the photo comes
   from --card-img on the card itself and is layered UNDER a dark gradient,
   which is what keeps the text readable once it fades in. A missing file
   simply leaves the gradient — the card deepens instead of breaking. */
.feature-card::before {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background-image:
    linear-gradient(var(--card-scrim-a, rgba(12, 28, 20, 0.58)),
                    var(--card-scrim-b, rgba(12, 28, 20, 0.76))),
    var(--card-img, none);
  background-size: cover;
  background-position: center;
  opacity: 0;
  transform: scale(1.05);
  transition: opacity 0.55s var(--ease-soft), transform 0.9s var(--ease-soft);
  pointer-events: none;
}
/* The six images, declared HERE and not inline: a url() inside a custom
   property resolves relative to the file that uses the var() — this
   stylesheet — so paths must be written the way every other asset path in
   here is, with the ../ that steps out of css/.
   TODO(assets): inside-dasos-1.jpg … -6.jpg */
.fc-dasos-1 { --card-img: url("../assets/img/inside-dasos-1.jpg"); }
.fc-dasos-2 { --card-img: url("../assets/img/inside-dasos-2.jpg"); }
.fc-dasos-3 { --card-img: url("../assets/img/inside-dasos-3.jpg"); }
.fc-dasos-4 { --card-img: url("../assets/img/inside-dasos-4.jpg"); }
.fc-dasos-5 { --card-img: url("../assets/img/inside-dasos-5.jpg"); }
.fc-dasos-6 { --card-img: url("../assets/img/inside-dasos-6.jpg"); }

/* The scrim takes the world's colour, so the revealed image sinks into the
   section it sits in rather than turning every card forest-green. */
.inside-mosses .feature-card {
  --card-scrim-a: rgba(22, 25, 60, 0.58);
  --card-scrim-b: rgba(22, 25, 60, 0.78);
}
.fc-mosses-1 { --card-img: url("../assets/img/inside-mosses-1.jpg"); }
.fc-mosses-2 { --card-img: url("../assets/img/inside-mosses-2.jpg"); }
.fc-mosses-3 { --card-img: url("../assets/img/inside-mosses-3.jpg"); }
.fc-mosses-4 { --card-img: url("../assets/img/inside-mosses-4.jpg"); }
.fc-mosses-5 { --card-img: url("../assets/img/inside-mosses-5.jpg"); }
.fc-mosses-6 { --card-img: url("../assets/img/inside-mosses-6.jpg"); }
.feature-card:hover::before,
.feature-card:focus-within::before {
  opacity: 1;
  transform: none;
}
.feature-card:hover { border-color: rgba(184, 152, 104, 0.7); }

/* Frosted glass — on both worlds now that both sections stand on a
   photograph, and the old 4%-white card was far too thin to read a paragraph
   on. The blur is what does the work: it flattens the picture's detail behind
   the text while the colour stays, so the painting is still visible through
   the card. Without backdrop-filter support the background alone is nearly
   opaque, which is the right fallback — legible first, pretty second. */
.inside-dasos .feature-card {
  background: rgba(11, 28, 20, 0.66);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
          backdrop-filter: blur(14px) saturate(120%);
  border-color: rgba(184, 152, 104, 0.30);
}
.inside-mosses .feature-card {
  background: rgba(17, 21, 54, 0.66);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
          backdrop-filter: blur(14px) saturate(120%);
  border-color: rgba(184, 152, 104, 0.30);
}
@supports not (backdrop-filter: blur(4px)) {
  .inside-dasos .feature-card  { background: rgba(11, 28, 20, 0.90); }
  .inside-mosses .feature-card { background: rgba(17, 21, 54, 0.90); }
}
/* Touch screens have no hover: show the images and be done with it */
@media (hover: none) {
  .feature-card::before { opacity: 1; transform: none; }
}
/* The text rides above the image layer */
.feature-card h3,
.feature-card p { position: relative; z-index: 1; }
.feature-card h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.0625rem;
  letter-spacing: 0.08em;
  margin: 0 0 0.5rem;
}
.feature-card p { margin: 0; font-size: 1rem; line-height: 1.6; opacity: 0.88; }
@media (min-width: 700px)  { .feature-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .feature-grid { grid-template-columns: 1fr 1fr 1fr; } }

/* --- The four tales (dasos only): illustration + numbered list rows --- */
.tales { padding-block: var(--section-pad); text-align: center; }
.tales-grid {
  display: grid;
  gap: 2.5rem;
  align-items: center;
  margin-top: 2rem;
}
@media (min-width: 900px) {
  .tales-grid {
    grid-template-columns: 0.85fr 1.15fr;
    gap: 3.5rem;
  }
}
/* The four-vignette illustration. aspect-ratio holds the space before the
   file loads, so nothing jumps. */
.tales-art {
  /* matches presentazione avventure 2.0 — much taller than the old
     four-vignette export, so the ratio moved with it */
  aspect-ratio: 1100 / 1856;
  border-radius: var(--radius-card);
  background-image: url("../assets/img/tales-dasos.webp");
  background-size: cover;
  background-position: center;
  box-shadow: 0 24px 48px rgba(31, 46, 53, 0.22);
}
.tales-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 46rem;
  text-align: left;
}
.tale-row { display: flex; align-items: baseline; gap: 1.5rem; padding: 1.5rem 0; }
.tale-row + .tale-row { border-top: 1px solid rgba(184, 152, 104, 0.3); }
.tale-numeral {
  font-family: var(--font-display);
  font-size: 1.75rem;
  color: var(--gold);
  flex: 0 0 3rem;
  text-align: center;
}
.tale-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.25rem;
  letter-spacing: 0.06em;
  margin: 0 0 0.35rem;
}
.tale-hook { margin: 0; opacity: 0.85; }
/* The level sits at the end of the hook, quieter than the prose */
.tale-level {
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--bronze);
  white-space: nowrap;
}

/* --- Le pagine: a still photographic band (dasos) ------------------------
   The spreads bleed off every edge of the export, so this is a texture, not
   a composition: cropping it to a band loses nothing and the pages running
   past the edges look deliberate.

   It replaced a background-attachment: fixed version. That pins the image to
   the viewport, so the band became a moving window: the spreads slid behind
   it and were cut at a different place at every scroll position, which reads
   as a rendering fault rather than an effect. Here the picture simply holds
   still and the band is a divider between the light half of the page and the
   dark Naos chapter that follows. */
.pages-band { display: block; }
.pages-band img {
  display: block;
  width: 100%;
  height: clamp(300px, 54vh, 620px);
  object-fit: cover;
  object-position: center;
}

/* --- Page-flip viewer (Turn the pages) --- */
.pages { padding-block: var(--section-pad); text-align: center; }
.book-viewer { display: grid; gap: 1.25rem; margin-top: 2.5rem; }
/* Mobile: the buttons are a horizontal scroll row above the image */
.viewer-tabs {
  display: flex;
  gap: 0.6rem;
  overflow-x: auto;
  padding-bottom: 0.25rem;
}
.viewer-tab {
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink);
  background: transparent;
  border: 1px solid rgba(184, 152, 104, 0.55);
  border-radius: 999px; /* pill */
  padding: 0.7em 1.4em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.3s var(--ease-soft), border-color 0.3s var(--ease-soft), color 0.3s var(--ease-soft);
}
.viewer-tab:hover { border-color: var(--gold); }
.viewer-tab.is-active {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--ink);
}
/* The stage: rounded image area where the selected spread crossfades in */
.viewer-stage {
  position: relative;
  /* The spread's own proportions, per page. 3/2 was a guess made before any
     export existed; the Mosses spreads measure 4667x3246, so that viewer
     sets --stage-ratio and nothing is cropped. */
  aspect-ratio: var(--stage-ratio, 3 / 2);
  border-radius: var(--radius-card);
  border: 1px solid rgba(184, 152, 104, 0.45);
  overflow: hidden;
}
.viewer-page {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 0.3s var(--ease-soft); /* the 300ms crossfade */
}
.viewer-page.is-active { opacity: 1; }
/* The spreads are real <img> so they can be loading="lazy"; the stacking and
   the crossfade above are tag-agnostic, only the fitting has to be restated. */
img.viewer-page {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
@media (min-width: 900px) {
  /* Desktop: pill buttons in a left column, stage on the right */
  .book-viewer { grid-template-columns: 220px 1fr; align-items: start; }
  .viewer-tabs { flex-direction: column; overflow: visible; padding: 0; }
}

/* --- Sfoglia le pagine, mosses: two viewers in one section --------------
   The first shows four chapters, so four kinds of layout; the second shows
   the moss entries, which is what the book is made of. */
.pages-mosses { --stage-ratio: 1.438; }   /* 4667 / 3246, the exported spread */

/* A wider pill column than the 220px default: the moss pills name both
   entries on their spread, and "Filonea e Crimson Whisper" needs 267px on
   one line. Set on BOTH viewers in the section, not just the one that needs
   it — otherwise the two stages would come out 60px apart in width, stacked
   one above the other, and read as a mistake. */
@media (min-width: 900px) {
  .pages-mosses .book-viewer { grid-template-columns: 280px 1fr; }
}

/* Sul telefono: mezza apertura, cioe' una pagina intera --------------------
   A 345px lo spread lascia 172px a pagina: una macchia. Qui il rapporto
   dello stage e' esattamente la meta' di quello dell'apertura
   (1.438 / 2 = 0.719), quindi `cover` scala l'immagine sull'altezza e la
   taglia precisamente sulla piega: object-position: left lascia la pagina
   di sinistra, intera, a riempire il riquadro. Nessuna seconda esportazione,
   e il taglio cade sulla cucitura per costruzione invece che a occhio.
   Le pagine di sinistra sono anche le piu' forti delle otto: tre aperture di
   capitolo, e la scheda che da' il nome al pulsante. */
@media (max-width: 699px) {
  .pages-mosses { --stage-ratio: 0.719; }
  .pages-mosses img.viewer-page { object-position: left center; }
}

/* The second viewer needs its own air: without it the pills of one group sit
   right under the stage of the other and the two read as one long strip. */
.section-head--sub { margin-top: 4rem; }
.section-subtitle {
  font-family: var(--font-display);
  font-weight: 500;
  /* A step under .section-title, not a second one: the group belongs to
     "Sfoglia le pagine" and must not compete with it. */
  font-size: clamp(1.25rem, 2.6vw, 1.6rem);
  letter-spacing: 0.06em;
  line-height: 1.25;
  margin: 0 0 0.5rem;
}

/* --- The moss pills -----------------------------------------------------
   Each moss carries its own pair of colours, taken from the spread the pill
   opens, so the row previews the pages instead of just labelling them.

   Idle they are outlined in the moss's own colour and carry a small gradient
   dot; only the selected one fills. Four filled gradients at once would be a
   row of sweets with no way to tell which one is open.

   Both light stops are dark enough to hold white text at 4.5:1 or better —
   that is what caps them, not taste. */
.viewer-tab--moss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  /* The outline goes through its own variable rather than reading --moss-b
     directly: Margheris ends on ivory, and an ivory outline on an ivory page
     is no outline at all. Everyone else lets it default to the light stop. */
  border-color: var(--moss-line, var(--moss-b));
}
.viewer-tab--moss::before {
  content: "";
  width: 0.55em;
  height: 0.55em;
  border-radius: 50%;
  flex: none;
  background: linear-gradient(135deg, var(--moss-a), var(--moss-b));
}
.viewer-tab--moss:hover { border-color: var(--moss-a); }
.viewer-tab--moss.is-active {
  background: linear-gradient(135deg, var(--moss-a), var(--moss-b));
  border-color: var(--moss-a);
  /* Margheris runs pale, so the label there is ink instead of white. */
  color: var(--moss-ink, var(--warm-white));
}
.viewer-tab--moss.is-active::before { background: rgba(252, 249, 245, 0.9); }

/* Each pill carries the two mosses on its spread, and the gradient runs from
   the colour of the first to the colour of the second — so the pill is a
   miniature of the pages it opens. Elderbloom has the spread to itself.

   Every stop is picked to clear 4.5:1 against its own label. That is what
   caps them: "verde pisello" and "arancione" both start out too bright for
   white type and are taken down until they hold it. */
.vt-filonea     { --moss-a: #1b4430; --moss-b: #a33228; }  /* verde foresta -> rosso intenso */
.vt-margheris   { --moss-a: #3f9fb4; --moss-b: #d8d3c4;    /* blu acqua -> grigio avorio */
                  --moss-line: #3f9fb4; --moss-ink: var(--ink); }
.vt-polytherion { --moss-a: #5c7a1e; --moss-b: #b0500f; }  /* verde pisello -> arancione */
.vt-elderbloom  { --moss-a: #1e2856; --moss-b: #4478b0; }  /* gli spiriti, indaco e azzurro */

/* --- Gallery strip + lightbox --- */
.gallery { padding-block: var(--section-pad); text-align: center; }
.gallery-strip {
  display: flex;
  gap: 1rem;
  margin-top: 2.5rem;
  overflow-x: auto; /* mobile: horizontal scroll row */
  padding-bottom: 0.5rem;
}
.gallery-thumb {
  flex: 0 0 220px;
  aspect-ratio: 4 / 3;
  border: 1px solid rgba(184, 152, 104, 0.35);
  border-radius: var(--radius-soft);
  background-size: cover;
  background-position: center;
  padding: 0;
  cursor: default;
  transition: transform 0.4s var(--ease-soft);
}
/* JS marks a thumb .is-loaded (and enables it) only when its real image
   exists — until then it stays a quiet world-colored tile */
.gallery-thumb.is-loaded { cursor: pointer; }
.gallery-thumb.is-loaded:hover { transform: scale(1.03); }
@media (min-width: 900px) {
  .gallery-strip { overflow: visible; }
  .gallery-thumb { flex: 1 1 0; min-width: 0; }
}

/* --- Showcase carousel ---
   One big centred image, its neighbours peeking in from both edges of the
   page, arrows straddling the centre slide, caption and dots underneath.

   --slide-w is the single source of truth: the slide width AND where the
   arrows sit are both derived from it, so the arrows always land exactly on
   the edges of the centre image at any screen size. */
.showcase {
  position: relative;
  --slide-w: min(78vw, 500px);
  --slide-gap: 1.25rem;
  margin-top: 2.5rem;
}
@media (min-width: 900px) {
  .showcase { --slide-w: min(52vw, 720px); --slide-gap: 1.75rem; }
}
/* Full page width with the overflow clipped: that is what lets the side
   slides bleed off both edges instead of forcing a horizontal scrollbar.
   The clipping is also why the padding has to clear the active slide's
   shadow: the shadow reaches ~24px above and ~64px below the slide, and
   anything past this padding gets sliced off in a hard straight line. */
.showcase-viewport {
  overflow: hidden;
  padding-block: 2rem 4.25rem;
}
.showcase-track {
  display: flex;
  gap: var(--slide-gap);
  /* js/main.js writes the translation that centres the active slide */
  transition: transform 0.55s var(--ease-soft);
  will-change: transform;
}
.showcase-slide {
  flex: 0 0 var(--slide-w);
  margin: 0;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-card);
  background-size: cover;
  background-position: center;
  /* the neighbours sit back: smaller and quieter than the one in focus */
  transform: scale(0.86);
  opacity: 0.5;
  transition: transform 0.55s var(--ease-soft), opacity 0.55s var(--ease-soft),
              box-shadow 0.55s var(--ease-soft);
}
.showcase-slide.is-active {
  transform: scale(1);
  opacity: 1;
  /* kept in line with the other large shadows on the site, and small enough
     to fit inside the viewport padding above */
  box-shadow: 0 20px 44px rgba(31, 46, 53, 0.28);
}
/* Set while the track is being re-seated after a loop: the slide taking
   over is the SAME picture in the SAME place, so it must not fade and grow
   into view as if it had just arrived. Nothing may animate during the jump. */
.showcase.is-jumping .showcase-track,
.showcase.is-jumping .showcase-slide { transition: none; }
/* Placeholder tints while the images are pending */
.sh-dasos .showcase-slide:nth-child(odd) {
  background-image: var(--slide-img, none),
    radial-gradient(ellipse at 30% 30%, rgba(178, 202, 107, 0.25), transparent 60%),
    linear-gradient(140deg, #12281d, var(--dasos));
}
.sh-dasos .showcase-slide:nth-child(even) {
  background-image: var(--slide-img, none),
    radial-gradient(ellipse at 70% 40%, rgba(77, 128, 152, 0.35), transparent 60%),
    linear-gradient(140deg, #10231a, var(--dasos-teal));
}
/* url() lives here, not inline: inside a custom property it resolves against
   the stylesheet, so an inline "assets/…" would be read as "css/assets/…" */
.ss-dasos-1 { --slide-img: url("../assets/img/gallery-dasos-1.webp"); }
.ss-dasos-2 { --slide-img: url("../assets/img/gallery-dasos-2.webp"); }
.ss-dasos-3 { --slide-img: url("../assets/img/gallery-dasos-3.webp"); }
.ss-dasos-4 { --slide-img: url("../assets/img/gallery-dasos-4.webp"); }
.ss-dasos-5 { --slide-img: url("../assets/img/gallery-dasos-5.webp"); }
.ss-dasos-6 { --slide-img: url("../assets/img/gallery-dasos-6.webp"); }

.sh-mosses .showcase-slide:nth-child(odd) {
  background-image: var(--slide-img, none),
    radial-gradient(ellipse at 30% 30%, rgba(135, 214, 252, 0.3), transparent 60%),
    linear-gradient(140deg, #1d2347, var(--mosses));
}
.sh-mosses .showcase-slide:nth-child(even) {
  background-image: var(--slide-img, none),
    radial-gradient(ellipse at 70% 40%, rgba(144, 88, 209, 0.35), transparent 60%),
    linear-gradient(140deg, #1a2044, var(--mosses-purple));
}
.ss-mosses-1 { --slide-img: url("../assets/img/gallery-mosses-1.webp"); }
.ss-mosses-2 { --slide-img: url("../assets/img/gallery-mosses-2.webp"); }
.ss-mosses-3 { --slide-img: url("../assets/img/gallery-mosses-3.webp"); }
.ss-mosses-4 { --slide-img: url("../assets/img/gallery-mosses-4.webp"); }
.ss-mosses-5 { --slide-img: url("../assets/img/gallery-mosses-5.webp"); }
.ss-mosses-6 { --slide-img: url("../assets/img/gallery-mosses-6.webp"); }

/* Arrows: half on the centre slide, half off it, from --slide-w */
.showcase-arrow {
  position: absolute;
  top: calc(1rem + (var(--slide-w) / 16 * 10) / 2);  /* mid-height of the slide */
  transform: translateY(-50%);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  font-size: 1.75rem;
  line-height: 1;
  color: var(--ink);
  background: var(--warm-white);
  border: 1px solid var(--gold);
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(31, 46, 53, 0.18);
  transition: background-color 0.3s var(--ease-soft), color 0.3s var(--ease-soft);
}
.showcase-arrow:hover { background: var(--gold); color: var(--ink); }
.showcase-prev { left: calc(50% - var(--slide-w) / 2 - 23px); }
.showcase-next { left: calc(50% + var(--slide-w) / 2 - 23px); }

.showcase-caption {
  width: min(46rem, 88%);
  /* the viewport already carries its shadow clearance below the slide */
  margin: 0.5rem auto 0;
  text-align: center;
}
.showcase-caption-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.25rem;
  letter-spacing: 0.05em;
  margin: 0;
}
/* Empty captions must not leave a gap: :empty collapses the block until
   data-title / data-text are filled in */
.showcase-caption-title:empty { display: none; }
.showcase-caption-text {
  margin: 0.6rem 0 0;
  opacity: 0.85;
}
.showcase-caption-text:empty { display: none; }

.showcase-dots {
  display: flex;
  justify-content: center;
  gap: 0.55rem;
  margin-top: 1.75rem;
}
.showcase-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 1px solid var(--gold);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: background-color 0.3s var(--ease-soft), transform 0.3s var(--ease-soft);
}
.showcase-dot.is-active { background: var(--gold); transform: scale(1.25); }

@media (prefers-reduced-motion: reduce) {
  .showcase-track,
  .showcase-slide { transition: none; }
}
/* Placeholder tints, alternating so the strip doesn't look like one slab */
.gs-dasos .gallery-thumb:nth-child(odd)  { background-image: radial-gradient(ellipse at 30% 30%, rgba(178, 202, 107, 0.25), transparent 60%), linear-gradient(140deg, #12281d, var(--dasos)); }
.gs-dasos .gallery-thumb:nth-child(even) { background-image: radial-gradient(ellipse at 70% 40%, rgba(77, 128, 152, 0.35), transparent 60%), linear-gradient(140deg, #10231a, var(--dasos-teal)); }
.gs-mosses .gallery-thumb:nth-child(odd)  { background-image: radial-gradient(ellipse at 30% 30%, rgba(135, 214, 252, 0.3), transparent 60%), linear-gradient(140deg, #1d2347, var(--mosses)); }
.gs-mosses .gallery-thumb:nth-child(even) { background-image: radial-gradient(ellipse at 70% 40%, rgba(144, 88, 209, 0.35), transparent 60%), linear-gradient(140deg, #1a2044, var(--mosses-purple)); }

/* The lightbox overlay (built once by js/main.js) */
.lightbox {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: 200;
  background: rgba(15, 22, 26, 0.93);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}
.lightbox[hidden] { display: none; }
.lightbox-img {
  max-width: min(1100px, 88vw);
  max-height: 84vh;
  border-radius: var(--radius-soft);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}
.lightbox-btn {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid rgba(252, 249, 245, 0.4);
  border-radius: 999px;
  color: var(--warm-white);
  font-family: var(--font-ui);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.3s var(--ease-soft), color 0.3s var(--ease-soft);
}
.lightbox-btn:hover { border-color: var(--gold); color: var(--gold); }
/* The JS hides the arrows (btn.hidden = true) when there's a single image.
   This rule is required: the author display:grid above would otherwise beat
   the [hidden] attribute's UA display:none and the arrows would still show. */
.lightbox-btn[hidden] { display: none; }
.lightbox-close { position: absolute; top: 1.25rem; right: 1.5rem; }
.lightbox-prev  { position: absolute; left: 1.5rem; top: 50%; transform: translateY(-50%); }
.lightbox-next  { position: absolute; right: 1.5rem; top: 50%; transform: translateY(-50%); }

/* --- The sales panel (specs + every way to buy) --------------------------
   This section used to open on a bare specs table. "Prendi il libro" in the
   hero jumps here, and what met you was a list of page counts with no
   heading — nothing to confirm you had landed where you meant to. It carries
   its own title now, worded exactly like the button that sends you here.

   It is also the only place on either book page where a DriveThruRPG link
   lives. Every other "get it" button on the page is an anchor to #get-the-book
   instead: one row of prices and links to keep in step rather than four, and
   the bundle URL only has to exist in one spot. */
.specs-get { padding-block: var(--section-pad); text-align: center; }
.specs-get-grid { display: grid; gap: 2.5rem; align-items: start; }
@media (min-width: 900px) {
  .specs-get-grid { grid-template-columns: 0.8fr 1.2fr; gap: 4rem; }
}
/* The fixed navbar must not cover the section when "Get the book" jumps here */
.specs-get { scroll-margin-top: calc(var(--header-h) + 1rem); }

/* === LE CITAZIONI ==========================================================
   La fascia .quotes, sopra il pannello d'acquisto di dasos.php e mosses.php
   (rev. 12 §H). Si stampa solo se l'array $citazioni della pagina non e'
   vuoto: qui non c'e' nessuna regola che nasconda qualcosa, semplicemente il
   markup non esiste finche' le citazioni vere non arrivano.

   FONDO CALDO E SOLO PADDING SOPRA. La sezione ha lo stesso bg-warm del
   pannello e nessun padding sotto: fra l'ultima citazione e il titolo "Prendi
   il libro" resta il padding-top del pannello, cioe' esattamente un
   --section-pad, la distanza standard fra due momenti della pagina. Metterlo
   da tutte e due le parti avrebbe fatto due section-pad sommati, che e' il
   doppio di qualunque altra giunzione del sito.

   PERCHE' NON ASSOMIGLIA A .pull-quote. Su mosses.php esiste gia' una
   blockquote.pull-quote nella sezione "Il mondo": e' la voce di Spiro, cioe'
   FINZIONE. Se le due si somigliassero, il lettore le confonderebbe e la
   testimonianza vera perderebbe tutto il suo valore. Quindi divergono in
   quattro punti misurabili, non in sfumature:
     .pull-quote          -> corsivo, filetto d'oro a sinistra, virgolette
                             alte "curly", firma in maiuscoletto bronzo
     .quote (questa qui)  -> tondo, scheda con bordo su tutti i lati,
                             virgolette basse «», nome in --ink non maiuscolo
   Le virgolette basse sono anche la forma italiana per il discorso riportato
   di una persona reale: e' la scelta giusta due volte.

   SCHEDA COSTRUITA COME .specs-card, non inventata: stesso avorio, stesso
   bordo bronzo al 45%, stesso raggio. La fascia deve sembrare nata insieme al
   pannello che le sta sotto, non appiccicata sopra.
   ============================================================================ */
.quotes {
  padding-top: var(--section-pad);
}
.quotes-grid {
  display: grid;
  gap: 1.25rem;
}
/* 760px e' la stessa soglia di .offer-grid: le due griglie della stessa zona
   di pagina devono passare a due colonne nello stesso punto, o scendendo si
   vede prima una spezzarsi e poi l'altra. */
@media (min-width: 760px) {
  .quotes-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Le due schede restano ALTE UGUALI anche con citazioni di lunghezza molto
   diversa (e' il caso da reggere: una lunga e una corta affiancate). Lo fanno
   da sole — la griglia allunga entrambe alla piu' alta — ma senza il flex qui
   sotto l'attribuzione della piu' corta resterebbe a mezz'aria sotto il suo
   testo: margin-top: auto su .quote-by la spinge in fondo alla scheda, cosi'
   i due nomi si leggono sulla stessa linea. */
.quote {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 1.75rem 1.9rem;
  background: var(--ivory);
  border: 1px solid rgba(184, 152, 104, 0.45);
  border-radius: var(--radius-card);
  text-align: left;
}
/* Corpo del testo del sito, tondo. Le virgolette basse le mette il CSS, cosi'
   non vanno battute nel testo: se le si scrivesse a mano nell'array uscirebbero
   doppie, ed e' l'errore che questa coppia di regole rende impossibile. */
.quote-text {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.7;
}
.quote-text::before { content: "\00AB"; }
.quote-text::after  { content: "\00BB"; }

/* Il nome in --ink e in tondo, non nel maiuscoletto bronzo di
   .pull-quote-cite: qui e' una persona che ha parlato, e va letta come tale.
   Il contesto sotto, piu' piccolo e in bronzo, e' quello che trasforma la
   frase in prova: senza, e' una bella riga che ha scritto chi vende. */
.quote-by {
  margin-top: auto;
  padding-top: 1.1rem;
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink);
}
.quote-ctx {
  display: block;
  margin-top: 0.2rem;
  font-weight: 500;
  color: var(--bronze);
}

/* --- The offers: one card per thing you can actually buy --- */
.offer-grid {
  display: grid;
  gap: 1.25rem;
  margin-top: 2.5rem;
  text-align: center;
}
/* SOTTO I 900: UNA COLONNA SOLA, mai due.
   Le schede sono TRE: due affiancate e la terza sotto fanno sempre un dispari,
   con la scheda orfana allineata a sinistra e un vuoto accanto. Qui non ci
   stanno in tre — sotto i 263px di scheda la nota sotto il titolo va a capo su
   una sola delle tre e sfalsa i prezzi, vedi il blocco dopo — quindi l'unica
   composizione che non lascia buchi e' la colonna: tre schede impilate e
   centrate.
   La colonna resta larga 22rem e non tutto il container — la scheda deve
   restare a forma di libro, non diventare una fascia orizzontale.

   Il repeat(1, ...) e' scritto per esteso invece di una traccia sola perche'
   la riga si legga come la sorella di quella qui sotto: cambia solo il numero.

   NOTA STORICA. Qui c'era auto-fit, con scritto che serviva perche' "la scheda
   del bundle si stampa solo quando esiste il suo URL" e che tre colonne fisse
   avrebbero lasciato un buco. Non e' piu' vero e forse non lo e' mai stato: la
   scheda del bundle si stampa SEMPRE, e' il suo pulsante a diventare uno
   <span> spento finche' manca $dtr_bundle. Le schede sono tre a ogni
   caricamento, ed e' proprio su questo che si puo' contare per fissarle a
   numero invece di lasciarle contare al browser — che contandole da solo
   produceva il due-piu-uno. */
@media (min-width: 760px) {
  .offer-grid {
    grid-template-columns: repeat(1, minmax(0, 22rem));
    justify-content: center;
  }
}

/* DA 900 IN SU: tre colonne, sempre.
   IL PROBLEMA CHE RISOLVE. Con auto-fit il numero di colonne lo decide il
   MASSIMO della minmax, non il minimo: tre schede da 22rem piu' i due stacchi
   fanno 1096px, e il container ne offre 942 a 1024px di finestra. Ne mancano
   154, e la terza scheda — proprio il bundle, quello col bordo d'oro — andava
   a capo da sola in una seconda fila, allineata a sinistra, con un vuoto
   accanto. Il pannello passava da 495 a 939px di altezza, quasi il doppio.
   Succedeva da 787 a 1191px: iPad in orizzontale, e ogni finestra di browser
   non a tutto schermo su un portatile.

   minmax(0, 22rem) e non minmax(15rem, 22rem): con un minimo di 15rem tre
   colonne pretendono 760px e sotto quella misura traboccherebbero dal
   container. Con lo zero le tre colonne si stringono a quanto c'e' — 263px a
   900, 301 a 1024, 352 (il massimo) da 1192 in su, dove il pannello torna
   identico a com'e' sempre stato.
   justify-content: center resta: da 1192 in su le tre tracce si fermano a
   22rem e i 24px che avanzano nel container vanno divisi ai due lati.

   PERCHE' 900 E NON PIU' GIU'. E' il pavimento misurato, e a fissarlo non e' il
   pulsante come sembrava a prima vista: e' la NOTA sotto il titolo. Su
   mosses.php "Il compendio · ~100 pagine" e' in maiuscoletto spaziato a 0,16em
   e a 247px di scheda va a capo, mentre le note delle altre due restano su una
   riga: il prezzo di quella scheda scendeva di 20px e i tre numeri non erano
   piu' sulla stessa linea — esattamente il difetto che le tre colonne servono
   a togliere. Misurato: a 247px la nota va a capo, a 250 no.
   (Il pulsante e' il secondo vincolo, non il primo: "Prendilo su DriveThruRPG"
   regge fino a 238px. La prima prova aveva messo il pavimento a 850 guardando
   solo quello, e su mosses.php i prezzi si sfalsavano.)
   900 e non 860: a 900 la scheda e' 263px, cioe' 16px oltre la misura che
   regge. Il margine serve perche' la soglia dipende dalle metriche del font, e
   con un carattere di ripiego — piu' largo del Cinzel, vedi
   tools/verify/README.md — quei pochi pixel se ne vanno tutti.
   900 e' anche il punto in cui la navbar passa a desktop (02-navbar.css): il
   pannello cambia forma dove cambia forma il resto della pagina, e non due
   volte a poca distanza. */
@media (min-width: 900px) {
  .offer-grid { grid-template-columns: repeat(3, minmax(0, 22rem)); }
}

/* IL PULSANTE, NELLA FASCIA STRETTA.
   E' il prezzo da pagare per le tre colonne, ed e' l'unico. Sotto i 329px di
   scheda "Prendilo su DriveThruRPG" va a capo mentre "Ottieni Naos" resta su
   una riga: i tre pulsanti venivano alti 71, 49 e 71, e nel tentativo di
   allineare i prezzi si disallineavano i pulsanti.
   MISURATO, non stimato: a 1114px di finestra la scheda e' 327px e il testo va
   a capo; a 1115 la scheda e' 329px e sta su una riga. Il limite qui sotto e'
   1149 e non 1114: 35px di margine, perche' la soglia dipende dalle metriche
   del font e un carattere di ripiego la sposta. Sforare in eccesso non si vede
   (il pulsante piccolo si vede solo in questa fascia, mai accanto a quello
   grande); sforare in difetto si vede eccome.
   Il limite basso e' 900, lo stesso da cui partono le tre colonne: sotto c'e'
   una colonna sola, larga 352px, dove il pulsante grande ci sta comodo.
   SI RIMPICCIOLISCE IL CARATTERE, NON SI ACCORCIA IL TESTO. "DriveThruRPG" e'
   l'informazione che dice dove porta il clic, e chi la legge decide se
   cliccare sapendo che esce dal sito: toglierla per guadagnare due caratteri
   costerebbe piu' di due punti di corpo.
   Tre numeri e non uno: il corpo da solo non bastava — e' la spaziatura fra le
   lettere a 0,18em che in maiuscoletto mangia la larghezza, e l'imbottitura
   laterale di 2em che a 263px di scheda si porta via un terzo della riga. */
@media (min-width: 900px) and (max-width: 1149px) {
  .offer .btn {
    font-size: 0.6875rem;
    letter-spacing: 0.09em;
    padding-inline: 0.75rem;
  }
}
.offer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  background: var(--ivory);
  border: 1px solid rgba(184, 152, 104, 0.45);
  border-radius: var(--radius-card);
  padding: 1.9rem 1.5rem 1.75rem;
}
/* contain e nessuna tile dietro: i mockup sono render su trasparenza con i
   loro bordi, per lo stesso motivo per cui .lore-cover non ha un pannello.

   ALTEZZA fissa e rapporto per copertina (i rapporti stanno sulle .oc-*).
   I cinque render escono dal tool a cinque proporzioni diverse una volta
   rifilati: 0,60 i volumi Dasos, 0,69 quelli dei Muschi, 0,80 il bundle
   Dasos, 1,55 i due libri Muschi affiancati. Fissando solo il rapporto ogni
   libro sarebbe stato disegnato di una dimensione diversa; fissando
   l'altezza stanno tutti alti uguali nella loro scheda. Il rapporto serve
   comunque, ma per la larghezza: la scatola deve fasciare il libro, se no
   l'ombra di contatto esce da sotto (vedi il blocco sulle ombre). */
.offer-cover {
  height: clamp(190px, 20vw, 240px);
  width: auto;
  max-width: 100%;
  margin-inline: auto;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center bottom;
  filter: drop-shadow(0 14px 24px rgba(31, 46, 53, 0.30));
}
/* IL TITOLO OCCUPA SEMPRE DUE RIGHE, anche quando ne riempie una (rev. 12).
   Su dasos.php "Racconti della Foresta di Dasos" va a capo e "Naos" no:
   misurato, 47px contro 23. Il titolo piu' alto spingeva giu' tutto quello che
   ha sotto, e i tre prezzi finivano su tre linee diverse — 24px di sfalsamento
   fra la prima scheda e le altre due. Tre prezzi affiancati che non stanno
   sulla stessa riga si confrontano peggio, ed e' il confronto tutto il lavoro
   che devono fare.
   2.6em e non 47px: em qui vale il corpo del titolo (1,125rem = 18px), quindi
   2,6em sono esattamente due righe di line-height 1.3. Scritto cosi', se un
   giorno il corpo del titolo cambia la riserva lo segue da sola; scritto in
   pixel resterebbe indietro in silenzio.
   DUE E NON TRE: due righe e' il massimo misurato su tutti e due i libri, a
   1440, 1024, 900 e 760. Un titolo di tre righe crescerebbe oltre la riserva e
   sfalserebbe di nuovo — ma allora il posto giusto dove intervenire e' il
   titolo, non questo numero.
   Il costo e' su mosses.php, dove i titoli stanno tutti su una riga: li' le
   schede guadagnano 24px di aria sotto il nome. Vale il pareggio, perche' e'
   aria uguale su tutte e tre e non un buco su una sola. */
.offer-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.125rem;
  letter-spacing: 0.06em;
  line-height: 1.3;
  min-height: 2.6em;
  margin: 0;
  text-wrap: balance;
}
.offer-note {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--bronze);
  margin: 0;
}
/* IL PREZZO (rev. 12 §B). Corpo del display e non del testo: nella scheda e'
   la seconda cosa che si guarda dopo la copertina, e in corpo normale finiva
   sotto la .offer-note maiuscoletta senza distinguersi da lei.
   In --ink pieno, non in --bronze come la nota: il bronzo e' il colore delle
   didascalie di servizio, e il prezzo qui non e' servizio, e' l'argomento.
   Margine solo sopra e negativo: il .offer e' un flex con gap 0.9rem, che
   staccherebbe il prezzo dalla riga a cui appartiene tanto quanto dal
   pulsante; -0.35rem lo riavvicina alla nota senza toccare il gap comune. */
.offer-price {
  margin: -0.35rem 0 0;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.1;
  color: var(--ink);
}
/* Il prezzo pieno del bundle, sbarrato. Piu' piccolo e in bronzo perche' deve
   leggersi come il termine di paragone, non come una seconda offerta: se i due
   numeri pesano uguale, per un istante sembrano due prezzi e la scheda smette
   di essere chiara. Il margine destro tiene i due a distanza di una parola. */
.offer-price-was {
  margin-right: 0.4rem;
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--bronze);
}

/* auto pushes the button to the foot of the card, so the buttons sit on one
   line however long the titles above them run; stretch makes them all the
   same width, which a row of differently-worded CTAs otherwise never is. */
.offer .btn {
  margin-top: auto;
  align-self: stretch;
}

/* A button with nowhere to go yet — the bundle, until its store URL exists.
   Rendered as a <span>, so there is no dead link to click, and drawn as an
   outline in bronze rather than a faded gold slab: half-opacity gold read as
   a broken button, an outline reads as one that is not open yet. */
.btn.is-pending {
  background: transparent;
  border-color: rgba(184, 152, 104, 0.55);
  color: var(--bronze);
  box-shadow: none;
  cursor: default;
  pointer-events: none;
}

/* The bundle: the same card, lit. Bordo d'oro e un rialzo caldo, senza
   etichetta "sconto".
   NOTA (rev. 12 §B): questo commento diceva che l'enfasi doveva essere solo
   visiva perche' non c'era un prezzo su cui vantare un risparmio. Adesso c'e',
   ed e' il prezzo pieno sbarrato a fare quel lavoro (.offer-price-was). Il
   bordo d'oro resta comunque: dice quale delle tre schede guardare prima, che
   e' un'informazione che il numero da solo non da'. Un badge no — sarebbero
   due enfasi sulla stessa scheda. */
.offer--bundle {
  border-color: var(--gold);
  box-shadow: 0 16px 34px rgba(184, 152, 104, 0.20);
}


.specs-card {
  background: var(--ivory);
  border: 1px solid rgba(184, 152, 104, 0.45);
  border-radius: var(--radius-card);
  padding: 1.9rem 2rem;
}
.specs-list { margin: 0; }
.specs-row { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: 0.65rem 0; }
.specs-row + .specs-row { border-top: 1px solid rgba(184, 152, 104, 0.22); }
.specs-row dt {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--bronze);
}
.specs-row dd { margin: 0; font-size: 1.0625rem; text-align: right; }

/* The shared spec sheet, under the offers: what is true of every product in
   the panel. Stacked rows on a phone like the card it used to be; from 760px
   up it opens out into a strip, because read across it is four short facts
   and reading four short facts down a column wastes the width. */
.specs-card--strip { margin-top: 1.25rem; }
@media (min-width: 760px) {
  .specs-card--strip .specs-list {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
  }
  .specs-card--strip .specs-row {
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 1rem;
    text-align: center;
  }
  .specs-card--strip .specs-row + .specs-row {
    border-top: 0;
    border-left: 1px solid rgba(184, 152, 104, 0.22);
  }
  .specs-card--strip .specs-row dd { text-align: center; }
}

/* The foot of the panel: the Kickstarter proof, centred under everything */
.get-foot { margin-top: 2.5rem; }
.get-foot .get-row { justify-content: center; }

/* The little gold diamond announces the badge line */
/* --- The Kickstarter cover, framed (mosses) ---
   A gold hairline with a hairline inset just inside it: the double line is
   what makes it read as a frame rather than as one more rounded card. */
.ks-frame {
  padding: 0.55rem;
  margin-bottom: 1.75rem;
  border: 1px solid rgba(184, 152, 104, 0.55);
  border-radius: var(--radius-card);
  box-shadow: 0 18px 40px rgba(31, 46, 53, 0.16);
}
.ks-cover {
  aspect-ratio: 16 / 9;   /* holds the space before the file lands */
  border-radius: calc(var(--radius-card) - 6px);
  background-size: cover;
  background-position: center;
}
/* TODO(asset): assets/img/ks-cover-mosses.jpg — until it exists the world
   gradient stands in, like every other pending image on the site.
   NOTE: unused since the sales panel was rebuilt around the product cards —
   kept here in case the Kickstarter cover is wanted back in that section. */
.ks-cover-mosses {
  background-image:
    url("../assets/img/ks-cover-mosses.jpg"),
    radial-gradient(ellipse at 30% 25%, rgba(135, 214, 252, 0.28), transparent 60%),
    linear-gradient(140deg, #1d2347, var(--mosses) 55%, var(--mosses-purple));
}

.funded-badge {
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--bronze);
  margin: 0 0 1.5rem;
}
.funded-badge::before {
  content: "\25C6"; /* ◆ */
  color: var(--gold);
  font-size: 0.7em;
  margin-right: 0.7em;
  vertical-align: 0.15em;
}
.get-row { display: flex; flex-wrap: wrap; gap: 1rem; }

/* Small muted side card (Forest Companions) */
.mini-card {
  margin-top: 2.25rem;
  max-width: 30rem;
  background: var(--ivory);
  border: 1px solid rgba(184, 152, 104, 0.35);
  border-radius: var(--radius-card);
  padding: 1.5rem 1.6rem;
}
.mini-card h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.0625rem;
  letter-spacing: 0.08em;
  margin: 0 0 0.4rem;
}
.mini-card p { margin: 0 0 0.9rem; font-size: 1rem; opacity: 0.85; }
/* The add-on card, with its cover next to the copy. A modifier and not a
   change to .mini-card itself: Epteka uses the plain card for two
   masterpieces that have no artwork to show. */
/* Stacked on a phone, side by side from 560px up. Two columns at 375px left
   the copy about 205px wide, and "Guarda su DriveThruRPG" broke over two
   lines — which .arrow-link handles badly: the arrow is a flex sibling of the
   label, so a wrapped label leaves it stranded on its own, centred against
   the far edge of the card. Stacking gives the line the width it needs. */
.mini-card--cover .mini-cover { width: 110px; }
@media (min-width: 560px) {
  .mini-card--cover {
    display: grid;
    grid-template-columns: 88px 1fr;
    gap: 1.25rem;
    align-items: start;
  }
  .mini-card--cover .mini-cover { width: auto; margin-bottom: 0; }
}
.mini-card--cover > :last-child > :first-child { margin-top: 0.1rem; }
.mini-cover {
  margin-bottom: 1rem;
  border-radius: 4px;
  border: 1px solid rgba(184, 152, 104, 0.45);
  background-size: cover;
  background-position: center;
  box-shadow: 0 8px 18px rgba(31, 46, 53, 0.20);
}
/* Inside the sales panel only: that section centres its contents, and the
   card has to be pulled back to the middle and its own copy set left again.
   Scoped, because Epteka uses .mini-card too, in a two-up grid that must
   keep the alignment it already has. */
.specs-get .mini-card { margin-inline: auto; text-align: left; }

/* --- Covers in the sales panel ------------------------------------------
   All five in place, every one a transparent render trimmed to the book's
   own edges — no gradient stand-ins left here. The Mosses volume is exported
   alone as well as inside the bundle render because this panel shows the two
   books both separately and together. (Fino a poco fa serviva anche alla
   home, che faceva salire il mockup sulla tile al passaggio del mouse: quella
   sezione adesso e' un indice con i nomi scritti e di mockup non ne usa.) */
/* Rapporto per copertina: e' quello del file, rifilato al bordo del libro.
   Con l'altezza fissata sopra, la scatola viene larga quanto il libro — che e'
   la condizione perche' l'ombra di contatto cada sotto il libro e non a lato. */
.oc-dasos         { aspect-ratio: 598 / 1000;  background-image: url("../assets/img/mockup-dasos.webp"); }
.oc-naos          { aspect-ratio: 601 / 1000;  background-image: url("../assets/img/mockup-naos.webp"); }
.oc-dasos-bundle  { aspect-ratio: 804 / 1000;  background-image: url("../assets/img/mockup-dasos-bundle.webp"); }
.oc-mosses        { aspect-ratio: 688 / 1000;  background-image: url("../assets/img/mockup-mosses.webp"); }
.oc-nsuaf         { aspect-ratio: 689 / 1000;  background-image: url("../assets/img/mockup-nsuaf.webp"); }
/* I due libri Muschi di fianco sono l'unico render orizzontale, e l'unico che
   NON prende un rapporto. Con 1000/644 a 240px di altezza verrebbe largo 373
   contro i 304 della scheda, quindi max-width lo strozzerebbe e il rapporto
   salterebbe comunque; e abbassando la scatola per farcelo stare, il titolo
   di quella scheda saliva rispetto alle altre due e i tre titoli non erano
   piu' in linea. Scatola a tutta larghezza e altezza come le altre, quindi:
   `contain` fa entrare il render da solo, appoggiato in basso, e all'ellisse
   si dice a mano quanto e' larga. */
.oc-mosses-bundle {
  width: 100%;
  background-image: url("../assets/img/mockup-mosses-bundle.webp");
}

/* === L'ombra dei libri =====================================================
   drop-shadow, che segue la sagoma del ritaglio: un box-shadow disegnerebbe
   un rettangolo attorno a un libro che rettangolo non e'.

   will-change: filter non e' decorativo, e' la correzione del difetto che si
   vedeva insieme alle animazioni dei pulsanti. `filter` costringe l'elemento
   su una superficie di rendering separata; senza una promozione esplicita
   quella superficie vive dentro il contesto del genitore, e ogni volta che un
   vicino promuove un layer — cosa che i pulsanti fanno a ogni hover, animando
   transform e box-shadow — la superficie viene ri-rasterizzata. Una sfocatura
   da 24-34px su tutta l'immagine, ricalcolata a meta' di una transizione, e'
   esattamente lo scatto che si vedeva. Con will-change ogni copertina ha il
   suo layer stabile e l'hover del pulsante accanto non la tocca piu'.

   Da usare con parsimonia, ed e' il caso: sono quattro elementi in tutto il
   sito e al massimo tre in viewport insieme. I pulsanti e le loro animazioni
   restano esattamente come sono. */
.offer-cover,
.lore-cover,
.naos-cover,
.sa-mosses {
  will-change: filter;
}


/* === CONTINUA A ESPLORARE ==================================================
   In fondo a dasos.php e mosses.php: due pannelli .world affiancati, l'altro
   libro e Epteka, con UNA riga di dati sotto ciascuno. Il modello sta in
   03-home.css (sezione "I MONDI") e non viene riscritto qui — qui c'e' solo
   cio' che cambia fra la home e il fondo di una pagina libro.
   Della didascalia della home sopravvive la sola .world-meta: il titolo e la
   freccia non sono spenti con un display:none, semplicemente il markup non ce
   li ha. Il perche' sta nel commento in cima alla sezione in dasos.php.

   1. IL FILETTO D'ORO. Sopra c'e' .specs-get, che e' bianco caldo; questa e'
      avorio. Fra le due tinte ballano cinque punti di rosso, sei di verde e
      undici di blu su 255: e' l'unica giunzione fra due sezioni chiare della
      pagina e senza una riga non si legge come giunzione — il pannello
      sembra cominciare a caso. Stesso filetto e stessa misura di
      .manifesto--creed in 07-pagine-e-piede.css: oro al 40%, che e' il
      valore di casa per i divisori a tutta larghezza su fondo chiaro.
      Sta come border-top di chi apre e non come border-bottom di chi chiude
      perche' qui, al contrario del caso di about.php, sopra il bordo non
      passa nessun figlio in posizione assoluta che possa coprirlo.

   2. MENO ARIA FRA I PANNELLI. In home il gap e' 3.5rem perche' li' sotto
      ogni pannello c'e' una didascalia alta tre righe e i due blocchi devono
      restare distinti. Qui sotto ciascuno c'e' una riga sola (rev. 12 §G):
      a 56px di distanza i due pannelli sembrerebbero due cose senza rapporto,
      a 32 si leggono come una coppia. I 2rem restano anche con la riga in
      piu' — una riga alta 13px non e' la didascalia che aveva richiesto i
      3.5rem della home.
      Due classi (0,2,0) contro la classe sola della media query (0,1,0),
      quindi questa vince a qualunque ordine dei fogli — non e' una
      scommessa sulla cascata.

   3. IL PANNELLO EPTEKA, che in home non esiste (li' Epteka e' la fascia
      dorata .world-band). Serve solo per queste due sezioni, quindi vive
      qui e non in 03-home.css: e' la variante di una pagina, non un modello.

   Cosa e' sparito da qui: .continue-grid e le due righe che truccavano
   .project-tile / .tile-caption. Le tile si appoggiavano a tre .jpg mai
   arrivati e mostravano solo il gradiente del mondo; adesso non le usa piu'
   nessuna pagina e sono uscite anche da 03-home.css. */
.continue {
  padding-block: var(--section-pad);
  text-align: center;
  border-top: 1px solid rgba(184, 152, 104, 0.4);
}
.continue .worlds-grid { gap: 2rem; }

/* --- Il pannello Epteka ---------------------------------------------------
   --scrim-k NON E' UN OPZIONALE, QUI. .world-panel::after calcola le sue
   opacita' con calc(0.92 * var(--scrim-k)): senza la variabile il calc e'
   invalido, l'intera dichiarazione background cade e il pannello resta
   SENZA velatura — cioe' col nome bianco sul niente. In home il problema non
   si pone perche' .world--epteka veste la fascia, che lo scrim non ce l'ha.

   E vale 1, il massimo, per il motivo opposto a Dasos: sotto il nome non
   c'e' sottobosco scuro ma la neve della copertina, che e' quasi bianca.
   Misurato sul rendering, campionando il fondo dentro il riquadro del nome
   col nome nascosto: bianco caldo sul velato sta a 5,35:1 nel pixel
   peggiore e 6,02:1 nel mediano a 1440, 5,43:1 e 6,12:1 a 390. Il minimo di
   casa e' 4,5. */
.continue .world--epteka { --scrim-k: 1; }

/* Il ritaglio. Il file e' 1920x1080 (16:9), la finestra del pannello e' 3:2:
   si perde il 16% della larghezza. `right` la toglie tutta da sinistra, dove
   c'e' solo cielo, e tiene intero il cavaliere col suo scudo, che nel file
   arriva gia' a 20px dal bordo destro. */
.continue .wa-epteka { object-position: right center; }

/* IL NOME COME TESTO. Epteka non ha un lockup da appoggiare sull'immagine
   (di questo mondo esistono la copertina della hero e le batterie, nessun
   marchio disegnato), quindi il nome e' composto: stesso angolo dei due
   loghi, stesso --logo-pad, stesso peso ottico.

   La misura non e' in vw. Il pannello e' meta' container, non una frazione
   della finestra: legarlo alla larghezza dello schermo lo farebbe crescere
   anche quando il pannello sta fermo. E' un valore fisso, scelto per pareggio
   ottico coi vicini — misurato in pagina a 1440, dove il pannello e' largo
   544: EPTEKA occupa 153px, il logo dei Muschi 147 (27%), quello di Dasos
   239 (44%).
   Sul telefono scende, se no in un pannello largo 358 la parola ci arriva
   quasi da bordo a bordo. */
.continue .world-title {
  position: absolute;
  left: var(--logo-pad);
  bottom: var(--logo-pad);
  z-index: 2;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--warm-white);
}
@media (max-width: 460px) {
  .continue .world-title { font-size: 1.5rem; letter-spacing: 0.12em; }
}
