/* A topographic map sheet. The field and the carved wordmark are the page;
   the content lives on an island — a landmass grown by the engine, filled
   with the map's own ink and carrying dark text. */

@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url("../assets/fonts/Montserrat-Black.ttf") format("truetype");
}

/* Registered so the ink can cross-fade on the automatic drift. */
@property --ink {
  syntax: "<color>";
  inherits: true;
  initial-value: #7fd4e6;
}

:root {
  --bg: #0b0e12;
  --text: #f2efe9; /* on --bg ≈ 17:1 (AAA) */
  --dim: #9fb0b8; /* on --bg ≈ 8:1 (AAA) */
  --faint: #8c979e; /* on --bg ≈ 5:1 (AA) */
  --ink: #7fd4e6; /* live: the exact color of the map's contour lines */
  --ink-text: #0b0e12; /* fixed dark text on any ink surface */
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --display: "Montserrat", var(--mono);
  --margin: clamp(1.1rem, 3.4vw, 2.75rem);
}

:root.ink-drift {
  transition: --ink 2s ease;
}

* {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  min-height: 100svh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  line-height: 1.55;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--ink);
  text-decoration: none;
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 4px;
}

.island :focus-visible,
.downloads :focus-visible {
  outline-color: var(--ink-text);
}

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

.skip-link {
  position: fixed;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 100;
  padding: 0.55rem 0.9rem;
  background: var(--text);
  color: var(--bg);
  font-weight: 700;
  transform: translateY(-160%);
  transition: transform 0.18s ease;
}
.skip-link:focus {
  transform: translateY(0);
}

/* ---- The sheet: living field + fallbacks ---- */
#field,
.poster,
.grain {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

#field {
  display: block;
}

.poster {
  object-fit: cover;
}
.poster[hidden] {
  display: none;
}

.grain {
  z-index: 1;
  opacity: 0.09;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: soft-light;
}

