/* violetre.io -- the long-form analysis pages.
   =========================================================================
   A companion to site.css, loaded after it, on /analysis/ pages only.
   site.css is the authority for tokens, type, the masthead, the rail, the
   bands, the footer, the theme toggle, the privacy notice, the motion rules
   and print. Nothing here redefines a colour token: every value below is a
   token from site.css, so light and dark come for free and stay in step.

   What this file adds is one component family that the landing page has no
   use for: a tool-output pane. A long-form piece is mostly transcripts --
   a command, its output verbatim, and a caption saying what to read in it.
   The landing page's .listing/.src pair is a source listing with a path and
   a tag; a pane is a shell session with a title and a note. Close cousins,
   different jobs, so they are kept apart rather than one being bent into
   the other.

   The code colours were chosen for a dark ground when these pages were
   written. They are not here any more. A pane now takes --ink, --ink-2,
   --ink-3 and --code-comment off the shared palette, which means the same
   markup is legible on white paper and on the dark ground, and the two
   themes were measured rather than eyeballed.

   No inline styles, pure ASCII, no em dashes and no en dashes: the same
   three rules the pages themselves keep. */

/* ---------- No waitlist line on an article ----------
   site.css reserves --wl-h at the foot of .page for the fixed waitlist bar,
   and site.js measures the real height in when that bar exists. These pages
   have no bar, so the reservation is zero at every width. This declaration
   comes after the breakpoint overrides in site.css and has the same
   specificity, so it wins at all widths; the notice and the scroll padding
   fall into place behind it. */
:root {
  --wl-h: 0px;
}

/* ---------- Byline ----------
   Date, target and method, above the headline. The three machine facts a
   reader needs before deciding to read the piece. */
.byline {
  margin-bottom: clamp(16px, 2vw, 24px);
  font-family: var(--mono);
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--ink-3);
}
.byline b { color: var(--ink-2); font-weight: 400; }

/* An article headline is a sentence or three, not a four-word hero line, so
   it is set smaller and allowed more measure than site.css gives an h1. */
.hero h1 {
  font-size: clamp(1.875rem, 3.9vw, 3rem);
  font-size: clamp(1.875rem, 7cqi, 3rem);
  line-height: 1.07;
  letter-spacing: -0.02em;
  max-width: 28ch;
}
.hero-note { max-width: 56ch; }

/* ---------- Subsections ---------- */
.sub { margin-top: clamp(32px, 4.4vw, 56px); }
.sub h3 + .body { margin-top: 14px; }
.sub h3 + .pane { margin-top: 16px; }
.sub h3 + .pair { margin-top: 18px; }

/* ---------- Tool output panes ----------
   figure.pane
     figcaption.pane-head   what the pane shows / what produced it
     pre.out                the transcript, verbatim
     p.pane-foot            what to read in it
   The head sits on --paper so it separates from the transcript on
   --paper-2, which is the same two-tone the landing page's listings use. */
.pane {
  margin-top: clamp(22px, 3vw, 34px);
  border: 1px solid var(--line);
  background: var(--paper-2);
  min-width: 0;
}
.pane-head {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  justify-content: space-between;
  align-items: baseline;
  padding: 10px 14px;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--ink-3);
}
.pane-head b { color: var(--ink); font-weight: 400; }
.pane-head code { font-size: 1em; color: var(--ink); }

/* The transcript. The scroll cue is the one from site.css: a hairline and a
   faint shade on whichever edge still has something to show. --scroll-bg
   has to match the pane ground or the cue paints over the text. */
