/* generated by tools/articles/sync.mjs from tools/articles/runtime/enhanced.css: do not edit */
/* ==========================================================================
   ottmar.work articles: the ENHANCED "20%" (Phase 1 lab)
   Linked only by pages that use these pieces, after article.css (whose tokens and grid they use):
     .xf   <x-feature expand>   a panel that widens from the text column to about 80vw as it reaches the middle
                                of the screen, then tucks back into the column as the reader scrolls on
     .xv   <x-bars>             an interactive bar chart (SVG drawn at build time, the data table underneath)
     .xu   <x-units>            a unit chart: one square per person, hover / tap / focus a role
   Ported from the viz lab (tools/articles/lab/viz/viz.css); enhanced.js adds the behaviour.
   ========================================================================== */

/* The feature's progress, 0 = at rest (the column), 1 = wide. Registered so a scroll timeline can animate it and
   everything inside the frame (the annotation's reveal) can read it. In the scroll-driven mode it is the product of
   two timelines: --xf-in (0 -> 1 while the block comes into view) and --xf-out (0 -> 1 while it leaves). */
@property --xf-p { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --xf-in { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --xf-out { syntax: '<number>'; inherits: true; initial-value: 0; }

/* ==========================================================================
   X-FEATURE
   The host (.xf) never changes size: it spans the full grid and reserves the frame's tallest height
   (--xf-reserve, measured by enhanced.js). Only the frame inside it widens, so nothing around it moves.
   The view timelines are tracked on the host, whose box is fixed: no feedback loop.
   Only the stage opens: the panel grows from its centre, and its content (.xf__in) is held on the text column's
   left edge, so no piece of text moves sideways; the bars lengthen into the room the panel opens on the right.
   ========================================================================== */
.xa-body > .xf {
  grid-column: full;
  container-type: inline-size;               /* 100cqi below = the host's width = the article's width */
  margin-top: var(--space-block);
  min-height: var(--xf-reserve, 0px);
  overflow-x: clip;                          /* the frame can never cause a sideways scroll */
}
.xa-body > .xf + * { margin-top: var(--space-block); }
.xf__frame {
  --pad: 1.75rem;
  --col: min(var(--measure-len), 100cqi - 2 * var(--gutter));    /* exactly the content track */
  --rest: calc(var(--col) + 2 * var(--pad));                     /* outset by its padding: the text inside sits on the
                                                                    body text's left edge */
  --wide: max(var(--rest), min(80cqi, 90rem));                   /* about 80vw, never narrower than at rest */
  --grow: calc((var(--wide) - var(--rest)) * var(--xf-p, 0));
  /* The frame's left edge stays put in layout and it grows to the right; a translate re-centres it. Moving a
     box's left edge counts as layout shift even when scroll drives it; a width change from a fixed start and a
     transform do not. */
  width: calc(var(--rest) + var(--grow));
  margin-inline-start: calc((100cqi - var(--col)) / 2 - var(--pad));
  transform: translateX(calc(var(--grow) / -2));
  min-height: var(--xf-reserve, 0px);
  padding: var(--pad) var(--pad) 1.4rem;                           /* constant: the content never moves in layout */
  background: var(--panel);
  /* the panel is one step darker than the ground: the site gray (4.64:1 on cream) and small orange text
     (4.84:1) fall to 4.24:1 and 4.42:1 on it (check.mjs contrast), so both go one step darker here (4.6:1) */
  --gray: #67645a;
  --orange-text: #a04d1c;
  border-radius: calc(var(--r-media) + 4px * var(--xf-p, 0));
  font: 400 1rem/1.5 var(--font-ui);
  --xv-text: var(--col);                                           /* text never wider than the column */
}
/* the content: moved right by what the centring moves the panel left, and half as much wider as the panel (the
   other half opens on the left as room), so its left edge never leaves the column's */
.xf__in {
  width: calc(100% - var(--grow) / 2);
  transform: translateX(calc(var(--grow) / 2));
}
/* without "expand" a feature is simply wide */
.xf:not([data-expand]) > .xf__frame { --xf-p: 1; }

/* Scroll-driven where the browser has view timelines and the reader has not asked for less motion. Timed by
   what the reader can see, not by fixed fractions of the pass:
     widen   while the block comes into view (entry 0% -> 100%: its top enters, then its bottom is on screen)
     wide    the whole time it is in full view
     tuck    as it leaves: from its bottom passing 38% of the screen's height to its bottom passing under the nav
             (the second timeline's end inset of 62% makes "exit" mean exactly that)
   enhanced.js computes the same two ranges for its fallback, with the same curve. */
@keyframes xf-in { from { --xf-in: 0; } to { --xf-in: 1; } }
@keyframes xf-out { from { --xf-out: 0; } to { --xf-out: 1; } }
@supports (animation-timeline: view()) and (animation-range: cover) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 900px) {
    :root:not(.xf-js):not(.xf-still) .xf[data-expand] {
      view-timeline: --xf-a block, --xf-b block;
      view-timeline-inset: auto, auto 62%;
    }
    :root:not(.xf-js):not(.xf-still) .xf[data-expand] > .xf__frame {
      --xf-p: calc(var(--xf-in) * (1 - var(--xf-out)));
      animation: xf-in linear both, xf-out linear both;
      animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
      animation-timeline: --xf-a, --xf-b;
      animation-range: entry 0% entry 100%, exit 0% exit 100%;
    }
  }
}
/* reduced motion (or the lab's ?mode=still): wide and still */
@media (prefers-reduced-motion: reduce) { .xf[data-expand] > .xf__frame { --xf-p: 1; } }
:root.xf-still .xf[data-expand] > .xf__frame { --xf-p: 1; animation: none; }
/* tablets: too little room for the move to read as one; the block sits wide and still */
@media (min-width: 640px) and (max-width: 899.98px) {
  .xf[data-expand] > .xf__frame { --xf-p: 1; animation: none; }
}
/* phones: edge to edge, no animation */
@media (max-width: 639.98px) {
  .xf > .xf__frame {
    --xf-p: 1;
    --grow: 0px;
    width: 100cqi;
    margin-inline-start: 0;
    transform: none;
    padding-inline: var(--gutter);
    border-radius: 0;
    animation: none;
  }
}

