/* Newsreader (SIL Open Font License), Latin subset, self-hosted. One variable
   file covers every weight the site uses, so no request goes to Google. */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("./fonts/newsreader-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light dark;

  --background: #fafafa;
  --foreground: #171717;
  --muted: #858585;
  --selection: rgb(23 23 23 / 12%);
  /* The only colour on the site — the flowers. */
  --bloom-deep: #5b2a86;
  --bloom: #8248b8;
  --bloom-pale: #b48ad9;
  --stem: #3f8f4a;

  --measure: 36rem;
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --background: #0a0a0a;
    --foreground: #ededed;
    --muted: #b8b8b8;
    --selection: rgb(255 255 255 / 16%);
    --bloom-deep: #9a62d6;
    --bloom: #b383e6;
    --bloom-pale: #d4b4f5;
    --stem: #5fbf6a;
  }
}

* { box-sizing: border-box; }

html { background: var(--background); overscroll-behavior-y: none; }

body {
  min-width: 320px;
  min-height: 100svh;
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.45;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--selection); }

main {
  position: relative;
  z-index: 1;
  width: min(100%, var(--measure));
  margin: 0 auto;
  padding: 3rem 1rem;
}

a {
  color: var(--muted);
  text-decoration-color: currentColor;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: color 140ms ease;
}
a:hover { color: var(--foreground); }
a:focus-visible { color: var(--foreground); border-radius: 2px; outline: 2px solid var(--foreground); outline-offset: 3px; }

.identity {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.75rem;
  row-gap: 0.6rem;
}

h1 {
  flex: none;
  margin: 0;
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: -0.015em;
}

nav { display: flex; flex: 1 0 auto; gap: 0.45rem; min-width: max-content; }
nav a { flex: none; font-size: 0.88rem; }
nav a:first-child { margin-left: auto; }

.about { margin-top: 2.5rem; }

ul {
  display: grid;
  gap: 0.42rem;
  margin: 0;
  padding: 0;
  color: var(--muted);
  font-size: 0.98rem;
  list-style: none;
}
li { display: grid; grid-template-columns: 0.8rem minmax(0, 1fr); }
li::before { content: "\2022"; }

/* Flower garden — decorative ASCII animation, drawn by flowers.js. Sits in
   the bottom half of the viewport, behind the copy. */
.garden {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 70vh;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.garden pre {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.1;
  white-space: pre;
  user-select: none;
  /* Only used to measure glyph metrics; flowers.js paints to a canvas. */
  visibility: hidden;
  position: absolute;
}

.garden i { font-style: normal; }
.garden .s { color: var(--stem); opacity: 0.65; }
.garden .d { color: var(--bloom-deep); opacity: 0.85; }
.garden .m { color: var(--bloom); opacity: 0.75; }
.garden .p { color: var(--bloom-pale); opacity: 0.8; }
/* Back flower: same hues, pushed further into the distance. */
.garden .bs { color: var(--stem); opacity: 0.3; }
.garden .bd { color: var(--bloom-deep); opacity: 0.42; }
.garden .bm { color: var(--bloom); opacity: 0.34; }
.garden .bp { color: var(--bloom-pale); opacity: 0.38; }

@media (max-width: 22rem) {
  nav { flex-basis: 100%; }
  nav a:first-child { margin-left: 0; }
}

@media (min-width: 40rem) {
  main { padding: 4rem 1.5rem; }
  .identity { column-gap: 1.5rem; }
  nav { gap: 0.6rem; }
}

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

/* Intro — the mark draws itself, holds, then recedes into the distance as the
   veil fades to reveal the page. Pure CSS; one 1.7s timeline shared by both. */
.intro {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  background: var(--background);
  pointer-events: none;
  animation: intro-veil 1.7s ease-in-out forwards;
}

.intro-mark {
  width: min(46vmin, 340px);
  height: auto;
  fill: none;
  stroke: var(--foreground);
  stroke-width: 5.5;
  stroke-linecap: round;
  animation: intro-recede 1.7s cubic-bezier(0.55, 0, 0.25, 1) forwards;
}

.intro-mark path {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  animation: intro-draw 0.5s ease-out forwards;
}
.intro-mark path:nth-child(2) { animation-delay: 0.07s; }
.intro-mark path:nth-child(3) { animation-delay: 0.14s; }
.intro-mark path:nth-child(4) { animation-delay: 0.21s; }

@keyframes intro-draw {
  to { stroke-dashoffset: 0; }
}

@keyframes intro-recede {
  0%, 50% { transform: perspective(700px) translateZ(0); opacity: 1; }
  100% { transform: perspective(700px) translateZ(-1300px); opacity: 0; }
}

@keyframes intro-veil {
  0%, 50% { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  .intro { display: none; }
}

/* Brand mark — the logo sits to the left of the name and fades in as the
   intro clears. Inline, so it behaves on narrow screens too. */
.brand {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.6rem;
}

.mark {
  display: block;
  flex: none;
  width: 1.5rem;
  color: var(--foreground);
  opacity: 0;
  animation: mark-in 0.45s ease-out 1.35s forwards;
}

.mark svg {
  display: block;
  width: 100%;
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 9;
  stroke-linecap: round;
}

@keyframes mark-in {
  from { opacity: 0; transform: scale(0.8); }
  to { opacity: 0.9; transform: scale(1); }
}

.mark:hover { opacity: 1; }

/* Wide screens: the logo stays pinned to the top-left corner of the window,
   out of the name's row. Phones keep it inline, to the left of the name. */
@media (min-width: 40rem) {
  .mark {
    position: fixed;
    top: 1.75rem;
    left: 1.75rem;
    z-index: 2;
    width: 1.9rem;
  }

  .mark svg { stroke-width: 8; }
}

@media (prefers-reduced-motion: reduce) {
  .mark { animation: none; opacity: 0.9; }
}
