/* Layout and components for the public site. Hand-written: adoi-min.css is a prebuilt Tailwind
   file that only contains the classes the old templates used, so it's kept just for .prose. */

:root {
  --bg: #fbfaf7;
  --surface: #ffffff;
  --text: #1c1f24;
  --muted: #5d6470;
  --border: #e8e3da;
  --accent: #c81e1e;
  --accent-strong: #9a1414;
  --accent-soft: rgba(200, 30, 30, 0.08);
  --shadow: 0 1px 2px rgba(28, 31, 36, 0.04), 0 10px 30px -12px rgba(28, 31, 36, 0.18);
  --radius: 16px;
  /* The system font stack from the original Tailwind build (adoi-min.css), for headings too. */
  --font-body: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  --font-display: var(--font-body);
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f172a;
    --surface: #152036;
    --text: #e5e7eb;
    --muted: #9ca3af;
    --border: #253250;
    --accent: #f87171;
    --accent-strong: #fca5a5;
    --accent-soft: rgba(248, 113, 113, 0.12);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 30px -12px rgba(0, 0, 0, 0.6);
  }
}

/* Base */

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

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.6;
}

a {
  color: var(--accent);
}

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

.container {
  width: 100%;
  max-width: 48rem;
  margin: 0 auto;
  padding: 0 1rem;
  box-sizing: border-box;
}

/* Header, footer and the home page: wide enough for the featured post to fill the screen. */
.container-wide {
  max-width: 74rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: 1rem;
  top: -3rem;
  z-index: 20;
  padding: 0.5rem 0.875rem;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
}

.skip-link:focus {
  top: 0.75rem;
}

/* Header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
}

/* Three columns with equal outer ones, so the logo and name sit at the true centre whatever the
   nav on the right holds. */
.site-header-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  min-height: 3.75rem;
}

.site-header-inner .brand {
  grid-column: 2;
}

.site-header-inner .site-nav {
  grid-column: 3;
  justify-self: end;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--text);
  text-decoration: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

/* The brain gives a little shiver every few seconds, and a proper twist when hovered. */
.brand-icon {
  flex: none;
  color: var(--accent);
  animation: brain-wobble 6s ease-in-out infinite;
}

.brand:hover .brand-icon {
  animation: brain-twist 0.7s var(--ease-out);
}

@keyframes brain-wobble {
  0%, 82%, 100% { transform: rotate(0); }
  86% { transform: rotate(-8deg); }
  90% { transform: rotate(7deg); }
  94% { transform: rotate(-4deg); }
}

@keyframes brain-twist {
  0% { transform: rotate(0) scale(1); }
  45% { transform: rotate(-20deg) scale(1.18); }
  100% { transform: rotate(0) scale(1); }
}

.site-nav {
  display: flex;
  gap: 0.25rem;
}

.site-nav a {
  padding: 0.375rem 0.75rem;
  border-radius: 999px;
  color: var(--muted);
  font-weight: 500;
  font-size: 0.9375rem;
  text-decoration: none;
  transition: color 0.2s, background-color 0.2s;
}

.site-nav a:hover {
  color: var(--text);
  background: var(--accent-soft);
}

.site-nav a[aria-current="page"] {
  color: var(--accent);
  background: var(--accent-soft);
}

@media (max-width: 420px) {
  .brand-name {
    font-size: 1rem;
  }
}

/* Main */

.site-main {
  flex: 1;
  padding-bottom: 4rem;
}

.flash {
  margin: 1.5rem 0 0;
  padding: 0.75rem 1rem;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
}

.flash-error {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-weight: 500;
}

/* Feed */

.feed-heading {
  margin: 3rem 0 1rem;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.feed-list {
  display: grid;
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.feed-item.is-new {
  animation: card-in 0.5s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms);
}

@keyframes card-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

.feed-empty {
  padding: 3rem 0;
  text-align: center;
  color: var(--muted);
}

.feed-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  margin-top: 2.5rem;
}

.load-more {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 1.25rem;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border));
  border-radius: 999px;
  background: var(--surface);
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s, transform 0.2s var(--ease-out);
}

.load-more:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}

