/* Wickfall — the whole stylesheet. Pure black and white, light on dark.
   There is no light mode by design. */

@font-face {
  font-family: 'Philosopher';
  /* Subset to the glyphs actually used — the wordmark is inlined SVG, so this
     font only ever sets a handful of short lines. See production/README.md for
     the pyftsubset command; it comes out around 6 KB, not 110. */
  src: url('/fonts/philosopher-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Philosopher';
  src: url('/fonts/philosopher-italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

:root {
  --ink: #ffffff;          /* brand white */
  --paper: #000000;        /* brand black */
  --warm: #f2efe9;         /* warm off-white, body text and links */
  --quiet: #a8a5a0;        /* secondary copy — 9.0:1 on black */
  --faint: #8c8983;        /* labels and small print — 5.9:1 on black */
  --hair: rgba(255, 255, 255, 0.16);
  --candlelight: 255, 243, 222;
  --display: 'Philosopher', Georgia, 'Times New Roman', serif;
  --text: ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
}

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

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--warm);
  font-family: var(--text);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: var(--warm); text-decoration-color: rgba(242, 239, 233, 0.38); text-underline-offset: 0.28em; text-decoration-thickness: 1px; }
a:hover { color: var(--ink); text-decoration-color: var(--ink); }

/* Visible against black, offset clear of the glyphs. */
a:focus-visible, button:focus-visible, input:focus-visible {
  outline: 2px solid #f5e9cf;
  outline-offset: 4px;
  border-radius: 1px;
}

::selection { background: #f5e9cf; color: var(--paper); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── the holding page ─────────────────────────────────────────────────── */

.page {
  min-height: 100svh;
  display: grid;
  grid-template-rows: 1fr auto;
  align-items: center;
  justify-items: center;
}

/* The stack has to read as deliberate with and without the signup block, so
   nothing here is balanced around it — it is one more step in the rhythm. */
.hearth {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 72px 24px 40px;
  width: 100%;
  max-width: 920px;
}

/* The trailing `100%` matters: without it the 280px floor plus .hearth's 48px of
   padding forces a 328px minimum, which overflows a 320px viewport. body has
   overflow-x:hidden, so that overflow would be silently clipped rather than
   scrollable — a WCAG 1.4.10 reflow failure hidden in plain sight. */
.mark { position: relative; width: min(clamp(280px, 50vw, 560px), 100%); }
.mark svg, .mark img { display: block; width: 100%; height: auto; position: relative; }
.mark--small { width: min(clamp(220px, 34vw, 360px), 100%); }

/* Warmth around the flame. Light, not atmosphere. */
.mark__glowpos {
  position: absolute; left: 43.8%; top: 25.6%;
  width: 105%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.mark__glow {
  width: 100%; height: 100%; border-radius: 50%;
  background: radial-gradient(circle,
    rgba(var(--candlelight), 0.34) 0%,
    rgba(255, 236, 203, 0.13) 32%,
    rgba(255, 232, 196, 0.045) 52%,
    rgba(255, 232, 196, 0) 72%);
  /* Lit by default, so the candle still has its warmth with JavaScript off.
     The build hides it again via .wf-build below, then animates it up. */
  opacity: 0.42;
  will-change: opacity, transform;
}
.mark__glow--lit { opacity: 0.42; }

#wf-flame { transform-box: fill-box; transform-origin: 50% 100%; }

/* ── pre-build state ──────────────────────────────────────────────────────
   intro.js adds .wf-build to <html> synchronously from <head>, before the body
   is parsed, and removes it the moment the animations are attached. Without
   this the finished wordmark can paint for a frame before the build starts.
   Listed explicitly rather than as `#wf-mark > g` because #wf-candle is a group
   the build never touches — its two children are animated individually, and
   hiding the parent would keep them invisible.                              */
.wf-build #wf-flourish,
.wf-build #wf-w,
.wf-build #wf-i,
.wf-build #wf-c,
.wf-build #wf-k,
.wf-build #wf-f,
.wf-build #wf-a,
.wf-build #wf-l,
.wf-build #wf-ribbon,
.wf-build #wf-spark-l,
.wf-build #wf-spark-r,
.wf-build #wf-flame,
.wf-build #wf-candle-body,
.wf-build .mark__glow,
.wf-build [data-stagger] { opacity: 0; }

.wf-build #wf-rule { opacity: 0; transform: scaleX(0); }

/* Draws outward from the candle, not from the middle. */
.rule {
  width: min(clamp(280px, 50vw, 560px), 100%);
  height: 1px;
  margin-top: 38px;
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%, rgba(255,255,255,.22) 18%,
    rgba(255,255,255,.22) 82%, rgba(255,255,255,0) 100%);
  transform-origin: 43.8% 50%;
}

.tagline {
  font-family: var(--display);
  font-size: clamp(1.2rem, 2.4vw, 1.6rem);
  line-height: 1.45;
  letter-spacing: 0.012em;
  margin: 30px 0 0;
  /* Wide enough to keep the tagline on one line. 34rem (544px) is sized to the
     Georgia fallback, which needs 508px at the 25.6px cap — Philosopher itself
     only needs 482px. Sizing to the wider of the two means the line does not
     re-wrap when the webfont swaps in. Below roughly a 410px viewport it wraps
     to two lines, which is correct on a phone. */
  width: min(34rem, 100%);
  text-wrap: pretty;
}

.lede {
  font-size: 0.95rem;
  line-height: 1.75;
  color: var(--quiet);
  margin: 22px 0 0;
  width: min(33rem, 100%);
  text-wrap: pretty;
}

.label { display: flex; align-items: center; gap: 16px; margin-top: 64px; }
.label__rule { height: 1px; width: 44px; background: var(--hair); }
/* An <h2>, so the section is in the heading outline — hence the margin and
   font-weight reset. */
.label__text {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 400;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--faint);
  white-space: nowrap;
}

.elsewhere { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px 28px; margin-top: 22px; }
.elsewhere a {
  font-family: var(--display);
  font-size: 1.0625rem;
  letter-spacing: 0.03em;
  text-decoration: none;
  border-bottom: 1px solid rgba(242, 239, 233, 0.3);
  padding-bottom: 3px;
}
.elsewhere a:hover { border-bottom-color: var(--ink); }

.press { font-size: 0.9375rem; line-height: 1.7; color: var(--quiet); margin: 30px 0 0; width: min(36rem, 100%); text-wrap: pretty; }

.foot { width: 100%; max-width: 920px; padding: 0 24px 34px; }
.foot__inner {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding-top: 20px;
  display: flex; justify-content: center; align-items: center; gap: 10px;
  font-size: 0.75rem; letter-spacing: 0.06em; color: var(--faint);
}
.foot__inner a { color: var(--faint); text-decoration: none; border-bottom: 1px solid rgba(140, 137, 131, 0.5); padding-bottom: 2px; }
.foot__inner a:hover { color: var(--warm); border-bottom-color: var(--warm); }

/* ── mailing list (behind MAILING_LIST_ENABLED) ───────────────────────── */

.signup { width: 100%; max-width: 432px; margin-top: 60px; display: flex; flex-direction: column; align-items: center; }
.signup .label { margin-top: 0; }
.signup__form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; width: 100%; justify-content: center; }
.signup__note { font-size: 0.8125rem; color: var(--faint); margin: 16px 0 0; }
.signup__note a { color: var(--faint); text-decoration-color: rgba(140, 137, 131, 0.5); }
.signup__note a:hover { color: var(--warm); }
.signup__form input {
  flex: 1 1 200px; min-width: 0;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.26);
  color: var(--warm);
  font: inherit; font-size: 0.9375rem;
  padding: 13px 15px; border-radius: 2px;
}
.signup__form input::placeholder { color: var(--faint); }
.signup__form button {
  flex: 0 0 auto;
  background: var(--warm); border: 1px solid var(--warm); color: var(--paper);
  font-family: var(--display); font-size: 0.9375rem; letter-spacing: 0.02em;
  padding: 13px 22px; border-radius: 2px; cursor: pointer;
  min-height: 46px; white-space: nowrap;
}
.signup__form button:hover { background: var(--ink); border-color: var(--ink); }

