/* Nostra — landing page.
   Palette and the dialog panel's borders are lifted from the game's own UI
   (scripts/npc_dialog.gd), so the call to action is the thing players will
   actually see when they walk up to Askel in the arena. */

@font-face {
  font-family: "Ortica";
  src: url("assets/Ortica-Bold.otf") format("opentype");
  font-weight: 700;
  font-display: swap;
}

:root {
  color-scheme: dark;

  --night: #0c0a07;
  --night-2: #14100a;
  --night-3: #1d1710;

  /* Straight out of scripts/npc_dialog.gd so the panel matches the game. */
  --parchment: #d1bc94;
  --parchment-lit: #e4d4b0;
  --ink: #382614;        /* INK_DARK  */
  --ink-title: #734a14;  /* INK_TITLE */
  --ink-body: #40301f;   /* INK_BODY  */
  --ink-faded: #6b5438;  /* INK_FADED */
  --frame: #52381a;

  --gold: #c9a24b;
  --gold-lit: #e5c87e;
  --ember: #c4562a;

  --bone: #e8e0d0;
  --bone-dim: #9a9184;

  --display: "Ortica", "Palatino Linotype", Palatino, Georgia, serif;
  --body: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --util: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, monospace;

  --measure: 1180px;
  --gutter: clamp(1.25rem, 5vw, 4rem);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--night);
  color: var(--bone);
  font-family: var(--body);
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* Cold moonlight above, ember low — keeps the page off flat black without
   putting a texture over the character. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(90rem 55rem at 72% -12%, rgba(120, 148, 196, 0.16), transparent 62%),
    radial-gradient(60rem 40rem at 12% 108%, rgba(196, 86, 42, 0.12), transparent 60%);
}

a { color: var(--gold-lit); }

::selection { background: var(--gold); color: var(--night); }

:focus-visible {
  outline: 2px solid var(--gold-lit);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------- top bar */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--measure);
  margin: 0 auto;
  padding: 1.4rem var(--gutter) 0;
}

.topbar-meta,
.topbar-link {
  margin: 0;
  font-family: var(--util);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bone-dim);
}

.topbar-link {
  color: var(--gold);
  text-decoration: none;
  border-bottom: 1px solid rgba(201, 162, 75, 0.35);
}

.topbar-link:hover { color: var(--gold-lit); border-bottom-color: var(--gold-lit); }

/* ------------------------------------------------------------------ hero */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: clamp(2rem, 4vw, 4rem);
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 4.5rem) var(--gutter) clamp(3rem, 7vw, 6rem);
}

.wordmark {
  display: block;
  width: min(100%, 26rem);
  height: auto;
  margin-bottom: 2rem;
}

.hero h1 {
  margin: 0 0 1.25rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.9rem, 1.2rem + 2.4vw, 3.1rem);
  line-height: 1.12;
  letter-spacing: 0.005em;
  color: var(--parchment-lit);
  text-wrap: balance;
}

.lede { margin: 0 0 1rem; max-width: 34rem; color: var(--bone); }

.lede-sub {
  margin: 0;
  font-family: var(--util);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bone-dim);
}

/* Askel stands in the page; the dialog panel is pinned over her right side,
   the way the window opens beside her in game. */
.hero-scene {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 34rem;
}

/* Askel sits a little below centre so the Q marker above her head has room. */
.figure-wrap {
  position: relative;
  display: flex;
  margin-left: -8%;
  margin-top: 5rem;
}

.figure {
  width: auto;
  height: clamp(26rem, 46vw, 40rem);
  max-width: 100%;
  object-fit: contain;
  filter: drop-shadow(0 2rem 3rem rgba(0, 0, 0, 0.65));
}

/* The quest marker the game floats over a quest giver's head (npc.gd). In game
   it is 0.5m tall on a 1.8m NPC and sits well clear of the head because a name
   plate sits between them; there is no name plate here, so it rides closer. */
.quest-mark {
  position: absolute;
  left: 0;
  /* She is rendered at a slight yaw, so her head is left of the image's centre.
     Insetting the right edge slides the centred marker over her head. */
  right: 24%;
  bottom: 100%;
  display: flex;
  justify-content: center;
  margin-bottom: 0.5rem;
  pointer-events: none;
}

.quest-mark img {
  width: auto;
  height: clamp(3.75rem, 6.5vw, 5.5rem);
  filter: drop-shadow(0 0.4rem 0.6rem rgba(0, 0, 0, 0.6));
  animation: quest-bob 3.14s ease-in-out infinite;
}

