/* ==========================================================================
   ageing.css - the two work examples on the Policy analysis & causal inference page
   (#trigger-gap, #income-screens), drawn by ageing.js. Colours are the site tokens only; gold marks the
   result. Names start with wx- or a figure prefix (tg, ls, dg, sh, ag, oc, md) so they cannot collide.
   ========================================================================== */

/* Controls and readouts */
/* Segmented control, set like the practice index: options are quiet text; the chosen one carries a 2px ink
   rule that sits on the figure's own 1px ink top rule directly below */
.wx-seg{display:flex;flex-wrap:wrap;column-gap:clamp(16px,2.2vw,28px);row-gap:0}
.wx-seg button{appearance:none;-webkit-appearance:none;display:flex;align-items:center;min-height:44px;margin:0;padding:0;border:0;background:none;
  font:400 14px/1.3 var(--sans);color:var(--ink-2);white-space:nowrap;cursor:pointer;box-shadow:inset 0 -2px 0 transparent;transition:color .2s,box-shadow .2s}
.wx-seg button:hover{color:var(--ink)}
.wx-seg button[aria-pressed="true"]{color:var(--ink);box-shadow:inset 0 -2px 0 var(--ink)}
.wx-seg button:focus-visible{outline-offset:-3px}

/* Range: ink at rest, gold on hover or drag; the thumb is round like the chart dots; the value is in the mono */
.wx-range{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;column-gap:16px;min-height:44px}
.wx-range label{font-size:14px;color:var(--ink-2);white-space:nowrap}
.wx-range output{font:500 13px/1 var(--mono);color:var(--ink);font-variant-numeric:tabular-nums;min-width:4ch;text-align:right}
.wx-range input[type=range]{--p:50%;-webkit-appearance:none;appearance:none;width:100%;height:32px;margin:0;background:none;cursor:pointer}
.wx-range input[type=range]::-webkit-slider-runnable-track{height:2px;background:linear-gradient(to right,var(--ink) var(--p),var(--rule-strong) var(--p))}
.wx-range input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;margin-top:-6px;border:0;border-radius:50%;background:var(--ink);transition:background-color .2s}
.wx-range input[type=range]::-moz-range-track{height:2px;background:var(--rule-strong)}
.wx-range input[type=range]::-moz-range-progress{height:2px;background:var(--ink)}
.wx-range input[type=range]::-moz-range-thumb{width:14px;height:14px;border:0;border-radius:50%;background:var(--ink)}
.wx-range input[type=range]:hover::-webkit-slider-thumb,.wx-range input[type=range]:active::-webkit-slider-thumb{background:var(--accent)}
.wx-range input[type=range]:hover::-moz-range-thumb,.wx-range input[type=range]:active::-moz-range-thumb{background:var(--accent)}
.wx-range input[type=range]:focus-visible{outline:2px solid var(--mark);outline-offset:3px}

/* Narrow screens: the options scroll sideways on one row, as the site's practice index does, so the chosen
   option's rule stays on the figure's rule; on phones the range label and value sit above a full-width track */
@media (max-width:1100px){
  .wx-seg{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;overscroll-behavior-x:contain}
  .wx-seg::-webkit-scrollbar{display:none}
  .wx-seg button{flex:none}
}
@media (max-width:560px){
  .wx-range{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:'lab out' 'rng rng';row-gap:2px}
  .wx-range label{grid-area:lab}
  .wx-range output{grid-area:out}
  .wx-range input[type=range]{grid-area:rng;height:44px}
}

/* The readout under a live figure: what the figure shows now, or the mark under the pointer */
.wx-readout{min-height:3.1em;margin-top:12px;font-size:14px;line-height:1.55;color:var(--ink-2);max-width:62ch}
.wx-readout .num{font-family:var(--mono);font-size:.9em;color:var(--ink)}
.wx-fig [data-read]{cursor:default}
.wx-fig [data-read]:focus{outline:none}
.wx-fig [data-read]:focus-visible{outline:2px solid var(--mark);outline-offset:2px}

/* The two teasers on the Policy analysis page, one under the other, in the style of the Data page's teaser */
.wx-teasers{grid-column:4 / span 9;display:flex;flex-direction:column;min-width:0}

/* Openings: the trigger gap sets its figure beside the title; the income screens run the title across and
   the figure full width below, like the causal page */
.wx--trigger .d-title{grid-column:1 / span 5}
.wx-herofig{grid-column:7 / span 6;align-self:end;min-width:0}
.wx-herofig--wide{grid-column:1 / -1}

