/* /projects/about-this-portfolio — the provenance essay.
   The one page on the site with no imagery in it, which is part of what it is
   arguing: everything here has to be carried by type, measure and rhythm,
   because the page's subject is what survives when there is nothing to look
   at. Every class is esy-* namespaced and scoped under .taxi-w.essay; nothing
   here may style the shared nav/footer. Tokens live on the page root, never on
   :root — the shared sheet owns that.

   Remember 1rem is not 16px: html{font-size} is a fluid function of viewport
   width (css-main.html), so every rem below is a proportional design unit.
   The reading column is deliberately the SAME size as the ten case studies
   (--esy-measure 62ch, body at 1rem) rather than a size chosen for this page
   alone — a long-form page that read a size larger than the ten long-form
   pages it sits beside would look bolted on, whatever its own merits.

   Motion contract, same as /projects and the case studies: the hidden start
   states are gated on .esyjs, which an inline one-liner in content.html sets
   pre-paint. No class -> no JS -> everything renders in its settled, fully
   visible end state.

   THE PAGE HAS EXACTLY TWO SURFACES: the paper, and one tone step above it
   with a 1px rim. The tone step is the concession block and the measured note,
   and nothing else on the page may claim it. No shadows anywhere — depth is
   the tone step plus the rim, exactly as the case-study sheet declares with
   --cs-lift: none. */

.taxi-w.essay {
  --esy-bg: #fafcfb;           /* the paper — the same white /projects and the case studies use */
  --esy-fg: #040504;           /* = --color--dark-green */
  --esy-dim: #535450;          /* = --color--dark-green-tint-2 · 7.41:1 on the paper */
  --esy-line: rgba(4, 5, 4, .09);
  /* THE TONE STEP. One value, used twice — the concession block and the
     measured note. A step down in brightness and a step UP in text weight,
     which is the opposite of what a disclaimer usually gets, and that is the
     whole point of the component. It is the same paper the case-study cards
     are cut from, deliberately: a new grey here would be a third neutral on a
     site that has two. */
  --esy-step: #e9efeb;         /* = --cs-card / --cs-shell */
  --esy-rim: #cbd3ce;          /* = --cs-rim · the edge of a surface, never the edge of a control */
  /* ONE SITE GREEN — the same #21f1a8 the nav's "Let's talk" button wears.
     It measures ~1.5:1 on this paper, so here it is never text and never a
     rule: it fills exactly one shape on the page, the primary button, and the
     type sitting on it is ink. */
  --esy-mint: var(--color--lime, #21f1a8);
  --esy-mint-hover: #19d894;
  --esy-on-mint: #10120f;
  --esy-mono: ui-monospace, SFMono-Regular, Menlo, 'Courier New', monospace;
  --esy-ease: cubic-bezier(.215, .61, .355, 1);
  --esy-measure: 62ch;
  --esy-rhythm: 6.5rem;

  /* what the shared footer band paints itself with — see css-main.html */
  --page-bg: var(--esy-bg);

  background-color: var(--esy-bg);
  color: var(--esy-fg);
  display: block;
  position: relative;
}

/* ---------------------------------------------------------------- resets

   Deliberately narrow. `.taxi-w.essay ol` is (0,2,1) and silently outranks any
   bare `.esy-*` class that tries to set a margin on the same element — the
   trap projects.css documents at .pjx-wall. So the element reset here only
   removes list markers, which no class needs to argue with, and every box
   value (margin, padding) is set on the class that owns it. The shared sheet
   already zeroes p/h1/h2 margins, so there is nothing else to undo. */

.taxi-w.essay ol,
.taxi-w.essay ul { list-style: none; }
.taxi-w.essay li { list-style: none; list-style-type: none; }
.taxi-w.essay li::marker { content: none; }
.taxi-w.essay dd { margin: 0; }

/* Quicksand ships here as THREE STATIC FACES mapped to weight ranges
   (200–300 light, 400 regular, 500–900 medium), not as a variable font — see
   the @font-face block in the shared sheet. `font-variation-settings` is
   therefore inert on this site and only font-weight actually selects a face.
   This page writes font-weight and nothing else, so what is declared is what
   renders. */

/* ---------------------------------------------------------------- layout */

.esy-wrap {
  width: 100%;
  max-width: var(--fluid-container);
  margin-inline: auto;
  padding-inline: var(--padding--container);
}

/* Invisible until focused, then a real, visible control — the .cs-skip
   contract, kept identical so the first Tab on any page of this site does the
   same thing in the same place. */
.esy-skip {
  position: fixed;
  top: 1rem;
  left: 50%;
  z-index: 20;
  transform: translate(-50%, -150%);
  opacity: 0;
  pointer-events: none;
  background-color: var(--esy-fg);
  color: #edf5f3;
  font-family: var(--esy-mono);
  font-size: .6875rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .625rem 1rem;
  border-radius: .375rem;
  transition: transform .25s var(--esy-ease), opacity .25s linear;
}
/* Page-scoped on purpose. The catch-all `.taxi-w.essay a:focus-visible` ring at
   the bottom of this file is (0,3,1) and would otherwise out-specify a bare
   `.esy-skip:focus-visible` (0,2,0) — painting an ink ring on an ink pill,
   which is a focus indicator you cannot see. Same class of bug as the
   `outline: none` one, arrived at from the opposite direction. */
.taxi-w.essay .esy-skip:focus-visible {
  transform: translate(-50%, 0);
  opacity: 1;
  pointer-events: auto;
  outline: 2px solid var(--esy-mint);
  outline-offset: 2px;
}

/* --------------------------------------------------------------- masthead */

.esy-mast {
  position: relative;
  padding-top: calc(var(--on-t-nav-spacer, 5.375rem) + 2.5rem);
  padding-bottom: 5rem;
}
.esy-crumb {
  display: flex;
  align-items: baseline;
  gap: .625rem;
  font-family: var(--esy-mono);
  font-size: .625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--esy-dim);
}
.esy-crumb a { color: var(--esy-dim); text-decoration: none; transition: color .3s linear; }
.esy-crumb a:hover, .esy-crumb a:focus-visible { color: var(--esy-fg); }
.esy-crumb b { color: var(--esy-fg); font-weight: 500; }