.out {
  --scroll-bg: var(--paper-2);
  margin: 0;
  min-width: 0;
  padding: 16px 14px 18px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.75rem;
  line-height: 1.7;
  tab-size: 4;
  color: var(--ink-2);
  white-space: pre;
  background:
    linear-gradient(var(--scroll-bg), var(--scroll-bg)) left / 14px 100% no-repeat local,
    linear-gradient(var(--scroll-bg), var(--scroll-bg)) right / 14px 100% no-repeat local,
    linear-gradient(var(--line-4), var(--line-4)) left / 1px 100% no-repeat scroll,
    linear-gradient(var(--line-4), var(--line-4)) right / 1px 100% no-repeat scroll,
    linear-gradient(to right, var(--shade), transparent) left / 12px 100% no-repeat scroll,
    linear-gradient(to left, var(--shade), transparent) right / 12px 100% no-repeat scroll;
}
@media (min-width: 640px) {
  .out { font-size: 0.8125rem; padding: 18px 16px 20px; }
}
.out:focus-visible { outline-offset: -2px; }
/* The rule above a caption belongs to the box, so it is drawn on the bottom
   of whatever the caption is about. Put on .pane-foot it would stop where
   the caption's 80ch measure stops, a third of the way short of the pane's
   own border on a wide column. */
.pane > .out:not(:last-child),
.pane > .chart:not(:last-child) { border-bottom: 1px solid var(--line); }
.pane-foot {
  padding: 12px 14px;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 80ch;
}
.pane-foot code { color: var(--violet-deep); }
.pane-foot a { font-weight: 500; }

/* ---------- Colour inside a transcript ----------
   Four weights, and two marks. The weights say what a line is: the command
   you typed is the strongest thing in the box, its prompt and its comments
   the quietest, an address quieter than the mnemonic beside it. The marks
   say which line the caption is about: amber for the line that carries the
   defect, violet for the line that fixed it. Both marks are a tint plus an
   underline, never colour alone, so they survive a greyscale print and a
   colour-vision difference. */
.cmd { color: var(--ink); }
.pr { color: var(--ink-3); }
.cm { color: var(--code-comment); }
.ad { color: var(--ink-3); }
.op { color: var(--violet-deep); }
.keep {
  color: var(--keep-ink);
  background: var(--keep-bg);
  box-shadow: inset 0 -1px 0 var(--violet);
}

/* ---------- Two transcripts side by side ----------
   .pair is site.css's two-column grid. Its own rules target .listing, so a
   pane inside one needs the same three adjustments. */
.pair { min-width: 0; }
.pair > .pane { margin-top: 0; display: flex; flex-direction: column; }
.pair > .pane > .pane-foot { margin-top: auto; }
@media (min-width: 980px) {
  .pair > .pane + .pane { border-left: 0; }
}
/* Which build a listing came from, said in the head's own colour rather
   than in words the caption would then have to repeat. */
.pane-vuln .pane-head b { color: var(--hold-ink); }
.pane-fix .pane-head b { color: var(--violet-deep); }

/* ---------- Named notes ----------
   A mono term and a paragraph, the same shape as .spec but for sentences
   rather than values, so the term can be longer than a field name. */
.notes {
  margin: 0;
  padding: 0;
  list-style: none;
  margin-top: clamp(24px, 3.2vw, 38px);
  border-top: 1px solid var(--ink);
}
.notes li {
  border-bottom: 1px solid var(--line);
  padding: 18px 0 20px;
  color: var(--ink-2);
}
.note-name {
  display: block;
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--violet-deep);
  margin-bottom: 7px;
}
.note-text { display: block; max-width: 64ch; }
.note-text code { color: var(--violet-deep); }
@media (min-width: 900px) {
  .notes li {
    display: grid;
    grid-template-columns: minmax(190px, 258px) minmax(0, 1fr);
    gap: 0 clamp(20px, 3vw, 40px);
    align-items: start;
  }
  .note-name { margin-bottom: 0; padding-top: 0.28em; }
}

/* ---------- Sources ----------
   Where each claim can be checked. A mono label, then the URL, printed in
   full so it can be read off paper and typed in. */
.sources {
  margin: 0;
  padding: 0;
  list-style: none;
  margin-top: clamp(22px, 3vw, 34px);
  border-top: 1px solid var(--line);
}
.sources li {
  border-bottom: 1px solid var(--line);
  padding: 12px 0;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-2);
}
.sources span {
  display: block;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink-3);
  margin-bottom: 3px;
}
.sources a { overflow-wrap: anywhere; }

