/* covariance.me — the whole stylesheet. No inline styles anywhere in the output:
   that is what lets the Caddy CSP keep `style-src 'self'` without 'unsafe-inline'. */

/* ---------- Fonts: self-hosted, so `font-src 'self'` holds (no CDN, no Google) --- */

@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/JetBrainsMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/JetBrainsMono-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ---------- Tokens --------------------------------------------------------- */

:root {
  --bg:            #ffffff;
  --text:          #1c1b22;
  --text-2:        #6c6b76;
  --accent:        #7a54e8;
  --accent-2:      #6a43d8;
  --accent-wash:   rgba(122, 84, 232, 0.10);

  --content-width: 40rem;
  --radius:        8px;

  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:            #18151e;
    --text:          #ececef;
    --text-2:        #a49daa;
    --accent:        #a98bf5;
    --accent-2:      #bda3ff;
    --accent-wash:   rgba(169, 139, 245, 0.16);
  }
}

/* ---------- Base ---------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  background: var(--bg);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.9375rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------- Full-screen single column ------------------------------------- */

.screen {
  min-height: 100vh;
  min-height: 100svh;           /* honours mobile browser chrome where supported */
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 3rem 1.5rem;
}

@media (max-width: 24rem) {
  .screen { padding: 2.5rem 1.25rem; }
}

/* ---------- Type ---------------------------------------------------------- */

.hero {
  font-size: clamp(1.5rem, 6vw, 2.125rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.2;
  margin: 0 0 1rem;
  color: var(--text);
}

.lede {
  color: var(--text-2);
  margin: 0 0 2rem;
  max-width: 46ch;
  text-wrap: pretty;
}

.contacts {
  display: flex;
  gap: 0.35rem 0.45rem;
  flex-wrap: wrap;
  margin: 0 0 0 -0.6em;
}

/* Hover is a tinted block behind the mark and the label together. An underline
   cannot work here: on the <a> it spans the whole flex row and runs under the
   icon, and on the label alone it detaches across the gap. The block has no
   such alignment to get wrong.

   The padding below is why `.contacts` carries a negative left margin and a
   tightened gap: without them the first link's box would overhang the text
   column, and the padding would add itself to the space between links. */
.contacts a {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  border-bottom: none;
  /* line-height 1 so the block hugs the text: the body's 1.7 would add half a
     line above and below, making the wash far taller than it is wide. */
  line-height: 1;
  padding: 0.42em 0.6em;
  border-radius: var(--radius);
  transition: color 120ms ease;
  /* isolate() so the ::before below, at z-index -1, stays behind the mark and
     label but in front of the page rather than dropping out of sight. */
  position: relative;
  isolation: isolate;
}

/* The wash is a pseudo-element, not a background on the link, so it can scale.
   It rests slightly undersized and hidden behind the content, then grows out to
   the full padded box — after a short beat, so a pointer crossing the row on its
   way somewhere else does not set off four of them. */
.contacts a::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: var(--radius);
  background: var(--accent-wash);
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 200ms ease, transform 300ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

.contacts a:hover::before {
  opacity: 1;
  transform: scale(1);
  transition-delay: 110ms;
}

.contacts a:focus-visible {
  outline-offset: 1px;
  border-radius: var(--radius);
}

/* `currentColor` keeps the mark in step with the link's hover and focus
   colours without a single inline style. */
.icon {
  width: 1em;
  height: 1em;
  flex: none;
  fill: currentColor;
}

/* ---------- Links --------------------------------------------------------- */

a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 120ms ease, color 120ms ease;
}

a:hover {
  color: var(--accent-2);
  border-bottom-color: currentColor;
}

a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  a { transition: none; }

  /* No growth, no delay: the wash simply is or is not there. */
  .contacts a::before,
  .contacts a:hover::before {
    transition: none;
    transform: none;
    transition-delay: 0s;
  }
}