/* npc.gd:221 — y = BASE + sin(ticks_msec * 0.002) * 0.06 on a 0.5m icon.
   0.002 rad/ms is 2 rad/s, so the period is 2*PI/2 = 3.14s, and the 0.06m
   swing is +-12% of the icon's own height. Percentage translateY resolves
   against the element's height, so the ratio holds at every screen size. The
   bob lives on the <img> because its parent owns the entrance animation's
   transform.

   Deliberately NOT inside the prefers-reduced-motion guard that the entrance
   animations use. This is the marker's identity — it is what the icon does in
   game — and it is a 21px drift with no flashing. Windows' "Animation effects"
   toggle (Settings > Accessibility > Visual effects) reports `reduce` to every
   browser, which is common on machines tuned for frame rate, and gating this
   on it meant the marker sat dead still for exactly the people most likely to
   be playing. */
@keyframes quest-bob {
  from, to { transform: translateY(12%); }
  50%      { transform: translateY(-12%); }
}

/* --------------------------------------------------------- dialog window */

/* This panel mirrors the NPC dialog window the player actually sees in game
   (scripts/npc_dialog.gd `_draw`): the same stretched parchment texture, the
   3px frame with a hairline 4px inside it, the offset drop shadow, and the
   option list pinned to the bottom of the paper. The game window is 380x540
   minimum and "always taller than wide" — kept here.

   Centred with auto margins rather than a translate, so the page-load
   animation owns `transform` outright. */
.dialog {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  height: fit-content;
  margin-block: auto;
  display: flex;
  flex-direction: column;
  width: min(23.75rem, 88%);
  min-height: 33.75rem;
  padding: 1.625rem; /* PAD = 26px */
  color: var(--ink-body);
  /* draw_texture_rect(_parchment, wr, false) stretches to fill, not tiles. */
  background: var(--parchment) url("assets/parchment.png") center / 100% 100% no-repeat;
  border: 3px solid var(--frame);
  box-shadow:
    5px 6px 0 rgba(0, 0, 0, 0.35),
    0 1.5rem 3rem rgba(0, 0, 0, 0.5);
}

/* The game draws a second hairline 4px inside the frame. */
.dialog::after {
  content: "";
  position: absolute;
  inset: 4px;
  border: 1px solid rgba(115, 82, 38, 0.45);
  pointer-events: none;
}

.dialog-name {
  margin: 0;
  font-family: var(--display);
  font-size: 1.6875rem; /* 27px */
  line-height: 1.05;
  color: var(--ink);
}

.dialog-name button {
  padding: 0;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

.dialog-name button:hover { color: var(--frame); }

.dialog-title {
  margin: 0.15rem 0 0;
  font-family: var(--display);
  font-size: 1rem; /* 16px */
  line-height: 1.1;
  color: var(--ink-title);
}

.dialog-rule {
  height: 0;
  margin: 0.75rem 0 0;
  border: 0;
  border-top: 1.5px solid rgba(89, 61, 26, 0.55);
}

.dialog-line {
  margin: 1.4rem 0 0;
  font-family: var(--display);
  font-size: 1.1875rem; /* 19px */
  line-height: 1.35;
  font-weight: 400;
  color: var(--ink-body);
}

/* Options sit at the bottom of the parchment, as in game — the gap above them
   grows with the window rather than following the spoken line. */
.dialog-options {
  margin-top: auto;
  padding-top: 1.5rem;
}

.option {
  display: block;
  padding: 0.5rem 0.75rem;
  color: var(--ink-faded);
  text-decoration: none;
  background: rgba(64, 43, 20, 0.1);
  border: 1.5px solid rgba(97, 69, 33, 0.5);
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}

.option + .option { margin-top: 0.5rem; } /* OPTION_H 44 - 36 = 8px */

.option:hover,
.option:focus-visible {
  color: var(--ink);
  background: rgba(77, 51, 20, 0.22);
  border-color: rgba(102, 69, 26, 0.9);
}

.option-name {
  display: block;
  font-family: var(--display);
  font-size: 1.0625rem; /* 17px */
  line-height: 1.2;
}

.option-sub {
  display: block;
  margin-top: 0.05rem;
  font-family: var(--util);
  font-size: 0.66rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  opacity: 0.75;
}

/* ----------------------------------------------------------------- bands */

.band {
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(2.5rem, 5vw, 4.5rem) var(--gutter);
  border-top: 1px solid rgba(201, 162, 75, 0.18);
}

.eyebrow {
  margin: 0 0 2rem;
  font-family: var(--util);
  font-size: 0.7rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold);
}