/* THE HEADLINE IS THE WORST FACT ON THE PAGE, set at the largest size this
   site has. That is the masthead's whole idea and it is not decoration: a page
   whose biggest type is its own disclosure cannot be read as having buried it.
   Orbitron uppercase, the same treatment the ten case-study mastheads wear, so
   this page is visibly part of the set it is about. */
.esy-h1 {
  margin: 2.25rem 0 0;
  font-family: Orbitron, Arial, sans-serif;
  font-size: clamp(2.5rem, 5.4vw, 4.75rem);
  line-height: .94;
  letter-spacing: -.075rem;
  text-transform: uppercase;
  font-weight: 700;
  font-variation-settings: normal;
  color: var(--esy-fg);
}
.esy-h1-l { display: block; }

.esy-lede {
  margin: 1.75rem 0 0;
  max-width: 46rem;
  color: var(--esy-dim);
  font-size: 1.0625rem;
  line-height: 1.55;
  font-weight: 400;
}
.esy-lede b {
  font-family: var(--esy-mono);
  font-size: .9em;
  font-weight: 400;
  color: var(--esy-fg);
}

.esy-by {
  margin: 2.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--esy-line);
  font-family: var(--esy-mono);
  font-size: .625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--esy-dim);
}

/* --------------------------------------------------------- rail + article */

/* The reading-progress rail is the only motion on this page besides the
   paragraph reveals, and it is here for one reason: the page is long, and an
   argument whose end you cannot see reads as a page that is stalling. The list
   doubles as the contents, which is why the last entry is called "Walking
   away" — the shape of the case is legible before a word of it is.

   Machinery is the case studies' .cs-prog contract, unchanged: essay/init.js
   writes --esy-p on .esy-prog and the line's ::after inherits it. */
.esy-layout { padding-bottom: var(--esy-rhythm); }
.esy-rail { margin: 0; }
.esy-rail-list {
  display: flex;
  gap: 1.25rem;
  margin: 0;
  padding: 1rem 0;
  overflow-x: auto;
  border-bottom: 1px solid var(--esy-line);
}
.esy-rail a {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  /* max() so the target clears 24 CSS px at every width the fluid root scale
     passes through, including the narrow band where 1rem is at its smallest */
  min-height: max(1.75rem, 24px);
  white-space: nowrap;
  font-family: var(--esy-mono);
  font-size: .625rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--esy-dim);
  transition: color .3s linear;
}
.esy-rail a b { color: var(--esy-fg); font-weight: 400; }
.esy-rail a:hover,
.esy-rail a:focus-visible,
.esy-rail a.is-here { color: var(--esy-fg); }
.esy-rail-line { display: none; }

