/* ==========================================================================
   Plumbline — reset, typography, controls
   ========================================================================== */

/* Metric-matched fallback. Inter runs noticeably smaller per em than Arial, so
   without the size-adjust the swap would reflow every line box on the page. */
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Liberation Sans");
  size-adjust: 107.12%;
  ascent-override: 90.44%;
  descent-override: 22.55%;
  line-gap-override: 0%;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* overflow-x here, not on body: a non-visible overflow on body would make
     BODY the viewport's scroll container, and scrollbar-gutter would then be
     ignored on html. With html as the scroller the gutter stays reserved, so
     locking the page for the menu no longer removes the scrollbar, widens the
     viewport and shunts every centred element sideways. */
  overflow-x: hidden;
  scrollbar-gutter: stable;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--wt-text);
  letter-spacing: var(--ls-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; background: var(--paper-sunk); }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: var(--wt-display);
  letter-spacing: var(--ls-h2);
  line-height: var(--lh-head);
  text-wrap: balance;
}
h1 { font-size: var(--fs-display); line-height: var(--lh-tight); letter-spacing: var(--ls-h1); font-weight: var(--wt-head); }
h2 { font-size: var(--fs-h2); font-weight: var(--wt-head); }
h3 { font-size: var(--fs-h3); letter-spacing: var(--ls-h3); }
h4 { font-size: var(--fs-h3); letter-spacing: var(--ls-h3); }

p { margin: 0; max-width: var(--measure); text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

/* --- Focus. Visible against both fill and background. ------------------- */
:focus-visible {
  outline: 3px solid var(--action);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
.on-ink :focus-visible { outline-color: var(--action-hi); }

/* --- Selection. The accent, washed out enough to read through. ----------- */
/* No colour set on the text itself: whatever was legible before the drag
   stays legible during it, on paper and on ink alike. */
::selection { background: rgba(190, 65, 23, .22); }
.on-ink ::selection { background: rgba(224, 90, 38, .30); }

.skip-link {
  position: absolute; top: -100px; left: var(--gutter); z-index: 200;
  padding: var(--s-3) var(--s-6);
  background: var(--ink); color: var(--text-inv);
  border-radius: var(--r-md); font-size: var(--fs-sm); font-weight: var(--wt-display);
  transition: top var(--t-fast) var(--ease-out);
}
.skip-link:focus { top: var(--s-4); }

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

.lead {
  font-size: var(--fs-lead);
  color: var(--text-sub);
  line-height: 1.5;
  max-width: 54ch;
}

.fig { font-weight: var(--wt-display); letter-spacing: var(--ls-hero); font-variant-numeric: tabular-nums; }

/* --- Buttons ------------------------------------------------------------ */
.btn {
  --btn-bg: transparent;
  display: inline-flex; align-items: center; gap: var(--s-3);
  min-height: 48px; padding: 0 var(--s-6);
  border: 1.5px solid transparent; border-radius: var(--r-md);
  background: var(--btn-bg);
  font: inherit; font-size: var(--fs-body);
  font-weight: var(--wt-display);
  letter-spacing: var(--ls-body);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease-out),
              border-color var(--t-fast) var(--ease-out),
              transform var(--t-fast) var(--ease-out);
}
.btn svg { flex: none; transition: transform var(--t-mid) var(--ease-out); }
.btn:hover svg { transform: translateX(4px); }

/* Filled. One per view. */
.btn--primary { --btn-bg: var(--action-fill); color: #fff; }
.btn--primary:hover  { --btn-bg: var(--action-fill-hi); }
.btn--primary:active { --btn-bg: var(--action-fill-lo); transform: translateY(1px); }

/* Outline. Everything else. */
.btn--outline { border-color: var(--line-strong); color: var(--text); }
.btn--outline:hover { border-color: var(--text); background: rgba(22,18,15,.04); }
.on-ink .btn--outline:hover { background: rgba(244,240,233,.08); }

/* Text link with a rule that grows — affordance changes, not just colour. */
.link {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--fs-body);
  font-weight: var(--wt-display);
  letter-spacing: var(--ls-body);
  color: var(--text);
  padding-bottom: 3px;
  background-image: linear-gradient(var(--action), var(--action));
  background-size: 0% 2px; background-position: 0 100%; background-repeat: no-repeat;
  transition: background-size var(--t-mid) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.link:hover { background-size: 100% 2px; color: var(--action-sunk); }
.on-ink .link:hover { color: var(--action-hi); }
.link svg { transition: transform var(--t-mid) var(--ease-out); }
.link:hover svg { transform: translateX(3px); }

/* --- Reduced motion: paint the end state, animate nothing. -------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .btn:hover svg, .link:hover svg { transform: none; }
}

/* --- Section headings: accent bar wipes across, words land behind it ------
   Structure is built by js/blinds.js and torn down again once it has played.
   The heading is plain, visible text before and after; only the bar and the
   opacity flip live here, and the flip's starting value is set in JS. */
.blind {
  display: inline-block; vertical-align: top;
  position: relative; overflow: hidden;
  width: fit-content;
}
.blind__text { position: relative; display: block; text-align: left; }
.blind__bar {
  position: absolute; inset: 0;
  background: var(--action);
  transform: translateX(-100%);
}
@keyframes blind-bar  { from { transform: translateX(-100%); } to { transform: translateX(101%); } }
/* The words appear at the midpoint, under the bar, so the bar looks like it
   is carrying them in rather than uncovering something already there. */
@keyframes blind-text { 0%, 49.9% { opacity: 0; } 50%, 100% { opacity: 1; } }

.is-wiping .blind__bar  { animation: blind-bar  1s cubic-bezier(.6,0,.4,1) var(--d, 0ms) both; }
.is-wiping .blind__text { animation: blind-text 1s linear var(--d, 0ms) both; }