.load-more:active {
  transform: scale(0.97);
}

.load-more-spinner {
  display: none;
  width: 1rem;
  height: 1rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.load-more[aria-busy="true"] {
  pointer-events: none;
  opacity: 0.8;
}

.load-more[aria-busy="true"] .load-more-spinner {
  display: inline-block;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.feed-end {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  color: var(--muted);
  font-size: 0.9375rem;
}

.feed-end svg {
  color: var(--accent);
}

.feed-back {
  font-size: 0.9375rem;
}

/* Back to top (any page long enough to need it) */

.back-to-top-marker {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 150vh;
  pointer-events: none;
}

/* A zero-height strip just above the footer. Sticky to the bottom of the window, so the button
   floats there while the footer is off screen, then stops above the footer instead of covering it. */
.back-to-top-dock {
  position: sticky;
  bottom: 0;
  z-index: 15;
  height: 0;
}

.back-to-top {
  position: absolute;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1.25rem, env(safe-area-inset-bottom));
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.625rem 1rem 0.625rem 0.875rem;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow);
  color: var(--accent);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
  /* Hidden (and out of the tab order) until the reader has scrolled down. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(16px) scale(0.92);
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out), visibility 0s linear 0.3s,
              background-color 0.2s, border-color 0.2s;
}

.back-to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out), visibility 0s,
              background-color 0.2s, border-color 0.2s;
}

.back-to-top:hover {
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
  border-color: var(--accent);
}

.back-to-top:hover svg,
.back-to-top:focus-visible svg {
  animation: arrow-rise 1.1s var(--ease-out) 0.1s infinite;
}

@keyframes arrow-rise {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

/* Post card */

.post-card {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out), border-color 0.3s;
}

.post-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}

.post-card:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.post-card-media {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--accent-soft);
}

.post-card-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease-out);
}

.post-card:hover .post-card-media img {
  transform: scale(1.04);
}

.post-card-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  min-width: 0;
  padding: 1.25rem 1.375rem 1.375rem;
}