@media screen and (min-width: 992px) {
  .esy-layout {
    display: grid;
    grid-template-columns: 12rem minmax(0, 1fr);
    column-gap: 4rem;
    align-items: start;
  }
  .esy-rail {
    position: sticky;
    top: calc(var(--on-t-nav-spacer, 5.375rem) + 2.5rem);
    margin: var(--esy-rhythm) 0 0;
    display: flex;
    gap: 1.125rem;
  }
  .esy-rail-line {
    display: block;
    position: relative;
    width: 1px;
    align-self: stretch;
    background-color: var(--esy-line);
    overflow: hidden;
  }
  /* Ink, not mint. Mint is ~1.5:1 on this paper and a progress rail is a
     graphical object the reader is meant to be able to see. */
  .esy-rail-line::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--esy-fg);
    transform: scaleY(var(--esy-p, 0));
    transform-origin: top center;
  }
  .esy-rail-list {
    flex-direction: column;
    align-items: flex-start;
    gap: .875rem;
    padding: 0;
    overflow: visible;
    border-bottom: 0;
  }
  .esy-rail a { white-space: normal; align-items: baseline; }
}

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

/* The skip link's destination. tabindex="-1" in the markup is NOT a tab stop —
   it only lets the skip link genuinely move focus instead of merely scrolling,
   which is the difference between a skip link that works for a screen-reader
   user and one that only works for a mouse. The ring is drawn deliberately
   rather than left to the user agent, and it is a ring: never `outline: none`. */
.esy-article:focus-visible { outline: 2px solid var(--esy-fg); outline-offset: .75rem; }

.esy-move { padding-top: var(--esy-rhythm); }
.esy-move + .esy-move {
  margin-top: var(--esy-rhythm);
  border-top: 1px solid var(--esy-line);
}

.esy-eyebrow {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  font-family: var(--esy-mono);
  font-size: .625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--esy-dim);
}
.esy-eyebrow b { color: var(--esy-fg); font-weight: 400; }

/* Sentence case, and that is a decision rather than an omission. The rest of
   the site sets its H2s uppercase, which works for two- and three-word section
   labels; these are sentences, and one of them is a question a person would
   actually type. An uppercase question reads as a sign rather than as
   something being asked. */
.esy-h2 {
  margin: 1.125rem 0 0;
  /* 32ch, not the 24–26ch the rest of the site uses on its H2s: these headings
     are sentences, and the longest of them ("What does self-initiated work
     prove that paid work can't?") lands on three lines at 26ch and two at 32.
     A heading that wraps to three where the design allows two is a copy bug —
     this is the same bug fixed from the CSS side. */
  max-width: 32ch;
  font-size: clamp(1.5rem, 2.6vw, 2.25rem);
  line-height: 1.14;
  letter-spacing: -.02em;
  text-transform: none;
  font-weight: 500;
  font-variation-settings: normal;
  color: var(--esy-fg);
}

.esy-body {
  margin: 1.25rem 0 0;
  max-width: var(--esy-measure);
  color: var(--esy-dim);
  font-size: 1rem;
  line-height: 1.65;
  font-weight: 400;
}
.esy-body + .esy-body { margin-top: 1rem; }

/* ------------------------------------------------------- concession block */

/* THE CONCESSION BLOCK. A tone-step surface with the same 1px rim as every
   other object on this site, and deliberately NOT a warning box: no amber, no
   red, no glyph, no border-left alert bar. Those signal "problem". This is
   rigour — and it is the most legible thing on the page, because its prose is
   the only full-ink body copy here, one step darker than the paragraphs
   around it.

   That is the load-bearing rule of the component, so it is written down rather
   than left to whoever edits next: a concession set smaller, lighter or
   narrower than the claim it qualifies has become fine print, which is the one
   thing this page exists not to be. */
.esy-cede {
  /* the measure is of the TEXT, so the box carries its own padding on top of
     it — otherwise every concession reads a column narrower than the argument */
  max-width: calc(var(--esy-measure) + 3.75rem);
  margin: 2rem 0 0;
  padding: 1.75rem 1.875rem;
  background-color: var(--esy-step);
  border: 1px solid var(--esy-rim);
  border-radius: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1.125rem;
}
.esy-cede-k {
  margin: 0 0 .25rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--esy-rim);
  font-family: var(--esy-mono);
  font-size: .625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--esy-dim);
}
.esy-cede-p,
.esy-cede-f {
  margin: 0;
  max-width: var(--esy-measure);
  color: var(--esy-fg);
  font-size: 1rem;
  line-height: 1.65;
  font-weight: 400;
}

