
@font-face{font-family:'Poppins';font-weight:400;font-style:normal;font-display:swap;src:url('/maths/assets/fonts/poppins-400.woff') format('woff')}
@font-face{font-family:'Poppins';font-weight:500;font-style:normal;font-display:swap;src:url('/maths/assets/fonts/poppins-500.woff') format('woff')}
@font-face{font-family:'Poppins';font-weight:700;font-style:normal;font-display:swap;src:url('/maths/assets/fonts/poppins-700.woff') format('woff')}
@font-face{font-family:'InkGlyphs';font-weight:400;font-style:normal;font-display:swap;src:url('/maths/assets/fonts/inkglyphs-400.woff') format('woff');unicode-range:U+0370-03FF,U+221D,U+2264-2265,U+00B2-00B3,U+00B9,U+2070-2079,U+207B,U+2080-2089,U+0127,U+2096,U+2192,U+207A,U+2153-2154,U+2713,U+2090,U+1E00-1EFF,U+0304,U+2032-2034,U+2057,U+207D-207E,U+2261,U+21D2,U+21D4,U+2208,U+2229-222A,U+2234,U+2115,U+211A,U+211D,U+2124,U+2260,U+220E,U+221B,U+22A5,U+207F,U+222B,U+21A6,U+2099,U+221E,U+2213}
@font-face{font-family:'InkGlyphs';font-weight:700;font-style:normal;font-display:swap;src:url('/maths/assets/fonts/inkglyphs-700.woff') format('woff');unicode-range:U+0370-03FF,U+221D,U+2264-2265,U+00B2-00B3,U+00B9,U+2070-2079,U+207B,U+2080-2089,U+0127,U+2096,U+2192,U+207A,U+2153-2154,U+2713,U+2090,U+1E00-1EFF,U+0304,U+2032-2034,U+2057,U+207D-207E,U+2261,U+21D2,U+21D4,U+2208,U+2229-222A,U+2234,U+2115,U+211A,U+211D,U+2124,U+2260,U+220E,U+221B,U+22A5,U+207F,U+222B,U+21A6,U+2099,U+221E,U+2213}
:root{--ink-bg:#0D1B2A;--ink-text:#F5F5F5;--ink-muted:#84919F;--ink-stroke:#6E7D8C;--ink-cyan:#38B6FF;--ink-purple:#A56EFF;--ink-coral:#EF476F;--ink-amber:#FFB703;--ink-success:#2EA043;--ink-card:rgba(255,255,255,.035);--ink-edge:rgba(245,245,245,.13);--ink-hair:rgba(245,245,245,.09);--navy:var(--ink-bg);--ink:var(--ink-text);--cyan:var(--ink-cyan);--amber:var(--ink-amber);--coral:var(--ink-coral);--grey:var(--ink-stroke);--greytx:var(--ink-muted);--bg:var(--ink-bg);--card:var(--ink-card);--edge:var(--ink-edge);--hair:var(--ink-hair);--space-1:.25rem;--space-2:.5rem;--space-3:.75rem;--space-4:1rem;--space-5:1.5rem;--space-6:2rem;--space-7:3rem;--space-8:4rem;--subject-accent:var(--ink-muted)}[data-subject="physics"]{--subject-accent:var(--ink-cyan)}[data-subject="maths"]{--subject-accent:var(--ink-purple)}[data-subject="biology"]{--subject-accent:var(--ink-coral)}
:root{color-scheme:dark;--wtext:42rem;--wpanel:47rem;--wfig:58rem}
*{box-sizing:border-box;margin:0}
html{scroll-behavior:smooth}
body{background:radial-gradient(1100px 520px at 50% -180px,rgba(56,182,255,.055),transparent 62%) var(--bg);
color:var(--ink);font-family:'Poppins','InkGlyphs',sans-serif;font-weight:400;line-height:1.68;font-size:1.05rem;
-webkit-font-smoothing:antialiased;display:flex;flex-direction:column;min-height:100vh}
main{flex:1 0 auto}
footer.site{flex-shrink:0}
.wrap{max-width:64rem;margin:0 auto;padding:0 1.2rem}
a{color:var(--cyan);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
main p a,main li a,main dd a{text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px}
:focus-visible{outline:2px solid var(--cyan);outline-offset:3px;border-radius:4px}
.skip{position:absolute;left:-999px;top:0;background:var(--bg);padding:.5rem 1rem;z-index:9}
.skip:focus{left:.5rem}
header.site{border-bottom:1px solid var(--hair);padding:1rem 0;margin-bottom:2.6rem}
header.site .wrap{display:flex;align-items:baseline;gap:1.6rem;flex-wrap:wrap}
.wm{display:flex;align-items:center}
.wm:hover{text-decoration:none}
.wmsvg{height:1.6rem;width:auto;display:block}
.wmsvg path{fill:var(--ink)}
.wmsvg circle{fill:var(--cyan)}
nav.top{margin-left:auto;display:flex;gap:1.4rem;font-weight:500;font-size:.95rem}
nav.top a{color:var(--ink);opacity:.82}
nav.top a:hover{color:var(--cyan);opacity:1;text-decoration:none}
main{display:block}
h1{font-weight:700;font-size:clamp(2.05rem,5.4vw,2.9rem);line-height:1.14;letter-spacing:-.012em;text-wrap:balance;margin:.1rem 0 .55rem}
.flourish{margin:.15rem 0 1.15rem}
.flourish svg{width:200px;height:auto;display:block}
h2{font-weight:700;font-size:1.42rem;line-height:1.3;margin:2.9rem 0 .9rem;display:flex;align-items:center;gap:.6rem;text-wrap:balance}
h2::before{content:"";width:.48rem;height:.48rem;border-radius:50%;background:var(--cyan);flex:none}
p{margin:0 0 1.15rem}
strong{font-weight:700}
.lede{color:var(--greytx);font-weight:500;font-size:1.17rem;line-height:1.6;margin-bottom:1.3rem;text-wrap:pretty}
.crumbs{font-size:.85rem;font-weight:500;color:var(--greytx);margin:0 0 1.15rem;letter-spacing:.01em}
.crumbs a{color:var(--greytx)}
.chips{display:flex;gap:.5rem;flex-wrap:wrap;margin:0 0 1.5rem}
.chip{border:1px solid var(--edge);border-radius:99px;padding:.16rem .78rem;font-size:.78rem;font-weight:500;color:var(--greytx);letter-spacing:.02em}
.chip.spec{border-color:rgba(56,182,255,.45);color:var(--cyan)}a.chip.spec{text-decoration:none;display:inline-block;line-height:1.55;min-height:1.9rem;padding-top:.2rem;padding-bottom:.2rem}a.chip.spec:hover,a.chip.spec:focus-visible{border-color:var(--cyan);text-decoration:underline}
.builds{font-size:.9rem;font-weight:500;color:var(--greytx);margin:-.6rem 0 1.4rem}
.builds a{color:var(--greytx);text-decoration:underline;text-underline-offset:3px}
.goals{border-top:1px solid var(--hair);border-bottom:1px solid var(--hair);padding:1rem 0 .5rem;margin:0 0 1.9rem}
.goals .gl{font-size:.73rem;font-weight:700;letter-spacing:.16em;color:var(--greytx);margin-bottom:.55rem}
.goals ul{list-style:none;margin:0;padding:0}
.goals li{padding:.22rem 0 .22rem 1.25rem;position:relative;color:var(--ink)}
.goals li::before{content:"";position:absolute;left:.1rem;top:.86em;width:.42rem;height:.42rem;border-radius:50%;background:var(--cyan);opacity:.8}
article.lesson>*,article.lesson section.lsec>*{max-width:var(--wtext);margin-left:auto;margin-right:auto;padding-left:1.2rem;padding-right:1.2rem}
article.lesson>section.lsec{max-width:none;padding-left:0;padding-right:0}
article.lesson>.panel,article.lesson section.lsec>.panel{max-width:var(--wpanel)}
article.lesson>.eqs,article.lesson section.lsec>.eqs{max-width:var(--wpanel)}
article.lesson>.rulecard,article.lesson section.lsec>.rulecard{max-width:var(--wpanel)}
article.lesson>.tblwrap,article.lesson section.lsec>.tblwrap{max-width:var(--wpanel)}
article.lesson>.pn,article.lesson section.lsec>.pn{max-width:var(--wpanel)}
article.lesson>figure.fig,article.lesson section.lsec>figure.fig{max-width:var(--wfig)}
article.lesson>.videoembed,article.lesson section.lsec>.videoembed{max-width:var(--wfig)}
/* The measure, applied off the lesson pages as well as on them.
   Everything above constrains a lesson to --wtext, 42rem, and every lesson on
   the site has obeyed it for as long as it has existed. Nothing constrained
   any other page, because every other page puts its prose straight into .wrap
   and .wrap is 64rem: on a laptop the lede on a unit hub, the answers on
   /maths/faq/, the standing text on /maths/exam-boards/, the whole of
   /maths/how-to-revise/ and the notes under every tool ran to about 1024px, a
   line roughly 2.4 times the measure the guide asks for and about 150
   characters long. It is the same body copy as a lesson's, written by the same
   people, and it was being set at a width no one would choose for it.
   The cap is applied by element and only to the direct children of a page's
   .wrap, which is the narrowest way to say "prose" in this markup without
   inventing a class for every page. Deliberately left alone, because width is
   doing a job for each of them: .cards (a responsive grid whose columns should
   keep filling the page), ul.topics and ul.tqlist and details.ub (index rows
   with a title on the left and a tag on the right, which read as a table and
   need the run), .tblwrap and figure.fig (tables and diagrams, which have
   their own wider limits), the filter and search bars, the app dashboards, and
   the .hero, which is centred and sizes itself.
   No margin:auto: the prose keeps the left edge the card grids and the topic
   lists already start from, so a hub reads as one column with wide furniture
   beside it rather than two competing centres. That is also why the two inline
   margins are zeroed rather than left alone. .note carries margin:2.4rem auto
   0, which did nothing at all while it had no width limit, and the moment this
   cap arrived it started centring the closing note on every tool page while
   the paragraph above it stayed left -- caught in Chromium on /maths/search/,
   where the note visibly stepped inwards. Lessons are untouched by this: the
   auto margins .note wants there come from the article.lesson rules above,
   which this selector never matches. The three jump rows are pills rather than
   sentences and are let back out to the full width, because wrapping a
   navigation strip earlier helps nobody. */
main>.wrap>p,main>.wrap>h1,main>.wrap>h2,main>.wrap>h3,main>.wrap>h4,
main>.wrap>.hubguide,main>.wrap>.faq,main>.wrap>section.qr{max-width:var(--wtext);margin-left:0;margin-right:0}
main>.wrap>p.jumps,main>.wrap>p.azjump,main>.wrap>p.hubroutes{max-width:none}
.panel{border:1px solid var(--edge);background:var(--card);border-radius:20px;padding:1.25rem 1.45rem 1.15rem;margin:2rem auto}
.panel .pl{display:flex;align-items:center;gap:.6rem;font-size:.73rem;font-weight:700;letter-spacing:.16em;margin-bottom:.6rem}
.pi{width:1.05rem;height:1.05rem;flex:none}
.p-lie{border-color:rgba(239,71,111,.4);background:rgba(239,71,111,.06)}
.p-lie .pl{color:var(--coral)}
.p-exam{border-color:rgba(255,183,3,.38);background:rgba(255,183,3,.05)}
.p-exam .pl{color:var(--amber)}
.p-check{border-color:rgba(56,182,255,.4);background:rgba(56,182,255,.055)}
.p-check .pl{color:var(--cyan)}
.p-check details+details{margin-top:.6rem}
.p-ex .pl{color:var(--ink)}
.p-ex .ext{font-weight:700;margin-bottom:.8rem}
.panel p:last-child{margin-bottom:0}
.p-exam ul{list-style:none;margin:.2rem 0 0;padding:0}
.p-exam li{margin:.7rem 0;padding-left:1.35rem;position:relative}
.p-exam li::before{content:"";position:absolute;left:.05rem;top:.62em;width:.5rem;height:.5rem;border-radius:50%;background:var(--amber)}
details summary{cursor:pointer;display:inline-flex;align-items:center;gap:.55rem;font-weight:500;color:var(--cyan);
border:1px solid rgba(56,182,255,.45);border-radius:11px;padding:.5rem 1.05rem;list-style:none;user-select:none;
transition:background .18s,border-color .18s}
details summary::-webkit-details-marker{display:none}
details summary::after{content:"";width:.5rem;height:.5rem;border-right:2px solid var(--cyan);border-bottom:2px solid var(--cyan);
transform:rotate(45deg) translateY(-1px);transition:transform .18s}
details[open] summary::after{transform:rotate(-135deg) translateY(-2px)}
details summary:hover{background:rgba(56,182,255,.08)}
details[open] summary{margin-bottom:.9rem}
details.hintbox summary{color:var(--greytx);border-color:var(--edge)}
details.hintbox summary::after{border-color:var(--greytx)}
details.hintbox summary:hover{background:rgba(245,245,245,.05)}
figure.fig{margin:2.3rem auto;position:relative}
figure.fig svg{width:100%;height:auto;display:block}
figure.fig img{width:100%;height:auto;display:block}
/* The unit-hub guide, below the lesson links: a reference block, not a
   second lede, so it is ruled off and set a little tighter. */
.hubguide{border-top:1px solid var(--hair);margin-top:2.4rem;padding-top:.6rem}
.hubguide h2{font-size:1.06rem;margin:1.5rem 0 .4rem}
.hubguide ul{margin:.3rem 0 0;padding-left:1.1rem}
.hubguide li{margin:0 0 .45rem;line-height:1.6}
.hubeq{margin:.4rem 0 0}
.hubeq dt{font-weight:700;margin:.7rem 0 .1rem}
.hubeq dd{margin:0 0 0 0;color:var(--greytx);line-height:1.5}
/* The expand control lives in the caption row below the artwork, never over
   it, and keeps a 44px hit target: 2.75rem at the 16px root. */
.figxbtn{flex:none;margin-left:auto;align-self:center;width:2.75rem;height:2.75rem;border-radius:12px;border:1px solid var(--edge);background:var(--bg);color:var(--greytx);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;opacity:.85}
.figxbtn:hover{color:var(--cyan);border-color:var(--cyan);opacity:1}
.figxbtn svg{width:1.05rem;height:1.05rem}
/* A figure whose smallest label would project below 9 CSS px on a phone keeps
   a build-computed minimum artwork width (--figmin) and scrolls sideways
   instead of shrinking its labels past reading size. fig.js makes the
   viewport a named, keyboard-focusable region only while it actually
   overflows, so it is never a tab stop that goes nowhere. */
.figscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.figscroll svg{min-width:var(--figmin,0)}
.figscroll:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
dialog.figdlg{background:var(--bg);border:1px solid var(--edge);border-radius:20px;padding:0;width:min(96vw,1150px);max-height:92vh;margin:auto;color:var(--ink)}
dialog.figdlg[open]{display:flex;flex-direction:column}
dialog.figdlg::backdrop{background:rgba(4,10,17,.82)}
.figdlgbar{display:flex;align-items:center;gap:1rem;justify-content:space-between;padding:.55rem .55rem .55rem .95rem;border-bottom:1px solid var(--hair)}
.figdlgbar p{margin:0;font-size:.85rem;color:var(--greytx);line-height:1.35}
.figdlgclose{flex:none;border:1px solid var(--edge);background:none;color:var(--ink);font:inherit;font-size:.85rem;border-radius:12px;padding:.35rem .8rem;cursor:pointer}
.figdlgclose:hover{border-color:var(--cyan);color:var(--cyan)}
.figdlgpan{overflow:auto;flex:1;min-height:0;padding:.9rem;-webkit-overflow-scrolling:touch}
.figdlgpan svg{width:900px;max-width:none;display:block;margin:0 auto}
@media print{.figxbtn,dialog.figdlg{display:none}}
figure.fig figcaption{display:flex;gap:.7rem;align-items:baseline;border-top:1px solid var(--hair);
margin-top:.7rem;padding-top:.55rem;color:var(--greytx);font-size:.9rem;line-height:1.55}
figure.fig .fign{color:var(--cyan);font-weight:700;font-size:.74rem;letter-spacing:.14em;flex:none}
.figsvg .sk-ink{stroke:var(--ink)}.figsvg .sk-cyan{stroke:var(--cyan)}.figsvg .sk-grey{stroke:var(--grey)}
.figsvg .sk-amber{stroke:var(--amber)}.figsvg .sk-coral{stroke:var(--coral)}.figsvg .sk-bg{stroke:var(--bg)}
.figsvg .fl-ink{fill:var(--ink)}.figsvg .fl-cyan{fill:var(--cyan)}.figsvg .fl-grey{fill:var(--grey)}
.figsvg .fl-amber{fill:var(--amber)}.figsvg .fl-coral{fill:var(--coral)}.figsvg .fl-bg{fill:var(--bg)}
rect.fl-bg[stroke-width]{stroke:var(--ink)}
.figsvg text{font-family:'InkGlyphs','Poppins',sans-serif}
.dvec{position:relative;display:inline-block;font-style:normal;margin-top:.42em}
/* The backslash before 2192 below is doubled in build.py, and it has to be.
   This block is an ordinary Python triple-quoted string, not a raw one, so
   Python read the characters after a single backslash before CSS ever saw
   them: backslash-2-1 is a valid octal escape and 9 is not an octal digit, so
   Python produced U+0011 (device control 1) followed by the literal
   characters 9 and 2. What shipped in style.css was a
   raw control character and the text "92", and what a reader saw above the AB
   in an overrightarrow{AB} was a notdef box and the number 92: on the vectors
   hub, both vectors lessons, the checklist, key ideas and the equations page,
   21 times in all. Doubling the backslash is what makes the CSS escape reach
   the browser: U+2192 RIGHTWARDS ARROW, the same codepoint mathml.py:394 puts
   in the <mover> for the MathML rendering of the same notation, and one of the
   codepoints the self-hosted InkGlyphs face declares in its unicode-range, so
   the arrow is drawn from a font this site already ships rather than from
   whatever the reader's system happens to substitute.
   The gate that would have caught this is in qc.py: no stylesheet this build
   emits may contain a control character. Anything that looks like a CSS escape
   inside a non-raw Python string needs its backslash doubled or the string
   needs an r prefix; there is no third option that is correct. */
.dvec::before{content:"\2192";position:absolute;left:0;right:0;top:-.72em;font-size:.62em;text-align:center;line-height:1}
@keyframes an-swing{from{transform:translate(var(--ox),var(--oy)) rotate(var(--a0)) translate(var(--nox),var(--noy))}to{transform:translate(var(--ox),var(--oy)) rotate(var(--a1)) translate(var(--nox),var(--noy))}}
@keyframes an-flip{from{transform:translate(var(--ox),var(--oy)) scaleY(1) translate(var(--nox),var(--noy))}to{transform:translate(var(--ox),var(--oy)) scaleY(-1) translate(var(--nox),var(--noy))}}
@keyframes an-jit{0%{transform:translate(0,0)}25%{transform:translate(3.5px,-2.6px)}50%{transform:translate(-2.9px,1.9px)}75%{transform:translate(1.9px,3.2px)}100%{transform:translate(0,0)}}
@keyframes an-walk{0%{transform:translate(0,0)}13%{transform:translate(8px,-5px)}26%{transform:translate(3px,7px)}40%{transform:translate(-7px,11px)}55%{transform:translate(-12px,2px)}68%{transform:translate(-4px,-9px)}82%{transform:translate(6px,-12px)}100%{transform:translate(0,0)}}
@keyframes an-strike{0%{transform:translate(0,0)}40%{transform:translate(var(--sx),var(--sy))}52%{transform:translate(calc(var(--sx)*0.86),calc(var(--sy)*0.86))}64%{transform:translate(var(--sx),var(--sy))}76%{transform:translate(calc(var(--sx)*0.3),calc(var(--sy)*0.3))}100%{transform:translate(0,0)}}
@media (prefers-reduced-motion: reduce){.figsvg g[class^="an-"]{animation:none !important;transform:none !important}}
.figsvg .tx-ink{fill:var(--ink)}.figsvg .tx-cyan{fill:var(--cyan)}.figsvg .tx-grey{fill:var(--greytx)}
.figsvg .tx-amber{fill:var(--amber)}.figsvg .tx-coral{fill:var(--coral)}.figsvg .sk-greytx{stroke:var(--greytx)}.figsvg .fl-greytx{fill:var(--greytx)}
@media (prefers-reduced-motion: reduce){}
@media print{}
/* Figures animated through the global an-* classes must print still too. */
@media print{.figsvg g[class^="an-"]{animation:none !important;transform:none !important}}
.eqs{text-align:center;padding:.4rem .2rem .2rem;margin:1.9rem auto;overflow-x:auto;overflow-y:hidden}
.eqs .eq{display:block;font-size:clamp(1.15rem,4.6vw,1.5rem);font-weight:500;letter-spacing:.01em;line-height:1.35;white-space:nowrap}
.eqs .dstag{display:inline-block;margin-top:.7rem;font-size:.68rem;font-weight:700;letter-spacing:.15em;
border-radius:99px;padding:.22rem .8rem}
.eqs .ds-on{color:var(--amber);border:1px solid rgba(255,183,3,.45)}
.eqs .ds-off{color:var(--greytx);border:1px solid var(--edge)}
.eqs .ds-der{color:var(--greytx);border:1px dashed var(--edge)}
.eqs .eqcond{display:block;max-width:44rem;margin:.6rem auto 0;font-size:.86rem;line-height:1.45;
color:var(--greytx);white-space:normal;text-align:center}
.eqs .eqcond b{font-weight:700;letter-spacing:.12em;text-transform:uppercase;font-size:.7rem;margin-right:.35rem}
.ieq{font-weight:500;white-space:nowrap}
/* The two semantic twins of an equation: the MathML a screen reader reads and
   the linear text a copy takes. Hidden by clipping and taken out of the flow,
   not by display:none or visibility:hidden, either of which would drop the
   MathML out of the accessibility tree along with the pixels.

   Out of the flow is the load-bearing part. Hiding an inline twin in place
   with font-size:0 reads the same and copies the same, but Chromium still
   gives a <math> containing an <mfrac> a two-pixel minimum width, and two
   pixels beside an inline equation move the rest of the line. Absolute
   positioning is the only version that is provably zero. */
.eqml,.eqtx{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
/* Only the visual layer that has a semantic twin opts out of selection, so a
   copy takes the unambiguous .eqtx once instead of the picture and the MathML
   twice. Bare affixes ("R{{_{2}}}") carry no aria-hidden and stay selectable. */
.eqml,.eq[aria-hidden],.ieq[aria-hidden]{-webkit-user-select:none;user-select:none}
.frac{display:inline-flex;flex-direction:column;align-items:center;vertical-align:middle;line-height:1.25;margin:0 .1em}
.frac .n{border-bottom:1.6px solid currentColor;padding:0 .28em}
.frac .d{padding:0 .28em}
.rt{margin-right:.05em}
.rad{border-top:1.6px solid currentColor;padding:0 .15em}
.rt.big{font-size:2.05em;font-weight:400;line-height:1;vertical-align:middle;margin-right:.02em}
.rad.tall{display:inline-flex;align-items:center;vertical-align:middle;border-top:1.6px solid currentColor;padding:.12em .22em .12em .12em}
sup,sub{line-height:0}
.tblwrap{overflow-x:auto;margin:1.6rem auto}
.dtable{width:100%;border-collapse:collapse;font-size:.95rem}
.dtable th{font-size:.73rem;letter-spacing:.14em;text-transform:uppercase;color:var(--greytx);text-align:left;padding:.5rem .8rem;border-bottom:2px solid rgba(110,125,140,.5);font-weight:700}
.dtable td{padding:.55rem .8rem;border-bottom:1px solid rgba(110,125,140,.28)}
.dtable td:first-child{font-weight:700}
.rulecard{border:2px solid rgba(56,182,255,.55);border-radius:20px;text-align:center;padding:1.6rem 1.3rem;margin:2.7rem auto 0}
.rulecard p{margin:0;font-weight:700;font-size:clamp(1.1rem,3.6vw,1.32rem);line-height:1.5}
.rulecard .r2{color:var(--cyan)}
.videoline .pi{width:.8rem;height:.8rem;vertical-align:-.08em;margin-right:.35rem}
.next{display:inline-flex;align-items:center;gap:.6rem;border:1px solid var(--edge);border-radius:14px;
padding:.7rem 1.2rem;color:var(--ink);font-weight:500;transition:border-color .18s,transform .18s cubic-bezier(.2,.9,.3,1.25)}
.next:hover{border-color:var(--cyan);text-decoration:none;transform:translateY(-1px)}
.next svg{width:1rem;height:1rem;flex:none}
.pn{display:flex;gap:.9rem;justify-content:space-between;flex-wrap:wrap;margin:2.4rem auto 0}
.pn .next{max-width:100%}
.pn .rev svg{transform:scaleX(-1)}
.pn .pnl{font-size:.68rem;font-weight:700;letter-spacing:.15em;color:var(--greytx);display:block}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(13.5rem,1fr));gap:.95rem;margin:1.5rem 0}
/* The three first-level choices on the maths front door, in three fixed tracks
   rather than auto-fill. Auto-fill sizes tracks from the container, so at
   1280px it opened a fourth empty column and left the row looking like one that
   had lost a card; below 860px three tracks of that width would be unreadable,
   so they stack. The flex column is what makes the three cards the same height
   when one meta line wraps and another does not, which the audit also caught. */
.qcards{grid-template-columns:repeat(3,minmax(0,1fr))}
.qcards .card{display:flex;flex-direction:column}
@media(max-width:860px){.qcards{grid-template-columns:1fr}}
.card{border:1px solid var(--edge);background:var(--card);border-radius:20px;padding:1.05rem 1.15rem;color:var(--ink);display:block;transition:transform .18s cubic-bezier(.2,.9,.3,1.25),border-color .18s}
a.card:hover{transform:translateY(-2px);border-color:rgba(56,182,255,.5);text-decoration:none}
.card h2,.card h3{font-size:1.02rem;font-weight:700;margin:0 0 .25rem}
.card .meta{color:var(--greytx);font-size:.84rem;font-weight:500}
.card.quiet{color:var(--greytx)}
ul.topics{list-style:none;padding:0;margin:.8rem 0}
ul.topics li{padding:.62rem .2rem;border-bottom:1px solid var(--hair);display:flex;align-items:baseline;gap:.7rem;flex-wrap:wrap}
ul.topics .tag{font-size:.7rem;font-weight:700;letter-spacing:.12em;color:var(--greytx);border:1px solid var(--edge);border-radius:6px;padding:.06rem .48rem;flex:none}
ul.topics .writing{color:var(--greytx)}
.search{width:100%;background:var(--card);border:1px solid var(--edge);border-radius:12px;color:var(--ink);font:inherit;padding:.62rem .95rem;margin:.4rem 0 .8rem}
.search::placeholder{color:var(--greytx)}
.unitline{color:var(--greytx);font-weight:700;font-size:.78rem;letter-spacing:.14em;margin:1.5rem 0 .1rem}
.jumps{color:var(--greytx);font-size:.88rem;line-height:2;margin:.2rem 0 1.2rem}
.jumps a{color:var(--greytx);text-decoration:underline;text-underline-offset:3px;white-space:nowrap}
.jumps a:hover{color:var(--cyan)}
ul.topics .tag a{text-decoration:none;padding:.12rem .1rem}
ul.topics .tag a:hover{color:var(--cyan);text-decoration:underline;text-underline-offset:3px}
@media (max-width:560px){
.jumps{line-height:2.35}
.jumps a{display:inline-block;border:1px solid var(--edge);border-radius:99px;padding:0 .68rem;text-decoration:none;margin:0 .06rem;line-height:1.9}
ul.topics li.flt{display:block}
ul.topics li.flt .tag{display:table;margin-top:.45rem;font-size:.74rem}
ul.topics li.flt .meta{display:block;color:var(--greytx);font-size:.84rem;margin-top:.3rem}
}
.progress{color:var(--greytx);font-size:.95rem;font-weight:500;margin:-.5rem 0 1.2rem}
.hero{text-align:center;padding:2.4rem 0 1rem}
.hero .bigwm{margin:0 0 .1rem;display:flex;justify-content:center}
.hero .bigwm .wmsvg{height:clamp(2.85rem,9.4vw,4.35rem)}
/* 1.5rem, not the 1.2rem this rule carried, and the extra .3rem is the only
   thing left of the sine-curve strip that used to sit here. The hero is four
   things in a column: the wordmark, this tagline, the sub-copy and the
   actions. The wordmark and the tagline are one group, bound by the .45rem
   above; the sub-copy is the next group and needs to look like it, so the
   gap above it has to beat the 1.15rem a paragraph leaves below itself.
   With the old 1.2rem the sub-copy sat equidistant between the brand line
   and the buttons and belonged to neither. Nothing else moved: the strip
   was removed rather than replaced, because the brand guide allows no large
   subject motif on a subject homepage, and a sine curve is one topic of
   many on a page that has to stand for Pure, Statistics, Mechanics and the
   whole of Further Maths. */
.hero .tag{color:var(--greytx);font-weight:500;font-size:1.14rem;margin:.45rem 0 1.5rem}
.hero .links{display:flex;gap:.85rem;justify-content:center;flex-wrap:wrap}
/* background is not decoration here. .btn was written for anchors, which
   are transparent by default, and it sets a colour without one — so the
   four <button class=btn> controls on the account page took the user
   agent's own button face, which is near-white, and wore near-white
   text on it. Transparent keeps every anchor exactly as it was and
   removes the default face from every button. */
.btn{background:transparent;border:1px solid var(--edge);border-radius:12px;padding:.58rem 1.15rem;font-weight:500;color:var(--ink);transition:border-color .18s,transform .18s cubic-bezier(.2,.9,.3,1.25)}
.btn:hover{border-color:var(--cyan);text-decoration:none;transform:translateY(-1px)}
.btn.primary{border-color:var(--cyan);color:var(--cyan)}
/* .searchbox, not .search, and the difference is the whole point. .search is
   the bare filter input on /definitions/, /key-ideas/, /equations/, the
   checklist and every unit filter bar: it paints its own card, its own border
   and its own 12px radius, because it IS the control. The search page needs a
   wrapper as well, to hold the input and the results list together, and that
   wrapper was also called .search -- so on /maths/search/ the two rules both
   matched, the wrapper drew a rounded grey frame and the input drew a second
   one inside it, and the reader saw a box in a box. Physics hit this first and
   fixed it by naming the wrapper .searchbox and giving .searchbox no border,
   no background and no padding of its own; this is that fix, transplanted, so
   the two subjects stay one design. There is deliberately no .searchbox rule
   at all: the wrapper's only job is to be a block, and a rule that said so
   would be the first thing someone added a border to. */
.searchbox input{width:100%;max-width:34rem;padding:.62rem .9rem;border-radius:12px;border:1px solid var(--edge);background:transparent;color:var(--ink);font:inherit}
/* No outline:none here, unlike the rule this replaces. Recolouring the border
   on focus is a nice touch and a poor focus indicator on its own, and the
   physics twin already dropped the suppression for that reason: a keyboard
   reader keeps the browser's ring on top of the cyan border. */
.searchbox input:focus{border-color:var(--cyan)}
.searchbox input::placeholder{color:var(--greytx)}
/* The claim code on the app sign-in fallback page: big enough to read off one
   screen and type into another, which is the whole job. */
.appsi-code{margin:1.2rem 0}
.appsi-code code{font-size:1.35rem;letter-spacing:.08em;word-break:break-all;
background:var(--card);border:1px solid var(--edge);border-radius:12px;
padding:.7rem .9rem;display:inline-block;max-width:100%}
/* One select, one shape, everywhere on the subject. Before this rule the
   stylesheet contained the word appearance zero times, so every dropdown kept
   the browser's own control: a system-drawn box with a system-drawn arrow,
   sitting on a page that draws everything else itself. Worse, the two rules
   that did style selects disagreed -- .fcscope select was .82rem text, .35rem
   .5rem padding and a .45rem radius, .qbbar select was .92rem, .3rem .5rem and
   8px -- so the flashcards page and the question-practice page of the same
   subject offered the same control in two different sizes and two different
   corner radii, and the account page's two selects were styled by nobody at
   all. This is now the only place a select's size, padding, border and radius
   are set; the per-page rules that remain say only how wide the control may
   grow inside its own row.
   appearance:none removes the browser's arrow, so the page has to draw one,
   and .selw::after does it with the same rotated-border chevron the .ub
   summaries and the .acch accordions already use. It is deliberately NOT a
   background-image data URI: img-src in the Content-Security-Policy is 'self'
   and does not allow data:, so a data URI would need the policy widened, and
   widening a policy to draw a 7px arrow is a bad trade. pointer-events:none on
   the chevron keeps the whole control clickable through it.
   Keyboard behaviour is untouched: appearance:none changes painting only, the
   select still opens on Enter/Space/Alt-Down and still walks its options with
   the arrow keys, and there is no outline:none anywhere in this block, so the
   browser's focus ring lands on the control exactly as it did before. The
   radius is 12px, the value .btn and .search already use, inside the 10-12px
   band the guide gives inputs and ordinary buttons. */
.selw{position:relative;display:inline-block;max-width:100%;min-width:0}
.selw::after{content:"";position:absolute;pointer-events:none;right:.78rem;top:50%;
width:.4rem;height:.4rem;margin-top:-.32rem;border-right:2px solid var(--greytx);
border-bottom:2px solid var(--greytx);transform:rotate(45deg)}
select{appearance:none;-webkit-appearance:none;font:inherit;font-size:.92rem;
padding:.45rem 2.1rem .45rem .8rem;border:1px solid var(--edge);border-radius:12px;
background:var(--card);color:var(--ink);cursor:pointer;max-width:100%;min-width:0}
select:hover{border-color:var(--cyan)}
.wbblock{margin:2.4rem 0 0;padding:1.4rem 1.5rem;border:1px solid var(--edge);border-radius:20px;background:var(--card)}
.wbblock .gl{font-size:.72rem;letter-spacing:.14em;color:var(--cyan);font-weight:600;margin:0 0 .5rem}
.wbblock>p{margin:0 0 1rem;color:var(--greytx)}
.wbblock .cards{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
/* A card inside a panel must not repaint the panel's own surface. Both
   carry --card, which is a translucent white over the navy, so a workbook
   card sitting in a workbook block stacked two tints and lifted the ground
   under it from the navy the palette assumes to a lighter grey. Muted text
   on that doubled surface measures 4.49:1, which fails WCAG AA for body
   text by a hundredth, and on the single surface it is 4.96:1 and passes.
   Fixing the nesting rather than the colour keeps both approved tokens
   exactly as the brand guide sets them, and it follows the guide's own
   rule that a surface inside a surface is told apart by its border rather
   than by a second fill. Nothing else on the site stacks two translucent
   backgrounds: a browser sweep of every element on twelve pages across the
   three libraries found this one nesting and no other. */
.wbblock .card{background:transparent}

.card.wb h3{display:flex;align-items:center;gap:.4rem}
.card.wb h3 .pi{width:1rem;height:1rem;flex:none}
.note{color:var(--greytx);font-size:.88rem;margin:2.4rem auto 0}
footer.site{border-top:1px solid var(--hair);margin-top:3.4rem;padding:1.5rem 0 2.3rem;color:var(--greytx);font-size:.86rem}
footer.site a{color:var(--greytx);text-decoration:underline;text-underline-offset:3px}
footer.site .reg{font-size:.78rem;opacity:.8}
/* animation:none as well as transition:none, which is the whole of the fix.
   This reset killed transitions and nothing else, so a reader who has asked
   the operating system for no motion still got every @keyframes the site
   declares: exin (the 250ms 6px rise on each newly revealed worked-example
   step) and stepr/stepl (the 26px horizontal slide between lesson steps in the
   installed app) both ran, and those are exactly the vestibular triggers the
   setting exists to switch off. Biology's reset already reads
   animation:none!important;transition:none!important and this now matches it.
   scroll-behavior:auto stays because it belongs to the same promise: no
   smooth-scrolled jumps either.
   The educational animations inside diagrams are content rather than
   interface, and the honest position is that they are NOT exempted here and
   never were: .figsvg g[class^="an-"] and .animfig * each carry their own
   prefers-reduced-motion rule further up this stylesheet that stops them, and
   the still frame is drawn to be readable on its own. Adding animation to this
   universal rule therefore changes nothing about them -- it stops the same
   things they already stopped, by a shorter route -- and if a future diagram
   is ever meant to keep moving for a reader who asked for stillness, it needs
   its own considered opt-out and a reason written next to it, not the removal
   of this line. */
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto}}
@media (max-width:680px){header.site .wrap{flex-wrap:wrap;row-gap:.4rem}nav.top{width:100%;margin-left:0;flex-wrap:wrap;justify-content:space-between;gap:.4rem .9rem;font-size:.9rem}}
/* The print block. Its core is brand.PRINT_CSS; the hide list below is the
   part that is genuinely about this subject's own furniture. */
