/* payoff.css: PAYOFFS. THE CONTROL IS THE PAGE.
 * ===========================================================================
 * THIS SHEET IMPORTS NOTHING AND CONTAINS NO SECOND DESIGN SYSTEM, which is
 * the whole reason it needs no firewall. Everything below is built out of the
 * app's OWN tokens (--ink/--ink2/--ink3, --line, --accent, --bg, --neg,
 * --hover-wash, --mono, --focus, --t-xs/--t-sm/--t-md/--t-lg/--t-hero,
 * --tr-label), so there is nothing here to contain and nothing that can leak.
 * No @keyframes are declared either: keyframe names are document-global and a
 * class prefix cannot scope them.
 *
 * ── WHAT THE SHEET IS DRAWING ─────────────────────────────────────────────
 * One control and its readouts. The plot, the rail and the ribbon are three
 * grips on a single handle, and every other object on the section is either a
 * figure the handle produces or a figure the CONTRACT produces. Those two are
 * drawn differently and labelled differently, and that division is the design:
 *
 *   .pf-out[data-lane="live"]    an --accent rule down the left edge. It
 *                                lights on --hover-wash while a drag is in
 *                                progress, so the first drag a reader makes
 *                                shows them which half of the page answers
 *                                their finger.
 *   .pf-out[data-lane="fixed"]   a --line rule. Same shape, no light, and the
 *                                label says why.
 *
 * ── WHAT !important IS AND IS NOT FOR ─────────────────────────────────────
 * instrument.css:343 pins font-size, font-family, font-weight, letter-spacing,
 * border-radius and box-shadow on `body *:not(svg):not(svg *)` with
 * !important, and an important declaration beats a normal one at ANY
 * specificity. It does NOT pin colour, border, padding, margin, display, grid
 * or white-space, which is nearly everything in this file. The few rules that
 * do carry it are claiming a type ROLE, and every size they claim is one the
 * scale already defines: --t-xs, --t-md, --t-lg and --t-hero, and nothing
 * between 15px and 30px, because there IS nothing between them.
 *
 * instrument.css:1883 is the trap: a SECOND blanket sets font-family to
 * var(--sans) on the same selector, so the default face on the live page is
 * not the mono stack. A figure that wants tabular digits says
 * `font-family: var(--mono) !important` for itself. Every figure below does.
 *
 * TWO CONSEQUENCES OF THAT NORMALISER ARE LOAD BEARING:
 *   box-shadow is pinned to `none !important`, so the selected step cannot be
 *   marked with an inset shadow. It uses `outline` with a negative offset,
 *   which the normaliser does not touch.
 *   border-radius is pinned to 0 on ELEMENTS but not on ::-webkit-slider-thumb,
 *   which is why the thumb is round with a plain declaration while the HTML
 *   markers have to restate theirs importantly. Verified on a PNG: the markers
 *   rendered as SQUARES on the first pass and the thumb did not.
 *
 * FOUR TOKENS THAT LOOK USABLE AND ARE NOT: --accent-ink resolves to the same
 * value as --accent on this theme, so anything sitting on an accent fill takes
 * --bg; --fill-1 and --fill-2 are both transparent, so a hover painted with
 * either does not exist and --hover-wash is the one that works.
 * ─────────────────────────────────────────────────────────────────────────── */

/* ══ 0. THE TWO STATES THE SECTION CAN BE IN BEFORE IT HAS ANYTHING ════════ */

.pf-wait { color: var(--ink2); padding: 40px 0; text-align: center; }
html body .pf-lede {
  margin: 14px 0 0;
  color: var(--ink2);
  max-width: 84ch;
  line-height: 1.55;
}

/* ══ 1. THE INSTRUMENT ═════════════════════════════════════════════════════
 * .pf-sim is the whole control, and it exists as one element so that the drag
 * can write ONE attribute on it and the sheet can light the live lane from
 * there. data-drag is set on pointerdown and removed on pointerup, and it is
 * the only state in this sheet that a gesture writes.
 * ─────────────────────────────────────────────────────────────────────────── */

.pf-sim { margin: 18px 0 0; }

/* ── the strike and the premium, as figures rather than as a form ───────────
   They were two labelled boxes in a control row, one pinned to the left edge
   and one to the right, which is the shape of a settings dialog. Both are
   still settable, because the premium being the READER'S number rather than
   ours is what keeps this section inside the rule that Moneyness quotes
   nothing. So they are set as editable figures inside the line that names what
   is drawn: a dotted rule underneath, no box, no fill, sized to their content.
   Nothing on this panel looks like a field except the two things that
   genuinely are one. */
