
/* House style matching the standard OpenStax / XYZ PDF eBook (College Algebra 2e reference). */
/* One serif family across prose, math, and figure labels (STIX Two Text = what the figures are rendered in). */
@font-face{font-family:"STIX Two Text";src:url("fonts/STIXTwoText.ttf") format("truetype");font-weight:400 700;font-style:normal;font-display:swap}
@font-face{font-family:"STIX Two Text";src:url("fonts/STIXTwoText-Italic.ttf") format("truetype");font-weight:400 700;font-style:italic;font-display:swap}
@font-face{font-family:"STIX Two Math";src:url("fonts/STIXTwoMath-Regular.otf") format("opentype");font-display:swap}
:root{
  /* XYZ Textbooks brand — xyz-design/tokens/xyz-brand.json, WCAG-AA verified 2026-07-05.
     --orange carries TEXT (h2 / nav / section cards), so it is the AA-safe deep shade
     #A94509 (primary-700 — the raw brand orange #F37021 is only 2.94:1 on white and must
     never carry text); navy bars carry white text at 11.09:1. */
  --blue:#154984; --orange:#A94509; --red:#DC2626; --green:#059669;
  --blue-tint:#EFF1F5; --blue-line:#CFDDF0; --green-tint:#EAF3EC;
  --ink:#111827; --rule:#E5E7EB;
  /* WCAG-safe variants (see contrast_check.py's PAIRS): brand success-600 --green is only
     3.77:1 on white / 3.32:1 on green-tint, so SMALL green text (callout labels, free badge)
     uses --green-text; --green itself is border/decoration-only. --gray-meta is brand
     neutral-500. Never use these two as backgrounds. */
  --gray-meta:#586170; --green-text:#007942;
  --serif:"STIX Two Text",Georgia,"Times New Roman",serif;
  --math:"STIX Two Math","STIX Two Text",serif;   /* real MATH-table font -> correct fraction/radical sizing */
  --sans:"Trebuchet MS",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif;
  color-scheme:light;
}
*{box-sizing:border-box}
body{margin:0;display:flex;flex-direction:column;min-height:100vh;
  font:18px/1.6 var(--serif);color:var(--ink);background:#fff}
/* reading area = the original two-column grid, now between the XYZ header & footer */
.reader-shell{display:grid;grid-template-columns:18rem minmax(0,1fr);flex:1 0 auto;width:100%}
/* left-rail nav (sticky under the fixed-height XYZ header + book bar) */
nav.toc{position:sticky;top:var(--stack-h,6.6rem);align-self:start;
  height:calc(100vh - var(--stack-h,6.6rem));overflow:auto;
  font-family:var(--sans);font-size:.9rem;background:#f6f7f9;border-right:1px solid var(--rule);padding:1.25rem 1rem}
nav.toc strong{display:block;margin-bottom:.7rem;font-size:.95rem;line-height:1.25;color:var(--blue)}
nav.toc a{display:block;color:var(--blue);text-decoration:none;padding:.3rem .5rem;border-radius:6px;line-height:1.3}
nav.toc a:hover{background:#e7edf7}
nav.toc a b{color:var(--orange)}
nav.toc a.current{background:var(--blue);color:#fff}
nav.toc a.current b{color:#ffd9c5}
main{max-width:48rem;width:100%;padding:0 2.2rem 6rem}
article{scroll-margin-top:1rem}
/* SC 2.4.11 Focus Not Obscured: keep anchor/focus scroll targets clear of the sticky
   header + book-bar stack (6.6rem) instead of letting them land underneath it */
html{scroll-padding-top:calc(var(--stack-h,6.6rem) + .75rem)}
/* section header = full-width blue bar (OpenStax "1.1" bar) */
h1{font-family:var(--sans);font-weight:700;font-size:1.22rem;letter-spacing:.01em;text-transform:uppercase;
  color:#fff;background:var(--blue);margin:1.9rem 0 1.2rem;padding:.62rem 1rem;border-radius:3px;line-height:1.25}
/* subsection headings = orange (OpenStax). Brand --orange is AA-safe at NORMAL text size
   (5.93:1 on white), so inline heading MATH sub-glyphs (super/subscript digits, which render
   below the large-text bar) pass 4.5:1 too — no h2-math color override needed anymore. */
h2{font-family:var(--sans);font-weight:700;font-size:1.3rem;color:var(--orange);margin:1.9rem 0 .5rem;line-height:1.25}
h3{font-family:var(--sans);font-weight:700;font-size:1.06rem;color:var(--blue);margin:1.3rem 0 .3rem}
p{margin:.7rem 0}
/* A URL is one unbreakable "word". Kozak's reference lists print the source URL
   in full ("Retrieved from http://data.worldbank.org/indicator/SH.XPD.TOTL.ZS"),
   sometimes as bare text rather than a link, and at the 320px reflow viewport a
   single one of those made its <p> 641px wide and took the whole document with
   it — WCAG 2.2 SC 1.4.10 again, and live on the deployed book. break-word only
   engages when the line would otherwise overflow, so ordinary prose is
   untouched. Scoped to the prose carriers: table cells stay as they are, since
   .table-scroll already contains them and breaking there would wreck the
   column widths of the critical-value tables. */
p,li,dd,figcaption{overflow-wrap:break-word}
strong,b{font-weight:700}
dfn{font-style:normal;font-weight:700;color:var(--ink)}    /* bold inline key terms, like the PDF */
/* worked example: white-on-blue "Example N" chip */
aside.example{background:var(--blue-tint);border:1px solid var(--blue-line);border-radius:6px;padding:.7rem 1rem;margin:1.5rem 0}
.ex-head{margin:.05rem 0 .55rem;font-family:var(--sans);font-size:1rem;font-weight:700;color:var(--ink)}
.ex-label{display:inline-block;background:var(--blue);color:#fff;font-family:var(--sans);font-weight:700;font-size:.82rem;
  padding:.14rem .55rem;border-radius:3px;margin-right:.55rem}
.solution::before{content:"Solution";display:block;font-family:var(--sans);font-weight:700;font-size:.85rem;color:var(--blue);margin:.4rem 0 .15rem}
.run-title{font-family:var(--sans);font-weight:700;color:var(--blue)} /* run-in Strategy/Solution/Significance labels — same --blue-on-white/blue-tint pairs as .solution::before */
.solution.hint::before{content:"Hint"}
.solution.answer::before{content:"Answer"}
/* callouts by role */
aside{border-left:4px solid #8a94a6;background:#f7f8fa;padding:.6rem 1rem;margin:1.3rem 0;border-radius:0 6px 6px 0}
.callout-label{display:block;font-family:var(--sans);font-weight:700;font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;margin:0 0 .35rem;color:#566}
.note-title{font-weight:700;font-style:italic;margin:.1rem 0 .35rem}
aside.note-check-point,aside.note-formula,aside.note-work-out{border-left-color:var(--green);background:var(--green-tint)}
aside.note-check-point .callout-label,aside.note-formula .callout-label,aside.note-work-out .callout-label{color:var(--green-text)}
aside.note-who-knew,aside.note-people-mathematics,aside.note-tech-check{border-left-color:var(--blue);background:var(--blue-tint)}
aside.note-who-knew .callout-label,aside.note-people-mathematics .callout-label,aside.note-tech-check .callout-label{color:var(--blue)}
aside.note-video{border-left-color:var(--red)} aside.note-video .callout-label{color:var(--red)}
/* Stitz-Zeager amsthm callouts: definition/theorem/corollary share the blue bucket,
   equation joins the green one. Labels are SMALL text, so they use --green-text
   (--green is 3.32:1 on green-tint and would fail the contrast gate). */
aside.note-theorem,aside.note-corollary{border-left-color:var(--blue);background:var(--blue-tint)}
aside.note-theorem .callout-label,aside.note-corollary .callout-label{color:var(--blue)}
aside.note-equation{border-left-color:var(--green);background:var(--green-tint)}
aside.note-equation .callout-label{color:var(--green-text)}
/* Stitz exercise answer keys: collapsible, keyboard-operable, no JS */
details.answer{margin:.5rem 0 .9rem;border:1px solid var(--rule);border-radius:6px;padding:.15rem .7rem;background:var(--blue-tint)}
details.answer summary{cursor:pointer;font-family:var(--sans);font-weight:700;font-size:.78rem;letter-spacing:.05em;text-transform:uppercase;color:var(--ink);padding:.3rem 0}
details.answer[open] summary{border-bottom:1px solid var(--rule);margin-bottom:.4rem}
aside.note-tip{border-left-color:var(--green);background:var(--green-tint)}
aside.note-tip .callout-label{color:var(--green-text)}
aside.note-important{border-left-color:var(--red)}
aside.note-important .callout-label{color:var(--red)}
/* Mojo Manual lane: build-verified example cells. The output disclosure is a
   native <details> (zero JS, keyboard/AT accessible); its <pre> reuses
   .code-block for styling + the clean_artifacts shield. */
.code-title{font-family:ui-monospace,SFMono-Regular,Consolas,"Liberation Mono",Menlo,monospace;
  font-size:.78rem;color:#555;background:#eef0f3;border:1px solid #dde1e6;border-bottom:0;
  border-radius:6px 6px 0 0;padding:.3rem .8rem;margin-top:.9rem}
.code-title+pre.code-block{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}
.code-example{margin:.9rem 0}
.code-example pre.code-block{margin-bottom:0}
details.code-output{margin:0 0 .9rem}
details.code-output summary{cursor:pointer;font-size:.85rem;font-weight:600;color:#3b4551;
  background:#f4f6f8;border:1px solid #dde1e6;border-top:0;border-radius:0 0 6px 6px;
  padding:.4rem .8rem}
details.code-output summary:hover{background:#eceff2}
details.code-output summary:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
details.code-output[open] summary{border-radius:0}
details.code-output pre.code-block{margin:0;border-top:0;border-radius:0 0 6px 6px;
  background:#0f1419;color:#e6e6e6}
.verified-chip{font-weight:600;font-size:.72rem;color:var(--green-text);

  background:var(--green-tint);border:1px solid var(--green);border-radius:99px;
  padding:.1rem .55rem;white-space:nowrap}
.cas-result{margin:1.25rem 0;padding:.75rem 1rem;border-left:3px solid var(--rule);
  background:var(--green-tint);overflow-x:auto}
.cas-result math{margin:0}
.cas-result figcaption{margin-top:.5rem;font-size:.86rem;color:var(--gray-meta)}
.cas-unchecked{font-weight:600;font-size:.72rem;color:var(--orange)}
/* The provenance sentence is for assistive tech: a sighted reader already has
   the chips, and repeating the same claim in prose next to them is noise. */
.cas-a11y{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  clip-path:inset(50%);white-space:nowrap}
/* footnotes: superscript marker in prose + flat endnote list at the page foot
   (NOT the gray callout box the generic aside rule gives) — text inherits the
   --ink-on-white pair, --rule is decoration-only */
.fn-ref a{text-decoration:none;font-weight:700;padding:0 .08em}
aside.footnotes{border-left:0;background:none;border-radius:0;border-top:1px solid var(--rule);
  margin-top:2.4rem;padding:.8rem 0 0;font-size:.92rem}
aside.footnotes ol{margin:.2rem 0 0 1.3rem;padding:0}
aside.footnotes li{margin:.3rem 0}
/* SC 2.5.8 Target Size (Minimum): a footnote's "return" glyph is a single character
   sitting immediately beside the footnote's own link, so neither cleared the 24px
   minimum NOR the spacing exception (their 24px circles intersect). Give both a real
   24px box. max-width + overflow-wrap keep a long bare URL breaking inside its own
   inline-block instead of pushing the page sideways. */
aside.footnotes a[href^="#fnref-"]{display:inline-block;min-width:24px;min-height:24px;line-height:24px;text-align:center;vertical-align:middle;text-decoration:none}
aside.footnotes li>a{display:inline-block;min-height:24px;line-height:24px;max-width:100%;overflow-wrap:anywhere}
/* SC 1.4.10 Reflow: a link whose visible text IS a bare URL cannot wrap at any
   normal break opportunity, so at the 320px viewport it pushes the whole page
   sideways (Lebl cites six of them by full URL — jirka.org/diffyqs,
   conf.math.illinois.edu/iode/fsgui.html — and each one failed the reflow lane
   on its own page). `anywhere`, not `break-word`: only `anywhere` shrinks the
   element's min-content width, which is what the overflow is measured against.
   Scoped to prose links inside <main>, so nav/header/footer chrome is untouched. */
main a{overflow-wrap:anywhere}
.exercise-ref{display:block;font-family:var(--sans);font-size:.9rem;color:#566;padding:.15rem 0}
/* standalone code sample (Introduction to Python Programming). white-space:pre-wrap +
   overflow-wrap (not plain `pre`'s default horizontal scroll) so a long line reflows
   instead of requiring horizontal scroll — WCAG 1.4.10 Reflow, same as everything else
   on the page at 320px/400% zoom. */
pre.code-block{font-family:ui-monospace,SFMono-Regular,Consolas,"Liberation Mono",Menlo,monospace;
  font-size:.92rem;line-height:1.5;background:#f7f8fa;border:1px solid var(--rule);border-radius:6px;
  padding:.7rem 1rem;margin:1rem 0;white-space:pre-wrap;overflow-wrap:anywhere}
pre.code-block code{font-family:inherit;background:none;padding:0}
/* inline video player (XYZ "+ to play") */
.video{display:block;margin:.35rem 0}
.vbtn{font-family:var(--sans);font-size:.85rem;font-weight:600;color:#fff;background:var(--red);border:0;border-radius:4px;padding:.22rem .6rem;cursor:pointer}
.vbtn:hover{filter:brightness(.92)}
.vtitle{font-weight:600}
.vlink{font-family:var(--sans);font-size:.8rem;color:#566;margin-left:.4rem;text-decoration:none}
.vlink:hover{text-decoration:underline}
.vwrap{display:block;margin-top:.6rem}
.vframe{display:block;width:100%;max-width:40rem;aspect-ratio:16/9;border:1px solid var(--rule);border-radius:6px}
/* FBD Studio self-check widget (standalone pages only — never in sections/ fragments).
   Shell styles (.fbd, .fbd-pv-*, launcher) are ours; the .fbd-root subtree is the engine's
   own UI (fbd.css from IMathAS-FORK master) re-tokened onto the reader palette —
   every text/bg pair is pinned in contrast_check.py. The engine's SVG vector strokes
   (Okabe-Ito) are set in fbd.js, not here. */
.fbd{margin:1.5rem 0;padding:.8rem 1rem;border:1px solid var(--blue-line);border-left:4px solid var(--blue);
  border-radius:0 6px 6px 0;background:#fff}
.fbd>figcaption{font-family:var(--sans);font-weight:700;color:var(--ink);margin:0 0 .5rem}
.fbd-kicker{display:inline-block;background:var(--blue);color:#fff;font-family:var(--sans);font-weight:700;
  font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;padding:.14rem .55rem;border-radius:3px;margin-right:.55rem}
.fbd-preview{display:block;max-width:100%;height:auto;margin:.3rem 0}
.fbd-pv-ground{stroke:var(--gray-meta);stroke-width:2}
.fbd-pv-hatch{stroke:var(--gray-meta);stroke-width:1}
.fbd-pv-body{fill:var(--blue-tint);stroke:var(--ink);stroke-width:2}
.fbd-pv-label{font-family:var(--sans);font-size:13px;fill:var(--ink)}
.fbd-pv-motion{stroke:var(--gray-meta);stroke-width:2;stroke-dasharray:4 3}
.fbd-pv-motionhead{fill:var(--gray-meta)}
.fbd-prompt{margin:.4rem 0}
.fbd-actions{margin:.5rem 0}
.fbd-toggle{font-family:var(--sans);font-size:.9rem;font-weight:600;color:#fff;background:var(--blue);
  border:0;border-radius:4px;padding:.45rem .8rem;min-height:44px;cursor:pointer}
.fbd-toggle:hover{filter:brightness(.92)}
.fbd-toggle[aria-pressed="true"]{box-shadow:inset 0 0 0 2px #fff,inset 0 0 0 4px var(--blue)}
.fbd-simlink{font-family:var(--sans);font-size:.8rem;color:#566;margin-left:.6rem;text-decoration:none}
.fbd-simlink:hover{text-decoration:underline}
.fbd-status{font-family:var(--sans);font-size:.9rem;color:var(--ink);margin:.3rem 0}
.fbd-mount{margin-top:.5rem}
/* --- engine UI (classes emitted by fbd.js) --- */
.fbd-root{--fbd-ink:var(--ink);--fbd-rule:#c7ccd3;--fbd-bg:#fff;--fbd-surface:#f6f7f9;
  --fbd-accent:var(--blue);--fbd-ok:var(--green);--fbd-warn:var(--orange);
  font-family:var(--sans);color:var(--fbd-ink);max-width:540px;border:1px solid var(--fbd-rule);
  border-radius:8px;padding:10px;background:var(--fbd-bg)}
.fbd-sronly{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.fbd-stagewrap{text-align:center}
.fbd-stage{border:1px solid var(--fbd-rule);border-radius:6px;background:var(--fbd-bg);max-width:100%;height:auto;touch-action:none}
.fbd-stage:focus{outline:3px solid var(--fbd-accent);outline-offset:2px}
.fbd-ground,.fbd-hatch{stroke:var(--gray-meta);stroke-width:2}
.fbd-hatch{stroke-width:1}
.fbd-wedge{fill:var(--blue-tint);stroke:var(--gray-meta);stroke-width:1.5}
.fbd-circpath{fill:none;stroke:#8a94a6;stroke-width:1.5;stroke-dasharray:6 5}
.fbd-circcenter{fill:var(--gray-meta)}
.fbd-envlabel,.fbd-axislabel,.fbd-bodylabel{font-size:13px;fill:var(--gray-meta)}
.fbd-body{fill:var(--blue-tint);stroke:var(--ink);stroke-width:2}
.fbd-com{fill:#000}
.fbd-axis{stroke:#000;stroke-width:1.6}
.fbd-vec .fbd-shaft,.fbd-vec .fbd-head{cursor:grab}
.fbd-grab{fill:transparent;cursor:grab}
.fbd-selhalo{stroke:#F0E442;stroke-width:9;stroke-linecap:round;opacity:.85} /* selection halo — decoration-only, never text */
.fbd-scratch{opacity:.45}
.fbd-veclabel{font-size:13px;fill:var(--fbd-ink);paint-order:stroke;stroke:#fff;stroke-width:3px;stroke-linejoin:round;pointer-events:none}
.fbd-angreadout{font-size:12px;fill:var(--gray-meta);paint-order:stroke;stroke:#fff;stroke-width:3px;pointer-events:none}
.fbd-motionarrow{stroke:var(--gray-meta);stroke-width:2;stroke-dasharray:4 3}
.fbd-motionhead{fill:var(--gray-meta)}
.fbd-motionlabel{font-size:12px;font-style:italic;fill:var(--gray-meta)}
.fbd-btn{min-height:44px;min-width:44px;padding:6px 12px;margin:2px;border:1px solid var(--fbd-rule);
  border-radius:6px;background:var(--fbd-surface);color:var(--fbd-ink);font-size:14px;cursor:pointer}
.fbd-btn:hover{background:#e7edf7}
.fbd-btn:focus-visible{outline:3px solid var(--fbd-accent);outline-offset:1px}
.fbd-btn:disabled{opacity:.5;cursor:default}
.fbd-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;margin:6px 0}
.fbd-barlabel{font-weight:600;margin-right:4px}
.fbd-swatch{display:inline-block;width:14px;height:14px;border-radius:3px;border:1px solid #566;vertical-align:-2px}
.fbd-bodytabs{display:flex;gap:4px;margin-bottom:4px}
.fbd-tab[aria-selected="true"]{background:var(--fbd-accent);color:#fff;border-color:var(--fbd-accent)}
.fbd-meta{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:6px 0}
.fbd-sum{font-family:ui-monospace,Menlo,monospace;font-size:14px;border:1px solid var(--fbd-rule);
  border-radius:6px;padding:6px 10px;background:var(--fbd-surface)}
.fbd-axesctl{font-size:14px}
.fbd-axesctl input{width:64px;min-height:36px;font-size:14px}
.fbd-spctl{margin:4px 0}
.fbd-sp{font-size:18px}
.fbd-list{border:1px solid var(--fbd-rule);border-radius:6px;margin:8px 0;padding:6px 10px}
.fbd-list legend{font-weight:600;font-size:14px;padding:0 4px}
.fbd-listul{list-style:none;margin:0;padding:0}
.fbd-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:6px 0;border-bottom:1px dashed var(--fbd-rule)}
.fbd-row:last-child{border-bottom:none}
.fbd-row select,.fbd-row input[type="number"],.fbd-row input[type="text"]{min-height:40px;font-size:14px;
  border:1px solid var(--fbd-rule);border-radius:4px;padding:2px 6px}
.fbd-f-angle,.fbd-f-len{width:76px}
.fbd-f-custom{width:110px}
.fbd-fieldw{font-size:13px}
.fbd-scratchw input{width:20px;height:20px}
.fbd-empty{color:#555;font-style:italic;padding:6px 0}
.fbd-rm{min-width:40px}
.fbd-steps{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}
.fbd-steplabel{margin:0;font-weight:600;font-size:14px}
.fbd-stepnav{display:flex;gap:4px}
.fbd-hints{border:1px solid var(--fbd-rule);border-radius:6px;padding:8px 10px;margin:8px 0;background:var(--fbd-surface)}
.fbd-hinthead{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.fbd-hinttitle{font-weight:600;font-size:14px}
.fbd-hintcost{font-size:12.5px;color:#566}
.fbd-hint{margin:6px 0;font-size:14px;padding-left:10px;border-left:3px solid var(--fbd-accent)}
.fbd-tier3{border-left-color:var(--fbd-warn)}
.fbd-feedback{margin:6px 0}
.fbd-mis{margin:5px 0;padding:7px 10px;border-left:4px solid var(--fbd-warn);background:#ffd9c5;font-size:14px;border-radius:0 6px 6px 0}
.fbd-ok{margin:5px 0;padding:7px 10px;border-left:4px solid var(--fbd-ok);background:var(--green-tint);font-size:14px;border-radius:0 6px 6px 0}
.fbd-help{font-size:12.5px;color:#566;margin:6px 0 0}
.fbd-static .fbd-root{border:none;padding:0}
.fbd-staticlist{font-size:13px;color:#566;margin:6px 0 0;padding-left:20px}
@media (prefers-reduced-motion:reduce){.fbd-root *{transition:none!important;animation:none!important}}
@media (prefers-contrast:more){.fbd-root{--fbd-rule:#000}.fbd-veclabel{stroke-width:4px}}
@media (forced-colors:active){.fbd-btn,.fbd-stage,.fbd-list,.fbd-hints{border:1px solid ButtonText}.fbd-selhalo{stroke:Highlight}}
@media (max-width:560px){.fbd-root{max-width:100%}.fbd-row{flex-direction:column;align-items:stretch}}
/* math — STIX Two Math (matches STIX Two Text body, has the MATH table for proper fractions/radicals) */
math{font-family:var(--math);font-size:1.05em}
/* NO display override: the UA renders <math display=block> as the special
   `block math` display type; forcing plain block makes Chrome stack each
   top-level MathML child on its own line (MathJax-shaped MathML has bare
   top-level children — equations collapsed into vertical slivers). */
math[display="block"]{width:fit-content;margin:1rem auto;font-size:1.1em}
/* Chrome (MathML Core) + a MATH-table font (STIX Two Math) skips the script-size
   step for a radical that is a DIRECT child of a fraction: the √n in σ/√n keeps
   full size and overflows the fraction bar (denominator most visibly; live report
   was PDS §4.1's E = z_c σ/√n, broken twice on one screen). Re-asserting the UA
   sizing here fixes it; on engines that already size correctly it re-declares the
   same value — a no-op. Verified headless against display/inline, numerator,
   both-sides, and expression-radicand cases. */
mfrac>msqrt,mfrac>mroot{math-depth:auto-add;font-size:math}
/* numbered display equation — OpenStax right-margin "(2.9)". Grid keeps the
   formula optically centred in the text column (equally-weighted 1fr gutters)
   with the number pinned to the right edge; the centre track can scroll a
   too-wide formula (min-width:0 + overflow-x) instead of overflowing the page. */
/* middle track is minmax(0,auto): sizes to the formula when it fits, but may shrink
   below its content so a too-wide formula scrolls inside .eqn-body instead of pushing
   the grid (and the page) wider than the viewport. */
.eqn{display:grid;grid-template-columns:1fr minmax(0,auto) 1fr;align-items:center;column-gap:.5rem;margin:1rem 0}
.eqn-body{grid-column:2;min-width:0;overflow-x:auto}
/* Same containment for UNnumbered display math, which is not in the .eqn grid:
   a wide formula scrolls instead of dragging the page sideways (SC 1.4.10 Reflow).
   The scroller is the math's PARENT, never the <math> itself. Putting overflow-x
   on <math> looks like it leaves the other axis alone, but CSS Overflow 3 says a
   `visible` axis computes to `auto` when the other one is not visible — so
   overflow-y:visible silently became overflow-y:auto, every tall formula
   (fractions, radicals, matrices) became a VERTICALLY scrollable region, and
   axe flagged all of them scrollable-region-focusable: 1076 across this book.
   Tall radicals were being cut too, which that declaration existed to prevent.
   Padding cannot fix it — the overflow scales with content, so it just moves the
   threshold. A parent block box sizes to its content vertically, so it scrolls on
   one axis only. This mirrors .eqn-body and .table-scroll, the two containers
   that already got this right. */
:has(> math[display="block"]){max-width:100%;overflow-x:auto}
math[display="block"]{max-width:none;overflow-x:visible;overflow-y:visible}
/* ...except inside the numbered-equation grid, which is ALREADY the scroller:
   nesting a second one there would double the scroll containers and the tab stops. */
.eqn-body :has(> math[display="block"]),
.eqn-body math[display="block"]{max-width:none;overflow-x:visible}
.eqn-body p{margin:0}
.eqn-body math[display="block"]{margin:0 auto}
/* number chip inherits the allowlisted caption gray (#555 on white) */
.eqn-num{grid-column:3;justify-self:end;white-space:nowrap;font-family:var(--sans);font-size:.9rem;color:#555}
/* Author \alert{} emphasis renders as mathcolor="magenta" (#FF00FF, 3.14:1 on white — fails
   the 4.5:1 normal-text bar; caught by the WCAG 2.2 AA gate on the Yoshiwara build). Remap to
   an AA-safe magenta (mediumvioletred #c71585, 5.42:1) via CSS color, which overrides the
   presentation attribute and cascades to descendants — preserves the alert emphasis, accessibly. */
[mathcolor="magenta"]{color:#c71585}
/* EVERY image is responsive, not just the ones inside a <figure>. Every sizing
   rule below is scoped `figure img[...]`, so an <img> emitted as a bare child of
   an <li> or <p> matched nothing and kept `max-width:none` — it rendered at its
   intrinsic pixel width and pushed the document wider than the viewport. Kozak
   §6.4 puts its TI-84 screenshots (345-347px) straight into list items: at the
   320px reflow viewport the page scrolled to 405px, failing WCAG 2.2 SC 1.4.10,
   and it did so on the LIVE deployment for as long as that book has been up. The
   figure-scoped rules keep specificity over this one and still specialise. */
img{max-width:100%;height:auto}
/* figures — figure box shrinks to the image so the caption can't exceed the image width */
figure{width:fit-content;max-width:100%;margin:1.6rem auto;text-align:center}
figure img{height:auto}
/* white card for RASTERS only (photos) — vector figures stay transparent so they
   blend with tinted callout backgrounds (white boxes on shaded asides looked broken) */
figure img[src$=".jpg"],figure img[src$=".jpeg"],figure img[src$=".png"]{border:1px solid #eee;border-radius:6px;background:#fff;padding:6px}
figure img[src^="figures/"]{width:min(100%,30rem);max-height:32rem}   /* vector diagrams: scale dense ones (area models) up to a legible width */
figure img[src^="photos/"]{max-width:min(100%,20rem);max-height:18rem}  /* raster photos: keep modest */
/* caption: one line, description only; credit hidden behind an ⓘ rollover */
figcaption{display:flex;justify-content:center;align-items:baseline;gap:.3rem;font-family:var(--sans);font-size:.85rem;color:#555;margin:.45rem 0 0;max-width:100%}
.cap-desc{min-width:0}
/* "Figure 5.3" / "Table 1.1" number chip (bold, inherits the caption gray #555 —
   an allowlisted pair); flex:none so the description column does the truncating */
.cap-label{flex:none;font-weight:700}
.credit-wrap{flex:none;position:relative}
.credit{cursor:pointer;color:#2156b8;background:none;border:0;padding:0;font:inherit;font-weight:700;line-height:1;display:inline-flex;align-items:center;justify-content:center;min-width:24px;min-height:24px}
.credit-pop{position:absolute;left:50%;transform:translateX(-50%);bottom:150%;width:min(22rem,80vw);background:#222;color:#fff;font:400 .78rem/1.4 var(--sans);padding:.45rem .65rem;border-radius:6px;white-space:normal;text-align:left;display:none;z-index:10;box-shadow:0 2px 9px rgba(0,0,0,.28)}
/* shown by pointer hover (pop is inside the wrap, so it stays hoverable — SC 1.4.13) or by
   the button's JS toggle; .dismissed is set by Escape (PLAYER_JS) until the pointer leaves */
.credit-wrap:hover:not(.dismissed) .credit-pop,.credit[aria-expanded="true"]+.credit-pop{display:block}
/* tables */
table{border-collapse:collapse;margin:1.3rem auto;font-size:.95rem}
/* Wide data tables scroll inside their own container rather than forcing the page
   to scroll (SC 1.4.10). The wrapper is keyboard-focusable and labelled so the
   scroll region is reachable without a mouse (SC 2.1.1). */
.table-scroll{overflow-x:auto;max-width:100%;margin:1.3rem 0}
.table-scroll>table{margin:0 auto}
.table-scroll:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
/* table number/title ("Table 1.1 Fundamental SI Units") — same visual family as
   figcaption (#555 on white is the allowlisted caption pair) */
table caption{caption-side:top;text-align:center;font-family:var(--sans);font-size:.85rem;color:#555;padding:0 .5rem .35rem}
th,td{border:1px solid #c7ccd3;padding:.4rem .7rem;text-align:left;vertical-align:middle}
th{background:#eef1f5;font-family:var(--sans);font-size:.9rem}
/* pager */
.pager{display:flex;justify-content:space-between;gap:1.5rem;margin-top:3rem;padding-top:1rem;border-top:2px solid var(--rule);font-family:var(--sans);font-size:.9rem}
.pager a{color:var(--blue);text-decoration:none;max-width:46%}.pager a:hover{text-decoration:underline}
/* chapter landing = navy banner + section cards (brand: navy bars carry white text) */
.chap-landing h1{background:linear-gradient(95deg,var(--blue),#2C5AA0);text-transform:none;font-size:2rem;padding:1.4rem 1.3rem}
.chap-landing>p{font-size:1.05rem}
.chap-landing ol{font-family:var(--sans);font-size:1.02rem;list-style:none;padding:0;margin-top:1.2rem}
.chap-landing ol li{margin:.45rem 0}
.chap-landing ol a{display:block;color:var(--blue);text-decoration:none;padding:.55rem .85rem;border:1px solid var(--rule);border-radius:6px}
.chap-landing ol a:hover{background:var(--blue-tint)}
.chap-landing ol a b{color:var(--orange);margin-right:.45rem}
/* chapter-opener intro (lead of section 1) shown on the landing */
.chap-intro{font-size:1.06rem;line-height:1.65;color:var(--ink);margin:.2rem 0 1.2rem}
.chap-intro p{margin:.7rem 0}
.chap-intro figure{margin:1rem auto 1.2rem}
.chap-intro figure img[src^="photos/"]{max-width:min(100%,26rem);max-height:22rem}
.chap-sub{font-size:1.05rem;color:#566}
.sec-list-head{font-family:var(--sans);text-transform:none;color:var(--ink);background:none;
  font-size:1.1rem;font-weight:700;margin:1.7rem 0 .7rem;padding:0}
.sec-meta{font-family:var(--sans);font-size:.78rem;color:var(--gray-meta);margin:.2rem 0 1rem}
/* per-page source + license notice (page_attrib) — same muted meta treatment as
   .sec-meta, ruled off from the content it attributes. The link keeps the global
   `a` color; both pairs are already in contrast_check's allowlist. */
.page-attrib{font-family:var(--sans);font-size:.78rem;line-height:1.5;color:var(--gray-meta);
  border-top:1px solid var(--rule);margin:2.5rem 0 0;padding:.9rem 0 0}
.skip{position:absolute;left:-9999px;top:auto}
.skip:focus{left:.6rem;top:.6rem;z-index:80;background:#fff;border:2px solid var(--blue);padding:.4rem .7rem;border-radius:6px;font-family:var(--sans)}
/* minmax(0,1fr), NOT 1fr: a bare 1fr track is minmax(AUTO,1fr), whose automatic
   minimum is the content size — so at mobile widths the single column refused to
   shrink below its widest table and <main> stayed ~733px inside a 320px viewport,
   taking the page with it (SC 1.4.10). The desktop track at .reader-shell already
   guards this; the mobile override silently dropped the guard. */
@media(max-width:820px){.reader-shell{grid-template-columns:minmax(0,1fr)}
  nav.toc{position:static;height:auto;border-right:0;border-bottom:1px solid var(--rule)}
  main{padding:0 1.1rem 4rem}
  .book-bar-in{flex-wrap:wrap;gap:.4rem .9rem}}

/* ===== XYZ Homework site header + footer (brand band; reader colors unchanged) ===== */
:root{--xyz-orange:#ff6e2d;--xyz-ink:#263238;--xyz-bg:#EEECEB;--hdr-h:3.6rem;--bar-h:3rem;--stack-h:6.6rem}
.xyz-hdr{position:sticky;top:0;z-index:60;background:#fff;border-bottom:1px solid #ececec;box-shadow:0 1px 3px rgba(0,0,0,.05)}
.xyz-hdr-in{max-width:80rem;margin:0 auto;height:var(--hdr-h);display:flex;align-items:center;gap:1.2rem;padding:0 1.1rem}
.xyz-logo{display:flex;align-items:center;flex:none}
.xyz-logo img{height:1.7rem;width:auto;display:block}
.xyz-hdr-nav{display:flex;gap:1.25rem;margin-left:.4rem}
.xyz-hdr-nav a{font-family:var(--sans);font-size:.93rem;font-weight:600;color:var(--xyz-ink);text-decoration:none}
.xyz-hdr-nav a:hover{color:var(--orange)}
/* SC 1.4.10 Reflow. This hide used to live in the @media block above, where the
   unconditional .xyz-hdr-nav{display:flex} that follows it overrode it at equal
   specificity — so the suite nav never actually hid, and its ~400px of links forced
   horizontal page scroll at 320px on every page of every book. Same rule, placed
   after the base declaration so the cascade lets it apply. */
@media(max-width:820px){.xyz-hdr-nav{display:none}}
/* Below ~380px the logo + Login pill alone no longer fit the 1.2rem gap and
   1.1rem side padding, and the pill pushed ~29px past the viewport. Tighten the
   row rather than let the page scroll sideways (SC 1.4.10). */
@media(max-width:380px){.xyz-hdr-in{gap:.5rem;padding:0 .6rem}
  .xyz-logo img,.xyz-logo svg{max-width:9rem}}
/* --xyz-orange as a BACKGROUND only clears WCAG AA with dark ink text (4.71:1);
   white-on-xyz-orange was 2.79:1 (fails even the 3:1 large-text floor) — same for
   the footer below. A darker hover background only lowers the ratio against ink
   text (both getting darker shrinks the contrast between them), so hover uses an
   underline instead of a background swap. */
.xyz-hdr-cta{margin-left:auto;font-family:var(--sans);font-size:.86rem;font-weight:700;color:var(--xyz-ink);background:var(--xyz-orange);
  border-radius:9999px;padding:.42rem 1.15rem;text-decoration:none;flex:none}
.xyz-hdr-cta:hover{text-decoration:underline}
/* book navigation bar (breadcrumb + jump-to-chapter) — under the site header */
.book-bar{position:sticky;top:var(--hdr-h);z-index:55;background:var(--blue);color:#fff}
.book-bar-in{max-width:80rem;margin:0 auto;min-height:var(--bar-h);display:flex;align-items:center;gap:1rem;
  padding:.35rem 1.1rem;font-family:var(--sans);font-size:.86rem}
.book-bar a{color:#fff;text-decoration:none}
.book-home{font-weight:700;letter-spacing:.01em;flex:none}
.book-home:hover{text-decoration:underline}
/* flex:none never shrinks: a long book title (the Lab Workbook's runs 343px at
   .86rem bold) holds the bar wider than a 320px viewport and the whole page
   scrolls sideways — SC 1.4.10, the same failure mode as .xyz-hdr-nav above,
   caught by the blocking reflow-320 lane. Below the tablet cut let the home
   link shrink and wrap instead of forcing the bar wide; the crumb beside it
   already yields via min-width:0 + ellipsis. */
@media(max-width:820px){.book-home{flex:0 1 auto;min-width:0}}
.crumb{color:#cfe0f6;display:flex;gap:.35rem;align-items:center;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.crumb a:hover{text-decoration:underline}.crumb .sep{opacity:.6}
.chap-jump{margin-left:auto;position:relative;flex:none}
.chap-jump>summary{list-style:none;cursor:pointer;font-weight:700;background:rgba(255,255,255,.15);
  border-radius:6px;padding:.28rem .7rem}
.chap-jump>summary::-webkit-details-marker{display:none}
/* box-shadow ring, not a brighter fill — a brighter rgba(255,255,255,N) fill
   composited over --blue drops white summary text below 4.5:1 past N≈.30
   (base state N=.15 over --blue #154984: 6.12:1) */
.chap-jump>summary:hover{box-shadow:inset 0 0 0 1px rgba(255,255,255,.6)}
.chap-menu{position:absolute;right:0;top:130%;background:#fff;color:var(--ink);min-width:19rem;max-height:70vh;overflow:auto;
  border:1px solid var(--rule);border-radius:8px;box-shadow:0 6px 22px rgba(0,0,0,.18);padding:.4rem;z-index:70}
.chap-menu a{display:block;color:var(--blue);padding:.4rem .6rem;border-radius:6px;line-height:1.3}
.chap-menu a:hover{background:var(--blue-tint)}.chap-menu a b{color:var(--orange);margin-right:.4rem}
.chap-menu a.here{background:var(--blue);color:#fff}.chap-menu a.here b{color:#ffd9c5}
/* download menu: sits just right of the chapter jump (no second auto-margin) */
.dl-jump{margin-left:.5rem}
.dl-menu{min-width:14rem}
/* footer */
.xyz-ftr{background:var(--xyz-orange);color:var(--xyz-ink);font-family:var(--sans);margin-top:auto}
.xyz-ftr-in{max-width:80rem;margin:0 auto;display:grid;grid-template-columns:repeat(4,1fr);gap:2rem;padding:2.4rem 1.4rem}
/* explicit color: the global h3 rule (var(--blue), 3.97:1 on --xyz-orange) would
   otherwise beat the container's inherited ink — footer headings stay on the
   footer's ink-on-orange scheme (4.71:1) */
.xyz-ftr h3{font-size:1.05rem;font-weight:700;margin:0 0 .9rem;color:var(--xyz-ink)}
.xyz-ftr ul{list-style:none;padding:0;margin:0}
.xyz-ftr li{margin:.5rem 0;font-size:.9rem}
.xyz-ftr a{color:var(--xyz-ink);text-decoration:none}.xyz-ftr a:hover{text-decoration:underline}
.xyz-ftr-logo{height:1.5rem;width:auto;margin-bottom:1rem;filter:brightness(0) invert(1)}
.xyz-ftr address{font-style:normal;font-size:.9rem;line-height:1.5}
.xyz-ftr .copy{margin-top:1.1rem;font-size:.85rem}   /* no opacity: composited over --xyz-orange it drops ink text below 4.5:1 */
@media(max-width:820px){.xyz-ftr-in{grid-template-columns:1fr 1fr;gap:1.6rem;padding:2rem 1.2rem}}
@media(max-width:520px){.xyz-ftr-in{grid-template-columns:1fr}}
/* book home (top-level index): single centered column, no left rail */
.book-shell{grid-template-columns:minmax(0,1fr)}
.book-shell main{margin-inline:auto}
.book-hero{font-family:var(--sans);color:#566;font-size:1.02rem;margin:.2rem 0 1.4rem}
.book-hero .free{display:inline-block;background:var(--green-tint);color:var(--green-text);font-weight:700;
  font-size:.82rem;padding:.18rem .6rem;border-radius:9999px;margin-left:.4rem}
/* ── live code cell. <pre class="code-cell lang-python"> ships as a readable
   listing; CODE_CELL_JS upgrades it to an editable Run widget (progressive
   enhancement — with JS off the reader sees the book exactly as before). ── */
.code-cell{font-family:var(--mono,ui-monospace,"SF Mono",Menlo,Consolas,monospace);font-size:.9rem;
  background:#f6f7f9;border:1px solid var(--rule);border-left:3px solid var(--blue);
  border-radius:6px;padding:.7rem .85rem;overflow-x:auto;white-space:pre;line-height:1.5;color:var(--ink);margin:1.1rem 0}
.code-cell code{font-family:inherit;white-space:pre}
.code-cell-wrap{margin:1.1rem 0;border:1px solid var(--rule);border-radius:8px;overflow:hidden;
  font-family:var(--mono,ui-monospace,"SF Mono",Menlo,Consolas,monospace)}
.code-cell-bar{display:flex;align-items:center;gap:.5rem;background:#f6f7f9;border-bottom:1px solid var(--rule);padding:.35rem .55rem}
.code-cell-lang{font-family:var(--sans);font-size:.7rem;font-weight:700;letter-spacing:.06em;color:var(--blue)}
.code-cell-hint{font-family:var(--sans);font-size:.72rem;color:var(--gray-meta);margin-left:.15rem}
.code-cell-run{margin-left:auto;font-family:var(--sans);font-size:.8rem;font-weight:600;color:#fff;
  background:var(--blue);border:0;border-radius:4px;padding:.25rem .75rem;cursor:pointer}
.code-cell-run:hover{filter:brightness(1.08)}
/* ── authored XYZ Graph figure: static poster, opt-in live viewer ───────────
   The poster is a normal figure image; .xg-live only appears on standalone
   pages (the ingest fragments drop the whole marked span). The frame reserves
   the poster's own aspect so expanding it doesn't jump the page. */
.xg-figure img[hidden]{display:none}
/* Hydrated inline figure: the shadow root replaces the poster+Explore
   children, so the div needs its own height — unhydrated it sizes to its
   children and these rules are inert. Height, not aspect-ratio: the mounted
   figure is canvas (76/47, like .xg-frame) PLUS the slider/prompt strip. */
.xg-hydrate[data-xyzfigure-mounted]{display:block;height:31rem;margin:.4rem 0;
  border:1px solid var(--rule);border-radius:6px;overflow:hidden;background:#fff}
.xg-live{margin:.4rem 0 .1rem}
.xg-explore{font-family:var(--sans);font-size:.8rem;font-weight:600;color:#fff;
  background:var(--blue);border:0;border-radius:4px;padding:.3rem .8rem;cursor:pointer}
.xg-explore:hover{filter:brightness(1.08)}
.xg-frame-wrap{margin-top:.5rem}
.xg-frame{display:block;width:100%;aspect-ratio:76/47;border:1px solid var(--rule);
  border-radius:6px;background:#fff}
/* Authored XYZ 3D figures: the facade is a plain img-in-a-link; the loader
   (when running) swaps it for the live viewer iframe on click. The un-upgraded
   custom element is display:contents-like by default (unknown element =
   inline), so give it block flow; .x3-open is the visible link caption. */
.x3-figure xyz-figure{display:block;margin:.4rem 0}
.x3-figure img{display:block;max-width:100%;height:auto;border:1px solid var(--rule);
  border-radius:6px;background:#fff}
.x3-figure .x3-open{display:inline-block;margin:.35rem 0 .1rem;
  font-family:var(--sans);font-size:.8rem;font-weight:600;color:var(--blue)}
.code-cell-run[disabled]{opacity:.55;cursor:progress}
.code-cell-ta{display:block;width:100%;box-sizing:border-box;border:0;resize:vertical;min-height:2.4rem;
  font-family:inherit;font-size:.9rem;line-height:1.5;padding:.6rem .85rem;color:var(--ink);background:#fff;tab-size:4}
.code-cell-ta:focus{outline:2px solid var(--orange);outline-offset:-2px}
.code-cell-out{font-size:.86rem;line-height:1.45;white-space:pre-wrap;padding:.55rem .85rem;
  background:#fbfbfc;border-top:1px solid var(--rule);color:var(--ink);min-height:1rem}
.code-cell-out:empty{display:none}
.code-cell-out .cell-err{color:var(--red)}
.code-cell-out figure{margin:.3rem 0 0}
.code-cell-out img{max-width:100%;height:auto;border:1px solid var(--rule);border-radius:4px;background:#fff}
.code-cell-boot{font-family:var(--sans);font-size:.72rem;color:var(--gray-meta);margin:.2rem 0 1.1rem}
/* worked-example solution disclosure (ID4_SOLUTION_REVEAL) */
.solution-reveal{margin:.9rem 0;border:1px solid var(--rule);border-radius:6px;background:#fbfbfc}
.solution-reveal>summary{cursor:pointer;padding:.5rem .85rem;font-family:var(--sans);font-size:.85rem;
  font-weight:700;color:var(--blue);border-radius:6px}
.solution-reveal>summary:hover{background:var(--blue-tint)}
.solution-reveal>summary:focus-visible{outline:2px solid var(--orange);outline-offset:-2px}
.solution-reveal[open]>summary{border-bottom:1px solid var(--rule);border-radius:6px 6px 0 0}
.solution-reveal .solution{margin:0;padding:.2rem .85rem .6rem}
/* secondary cell controls: Reset (per cell, appears once edited) + Restart session (per page) */
.code-cell-reset{font-family:var(--sans);font-size:.75rem;font-weight:600;color:var(--gray-meta);
  background:transparent;border:1px solid var(--rule);border-radius:4px;padding:.2rem .5rem;cursor:pointer}
.code-cell-reset:hover{color:var(--ink);border-color:var(--gray-meta)}
.code-cell-reset[hidden]{display:none}
.code-cell-restart{font-family:var(--sans);font-size:.72rem;font-weight:600;color:var(--gray-meta);
  background:transparent;border:1px solid var(--rule);border-radius:9999px;padding:.15rem .7rem;
  cursor:pointer;margin:0 0 1.1rem}
.code-cell-restart:hover{color:var(--ink);border-color:var(--gray-meta)}
.code-cell-restart[disabled]{opacity:.55;cursor:progress}
/* declared code-errata note: this cell runs a corrected copy of the book's code */
.code-cell-errata{font-family:var(--sans);font-size:.74rem;line-height:1.45;color:var(--gray-meta);
  background:#fffaf3;border-bottom:1px solid var(--rule);padding:.4rem .85rem}
.code-cell-errata b{color:var(--orange);font-weight:700}
/* reference-solution disclosure on a practice cell (native <details>, no ARIA needed) */
.code-cell-sol{border-top:1px solid var(--rule);font-family:var(--sans)}
.code-cell-sol>summary{cursor:pointer;padding:.4rem .85rem;font-size:.78rem;font-weight:600;color:var(--blue)}
.code-cell-sol>summary:hover{background:var(--blue-tint)}
.code-cell-sol>summary:focus-visible{outline:2px solid var(--orange);outline-offset:-2px}
.code-cell-sol pre{margin:0;padding:.6rem .85rem;background:#fbfbfc;border-top:1px solid var(--rule);
  font-family:var(--mono,ui-monospace,"SF Mono",Menlo,Consolas,monospace);font-size:.86rem;
  line-height:1.5;white-space:pre;overflow-x:auto;color:var(--ink)}