@media print{
:root{--bg:#ffffff;--ink:#15222e;--cyan:#0b6fae;--amber:#8a6100;--coral:#b3264e;--grey:#5a6570;--greytx:#5a6570;--card:#ffffff;--edge:#c9d1d8;--hair:#dfe5ea}
body{background:#fff;font-size:11pt;line-height:1.55}
a{color:inherit;text-decoration:none}
figure.fig,.panel,.eqs,.goals{break-inside:avoid;page-break-inside:avoid}
details{display:block}details summary{display:none}details>*{display:block}
.card{box-shadow:none}
header.site nav.top,.search,.searchbox,.pn,footer.site .fgroups,.hero .links{display:none}
.wbblock .card.wb{box-shadow:none}
}
.ckbar{display:flex;gap:.55rem;flex-wrap:wrap;margin:.2rem 0 1rem}.ckbar button{font:inherit;font-size:.82rem;padding:.4rem .8rem;border:1px solid var(--edge);border-radius:12px;background:var(--card);color:var(--ink);cursor:pointer}.ckbar button:hover{border-color:var(--cyan)}.ckbar button[aria-pressed=true]{border-color:var(--cyan);color:var(--cyan)}.cklegend{font-size:.8rem;color:var(--greytx);margin:.1rem 0 1.5rem}.cklegend span{white-space:nowrap;margin-right:1rem;line-height:2}.cklegend i{display:inline-flex;align-items:center;justify-content:center;font-style:normal;font-weight:700;font-size:.5rem;color:#0D1B2A;width:.72rem;height:.72rem;border-radius:50%;margin-right:.32rem;vertical-align:middle;box-sizing:border-box}.cklist{list-style:none;padding:0;margin:.2rem 0}li.ck{display:flex;gap:.65rem;align-items:flex-start;padding:.28rem 0}li.ck.hide{display:none}.ckdot{flex:0 0 auto;width:1.3rem;height:1.3rem;margin-top:.1rem;border-radius:50%;border:2px solid var(--grey);background:transparent;cursor:pointer;padding:0;position:relative;transition:background .12s,border-color .12s}.ckdot::before{content:'';position:absolute;inset:-12px}.ckdot::after{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:.76rem;font-weight:700;color:#0D1B2A;line-height:1}.ckdot:hover{border-color:var(--cyan)}li.ck[data-state="1"] .ckdot{background:var(--coral);border-color:var(--coral)}li.ck[data-state="1"] .ckdot::after{content:"!"}li.ck[data-state="2"] .ckdot{background:var(--amber);border-color:var(--amber)}li.ck[data-state="2"] .ckdot::after{content:"~"}li.ck[data-state="3"] .ckdot{background:#2ea043;border-color:#2ea043}li.ck[data-state="3"] .ckdot::after{content:"\2713"}.cktext{flex:1;line-height:1.45}.cktally{display:block;font-size:.8rem;color:var(--greytx);font-weight:400;letter-spacing:0;margin-top:.2rem}.cklesson{margin:0 0 1.15rem}.cklesson h3,.cklesson h2{margin:.1rem 0;font-size:1.02rem}.ckspec{font-size:.76rem;color:var(--greytx);font-weight:400;margin-left:.15rem}.ckstrip{margin-top:2.2rem;padding-top:1.3rem;border-top:1px solid var(--hair)}.ckstrip .cknote{font-size:.85rem;margin-top:.75rem}.qr dl{margin:0 0 .5rem}.qr dt{font-weight:700;margin:1.15rem 0 .15rem;color:var(--ink)}.qr dd{margin:0;line-height:1.5}.qr dd .eg{display:block;color:var(--greytx);font-size:.9rem;margin-top:.15rem}.ki{margin:0 0 1rem}.ki h3{margin:.1rem 0 .25rem;font-size:1.0rem}.ki ul{list-style:none;padding:0;margin:0}.ki li{padding:.1rem 0 .1rem .9rem;border-left:2px solid var(--edge);margin:.32rem 0;line-height:1.45}.ub{border-bottom:1px solid var(--edge)}.ub>summary::-webkit-details-marker{display:none}.ub>summary::after{content:'';margin-left:auto;flex:none;width:.5rem;height:.5rem;border-right:2px solid var(--greytx);border-bottom:2px solid var(--greytx);transform:rotate(45deg);transition:transform .18s ease;align-self:center}.ub[open]>summary::after{transform:rotate(-135deg)}.ub>summary:hover .ubt,.ub>summary:focus-visible .ubt{color:var(--cyan)}.ubt{font-weight:600;color:var(--ink)}.ubm{color:var(--greytx);font-size:.86rem}.ubn{color:var(--greytx);font-size:.74rem;font-weight:700;letter-spacing:.1em;border:1px solid var(--edge);border-radius:6px;padding:.06rem .48rem;flex:none;white-space:nowrap}.ubb{padding:.1rem 0 1.1rem}.fltbar{position:sticky;top:0;z-index:5;background:var(--bg);padding:.7rem 0 .5rem;margin:0 0 .4rem}.fltcount{display:flex;gap:.6rem;justify-content:space-between;margin:.35rem .1rem 0;font-size:.78rem;color:var(--greytx)}.fcgo{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .9rem;margin:.7rem 0 .2rem}.fcstart{font-weight:700;font-size:1rem;padding:.62rem 1.5rem;border-radius:999px;background:var(--cyan);color:var(--navy);border:0;cursor:pointer;min-height:44px}.fcstart:disabled{background:none;color:var(--greytx);border:1px solid var(--edge);cursor:default}.fcstart:hover{filter:brightness(1.08)}.fclink2{background:none;border:0;color:var(--greytx);font-size:.9rem;cursor:pointer;padding:.5rem .1rem;text-decoration:underline;text-underline-offset:3px;min-height:44px}.fclink2:hover,.fclink2:focus-visible{color:var(--cyan)}.fcman{margin:.5rem 0 0}.fcman>summary{cursor:pointer;color:var(--greytx);font-size:.84rem;padding:.45rem .1rem;min-height:44px;display:flex;align-items:center}.fcman>summary:hover{color:var(--cyan)}.azjump a:hover,.azjump a:focus-visible{color:var(--cyan)}@media print{.fltbar{display:none}.ub>summary::after{display:none}}.ki h2{margin:.1rem 0 .25rem;font-size:1.0rem}.ki h2{display:block;line-height:1.3;gap:0;letter-spacing:normal}.ki h2::before{content:none;display:none}.ub>summary{display:flex;align-items:baseline;flex-wrap:wrap;gap:.2rem .6rem;cursor:pointer;padding:.85rem .2rem;list-style:none;min-height:44px;box-sizing:border-box}.azjump{display:flex;flex-wrap:wrap;gap:.1rem .55rem;margin:.2rem .1rem 1.2rem;font-size:.84rem;font-weight:700}.azjump a{color:var(--greytx);text-decoration:none;padding:.15rem .1rem}@media print{.azjump{display:none}}.gdef{margin:0 0 .85rem}.gdef dt{font-weight:700;margin:.7rem 0 .1rem}.gdef dd{margin:0;line-height:1.5}.glink{color:var(--greytx);font-size:.88rem}.eqgrp{margin:0 0 1.35rem}.eqgrp h3,.eqgrp h2{margin:.1rem 0 .3rem;font-size:1.0rem}.eqgrp h2{display:block;line-height:1.3;gap:0;letter-spacing:normal}.eqgrp h2::before{content:none;display:none}.eqgrp .eqs{margin:.3rem 0}.fcbar{margin:.2rem 0 1.2rem}.fcbar[hidden]{display:none}.fcrow{display:flex;gap:.55rem;flex-wrap:wrap}.fcscope{display:flex;gap:.9rem;flex-wrap:wrap;margin:0 0 .65rem}.fcbar button,.fcgrade button,.fcnav button,.fcpr{font:inherit;font-size:.82rem;padding:.4rem .8rem;border:1px solid var(--edge);border-radius:12px;background:var(--card);color:var(--ink);cursor:pointer}.fcbar button:hover,.fcgrade button:hover,.fcnav button:hover,.fcpr:hover{border-color:var(--cyan)}@media (max-width:560px){.fcrow{display:grid;grid-template-columns:1fr 1fr;gap:.45rem}.fcrow button{width:100%}}.fccard{display:flex;flex-direction:column;width:100%;max-width:660px;margin:.4rem auto 1rem;background:var(--card);border:2px solid rgba(56,182,255,.55);border-radius:22px;padding:1.5rem 1.7rem 1.2rem;min-height:15rem;cursor:pointer;text-align:left;color:var(--ink);font:inherit;transition:transform .14s ease}.fccard.turn{transform:rotateY(90deg)}.fccard:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}.fctype{font-size:.72rem;font-weight:700;letter-spacing:.14em;color:var(--cyan);margin:0 0 .7rem}.fctopic{font-size:.78rem;color:var(--greytx);margin:0 0 .25rem}.fcq{font-size:1.12rem;line-height:1.55;margin:.2rem 0}.fccard .r1,.fccard .r2{font-weight:700;font-size:1.05rem;line-height:1.5;margin:.5rem 0}.fccard .r2{color:var(--cyan)}.fcfoot{display:flex;justify-content:space-between;align-items:center;margin-top:auto;border-top:1px solid var(--hair);padding-top:.7rem;font-size:.8rem;color:var(--greytx)}.fcprog{font-size:.85rem;color:var(--greytx);max-width:660px;margin:.4rem auto}.fcgrade{display:flex;gap:.55rem;max-width:660px;margin:.4rem auto 1rem}.fcgrade button{flex:1;text-align:center}.fcgrade button.g1{border-color:var(--coral)}.fcgrade button.g2{border-color:var(--amber)}.fcgrade button.g3{border-color:var(--cyan)}.fcnav{display:flex;gap:.55rem;max-width:660px;margin:.2rem auto 1.2rem}.fcunit{margin-top:2.4rem}.fcunit h2 .fcpr{margin-left:.7rem;vertical-align:middle}.fccard .eqs{margin:.9rem auto}.fccard .eqs .eq{font-size:clamp(1rem,3.4vw,1.25rem)}@media print{.fcbar,#fcplayer{display:none}}.fcscope label{display:flex;align-items:center;flex-wrap:wrap;gap:.3rem .45rem;min-width:0;font-size:.92rem;color:var(--greytx)}.fcscope .selw{max-width:100%;min-width:0}.fcscope select{max-width:100%}.fcanswer .r2{font-weight:700;font-size:1.05rem;line-height:1.5;margin:.5rem 0}.fcanswer .r2{color:var(--cyan)}.fcd .eqs{margin:.9rem auto}.fcd .eqs .eq{font-size:clamp(1rem,3.4vw,1.25rem)}.apptabs{display:none}a.searchtop{display:none}@media (display-mode: standalone){nav.top{display:none}a.searchtop{display:flex;align-items:center;color:var(--ink);-webkit-tap-highlight-color:transparent}body{padding-bottom:calc(72px + env(safe-area-inset-bottom))}.apptabs{display:flex;position:fixed;bottom:0;left:0;right:0;z-index:60;background:var(--bg);border-top:1px solid var(--hair);padding-bottom:env(safe-area-inset-bottom)}@supports (backdrop-filter: blur(1px)){.apptabs{background:color-mix(in srgb,var(--bg) 86%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}}.apptabs a{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;padding:9px 0 7px;color:var(--greytx);font-size:.6rem;font-weight:500;letter-spacing:.04em;text-decoration:none;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}header.site{padding-top:env(safe-area-inset-top)}.apptabs a svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:transform .12s}.apptabs a.on{color:var(--cyan)}.apptabs a:active svg{transform:scale(.88)}.crumbs{display:none}footer.site{display:none}main h1{font-size:1.7rem}.lede{font-size:.98rem}.topics li.flt{display:flex;align-items:center;justify-content:space-between;gap:.8rem;min-height:50px;border-bottom:1px solid var(--hair);padding:.35rem 0}.lprog{height:4px;background:var(--hair);border-radius:2px;margin:.3rem 0 .55rem;overflow:hidden}.lprog i{display:block;height:100%;width:0;background:var(--cyan);transition:width .25s}.lproglbl{font-size:.72rem;letter-spacing:.06em;color:var(--greytx);text-transform:uppercase;margin:0 0 .9rem}.lstep{display:none}.lstep.on{display:block}.lnav{display:flex;gap:.6rem;margin:1.5rem 0 .6rem}.lnav button{flex:1;font:inherit;font-size:.95rem;padding:.72rem;border-radius:12px;border:1px solid var(--edge);background:var(--card);color:var(--ink);cursor:pointer}.lnav button[data-l-next]{border-color:var(--cyan);font-weight:600}.lnav button:disabled{opacity:.35}.lstep.si-r{animation:stepr .18s ease}.lstep.si-l{animation:stepl .18s ease}.uprog{height:5px;border-radius:3px;background:var(--hair);overflow:hidden;margin:.55rem 0 .25rem}.uprog i{display:block;height:100%;background:var(--cyan);border-radius:3px}.usub{font-size:.72rem;color:var(--greytx)}.donetick{color:var(--cyan);font-weight:700;margin-left:.45rem}.acch{cursor:pointer;-webkit-user-select:none;user-select:none;display:flex;align-items:center;justify-content:space-between;gap:.6rem}.acch::after{content:"";flex:none;width:9px;height:9px;border-right:2px solid var(--greytx);border-bottom:2px solid var(--greytx);transform:rotate(45deg);transition:transform .15s}.acch.acco::after{transform:rotate(225deg)}header.site .wrap{padding-top:.5rem;padding-bottom:.5rem}.fcrow button{flex:1 1 30%;padding:.6rem .5rem}.fcmanage{display:none;margin-top:.55rem}.fcmanage.open{display:flex}.fcmanagetg{font:inherit;font-size:.78rem;background:none;border:0;color:var(--greytx);text-decoration:underline;cursor:pointer;padding:.45rem 0 0;display:block}.fcunit h2 .ckspec{display:none}.exnext{font:inherit;font-size:.85rem;padding:.5rem .95rem;margin:.45rem 0 .15rem;border:1px solid var(--cyan);border-radius:12px;background:var(--card);color:var(--ink);cursor:pointer}.exin{animation:exin .25s ease}}@keyframes exin{from{opacity:0;transform:translateY(6px)}}@keyframes stepr{from{opacity:.25;transform:translateX(26px)}to{opacity:1;transform:none}}@keyframes stepl{from{opacity:.25;transform:translateX(-26px)}to{opacity:1;transform:none}}.hintcard{border:1px solid var(--hair);border-radius:14px;padding:.85rem 1rem;margin:.2rem 0 1rem;font-size:.88rem;color:var(--greytx);display:flex;justify-content:space-between;gap:.8rem;align-items:flex-start}.hintcard button{font:inherit;background:none;border:0;color:var(--cyan);cursor:pointer;padding:0;font-weight:600}.statwrap .big{font-size:1.4rem;font-weight:700;color:var(--ink);margin:.3rem 0}.statbars{display:flex;align-items:flex-end;gap:4px;height:88px;margin:.6rem 0 1rem}.statcol{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;justify-content:flex-end;min-width:0}.statcol i{display:block;width:100%;max-width:22px;border-radius:4px 4px 0 0;background:var(--cyan)}.statcol span{font-size:.56rem;color:var(--greytx);white-space:nowrap}.statrow{display:flex;align-items:center;gap:.7rem;margin:.45rem 0}.statlbl{flex:0 0 9.5rem;font-size:.82rem;color:var(--greytx);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.statprog{flex:1;margin:0}.statn{flex:0 0 3.2rem;text-align:right;font-size:.8rem;color:var(--ink)}@media (max-width:480px){.statlbl{flex-basis:7.2rem;font-size:.74rem}}@media not (prefers-reduced-motion: reduce){@view-transition{navigation:auto}}.tbadge{position:absolute;top:3px;left:50%;margin-left:8px;background:var(--coral);color:#fff;font-style:normal;font-size:.58rem;font-weight:700;line-height:15px;min-width:15px;border-radius:8px;padding:0 4px;text-align:center}.offpill{display:none;align-items:center;font-size:.66rem;letter-spacing:.08em;border:1px solid var(--hair);border-radius:99px;padding:.15rem .55rem;color:var(--greytx)}.offpill.on{display:inline-flex}a.card{transition:transform .12s}a.card:active{transform:scale(.985)}html{-webkit-tap-highlight-color:rgba(56,182,255,.12)}.appdash .big{font-size:1.5rem;font-weight:700;color:var(--ink);margin:.35rem 0}.ckprog{height:7px;border-radius:4px;background:var(--hair);overflow:hidden;margin:.5rem 0}.ckprog i{display:block;height:100%;width:0;border-radius:4px;background:var(--cyan);transition:width .4s}@media (display-mode: standalone){footer.site .fgroups{display:none}}.tqlist{list-style:none;padding:0;margin:1.4rem 0}.tqq{border-top:1px solid var(--hair);padding:1rem 0}.tqq:last-child{border-bottom:1px solid var(--hair)}.tqmeta{font-size:.74rem;letter-spacing:.06em;text-transform:uppercase;color:var(--greytx);margin:0 0 .35rem}.tqtext{margin:0}.tqa{margin:.6rem 0 0}.tqa summary{cursor:pointer;font-size:.85rem;color:var(--cyan);padding:.35rem 0;min-height:32px}.tqa>div{border-left:2px solid var(--edge);padding:.1rem 0 .1rem .8rem;margin:.3rem 0 0;color:var(--greytx);font-size:.94rem}.tqgo{margin:1.6rem 0 .4rem}.qbbar{margin:.2rem 0 1.1rem}.qbbar[hidden]{display:none}.qbscope{display:flex;flex-wrap:wrap;gap:.5rem 1rem;align-items:baseline;font-size:.92rem;color:var(--greytx);margin-bottom:.2rem}.qbscope label{min-width:0}.qbscope select{width:100%}select option{background:var(--navy);color:var(--ink)}@media print{:root{color-scheme:light}}.qbgo{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .9rem;margin:.7rem 0 .2rem}.qbstart{font-weight:700;font-size:1rem;padding:.62rem 1.5rem;border-radius:999px;background:var(--cyan);color:var(--navy);border:0;cursor:pointer;min-height:44px}.qbstart:hover{filter:brightness(1.08)}.qbstart:disabled{background:none;color:var(--greytx);border:1px solid var(--edge);cursor:default}.qblink{background:none;border:0;color:var(--greytx);font-size:.9rem;cursor:pointer;padding:.5rem .1rem;text-decoration:underline;text-underline-offset:3px;min-height:44px}.qblink:hover,.qblink:focus-visible{color:var(--cyan)}.qbman{margin:.4rem 0 0}.qbman>summary{cursor:pointer;color:var(--greytx);font-size:.84rem;padding:.45rem .1rem;min-height:44px;display:flex;align-items:center}.qbman>summary:hover{color:var(--cyan)}.qbcard{border:2px solid var(--edge);border-radius:20px;background:var(--card);padding:1.15rem 1.2rem 1.3rem;margin:.4rem 0 1rem}.qbmeta{display:flex;flex-wrap:wrap;gap:.45rem;align-items:center;margin:0 0 .7rem}.qbchip{font-size:.68rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--greytx);border:1px solid var(--edge);border-radius:6px;padding:.1rem .5rem}.qbchip.on{color:var(--navy);background:var(--cyan);border-color:var(--cyan)}.qbq{font-size:1.06rem;line-height:1.55;margin:.1rem 0 .9rem}.qbwork{width:100%;box-sizing:border-box;font:inherit;font-size:.95rem;line-height:1.5;min-height:5.5rem;padding:.6rem .7rem;border-radius:12px;background:var(--bg);color:var(--ink);border:1px solid var(--edge);resize:vertical}.qbhint{font-size:.82rem;color:var(--greytx);margin:.35rem 0 .8rem}.qbans{border-top:1px solid var(--edge);margin-top:1rem;padding-top:.9rem}.qbans h3{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--cyan);margin:0 0 .5rem}.qbans p{line-height:1.6;margin:.3rem 0}.qbgrade{display:flex;flex-wrap:wrap;gap:.5rem;margin:1rem 0 .2rem}.qbgrade button{font:inherit;font-size:.9rem;font-weight:600;padding:.55rem 1rem;border-radius:999px;cursor:pointer;min-height:44px;border:1px solid var(--edge);background:var(--bg);color:var(--ink)}.qbgrade button:hover{border-color:var(--cyan)}.qbg0{border-color:var(--coral)!important;color:var(--coral)!important}.qbg1{border-color:var(--amber)!important;color:var(--amber)!important}.qbg2{border-color:#2ea043!important;color:#2ea043!important}.qbprog{display:flex;justify-content:space-between;gap:.8rem;font-size:.8rem;color:var(--greytx);margin:.2rem .1rem 0}.qbdone{text-align:center;padding:1.6rem 1rem}.qbdone .big{font-size:1.5rem;font-weight:700;color:var(--ink);margin:.2rem 0 .5rem}.qbpaper{border-top:1px solid var(--edge);padding-top:.7rem;font-size:.92rem;color:var(--greytx)}.qbpaperbar{display:flex;justify-content:space-between;align-items:center;gap:.8rem;margin:.2rem 0 .5rem}.qbclock{font-weight:700;font-size:1.1rem;color:var(--ink);font-variant-numeric:tabular-nums}.qbyours{border-top:1px solid var(--edge);margin-top:1rem;padding-top:.9rem}.qbyours h3{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--greytx);margin:0 0 .5rem}.qbyours p{white-space:pre-wrap;line-height:1.55;margin:.3rem 0;color:var(--ink)}.qbmarks{align-items:center;gap:.4rem}.qbmkl{font-size:.82rem;color:var(--greytx)}.qbmk{min-width:46px;font-variant-numeric:tabular-nums;font-weight:700;padding:.55rem .5rem}.qbbd{margin:1.1rem 0 0;text-align:left}.qbbd>summary{cursor:pointer;color:var(--greytx);font-size:.84rem;padding:.45rem .1rem;min-height:44px;display:flex;align-items:center}.qbbd>summary:hover{color:var(--cyan)}.qbsketch{margin:.7rem 0 .2rem}.qbskh{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--greytx);margin:0 0 .4rem}.qbcanvas{--skink:var(--cyan);display:block;width:100%;border-radius:12px;background:var(--bg);border:1px solid var(--edge);touch-action:none;cursor:crosshair}.qbcanvas[data-ro]{cursor:default}.qbsktools{display:flex;flex-wrap:wrap;align-items:center;gap:.2rem .8rem;margin-top:.1rem}@media print{.qbsktools{display:none}.qbbar,.qbgrade,.qbwork{display:none}}.qbscope .selw{width:100%}.qbbar select{max-width:100%}.qbgo label{min-width:0;max-width:100%}.qbstrip{border:1px solid var(--edge);border-radius:16px;padding:.9rem 1rem;margin:1.4rem 0;display:flex;flex-wrap:wrap;gap:.5rem 1rem;align-items:center}.qbstrip .qbn{font-weight:700;color:var(--ink)}.qbclock.qblow{color:var(--coral)}.plset{margin:.4rem 0 1.4rem}.plset fieldset{border:0;padding:0;margin:0 0 1.5rem}.plset legend{font-weight:700;font-size:1.05rem;padding:0;margin:0 0 .2rem}.plset .meta{margin:0 0 .7rem}.plopts{display:flex;flex-wrap:wrap;gap:.5rem}.plopt{font:inherit;font-size:.95rem;font-weight:600;padding:.55rem 1.1rem;border-radius:999px;cursor:pointer;min-height:44px;border:1px solid var(--edge);background:var(--bg);color:var(--ink)}.plopt:hover{border-color:var(--cyan)}.plopt[aria-pressed=true]{background:var(--cyan);border-color:var(--cyan);color:var(--navy)}.pldays .plopt{min-width:3.4rem;padding:.55rem .5rem;text-align:center}.plsum{border:1px solid var(--edge);border-radius:16px;padding:.9rem 1.1rem;margin:.2rem 0 1.4rem;font-size:.95rem;color:var(--greytx)}.plsum b{color:var(--ink)}.pldots{display:flex;gap:.2rem;margin:.2rem 0 1.1rem}.pldot{flex:1 1 0;height:.36rem;border-radius:3px;background:var(--edge);min-width:2px}.pldot.on{background:var(--cyan)}.pldot.at{background:var(--amber)}.plkind{font-size:.68rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--cyan);margin:0 0 .5rem}.plles h2{margin:.1rem 0 .5rem;font-size:1.3rem}.plles h2::before{display:none}.plles .meta{margin:0 0 1rem}.plflip{cursor:pointer}.pldone{text-align:center;padding:1.8rem 1rem 1.6rem}.plring{display:block;margin:0 auto .9rem;width:104px;height:104px}.plring circle{fill:none;stroke-width:6;stroke-linecap:round}.plring .trk{stroke:var(--edge)}.plring .arc{stroke:var(--cyan);stroke-dasharray:295;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%}.plring .tk{fill:none;stroke:var(--cyan);stroke-width:7;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:44;stroke-dashoffset:0}.plgo .plring .arc{animation:plarc .9s ease-out both}.plgo .plring .tk{animation:pltk .45s .75s ease-out both}.plgo .pldone .big{animation:plpop .5s .9s ease-out both}@keyframes plarc{from{stroke-dashoffset:295}to{stroke-dashoffset:0}}@keyframes pltk{from{stroke-dashoffset:44}to{stroke-dashoffset:0}}@keyframes plpop{from{opacity:0;transform:translateY(.4rem) scale(.94)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.plgo .plring .arc,.plgo .plring .tk,.plgo .pldone .big{animation:none}}.plbackbar{position:fixed;left:0;right:0;bottom:0;z-index:8;display:flex;justify-content:center;padding:.6rem .8rem calc(.6rem + env(safe-area-inset-bottom));background:linear-gradient(to top,var(--bg) 62%,rgba(13,27,42,0))}.plbackbar button{font:inherit;font-weight:700;font-size:.95rem;padding:.62rem 1.5rem;border-radius:999px;background:var(--cyan);color:var(--navy);border:0;cursor:pointer;min-height:44px;box-shadow:0 6px 22px rgba(0,0,0,.4)}body.hasplanbar{padding-bottom:4.5rem}@media print{.plbackbar{display:none}}.flagbtn{background:none;border:0;color:var(--greytx);font:inherit;font-size:.78rem;cursor:pointer;padding:.4rem .1rem;text-decoration:underline;text-underline-offset:3px;min-height:44px}.flagbtn:hover,.flagbtn:focus-visible{color:var(--cyan)}.lsec>.flagbtn{display:block;margin:.1rem 0 0}figcaption .flagbtn{font-size:.72rem;min-height:0;padding:.15rem .1rem}.flagrow{margin:.6rem 0 0}.flagdlg{background:var(--bg);background-image:linear-gradient(var(--card),var(--card));color:var(--ink);border:2px solid var(--edge);box-shadow:0 18px 50px rgba(0,0,0,.55);border-radius:18px;padding:1.1rem 1.2rem;max-width:26rem;width:calc(100vw - 2.4rem)}.flagdlg::backdrop{background:rgba(3,8,14,.78)}.flagdlg h2{margin:0 0 .6rem;font-size:1.05rem}.flagcats{display:flex;flex-direction:column;gap:.15rem;margin:0 0 .8rem}.flagcats label{display:flex;gap:.5rem;align-items:baseline;padding:.22rem 0;cursor:pointer}.flagnote{display:block;font-size:.84rem;color:var(--greytx);margin:0 0 .3rem}.flagdlg textarea{width:100%;box-sizing:border-box;font:inherit;font-size:.92rem;min-height:4.2rem;padding:.5rem .6rem;border-radius:10px;background:var(--bg);color:var(--ink);border:1px solid var(--edge);resize:vertical}.flagemail{width:100%;box-sizing:border-box;font:inherit;font-size:.92rem;min-height:44px;padding:.5rem .6rem;border-radius:10px;background:var(--bg);color:var(--ink);border:1px solid var(--edge)}.flagts{margin:.7rem 0 0}.flagstat{font-size:.88rem;margin:.5rem 0 0;min-height:1.2em}.flagact{display:flex;gap:.6rem;justify-content:flex-end;margin-top:.6rem}.flagact button{font:inherit;cursor:pointer;min-height:44px;padding:.5rem 1.1rem;border-radius:999px}.flagcancel{background:none;border:1px solid var(--edge);color:var(--ink)}.flagsend{background:var(--cyan);color:var(--navy);border:0;font-weight:700}.optsel{border:1px solid var(--edge);border-radius:12px;background:var(--card);margin:.2rem 0 1.1rem;padding:0}.optsel>summary{cursor:pointer;padding:.7rem .9rem;font-weight:600;font-size:.92rem}.optbody{padding:0 .9rem .9rem}.optrows{display:flex;flex-wrap:wrap;gap:.55rem .95rem;margin:.5rem 0}.optrow{display:flex;align-items:center;gap:.45rem;font-size:.86rem;min-height:2.75rem}.optrow input{width:1.1rem;height:1.1rem}.optfm{font-weight:600;font-size:.92rem}.optpapers{margin:.2rem 0 0;padding-left:1.1rem;border-left:1px solid var(--hair)}.optpapers[hidden]{display:none}.ckall{margin:.1rem 0 1rem;font-size:.9rem;color:var(--greytx)}.ckunit.ckoff,.optoff{opacity:.5}.ckunit.ckoff .ubt::after,.optoff>summary .ubt::after{content:" (not on your course)";font-weight:400;color:var(--greytx);font-size:.82rem}.optclear{font:inherit;font-size:.8rem;padding:.4rem .7rem;border-radius:12px;border:1px solid var(--edge);background:transparent;color:var(--greytx);cursor:pointer}html{-webkit-text-size-adjust:100%}.brandrow{display:flex;align-items:center;gap:.6rem;min-width:0}.brandrow .wmsvg{display:block}.brandsub{display:flex;align-items:center;text-decoration:none;margin-right:.15rem}.brandpar{display:flex;align-items:center;text-decoration:none;padding-left:.6rem;border-left:1px solid var(--ink-edge);opacity:.85}.brandpar:hover,.brandpar:focus-visible{opacity:1}@media(max-width:420px){.brandpar{padding-left:.42rem}.brandpar .wmsvg{height:13px}.brandrow{gap:.42rem}}nav.top a[aria-current]{color:var(--subject-accent);opacity:1;border-bottom:2px solid var(--subject-accent)}nav.top [aria-disabled=true]{color:var(--ink-muted);cursor:default;display:inline-flex;align-items:baseline;gap:.32rem}nav.top [aria-disabled=true] .soon{font-size:.62rem;letter-spacing:.04em;text-transform:uppercase;border:1px solid var(--ink-edge);border-radius:999px;padding:.06rem .34rem;white-space:nowrap}.navbtn{display:none;align-items:center;justify-content:center;width:44px;height:44px;border:1px solid var(--ink-edge);border-radius:12px;background:transparent;color:var(--ink-text);cursor:pointer;flex:none}.navbtn svg{width:20px;height:20px}@media(max-width:720px){.navbtn{display:inline-flex}header.site nav.top{display:none;order:3;width:100%;flex-wrap:wrap;gap:.2rem .9rem;padding:.5rem 0 .1rem;border-top:1px solid var(--ink-hair);margin-top:.55rem}header.site nav.top.open{display:flex}header.site nav.top a{padding:.55rem 0;min-height:44px;display:inline-flex;align-items:center}}@media(prefers-reduced-motion:no-preference){.navbtn{transition:border-color 140ms ease}}.fgroups{display:grid;gap:var(--space-5) var(--space-6);grid-template-columns:repeat(4,minmax(0,1fr));margin:0 0 var(--space-5)}@media(max-width:900px){.fgroups{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:520px){.fgroups{grid-template-columns:1fr}}.fgroup h2{font-size:.74rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-muted);margin:0 0 .5rem;font-weight:600}.fgroup ul{list-style:none;margin:0;padding:0;display:grid;gap:.34rem}.fgroup a{color:var(--ink-text);text-decoration:none;font-size:.88rem}.fgroup a:hover,.fgroup a:focus-visible{text-decoration:underline;text-underline-offset:3px}.beta{display:inline-block;font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;border:1px solid var(--ink-edge);border-radius:999px;padding:.1rem .42rem;color:var(--ink-muted);vertical-align:.14em;margin-left:.45rem;font-weight:600}