/* fractionalytics.io
   The 2026 Fractionalytics brand: steel blue #1A658F, sky cyan #41B6E6, warm paper.
   Kept in an external file on purpose. Inlining it would bloat every page's markup
   and push the text-to-markup ratio down, which is the thing agents actually measure. */

:root {
  --brand-blue: #1A658F;
  --brand-cyan: #41B6E6;
  --blue-600:   #155578;
  --blue-700:   #114561;
  --blue-900:   #0A2838;
  --paper-0:    #FAF9F7;
  --paper-50:   #F2F0EC;
  --paper-100:  #E4E2DD;
  --paper-400:  #97928A;
  --paper-600:  #565350;
  --border:     #D4D1C9;

  --font-display: 'Oswald', 'Arial Narrow', sans-serif;
  --font-body:    'Archivo', system-ui, -apple-system, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, monospace;

  --ring: color-mix(in srgb, var(--brand-cyan) 55%, transparent);
  --measure: 68ch;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--paper-0);
  color: var(--blue-900);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

/* ---------- masthead + nav ---------- */

.masthead {
  border-bottom: 1px solid var(--border);
  background: var(--paper-50);
}

.masthead-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 20px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}

.masthead .logo { width: 188px; height: auto; display: block; }

.sitenav ul { list-style: none; display: flex; gap: 22px; flex-wrap: wrap; }

.sitenav a {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue-600);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
}

.sitenav a:hover,
.sitenav a[aria-current="page"] { color: var(--brand-blue); border-color: var(--brand-cyan); }

.skip-link {
  position: absolute;
  left: -9999px;
  background: var(--brand-blue);
  color: #fff;
  padding: 10px 16px;
  z-index: 10;
}
.skip-link:focus { left: 12px; top: 12px; }

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

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 28px; }

main { padding: 56px 0 24px; }

.prose { max-width: var(--measure); }

/* ---------- headings ---------- */

h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.85rem, 4.2vw, 2.9rem);
  line-height: 1.12;
  letter-spacing: 0.002em;
  color: var(--brand-blue);
  max-width: 22ch;
}

h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.3rem, 2.6vw, 1.65rem);
  line-height: 1.22;
  color: var(--brand-blue);
  margin: 2.4em 0 0.7em;
  /* Headings are held narrower than the 68ch prose measure so display type does not run
     loose at wide viewports.

     40ch DELIBERATELY BINDS, and the earlier comment here claimed otherwise. It said "40ch
     clears every current heading by ~60px", which was true of the practice page and false of
     the site: three h2s in the Unsexy article want 49.1ch, 56.6ch and 62.6ch, all of which fit
     inside the 68ch measure and wrap only because of this cap. Those are David's published
     article titles, long and sentence-shaped, and two lines is right for them. Short editorial
     headings on the other pages stay on one line.

     So this cap is BINDING BY INTENT, not derived from the longest content, and `node build.mjs`
     knows the difference: see HEADING_CAPS there, which warns on derived caps and stays quiet on
     binding ones. Change the intent flag there if you change the number here. */
  max-width: 40ch;
}

h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.06rem;
  line-height: 1.35;
  color: var(--blue-700);
  margin: 1.9em 0 0.5em;
}

.eyebrow {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-600);
  margin-bottom: 14px;
}

.lede {
  font-size: 1.16rem;
  line-height: 1.5;
  color: var(--blue-700);
  margin-top: 18px;
  max-width: 56ch;
}

/* The identity line: what this company is, stated plainly under the H1. Home page
   only. Set above the lede so the first thing after the headline is an answer to
   "what is this?" rather than the start of an argument. */
.identity {
  font-size: 1.28rem;
  line-height: 1.45;
  font-weight: 500;
  color: var(--ink, var(--blue-700));
  margin-top: 20px;
  max-width: 54ch;
}

/* ---------- page head with a portrait ---------- */

/* The portrait goes at the TOP of the About page, beside the name. On print collateral the
   hedcut sits in a signature footer because a one-pager has nowhere else to put it; on the web
   a footer is navigation, and a face down there reads as a stray asset. */
.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 30px;
  max-width: var(--measure);
}
.page-head-text { min-width: 0; }
.page-head h1 { margin: 0; }

.headshot {
  width: 160px;
  height: 160px;
  flex: none;
  display: block;
}

@media (max-width: 640px) {
  .page-head { flex-direction: column-reverse; align-items: flex-start; gap: 18px; }
  .headshot { width: 128px; height: 128px; }
}

/* ---------- text ---------- */

p { margin: 1.05em 0; }