/* Blocks: a short text, the control sitting on the figure's top rule, the figure, the readout */
.wx-body{grid-column:4 / span 9;min-width:0}
.wx-text{max-width:60ch;margin-bottom:20px;color:var(--ink-2)}
.wx-fig{position:relative;min-width:0;padding-top:14px;border-top:1px solid var(--ink)}
.wx-fig > svg{display:block;width:100%;height:auto;overflow:visible}

.wx-findings{grid-column:4 / span 8}
.wx-findings li{max-width:38em;padding-block:14px;border-bottom:1px solid var(--rule);font:400 clamp(1.08rem,1.4vw,1.24rem)/1.42 var(--serif)}
.wx-findings li:first-child{padding-top:0}
.wx-findings li:last-child{padding-bottom:0;border-bottom:0}
.wx-limits{grid-column:4 / span 7;font-size:14.5px;line-height:1.55;color:var(--ink-2)}
.wx-limits li{max-width:62ch;padding-block:10px;border-bottom:1px solid var(--rule)}
.wx-limits li:first-child{padding-top:1px}
.wx-limits li:last-child{padding-bottom:0;border-bottom:0}

/* A figure is never drawn much larger than its canvas, so its type stays close to the house figures */
.wx-body .wx-fig > svg{max-width:640px}
/* The readout is not a caption: it shows while the reader works with the figure or its control (hover, focus
   or tap); screen readers still get it, and its space is kept so nothing moves */
.wx-readout{opacity:0;transition:opacity .2s}
.wx-body:hover .wx-readout,.wx-body:focus-within .wx-readout,.wx-herofig:hover .wx-readout,.wx-herofig:focus-within .wx-readout{opacity:1}
/* The rule labels in the capacity figure knock out the faint tracks behind them */
#fig-mandate .c-label{paint-order:stroke;stroke:var(--ground);stroke-width:3px;stroke-linejoin:round}

@media (max-width:1100px){
  .wx--trigger .d-title,.wx-herofig{grid-column:1 / -1}
  .wx-herofig:not(.wx-herofig--wide) .wx-fig > svg{max-width:640px}
}
@media (max-width:860px){
  .wx--trigger .d-title,.wx-herofig,.wx-body,.wx-findings,.wx-limits,.wx-teasers{grid-column:1 / -1}
}

/* Figure: trigger */
/* Case 1 opening figure (trigger), concept B: the staircase. Cream stairs on a 1× ground, the first step gold, a
   thin wall at the two-limitation trigger (just before the step up to two, so that riser stays a stair) with the
   not-paid region washed to its left, a dashed reference at the 1.414 of a second adult. Every mark rests in its
   final state; the intro climbs the stairs (per-mark --d, --t), then the wall drops in and the wash spreads back
   from it, still by about 3.2 s */
