
/* 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}
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}
/* 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}
.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}
/* 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}
/* 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}
.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}
.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)}
.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)}
