/* AP Precalculus Practice for Central Magnet Students.
   One stylesheet, no CDN, no web fonts.
   Mobile first: every rule below is written for a 360px-wide phone and only
   widened at a breakpoint. The only thing on the page that has a natural width
   is the question PNG (853px), and it is clamped to the column. */

:root {
  --ink:        #17181a;
  --ink-soft:   #55585e;
  --line:       #d8dce2;
  --paper:      #ffffff;
  --sunken:     #f4f6f8;
  --brand:      #0b5cab;
  --brand-dark: #073f77;
  --right:      #1b6b33;
  --right-bg:   #e8f5ec;
  --wrong:      #a3282a;
  --wrong-bg:   #fdeceb;
  --radius:     10px;
  --tap:        48px;          /* nothing tappable is smaller than this */
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding: 0;
  background: var(--sunken);
  color: var(--ink);
  font: 17px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  overflow-wrap: break-word;   /* a long token must wrap, never widen the page */
}

/* ---- chrome -------------------------------------------------------- */

.bar {
  display: flex; align-items: baseline; gap: 4px 10px;
  /* The site name is long ("AP Precalculus Practice for Central Magnet
     Students"), so the bar is allowed to take two lines on a narrow screen
     rather than truncating the school out of it. */
  flex-wrap: wrap;
  padding: 9px 14px;
  background: var(--brand); color: #fff;
  font-size: 15px;
  position: sticky; top: 0; z-index: 10;
  padding-top: max(9px, env(safe-area-inset-top));
}
.bar-title { font-weight: 600; min-width: 0; line-height: 1.25; }

/* The site mark. Inline SVG rather than a file: no second request, it inherits
   the bar's white through currentColor, and it is the same path as the favicon.
   align-self is required -- the bar is align-items: baseline, and an SVG has no
   useful baseline, so without this it hangs below the text. flex-shrink: 0
   keeps it whole when the long title wraps to two lines on a phone. */
.bar-icon { align-self: center; flex-shrink: 0; display: block; }

@media (max-width: 420px) {
  .bar-title { font-size: 13.5px; }
  .bar-icon { width: 18px; height: 18px; }
}
.bar-who { margin-left: auto; opacity: .85; font-size: 13px;
           max-width: 45%; overflow: hidden; text-overflow: ellipsis;
           white-space: nowrap; }

#main {
  max-width: 720px;
  margin: 0 auto;
  padding: 16px 14px 40px;
}

.foot {
  max-width: 720px; margin: 0 auto;
  padding: 0 14px 24px;
  color: var(--ink-soft); font-size: 12px; text-align: center;
}

.screen { background: var(--paper); border: 1px solid var(--line);
          border-radius: var(--radius); padding: 16px 14px 20px; }

h1 { font-size: 21px; margin: 0 0 8px; line-height: 1.25; }

/* Visible to a screen reader and to nothing else. The question screen's only
   heading is one of these: the numbers beside it are already on the page, but
   not as anything that can be jumped to. Same technique the bank uses for
   .pwsep, spelled the same way. */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden;
      clip-path: inset(50%); white-space: nowrap; margin: 0; padding: 0; }
h2 { font-size: 15px; margin: 0 0 6px; letter-spacing: .02em;
     text-transform: uppercase; color: var(--ink-soft); }
.lede { margin: 0 0 16px; color: var(--ink-soft); font-size: 15px; }

/* ---- forms and buttons ---------------------------------------------- */

.field { display: block; margin-bottom: 14px; }
.field span { display: block; font-size: 14px; color: var(--ink-soft);
              margin-bottom: 5px; }
.field input {
  width: 100%; min-height: var(--tap);
  padding: 10px 12px;
  font: inherit; font-size: 17px;   /* 16px+ or iOS zooms the whole page in */
  color: var(--ink);
  border: 1.5px solid var(--line); border-radius: 8px; background: #fff;
}
.field input:focus { outline: 3px solid #bcd6f2; border-color: var(--brand); }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); width: 100%;
  padding: 10px 16px;
  font: inherit; font-weight: 600;
  border-radius: 8px; border: 1.5px solid transparent;
  cursor: pointer;
}
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary:active { background: var(--brand-dark); }
.btn-quiet { background: #fff; color: var(--brand); border-color: var(--line);
             font-weight: 500; margin-top: 12px; }
