/* vivekn.co site styles: home, 404 and the long-form text page.
   An old hand-inked map: black and red ink on vellum. The story vignette is the one loud element. */

:root {
  color-scheme: light dark;
  --vellum: #ECE3CC;
  --ink: #221F1A;
  --faded: #6E6754;
  --red-ink: #962A1C;
  --gold: #B8862B;
  --banner: #2F4F7F;

  --vellum-deep: color-mix(in srgb, var(--vellum) 88%, var(--ink));
  --grain-opacity: 0.09;
  --edge-shade: rgba(110, 80, 30, 0.16);

  --display: "IM Fell English", "Iowan Old Style", Georgia, serif;
  --body: "Alegreya Sans", "Gill Sans", "Trebuchet MS", sans-serif;

  --s14: 0.875rem;
  --s16: 1rem;
  --s18: 1.125rem;
  --s21: 1.3125rem;
  --s28: 1.75rem;
  --s42: 2.625rem;
  --s72: 4.5rem;

  --gutter: 16px;
  --rule: 1px;
}

@media (min-width: 720px) {
  :root { --gutter: clamp(48px, 8vw, 128px); }
}

@media (prefers-color-scheme: dark) {
  :root {
    --vellum: #17150F;
    --ink: #E9E1CC;
    --faded: #A39A82;
    --red-ink: #D9785E;
    --gold: #E0B34E;
    --banner: #7E9CCB;
    --vellum-deep: color-mix(in srgb, var(--vellum) 90%, var(--ink));
    --grain-opacity: 0.05;
    --edge-shade: rgba(0, 0, 0, 0.45);
  }
}

/* Base */

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

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

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--vellum);
  background-image: radial-gradient(ellipse at 50% 40%, transparent 55%, var(--edge-shade) 100%);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--s18);
  font-weight: 400;
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* The grain sits under everything at low strength. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.35 0 0 0 0 0.27 0 0 0 0 0.12 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23g)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: var(--grain-opacity);
}

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.12;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }

a {
  color: var(--red-ink);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  text-decoration-color: color-mix(in srgb, var(--red-ink) 55%, transparent);
  transition: text-decoration-color 120ms ease, text-decoration-thickness 120ms ease;
}

a:hover {
  text-decoration-color: currentColor;
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--red-ink);
  outline-offset: 3px;
  border-radius: 1px;
}

::selection {
  background: color-mix(in srgb, var(--red-ink) 28%, transparent);
  color: var(--ink);
}

.visually-hidden, .sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Runes: small original marks that sit on frame corners. Defined once as an SVG symbol. */

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.rune {
  position: absolute;
  width: 22px;
  height: 22px;
  color: var(--ink);
  --rune-mark: var(--red-ink);
  pointer-events: none;
}
.rune.tl { top: -11px; left: -11px; }
.rune.tr { top: -11px; right: -11px; transform: rotate(90deg); }
.rune.br { bottom: -11px; right: -11px; transform: rotate(180deg); }
.rune.bl { bottom: -11px; left: -11px; transform: rotate(270deg); }

/* Map border around the whole sheet on wide screens (home and 404). */

.sheet {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
}

.sheet-frame { display: none; }

@media (min-width: 720px) {
  .sheet-frame {
    display: block;
    position: absolute;
    inset: 24px;
    border: var(--rule) solid var(--faded);
    outline: var(--rule) solid var(--faded);
    outline-offset: -5px;
    pointer-events: none;
  }
  .sheet-frame .rune { color: var(--faded); }
}

/* Home */

.home {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "intro"
    "inset"
    "social";
  row-gap: 40px;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 64px var(--gutter) 48px;
  align-content: start;
}

.intro { grid-area: intro; max-width: 34rem; }

.name {
  font-size: var(--s42);
  letter-spacing: -0.005em;
  margin-bottom: 14px;
}

.line {
  font-size: var(--s18);
  max-width: 30rem;
  text-wrap: balance;
}

.story-links {
  list-style: none;
  margin: 28px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
  justify-items: start;
}

.story-links .play { font-size: var(--s21); font-weight: 500; }
.story-links .read { font-size: var(--s18); }

.social {
  grid-area: social;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 28px;
  font-size: var(--s16);
}

.social a { color: var(--faded); text-decoration-color: color-mix(in srgb, var(--faded) 50%, transparent); }
.social a:hover { color: var(--ink); text-decoration-color: currentColor; }
.social .placeholder { color: var(--faded); font-size: var(--s14); }

/* The four chapters, readable without the game, and the site's own pages. */

.page { padding: 64px var(--gutter) 56px; max-width: 42rem; }
.page h1 { font-size: var(--s42); margin-bottom: 18px; }
.page h2 { font-size: var(--s21); margin: 28px 0 8px; }
.page p { margin-bottom: 12px; max-width: 62ch; }
.page ul { margin: 0 0 12px; padding-left: 1.2em; }
.page .back { margin-top: 32px; }

