/* ============================================================================
   josephpuls.com
   One stylesheet, one typeface. Every colour, size, and gap is a token below.
   ========================================================================= */

:root {
  /* ── Colour ───────────────────────────────────────────────────────────
     Taken from the Clay Mathematics Institute's own palette: deep navy ink
     (#051c2c), a strong blue (#164194), an orange accent (#f39200), and a
     flat tint for alternating bands (#f2f2f2). Warmed slightly here so the
     page reads as paper rather than screen.                               */
  --paper:    #fdfcfa;
  --tint:     #f1efe8;   /* alternating band background */
  --navy:     #071a27;   /* dark band + footer */

  --ink:      #0a1f2d;   /* headings */
  --ink-2:    #344654;   /* body copy — dark enough to hold its own */
  --ink-3:    #6d7d88;   /* captions, notes */
  --rule:     #c9d1d6;   /* visible hairline, not a whisper */
  --rule-soft:#dfe4e6;

  --blue:     #164194;
  --blue-dk:  #0f2d68;
  --blue-lt:  #a8c4f0;   /* links on the dark band */
  --ochre:    #c2760a;

  /* Figure strokes. Deliberately not grey and not 1px — this is the fix for
     the thin, washed-out geometry. Raise --fig-w to 2.5 if you want it
     heavier still; every figure on the page reads from these two values. */
  --fig:      #2b4356;
  --fig-w:    2;

  /* ── Type ─────────────────────────────────────────────────────────────
     A single family throughout, as asked. Newsreader is the closest freely
     licensed relative of Clay's kepler-std — a text-optimised serif with a
     true optical-size axis. `kepler-std` sits first in the stack, so adding
     a Typekit kit to index.html swaps in the real thing with no other
     change.                                                              */
  --serif: "kepler-std", "Kepler Std", "Newsreader", Georgia,
           "Times New Roman", serif;

  --t-hero:  clamp(2.1rem, 4.4vw, 3.4rem);
  --t-h2:    clamp(1.75rem, 3.2vw, 2.5rem);
  --t-h3:    clamp(1.25rem, 1.9vw, 1.4375rem);
  --t-quote: clamp(1.25rem, 2.1vw, 1.5rem);
  --t-lead:  clamp(1.1875rem, 1.7vw, 1.375rem);
  --t-body:  clamp(1.0625rem, 1.1vw, 1.125rem);
  --t-small: 0.8125rem;

  /* ── Space ────────────────────────────────────────────────────────────
     Geometric scale, ratio ≈ 1.5, seven steps. Every gap on the page is one
     of these values; that repetition is what reads as deliberate.         */
  --s-1: 0.5rem;
  --s-2: 0.75rem;
  --s-3: 1.25rem;
  --s-4: 2rem;
  --s-5: 3.25rem;
  --s-6: 5.25rem;
  --s-7: 8.5rem;

  --gutter:  clamp(1.5rem, 5.5vw, 4.5rem);
  --shell:   76rem;
  --measure: 36rem;   /* ≈ 68 characters */
}

/* ── Reset ───────────────────────────────────────────────────────────── */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--serif);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.68;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ul, dl, dt, dd, blockquote, figure { margin: 0; }
ul { padding: 0; list-style: none; }
dd { margin-inline: 0; }
a { color: inherit; }

::selection { background: #dbe4f5; }

/* ── Shell ───────────────────────────────────────────────────────────── */

.shell {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: var(--gutter);
  top: var(--s-2);
  z-index: 10;
  padding: var(--s-1) var(--s-2);
  background: var(--paper);
  outline: 2px solid var(--blue);
}

/* ── Masthead ────────────────────────────────────────────────────────── */

.masthead {
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--rule);
}

.masthead__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  align-items: baseline;
  justify-content: space-between;
}

/* The only place the name appears. */
.wordmark {
  font-size: 1.3125rem;
  font-weight: 500;
  letter-spacing: 0.005em;
  text-decoration: none;
  color: var(--ink);
}