/* ==========================================================================
   CHARTS (shared): head, plot, foot, table, tooltip
   ========================================================================== */
.xv, .xu { font: 400 1rem/1.5 var(--font-ui); font-variant-numeric: normal; }
/* a chart on its own sits at popout width between hairlines */
.xa-body > .xv, .xa-body > .xu { grid-column: popout; margin-top: var(--space-block); padding: 1.25rem 0 1.4rem; border-block: 1px solid var(--rule-strong); }
.xa-body > .xv + *, .xa-body > .xu + * { margin-top: var(--space-block); }
/* Text blocks stay under the frame's narrowest inner width, so they wrap the same at every stage and the frame's
   height never depends on its width, with or without the script. */
.xv__head { max-width: var(--xv-text, 30rem); }
.xa-body .xv p, .xa-body .xu p { hanging-punctuation: none; }
.xv__kicker {
  margin-bottom: 0.55rem;
  font: 500 var(--fs-label)/1.2 var(--font-ui);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--gray);
}
.xv__title {
  font: 400 clamp(1.375rem, 1.15rem + 0.7vw, 1.75rem)/1.12 var(--font-display);
  letter-spacing: -0.02em; text-wrap: balance;
  color: var(--black);
}
.xv__dek { margin-top: 0.4rem; font-size: 0.9375rem; line-height: 1.45; color: var(--ink-2); text-wrap: pretty; }
.xv__note { margin-top: 0.3rem; font-size: 0.8125rem; line-height: 1.45; color: var(--gray); }

/* ---------- bars ----------
   Font sizes in rem and every vertical measure in em (lib/charts.mjs): a chart follows the reader's text size. */
.xv { --xv-reveal: 1; }
.xf[data-expand] .xv { --xv-reveal: clamp(0, (var(--xf-p, 0) - 0.85) / 0.15, 1); }   /* the annotation arrives once fully wide */
.xv__plot { position: relative; margin-top: 1.5rem; container: xvplot / inline-size; }
@container xa (max-width: 30rem) { .xv__plot { margin-right: 1.5rem; } }   /* room for the longest bar's value */
/* the annotation needs room beside the short bars: only in a plot wider than the column (the wide state); at
   column width and on phones the text around the chart says it */
@container xvplot (max-width: 38rem) { .xv-annot { display: none; } }
/* a label's note gives way when the plot is narrower than the longest label and its note (data-lw, in rem, from
   lib/charts.mjs): at 200 % text on a phone it would run out of the panel; the bar's name and the table keep it */