.btn:focus-visible { outline: 3px solid #bcd6f2; outline-offset: 2px; }

.row { display: flex; flex-direction: column; gap: 0; }

.err { color: var(--wrong); font-size: 14px; margin: -6px 0 12px; }

/* ---- topic list ------------------------------------------------------ */

.topics { list-style: none; margin: 0 0 4px; padding: 0; }
.topics li { margin-bottom: 8px; }
.topics button {
  display: flex; align-items: center; gap: 10px;
  width: 100%; min-height: var(--tap);
  padding: 11px 12px;
  font: inherit; text-align: left;
  background: #fff; color: var(--ink);
  border: 1.5px solid var(--line); border-radius: 8px; cursor: pointer;
}
.topics button:active { background: var(--sunken); }
.topics .tcode { font-variant-numeric: tabular-nums; font-weight: 700;
                 color: var(--brand); min-width: 3.1em; }
.topics .tname { flex: 1 1 auto; font-size: 15px; line-height: 1.3; }
.topics .tn    { color: var(--ink-soft); font-size: 13px; white-space: nowrap; }
.topics .done  { color: var(--right); font-weight: 600; }

/* ---- question -------------------------------------------------------- */

.qhead { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.qtopic { font-size: 14px; color: var(--ink-soft); flex: 1 1 auto; }
.qcount { font-size: 14px; color: var(--ink-soft); font-variant-numeric: tabular-nums;
          white-space: nowrap; }

.qprogress { height: 4px; background: var(--line); border-radius: 2px;
             overflow: hidden; margin-bottom: 14px; }
.qprogress-fill { height: 100%; width: 0; background: var(--brand);
                  transition: width .18s ease; }

/* ---- the question ----------------------------------------------------
   An item is the bank's HTML (.qstem + .qfigure) or, if its markup did not
   survive the export, the PNG it always had (.qfig). One or the other. */

.qstem { margin: 0 0 4px; }
.qfigure { margin: 0 0 14px; }

.qfig { margin: 0 0 16px; }
/* The PNG is 853px at 150dpi. Cap it to the column and let it scale; never let
   it set the page width, which is what would create a horizontal scrollbar. */
.qfig img { display: block; width: 100%; max-width: 853px; height: auto;
            margin: 0 auto; background: #fff; }

/* ---- the choices -----------------------------------------------------
   TWO LAYOUTS, because there are two kinds of choice.

   A fallback item's choices are inside its picture, so its buttons carry only
   a letter and four of them fit across. An HTML item's button carries the
   choice itself -- a stacked fraction, a piecewise definition three clauses
   long -- so they go one per row, full width, the way the review page Randy
   approved puts them. The exception is the item whose choices ARE figures,
   which pairs them up because four mini-graphs in one column is a scroll. */

.choices { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.choices.choices-html { grid-template-columns: 1fr; gap: 8px; }
.choices.choices-fig  { grid-template-columns: repeat(2, 1fr); }

.choice {
  min-height: 56px;
  font: inherit; font-size: 20px; font-weight: 700;
  background: #fff; color: var(--brand);
  border: 2px solid var(--line); border-radius: 8px; cursor: pointer;
}
/* An HTML choice is a row: the letter, then the choice. Left-aligned and set
   in the body weight, because it is mathematics to read rather than a label to
   press -- the button is still the whole row. */
.choices-html .choice {
  display: flex; align-items: flex-start; gap: 10px;
  text-align: left; font-size: 17px; font-weight: 400;
  color: var(--ink); padding: 10px 11px; min-height: 48px;
}
.choices-html .clet { flex: 0 0 auto; font-weight: 700; color: var(--brand);
                      font-size: 16px; min-width: 1.5em; }
.choices-html .cbody { flex: 1 1 auto; min-width: 0; }
/* A figure choice puts the picture under nothing: its (A)-(D) label is drawn
   inside it by the bank. */
.choices-fig .choice { display: block; padding: 8px 6px; }
/* Nothing inside a choice is pressable on its own. */
.choice * { pointer-events: none; }
.choice:active { background: var(--sunken); }
.choice:focus-visible { outline: 3px solid #bcd6f2; outline-offset: 2px; }
.choice[disabled] { cursor: default; opacity: .55; }
/* Answered state. Colour alone is not the signal: the chosen choice is also
   labelled, and the key is outlined, so this reads on a mono or colour-blind
   screen too. */
.choice.picked        { opacity: 1; border-width: 3px; }
.choice.picked.right  { background: var(--right-bg); border-color: var(--right);
                        color: var(--right); }
.choice.picked.wrong  { background: var(--wrong-bg); border-color: var(--wrong);
                        color: var(--wrong); }
.choice.iskey         { opacity: 1; border-color: var(--right); color: var(--right); }
.choice .tag { display: block; font-size: 11px; font-weight: 600;
               letter-spacing: .04em; text-transform: uppercase; }
/* In a row layout the chip goes at the end of the row, not under the letter. */
.choices-html .choice .tag { flex: 0 0 auto; align-self: center;
                             margin-left: auto; padding-left: 8px; }

/* ---- feedback -------------------------------------------------------- */

.feedback { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 14px; }
.verdict { font-size: 19px; font-weight: 700; margin: 0 0 12px; }
.verdict.right { color: var(--right); }
.verdict.wrong { color: var(--wrong); }

.note { background: var(--wrong-bg); border-left: 4px solid var(--wrong);
        border-radius: 0 8px 8px 0; padding: 10px 12px; margin-bottom: 14px; }
.note p { margin: 0; font-size: 15.5px; }

.solution { margin-bottom: 16px; }

/* ---- summary --------------------------------------------------------- */

.score { font-size: 19px; font-weight: 700; margin: 0 0 14px; }
.reviewlist { list-style: none; margin: 0 0 18px; padding: 0; }
.reviewlist li { border-top: 1px solid var(--line); padding: 9px 0; font-size: 15px; }
.reviewlist .mark { font-weight: 700; margin-right: 8px; }
.reviewlist .mark.right { color: var(--right); }
.reviewlist .mark.wrong { color: var(--wrong); }
.reviewlist .why { display: block; color: var(--ink-soft); font-size: 14px;
                   margin-top: 2px; }

/* ---- flagging a question --------------------------------------------- */

/* Deliberately quiet. It must be findable, not inviting: a link that looks
   like the main action gets pressed by students who have nothing to report. */
.flagrow { margin: 14px 0 0; display: flex; flex-wrap: wrap; gap: 4px 18px; }
.linkbtn {
  appearance: none; background: none; border: 0; padding: 6px 0;
  font: inherit; font-size: 14px; color: var(--ink-soft);
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer; text-align: left; min-height: 32px;
}
.linkbtn:hover, .linkbtn:focus-visible { color: var(--brand); }
.linkbtn:focus-visible { outline: 3px solid #bcd6f2; outline-offset: 2px; }
.linkbtn[disabled] { text-decoration: none; cursor: default; opacity: .6; }

.flagbox {
  margin: 12px 0 0; padding: 14px 12px;
  background: var(--sunken); border: 1px solid var(--line); border-radius: 8px;
}
.flagbox h2 { margin-bottom: 8px; color: var(--ink); text-transform: none;
              font-size: 16px; letter-spacing: 0; }
.flagbox .field { margin-bottom: 8px; }
.flagbox textarea {
  width: 100%; min-height: 96px; padding: 10px 12px;
  font: inherit; font-size: 17px;  /* 16px+ or iOS zooms the page in */
  color: var(--ink); background: #fff;
  border: 1.5px solid var(--line); border-radius: 8px; resize: vertical;
}
.flagbox textarea:focus { outline: 3px solid #bcd6f2; border-color: var(--brand); }
.flagmeta { margin: 0 0 10px; font-size: 13px; color: var(--ink-soft); }

.flagsent {
  margin: 12px 0 0; padding: 9px 12px;
  background: var(--right-bg); border-left: 4px solid var(--right);
  border-radius: 0 8px 8px 0;
  font-size: 15px; color: var(--right); font-weight: 600;
}

/* ---- the little "still saving" note ---------------------------------- */

.saving {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: max(10px, env(safe-area-inset-bottom));
  margin: 0; padding: 7px 14px;
  background: #23262b; color: #fff; font-size: 13px;
  border-radius: 999px; z-index: 20; max-width: calc(100vw - 28px);
}

/* ======================================================================
   REMOVED 2026-09-19: the site's hand-ported copy of the bank's math rules.

   .math, .frac, .lim, .bp, .sq1 and the figure/table rules used to be written
   out here by hand, with values chosen by eye, because the student page had no
   bank markup in it except the worked solutions. It has all of it now, so the
   page loads assets/bank-item.css -- the bank's OWN rules, generated from its
   web render target, whose values audit_phone.py measures at 360px in headless
   Chrome -- and there is one copy rather than two.

   Everything below is what is left: the site's deliberate DEPARTURES from
   those rules. That is what this section has always been for; it is simply no
   longer sitting underneath a second set of the same rules.
   ====================================================================== */

/* ======================================================================
   BANK HTML  (.bankhtml) -- the site's DEPARTURES from the bank's own rules.

   The item rules themselves are no longer written here. They are generated
   into assets/bank-item.css from the bank's web render target, whose values
   audit_phone.py measures at 360px in headless Chrome. That file is loaded
   FIRST; everything below overrides it, and each override says why it exists.
   If a rule here has no reason beside it, it should not be here.
   ====================================================================== */

/* The bank sets these on `body`, which is page-level and deliberately not
   imported -- the site lays out its own page. They have to land somewhere, and
   the scope root is the honest place. */
.bankhtml { font-size: 17px; line-height: 1.55; }

/* The bank draws figure and radical text in Noto Serif. The site loads no web
   fonts at all (no CDNs), so a serif stack stands in. This is the one place the
   site cannot match the bank and knows it. */
.bankhtml svg text.tick,
.bankhtml svg text.orig,
.bankhtml svg text.axl,
.bankhtml svg text.ptlab,
.bankhtml .sq1 text { font-family: Georgia, "Times New Roman", serif; }

/* The bank rules a fraction in #000, which is right on paper. On screen a
   fraction can sit inside coloured text -- a rejected item's state line, a
   misconception note -- and a black rule through red text reads as a mistake. */
.bankhtml .frac .num { border-bottom-color: currentColor; }

/* Subscripts and superscripts: the bank styles neither. Its `.sub` is a CLASS
   (its page subtitle), not the <sub> ELEMENT, so there is nothing upstream to
   inherit and these numbers are the site's own -- tuned on a phone by Randy,
   for the 55 items that use subscripted log bases and sequence terms.
   0.66em is about 11px here, which is where a two-character base like log_(-2)
   stops being legible; `vertical-align` in em resolves against the element's
   OWN size, so -0.42em is 0.28 of the parent em, about half again the browser
   default, which is what makes the drop visible. */
.bankhtml sub { font-size: 0.66em; vertical-align: -0.42em; line-height: 0; }
.bankhtml sup { font-size: 0.74em; }

/* A stacked fraction inside a superscript -- (3)^(t/4), the only one in the
   bank. What read as "too big" was the stack HEIGHT, not the digits, so both
   levers are pulled. ~0.59 of the page em is about 10px, and that is the floor:
   below it the fraction rule and the digit strokes stop separating. */
.bankhtml sup .frac { font-size: 0.80em; vertical-align: -0.30em;
                      line-height: 1; margin: 0 0.05em; }
.bankhtml sup .frac .num,
.bankhtml sup .frac .den { padding: 0 0.14em; }
.bankhtml sup .frac .num { border-bottom-width: 1px; }

/* The bank sets .minicell to 46% because its own page puts the four
   graph-valued choices in one flow. The review page and the student page both
   put each choice in its own grid cell and do the columns themselves, so the
   cell should fill what it is given. */
.bankhtml .minicell { display: block; width: 100%; margin: 0; }

/* AND THE DRAWING INSIDE IT HAS TO SCALE WITH THE CELL.
   The bank's own rule for this is `.figwrap svg { max-width: 100% }`, and a
   graph-valued choice is not in a .figwrap -- it is in a .minicell -- so that
   rule does not reach it. Without this, the four mini-graphs of unit1:1.1.B.1
   render at their intrinsic 150px inside a ~145px cell and push the whole page
   sideways: measured at 369px against a 360px phone before this rule, 360px
   after. It is the one item in the bank with figure-valued choices, and it is
   the reason the review page never showed this -- its panes are wider. */
.bankhtml .minicell svg { max-width: 100%; height: auto; }

/* ---- wider screens --------------------------------------------------- */

@media (min-width: 560px) {
  #main { padding: 22px 18px 48px; }
  .screen { padding: 22px 22px 26px; }
  h1 { font-size: 24px; }
  /* Four across, for the four letter buttons under a fallback item's picture.
     An HTML choice stays one per row at every width: the constraint is the
     length of a piecewise definition, not the width of the screen. */
  .choices { grid-template-columns: repeat(4, 1fr); }
  .choices.choices-html { grid-template-columns: 1fr; }
  .btn { width: auto; min-width: 190px; }
  .row { flex-direction: row; gap: 12px; }
  .btn-quiet { margin-top: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .qprogress-fill { transition: none; }
}

/* The session countdown. Tabular figures so the width does not jitter every
   second, and a colour change in the last minute rather than an alarm. */
.qclock { font-size: 14px; font-variant-numeric: tabular-nums; white-space: nowrap;
          color: var(--ink-soft); font-weight: 600; }
.qclock.low { color: var(--wrong); }