/* ---------- The limits band ----------
   The section where the page says what the product would not find. It gets
   the one display line on the page after the headline, because it is the
   paragraph a reader is most likely to skip and most needs. */
.limit-body { max-width: 64ch; }
.limit-body p { font-size: 1.0625rem; line-height: 1.65; color: var(--ink-2); }
.limit-body p + p { margin-top: 0.95em; }
.verdict {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--ink);
  max-width: 24ch;
  margin-top: clamp(22px, 2.8vw, 32px);
  padding-bottom: 14px;
  border-bottom: 2px solid var(--hold-ink);
  margin-bottom: clamp(24px, 3vw, 34px);
}

/* ---------- Close ---------- */
.after-pair { margin-top: 22px; }
.after-line { margin-top: 24px; }
.close-line {
  margin-top: clamp(24px, 3.2vw, 36px);
  font-family: var(--serif);
  font-size: clamp(1.375rem, 2.4vw, 1.875rem);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.014em;
  color: var(--ink);
  max-width: 28ch;
}

/* ---------- The chart ----------
   One figure, two lines, drawn from the table printed directly above it. The
   colours were hard-coded hex in the SVG, which is why it only worked on a
   dark ground; they are classes now and the geometry is untouched. Two
   lines, so they are told apart by weight and by dash, not by hue: the
   series carries a solid stroke in --ink, the subset a dashed stroke in
   --ink-3, and each is labelled at its own right-hand end. */
.chart-pane .chart {
  display: block;
  width: 100%;
  height: auto;
  padding: 14px 10px 6px;
}
.chart text {
  font-family: var(--mono);
  font-size: 11px;
  fill: var(--ink-3);
}
.chart .l1 { fill: var(--ink); }
.chart .l2 { fill: var(--ink-2); }
/* --line-3, not --line: a gridline a reader is meant to follow across to the
   axis needs more presence than a hairline between two blocks of prose, and
   the two themes come out level at 1.78 and 1.97 against the pane ground. */
.chart .ch-grid { stroke: var(--line-3); }
.chart .ch-a { stroke: var(--ink); }
.chart .ch-b { stroke: var(--ink-3); }
.chart .ch-dot-a { fill: var(--ink); }
.chart .ch-dot-b { fill: var(--ink-3); }
/* Narrow: the viewBox scales down with the column, so the type scales with
   it and has to be set back up. The leading word of each end label goes,
   leaving the figure. */
@media (max-width: 639px) {
  .chart text { font-size: 20px; }
  .chart .wide { display: none; }
}
/* The key, in the pane head rather than under the figure, so the figure is
   not pushed further down the column. Named .keys, not .legend: site.css
   owns .legend for the swatch row under a listing pair. */
.keys {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
}
.key {
  display: inline-block;
  width: 22px;
  height: 0;
  vertical-align: middle;
  margin-right: 7px;
  border-top: 2px solid var(--ink);
}
.key-dash { border-top: 2px dashed var(--ink-3); }

/* ---------- Motion ----------
   The reference's cascade, for a page whose headline is a sentence rather
   than a phrase. The landing page rises its headline a word at a time; an
   eighteen-word opening sentence does not take that, so the headline rises
   as one line and the lede and the note follow it. Keyframes, easing and
   the reduced-motion override all come from site.css: under
   prefers-reduced-motion: reduce every duration there becomes 0.001ms, so
   nothing below needs repeating.
   Everything else on these pages is a [data-reveal] or a .draws-top, which
   site.css already drives. */
@media (prefers-reduced-motion: no-preference) {
  .hero h1 { animation: rise-soft 0.9s var(--ease) 0.1s both; }
  .hero .lede { animation-delay: 0.34s; }
  .hero-note { animation-delay: 0.5s; }
  .byline { animation: fade 0.7s ease both; }
}

/* ---------- Print ----------
   site.css forces the light palette and unhides everything a reveal hid.
   These three keep a transcript from being cut off at the page edge. */
@media print {
  .out { white-space: pre-wrap; overflow: visible; background: none; }
  .pane, .notes li, .chart-pane { break-inside: avoid; }
  .verdict { border-bottom-width: 1px; }
}