@container xvplot (max-width: 10rem) { .xv[data-lw="10"] .xv-label__note { display: none; } }
@container xvplot (max-width: 12rem) { .xv[data-lw="12"] .xv-label__note { display: none; } }
@container xvplot (max-width: 14rem) { .xv[data-lw="14"] .xv-label__note { display: none; } }
@container xvplot (max-width: 16rem) { .xv[data-lw="16"] .xv-label__note { display: none; } }
@container xvplot (max-width: 18rem) { .xv[data-lw="18"] .xv-label__note { display: none; } }
@container xvplot (max-width: 20rem) { .xv[data-lw="20"] .xv-label__note { display: none; } }
@container xvplot (max-width: 22rem) { .xv[data-lw="22"] .xv-label__note { display: none; } }
@container xvplot (max-width: 24rem) { .xv[data-lw="24"] .xv-label__note { display: none; } }
@container xvplot (max-width: 26rem) { .xv[data-lw="26"] .xv-label__note { display: none; } }
@container xvplot (max-width: 28rem) { .xv[data-lw="28"] .xv-label__note { display: none; } }
@container xvplot (max-width: 30rem) { .xv[data-lw="30"] .xv-label__note { display: none; } }
@container xvplot (max-width: 32rem) { .xv[data-lw="32"] .xv-label__note { display: none; } }
@container xvplot (max-width: 34rem) { .xv[data-lw="34"] .xv-label__note { display: none; } }
@container xvplot (max-width: 36rem) { .xv[data-lw="36"] .xv-label__note { display: none; } }
@container xvplot (max-width: 38rem) { .xv[data-lw="38"] .xv-label__note { display: none; } }
@container xvplot (max-width: 40rem) { .xv[data-lw="40"] .xv-label__note { display: none; } }
.xv-svg { display: block; width: 100%; height: var(--xv-h); overflow: visible; font-size: 1rem; }
.xv-group { font: 500 0.75rem var(--font-ui); letter-spacing: 0.14em; text-transform: uppercase; fill: var(--gray); }
.xv-rule { stroke: var(--rule-strong); stroke-width: 1; }
.xv-label { font: 400 0.875rem var(--font-ui); fill: var(--black); }
.xv-label__note { fill: var(--gray); font-weight: 400; }
.xv-row.is-accent .xv-label { font-weight: 500; }
.xv-bar { fill: var(--gray); }
.xv-row.is-accent:not(.is-approx) .xv-bar { fill: var(--orange); }
/* an estimate: a light fill on an orange outline (still while the bar lengthens; a hatch shimmered) */
.xv-bar--approx { fill: #f2d3bf; stroke: var(--orange); stroke-width: 1.5; }
.xv-val {
  font: 500 1.25rem var(--font-display);                            /* one size at every stage: read while it moves */
  letter-spacing: -0.01em;
  fill: var(--black);
}
.xv-hit { fill: transparent; transition: fill 0.2s ease; }
.xv-row { cursor: default; transition: opacity 0.2s ease; outline: none; }
.xv-focus { fill: var(--black); opacity: 0; }
.xv-row:focus-visible .xv-focus { opacity: 1; }
.xv-row:focus-visible .xv-hit { fill: rgba(26, 24, 20, 0.05); }
.xv-svg.has-active .xv-row:not(.is-active),
.xv-svg:not(.is-live):has(.xv-row:hover) .xv-row:not(:hover) { opacity: 0.38; }
.xv-row.is-active .xv-hit { fill: rgba(26, 24, 20, 0.05); }
.xv-annot { opacity: var(--xv-reveal); transition: opacity 0.2s ease; }
.xv-svg.has-active .xv-annot { opacity: calc(var(--xv-reveal) * 0.3); }
.xv-annot__mark { fill: none; stroke: var(--black); stroke-width: 1; stroke-linecap: square; }
.xv-annot__text { font: 500 0.8125rem var(--font-ui); fill: var(--black); }
.xv-annot__sub { font: 400 0.8125rem var(--font-ui); fill: var(--ink-2); }

.xv__foot {
  display: grid; justify-items: start; gap: 0.3rem;
  margin-top: 1.25rem; padding-top: 0.8rem;
  border-top: 1px solid var(--rule);
  font-size: 0.8125rem; line-height: 1.45; color: var(--ink-2);
}
.xv__foot > * { max-width: var(--xv-text, 30rem); }
.xv__key { display: inline-flex; align-items: center; gap: 0.5rem; }
.xv__swatch { display: block; flex: none; }
.xv__source i { font-family: var(--serif); font-style: italic; font-size: 1.08em; }
.xv__source .xc { font-size: 0.8em; }

/* the tooltip (built by enhanced.js; the same details on hover, tap and keyboard focus) */
.xv-tip {
  position: absolute; left: 0; top: 0; z-index: 3;
  width: max-content; max-width: min(15rem, 100%);
  padding: 0.6rem 0.8rem 0.65rem;
  background: var(--black); color: var(--white);
  border-radius: 8px;
  box-shadow: 0 6px 24px rgba(26, 24, 20, 0.18);
  font: 400 0.8125rem/1.4 var(--font-ui);
  pointer-events: none;
  opacity: 0; visibility: hidden;
  transition: opacity 0.15s ease, visibility 0s linear 0.15s;
}
.xv-tip.is-on { opacity: 1; visibility: visible; transition: opacity 0.15s ease; }
.xv-tip__value { display: block; font: 400 1.5rem/1.05 var(--font-display); letter-spacing: -0.02em; }
.xv-tip__label { display: block; margin-top: 0.2rem; }
.xv-tip__src { display: block; margin-top: 0.35rem; color: var(--gray-light); font-size: 0.75rem; }

/* the data table, underneath */
.xv-data { margin-top: 0.75rem; font-size: 0.8125rem; }
.xv-data summary {
  display: inline-flex; align-items: center; gap: 0.45rem;
  min-height: 2.75rem;                              /* 44 px target */
  cursor: pointer; color: var(--ink-2);
  font-weight: 500; letter-spacing: 0.02em;
  list-style: none;
}
.xv-data summary::-webkit-details-marker { display: none; }
.xv-data summary::before {
  content: ""; width: 0.45rem; height: 0.45rem;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg); transition: transform 0.2s ease;
}
.xv-data[open] summary::before { transform: rotate(45deg); }
.xv-data summary:hover { color: var(--black); }
.xv-table { width: 100%; max-width: var(--xv-text, 30rem); border-collapse: collapse; font-variant-numeric: tabular-nums; }
.xv-table caption { text-align: left; padding-bottom: 0.4rem; color: var(--gray); }
.xv-table th, .xv-table td { padding: 0.4rem 0.75rem 0.4rem 0; border-bottom: 1px solid var(--rule); text-align: left; font-weight: 400; }
.xv-table thead th { font-weight: 500; color: var(--gray); }
.xv-table td { text-align: right; padding-right: 0; }
.xv-table thead th:last-child { text-align: right; padding-right: 0; }
.xv-table__group th { padding-top: 0.8rem; font: 500 0.6875rem/1.2 var(--font-ui); letter-spacing: 0.14em; text-transform: uppercase; color: var(--gray); }
.xv-table .is-accent th { font-weight: 500; }
.xv-table__note { color: var(--gray); }