a { color: var(--blue-600); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { color: var(--brand-cyan); }
a:focus-visible { outline: 3px solid var(--ring); outline-offset: 3px; border-radius: 2px; }

strong { font-weight: 600; color: var(--blue-700); }

ul, ol { margin: 1.05em 0; padding-left: 1.35em; }
li { margin: 0.42em 0; }

blockquote {
  margin: 1.5em 0;
  padding: 2px 0 2px 20px;
  border-left: 3px solid var(--brand-cyan);
  color: var(--blue-700);
}
blockquote p { margin: 0.5em 0; }

hr { border: 0; border-top: 1px solid var(--border); margin: 2.6em 0; }

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--paper-100);
  padding: 1px 5px;
  border-radius: 3px;
}

/* ---------- tables ---------- */

.table-scroll { overflow-x: auto; margin: 1.6em 0; }

table { border-collapse: collapse; width: 100%; font-size: 0.97rem; }
caption {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--paper-600);
  padding-bottom: 10px;
}
th, td { text-align: left; padding: 9px 14px 9px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
thead th { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--paper-600); }

/* ---------- article ---------- */

.article-meta {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper-600);
  margin-top: 22px;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

.tags { list-style: none; display: flex; gap: 8px; flex-wrap: wrap; padding: 0; margin: 16px 0 0; }
.tags li {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue-600);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 11px;
  margin: 0;
}

.article-body { margin-top: 34px; }
.article-body > h2:first-child { margin-top: 0; }

.origin-note {
  margin-top: 44px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 0.94rem;
  color: var(--paper-600);
}

.figure-note {
  margin: 1.8em 0;
  padding: 16px 20px;
  border: 1px dashed var(--border);
  border-radius: 4px;
  background: var(--paper-50);
}
.figure-note figcaption { font-size: 0.95rem; color: var(--paper-600); }
.figure-note .stamp { display: block; margin-bottom: 5px; }

/* ---------- breadcrumbs ---------- */

.crumbs { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; margin: 8px 0 34px; }
.crumbs ol { list-style: none; display: flex; gap: 8px; flex-wrap: wrap; padding: 0; margin: 0; }
.crumbs li { margin: 0; color: var(--paper-400); }
.crumbs a { color: var(--blue-600); text-decoration: none; }
.crumbs a:hover { color: var(--brand-cyan); }

/* ---------- writing index ---------- */

.post-list { list-style: none; padding: 0; margin: 34px 0 0; }

.post-list > li {
  margin: 0;
  padding: 26px 0;
  border-top: 1px solid var(--border);
  max-width: var(--measure);
}
.post-list > li:last-child { border-bottom: 1px solid var(--border); }

.post-list h2 { margin: 0 0 6px; font-size: 1.28rem; max-width: none; }
.post-list h2 a { text-decoration: none; color: var(--brand-blue); }
.post-list h2 a:hover { color: var(--brand-cyan); }
.post-list p { margin: 0.4em 0 0; color: var(--paper-600); }

.stamp {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--paper-400);
}

/* ---------- cards / callouts ---------- */

.cards { list-style: none; display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); padding: 0; margin: 30px 0; }
.cards li { margin: 0; border: 1px solid var(--border); border-radius: 4px; padding: 20px 22px; background: var(--paper-50); }
.cards h3 { margin-top: 0; }
.cards p { font-size: 0.97rem; }

.callout {
  border-left: 3px solid var(--brand-cyan);
  background: var(--paper-50);
  padding: 18px 22px;
  margin: 2em 0;
  max-width: var(--measure);
}
.callout p:first-child { margin-top: 0; }
.callout p:last-child { margin-bottom: 0; }

/* ---------- diagnostic ---------- */

.q { border-top: 1px solid var(--border); padding: 26px 0; max-width: var(--measure); }
.q:first-of-type { border-top: 0; }
.q h3 { margin-top: 0; font-size: 1.12rem; color: var(--brand-blue); }
.q .good { border-left: 3px solid var(--brand-cyan); padding-left: 18px; margin-top: 14px; color: var(--paper-600); font-size: 0.98rem; }
.q .good strong { color: var(--blue-700); }

.answers { list-style: none; display: flex; gap: 10px; flex-wrap: wrap; padding: 0; margin: 16px 0 0; }
.answers li { margin: 0; }
.answers label {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 16px;
  cursor: pointer;
  background: #fff;
  color: var(--blue-600);
}
.answers input { position: absolute; opacity: 0; width: 0; height: 0; }
.answers input:checked + label { background: var(--brand-blue); border-color: var(--brand-blue); color: #fff; }
.answers input:focus-visible + label { outline: 3px solid var(--ring); outline-offset: 2px; }

.verdict-panel { border: 1px solid var(--border); border-radius: 4px; background: var(--paper-50); padding: 24px 26px; margin: 30px 0; max-width: var(--measure); }
.verdict-panel h2 { margin-top: 0; }

.verdict { border-top: 1px solid var(--border); padding: 22px 0; max-width: var(--measure); }
.verdict:first-of-type { border-top: 0; }
.verdict h3 { margin-top: 0; font-family: var(--font-display); font-weight: 500; font-size: 1.15rem; color: var(--brand-blue); letter-spacing: 0.01em; }

/* JS turns this on; without JS the whole page is still readable prose. */
.js-only { display: none; }

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

.sitefooter {
  border-top: 1px solid var(--border);
  background: var(--paper-50);
  margin-top: 72px;
  padding: 40px 0 56px;
}

.footer-grid { display: grid; gap: 30px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

.sitefooter h2 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-600);
  margin: 0 0 12px;
}

