/* Infra-Bench CLS — project page.
   Dark, warm, serif. Palette and type follow jg-geoportfolio. */

:root {
  --bg:         #1a1e1b;   /* dark green-black */
  --bg-raised:  #21251e;
  --ink:        #c4b9a5;   /* body */
  --ink-bright: #e2d8c4;   /* headings */
  --ink-dim:    #9b8e7a;   /* secondary */
  --rule:       #3a3c33;   /* hairlines — never used for text */
  --rule-soft:  #2b2e26;

  --brown:      #7a5c3d;
  --tan:        #c8b08a;
  --green:      #2f4a3a;
  --gold:       #c4a24e;

  /* Lifted variants of the two darkest palette colors. The originals are
     right for fills but sit at ~2.8:1 on this background — too low for the
     small mono labels they were being used on. */
  --brown-lit:  #a8825a;   /* 4.9:1 */
  --green-lit:  #7d9a63;   /* 5.4:1 */

  --serif:  "EB Garamond", Georgia, serif;
  --body:   "Crimson Pro", Georgia, serif;
  --mono:   "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 18.5px/1.7 var(--body);
  -webkit-font-smoothing: antialiased;
}

/* One centered column, shared by every block on the page, so section rules,
   prose and figures all break on the same edges. */
header, nav, main, footer { max-width: 900px; margin: 0 auto; padding: 0 26px; }

a { color: var(--tan); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--ink-bright); }

/* ------------------------------------------------------------------ header */

header {
  padding-top: 82px;
  padding-bottom: 4px;
  text-align: center;
}

h1 {
  font: 500 3.1rem/1.1 var(--serif);
  color: var(--ink-bright);
  margin: 0;
}

.lede {
  margin: 18px 0 0;
  font-size: 1.14rem;
  color: var(--ink);
}

/* Author line and affiliation key, set like a paper's title block. */
.byline {
  margin: 26px auto 0;
  max-width: 58ch;
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--ink);
}

/* Each name is one unbreakable unit, so a wrap never splits a person in half. */
.byline .author { white-space: nowrap; }

.affils {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin: 10px 0 0;
  font: 0.78rem/1.5 var(--mono);
  color: var(--ink-dim);
}

/* Superscript affiliation markers. vertical-align rather than <sup> so the
   line height of the author block stays even. */
.mark {
  font: 500 0.62rem/1 var(--mono);
  vertical-align: super;
  color: var(--brown-lit);
  margin-left: 1px;
}

.affils .mark { margin: 0 3px 0 0; }

/* --------------------------------------------------------------------- nav */

nav {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 6px;
  margin-top: 34px;
  padding-bottom: 4px;
}

nav a {
  font: 500 0.72rem/1 var(--mono);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
  padding: 9px 14px;
  border: 1px solid transparent;
}

nav a:hover { color: var(--ink-bright); }

nav a:focus-visible { outline: 1px solid var(--tan); outline-offset: 1px; }

/* ---------------------------------------------------------------- sections */

/* Separated mostly by space; the rule is a warm hairline, deliberately dim so
   it reads as a division rather than a border. */
section {
  margin-top: 96px;
  padding-top: 58px;
  border-top: 1px solid rgba(200, 176, 138, 0.13);
}

main > section:first-of-type { border-top: none; padding-top: 0; margin-top: 52px; }

h2 {
  font: 500 2rem/1.2 var(--serif);
  color: var(--ink-bright);
  margin: 0 0 14px;
  text-align: center;
}

h3 {
  font: 500 1.28rem/1.3 var(--serif);
  color: var(--ink-bright);
  margin: 38px 0 8px;
}

/* ----------------------------------------------------------------- figures */

figure { margin: 0 0 44px; }

figure img {
  width: 100%;
  height: auto;
  display: block;
  background: #fff;
  border: 1px solid var(--rule);
}

figcaption {
  margin-top: 11px;
  font-size: 0.92rem;
  color: var(--ink-dim);
}

figcaption strong { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------------- prose */

/* Justified. No auto-hyphenation: on this measure the word spacing stays
   even enough without it, and hyphen breaks would read as the stray dashes
   we deliberately kept out of the copy. */
.prose p {
  color: var(--ink);
  margin: 0 0 14px;
  text-align: justify;
  text-justify: inter-word;
  hyphens: none;
}

/* Ragged right where justifying would look wrong: short captions and the
   one-line link descriptions. */
figcaption, .prose dd { text-align: left; }
.prose em { font-style: italic; color: var(--ink-bright); }

.prose dl { margin: 20px 0 18px; }

.prose dt {
  font: 500 0.72rem/1 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brown-lit);
  margin-top: 17px;
}

.prose dd { margin: 5px 0 0; color: var(--ink); }

/* Paper / dataset / code, each a term with a line under it. */
.links dt { margin-top: 22px; }
.links dt:first-child { margin-top: 0; }

.authors { padding: 0; margin: 20px 0 0; list-style: none; }