/* ---- Registration marks (printed-sheet corners) ---- */
.marks {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.mark {
  position: absolute;
  width: 13px;
  height: 13px;
  opacity: 0.5;
}
.mark::before,
.mark::after {
  content: "";
  position: absolute;
  background: var(--dim);
}
.mark::before {
  inset: 6px 0 auto 0;
  height: 1px;
}
.mark::after {
  inset: 0 auto 0 6px;
  width: 1px;
}
.mark--tl {
  top: var(--margin);
  left: var(--margin);
}
.mark--tr {
  top: var(--margin);
  right: var(--margin);
}
.mark--bl {
  bottom: var(--margin);
  left: var(--margin);
}
.mark--br {
  bottom: var(--margin);
  right: var(--margin);
}

/* ---- The island ---- */
.island {
  position: fixed;
  z-index: 3;
  top: var(--margin);
  right: var(--margin);
  width: min(30rem, 46vw);
  height: min(27rem, 66vh);
}

.island__shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* The safe zone: a rectangle guaranteed to sit inside any silhouette
   (the shape's radius never dips below 80% of its half-extent). */
.island__content {
  position: absolute;
  inset: 23% 21%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.45rem;
  color: var(--ink-text);
}

.island__statement {
  margin: 0;
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(0.78rem, 1.15vw, 1rem);
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.island__statement > span {
  white-space: nowrap;
}

.island__seed {
  margin: 0.15rem 0 0;
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(1.1rem, 1.9vw, 1.6rem);
  letter-spacing: 0.02em;
}

.island__contours {
  margin: 0;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.75;
  text-wrap: balance;
}
.island__contours > span {
  white-space: nowrap;
}

/* Primary interaction: a negative landmass — a dark blob carved into the
   island, its own silhouette re-plotted per seed. Rings radiate on hover. */
.island__generate {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(13rem, 92%);
  min-height: 3.1rem;
  margin: 0.35rem 0 0;
  padding: 0.7rem 1.2rem;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.island__generate-shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: transform 0.2s ease;
}
.island__generate:hover .island__generate-shape,
.island__generate:focus-visible .island__generate-shape {
  transform: scale(1.06);
}
.island__generate-label {
  position: relative;
  display: inline-block;
}
.island__generate-label::after {
  content: "";
  position: absolute;
  left: 0.05em;
  top: 50%;
  width: 1.3em;
  height: 1.3em;
  margin-top: -0.65em;
  border: 1px solid currentColor;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
.island__generate:hover .island__generate-label::after,
.island__generate:active .island__generate-label::after {
  animation: ring-radiate 1.1s ease-out infinite;
}
@keyframes ring-radiate {
  from {
    transform: scale(0.4);
    opacity: 0.8;
  }
  to {
    transform: scale(2.2);
    opacity: 0;
  }
}

.island__hint {
  margin: 0;
  font-size: 0.62rem;
  line-height: 1.4;
  opacity: 0.7;
  text-align: center;
  text-wrap: pretty;
}
.island__hint kbd {
  border: 1px solid currentColor;
  padding: 0.02em 0.4em;
}

/* ---- The islet: downloads ---- */
.islet-wrap {
  position: fixed;
  z-index: 4;
  right: calc(var(--margin) + 1rem);
  top: calc(var(--margin) + min(24rem, 60vh) + 0.75rem);
}

.islet {
  position: relative;
  width: 11rem;
  height: 5.2rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}
.islet__shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.islet__label {
  position: relative;
  color: var(--ink-text);
  font-weight: 700;
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.downloads {
  position: absolute;
  top: calc(100% + 0.6rem);
  right: 0;
  width: 20rem;
  display: grid;
  gap: 0.15rem;
  padding: 1.9rem 2.5rem 2.3rem;
  color: var(--ink-text);
}
.downloads[hidden] {
  display: none;
}
.downloads__shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* While the downloads panel is open, a single scrim veils everything behind
   it uniformly — map, island, and margins recede together, no patchwork. */
.downloads-open::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 5;
  background: rgba(11, 14, 18, 0.66);
  animation: scrim-in 0.25s ease;
}
@keyframes scrim-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
/* The wrap rises above the scrim so the open panel stays vivid; the islet
   button itself fades so only the panel reads. */
.downloads-open .islet-wrap {
  z-index: 6;
}
.islet {
  transition: opacity 0.25s ease;
}
.downloads-open .islet {
  opacity: 0.25;
}
.downloads > :not(.downloads__shape) {
  position: relative;
}
.downloads__close {
  justify-self: end;
  margin: 0.5rem 1.6rem 0.3rem 0;
  padding: 0.15rem 0.35rem;
  border: 0;
  background: none;
  color: var(--ink-text);
  font: inherit;
  font-size: 0.72rem;
  cursor: pointer;
  opacity: 0.75;
}
.download__note {
  display: none; /* desktop-only builds — only worth saying on touch devices */
  margin: 0 0 0.4rem;
  padding: 0.4rem 0.5rem;
  font-size: 0.74rem;
  line-height: 1.5;
  border-bottom: 1px dotted currentColor;
}
@media (pointer: coarse) {
  .download__note {
    display: block;
  }
}
.download {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.45rem 0.8rem;
  border-radius: 999px;
  color: var(--ink-text);
  transition: background 0.12s ease;
}
.download:hover,
.download:focus-visible {
  background: color-mix(in srgb, var(--ink-text) 14%, transparent);
}
.download__icon {
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
  color: var(--ink-text);
}
.download__os {
  font-weight: 700;
}
.download__format {
  margin-left: auto;
  font-size: 0.72rem;
  opacity: 0.7;
}
.download--minor {
  font-size: 0.82rem;
}
.download--minor .download__os {
  font-weight: 400;
}
.download--minor .download__icon {
  width: 1.15rem;
  height: 1.15rem;
  opacity: 0.7;
}
.download--all {
  justify-content: center;
  padding-left: 0;
  font-weight: 700;
  opacity: 1;
}

/* ---- Loose margin annotations ---- */
.source {
  position: fixed;
  z-index: 3;
  left: var(--margin);
  top: var(--margin);
  color: var(--text);
  font-size: 0.78rem;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 0.15rem;
  transition: color 0.15s ease;
}
.source:hover {
  color: var(--ink);
}
.source::after {
  content: "→";
  display: inline-block;
  margin-left: 0.35rem;
  transition: transform 0.15s ease;
}
.source:hover::after {
  transform: translateX(4px);
}

.edge {
  position: fixed;
  z-index: 3;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  padding: 0.2rem 0.7rem;
  background: var(--bg); /* opaque backing over the field so the label stays legible */
  color: var(--faint);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.edge--bottom {
  bottom: calc(var(--margin) - 0.15rem);
}

/* ---- Cursor follower: decorative registration cross trailing the pointer ---- */
.follower {
  position: fixed;
  z-index: 90;
  top: 0;
  left: 0;
  width: 30px;
  height: 30px;
  margin: -15px 0 0 -15px;
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  will-change: transform;
}
.follower::before,
.follower::after {
  content: "";
  position: absolute;
  background: var(--ink);
}
.follower::before {
  inset: 12.75px 4px auto 4px;
  height: 1.5px;
}
.follower::after {
  inset: 4px auto 4px 12.75px;
  width: 1.5px;
}
@media not (pointer: fine) {
  .follower {
    display: none;
  }
}

/* ---- Small viewports: map fills the screen, island anchors low ---- */
@media (max-width: 40rem) {
  .island {
    top: auto;
    bottom: calc(var(--margin) + 4.2rem);
    left: calc(var(--margin) * 0.5);
    right: calc(var(--margin) * 0.5);
    width: auto;
    height: min(29rem, 58vh);
  }
  .island__content {
    inset: 24% 25%;
    gap: 0.4rem;
  }
  .island__hint {
    font-size: 0.6rem;
  }
  .islet-wrap {
    top: auto;
    right: var(--margin);
    bottom: calc(var(--margin) + 0.2rem);
  }
  .islet {
    width: 9.5rem;
    height: 4.2rem;
  }
  /* The downloads become a bottom sheet; the wordmark sits in the upper half. */
  .downloads {
    position: fixed;
    top: auto;
    left: calc(var(--margin) * 0.5);
    right: calc(var(--margin) * 0.5);
    bottom: calc(var(--margin) * 0.5);
    width: auto;
    max-height: 48vh;
    overflow-y: auto;
    z-index: 6;
    padding: 2.4rem 2.8rem;
  }
  .source {
    top: auto;
    bottom: calc(var(--margin) + 0.05rem);
    left: var(--margin);
    max-width: calc(100vw - 2 * var(--margin) - 8.5rem);
    font-size: 0.7rem;
    text-wrap: balance;
    background: var(--bg);
    padding: 0.2rem 0.4rem 0.3rem;
  }
  .edge--bottom {
    display: none;
  }
}

/* Reveal baseline: JS fades the island in. Without JS it stays visible. */
.js [data-reveal] {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] {
    opacity: 1;
  }
  .skip-link {
    transition: none;
  }
  :root.ink-drift {
    transition: none;
  }
  .island__generate:hover .island__generate-label::after,
  .island__generate:active .island__generate-label::after {
    animation: none;
  }
  .island__generate-shape {
    transition: none;
  }
  .follower {
    display: none;
  }
}