.pf-set {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 9px 26px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
/* THE WHOLE ROW IS ONE SIZE, and the loudness is bought with INK and WEIGHT
   rather than with size. At --t-lg the position competed with the display
   figure below it, which is the "numbers should adapt" complaint restated one
   line higher. Every item in the row is --t-md, which is what makes it read as
   one line rather than as four. */
html body .pf-set-p {
  color: var(--ink);
  font-weight: 600 !important;
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-md) !important;
}
.pf-set-h { display: inline-flex; align-items: baseline; gap: 10px; }
html body .pf-set-u {
  color: var(--ink2);
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-md) !important;
}
.pf-set-f { display: inline-flex; align-items: baseline; gap: 8px; }
html body .pf-set-f label {
  color: var(--ink3);
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-in {
  -moz-appearance: textfield;
  appearance: textfield;
  background: transparent;
  border: 0;
  border-bottom: 1px dashed var(--ink3);
  color: var(--ink);
  font-family: var(--mono) !important;
  font-size: var(--t-md) !important;
  font-variant-numeric: tabular-nums;
  padding: 1px 0 3px;
  width: 8ch;
  min-width: 0;
  text-align: left;
}
/* The spinners are a form's furniture and this is not a form. */
.pf-in::-webkit-outer-spin-button,
.pf-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pf-in:hover { border-bottom-color: var(--ink2); }
.pf-in:focus { outline: none; border-bottom: 1px solid var(--accent); }
.pf-in:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

html body .pf-seed {
  color: var(--ink3); line-height: 1.5; margin: 11px 0 0; max-width: 84ch;
}
html body .pf-seed b { color: var(--ink2); font-weight: 600 !important; }

/* ── THE GRAB TARGETS ───────────────────────────────────────────────────────
   touch-action IS DECLARED HERE, ON THE ELEMENTS THAT RECEIVE THE POINTER,
   AND ON NO WRAPPER. With it on the wrapper instead, measured on an iPhone 13
   profile, computed touch-action on the svg read "auto", the browser claimed
   the gesture for a page scroll, and pointerdown fired ZERO times. That
   presents as "the drag is broken" and is really "the drag never received an
   event".

   IT HANGS OFF [data-grab] RATHER THAN OFF EACH CLASS. There are two grab
   targets now, the plot and the ribbon, and a third can be added without
   anyone remembering to bring the one declaration that makes it work. */
.pf-sim [data-grab] {
  touch-action: none;
  cursor: grab;
}
.pf-sim [data-grab].pf-dragging { cursor: grabbing; }
.pf-sim [data-grab]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* ── the stage ──────────────────────────────────────────────────────────────
   No frame around it. The zero line inside the plot, the rail's track under it
   and the ribbon's base line are already three hairlines, and a box would be a
   fourth arguing with all of them. The composition reads picture, track,
   landmarks, which is the shape of every range control with a distribution
   drawn on it. */
.pf-stage { position: relative; margin: 20px 0 0; }
.pf-svg {
  display: block;
  width: 100%;
  /* 280 AND NOT 300, SETTLED ON THE SHORT PUT'S OWN PNG. The scale is fixed at
     plus or minus 1.5 strikes on all four positions so the put curves visibly
     STOP while the call curves leave the frame, which means the short put's
     upper half is empty at every height: its ceiling is the premium. Height
     only decides how much of the picture that emptiness is. 220 was too small
     to lead the section; 320 was rendered and rejected, because the void above
     the flat line becomes the biggest object in the frame; 280 is the last
     height where the drop still dominates what you see. Tightening y so the
     frame fills is not available: the same axis on all four positions is what
     lets the puts stop and the calls run, and that comparison is the section. */
  height: 280px;
  touch-action: none;
}

/* ONE SHADED REGION, AND IT IS THE LOSS. There were two, jade above the zero
   line and rose below it, and on a long call the jade wash was the largest
   object in the frame while the payoff LINE, which is the claim, competed with
   it. The gain is unshaded and the line's position above zero says it.
   Deliberately weak either way: the line is the claim, the area is a hint. */
.pf-fill-dn { fill: var(--neg); opacity: 0.16; }

/* THE CURVE IS TWO POLYLINES, ONE PER LEG, and .pf-stage's data-leg says which
   one the handle is standing on. The live leg is HEAVIER and the other keeps
   its full colour: nothing is faded, because on a short put the sloped loss
   leg is the entire point of the picture and dimming it while the reader
   stands on the flat side would hide the fact the section exists to show.
   Weight, not opacity.

   fill:none is not cosmetic. An unstyled <polyline> is not invisible: SVG
   defaults it to a solid BLACK FILL, so the payoff renders as a black wedge,
   which is a working DOM and a broken picture. */
.pf-line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.2;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.pf-stage[data-leg="a"] .pf-leg-a,
.pf-stage[data-leg="b"] .pf-leg-b { stroke-width: 4; }

.pf-zero { stroke: var(--ink3); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pf-strikeline {
  stroke: var(--ink3); stroke-width: 1; stroke-dasharray: 3 4;
  vector-effect: non-scaling-stroke;
}
/* THE CROSSHAIR. Two lines, one per axis, so the handle reads as WHERE you are
   and WHAT IT IS WORTH at the same time. They are the same weight and the same
   dash because they are one mark: a crosshair drawn in two colours reads as
   two unrelated rules crossing. */
.pf-spotline,
.pf-pnlline {
  stroke: var(--ink2); stroke-width: 1; stroke-dasharray: 2 3;
  vector-effect: non-scaling-stroke;
}

/* ── the marks, which are HTML sitting over the svg ─────────────────────────
   THEY WERE <circle> AND <polygon> AND EVERY ONE OF THEM WAS DISTORTED. The
   svg carries preserveAspectRatio="none", so x and y scale by different
   factors and a circle comes out an ellipse: measured on the PNG, a tall
   narrow egg at 390 and a wide flat one at 1400. Paths in there are MEANT to
   be distorted, because the curve's shape is the scales' job. A marker is not.

   In HTML they are placed in percentages of the stage, which is aspect
   independent by construction, and CSS gives them their shape at any rendered
   size. pointer-events IS NONE ON ALL OF THEM: they sit ON a grab target, and
   a marker that swallowed the pointerdown underneath it would break the
   control it exists to describe. */
.pf-mk {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
/* border-radius CARRIES !important AND IT HAS TO. instrument.css pins
   `border-radius: 0 !important` on `body *:not(svg):not(svg *)`, and these
   marks stopped being svg children the moment they moved to HTML, so the pin
   reaches them: measured on the PNG, both dots rendered as SQUARES on the
   first pass. A class selector is (0,1,0) against that rule's (0,0,3), so
   restating it importantly here wins. */
.pf-mk-spot {
  width: 18px;
  height: 18px;
  border-radius: 50% !important;
  background: var(--accent);
  border: 2px solid var(--bg);
  transition: width 90ms ease-out, height 90ms ease-out;
}
.pf-sim[data-drag="1"] .pf-mk-spot { width: 24px; height: 24px; }
.pf-mk-be {
  width: 8px; height: 8px; border-radius: 50% !important; background: var(--ink);
}
/* THE EDGE WEDGE carries no caption. It is the payoff line continuing past the
   frame, so it takes the payoff line's colour and means exactly that in both
   directions. In --neg it marked an unbounded GAIN in the loss hue on the long
   call, which is the one position whose upside is the entire point. A CSS
   triangle rather than a glyph, so it needs no font and cannot fall back to a
   box. */
.pf-mk-runs {
  position: absolute;
  right: 0;
  pointer-events: none;
  width: 0;
  height: 0;
  border-left: 15px solid var(--accent);
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
}
.pf-mk-runs[data-dir="up"] { transform: translateY(-2px); }
.pf-mk-runs[data-dir="dn"] { transform: translateY(-16px); }

/* ── the spot flag, which is the handle's own readout ───────────────────────
   IT RIDES AT A FIXED HEIGHT AND MOVES ONLY IN x. It was drawn above the dot
   for one pass and it clipped out of the frame the moment the dot reached the
   top or the bottom of the plot, which on the two unbounded positions is most
   of the frame. Pinned to the top of the plot on the spot line it can never
   leave the picture, and it is always in the same place, which is what a value
   flag on a scrub track is for.

   IT CARRIES THE SPOT AND NOT THE PAYOFF. The control shows its INPUT and the
   page shows its OUTPUT, once each: printing the payoff here as well would put
   the same figure on the panel twice, which is the duplication this section
   has been cut twice to remove.

   data-edge IS HOW IT STAYS INSIDE THE FRAME. translateX(-50%) hangs half the
   flag off the left edge when the handle is at zero. Rather than measuring the
   flag's width on every frame, which is a forced reflow inside a drag, the
   script writes one of three states and the transform follows. */
.pf-flag {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 3px 8px 4px;
  background: var(--bg);
  border: 1px solid var(--line);
  white-space: nowrap;
  pointer-events: none;
}
.pf-flag[data-edge="l"] { transform: none; }
.pf-flag[data-edge="r"] { transform: translateX(-100%); }
html body .pf-flag i {
  color: var(--ink3);
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-flag b {
  color: var(--ink);
  font-family: var(--mono) !important;
  font-size: var(--t-md) !important;
  font-weight: 600 !important;
  font-variant-numeric: tabular-nums;
}
.pf-sim[data-drag="1"] .pf-flag { border-color: var(--accent); }

/* ── the rail: the second grip on the same control ──────────────────────────
   width is 100% + one thumb and the margin pulls back half a thumb at each
   end, so the thumb CENTRE travels the stage's full width rather than the
   track's inset. margin-top is minus half the rail's height, which puts the
   track on the stage's bottom edge, where the spot line arrives.
   The thumb is round: instrument.css pins border-radius to 0 on `body *`, and
   `body *` matches ELEMENTS, never ::-webkit-slider-thumb. Verified on a PNG. */
.pf-railwrap { position: relative; margin-top: -13px; }
html body .pf-rail {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: calc(100% + 20px);
  margin: 0 -10px;
  height: 26px;
  padding: 0;
  background: transparent;
  cursor: ew-resize;
}
/* THE TRACK IS TWO GREYS AND NOT THE ACCENT, and that is a correction made on
   the rendered PNG. Painted accent, the filled half of the track was a second
   full-width orange horizontal line sitting under the payoff line, which is
   also a full-width orange horizontal line on three of the four positions. Two
   identical marks, one measured and one furniture, is exactly the confusion
   this section cannot afford. The accent is spent on ONE thing per object: the
   payoff line in the plot, the thumb on the rail, the handle tick on the
   ribbon.

   It is still split rather than flat, because the filled share is what tells a
   reader the rail is a control at all, and --line against this ground is very
   nearly invisible on its own. Custom properties cascade into pseudo-elements
   from the element they are set on, so one --pf-fill written on the input by
   payoff.js drives both halves. */
.pf-rail::-webkit-slider-runnable-track {
  height: 2px;
  border: 0;
  background: linear-gradient(
    to right,
    var(--ink2) 0%,
    var(--ink2) var(--pf-fill, 50%),
    var(--line) var(--pf-fill, 50%),
    var(--line) 100%
  );
}
.pf-rail::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  margin-top: -9px;
  cursor: grab;
}
.pf-rail::-moz-range-track { height: 2px; background: var(--line); border: 0; }
.pf-rail::-moz-range-progress { height: 2px; background: var(--ink2); }
.pf-rail::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg); cursor: grab;
}
.pf-rail:focus { outline: none; }
.pf-rail:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* ══ THE RIBBON: THE LANDMARKS, IN TWO LANES, AND THE THIRD GRIP ═══════════
 * It replaces the three label axis and it is a grab target as well as a
 * legend, which is the point: the strip that names where things are is also a
 * strip you can put the handle on.
 *
 * TWO LANES BECAUSE THE TWO LANDMARKS COLLIDE. On the seeded short put the
 * strike sits at 40.0% of the frame and the settle at 46.2%, which is 55px
 * apart at a 1030px render against labels about 90px wide. Stacking them is
 * not only a collision fix, it is the correct division:
 *
 *   ABOVE the track   what the CONTRACT says. The strike. Arithmetic on the
 *                     reader's own two numbers.
 *   BELOW the track   what the TAPE says. Where the underlying actually
 *                     settled, with the venue that printed it and the date.
 *
 * On this product those two do not share a line, and the measured one is the
 * only tick drawn solid and in full ink. Everything else on that axis is a
 * scenario. A reader who cannot tell them apart reads the whole axis as data.
 *
 * ITS PROVENANCE IS ON THE PAGE AND NOT IN A title ATTRIBUTE. A title is not a
 * disclosure: it does not exist on a phone, and an audit of one section
 * measured 67.6% of its prose sitting behind hover.
 * ─────────────────────────────────────────────────────────────────────────── */

.pf-rib { margin-top: 11px; }
.pf-rib-lane {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0;
  min-height: 14px;
}
.pf-rib-lane[data-lane="contract"] { margin-bottom: 5px; }
.pf-rib-lane[data-lane="tape"] { margin-top: 6px; }
.pf-rib-t {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
}
html body .pf-rib-t i,
html body .pf-rib-t em,
html body .pf-rib-e {
  color: var(--ink3);
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-rib-e {
  font-family: var(--mono) !important;
  text-transform: none;
  font-variant-numeric: tabular-nums;
}
html body .pf-rib-t b {
  color: var(--ink2);
  font-family: var(--mono) !important;
  font-size: var(--t-xs) !important;
  font-weight: 600 !important;
  font-variant-numeric: tabular-nums;
}
/* THE MEASURED LANDMARK IS THE ONLY ONE IN FULL INK. It is the one figure on
   this axis that we observed rather than computed, and it is drawn as the
   loudest thing on the ribbon for exactly that reason. */
html body .pf-rib-t[data-m="1"] b { color: var(--ink); }

.pf-rib-svg {
  display: block;
  width: 100%;
  height: 26px;
}
.pf-rib-base { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pf-rib-k {
  stroke: var(--ink3); stroke-width: 1; stroke-dasharray: 3 4;
  vector-effect: non-scaling-stroke;
}
.pf-rib-m { stroke: var(--ink); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.pf-rib-h { stroke: var(--accent); stroke-width: 2; vector-effect: non-scaling-stroke; }

/* ── the legend, which is the only instruction on the section ───────────────
   A section built around one control has to say what that control answers, and
   nothing else here does. The three letters are the three points on the axis
   worth landing on EXACTLY rather than approximately: a drag is approximate by
   construction, and the strike, the break even and the settle are the places
   where approximate is not good enough. */
.pf-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 7px 18px;
  margin: 14px 0 0;
}
.pf-key { display: inline-flex; align-items: baseline; gap: 7px; }
html body .pf-key {
  color: var(--ink3);
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
}
html body .pf-key[data-k="drag"] { color: var(--ink2); }
html body .pf-key kbd {
  color: var(--ink2);
  font-family: var(--mono) !important;
  font-size: var(--t-xs) !important;
  letter-spacing: normal !important;
  border: 1px solid var(--line);
  padding: 2px 6px;
}

/* ══ 2. THE READOUTS, IN TWO LANES ═════════════════════════════════════════
 * THIS IS THE PRODUCT AND THE LANES ARE THE ARGUMENT. A reader cannot see
 * which figures answer their finger, and both guesses available to them are
 * wrong: either the whole panel is live, which it is not, or none of it is,
 * which it is not either. So the readouts are split, labelled and given
 * different rules, and the live lane's rule lights during a drag.
 *
 * .ds-stat IS DELIBERATELY NOT USED HERE. system.css requires a population and
 * a window slot on it and draws a red banner when they are missing, because
 * every other figure on this site is measured. These are NOT measured: they
 * are arithmetic on numbers the reader can edit. Faking a population to get
 * past the guard would be the exact failure the guard exists to catch, and
 * stripping the guard would be worse. The lane labels are the honest answer:
 * they say what produced the figure instead of pretending it has a tape behind
 * it. The three figures on this section that DO have a population, the strike,
 * the premium and the settle, carry it: the first two on the seed line with
 * the method mark, the third on the ribbon and in the disclosure.
 * ─────────────────────────────────────────────────────────────────────────── */

.pf-out {
  margin: 30px 0 0;
  padding: 0 0 0 18px;
  border-left: 2px solid var(--line);
}
.pf-out[data-lane="live"] { border-left-color: var(--accent); }
/* THE FIRST DRAG SHOWS THE READER WHICH HALF OF THE PAGE THEY ARE STEERING.
   Nothing else on the section says it, and a sentence saying it would be a
   sentence. --hover-wash rather than --fill-1 or --fill-2: both of those are
   transparent on every theme here, so a wash painted with either does not
   exist. */
.pf-sim[data-drag="1"] .pf-out[data-lane="live"] {
  background: var(--hover-wash);
}
.pf-lane {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 3px 12px;
  margin: 0 0 14px;
}
html body .pf-lane span {
  color: var(--ink2);
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
  font-weight: 600 !important;
}
.pf-out[data-lane="live"] .pf-lane span { color: var(--ink); }
html body .pf-lane i {
  color: var(--ink3);
  font-style: normal;
  font-size: var(--t-xs) !important;
}

.pf-live { display: flex; flex-direction: column; gap: 7px; }
/* THE ONE DISPLAY FIGURE ON THE SECTION, drawn exactly the way detail.css
   draws .vp-num-n: --t-hero, 0.92 leading so a 76px number does not reserve
   100px of line box, and -0.045em so the digits sit as one shape. */
html body .pf-live-n {
  font-family: var(--mono) !important;
  font-size: var(--t-hero, clamp(48px, 6.6vw, 76px)) !important;
  font-weight: 600 !important;
  line-height: 0.92;
  letter-spacing: -0.045em !important;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
/* A GAIN IS INK, WHICH IS WHAT THE APP'S OWN HEROES DO: .vp-num-n and
   .mn-hero-n both draw the display figure in --ink and reserve their colour
   variants for STATE, never for sign. A LOSS keeps --neg, because that is this
   section's one exposure hue and the figure going red as the handle crosses
   break even is the reading. There is no .pf-up rule; the class is written so
   the element can be styled by state later, and it resolves to ink today. */
html body .pf-live-n.pf-dn { color: var(--neg); }
html body .pf-live-u {
  color: var(--ink3);
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}

/* ── the three relations ────────────────────────────────────────────────────
   All three are the handle against a landmark, and nothing else. Spot against
   strike, spot against break even, and the word for which side of the strike
   an option of this kind is on. NO PROBABILITY, NO EXPECTED VALUE, NO VOL: a
   figure saying how LIKELY any of it is would be a model, and this section
   does not own one.

   "IN THE MONEY" is a property of the OPTION and not of your position, and the
   copy says so. A short put that is in the money is the writer's bad day, so
   "you are in the money" would be exactly backwards half the time. */
.pf-chips {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px 26px;
  margin: 26px 0 0;
}
.pf-chip { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
html body .pf-chip i {
  color: var(--ink3);
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-chip b {
  color: var(--ink);
  font-family: var(--mono) !important;
  font-size: var(--t-md) !important;
  font-weight: 600 !important;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
  min-height: 1em;
}
/* THE WORD CHIP IS DRAWN AS A WORD. Tracked and lighter than the two figures
   beside it, the same treatment NO CEILING gets, so it can never be scanned as
   a quantity that happens to be spelled out. */
html body .pf-chip b.pf-w {
  font-weight: 400 !important;
  letter-spacing: 0.04em !important;
}

/* ── the three bounds ───────────────────────────────────────────────────────
   THEY KEEP THREE FIXED PLACES, so switching position reads as the NUMBERS
   CHANGING rather than as a new panel arriving. That fixed order is the
   comparison: watch MOST YOU CAN LOSE go from a premium to NO CEILING when you
   step from the long call to the short call. */
.pf-b3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  margin: 0;
}
.pf-b {
  background: var(--bg);
  padding: 13px 16px 15px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
html body .pf-b-l {
  color: var(--ink3);
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-b-v {
  color: var(--ink);
  font-family: var(--mono) !important;
  font-size: var(--t-lg) !important;
  font-weight: 600 !important;
  line-height: 1;
  letter-spacing: -0.02em !important;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
/* MOST YOU CAN MAKE IS INK. It was jade, which made the strip a traffic light
   and put a third hue on the panel to say what its own label already says.
   MOST YOU CAN LOSE keeps --neg because exposure is the one thing this section
   colours, and NO CEILING lands in that cell in that hue on the short call,
   which is the loudest true fact on the panel. */
.pf-b[data-kind="loss"] .pf-b-v { color: var(--neg); }
/* UNBOUNDED IS A WORD AND IT IS DRAWN AS ONE. Still at figure scale, because
   it is the loudest fact on the panel, but tracked and lighter so it can never
   be scanned as a quantity. */
html body .pf-b-v.pf-b-none {
  font-weight: 400 !important;
  letter-spacing: 0.04em !important;
}

/* ══ 3. THE DECK: ONE CONTRACT, TWO SIDES, ONE AT A TIME ═══════════════════
 * It is the ONLY position control. The card you are looking at IS the selected
 * position, so there is no display here and a control somewhere else, which is
 * the duplication deleted at 77b9122. NO SEGMENTED CONTROL COMES BACK.
 *
 * AND IT IS DOWNSTREAM OF THE HANDLE TOO. .pf-atspot carries the live lane's
 * accent rule, because it is the one line in this object that answers the
 * handle and a reader has to be able to tell it from the two hands underneath,
 * which do not.
 * ─────────────────────────────────────────────────────────────────────────── */

html body .pf-h {
  margin: 46px 0 4px; padding-top: 22px;
  border-top: 1px solid var(--line);
  color: var(--ink);
  font-size: var(--t-md) !important; font-weight: 600 !important;
  max-width: 84ch; line-height: 1.5;
}
html body .pf-sub {
  margin: 0 0 4px; color: var(--ink3); max-width: 84ch; line-height: 1.5;
}
html body .pf-sub b { color: var(--ink2); font-weight: 600 !important; }

.pf-deck { border: 1px solid var(--line); margin: 14px 0 0; }
.pf-deck-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
}
html body .pf-deck-k {
  color: var(--ink3);
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
.pf-deck-nav { display: inline-flex; align-items: center; gap: 12px; }
html body .pf-deck-i {
  color: var(--ink3);
  font-family: var(--mono) !important;
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
}
/* An outline rather than a shadow, because box-shadow is pinned to none. */
html body .pf-nav {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink2);
  cursor: pointer;
  line-height: 1;
  padding: 5px 11px 7px;
  font-size: var(--t-md) !important;
}
.pf-nav:hover { color: var(--ink); border-color: var(--ink3); }
.pf-nav:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* THE LIVE LINE ON THE CARD. As you scrub across the strike on a short put it
   turns "The buyer walks away. You keep the premium." into "You are made to
   buy HYPE at $73.22." That is the owner's own correction, delivered by the
   gesture rather than by a badge:

     "Selling a put gives you an obligation, never a right. You cannot decide
      to buy at 61k. You can only be made to." */
.pf-atspot {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0;
  padding: 14px 16px 15px;
  border-left: 2px solid var(--accent);
  border-bottom: 1px solid var(--line);
}
html body .pf-atspot i {
  color: var(--ink3);
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-atspot b {
  color: var(--ink);
  font-size: var(--t-md) !important;
  font-weight: 600 !important;
  line-height: 1.45;
}

/* EVERY CARD CARRIES BOTH SIDES OF THE SAME CONTRACT, facing each other across
   one hairline. The grid put a RIGHT and an OBLIGATION in different quadrants,
   describing two different contracts; the card puts them on ONE. */
.pf-card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--line);
  /* pan-y, NEVER none. none would take the vertical scroll away from a reader
     whose thumb lands on the card, which is most of a phone screen at this
     point in the section. pan-y leaves the page scrolling and gives us the
     horizontal axis. */
  touch-action: pan-y;
}
.pf-hand {
  background: var(--bg);
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}
.pf-hand[data-who="them"] .pf-hand-do,
.pf-hand[data-who="them"] .pf-hand-l { color: var(--ink2); }
html body .pf-hand-w {
  color: var(--ink3);
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-hand-do {
  color: var(--ink);
  font-size: var(--t-lg) !important;
  font-weight: 600 !important;
  line-height: 1.05;
  letter-spacing: -0.02em !important;
}
/* THE TWO BADGES ARE THE ASYMMETRY AND THEY ARE THE ONLY PLACE IT IS COLOURED.
   ON THE FILLED BADGE THE INK IS --bg AND NOT --accent-ink: this theme
   resolves --accent and --accent-ink to the same value, so accent-ink on an
   accent fill prints the accent on the accent and the badge renders as a blank
   orange blob. */
html body .pf-hand-b {
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
  font-weight: 600 !important;
  padding: 4px 9px 5px;
  border: 1px solid var(--line);
}
.pf-hand[data-hold="right"] .pf-hand-b { color: var(--ink); }
.pf-hand[data-hold="obligation"] .pf-hand-b {
  background: var(--neg);
  border-color: var(--neg);
  color: var(--bg);
}
html body .pf-hand-l { color: var(--ink); line-height: 1.45; }
html body .pf-hand-p {
  color: var(--ink3);
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
}

/* THE STEPS ARE THE PAGER AND THE PAGER IS FOUR PAYOFF SHAPES, not four dots,
   so the side by side comparison the 2x2 carried in badges survives inside the
   one object you steer with. */
.pf-steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
}
html body .pf-step {
  background: var(--bg);
  border: 0;
  cursor: pointer;
  padding: 10px 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}
.pf-step:hover { background: var(--hover-wash); }
.pf-step:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
/* AN OUTLINE WITH A NEGATIVE OFFSET AND NOT A SHADOW. box-shadow is pinned to
   `none !important` by the normaliser, and the negative offset keeps the mark
   inside the 1px grid gap instead of straddling it. */
.pf-step[data-on="1"] {
  outline: 1px solid var(--accent);
  outline-offset: -1px;
}
.pf-step .pf-gl { width: 100%; max-width: 78px; height: 20px; display: block; }
.pf-gl-l { fill: none; stroke-width: 2; vector-effect: non-scaling-stroke; }
.pf-gl-z { stroke: var(--line2); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* The selected glyph takes the accent, which is "where you are" everywhere in
   this app. The unselected ones stay --ink3: the badges above carry right
   against obligation, and repeating that distinction down here in a second
   place would spend a third hue to say it twice. */
.pf-step .pf-gl-l { stroke: var(--ink3); }
.pf-step[data-on="1"] .pf-gl-l { stroke: var(--accent); }

/* "The buyer chooses. The seller is chosen." is the whole deck in six words,
   so it sits directly under it rather than in a caption further down. */
html body .pf-ro-n { color: var(--ink2); margin: 10px 0 0; }

/* ══ 4. THE CAVEATS, BEHIND A DISCLOSURE THAT ACTUALLY OPENS ═══════════════
 * The facts are not negotiable and none of them was dropped. What changed is
 * where they are read: a 130 word paragraph, then labelled rows standing open,
 * and now those same rows one click inside a <details>, plus one new row for
 * the measured settle this build puts on the axis.
 *
 * THE SUMMARY IS DRAWN THE WAY premium.css DRAWS ITS OWN, and it is restated
 * here rather than imported, because this sheet imports nothing on purpose.
 * Native <details> needs no script, so this disclosure cannot become a control
 * that looks live and opens nothing, which is what the footer's own "How this
 * is measured" button is today.
 * ─────────────────────────────────────────────────────────────────────────── */

.pf-m { margin: 36px 0 0; border-top: 1px solid var(--line); }
html body .pf-m > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 12px 0;
  color: var(--ink3);
  text-transform: uppercase;
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
}
.pf-m > summary::-webkit-details-marker { display: none; }
/* A CHARACTER RATHER THAN A GLYPH FONT, so it cannot fall back to a box, and
   U+2212 rather than a hyphen so the open state reads as a minus at the same
   width as the plus. */
.pf-m > summary::before { content: "+"; line-height: 1; opacity: 0.75; }
.pf-m[open] > summary::before { content: "\2212"; }
.pf-m > summary:hover { color: var(--ink); }
.pf-m > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.pf-notes { margin: 0 0 8px; border-top: 1px solid var(--line); }
.pf-note {
  display: grid;
  grid-template-columns: 128px 1fr;
  gap: 4px 22px;
  padding: 11px 0 12px;
  border-bottom: 1px solid var(--line);
}
html body .pf-note-k {
  color: var(--ink3);
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
  padding-top: 2px;
}
html body .pf-note-v { color: var(--ink2); line-height: 1.55; max-width: 86ch; }
html body .pf-note-v b { color: var(--ink); font-weight: 600 !important; }

/* ══ 5. THE PHONE ═════════════════════════════════════════════════════════
 * 620px is the app's one shared breakpoint. The grab band is what this build
 * protects here: 240 of plot, 32 of rail and 34 of ribbon is a continuous
 * 306px tall target, which is what makes the handle usable with a thumb rather
 * than with a stylus.
 * ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 620px) {
  .pf-svg { height: 240px; }
  .pf-mk-spot { width: 16px; height: 16px; }
  /* The thumb grows on a phone because a finger is 44px wide and a 20px target
     is a miss waiting to happen. The rail's own geometry follows it, or the
     handle would stop agreeing with the plot's x range. */
  .pf-railwrap { margin-top: -16px; }
  html body .pf-rail { height: 32px; width: calc(100% + 26px); margin: 0 -13px; }
  .pf-rail::-webkit-slider-thumb { width: 26px; height: 26px; margin-top: -12px; }
  .pf-rail::-moz-range-thumb { width: 22px; height: 22px; }
  .pf-rib-svg { height: 34px; }
  /* ONE COLUMN, NOT THREE. Three relations at about 90px each break their own
     labels over four ragged lines, and a figure whose label is unreadable is
     not a figure. */
  .pf-chips { grid-template-columns: 1fr; gap: 15px; }
  .pf-b3 { grid-template-columns: 1fr; }
  /* THE TWO HANDS STACK RATHER THAN SHRINK. Side by side at 300px of section
     width each column is about 150px, which breaks "You are made to buy HYPE
     at the strike" over five ragged lines and makes the card unreadable in
     exactly the place it matters most. Stacked, YOU still sits above THE OTHER
     SIDE across the same hairline. NEITHER HAND IS HIDDEN at any width: the
     card is one contract seen from both ends, and dropping the far end would
     delete the thing the section exists to teach. */
  .pf-card { grid-template-columns: 1fr; }
  .pf-set { gap: 9px 18px; }
  .pf-out { padding-left: 13px; }
  .pf-note { grid-template-columns: 1fr; gap: 5px; }
}

/* ══ THE CHOOSER, THE TERMS AND THE ANSWER ═══════════════════════════════════
 * WRITTEN AFTER THE MARKUP, WHICH IS WHY THIS BLOCK EXISTS AS A BLOCK. The
 * agent that built the two step chooser was interrupted before it wrote any
 * CSS, so .pf-pick-b rendered as the browser's own white button on a dark
 * ground, the selected state was invisible, and "strike78.39" and
 * "-$106.2one short call" ran together because their labels had no spacing.
 * Caught on the PNG. A DOM check would have found four buttons and passed.
 *
 * TWO DECISIONS OF TWO, NOT ONE ROW OF FOUR. Owner: "i should be able to
 * select long/short on 2 buttons, that's hot design, and when i select long or
 * short then im able to choose either call or put". So the two rows are drawn
 * as one object with a shared edge: they read as a single control that happens
 * to take two answers, rather than as two unrelated toolbars.
 *
 * COLOUR CARRIES ONE DISTINCTION AND NOTHING ELSE: which option you have
 * chosen. The accent marks the selected segment and appears nowhere else in
 * this block. The loss colour stays reserved for a negative figure, which is
 * the only other thing on the section allowed a hue.
 * ─────────────────────────────────────────────────────────────────────────── */

/* SIZED AGAINST THE GRAPH, NOT AGAINST ITS OWN TEXT. The first build used
   inline-flex with min-width:9ch, so the control measured 158px on a 920px
   content column and the four segments came out 73/83/81/75 wide, uneven
   because each one sized to its own word. The second build fixed the segments
   (flex:1 1 0) but capped the object at 640px, which left its right edge
   157px short of the chart's and made the control read as a leftover sitting
   beside the section rather than as the section's first instrument. Measured
   on the PNG: .pf-pick w=640.0 against .pf-svg w=919.6, same x.

   IT IS NOW THE COLUMN. width:100% and no cap, so the cells and the graph
   share one left edge and one right edge and the section reads as a single
   object. Everything else here follows from that width: at ~460px a cell
   cannot hold an 11px word without looking abandoned. Owner on the render:
   "nice i like the display now". The size question is closed. */

/* TWO QUESTIONS, AND NOW THEY LOOK LIKE TWO. Owner, same message, 2026-09-05:
   "can you differenciate the buttons a bit of logn/short and put call". This
   block used to argue for one box with a shared edge, and on the render that
   argument lost: four identical segments in one bordered box read as one
   toolbar of four buttons, not as direction-then-kind. THAT ARGUMENT IS NOW
   REVERSED ON PURPOSE, by the owner, on the PNG. Do not restore the shared
   edge without him.

   THE ROWS ARE DIFFERENTIATED BY WEIGHT, GROUND, SCALE AND A SEAM, NEVER BY
   HUE. Colour in this control carries exactly one distinction, which is which
   segment is selected, and the loss colour stays reserved for a negative
   figure. So: direction leads (raised --panel ground, 26px, 600, the first
   decision and the one that flips the sign of the whole payoff), kind follows
   (flush with the page ground, 18px, 500), and 10px of page ground
   runs between them as a real seam rather than the same 1px hairline that
   divides the two segments INSIDE a row. Each row carries its own border, so
   each row is its own object.

   NO ROW LABEL. One quiet word per row was on the table and did not earn its
   place: LONG/SHORT and CALL/PUT already name their own question to this
   audience, and text has been cut from this section three times. */
.pf-pick {
  display: flex;
  flex-direction: column;
  width: 100%;
  /* 10px between the two questions against 0 inside a row: the grouping is
     carried by proximity, so the pair reads as a pair before you read a word
     of it. */
  gap: 10px;
  margin: 0 0 20px;
}
.pf-pick-r { display: flex; }
/* DIRECTION, raised. --panel is the app's own one-step-up ground and carries
   no hue. --hover-wash is NOT used for a resting ground: it is the hover state
   and has to stay free to mean something. --fill-1/--fill-2 are both
   transparent live and say nothing. */
.pf-pick-r:first-child { background: var(--panel); }
/* KIND, flush with the page. The step down in ground is the second half of
   the same signal as the step down in size. */
.pf-pick-r:last-child { background: transparent; }

html body .pf-pick-b {
  flex: 1 1 0;
  min-width: 0;
  background: transparent;
  /* EVERY CELL CARRIES ITS OWN FOUR-SIDED EDGE, AND THE TOKEN IS --line2, NOT
     --line. Independent read of the render: "the vertical seam between LONG
     and SHORT disappears into the accent fill, so row one reads as one bar
     with a colour change rather than as two segments". Measured, and the eye
     was right for a reason the eye could not see: --line #302a23 is 1.39:1 on
     --bg and 1.30:1 on --panel, but 5.44:1 against the accent. THE DIVIDER
     ONLY EXISTED ON THE FILLED HALF. The unselected cell had a border-left it
     could not show and no right edge at all, so it read as the empty part of a
     bar rather than as a thing you can press.
     --line2 #423a31 is the next rung that already exists in the palette and is
     36% more separation (1.77:1 on --bg). It still misses the 3:1 WCAG
     non-text floor, and so does every other neutral here: --s1 and --s2 sit at
     1.07 and 1.16 against --bg. That is a property of a near-black palette
     where the +0.05 flare term dominates the ratio, not a defect in this
     control, and inventing a brighter grey would make this the only bright
     border on the site. The information is not carried by the hairline
     anyway: it is carried by the accent fill, 7.58:1 for its ink. So the
     hairline is judged on the PNG, and the four-sided edge is what does the
     work. */
  border: 1px solid var(--line2);
  cursor: pointer;
  text-align: center;
  /* on the element that RECEIVES the pointer, never on .pf-pick: a wrapper's
     touch-action does not remove the double-tap delay from the child. */
  touch-action: manipulation;
  text-transform: uppercase;
  line-height: 1;
  transition: color 110ms ease-out, background 110ms ease-out;
}

/* THE SIZES ARE LITERAL PX BECAUSE THE SCALE HAS NO STEP HERE: --t-sm and
   --t-md both resolve to 15px live and --t-lg is 30px, so there is no token
   between body copy and a section heading, and this control needs two rungs
   inside that gap.

   26 AND 18, NOT 22 AND 16, AND THE CEILING IS THE ANSWER FIGURE. Independent
   read of the render: "at 458px per segment the words float in a lot of empty
   ground". Both sizes were rendered and compared on the PNG. 22/16 left the
   words swimming; 26/18 fills the cell and widens the gap between the two
   rows at the same time, which is the other thing this control was asked for.
   The hard ceiling is .pf-ans-n at 30px: the section's payload is the figure
   the slide produces, and a control that out-typed its own answer would inv-
   ert the section. 26 is the largest rung that stays under it. Do not raise
   it to 30 to "use the token". The token IS the answer's size.

   Tracking moves the other way, because smaller uppercase needs more of it,
   and both sit under --tr-label (.14em), which at 26px is 3.6px and pulls the
   word apart. */
html body .pf-pick-r:first-child .pf-pick-b {
  padding: 23px 12px;
  font-size: 26px !important;
  font-weight: 600 !important;
  letter-spacing: .09em !important;
  color: var(--ink2);
}
/* --ink2, THE SAME INK AS THE ROW ABOVE, AND THAT IS DELIBERATE. The first
   render of this row used --ink3 and it worked too well: CALL came out dim
   enough to read as DISABLED, which is a false signal on a control and would
   cost a click, not just taste. The ask was to tell the two pairs APART, not
   to rank one under the other. Scale, weight, ground and the seam already
   carry four signals of difference; a fifth one that says "inactive" is worse
   than no fifth one. Caught on the PNG. */
html body .pf-pick-r:last-child .pf-pick-b {
  padding: 17px 12px;
  font-size: 18px !important;
  font-weight: 500 !important;
  letter-spacing: .13em !important;
  color: var(--ink2);
}

/* SQUARE CELLS, AND THE SELECTOR IS THAT LONG ON PURPOSE. instrument.css §17
   squares every corner, then a later rule re-rounds
   `body button:not(.sc-b):not(.sc-mk):not(.sc-af):not(.tw-b):not(.sc-h)` to
   8px !important. That put an 8px pill inside a square hairline box and the
   pill's rounded right edge sat ON TOP of the row border and hid it. Caught on
   the PNG twice: the first fix here was `html body .pf-pick-b { border-radius:
   0 !important }` and it LOST, because :not() carries its argument's
   specificity, so that rule scores 0,5,2 and mine scored 0,1,2. Two
   !importants are decided on specificity, not on which one is angrier. The
   chain below scores 0,5,2 as well and payoff.css loads after instrument.css,
   so the tie goes to this file. Do not shorten it without re-rendering: the
   fill has to reach the hairline, and a DOM check cannot see a rounded
   corner. */
html body .pf-pick .pf-pick-r .pf-pick-b[role="radio"][type="button"] {
  border-radius: 0 !important;
}

/* SPECIFICITY LADDER, WRITTEN DOWN BECAUSE THE PER-ROW RULES CHANGED IT. The
   two rules above score 0,3,2. Anything that has to beat them on the same
   property needs more, so hover and the selected fill both carry a longer
   chain than they look like they need. Shorten either one and the selected
   segment silently goes back to reading --ink2 on orange. */
html body .pf-pick-r .pf-pick-b:not([data-on="1"]):hover {
  color: var(--ink);
  background: var(--hover-wash);
}
/* THE SELECTED SEGMENT TAKES --bg AS ITS INK, NOT --accent-ink, which resolves
   to the same value as --accent on this theme (both #ff7a1a live) and would
   print orange on orange. Measured on the live page, not read off the token
   name. Size and weight are NOT restated here: the selected cell keeps its own
   row's scale, so selecting something never changes the layout. */
html body .pf-pick .pf-pick-r .pf-pick-b[data-on="1"] {
  background: var(--accent);
  color: var(--bg);
}
/* THE RING NEEDS !important AND THE REASON IS NOT STYLE. instrument.css:680
   and :1364 declare a bare `:focus-visible { outline: 1px solid var(--accent)
   !important }`. A more specific rule WITHOUT !important loses to it, so the
   first version of this rule rendered as a 1px ORANGE ring, and on the
   SELECTED cell that is orange on orange and disappears. Measured: computed
   outline came back `rgb(255,122,26) solid 1px` where this file had asked for
   2px. It inverts to --bg on the filled cell. */
html body .pf-pick-b:focus-visible {
  outline: 2px solid var(--focus) !important;
  outline-offset: -3px;
}
html body .pf-pick .pf-pick-r .pf-pick-b[data-on="1"]:focus-visible {
  outline-color: var(--bg) !important;
}

/* ── the terms, as figures on a rule rather than as a form ─────────────────── */
.pf-terms {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 22px;
  margin: 0 0 4px;
  color: var(--ink3);
}
.pf-term { display: inline-flex; align-items: baseline; gap: 8px; }
html body .pf-term label {
  color: var(--ink3);
  text-transform: uppercase;
  letter-spacing: var(--tr-label) !important;
  font-size: var(--t-xs) !important;
}
html body .pf-terms-q { color: var(--ink3); font-size: var(--t-xs) !important; }

/* ── the answer ───────────────────────────────────────────────────────────────
   ONE FIGURE ON THIS LINE, AND THE REASON IS A MEASUREMENT. Every leaf text
   node in .pf-sim was dumped with its position at 1280 and "$84.61" came back
   twice: y=341 on the flag riding the handle, y=667 in this line at 20px mono
   600. The previous version of this block gave the SPOT the second largest
   type on the page, to repeat a number the reader's own finger was sitting
   on. Two large mono dollar figures separated by an 11px "at" is not a claim
   with a condition, it is two numbers competing to be the answer.

   IT WAS NEVER A WRAP FAULT, and the first pass fixed a wrap. Measured at
   twelve widths from 1920 to 360: one 32px row down to 540, and the only
   break below that is the caption's, which is fine.

   SO: the payoff figure, then a caption naming the contract. `.pf-ans-pair`,
   `.pf-ans-at` and `.pf-ans-sp` are gone with the spot they carried. Do not
   put a second figure back on this line without moving the first one off it.

   THE SIGN IS THE SEPARATOR, NOT THE COLOUR. A reader has to tell a payoff
   from a price with no label, and the flag and this line are both mono, both
   bold and both dollar-prefixed. signed() in payoff.js puts a "+" on a gain.
   --neg still means loss and only loss, and a gain does NOT get a second
   colour: this page reports what a position is worth, it does not cheer. */
.pf-ans {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 20px;
  margin: 14px 0 0;
}
/* `flex: 0 0 auto` SO THE FIGURE NEVER SHRINKS UNDER ITS OWN CAPTION. Without
   it a narrow column compresses the payload rather than wrapping the words,
   which is the section inverted. */
html body .pf-ans-n {
  flex: 0 0 auto;
  color: var(--ink);
  font-family: var(--mono) !important;
  font-variant-numeric: tabular-nums;
  font-size: var(--t-lg) !important;
  font-weight: 600 !important;
  line-height: 1.05;
}
html body .pf-ans-n.pf-dn { color: var(--neg); }

/* THE CAPTION IS THE CONTRACT. 17px IS A LITERAL AND THE SCALE IS WHY: read
   off the live page in this session, --t-sm and --t-md BOTH resolve to 15px
   and --t-lg to 30px, so there is no token between body copy and the figure.
   15px under a 30px payload read as fine print on the PNG. Do not "use the
   token" here: --t-md is not a rung above --t-sm on this build, it is the
   same 15px, and swapping the literal for it silently undoes this. */
html body .pf-ans-u {
  color: var(--ink2);
  font-size: 17px !important;
  line-height: 1.3;
}
html body .pf-ans-u b { color: var(--ink); font-weight: 600 !important; }

/* THE MARK AND ITS TICKER ARE ONE UNIT. They bind to the contract now that
   the price they stood beside is gone, and they must never be split by a
   wrap: a mark on one line and its ticker on the next names nothing. It is
   inline rather than inline-flex so the ticker keeps the caption's baseline;
   the glyph is dropped onto that baseline by vertical-align, measured on the
   render rather than guessed. */
.pf-ans-a { white-space: nowrap; margin-right: 9px; }
html body .pf-ans-a i {
  font-style: normal;
  color: var(--ink2);
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
  text-transform: uppercase;
}
/* display:inline-block IS LOAD-BEARING AND IT COST A RENDER TO FIND. style.css
   :739 sets `.mk { display: block }` for the flex contexts every other surface
   puts a mark in, so inside a text line the glyph takes a LINE OF ITS OWN.
   Measured on the first PNG of this pass: the mark rendered above "HYPE"
   instead of beside it and pushed .pf-ans from 31.5px to 39.5px tall, with
   the computed vertical-align sitting uselessly at -4.8px on a block box.
   learn.css:1034 hit the identical trap on the tape's asset cell. A DOM check
   cannot see this; only the render can.

   MONOCHROME, BY MARKS.JS RULE 3 AND NOT BY LUCK. The glyph is drawn in
   currentColor, so it takes whatever ink is set here. It is set HERE rather
   than inherited on purpose: `.pf-ans-n.pf-dn` is a sibling on this line, and
   --neg on this page means "this figure is a loss". A mark is not a figure
   and must never be able to pick that colour up. */
html body .pf-ans-a .mk {
  display: inline-block;
  color: var(--ink2);
  vertical-align: -4px;
  margin-right: 7px;
}

/* PHONE. The control is already the column, so nothing needs uncapping; what
   changes is that a ~460px cell becomes a ~150px one. Both rows step down one
   rung and the seam between them stays, because the whole point of the two
   sizes is the difference and squashing them together would erase it.
   Verified on a 390px render, not assumed. */
@media (max-width: 620px) {
  html body .pf-pick-r:first-child .pf-pick-b {
    padding: 18px 6px;
    font-size: 20px !important;
    letter-spacing: .07em !important;
  }
  html body .pf-pick-r:last-child .pf-pick-b {
    padding: 14px 6px;
    font-size: 14px !important;
    letter-spacing: .10em !important;
  }
}
