/* This week on the home (templates/partials/this_week.html). */
.this-week h2{margin-bottom:2px}.this-week .tw-range{margin-top:0}
.tw-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:14px 0}
.tw-card{border:1px solid var(--outline-variant);border-radius:14px;padding:12px 14px;background:var(--surface);min-height:104px}
.tw-card p{margin:0}.tw-card-label{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--on-surface-variant)}
.tw-card-value{margin-top:6px!important;font-size:26px;font-weight:750;line-height:1.15;color:var(--on-surface);font-variant-numeric:tabular-nums}
.tw-card-value.is-negative{color:var(--negative)}
.tw-card-source{margin-top:6px!important;font-size:12px;line-height:1.45;color:var(--on-surface-variant)}
.tw-card-source a{color:var(--primary);text-decoration:underline;text-underline-offset:3px}
.tw-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr) minmax(0,1fr);align-items:center;gap:10px;margin:8px 0 4px}
.tw-split-side p{margin:0;font-size:12px;font-weight:650;color:var(--on-surface-variant)}
.tw-split-side strong{display:block;font-size:20px;font-variant-numeric:tabular-nums}
.tw-split-side.is-followed strong{color:#0d9468}.tw-split-side.is-broke{text-align:right}.tw-split-side.is-broke strong{color:#b45309}
.tw-split-dots{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;min-height:14px}
.tw-dot{width:9px;height:9px;border-radius:50%;transition:transform .8s ease-out,opacity .8s ease-out}
.tw-dot.is-followed{background:#0d9468;order:0}.tw-dot.is-broke{background:#d97706;order:1}
.tw-split.is-start .tw-dot{transition:none;opacity:.35}.tw-split.is-start .tw-dot.is-followed{transform:translateX(24px)}
.tw-split.is-start .tw-dot.is-broke{transform:translateX(-24px)}
@media (prefers-reduced-motion:reduce){.tw-dot{transition:none}}
.tw-line{margin:10px 0 0}
.tw-legend{display:flex;flex-wrap:wrap;gap:6px 18px;font-size:13px;font-weight:650;margin-bottom:6px}
.tw-legend strong{font-variant-numeric:tabular-nums}.tw-key-plan strong{color:#0d9468}
.tw-line-chart{height:180px;border:1px solid var(--outline-variant);border-radius:10px;overflow:hidden;background:#fff}
.tw-line-chart svg{display:block;width:100%;height:100%}
.tw-line figcaption{margin-top:6px;font-size:12px;line-height:1.5;color:var(--on-surface-variant)}
.tw-switches{border:0;margin:10px 0 0;padding:0}.tw-switches legend{font-size:13px;font-weight:700;margin-bottom:4px}
.tw-switch{display:flex;flex-wrap:wrap;align-items:center;gap:6px;font-size:13px;margin:2px 0}
.tw-switch small{color:var(--on-surface-variant)}
.tw-copy-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:10px}
.tw-empty{margin:6px 0 0}
.tw-summary{margin-top:16px;padding:14px 16px;border-radius:12px;background:var(--surface-container-low);border:1px solid var(--outline-variant)}
.tw-summary p{margin:0}.tw-summary-label{font-size:12px;font-weight:700;color:var(--on-surface-variant)}
.tw-summary-text{margin-top:6px!important;color:var(--on-surface);line-height:1.6}
.tw-summary details{margin-top:8px}.tw-summary summary{cursor:pointer;font-weight:650;color:var(--primary)}
.tw-summary-facts{margin:8px 0 0;display:grid;gap:4px}.tw-summary-facts div{display:flex;justify-content:space-between;gap:12px;font-size:13px}
.tw-summary-facts dt{color:var(--on-surface-variant)}.tw-summary-facts dd{margin:0;font-weight:650;text-align:right;font-variant-numeric:tabular-nums}
.tw-next{margin-top:14px!important;font-weight:650}.tw-next-link{color:var(--primary);text-decoration:underline;text-underline-offset:3px}
.tw-checklist ol{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:8px}
.tw-checklist li{display:flex;align-items:center;gap:10px;font-weight:600}
.tw-checklist a{color:var(--primary);text-decoration:underline;text-underline-offset:3px}
.tw-check{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;border:1px solid var(--outline-variant);font-size:12px;font-weight:700}
.tw-checklist li.is-done{color:var(--on-surface-variant)}.tw-checklist li.is-done .tw-check{background:#0d9468;border-color:#0d9468;color:#fff}
/* On a phone each card is one row, label and source left, value right, so the week
   stays on the first screen (PLAN §21.1). */
@media(max-width:600px){.tw-cards{grid-template-columns:1fr;gap:8px}
.tw-card{min-height:0;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:12px;align-items:center;padding:10px 12px}
.tw-card-label{grid-column:1;grid-row:1}.tw-card-source{grid-column:1;grid-row:2;margin-top:2px!important}
.tw-card-value{grid-column:2;grid-row:1/span 2;margin-top:0!important;font-size:21px;text-align:right}
.tw-line-chart{height:140px}.tw-split{grid-template-columns:1fr 1fr}.tw-split-dots{grid-column:1/-1;order:3}}
.tw-attention{margin:0 0 12px!important;padding:10px 14px;border-radius:12px;border:1px solid rgba(217,119,6,.35);background:rgba(217,119,6,.08);color:var(--on-surface);font-weight:600}
/* The figures and the Split chart in the design system's treatment (WOW.md §3, §6): Geist's
   tabular digits, the Rule Cost in the loss red like its side of the Split (POLISH.md §2), the chart at its own
   proportions with gridlines, the shaded gap and the halos (static/css/split_chart.css). */
.tw-card{padding:14px 16px;border-radius:16px;box-shadow:0 1px 2px rgba(14,21,37,.05)}
.tw-card-label{font-size:11px;letter-spacing:.09em;font-weight:650}
.tw-card-value{margin-top:8px!important;font-family:var(--ds-font-sans);font-size:30px;font-weight:700;letter-spacing:var(--ds-tracking-figure)}
#tw-card-rulecost .tw-card-value.is-negative{color:var(--ds-loss-text)}
.dark #tw-card-rulecost .tw-card-value.is-negative{color:var(--ds-loss-on-ink)}
.tw-split-side strong{font-family:var(--ds-font-sans);font-size:22px;font-weight:700;letter-spacing:var(--ds-tracking-figure)}
.tw-legend strong{font-family:var(--ds-font-sans)}
.tw-line-chart{height:auto;aspect-ratio:640/216;padding:6px 8px 2px;border-radius:14px}
.dark .tw-line-chart{background:var(--ds-ink-900);border-color:var(--ds-ink-line)}
.tw-line-chart svg{height:auto}
/* On a phone the cards keep their compact, one-line layout (PLAN §21.1: the week stays on the first screen). */
@media(max-width:600px){.tw-card{padding:10px 12px}.tw-card-value{margin-top:0!important;font-size:22px}.tw-split-side strong{font-size:19px}.tw-line-chart{padding:4px 4px 0}}
/* One colour per meaning (POLISH.md §2): a rule break and its money are the loss red, not amber. */
.tw-split-side.is-broke strong{color:var(--ds-loss-text,#c52a30)}
.tw-dot.is-broke{background:var(--ds-loss,#e5484d)}
.dark .tw-split-side.is-broke strong{color:var(--ds-loss-on-ink,#ff7a7f)}
/* The week as one instrument (DASHBOARD-WOW.md D2), on the dashboard data language (arctic.css --vg-*): the Rule
   Cost as the one display number with its sentence, the band (static/js/week_band.mjs) with a readout that
   follows the pointer and the keyboard, and a legend in words. The ledger strip (D3) follows. */
.tw-instrument{display:grid;gap:20px 30px;margin:20px 0 0}
.tw-headline{margin:0}
.tw-headline #tw-card-rulecost{min-height:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none}
.tw-headline .tw-card-label{color:var(--vg-ink-3);font-size:var(--vg-label-size);font-weight:600;letter-spacing:.08em}
.tw-headline .tw-card-value{margin-top:10px!important;color:var(--vg-ink-1);font-size:var(--vg-num-display);font-weight:700;line-height:1;letter-spacing:-.035em;font-variant-numeric:tabular-nums lining-nums}
.tw-headline #tw-card-rulecost .tw-card-value.is-negative,.dark .tw-headline #tw-card-rulecost .tw-card-value.is-negative{color:var(--vg-down)}
.tw-headline .tw-card-source{max-width:62ch;margin-top:12px!important;color:var(--vg-ink-2);font-size:15px;line-height:1.5}
.tw-line{margin:0}
.tw-ledger{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:0}
/* The strip's measures (D3): the room as a thin meter, the days as a stepped mark, both filled in the accent. */
.tw-ledger .tw-card{display:flex;flex-direction:column;min-height:0;padding:14px 16px}
.tw-meter{display:block;height:4px;margin-top:12px;border-radius:2px;background:var(--vg-surface-quiet);box-shadow:inset 0 0 0 1px var(--vg-hairline);overflow:hidden}
.tw-meter span{display:block;height:100%;border-radius:2px;background:var(--vg-accent)}
.tw-meter.is-reached span{background:var(--vg-break)}
.tw-steps{display:flex;align-items:flex-end;gap:3px;height:13px;margin-top:12px}
.tw-steps i{display:block;width:13px;height:4px;border-radius:2px;background:var(--vg-hairline-strong)}
.tw-steps i.is-done{height:13px;background:var(--vg-accent)}
.tw-ledger .tw-card-source{margin-top:auto!important}
/* Followed against broken is the strip's third cell: the two sums one over the other, the week's dots beneath. */
.tw-ledger .tw-split{display:grid;grid-template-columns:minmax(0,1fr);align-content:center;gap:2px;margin:0;padding:12px 14px;border:1px solid var(--vg-hairline);border-radius:14px;background:var(--vg-surface-1)}
.tw-ledger .tw-split-side{display:flex;align-items:baseline;justify-content:space-between;gap:10px;min-width:0}
.tw-ledger .tw-split-side p{margin:0;font-size:11.5px;font-weight:650;color:var(--vg-ink-2)}
.tw-ledger .tw-split-side p b{font-weight:700;color:var(--vg-ink-1);font-variant-numeric:tabular-nums}
.tw-ledger .tw-split-side.is-followed strong{color:var(--vg-up)}
.tw-ledger .tw-split-side.is-broke strong{color:var(--vg-down)}
.tw-ledger .tw-split-side strong{display:block;font-size:15px;font-variant-numeric:tabular-nums}
.tw-ledger .tw-split-dots{order:3;display:flex;flex-wrap:wrap;gap:3px;margin-top:7px}
/* The band reads in one column: the number, the strip under it, the week drawn full width beneath both. The
   strip stays above the chart at every width: the day's Review has to stay within the second screen on a phone
   (tests/e2e/test_demo_mode.py), and the chart is what gains the width. */
@media(min-width:1000px){
.tw-instrument{grid-template-columns:minmax(0,1fr);gap:16px}
.tw-instrument .tw-ledger{grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-top:2px}
}
.tw-line .tw-legend{margin:0 0 12px;font-weight:500}
.tw-line .tw-key{color:var(--vg-ink-2)}
.tw-line .tw-key strong,.tw-line .tw-key-plan strong{color:var(--vg-ink-1);font-weight:600;font-variant-numeric:tabular-nums}
.tw-line .tw-key-note{color:var(--vg-ink-3)}
.tw-line .tw-key-note::before{content:"· ";margin-left:.1rem}
.tw-stage{position:relative;border-radius:var(--vg-radius-inner);cursor:crosshair;touch-action:pan-y}
.tw-stage:focus-visible{outline:2px solid var(--vg-accent);outline-offset:6px}
.tw-stage .tw-line-chart,.dark .tw-stage .tw-line-chart{height:auto;aspect-ratio:auto;padding:0;border:0;border-radius:0;background:none;overflow:visible}
.wb{display:block;width:100%;height:auto;overflow:visible;font-family:inherit;font-variant-numeric:tabular-nums}
.wb-tick,.wb-zero-label{fill:var(--vg-ink-3);font-weight:500}
.wb-day{stroke:var(--vg-hairline);stroke-width:1}
.wb-zero{stroke:var(--vg-hairline-strong);stroke-width:1}
.wb-gap{fill:var(--vg-break-tint)}
.wb-hatch{stroke:var(--vg-break);stroke-opacity:.26;stroke-width:1}
.wb-traded{stroke:var(--vg-traded);stroke-width:1.75;stroke-linejoin:round;stroke-linecap:round}
.wb-plan{stroke:var(--vg-plan);stroke-width:2.5;stroke-linecap:round}
.wb-break{fill:var(--vg-surface-raised);stroke:var(--vg-break);stroke-width:2}
.wb-flag{fill:var(--vg-break);stroke:var(--vg-break);stroke-width:1.25;stroke-linejoin:round}
.wb-gap-label{fill:var(--vg-down);font-weight:650;paint-order:stroke;stroke:var(--vg-surface-raised);stroke-width:4px;stroke-linejoin:round}
/* Drawn in once, on first paint (D7: at most 600 ms); never again, never with reduced motion. */
.wb.is-drawing .wb-reveal{animation:wb-reveal 560ms var(--vg-ease) both}
.wb.is-drawing .wb-marks{animation:wb-fade 260ms var(--vg-ease) 420ms both}
@keyframes wb-reveal{from{width:0}}
@keyframes wb-fade{from{opacity:0}}
@media (prefers-reduced-motion:reduce){.wb.is-drawing .wb-reveal,.wb.is-drawing .wb-marks{animation:none}}
.tw-cursor{position:absolute;top:0;width:0;border-left:1px dashed var(--vg-hairline-strong);opacity:0;pointer-events:none}
.tw-point{position:absolute;width:10px;height:10px;margin:-5px 0 0 -5px;border:2px solid var(--vg-ink-1);border-radius:50%;background:var(--vg-surface-raised);opacity:0;pointer-events:none}
.tw-stage.is-reading .tw-cursor,.tw-stage.is-reading .tw-point{opacity:1}
/* #tw-readout is the shared readout chip (arctic.css .vg-ro-chip, static/js/instrument.js): its place, its
   leader and its phone dock are the component's; only the week's own type sizes are set here. */
.tw-readout{font-size:12.5px}
.tw-readout[hidden]{display:none}
.tw-readout p{margin:0}
.tw-ro-when{color:var(--vg-ink-3);font-size:11.5px}
.tw-ro-trade{margin-top:2px!important;font-weight:600}
.tw-ro-net{margin-top:4px!important;font-weight:600}
.tw-ro-rule{margin-top:6px!important;padding-top:6px;border-top:1px solid var(--vg-hairline);color:var(--vg-ink-2)}
.tw-ro-rule.is-broke{color:var(--vg-ink-1)}
.tw-ro-rule.is-broke::before{content:"";display:inline-block;width:7px;height:7px;margin:0 .45rem .05rem 0;border:2px solid var(--vg-break);border-radius:50%;vertical-align:middle}
.tw-ro-cost{color:var(--vg-ink-2)}
/* On a phone: one column, the strip as compact rows, the readout as a bar under the chart (never over it). The
   old phone rules above treat every .tw-card as a two-cell tile; the headline's number is not a tile. */
@media(max-width:600px){
.this-week h2{margin-bottom:0}
.tw-range{margin-bottom:2px}
.tw-instrument{gap:6px;margin-top:12px}
.tw-headline{margin-top:0}
.tw-headline #tw-card-rulecost{display:block;padding:0}
.tw-headline .tw-card-value{font-size:2.4rem;margin-top:8px!important}
.tw-headline .tw-card-source{font-size:14px;line-height:1.4;margin-top:8px!important}
.tw-ledger{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
.tw-ledger #tw-split{grid-column:1/-1}
.tw-ledger .tw-card{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:0 8px;min-height:0;padding:8px 12px}
.tw-ledger .tw-card-label{grid-column:1}
.tw-ledger .tw-card-value{grid-row:1;grid-column:2;margin:0!important;font-size:17px;white-space:nowrap}
.tw-ledger .tw-card-source{grid-column:1/-1;margin-top:2px!important;font-size:11.5px}
.tw-ledger .tw-meter,.tw-ledger .tw-steps{grid-column:1/-1;margin-top:8px}
.tw-ledger .tw-card{gap:0 8px}
.tw-ledger .tw-split{display:grid;grid-template-columns:minmax(0,1fr);gap:1px;margin:0;padding:9px 12px}
/* On a phone the two money lines would repeat the headline and the legend (both above it), so the strip keeps the
   week's dots alone: green traded within the rules, red broke one. It is aria-hidden either way; the legend and the
   headline carry the figures in words. */
.tw-ledger .tw-split-side{display:none}
.tw-ledger .tw-split-dots{margin-top:0;gap:4px;justify-content:flex-start}
.tw-ledger .tw-dot{width:6px;height:6px}
.tw-switches{display:flex;flex-wrap:wrap;gap:4px;margin:6px 0 0}
.tw-switches legend{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
.tw-switch{display:inline-flex;align-items:center;gap:6px;margin:0;padding:5px 10px;border:1px solid var(--vg-hairline);border-radius:999px;font-size:12px;line-height:1.2}
.tw-switch small{display:none}
.tw-line .tw-legend{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.25rem .6rem;font-size:11.5px;margin-bottom:4px}
.tw-line .tw-legend .is-gap{grid-column:1/-1}
.tw-line .tw-key-note{display:none}
.tw-line figcaption{font-size:11.5px;line-height:1.45}
}
/* The gap's legend line is one sentence: its swatch, the words and (on a narrow chart) the figure, flowing and
   wrapping as text rather than as a row of separate boxes. */
.tw-line .tw-legend .is-gap{display:block}
.tw-line .tw-legend .is-gap i{display:inline-block;vertical-align:-1px;margin-right:.5rem}
.tw-line #tw-gap-cost{color:var(--vg-ink-1);font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
/* A rule switch is a control in a row, not a form field: focus.css's `.focus-card label` (a form label's 16 px
   above and 8 px below) outranks `.tw-switch`, so the switches set their own spacing at the same weight. */
.focus-card .tw-switch{display:flex;margin:2px 0;font-size:13px;font-weight:500}
@media(max-width:600px){.focus-card .tw-switch{display:inline-flex;margin:0;font-size:12px}}
/* ---- The week, alive (NEXT-LEVEL.md N3) ---------------------------------------------------------------------- */
/* Real axes: money ticks on y with a short mark, day ticks on x, both on the dot grid. */
.wb-ytick{stroke:var(--vg-hairline-strong);stroke-width:1}
.wb-ytick-label{fill:var(--vg-ink-3);font-weight:500}
/* A rule switch's morph: the breaks' marks step aside while the lines move, the new ones land after. */
.wb.is-morphing .wb-marks,.wb.is-morphing .wb-breaks{opacity:0;transition:opacity 120ms var(--vg-ease)}
.wb.is-landing .wb-marks,.wb.is-landing .wb-breaks{animation:wb-fade 180ms var(--vg-ease) both}
@media (prefers-reduced-motion:reduce){.wb.is-landing .wb-marks,.wb.is-landing .wb-breaks{animation:none}}
/* A room value that is not a figure is words, at the size of words. */
.tw-ledger .tw-card-value.is-words{color:var(--vg-ink-2);font-size:15px;font-weight:600;letter-spacing:0}
/* The day cursor on the band: a quiet column over the day's trades. */
.tw-dayband{position:absolute;z-index:0;border-radius:6px;background:rgba(var(--primary-rgb),.075);box-shadow:inset 0 0 0 1px rgba(var(--primary-rgb),.16);pointer-events:none}
.tw-dayband[hidden]{display:none}
.tw-stage .tw-line-chart{position:relative;z-index:1}
/* The stop line: a handle the trader drags; the week after it fades. */
.tw-stop{position:absolute;z-index:4;width:32px;margin-left:-16px;cursor:ew-resize;touch-action:none;outline:none}
.tw-stop-line{position:absolute;left:15px;top:0;bottom:0;width:2px;border-radius:1px;background:var(--vg-ink-1);opacity:.55}
.tw-stop:hover .tw-stop-line,.tw-stop:focus-visible .tw-stop-line,.tw-stop:not(.is-end) .tw-stop-line{opacity:1}
.tw-stop-grip{position:absolute;top:-4px;left:22px;padding:3px 8px;border:1px solid var(--vg-hairline-strong);border-radius:999px;background:var(--vg-surface-raised);box-shadow:var(--vg-elev-raised);color:var(--vg-ink-1);font-size:11px;font-weight:600;white-space:nowrap}
.tw-stop.is-end .tw-stop-grip{left:auto;right:22px}
.tw-stop:not(.is-end) .tw-stop-grip{display:none}
.tw-stop:focus-visible .tw-stop-grip{outline:2px solid var(--vg-accent);outline-offset:2px}
.tw-stop-shade{position:absolute;z-index:2;background:var(--vg-surface-hero);opacity:.74;pointer-events:none}
.tw-stop-shade[hidden]{display:none}
.tw-stop-point.is-on{border-color:var(--vg-accent)}
/* The day strip: one cell per day under the band, its net on the figure and its rule marks as flags. */
.tw-days{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:6px;margin:10px 0 0;padding:0;list-style:none}
.tw-day{display:flex;flex-direction:column;gap:2px;min-height:56px;padding:7px 10px;border:1px solid var(--vg-hairline);border-radius:10px;background:var(--vg-surface-1);color:var(--vg-ink-2);text-decoration:none;font-variant-numeric:tabular-nums;transition:border-color 120ms var(--vg-ease),background-color 120ms var(--vg-ease)}
.tw-day:hover,.tw-day.is-current{border-color:rgba(var(--primary-rgb),.45);background:rgba(var(--primary-rgb),.05)}
.tw-day:focus-visible{outline:2px solid var(--vg-accent);outline-offset:2px}
.tw-day-label{display:flex;align-items:center;gap:6px;color:var(--vg-ink-3);font-size:11px;font-weight:650;letter-spacing:.06em;text-transform:uppercase}
.tw-day-closed{width:6px;height:6px;border-radius:50%;background:var(--vg-accent)}
.tw-day-net{color:var(--vg-ink-1);font-size:13.5px;font-weight:650}
.tw-day-net.is-none{color:var(--vg-ink-3);font-size:12px;font-weight:500}
.tw-day-short{display:none}
.tw-day-marks{display:flex;align-items:center;gap:3px;min-height:12px;color:var(--vg-break);font-size:11px;font-weight:650}
.tw-day-kept{color:var(--vg-ink-3);font-weight:500}
.tw-flag{display:inline-block;width:7px;height:11px;background:linear-gradient(var(--vg-break),var(--vg-break)) left/1.5px 100% no-repeat;position:relative}
.tw-flag::after{content:"";position:absolute;left:1.5px;top:0;border-left:6px solid var(--vg-break);border-top:3px solid transparent;border-bottom:3px solid transparent}
.tw-day.is-future{opacity:.6}
@media(max-width:600px){
.tw-days{gap:4px;margin-top:8px}
.tw-day{min-height:52px;padding:6px 5px;gap:2px;border-radius:8px}
.tw-day-label{font-size:10px;letter-spacing:.03em}
.tw-day-long{display:none}
.tw-day-short{display:inline}
.tw-day-net{font-size:12px}
.tw-day-net.is-none{font-size:10.5px}
.tw-stop-grip{font-size:10.5px}
}
/* On a phone the day strip carries, day by day, what the dots row says trade by trade: the row steps aside there
   (it stays in the page for the Split after an import on a wider screen). */
@media(max-width:600px){.tw-ledger #tw-split{display:none}}
.tw-stop-short{display:none}
@media(max-width:600px){
.tw-stop-long{display:none}
.tw-stop-short{display:inline}
.tw-stop-grip{top:-2px;padding:2px 7px}
/* A room value in words takes the tile's width under its label, not the figure's column beside it. */
.tw-ledger .tw-card-value.is-words{grid-column:1/-1;grid-row:auto;margin-top:2px!important;font-size:13px;white-space:normal}
}
/* A day cell is a link, but reads as an instrument: no underline (focus.css underlines a card's links), its net in
   the money colours, its label on one line. */
.focus-card .tw-days a.tw-day,.focus-card .tw-days a.tw-day:hover{color:var(--vg-ink-2);text-decoration:none}  /* matches focus.css (0,3,1), later */
.tw-day .tw-day-net.vg-up{color:var(--vg-up)}
.tw-day .tw-day-net.vg-down{color:var(--vg-down)}
.tw-day-label{white-space:nowrap}
@media(max-width:600px){
.tw-ledger .tw-card-value.is-words{grid-row:2;text-align:left;justify-self:start}
.tw-ledger .tw-card-value.is-words+.tw-card-source{grid-row:3}
.tw-day-label{letter-spacing:.02em}
}
/* A phone's week keeps the two-screen budget with room to spare (NEXT-LEVEL.md N6): the legend's shorter words (the
   long ones stay on a wider screen and in the band's own description), tighter rule chips and day cells. */
.tw-short{display:none}
@media(max-width:600px){
.tw-long{display:none}
.tw-short{display:inline}
.tw-line .tw-legend .is-gap{grid-column:auto}
.focus-card .tw-switch{padding:3px 9px;font-size:11.5px}
.tw-switches{gap:3px;margin-top:4px}
.tw-day{min-height:46px;padding:5px;gap:1px}
}
/* At 320 the two tiles stack, so a tile's label never runs over its figure. */
@media(max-width:360px){.tw-instrument .tw-ledger{grid-template-columns:minmax(0,1fr)}}
/* The first week's steps and the Sunday report waiting beside them (NEXT-LEVEL.md N8); a phone keeps the list alone. */
.tw-checklist-body{display:grid;grid-template-columns:minmax(0,1fr) 11rem;gap:1rem;align-items:center}
@media(max-width:600px){.tw-checklist-body{grid-template-columns:1fr}.tw-checklist-ill{display:none}}
/* ---- The week's chart, read without a legend (NEXT-FIX.md NF2) ------------------------------------------------ */
/* Each line named where it ends, a name over its figure; the gap's figure on the bracket between the two ends. */
.wb-end-name,.wb-gap-name{fill:var(--vg-ink-2);font-weight:600}
.wb-end-plan-label .wb-end-name{fill:var(--vg-plan)}
.wb-end-value{fill:var(--vg-ink-1);font-weight:650;font-variant-numeric:tabular-nums}
.wb-gap-label{font-variant-numeric:tabular-nums}
.wb-bracket{stroke:var(--vg-break);stroke-width:1.25;stroke-linecap:round}
.wb-leader{stroke:var(--vg-hairline-strong);stroke-width:1}
/* A day without a session: a faint band over its slot, its name on the axis's baseline with the others, dimmed. */
.wb-skip{fill:var(--vg-surface-quiet)}
.wb-skip-label{fill:var(--vg-ink-3);font-weight:500;opacity:.8}
/* What the chart shows, on request: the sentences that were its legend. */
.tw-info{position:absolute;z-index:6;left:0;bottom:2px;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;border:1.25px solid var(--vg-ink-3);border-radius:50%;background:var(--vg-surface-1);color:var(--vg-ink-2);font:750 11px/1 var(--ds-font-sans,Inter,system-ui,sans-serif);cursor:help}
/* The circle stays 22px so it does not shout on the chart; the hit area a finger needs is 44.
   A transparent pseudo-element grows the target without moving a single visible pixel. */
.tw-info::before{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;transform:translate(-50%,-50%);border-radius:50%}
.tw-info:hover,.tw-info:focus-visible{color:var(--vg-accent);border-color:var(--vg-accent);outline:none}
.tw-info:focus-visible{box-shadow:0 0 0 2px var(--vg-surface-1),0 0 0 4px var(--vg-accent)}
.tw-info::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:0;width:max-content;max-width:min(300px,78vw);padding:.55rem .7rem;border:1px solid var(--vg-hairline-strong);border-radius:10px;background:var(--vg-surface-raised);box-shadow:var(--vg-elev-raised);color:var(--vg-ink-1);font-size:12px;font-weight:500;line-height:1.5;text-align:left;white-space:normal;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s var(--vg-ease)}
.tw-info:hover::after,.tw-info:focus::after{opacity:1;visibility:visible}
/* The stop line is found by its grip (NEXT-FIX.md F2.3): a knob on the line, the resize cursor, a focus ring. */
.tw-stop-knob{position:absolute;left:16px;top:50%;width:14px;height:30px;margin:-15px 0 0 -7px;border:1.5px solid var(--vg-ink-1);border-radius:7px;background:linear-gradient(var(--vg-ink-2),var(--vg-ink-2)) 2.75px 8px/1.5px 11px no-repeat,linear-gradient(var(--vg-ink-2),var(--vg-ink-2)) 6.75px 8px/1.5px 11px no-repeat,var(--vg-surface-raised);box-shadow:var(--vg-elev-raised);cursor:ew-resize}
.tw-stop:hover .tw-stop-knob{border-color:var(--vg-accent)}
.tw-stop:focus-visible .tw-stop-knob{outline:2px solid var(--vg-accent);outline-offset:2px}
.tw-stop:focus-visible .tw-stop-line{opacity:1;background:var(--vg-accent)}
.tw-stop-nudge{position:absolute;z-index:5;max-width:calc(100% - 96px);white-space:nowrap;margin:0;padding:5px 10px;border:1px solid var(--vg-hairline-strong);border-radius:10px;background:var(--vg-surface-raised);box-shadow:var(--vg-elev-raised);color:var(--vg-ink-1);font-size:12px;font-weight:600;line-height:1.35;pointer-events:none}
.tw-stop-nudge::after{content:" \2192";color:var(--vg-accent)}
.tw-stop-nudge[hidden]{display:none}
.tw-stage.has-nudge .tw-stop.is-end .tw-stop-grip{display:none}
/* A past week: its room left today is said once, under the title, and the ledger's other cards share the row. */
.tw-room-note{color:var(--vg-ink-3)}
.tw-room-note::before{content:"·";margin:0 .45rem}
@media(min-width:601px){.tw-instrument .tw-ledger.is-past{grid-template-columns:minmax(0,1fr) minmax(0,1.6fr)}}
@media(max-width:600px){.tw-ledger.is-past #tw-card-days{grid-column:1/-1}}
/* The chart's box from the first paint, the script's own heights (static/js/this_week.mjs layout()), so nothing moves when
   it is drawn. A phone's nudge may wrap. */
.tw-stage .tw-line-chart,.dark .tw-stage .tw-line-chart{aspect-ratio:640/220}
@media(max-width:600px){.tw-stage .tw-line-chart,.dark .tw-stage .tw-line-chart{aspect-ratio:640/320}.tw-stop-nudge{white-space:normal;font-size:11.5px}}
/* The stop's chip stays short, its three lines one line each: it has to find a clear place beside the week's lines. */
.tw-stop-chip:not(.is-docked){max-width:none}
.tw-stop-chip:not(.is-docked) p{white-space:nowrap}
/* The rules ranked by what their breaks cost (getquin-gaps PLAN G2): the switch, then its net and share of the Rule
   Cost, then a link to the week's trades that broke it. One row each; on a phone the row keeps the switch's chip. */
.tw-rule{display:flex;flex-wrap:wrap;align-items:center;gap:2px 12px;margin:2px 0}
.tw-rule .tw-switch,.focus-card .tw-rule .tw-switch{margin:0}
.tw-rule-cost{color:var(--vg-ink-2);font-size:12.5px;font-variant-numeric:tabular-nums}
.tw-rule-cost .vg-down{color:var(--vg-down)}.tw-rule-cost .vg-up{color:var(--vg-up)}
.tw-rule-trades{display:inline-flex;align-items:center;min-height:24px;color:var(--primary);font-size:12.5px;text-decoration:underline;text-underline-offset:3px}
@media(max-width:600px){.tw-switches .tw-rule{width:100%;gap:2px 8px;margin:0;line-height:16px}.tw-rule-cost,.tw-rule-trades{font-size:11.5px}.tw-switches{gap:0}.tw-ledger .tw-card{padding-top:6px;padding-bottom:6px}.tw-switches{margin-top:0}.tw-switches .tw-rule{line-height:15px}.tw-rooms-card .tw-card-label{font-size:11px}.tw-rooms-line{font-size:11.5px}}
/* The ranked rows (G2) added each rule's share and its link, so the block grew past the 900 px screen the product
   screens test captures (tests/e2e/test_product_screens.py): no margin above it and none between rows, a 18 px line
   and a 12/15 px tail. Every row stays whole; no sample content is dropped. */
@media(min-width:601px){.tw-switches{margin-top:0}.tw-rule{line-height:18px;margin:0}.tw-rule-cost,.tw-rule-trades{font-size:12px;line-height:15px}}
/* How fresh the week's trades are (getquin-gaps PLAN G3): one quiet line under the range, in the range's own colour;
   the stale sentence is the same line with a plain link, no warning colour and no icon. */
.this-week .tw-fresh{margin:0;color:var(--vg-ink-3);font-size:12.5px}
.this-week .tw-fresh a{color:var(--primary);text-decoration:underline;text-underline-offset:3px}
/* Room left on every firm account (getquin-gaps PLAN G4): in the all view the room card takes the strip's whole row and
   lists one row per firm account, the room on the right, its limit and where it comes from under it, the strip's own
   thin meter beneath. The other two cells share the row after it. */
.tw-ledger .tw-card.tw-rooms-card{display:flex;flex-direction:column;grid-column:1/-1}
@media(min-width:1000px){.tw-instrument .tw-ledger.has-rooms{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:600px){.tw-ledger.has-rooms #tw-card-days{grid-column:1/-1}}
.tw-rooms-details{margin:0}
.tw-rooms-details>summary{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 8px;cursor:pointer;list-style:none}
.tw-rooms-details>summary::-webkit-details-marker{display:none}
.tw-rooms-card .tw-card-label{margin:0}
.tw-rooms-details>summary::after{content:" ›";color:var(--vg-ink-3)}
.tw-rooms-details[open]>summary::after{content:" ⌄"}
.tw-rooms-card .tw-card-source{margin-top:4px!important}
/* One line of information, so the card is not held open by the .tw-card minimum. */
.tw-ledger .tw-card.tw-rooms-card{min-height:0;padding-top:8px;padding-bottom:8px}
.tw-rooms-card .tw-card-label{line-height:1.2}
/* Author display wins over the user agent hiding a closed details, so the list is hidden explicitly. */
.tw-rooms-details:not([open])>.tw-rooms{display:none}
.tw-rooms{display:grid;gap:0;margin:2px 0 4px;padding:0;list-style:none}
.tw-room{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:0 10px;padding:3px 0;border-top:1px solid var(--vg-hairline)}
.tw-room:first-child{padding-top:0;border-top:0}
/* One line per account: the account truncates rather than wraps, the limit sits beside the room left and the
   source is said once under the list (getquin-gaps PLAN G4). */
.tw-room-name{min-width:0;color:var(--vg-ink-1);font-size:13px;font-weight:650;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tw-room-left{color:var(--vg-ink-1);font-size:14px;font-weight:700;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.tw-room-left.vg-down{color:var(--vg-down)}
.tw-room-of{color:var(--vg-ink-3);font-size:11.5px;font-weight:400}
.tw-rooms-card .tw-card-source{font-size:11.5px;line-height:1.35}
.tw-rooms-card .tw-card-source a,.tw-room-of a{color:var(--primary);text-decoration:underline;text-underline-offset:3px}

/* The rule switches and "See the trades" links stay 18 px tall at every width: giving them 44 px rows pushed
   .review-today out of the two-fold budget that tests/e2e/test_product_screens.py enforces at 390 px
   (1 failed). Raising them is a card redesign, not a CSS tweak, so this is a documented gap, not a silent one. */