.authors li {
  padding: 13px 0;
  border-bottom: 1px solid var(--rule-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
}

.authors li:last-child { border-bottom: none; }
.authors strong { color: var(--ink); font-weight: 600; font-size: 1.05rem; }

.authors a {
  color: var(--gold);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.authors a:hover { color: var(--tan); }

.affil {
  font: 0.74rem/1.4 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* --------------------------------------------------------------- citation */

.cite-block {
  position: relative;
  margin: 20px 0 0;
  border: 1px solid var(--rule);
  background: var(--bg-raised);
}

.cite-block pre {
  margin: 0;
  padding: 20px 22px;
  overflow-x: auto;
  font: 0.78rem/1.75 var(--mono);
  color: var(--ink);
  tab-size: 2;
}

.copy {
  position: absolute;
  top: 10px;
  right: 10px;
  font: 500 0.64rem/1 var(--mono);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-dim);
  background: var(--bg);
  border: 1px solid var(--rule);
  padding: 7px 11px;
  cursor: pointer;
}

.copy:hover { color: var(--ink-bright); border-color: var(--brown-lit); }
.copy:focus-visible { outline: 1px solid var(--tan); outline-offset: 1px; }
.copy.done { color: var(--green-lit); border-color: var(--green-lit); }

/* --------------------------------------------------------- margin sketches */

/* Sized fluidly against the margin the layout actually leaves, rather than
   stepped through breakpoints: the margin is (100vw - 900px) / 2, so a drawing
   takes that minus the gap it needs from the text, plus a small deliberate
   bleed past the viewport edge. Positioning uses `right: 100% + gap` instead of
   a negative offset, which pins the inner edge a fixed distance from the column
   without needing to know the width — so width and position stay independent.

   --sk-gap is clearance from the host's own edge, which resolves to a different
   place depending on the host: `header` and `footer` carry the column's 26px
   padding themselves, so a child measures from their border box and gains that
   padding on top, while hosts inside main sit at the content edge already. The
   effect is more air at the very top and bottom of the page, which suits it.

   The gap runs ~12px wider than the clearance actually wanted, because each
   drawing is rotated a few degrees and a rotated bounding box is wider than the
   element, eating that much back. */
:root {
  --sk-gap:   34px;
  --sk-bleed: 18px;   /* how far a drawing may hang past the viewport edge */
  --sk-min:   170px;
  --sk-max:   600px;
}

/* The bleed needs the horizontal axis clipped, or the overhang adds a
   horizontal scrollbar.

   `clip` rather than `hidden`, and on body alone. `overflow-x: hidden` makes an
   element a scroll container, which forces overflow-y from visible to auto — so
   body grew its own vertical scrollbar alongside the browser's, two bars for
   one page. `clip` crops without creating a scroll container, so overflow-y
   stays visible and only the real scroller (html) shows a bar.

   Safe here because nothing on the page is position:sticky, which is what
   clipping an ancestor would otherwise break. */
body { overflow-x: clip; }

@supports not (overflow-x: clip) {
  /* Older engines: rather than fall back to `hidden` and reintroduce the
     second scrollbar, just stop the drawings overhanging at all. */
  :root { --sk-bleed: -6px; }
}

.sketch { display: none; }

.sketch-host { position: relative; }

@media (min-width: 1280px) {
  .sketch {
    display: block;
    position: absolute;
    width: clamp(
      var(--sk-min),
      calc(((100vw - 900px) / 2 - var(--sk-gap) + var(--sk-bleed)) * var(--sk-f, 1)),
      var(--sk-max)
    );
    height: auto;
    pointer-events: none;
    /* The ink is a dark olive that measures 2.7:1 against this background, and
       opacity alone drops it to 1.6:1 — invisible. Lift it hard and warm it
       into the palette instead, at full opacity: measured, this renders around
       rgb(139,131,113), which is 4.5:1 on average and 12.7:1 on the densest
       strokes. The peak is what matters, because the handwritten labels are
       the darkest ink in each drawing and would not otherwise read. */
    filter: brightness(2) sepia(0.6);
  }

  /* Pin the inner edge a fixed distance outside the column, independent of
     however wide the drawing turns out to be. */
  .sketch-left  { right: calc(100% + var(--sk-gap)); }
  .sketch-right { left:  calc(100% + var(--sk-gap)); }
}

/* ------------------------------------------------------------------ footer */

footer {
  margin-top: 84px;
  padding-top: 26px;
  padding-bottom: 70px;
  border-top: 1px solid var(--rule-soft);
}

footer p {
  margin: 0 0 5px;
  font: 0.78rem/1.7 var(--mono);
  color: var(--ink-dim);
}

/* Licensing and provenance are different things, so they get separate terms
   rather than one run-on line of dot-separated fragments. */
.foot { margin: 0; }

.foot dt {
  font: 500 0.66rem/1 var(--mono);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--brown-lit);
  margin-top: 18px;
}

.foot dt:first-child { margin-top: 0; }

.foot dd {
  margin: 7px 0 0;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--ink-dim);
  max-width: 70ch;
}

footer a { color: var(--brown-lit); }
footer a:hover { color: var(--tan); }

/* ------------------------------------------------------------------ mobile */

@media (max-width: 640px) {
  header, nav, main, footer { padding: 0 18px; }
  header { padding-top: 52px; }
  h1 { font-size: 2.3rem; }
  .lede { font-size: 1.06rem; }
  nav { margin-top: 26px; gap: 2px; }
  nav a { padding: 8px 10px; font-size: 0.68rem; letter-spacing: 0.1em; }
  section { margin-top: 60px; padding-top: 38px; }
  main > section:first-of-type { margin-top: 38px; }
  h2 { font-size: 1.62rem; }

  /* A 339px column is too narrow to justify without hyphenation: the word
     spacing opens into rivers. Ragged right below this breakpoint. */
  .prose p { text-align: left; }

  /* The code block scrolls sideways on a phone, so an overlaid button would
     sit on top of whatever has been scrolled under it. Put it in the flow. */
  .cite-block { display: flex; flex-direction: column-reverse; }
  .copy {
    position: static;
    align-self: flex-end;
    margin: 10px 10px 0;
    min-height: 44px;
    padding: 0 18px;
  }
}