/* The map inset that holds the live vignette. */

.inset {
  grid-area: inset;
  align-self: start;
  position: relative;
  margin: 0;
  width: 100%;
  max-width: 720px;
  padding: 5px;
  border: 2px solid var(--ink);
  transition: border-color 160ms ease;
}

.inset-view {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border: var(--rule) solid var(--ink);
  background-color: var(--vellum-deep);
  background-image:
    repeating-linear-gradient(135deg, transparent 0 9px, color-mix(in srgb, var(--faded) 22%, transparent) 9px 10px);
}

/* Drawn under the iframe so the frame reads as a map before the town loads. */
.inset-compass {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 34%;
  height: auto;
  aspect-ratio: 1;
  color: var(--faded);
  opacity: 0.7;
}

/* One pixel of overscan so the hatching never shows at a fractional edge. */
.inset iframe {
  position: absolute;
  inset: -1px;
  width: calc(100% + 2px);
  height: calc(100% + 2px);
  border: 0;
  display: block;
  background: transparent;
  pointer-events: none;
}

.inset-link {
  position: absolute;
  inset: -7px;
  z-index: 2;
  cursor: pointer;
}

.inset-link:focus-visible { outline-offset: 4px; }

.inset:hover,
.inset:focus-within { border-color: var(--red-ink); }

.inset:hover .rune,
.inset:focus-within .rune { color: var(--red-ink); }

@media (min-width: 720px) {
  .home {
    padding-top: 72px;
    padding-bottom: 72px;
  }
}

@media (min-width: 960px) {
  .home {
    grid-template-columns: minmax(0, 30rem) minmax(0, 720px);
    grid-template-areas:
      "intro inset"
      "social .";
    column-gap: clamp(48px, 7vw, 112px);
    row-gap: 64px;
    align-content: center;
  }
  /* Name, line and story links read as one block, centred on the inset. */
  .intro { align-self: center; }
  .intro .story-links { margin-top: 40px; gap: 8px; }
  .name { font-size: var(--s72); line-height: 1; margin: -6px 0 24px; }
  .line { font-size: var(--s21); }
}

/* Not found */

.lost {
  display: grid;
  align-content: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 56px var(--gutter);
  max-width: 44rem;
}

.lost h1 { font-size: var(--s42); margin-bottom: 14px; }
.lost p { max-width: 40ch; }
.lost .story-links { margin-top: 28px; }

@media (min-width: 960px) {
  .lost h1 { font-size: var(--s72); line-height: 1; margin-bottom: 20px; }
  .lost p { font-size: var(--s21); }
}

/* Long-form text page (story/text.html). Element level and low specificity, so plain markup reads well
   and the home and 404 layouts are left alone. */

:where(main:not(.home, .lost)),
:where(body > header, body > footer) {
  display: block;
  max-width: calc(68ch + 2 * var(--gutter));
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

:where(body > header) { padding-top: 40px; }
:where(main:not(.home, .lost)) { padding-top: 32px; padding-bottom: 48px; }
:where(body > footer) { padding-bottom: 56px; color: var(--faded); font-size: var(--s16); }

:where(body > header nav, main:not(.home, .lost) nav) {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 24px;
  font-size: var(--s16);
}

:where(main:not(.home, .lost)) h1 { font-size: var(--s42); margin: 0 0 12px; }
:where(main:not(.home, .lost)) h2 {
  font-size: var(--s28);
  margin: 56px 0 6px;
  padding-top: 20px;
  border-top: 3px double var(--faded);
}
:where(main:not(.home, .lost)) h3 { font-size: var(--s21); margin: 32px 0 4px; }

:where(main:not(.home, .lost)) p { margin: 0 0 1em; max-width: 68ch; }

:where(main:not(.home, .lost)) :is(ul, ol) { padding-left: 1.25em; margin: 0 0 1em; max-width: 68ch; }
:where(main:not(.home, .lost)) li + li { margin-top: 4px; }

:where(main:not(.home, .lost)) :is(section, article) { max-width: 68ch; }

:where(small, .meta) {
  display: block;
  font-size: var(--s14);
  font-style: italic;
  color: var(--faded);
  line-height: 1.45;
  margin: 0 0 12px;
}

:where(p, li, a, span, h1, h2, h3) small { display: inline; margin: 0; }

:where(main:not(.home, .lost)) blockquote {
  margin: 0 0 1em;
  padding-left: 16px;
  border-left: 1px solid var(--red-ink);
  font-style: italic;
}

:where(hr) {
  border: 0;
  border-top: 3px double var(--faded);
  margin: 40px 0;
  max-width: 68ch;
}

@media (min-width: 960px) {
  :where(main:not(.home, .lost)) h1 { font-size: var(--s72); line-height: 1; margin-bottom: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}