/* ----------------------------------------------------------------- terms */

.esy-terms { display: grid; gap: 1.25rem; margin: 0; }
.esy-terms > div { display: grid; gap: .35rem; }
.esy-terms dt {
  font-size: 1rem;
  line-height: 1.3;
  font-weight: 500;
  color: var(--esy-fg);
}
.esy-terms dd {
  max-width: var(--esy-measure);
  font-size: .9375rem;
  line-height: 1.6;
  color: var(--esy-dim);
}
/* Inside the concession block the definitions ARE the concession, so they take
   ink like the rest of it. */
.esy-cede .esy-terms dd { color: var(--esy-fg); }
/* The "what goes in writing" list carries a section on its own, so it is ruled
   apart and set a size up. */
.esy-terms.is-lg {
  margin: 2rem 0 0;
  gap: 0;
  border-top: 1px solid var(--esy-line);
}
.esy-terms.is-lg > div {
  gap: .5rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--esy-line);
}
.esy-terms.is-lg dt { font-size: 1.0625rem; }

/* --------------------------------------------------------------- the beam */

/* THE FIVE ASYMMETRIES, WEIGHED. Two pans and a beam: the concession on the
   left, the counter on the right, and the number sitting on the hairline
   between them like a fulcrum. The layout is the argument — two things are
   being held against each other and neither pan is allowed to be heavier.

   Hence the one rule this block must never lose: .esy-side-t is a SINGLE class
   used on both sides. Same size, same weight, same colour, same measure. If a
   later edit wants the right-hand column to land harder, the sentence is what
   changes, not the type. */
.esy-weighs {
  counter-reset: esy-w;
  margin: 2.5rem 0 0;
  padding: 0;
  border-top: 1px solid var(--esy-line);
}
.esy-weigh {
  counter-increment: esy-w;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 3.25rem minmax(0, 1fr);
  align-items: stretch;
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--esy-line);
}
.esy-side { display: flex; flex-direction: column; gap: .5rem; }
.esy-side-k {
  margin: 0;
  font-family: var(--esy-mono);
  font-size: .5625rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--esy-dim);
}
.esy-side-t {
  margin: 0;
  font-size: .9375rem;
  line-height: 1.6;
  font-weight: 400;
  color: var(--esy-fg);
}

/* The beam is painted as a background rather than built from a second element,
   so the number can knock its hole in it with the paper colour and the two can
   never overlap however tall the row grows. */
.esy-fulcrum {
  position: relative;
  display: block;
  background-image: linear-gradient(var(--esy-line), var(--esy-line));
  background-size: 1px 100%;
  background-position: 50% 0;
  background-repeat: no-repeat;
}
.esy-fulcrum::before {
  content: counter(esy-w, decimal-leading-zero);
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: .4rem .3rem;
  background-color: var(--esy-bg);
  font-family: var(--esy-mono);
  font-size: .625rem;
  letter-spacing: .06em;
  color: var(--esy-dim);
}

/* ----------------------------------------------------- the measured note */

/* Monospace is this site's "you are looking at a measurement" signal, so the
   one paragraph on the page carrying figures is set in it — with its date, its
   command and its conditions in the same breath, because a number without them
   is the exact tell this page is written against. */
.esy-meas {
  max-width: calc(var(--esy-measure) + 3.75rem);
  margin: 2.5rem 0 0;
  padding: 1.375rem 1.5rem;
  background-color: var(--esy-step);
  border: 1px solid var(--esy-rim);
  border-radius: 1rem;
  font-family: var(--esy-mono);
  font-size: .75rem;
  line-height: 1.85;
  color: var(--esy-dim);
}
.esy-meas b { color: var(--esy-fg); font-weight: 400; }
.esy-meas code { font-family: inherit; font-size: 1em; color: var(--esy-fg); }

/* ------------------------------------------------------------------- end */