.nav { display: flex; flex-wrap: wrap; gap: var(--s-3); }

.nav a {
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-3);
  padding-bottom: 2px;
  border-bottom: 1.5px solid transparent;
  transition: color 160ms ease, border-color 160ms ease;
}
.nav a:hover { color: var(--blue); border-bottom-color: var(--blue); }

/* ── Hero ────────────────────────────────────────────────────────────── */

.hero { padding-block: var(--s-6) var(--s-7); }

.hero__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-6);
}

.hero__text { max-width: 34rem; }

h1 {
  font-size: var(--t-hero);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-wrap: balance;
}

.hero__range {
  margin-top: var(--s-3);
  font-size: var(--t-lead);
  font-style: italic;
  font-weight: 300;
  color: var(--ink-3);
}

/* The quote is set off by a blue rule rather than quotation marks. */
.quote {
  margin-top: var(--s-5);
  padding-left: var(--s-3);
  border-left: 3px solid var(--blue);
}

.quote blockquote {
  font-size: var(--t-quote);
  font-style: italic;
  font-weight: 300;
  line-height: 1.45;
  color: var(--ink);
}

.quote figcaption {
  margin-top: var(--s-2);
  font-size: var(--t-small);
  font-style: normal;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.hero__line {
  margin-top: var(--s-4);
  max-width: 30rem;
  font-size: var(--t-lead);
  color: var(--ink-2);
}

/* ── Actions ─────────────────────────────────────────────────────────── */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  margin-top: var(--s-5);
}

.action {
  text-decoration: none;
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--rule);
  transition: color 180ms ease, border-color 180ms ease;
}
.action:hover { color: var(--ink); border-bottom-color: var(--ink); }

.action--primary { color: var(--blue); border-bottom-color: var(--blue); }
.action--primary:hover { color: var(--blue-dk); border-bottom-color: var(--blue-dk); }

/* ── Bands ───────────────────────────────────────────────────────────── */

.band {
  padding-block: var(--s-6);
  scroll-margin-top: var(--s-2);
}

.band--tint { background: var(--tint); }

.band--dark {
  background: var(--navy);
  color: #d9e2e8;
}

/* CMI's pattern: a small uppercase eyebrow, a large heading, a rule, then
   the content. The rule is what gives each section a visible top edge. */
.section-head {
  max-width: var(--measure);
  padding-bottom: var(--s-3);
  margin-bottom: var(--s-5);
  border-bottom: 1px solid var(--rule);
}
.band--dark .section-head { border-bottom-color: #2a4150; }

.eyebrow {
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--blue);
}
.band--dark .eyebrow { color: var(--blue-lt); }

h2 {
  margin-top: var(--s-2);
  font-size: var(--t-h2);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--ink);
}
.band--dark h2 { color: #f3f7f9; }

.section-body { max-width: var(--measure); }
.section-body > * + * { margin-top: var(--s-3); }

.lede {
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--ink);
}

.note { font-size: 1rem; color: var(--ink-3); }
.band--dark .note { color: #90a5b2; }

/* ── Approach: term / gloss rows ─────────────────────────────────────── */

.section-body > .terms {
  margin-top: var(--s-5);
  margin-bottom: var(--s-5);
  border-top: 1px solid var(--rule-soft);
}

.terms__row {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: var(--s-2) var(--s-4);
  padding-block: var(--s-3);
  border-bottom: 1px solid var(--rule-soft);
  transition: background-color 200ms ease;
}
.terms__row:hover { background: rgba(22, 65, 148, 0.04); }

.terms dt {
  font-size: 1.125rem;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.5;
}
.terms dd { color: var(--ink-2); line-height: 1.55; }

/* ── Areas: a three-block grid, CMI's listing pattern ────────────────── */

.areas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--s-5) var(--s-4);
}

.area {
  padding-top: var(--s-4);
  border-top: 2px solid var(--rule);
  transition: border-color 260ms ease;
}
.area:hover { border-top-color: var(--blue); }