.post-card-badge {
  padding: 0.125rem 0.625rem;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

@media (prefers-color-scheme: dark) {
  .post-card-badge {
    color: #0f172a;
  }
}

.post-card-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.post-card-title a {
  color: var(--text);
  text-decoration: none;
  transition: color 0.2s;
}

/* Stretch the title link over the whole card. */
.post-card-title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.post-card-title a:focus-visible {
  outline: none;
}

.post-card:hover .post-card-title a {
  color: var(--accent);
}

.post-card-date {
  margin: 0;
  color: var(--muted);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.post-card-summary {
  margin: 0.125rem 0 0;
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Image beside the text on wider screens, except for the featured post. */
@media (min-width: 40rem) {
  .post-card:not(.post-card--featured):not(.post-card--no-image) {
    grid-template-columns: 13rem 1fr;
  }

  .post-card:not(.post-card--featured) .post-card-media {
    aspect-ratio: auto;
    min-height: 100%;
  }
}

/* The featured (latest) post fills the first screen: the card is the height of the viewport
   below the header, and its image takes whatever the title and summary leave. */
.post-card--featured {
  display: flex;
  flex-direction: column;
  margin-top: 1.5rem;
  /* Capped, so very tall (portrait) screens don't get a giant image. */
  min-height: min(calc(100vh - 3.75rem - 3rem), 70rem);
  min-height: min(calc(100svh - 3.75rem - 3rem), 70rem);
}

.post-card--featured .post-card-media {
  position: relative;
  flex: 1 1 auto;
  aspect-ratio: auto;
  min-height: 16rem;
}

.post-card--featured .post-card-media img {
  position: absolute;
  inset: 0;
}

.post-card--featured .post-card-body {
  padding: 1.5rem 1.75rem 1.75rem;
}

.post-card--featured .post-card-title {
  font-size: clamp(1.625rem, 4.5vw, 2.5rem);
  max-width: 52rem;
}

.post-card--featured .post-card-summary {
  -webkit-line-clamp: unset;
  max-width: 52rem;
  font-size: 1.0625rem;
}

@media (min-width: 64rem) {
  .post-card--featured .post-card-body {
    padding: 1.75rem 2.25rem 2.25rem;
  }
}

/* On wide but short screens (most laptops), stacking would crop the image to a thin strip, so put
   it beside the text instead. */
@media (min-width: 60rem) and (max-height: 60rem) {
  .post-card--featured {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  }

  .post-card--featured .post-card-media {
    min-height: 0;
  }

  .post-card--featured .post-card-body {
    justify-content: center;
    padding: 2.25rem 2.5rem;
  }

  .post-card--featured .post-card-title {
    font-size: clamp(1.75rem, 2.6vw, 2.375rem);
  }
}

/* On the wide home page, everything after the featured post keeps to reading width. */
.container-wide .feed-heading,
.container-wide .feed-list,
.container-wide .feed-empty,
.container-wide .feed-footer {
  max-width: 46rem;
  margin-left: auto;
  margin-right: auto;
}

/* "Read more": the underline sweeps in and the arrow nudges forward while the card is hovered. */

.read-more {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.375rem;
  padding-bottom: 2px;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
}

.read-more::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s var(--ease-out);
}

.read-more svg {
  transition: transform 0.35s var(--ease-out);
}

.post-card:hover .read-more,
.post-card:focus-within .read-more {
  color: var(--accent-strong);
}

.post-card:hover .read-more::after,
.post-card:focus-within .read-more::after {
  transform: scaleX(1);
}

.post-card:hover .read-more svg,
.post-card:focus-within .read-more svg {
  animation: arrow-nudge 1.1s var(--ease-out) 0.15s infinite;
}

@keyframes arrow-nudge {
  0%, 100% { transform: translateX(3px); }
  50% { transform: translateX(8px); }
}

/* Article (post, about, 404) */

.article {
  padding-top: 2rem;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--muted);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.2s;
}

.back-link svg {
  transition: transform 0.3s var(--ease-out);
}

.back-link:hover {
  color: var(--accent);
}

.back-link:hover svg {
  transform: translateX(-4px);
}

.article-header {
  margin: 1.5rem 0 2rem;
}

.article-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2rem, 6vw, 2.875rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--text);
  overflow-wrap: anywhere;
}

.article-meta {
  margin: 0.75rem 0 0;
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.article-image {
  margin: 0 0 2.25rem;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--accent-soft);
}

.article-image img {
  display: block;
  width: 100%;
  height: auto;
}

.article-body {
  --tw-prose-body: var(--text);
  --tw-prose-headings: var(--text);
  --tw-prose-bold: var(--text);
  --tw-prose-links: var(--accent);
}

.article-body :where(h1, h2, h3, h4) {
  font-family: var(--font-display);
  letter-spacing: -0.01em;
}

.article-body a {
  color: var(--accent);
}

/* 404 */

.not-found-code {
  margin: 0 0 0.25rem;
  font-family: var(--font-display);
  font-size: 4.5rem;
  font-weight: 700;
  line-height: 1;
  color: var(--accent);
}

.typewriter {
  width: 100%;
  box-sizing: border-box;
  min-height: 12rem;
  padding: 1rem 1.125rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: 0.9375rem/1.7 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  resize: none;
}

/* Footer */

.site-footer {
  border-top: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font-size: 0.875rem;
}

.site-footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  padding-top: 1.75rem;
  padding-bottom: 1.75rem;
}

.site-footer-disclaimer {
  flex: 1 1 22rem;
  margin: 0;
  line-height: 1.55;
}

.site-footer-disclaimer strong {
  color: var(--text);
  font-weight: 600;
}

.site-footer-disclaimer a {
  font-weight: 600;
  white-space: nowrap;
}

.site-footer-meta {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.4rem;
  margin: 0;
}

.site-footer-name {
  white-space: nowrap;
}

.site-footer-tagline {
  margin-left: 0.35rem;
  padding-left: 0.75rem;
  border-left: 1px solid var(--border);
  font-style: italic;
  white-space: nowrap;
}

.site-footer-meta svg {
  color: var(--accent);
}

/* Motion */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .post-card:hover {
    transform: none;
  }
}