/* ==========================================================================
   X-UNITS
   ========================================================================== */
.xu__body { margin-top: 1.25rem; display: grid; gap: 0.9rem 2.25rem; }
.xu__plot { min-width: 0; }
/* the drawing is sized in em (lib/charts.mjs) and scales its viewBox, so its text sizes are in its own units */
.xu-svg { display: block; max-width: 100%; height: auto; overflow: visible; font-size: 1rem; }
.xu-n { font: 400 18px var(--font-display); fill: var(--black); }
.xu-name { font: 400 14px var(--font-ui); fill: var(--black); }
.xu-unit { fill: var(--ink-2); transition: fill 0.2s ease; }
.xu-row.is-accent .xu-unit { fill: var(--orange); }
.xu-hit { fill: transparent; transition: fill 0.2s ease; }
.xu-row { transition: opacity 0.2s ease; outline: none; }
.xu-row:focus-visible .xu-hit { stroke: var(--black); stroke-width: 1.5; }
.xu-svg.has-active .xu-row:not(.is-active),
.xu-svg:not(.is-live):has(.xu-row:hover) .xu-row:not(:hover) { opacity: 0.28; }
.xu-row.is-active .xu-hit { fill: rgba(26, 24, 20, 0.05); }
.xu-row.is-active .xu-unit { fill: var(--black); }
.xu-row.is-accent.is-active .xu-unit { fill: var(--orange); }

.xu__readout {
  min-height: calc(4 * 1.45em);                     /* the longest line, so changing it never moves the page */
  font-size: 0.9375rem; line-height: 1.45; color: var(--ink-2);
  text-wrap: pretty;
}
.xu__ro-name { display: block; margin-bottom: 0.2rem; font: 400 1.25rem/1.2 var(--font-display); letter-spacing: -0.015em; color: var(--black); }
.xu__ro-sub { display: block; font-size: 0.8125rem; color: var(--gray); margin-bottom: 0.15rem; }
.xu__ro-text { display: block; }

@container xa (min-width: 44rem) {
  .xu__body { grid-template-columns: auto minmax(0, 1fr); align-items: start; }
  .xu__readout { min-height: 0; transform: translateY(var(--ro-y, 0px)); transition: transform 0.35s var(--ease); }
}

@media (prefers-reduced-motion: reduce) {
  .xv-tip, .xu__readout { transition: none !important; }
}