.esy-end { margin-top: 3rem; }
.esy-end-t {
  margin: 0;
  max-width: var(--esy-measure);
  color: var(--esy-dim);
  font-size: .9375rem;
  line-height: 1.6;
}
.esy-end-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  margin-top: 1.5rem;
}
/* ONE solid button on the page, and the second action is a text link — the
   site-wide CTA hierarchy, and the reason is not only hierarchy: a second
   outlined pill would need a boundary that carries 3:1 on this paper, and the
   hairline rim the rest of the site uses does not (≈1.5:1). A rim is fine
   around a surface that is also a tone step; it is not fine as the only thing
   telling you where a control starts. Ink type on paper is 17.6:1 and needs no
   box at all. */
.esy-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* max() keeps the target above 24 CSS px at every width the fluid root scale
     passes through, without inflating it on a wide screen */
  min-height: max(2.75rem, 24px);
  padding: .875rem 1.5rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: .9375rem;
  line-height: 1;
  font-weight: 500;
  text-decoration: none;
  transition: background-color .35s var(--esy-ease);
}
.esy-btn.is-primary { background-color: var(--esy-mint); color: var(--esy-on-mint); }
.esy-btn.is-primary:hover,
.esy-btn.is-primary:focus-visible { background-color: var(--esy-mint-hover); }

.esy-link {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: max(2.75rem, 24px);
  padding: 0 .5rem;
  color: var(--esy-fg);
  font-size: .9375rem;
  line-height: 1;
  font-weight: 500;
  text-decoration: none;
}
.esy-link span:first-child {
  text-decoration: underline;
  text-decoration-color: var(--esy-rim);
  text-underline-offset: .35em;
  transition: text-decoration-color .35s var(--esy-ease);
}
.esy-link:hover span:first-child,
.esy-link:focus-visible span:first-child { text-decoration-color: var(--esy-fg); }
.esy-link-a { transition: transform .35s var(--esy-ease); }
.esy-link:hover .esy-link-a { transform: translateX(.25rem); }

/* One focus treatment for every focusable thing on the page, and never
   `outline: none` on :focus — that silently out-specifies the global
   :focus-visible ring, a bug this repository has already fixed twice. */
.taxi-w.essay a:focus-visible { outline: 2px solid var(--esy-fg); outline-offset: 3px; }
.taxi-w.essay .esy-btn.is-primary:focus-visible { outline-offset: 4px; }

/* ------------------------------------------------------------------ motion */

/* One reveal, used everywhere, and nothing else. A page arguing for restraint
   that performs is arguing against itself — so there is no parallax here, no
   pinning, no counter, and nothing that delays a sentence the reader is being
   asked to weigh. The hidden start state exists only once .esyjs is on <html>,
   set pre-paint by the inline one-liner on line 1 of content.html. */
.esyjs .esy-rise { opacity: 0; transform: translateY(1.25rem); }
.esyjs .esy-rise.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .8s var(--esy-ease), transform .8s var(--esy-ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}

@media (prefers-reduced-motion: reduce) {
  .taxi-w.essay *,
  .taxi-w.essay *::before,
  .taxi-w.essay *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  /* Everything reaches its settled, visible state: the reveals are simply not
     hidden, and the progress rail renders full rather than empty (init.js also
     stops writing --esy-p and clears what it already wrote). Nothing on this
     page depends on an animation finishing. */
  .esyjs .esy-rise { opacity: 1; transform: none; }
  .esyjs .esy-rise.is-in { transition: none; }
  .esy-rail-line::after { transform: none; }
}

/* -------------------------------------------------------------- responsive */

@media screen and (max-width: 991px) {
  .taxi-w.essay { --esy-rhythm: 4.5rem; }
  .esy-mast {
    padding-top: calc(var(--on-t-nav-spacer, 5.375rem) + 1.5rem);
    padding-bottom: 3.5rem;
  }
  .esy-h2 { max-width: none; }
}

@media screen and (max-width: 767px) {
  /* The beam turns ninety degrees. The two pans stack, the hairline runs
     between them instead of down the middle, and the number still sits on it —
     same object, same meaning, one axis rotated. */
  .esy-weigh { grid-template-columns: minmax(0, 1fr); }
  .esy-fulcrum {
    height: 2.25rem;
    background-size: 100% 1px;
    background-position: 0 50%;
  }
  .esy-fulcrum::before { padding: 0 .625rem; }
  .esy-cede { padding: 1.375rem 1.25rem; }
  .esy-meas { padding: 1.125rem 1.25rem; line-height: 1.75; }
  .esy-end-row { gap: .625rem; }
  .esy-btn { width: 100%; }
}