.tg-stair{fill:none;stroke:var(--ink);stroke-width:2}
.tg-stair.gold{stroke:var(--accent)}
.tg-stair.sm{stroke-width:2.5}
.tg-wall{stroke:var(--rule-strong);stroke-width:1;transition:stroke .2s}
.tg-wash{fill:var(--mark-soft);transform-box:fill-box;transform-origin:100% 50%}
.tg-ref{stroke:var(--ink-3);stroke-width:1;stroke-dasharray:4 3;transition:stroke .2s}
.tg-ci{fill:none;transform-box:fill-box}
.tg-hit{fill:none;pointer-events:all}
.c-num.tg-acc{fill:var(--accent)}
.tg-col:hover .tg-ci,.tg-col:focus-visible .tg-ci{stroke:var(--ink)}
.wx-fig svg:has(.tg-kw:hover,.tg-kw:focus-visible) .tg-wall{stroke:var(--ink-3)}
.wx-fig svg:has(.tg-kr:hover,.tg-kr:focus-visible) .tg-ref{stroke:var(--ink)}
/* Keyboard focus: the ring goes round the mark's own label, never over the stairs */
.tg-ring{fill:none;stroke:none;stroke-width:2;pointer-events:none}
.tg-col[data-read]:focus-visible,.tg-key[data-read]:focus-visible{outline:none}
.tg-col:focus-visible .tg-ring,.tg-key:focus-visible .tg-ring{stroke:var(--mark)}
.animate .tg.draw{animation:draw var(--t,1s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
.animate .tg.fade{animation:hfade var(--t,.45s) ease var(--d,0s) both}
.animate .tg-wash.tg{animation:tg-sx var(--t,.6s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
.animate .tg-ci.tg{animation:tg-sy var(--t,.35s) cubic-bezier(.3,.1,.2,1) var(--d,0s) both}
@keyframes tg-sx{from{transform:scaleX(0)}}
@keyframes tg-sy{from{transform:scaleY(0)}}

/* Figure: lifesplit */
/* Lifetime split (case 1): gold = at exactly one limitation (before the trigger); cream = two or more. The resting
   state is the finished figure; the intro fills each bar left to right, stops at the trigger tick (1.3–2.15 s),
   sets the tick and the share, then fills the rest; still by about 3.5 s */
.ls-one{fill:var(--accent)}
.ls-rest{fill:var(--ink-2);fill-opacity:.42}
.ls-hit{fill:var(--ink);fill-opacity:0}
.ls-div{stroke:var(--rule);stroke-width:2}
.ls-tick{stroke:var(--ink);stroke-width:1.6}
.ls-ci line{stroke:var(--ink-2);stroke-width:1.2}
.ls-num{fill:var(--accent)}
.ls-grow{transform-box:fill-box;transform-origin:0 50%}
.animate .ls.ls-grow{animation:ls-sx var(--t,1s) cubic-bezier(.35,.1,.25,1) var(--d,0s) both}
.animate .ls.ls-grow.lin{animation-timing-function:cubic-bezier(.33,.33,.55,1)}
.animate .ls.draw{animation:draw var(--t,.3s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
.animate .ls.fade{animation:hfade var(--t,.45s) ease var(--d,0s) both}
@keyframes ls-sx{from{transform:scaleX(0)}}

/* Figure: designs */
/* Designs (case 1): gap closed relative to the two-ADL trigger (= 100). Gains filled gold, losses open, as in
   the CGE figure. The resting state is the finished figure; the intro starts every dot on the 100 line, slides
   the gains out (0.75–2.2 s), then the loss (2.3–3.2 s); the values arrive as each dot lands; still by 3.6 s */
.dg-ref{stroke:var(--ink);stroke-width:1}
.dg-conn{stroke:var(--ink-3);stroke-width:1.2}
.dg-dot{fill:var(--accent)}
.dg-dot.neg{fill:var(--ink-3);fill-opacity:0;stroke:var(--ink-2);stroke-width:1.2}
.dg-hit{fill:var(--ink);fill-opacity:0}
.animate .dg.draw{animation:draw var(--t,1s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
.animate .dg.fade{animation:hfade var(--t,.45s) ease var(--d,0s) both}
.animate .dg.slide{animation:dg-slide var(--t,1s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
@keyframes dg-slide{from{transform:translateX(var(--dx,0px))}}

/* Figure: shift */
/* Case 2 · shift: the hidden group as 100 dots on multiples of the cut-off. Cream dots pass the screen on the
   measure shown, gold dots fall below it; open rings keep the resources positions. The resting state is the
   finished figure; the intro (3.3 s) only animates each mark in: the dots appear at their resources places
   (--a), glide to their final places from --dx, --dy (--d), and gold dots turn gold as they cross (--c) */
.sh-dot{fill:var(--ink)}
.sh-dot.lo{fill:var(--accent)}
.sh-ring{fill:none;stroke:var(--rule-strong);stroke-width:1;pointer-events:none}
.sh-cut{stroke:var(--ink);stroke-width:1.2}
.c-num.sh-on{fill:var(--ink)}
.animate .sh.draw{animation:draw var(--t,1s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
.animate .sh.fade{animation:hfade var(--t,.45s) ease var(--d,0s) both}
/* the glide: its duration (--mv) and curve (--ez) are set on the <svg> by the figure's script, from the same
   constants its crossing-time solver uses; without them the dots simply rest in place */
.animate .sh-dot{animation:hfade .35s ease var(--a,0s) both,sh-move var(--mv) var(--ez) var(--d,0s) both}
.animate .sh-dot.lo{animation:hfade .35s ease var(--a,0s) both,sh-move var(--mv) var(--ez) var(--d,0s) both,sh-gild .16s linear var(--c,0s) both}
@keyframes sh-move{from{transform:translate(var(--dx,0px),var(--dy,0px))}}
@keyframes sh-gild{from{fill:var(--ink)}}

/* Figure: agegap */
/* Case 2 · agegap: cream bases (poor on both screens), gold caps (hidden), the gold share line above.
   Every mark rests in its final state; the intro only plays it in on per-mark --d (delay) and --t (duration). */
.ag-base{fill:var(--ink-2)}
.ag-cap{fill:var(--accent)}
.ag-base,.ag-cap{transform-box:fill-box;transform-origin:50% 100%}
.ag-line{fill:none;stroke:var(--accent);stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round;pointer-events:none}
.ag-dot{fill:var(--accent)}
/* The two ends of the share line are set in gold: they belong to the line, not to the columns' axis */
.ag-end{fill:var(--accent)}
/* Hover or focus lifts the band's field a shade, and the readout names it */
.ag-hit{fill:var(--rule);fill-opacity:0;transition:fill-opacity .2s}
.ag-band:hover .ag-hit,.ag-band:focus .ag-hit{fill-opacity:.6}
.ag-band:focus{outline:none}
.animate .ag.rise{animation:ag-rise var(--t,.6s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
.animate .ag.draw{animation:draw var(--t,1s) linear var(--d,0s) both}
.animate .ag.fade{animation:hfade var(--t,.45s) ease var(--d,0s) both}
@keyframes ag-rise{from{transform:scaleY(0)}}

/* Figure: outcomes */
/* Case 2 · outcomes: one bar per group, crude rate with its 95% interval. Hidden gold, both screens cream,
   income only open, neither quiet. Every mark rests in its final state; the intro plays it in on per-mark
   --d (delay) and --t (duration). */
.oc-bar{transform-box:fill-box;transform-origin:0 50%}
.oc-nei{fill:var(--rule-strong)}
.oc-inc{fill:var(--ink-2);fill-opacity:0;stroke:var(--ink-2);stroke-width:1.2;vector-effect:non-scaling-stroke}
.oc-hid{fill:var(--accent)}
.oc-bot{fill:var(--ink-2)}
.oc-ci line{stroke:var(--ink-2);stroke-width:1.1}
.oc-ci-hid line{stroke:var(--accent)}
.oc-rate{fill:var(--ink-2)}
.oc-rate.hi{fill:var(--ink);font-weight:500}
.oc-rel{fill:var(--ink-3);font-weight:400}
/* Hover or focus lifts the row's field a shade, and the readout gives the numbers */
.oc-hit{fill:var(--rule);fill-opacity:0;transition:fill-opacity .2s}
.oc-row:hover .oc-hit,.oc-row:focus .oc-hit{fill-opacity:.6}
.oc-row:focus{outline:none}
.animate .oc.grow{animation:oc-grow var(--t,.55s) cubic-bezier(.4,.1,.2,1) var(--d,0s) both}
.animate .oc.fade{animation:hfade var(--t,.45s) ease var(--d,0s) both}
@keyframes oc-grow{from{transform:scaleX(0)}}

/* Figure: mandate */
/* Mandate (case 2): rules on the plane of health events reached (across) by financial difficulty reached (up).
   Gold is the proposal, cream the income flag, the others quiet, the black-box model an open ring; the dashed
   diagonal is the random rule. The resting state is the finished figure. The intro (3.7 s): the diagonal grows
   from the origin and the random dot appears; each rule emerges from the random point as it sets off to its
   place (the gold one last, from 2.2 s), then tracks and labels fade in */
.md-diag{stroke:var(--rule-strong);stroke-width:1;stroke-dasharray:4 3;transform-box:fill-box;transform-origin:0 100%}
.md-trk{fill:none;stroke:var(--ink-3);stroke-width:1;stroke-opacity:.22;stroke-linejoin:round;stroke-linecap:round}
.md-trk.i{stroke:var(--ink);stroke-opacity:.34}
.md-trk.n{stroke:var(--accent);stroke-opacity:.5}
.md-dot{fill:var(--ink-3)}
.md-dot.i{fill:var(--ink)}
.md-dot.n{fill:var(--accent)}
.md-dot.m{fill-opacity:0;stroke:var(--ink-2);stroke-width:1.4}
.md-dot.z{fill:var(--rule-strong)}
.md-hit{fill:var(--ink);fill-opacity:0}
.c-label.md-n{fill:var(--accent)}
.animate .md.fade{animation:hfade var(--t,.45s) ease var(--d,0s) both}
.animate .md-diag{animation:md-grow .8s cubic-bezier(.4,.1,.2,1) .05s both}
.animate .md-g{animation:hfade .2s ease var(--d,1s) both,md-go var(--t,.8s) cubic-bezier(.55,.05,.25,1) var(--d,1s) both}
@keyframes md-grow{from{transform:scale(0)}}
@keyframes md-go{from{transform:translate(var(--dx),var(--dy))}}