/* ── welcome / 404 ────────────────────────────────────────────────────── */

.centred { min-height: 100svh; display: grid; place-items: center; padding: 48px 24px; }
.centred > * { display: flex; flex-direction: column; align-items: center; text-align: center; }
.centred { grid-auto-flow: row; }
.centred > .mark, .centred > p, .centred > a { justify-self: center; }
.say { font-family: var(--display); font-size: clamp(1.3rem, 2.6vw, 1.7rem); line-height: 1.45; margin: 44px 0 0; max-width: 28ch; text-wrap: pretty; text-align: center; }
.say--lone { margin: 0; max-width: 24ch; font-size: clamp(1.35rem, 3vw, 1.9rem); }
.say__small { font-size: 0.875rem; line-height: 1.7; color: var(--faint); margin: 26px 0 0; max-width: 36ch; text-wrap: pretty; text-align: center; }
.doorway {
  font-family: var(--display); font-size: 1rem; letter-spacing: 0.03em;
  margin-top: 40px; text-decoration: none;
  border-bottom: 1px solid rgba(242, 239, 233, 0.3); padding-bottom: 3px;
}
.doorway--italic { font-style: italic; font-size: 1.0625rem; margin-top: 32px; }
.doorway:hover { border-bottom-color: var(--ink); }

/* ── privacy ──────────────────────────────────────────────────────────── */