.sitefooter ul { list-style: none; padding: 0; margin: 0; }
.sitefooter li { margin: 6px 0; font-size: 0.95rem; }
.sitefooter a { color: var(--blue-600); text-decoration: none; }
.sitefooter a:hover { color: var(--brand-cyan); text-decoration: underline; }

.colophon { margin-top: 34px; font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--paper-400); }

@media (max-width: 620px) {
  main { padding-top: 38px; }
  .masthead-inner { padding: 16px 20px; }
  .wrap { padding: 0 20px; }
  .masthead .logo { width: 156px; }
}

/* ---------- recommended reading ---------- */
/* Reuses .post-list geometry so the two halves of /writing sit on one grid.
   The outlet is the publication, set apart from the person's name. */
.reading-list h3 {
  font-family: var(--font-display, inherit);
  font-size: 1.14rem;
  margin: 0 0 8px;
}
.reading-list .outlet {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--paper-600);
  text-transform: none;
}
.reading-list blockquote {
  margin-top: 12px;
}

/* ---------- home page: its own template ---------- */
/* The home page used the article template and read as one more blog post
   (David, 2026-08-21, twice). It now gets a full-bleed hero band and its own
   rhythm below it, so the front door does not look like a post. */
.homemain { padding: 0 0 24px; }

/* NOT --paper-50: that is the masthead's colour, and the two bands blended into
   one shape (David, 2026-08-21). The hero is a step darker than the header above
   it and two steps darker than the body below. */
.hero {
  background: var(--paper-100);
  border-bottom: 1px solid var(--paper-400);
}
.hero-inner {
  padding-top: 92px;
  padding-bottom: 76px;
}
.hero h1 {
  max-width: 18ch;
  font-size: clamp(2.1rem, 5.4vw, 3.6rem);
}
.hero .identity {
  margin-top: 26px;
  max-width: 50ch;
}
.hero .lede {
  margin-top: 22px;
  color: var(--paper-600);
  max-width: 58ch;
}

.homebody { padding-top: 56px; }

/* Section rules give the front page a structure a single prose column does not.
   Suppressed on the first heading so it does not double the hero's border. */
.homebody .prose > h2 {
  margin-top: 58px;
  padding-top: 26px;
  border-top: 1px solid var(--border);
}
.homebody .prose > h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

@media (max-width: 600px) {
  .hero-inner { padding-top: 54px; padding-bottom: 46px; }
  .homebody { padding-top: 38px; }
  .homebody .prose > h2 { margin-top: 42px; }
}

/* ---------- recovered article figures ---------- */
/* The images from the LinkedIn originals, restored 2026-08-21 from David's own PDF exports.
   Full content width rather than the prose measure, because the Venns carry small labels. */
.figure-img {
  margin: 32px 0;
  max-width: 100%;
}
.figure-img img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: #fff;
}
.figure-img figcaption {
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--paper-600);
  margin-top: 10px;
  max-width: 62ch;
}

/* ---------- article cover ---------- */
/* Every piece was published on LinkedIn with a cover image and the site showed none of them
   until 2026-08-21. Full content width, above the table of contents, below the title block. */
.cover {
  margin: 0 0 30px;   /* sits ABOVE the title block now, below the breadcrumbs */
}
.cover img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--paper-50);
}

/* ---------- writing list, with thumbnails ---------- */
/* The list was seven blocks of grey text. Thumbnails give it a shape you can scan.
   The image is aria-hidden with an empty alt and tabindex -1 on purpose: it is decorative
   and duplicates the title link right beside it, so a screen reader would otherwise hear
   every entry twice and a keyboard user would tab through fourteen links to reach seven. */
/* max-width: none was WRONG and David caught it: the row then filled the 1080px wrap while
   every other block on the page stops at --measure, so the right edge of /writing sat further
   right than the rest of the site. The row is capped at --measure like its neighbours, and the
   thumbnail column comes OUT of that width rather than being added to it. */
.post-list > li.has-thumb {
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 22px;
  align-items: start;
  max-width: var(--measure);
}
.post-list .thumb { display: block; }
.post-list .thumb img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--paper-50);
}
.post-list .post-item-text { min-width: 0; }  /* the row is already capped; a second cap here does nothing but confuse */

@media (max-width: 640px) {
  .post-list > li.has-thumb { grid-template-columns: 1fr; gap: 14px; }
  .post-list .thumb img { max-height: 190px; }
}