.area h3 {
  margin-top: var(--s-3);
  font-size: var(--t-h3);
  font-weight: 500;
  line-height: 1.25;
  color: var(--ink);
}

.area p {
  margin-top: var(--s-2);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink-2);
}

.areas + .note { margin-top: var(--s-5); }

/* ── Figures ─────────────────────────────────────────────────────────── */

svg { display: block; width: 100%; height: auto; }

.area__figure { width: 100%; max-width: 11rem; }

.area__figure svg,
.lt svg {
  overflow: visible;
  fill: none;
  stroke: var(--fig);
  stroke-width: var(--fig-w);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.accent { stroke: var(--ochre); }
.area__figure .axis { stroke: var(--rule); }
.area__figure .node { fill: var(--tint); }
.area__figure .node.accent { fill: var(--ochre); stroke: var(--ochre); }

/* Draw-on. pathLength="1" on every shape means one unitless dash value
   works for a 58px circle and a 5px node alike. */
[data-draw] {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 900ms cubic-bezier(0.25, 0.8, 0.3, 1);
}
.is-drawn [data-draw] { stroke-dashoffset: 0; }

[data-draw]:nth-child(2) { transition-delay: 120ms; }
[data-draw]:nth-child(3) { transition-delay: 240ms; }
[data-draw]:nth-child(4) { transition-delay: 320ms; }
[data-draw]:nth-child(5) { transition-delay: 400ms; }
[data-draw]:nth-child(6) { transition-delay: 460ms; }
[data-draw]:nth-child(7) { transition-delay: 520ms; }
[data-draw]:nth-child(n+8) { transition-delay: 580ms; }

/* Hover transformations. Each one is an actual property of the figure:
   the triangle has 3-fold rotational symmetry, the trajectory redraws
   itself, the tree lights up in breadth-first order. */
/* Note the stroke-dashoffset is repeated in each transition below. These
   selectors outrank the generic [data-draw] rule, and `transition` is a
   single shorthand property — omitting it here would silently kill the
   draw-on for these shapes. */
.area__figure .spin {
  transform-box: view-box;
  transform-origin: 80px 80px;
  transition: transform 800ms cubic-bezier(0.34, 1.2, 0.4, 1),
              stroke-dashoffset 900ms cubic-bezier(0.25, 0.8, 0.3, 1);
}
.area:hover .area__figure .spin { transform: rotate(120deg); }

.area__figure .arc,
.area__figure .vec {
  transition: stroke-dashoffset 900ms cubic-bezier(0.25, 0.8, 0.3, 1);
}
.area:hover .area__figure .arc { animation: redraw 1100ms ease-in-out; }

@keyframes redraw {
  0%   { stroke-dashoffset: 1; }
  100% { stroke-dashoffset: 0; }
}

.area__figure .node {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 340ms cubic-bezier(0.34, 1.3, 0.4, 1),
              fill 340ms ease, stroke 340ms ease,
              stroke-dashoffset 900ms cubic-bezier(0.25, 0.8, 0.3, 1);
}
.area:hover .area__figure .node { fill: var(--blue); stroke: var(--blue); }
.area:hover .area__figure .node:nth-of-type(1) { transform: scale(1.7); transition-delay: 0ms; }
.area:hover .area__figure .node:nth-of-type(2) { transform: scale(1.5); transition-delay: 90ms; }
.area:hover .area__figure .node:nth-of-type(3) { transform: scale(1.5); transition-delay: 90ms; }
.area:hover .area__figure .node:nth-of-type(4),
.area:hover .area__figure .node:nth-of-type(5),
.area:hover .area__figure .node:nth-of-type(6),
.area:hover .area__figure .node:nth-of-type(7) { transform: scale(1.35); transition-delay: 190ms; }

/* ── Hero figure: a grid under a changing linear map ─────────────────── */

.lt {
  flex: 0 0 auto;
  width: min(22rem, 34vw);
}

.lt__grid { stroke: #b9c5cc; stroke-width: 1.1; }
.lt__axis { stroke: var(--ink-3); stroke-width: 1.6; }
.lt__i    { stroke: var(--blue);  stroke-width: 3.5; }
.lt__j    { stroke: var(--ochre); stroke-width: 3.5; }
.lt__span { fill: rgba(22, 65, 148, 0.09); stroke: none; }

/* The whole field is transformed together, about the origin at (160,160) —
   which is what makes it read as one linear map rather than four moving
   parts. 24s is slow enough to feel like breathing, not animation. */
.lt__field {
  transform-box: view-box;
  transform-origin: 160px 160px;
  animation: linmap 24s ease-in-out infinite;
}

@keyframes linmap {
  0%,  100% { transform: matrix(1, 0, 0, 1, 0, 0); }
  25%       { transform: matrix(1, 0.26, -0.34, 1, 0, 0); }
  50%       { transform: matrix(0.74, 0.48, -0.48, 0.88, 0, 0); }
  75%       { transform: matrix(1.16, -0.2, 0.3, 0.84, 0, 0); }
}

/* ── Contact ─────────────────────────────────────────────────────────── */

.email { font-size: clamp(1.375rem, 2.6vw, 1.875rem); }

.email a {
  color: #f3f7f9;
  text-decoration: none;
  border-bottom: 2px solid var(--blue-lt);
  padding-bottom: 0.15rem;
  transition: border-color 180ms ease, color 180ms ease;
}
.email a:hover { color: #fff; border-bottom-color: #fff; }

.band--dark .action { color: #a9bcc7; border-bottom-color: #2a4150; }
.band--dark .action:hover { color: #fff; border-bottom-color: #fff; }
.band--dark .action--primary { color: var(--blue-lt); border-bottom-color: var(--blue-lt); }
.band--dark .action--primary:hover { color: #fff; border-bottom-color: #fff; }

/* ── Footer ──────────────────────────────────────────────────────────── */

.footer {
  padding-block: var(--s-4);
  background: var(--navy);
  border-top: 1px solid #16303e;
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  align-items: baseline;
  justify-content: space-between;
}

.footer p {
  font-size: var(--t-small);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #7d94a2;
}

.nav--footer a { color: #7d94a2; }
.nav--footer a:hover { color: #fff; border-bottom-color: #fff; }

/* ── Scroll reveal ───────────────────────────────────────────────────── */

/* The .reveal class only does anything once motion.js confirms it can
   observe; see the `js-reveal` gate, which keeps content visible if the
   script never runs. */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 620ms ease, transform 620ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.js-reveal .reveal.is-visible { opacity: 1; transform: none; }

/* ── Focus ───────────────────────────────────────────────────────────── */

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 4px;
  border-radius: 1px;
}
.band--dark :focus-visible, .footer :focus-visible { outline-color: var(--blue-lt); }

/* ── Narrow screens ──────────────────────────────────────────────────── */

@media (max-width: 64rem) {
  .hero__inner { display: block; }
  .lt {
    width: min(18rem, 60vw);
    margin-top: var(--s-6);
  }
}

@media (max-width: 48rem) {
  :root { --s-6: 3.75rem; --s-7: 4.5rem; }

  .terms__row { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; }
  .actions { gap: var(--s-3) var(--s-4); }
  .area__figure { max-width: 8rem; }
  .section-head { margin-bottom: var(--s-4); }
}

/* ── Print ───────────────────────────────────────────────────────────── */

@media print {
  .masthead, .footer, .actions, .lt, .area__figure { display: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .band--dark { background: #fff; color: #000; }
  .band--dark h2, .band--dark .email a { color: #000; }
}

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    animation: none !important;
  }
  /* With the animations off, the artwork must simply be there. */
  [data-draw] { stroke-dashoffset: 0; }
  .lt__field { transform: none; }
  .js-reveal .reveal { opacity: 1; transform: none; }
}