.prose { min-height: 100svh; display: flex; flex-direction: column; align-items: center; padding: 56px 24px 0; }
.prose > * { width: 100%; max-width: 68ch; }
.prose__head { display: flex; justify-content: center; }
.prose__mark { display: block; width: 236px; max-width: 64%; }
.prose__mark img { display: block; width: 100%; height: auto; }
.prose__body { font-size: 1rem; line-height: 1.75; color: #c8c5bf; }
.prose__body h1 { font-family: var(--display); font-weight: 400; font-size: clamp(1.9rem, 4vw, 2.6rem); line-height: 1.15; color: var(--warm); margin: 38px 0 0; }
.prose__body h1 + p em { font-family: var(--display); font-size: 0.9375rem; color: var(--faint); font-style: italic; }
.prose__body h2 { font-family: var(--display); font-weight: 400; font-size: 1.375rem; color: var(--warm); margin: 44px 0 14px; letter-spacing: 0.01em; }
.prose__body p { margin: 0 0 18px; text-wrap: pretty; }
.prose__body strong { color: var(--warm); font-weight: 600; }
.prose__body ul { margin: 0 0 22px; padding-left: 1.25em; display: flex; flex-direction: column; gap: 7px; }
.prose__body table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; margin: 0 0 22px; }
.prose__body th { text-align: left; font-weight: 600; color: var(--warm); padding: 0 16px 10px 0; border-bottom: 1px solid var(--hair); }
.prose__body td { padding: 14px 16px 14px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.08); vertical-align: top; }
.prose__body th:last-child, .prose__body td:last-child { padding-right: 0; }
.prose__foot {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  margin-top: 64px; padding: 20px 0 40px;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  font-size: 0.75rem; letter-spacing: 0.06em; color: var(--faint);
}
.prose__foot a { color: var(--faint); text-decoration: none; border-bottom: 1px solid rgba(140, 137, 131, 0.5); padding-bottom: 2px; }
.prose__foot a:hover { color: var(--warm); border-bottom-color: var(--warm); }

/* ── hit areas ────────────────────────────────────────────────────────────
   Every link here is small text: the footer "Privacy" link measures 42×19 and
   the email link 21px tall, against the 24×24 that WCAG 2.2 SC 2.5.8 asks for.
   They technically pass under the spacing exception — nothing sits close enough
   to mis-tap — but they are still fiddly targets on a phone. This expands the
   clickable region with a pseudo-element, so the hit area grows without moving
   a single pixel of the design.                                              */
.elsewhere a, .press a, .foot__inner a, .prose__foot a, .doorway,
.signup__note a { position: relative; }
.elsewhere a::after, .press a::after, .foot__inner a::after,
.prose__foot a::after, .doorway::after, .signup__note a::after {
  content: '';
  position: absolute;
  inset: -8px -6px;
}

/* ── forced colours (Windows High Contrast) ───────────────────────────────
   The wordmark is white artwork on transparent. Forced-colours mode repaints
   backgrounds and text but leaves SVG fills alone, so on a light high-contrast
   theme the mark would vanish against its own background. The inlined SVG can
   take the system text colour; the two <img> copies are a separate document CSS
   cannot reach into, so they keep an explicit dark backdrop instead.          */
@media (forced-colors: active) {
  #wf-mark { fill: CanvasText; }
  .mark__glow { display: none; }
  .prose__mark, .mark--small {
    background: #000;
    forced-color-adjust: none;
    padding: 6px;
  }
}

/* ── motion ───────────────────────────────────────────────────────────── */

@keyframes wf-flicker {
  0%, 100% { transform: scale(1) translateY(0); opacity: 1; }
  18% { transform: scale(1.035, 0.985) translateY(0.4px); opacity: 0.94; }
  37% { transform: scale(0.985, 1.05) translateY(-0.6px); opacity: 1; }
  55% { transform: scale(1.02, 0.99) translateY(0.2px); opacity: 0.97; }
  74% { transform: scale(0.995, 1.025) translateY(-0.3px); opacity: 1; }
}
@keyframes wf-breathe {
  0%, 100% { opacity: 0.40; transform: scale(1); }
  50% { opacity: 0.52; transform: scale(1.045); }
}
@keyframes wf-twinkle {
  0%, 84%, 100% { opacity: 0.82; }
  90% { opacity: 1; }
  94% { opacity: 0.62; }
}

/* A designed still, not the page with the motion switched off: everything in
   place, the candle lit, the warmth around the flame held at a fixed value.
   intro.js checks the same query and skips the build entirely. */
@media (prefers-reduced-motion: reduce) {
  .mark__glow { opacity: 0.42; }
  #wf-flame, .mark__glow, #wf-spark-l, #wf-spark-r { animation: none !important; }
  * { transition: none !important; }
}