/* Four pillars, so step 4 -> 2 -> 1 and never 3: an auto-fit track count
   strands the fourth one alone on its own row at middling widths. */
.pillars {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
}

@media (max-width: 68rem) {
  .pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 34rem) {
  .pillars { grid-template-columns: 1fr; }
}

.pillar h2,
.realm h2 {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.3rem;
  line-height: 1.2;
  color: var(--parchment-lit);
}

.pillar p,
.realm p { margin: 0; color: var(--bone-dim); }

.realms {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
}

.realm {
  padding: 1.6rem 1.7rem;
  background: linear-gradient(160deg, var(--night-3), var(--night-2));
  border: 1px solid rgba(201, 162, 75, 0.22);
}

.realm-kind {
  margin: 0 0 0.65rem;
  font-family: var(--util);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ember);
}

/* ----------------------------------------------------------------- get in */

.get-in { text-align: center; }

.get-in-head {
  margin: 0 0 1rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.8rem, 1.2rem + 2vw, 2.7rem);
  line-height: 1.15;
  color: var(--parchment-lit);
}

.get-in-copy {
  max-width: 36rem;
  margin: 0 auto 2rem;
  color: var(--bone-dim);
}

.cta {
  display: inline-block;
  padding: 1rem 2.4rem;
  font-family: var(--display);
  font-size: 1.2rem;
  color: var(--night);
  text-decoration: none;
  background: linear-gradient(175deg, var(--gold-lit), var(--gold));
  border: 1px solid #f0dda6;
  box-shadow: 4px 5px 0 rgba(0, 0, 0, 0.45);
  transition: transform 140ms ease, box-shadow 140ms ease;
}

.cta:hover,
.cta:focus-visible {
  transform: translate(-2px, -2px);
  box-shadow: 6px 7px 0 rgba(0, 0, 0, 0.5);
}

.cta-sub {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--util);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(28, 20, 8, 0.72);
}

.fineprint {
  max-width: 32rem;
  margin: 1.5rem auto 0;
  font-size: 0.85rem;
  color: var(--bone-dim);
}

.get-in-alt { margin: 2rem 0 0; color: var(--bone-dim); }

/* ---------------------------------------------------------------- footer */

.foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  max-width: var(--measure);
  margin: 0 auto;
  padding: 2rem var(--gutter) 3rem;
  border-top: 1px solid rgba(201, 162, 75, 0.18);
  font-family: var(--util);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bone-dim);
}

.foot p { margin: 0; }

/* ------------------------------------------------------------- responsive */

@media (max-width: 60rem) {
  .hero {
    grid-template-columns: 1fr;
    padding-bottom: clamp(2rem, 6vw, 4rem);
  }

  .hero-copy { text-align: center; }
  .wordmark { margin-inline: auto; }
  .lede { margin-inline: auto; }

  .hero-scene {
    flex-direction: column;
    align-items: center;
    min-height: 0;
  }

  .figure-wrap {
    margin-left: 0;
    margin-top: 3.5rem;
    margin-bottom: -3rem;
  }

  .figure { height: clamp(20rem, 62vw, 30rem); }

  /* The game's window is a fixed 540px tall, which on a phone is mostly empty
     paper. Shortened here — still taller than wide, still the same panel. */
  .dialog {
    position: static;
    margin-block: 0;
    height: auto;
    width: min(23.75rem, 100%);
    min-height: 26rem;
  }

  .foot { justify-content: center; text-align: center; }
}

/* ---------------------------------------------------------- page arrival */

@media (prefers-reduced-motion: no-preference) {
  .hero-copy > *,
  .figure,
  .quest-mark,
  .dialog {
    animation: rise 700ms cubic-bezier(0.2, 0.7, 0.25, 1) both;
  }

  .hero-copy > *:nth-child(1) { animation-delay: 60ms; }
  .hero-copy > *:nth-child(2) { animation-delay: 150ms; }
  .hero-copy > *:nth-child(3) { animation-delay: 230ms; }
  .hero-copy > *:nth-child(4) { animation-delay: 300ms; }
  .figure { animation-delay: 180ms; animation-duration: 900ms; }
  .quest-mark { animation-delay: 700ms; }
  .dialog { animation-delay: 520ms; }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(1.25rem); }
  to { opacity: 1; transform: none; }
}
