/* links.css: the bio-link hub at /links/. Loads after site.css, so it only
   ever reads tokens from there and never redefines one.

   Shape is deliberately the one every visitor already knows from Linktree:
   avatar, name, one line, a stack of full-width buttons, social marks at the
   foot. What is ours is the atmosphere it sits in — the landing page's own
   crimson washes and star dust, with the orrery behind the avatar instead of
   floating off to the right — and the fact that the buttons carry the actual
   covers rather than a row of words.

   Mobile-first: almost everybody arrives by tapping one link on an Instagram
   profile, on a phone, once. */

.links {
  position: relative;
  overflow: hidden;
  min-height: 100vh;
  padding-bottom: clamp(3rem, 8vw, 4.5rem);
}
/* the atmosphere, lifted from home.css's hero so the two pages read as one
   house: two warm radial washes over the star-dust tile */
.links::before {
  content: "";
  position: absolute; inset: -10% -10% auto;
  height: min(120vh, 1100px);
  background:
    radial-gradient(42% 40% at 22% 6%, rgba(110, 40, 48, 0.42), transparent 70%),
    radial-gradient(50% 45% at 84% 40%, rgba(166, 61, 71, 0.16), transparent 72%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cg fill='%23e8ddd0'%3E%3Ccircle cx='23' cy='41' r='1' opacity='.5'/%3E%3Ccircle cx='187' cy='19' r='1.3' opacity='.35'/%3E%3Ccircle cx='104' cy='128' r='.8' opacity='.45'/%3E%3Ccircle cx='219' cy='203' r='1' opacity='.3'/%3E%3C/g%3E%3Cg fill='%23c9a96e'%3E%3Ccircle cx='61' cy='176' r='1.2' opacity='.4'/%3E%3Ccircle cx='152' cy='84' r='.9' opacity='.5'/%3E%3C/g%3E%3Cg fill='%23d98f95'%3E%3Ccircle cx='36' cy='222' r='1' opacity='.35'/%3E%3Ccircle cx='203' cy='117' r='.8' opacity='.4'/%3E%3C/g%3E%3C/svg%3E") repeat;
  pointer-events: none;
}

.links__col {
  position: relative;
  max-width: 27rem;
  margin-inline: auto;
  padding-inline: 1.25rem;
}

/* ── the introduction: the orrery, the avatar at its centre ───────────── */

.intro {
  position: relative;
  text-align: center;
  padding-block: clamp(2.5rem, 8vw, 4rem) clamp(1.5rem, 4vw, 2rem);
}
.intro__orrery {
  position: absolute;
  left: 50%;
  top: clamp(1rem, 4vw, 2rem);
  translate: -50% 0;
  width: min(120vw, 30rem);
  aspect-ratio: 1;
  pointer-events: none;
  opacity: 0.85;
}
@media (prefers-reduced-motion: no-preference) {
  .intro__orbs {
    transform-origin: 300px 300px;
    animation: orrery-turn 150s linear infinite;
  }
  @keyframes orrery-turn { to { transform: rotate(360deg); } }
}

.intro__avatar {
  position: relative;
  display: block;
  width: clamp(6.5rem, 26vw, 8.5rem);
  aspect-ratio: 1;
  object-fit: cover;
  object-position: 50% 20%;
  border-radius: 50%;
  margin: 0 auto 1rem;
  border: 1px solid var(--gold-border);
  box-shadow: 0 0 0 6px var(--bg), 0 0 34px rgba(166, 61, 71, 0.28);
}
.intro h1 {
  position: relative;
  font-size: clamp(1.75rem, 6vw, 2.25rem);
  font-weight: 520;
  margin-bottom: 0.4rem;
}
.intro__bio {
  position: relative;
  color: var(--text-dim);
  font-style: italic;
  max-width: 26ch;
  margin-inline: auto;
}

/* ── the stack ────────────────────────────────────────────────────────── */

.stack { display: grid; gap: 0.6rem; }

.tile {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.9rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(28, 17, 20, 0.82);
  backdrop-filter: blur(2px);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease, translate 0.15s ease;
}
.tile:hover,
.tile:focus-visible {
  border-color: var(--border-hover);
  background: var(--surface-raised);
  translate: 0 -1px;
}
.tile__name { font-weight: 520; font-size: 1.0625rem; display: block; }
.tile__meta {
  display: block;
  text-wrap: balance;
  font-family: var(--mono, "IBM Plex Mono", monospace);
  font-size: 0.6875rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-top: 0.2rem;
}
/* a second meta line sits tighter under the first: series above, date below,
   which is what stops "Perpetura Book One - Out 18 September 2026" wrapping
   with the year stranded on a line of its own */
.tile__meta + .tile__meta { margin-top: 0.15rem; color: var(--text-dim); }
.tile__cover {
  width: 44px;
  height: 66px;
  object-fit: cover;
  border-radius: 2px;
  border: 1px solid var(--divider);
  display: block;
}
.tile__icon { width: 22px; height: 22px; color: var(--text-dim); }

.tile--pantheon .tile__name { color: var(--brass); }
.tile--perpetura .tile__name { color: var(--gold); }
.tile--pantheon:hover, .tile--pantheon:focus-visible { border-color: var(--brass-border); }
.tile--perpetura:hover, .tile--perpetura:focus-visible { border-color: var(--gold-border); }

/* the one free thing. Crimson is the wash and the border, never the text. */
.tile--lead {
  border-color: var(--border-hover);
  background: linear-gradient(rgba(166, 61, 71, 0.22), rgba(166, 61, 71, 0.10));
  padding-block: 1rem;
}
.tile--lead .tile__name { font-size: 1.125rem; }
.tile--lead .tile__icon { width: 26px; height: 26px; color: var(--rose-200); }

/* the small marks that ride under a book: icon only, no words */
.marks {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin: 0.5rem 0 0.4rem;
}
.marks a {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-faint);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.marks a:hover, .marks a:focus-visible { border-color: var(--border-hover); color: var(--text); }
.marks svg { width: 15px; height: 15px; }

/* ── the social row at the foot, and the divider above it ─────────────── */

.social {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  margin-top: clamp(1.75rem, 5vw, 2.5rem);
  padding-top: clamp(1.25rem, 4vw, 1.75rem);
  border-top: 1px solid var(--divider);
}
.social a {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-dim);
  transition: border-color 0.15s ease, color 0.15s ease, translate 0.15s ease;
}
.social a:hover, .social a:focus-visible {
  border-color: var(--border-hover);
  color: var(--text);
  translate: 0 -1px;
}
.social svg { width: 19px; height: 19px; }

.links__foot {
  text-align: center;
  margin-top: 1.5rem;
  font-family: var(--mono, "IBM Plex Mono", monospace);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}
.links__foot a { color: inherit; }
.links__foot br + * , .links__foot { line-height: 1.9; }

svg.sprite { position: absolute; width: 0; height: 0; }
.tile__icon, .marks svg, .social svg { fill: currentColor; }

.intro__note {
  position: relative;
  margin-top: 0.5rem;
  font-family: var(--mono, "IBM Plex Mono", monospace);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold);
}


/* ── clockwork: the decorations that are not the orrery behind the avatar ──
   All three are absolutely placed inside .links, which clips them, so each
   can sit half off the page without ever making the document wider. They are
   pointer-events: none and aria-hidden, so nothing here can eat a tap. */

.deco { position: absolute; pointer-events: none; }
.deco--right {
  right: -34vw; top: 38%;
  width: min(78vw, 26rem); aspect-ratio: 1;
  opacity: 0.5;
}
.deco--left {
  left: -30vw; top: 62%;
  width: min(64vw, 21rem); aspect-ratio: 1;
  opacity: 0.4;
}
.deco--foot {
  left: 50%; bottom: -14%;
  translate: -50% 0;
  width: min(110vw, 34rem); aspect-ratio: 1;
  opacity: 0.45;
}

/* the small centred mark that sits above the social row, in the flow */
.rule {
  display: block;
  width: 34px; height: 34px;
  margin: clamp(1.75rem, 5vw, 2.5rem) auto 0;
  color: var(--gold);
  opacity: 0.75;
}

@media (prefers-reduced-motion: no-preference) {
  .deco__spin { transform-origin: 300px 300px; animation: orrery-turn 220s linear infinite; }
  .deco__spin--back { transform-origin: 300px 300px; animation: orrery-turn 320s linear infinite reverse; }
  .rule__hand { transform-origin: 12px 12px; animation: orrery-turn 60s steps(60) infinite; }
}


/* The ARC tiles. Gold rather than crimson so they read as a second offer rather
   than a second lead. Two side by side in one row: since 2026-10-10, by author
   call, the advance-copy form and Booksprout (NetGalley came off). When Booksprout
   closes on 23 October, drop the .arc-pair wrapper and the form is a full-width
   tile again. */
.arc-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}
/* half a column is too narrow for icon beside text, so the icon sits on top */
.arc-pair .tile {
  grid-template-columns: 1fr;
  align-content: start;
  gap: 0.5rem;
  /* centred to match the book pair below, by author call 2026-09-25 */
  justify-items: center;
  text-align: center;
}
.tile--arc {
  border-color: var(--gold-border);
  background: linear-gradient(rgba(201, 169, 110, 0.10), rgba(201, 169, 110, 0.04));
}
.tile--arc .tile__name { color: var(--gold); }
.tile--arc .tile__icon { color: var(--gold); }
.tile--arc:hover, .tile--arc:focus-visible { border-color: var(--gold); }

/* The two Perpetūra volumes, one row since 2026-09-25. Same reasoning as the
   ARC pair: half a column is too narrow for cover beside text at phone width,
   so the cover sits on top. Each column stretches its tile so the two covers
   and titles line up whatever the meta wraps to. */
.book-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}
.book-pair__col { display: flex; flex-direction: column; }
.book-pair .tile {
  flex: 1;
  grid-template-columns: 1fr;
  align-content: start;
  gap: 0.6rem;
}
.book-pair .tile__cover { width: 56px; height: 84px; }
/* centred by author call: cover, title and meta on one axis in each tile */
.book-pair .tile { justify-items: center; text-align: center; }
