/* ---------------------------------------------------------------------------
   Answers, and printout-only content
   ---------------------------------------------------------------------------
   Three views, two of them from the same build:

     slides     ./deck N
     website    ./web            includes answers, behind "Show answer"
     printout   ./handout N      the website, printed, with answers removed

   Wrap an answer in a div and it shows on the website and in the slide deck,
   but vanishes when the page is printed. That protects cold calls: the handout
   in front of students during class does not contain the answer, while the
   website stays a complete reference for revision.

       <div class="answer">

       **Answer.** Markdown works in here, but you need the blank lines.

       </div>

   Use `.handout-only` for the reverse: content that appears only on paper,
   such as ruled space for notes. Hidden on screen, shown when printed.

   Use `.web-only` for the third case: on the website, but off the paper. The
   build flags cannot do this. `is_website` only means "not the slides", and
   the handout IS the website build, so an `{% if is_website %}` appendix
   prints in full. Wrap it in a `.web-only` div as well and it stays on the
   site while the handout ends where the class does. Lecture 12's five FYI
   appendices are the case this was written for.

   Headings inside a `.web-only` div are fine, unlike `.answer`, because the
   content is inside `{% if is_website %}` and the slide generator never sees
   it. If you ever use `.web-only` outside such a block, the `.answer` warning
   below applies: keep the `##` outside the div.

   THE COLD-CALL QUESTION PATTERN
   ------------------------------
   A question you ask in the room needs three different things in three views:
   two slides on the deck (ask, then reveal), the answer alone on the website,
   and the question plus space to write on the handout. Naively wrapping the
   whole section in `.answer` deletes the heading from the handout too, leaving
   students a blank where the question should be.

   This is the shape that works. Two `##` headings, one question, one `.answer`:

       {% if is_slides %}
       ## What is a compiler?

       Think, then turn to your neighbor: **what does a compiler do?**

       {% endif %}

       ## What is a compiler?

       Think, then turn to your neighbor: **what does a compiler do?**

       <div class="write-in"><hr><hr><hr><hr></div>

       <div class="answer">

       A compiler translates your whole program ahead of time...

       </div>

   Deck:     slide 1 is the question, slide 2 keeps the question on screen and
             adds the answer under it. The write-in is invisible on screen.
   Website:  the second heading only, so question then answer, one heading.
   Handout:  heading, question, ruled lines. The answer is gone.

   The heading and the question repeat because that is the ordinary progressive
   build, not because anything is duplicated between two flags. Keep the `##`
   OUT of the `.answer` div: the slide generator splits on `##` before any CSS
   applies, so a heading inside a hidden div still produces a slide, and it
   produces an empty one.
   --------------------------------------------------------------------------- */

.answer {
    border-left: 3px solid var(--links);
    padding: 0.1rem 0 0.1rem 0.9rem;
    margin: 1rem 0;
    opacity: 0.92;
}

/* The "Show answer" wrapper, added on the website by src/answer-toggle.js */
.answer-toggle {
    margin: 0.6rem 0 1rem;
}

.answer-toggle > summary {
    cursor: pointer;
    color: var(--links);
    font-size: 0.9em;
    width: fit-content;
}

.answer-toggle > .answer {
    margin-top: 0.4rem;
}

/* ---------------------------------------------------------------------------
   Page outline (the syllabus contents block)
   ---------------------------------------------------------------------------
   Two columns to keep it to about half a page, and it prints, unlike the
   sidebar. Collapses to one column on narrow screens.
   --------------------------------------------------------------------------- */

.toc {
    column-count: 2;
    column-gap: 2.5rem;
    font-size: 0.9em;
    line-height: 1.35;
    border: 1px solid var(--sidebar-bg);
    border-radius: 4px;
    padding: 1rem 1.2rem 0.4rem;
    margin: 1.5rem 0 2rem;
}

.toc p,
.toc ul {
    margin: 0 0 0.35rem;
}

/* Let the two columns balance by length.
   These used to carry break-inside: avoid, to keep a group heading with the
   list under it. The cost was worse than the problem: "How the course works"
   has a long list, the whole thing refused to split, so it jumped to column
   two and left column one ending on a bare heading with half a column of
   white space under it. Balanced columns that occasionally split a group read
   better than one short column and one long one.

   break-after on the heading is a best-effort ask not to strand it alone at
   the foot of a column. Multi-column support for it is patchy, so nothing
   depends on it. List items still never split across the gap. */

.toc p {
    break-after: avoid;
}

.toc p {
    margin-top: 0.5rem;
}

.toc ul {
    padding-left: 1.1rem;
    list-style: none;
}

.toc ul ul {
    padding-left: 0.9rem;
    opacity: 0.75;
}

.toc li {
    margin: 0.1rem 0;
    break-inside: avoid;
}

/* markdown renders these as loose lists; strip the paragraph margins */
.toc li p {
    margin: 0;
}

@media (max-width: 700px) {
    .toc { column-count: 1; }
}

@media print {
    .toc {
        font-size: 0.82em;
        border: 1px solid #999;
        break-inside: avoid;
    }
    /* links are noise on paper, but keep the structure readable */
    .toc a { color: inherit; text-decoration: none; }
}

/* ---------------------------------------------------------------------------
   Top-level part headings
   ---------------------------------------------------------------------------
   The syllabus is in three parts (Overview, How the course works, Policies).
   A rule above each one makes them read as real dividers rather than as
   slightly larger section headings, and matches the three groups in the
   outline block at the top of the page.

   The page title is also an h1, so `main > h1:first-of-type` is excluded.
   --------------------------------------------------------------------------- */

main h1 {
    border-top: 2px solid var(--links);
    padding-top: 1.4rem;
    margin-top: 3rem;
}

main h1:first-of-type {
    border-top: none;
    padding-top: 0;
    margin-top: 0;
}

/* ---------------------------------------------------------------------------
   Print: keep blocks whole
   ---------------------------------------------------------------------------
   Tables split across a page break are hard to read on paper, since the
   header row does not repeat. Same for the callout notes.
   --------------------------------------------------------------------------- */

@media print {
    table,
    blockquote {
        break-inside: avoid;
        page-break-inside: avoid;   /* older print engines */
    }

    /* do not strand a heading at the foot of a page */
    h1, h2, h3 {
        break-after: avoid;
        page-break-after: avoid;
    }

    /* The announcements block ends in ruled lines. A part divider's rule
       immediately under them reads as a fourth line to write on, so a heading
       that follows the block loses its rule and the writing space gains room.
       Only in print: on the website the block is hidden and the divider is
       wanted. Later h1s on the page keep theirs. */
    .handout-only {
        margin-bottom: 0.45in;
    }

    .handout-only + h1 {
        border-top: none;
        padding-top: 0;
        margin-top: 0;
    }

    /* To start each of the three parts on a fresh page, uncomment this. It
       costs a little paper and makes the printout easier to navigate.
       main h1            { break-before: page; page-break-before: always; }
       main h1:first-of-type { break-before: auto; page-break-before: auto; } */
}

.answer > :first-child { margin-top: 0; }
.answer > :last-child { margin-bottom: 0; }

.handout-only {
    display: none;
}

@media print {
    /* Never print an answer. This is the whole point. */
    .answer,
    .answer-toggle {
        display: none !important;
    }

    .handout-only {
        display: block;
    }

    /* Website, but not worth the paper. See the note at the top of this file. */
    .web-only {
        display: none !important;
    }

    /* Space to write in, when .handout-only wraps nothing else */
    .handout-only.note-space {
        min-height: 6rem;
    }

    /* A table on the handout is usually one students fill in: a guess, a
       measured value, a note. Web-height rows leave nowhere to write, so give
       every cell a line's worth of space. */
    .handout-only td {
        height: 0.4in;
        vertical-align: top;
    }
}

/* ---------------------------------------------------------------------------
   Slide number
   ---------------------------------------------------------------------------
   make-slides.py appends a <div class="slide-progress"> to every generated
   slide. Without these rules it renders as ordinary body text at the bottom of
   the content, which is what it used to do.

   Pinned to the bottom right of the window and dimmed so it reads as chrome
   rather than content. Only slides contain this element, so these rules do
   nothing on the website.

   To hide slide numbers entirely, change the display line below to
   `display: none;`. */

.slide-progress {
    position: fixed;
    right: 1.6rem;
    bottom: 1rem;
    z-index: 100;

    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    line-height: 1;

    color: var(--fg);
    opacity: 0.28;

    pointer-events: none;
    user-select: none;
}

/* Nudge clear of mdBook's mobile navigation arrows on narrow screens */
@media (max-width: 1080px) {
    .slide-progress {
        right: 0.75rem;
        bottom: 0.6rem;
        font-size: 0.85rem;
    }
}

/* Never print the counter */
@media print {
    .slide-progress {
        display: none;
    }
}

/* Custom CSS for wider tables */

/* Make tables wider and allow horizontal scrolling on mobile */
table {
    width: 100% !important;
    max-width: none !important;
    table-layout: auto !important;
    font-size: 0.9em;
}

/* Cells wrap by default.
   This used to be `white-space: nowrap` on every cell, with wrapping opted back
   in for columns 4 and 5, which were the schedule's Topic and Reading columns.
   Any table with a different shape, such as the syllabus link table, got a
   horizontal scrollbar instead. `overflow: hidden` with an ellipsis was worse
   than the scrollbar, because a cut-off cell looks finished.

   overflow-wrap is what does the real work: a long URL has no space in it, so
   nothing else will break it. */
table th, table td {
    padding: 8px 12px !important;
    overflow-wrap: break-word;
    vertical-align: top;
}

/* The one column that should not wrap. It is a date or a label in every table
   here, and breaking "Mon Sep 21" across two lines helps nobody. */
table th:first-child, table td:first-child {
    white-space: nowrap;
}

/* Make the overall content area wider for tables */
.content {
    max-width: 1200px !important;
}

/* Horizontal scroll for very wide tables on mobile */
.table-wrapper {
    overflow-x: auto;
    margin: 1em 0;
}

/* Better responsive behavior */
@media (max-width: 768px) {
    table {
        font-size: 0.8em;
    }

    table th, table td {
        padding: 6px 8px !important;
    }

    /* On a phone there is no room to keep anything on one line. */
    table th:first-child, table td:first-child {
        white-space: normal;
    }
}
/* ---------------------------------------------------------------------------
   Sidebar chapter numbers
   ---------------------------------------------------------------------------
   mdBook auto-numbers every entry in SUMMARY.md, so the sidebar counts
   1, 2, 3... straight through. Those numbers do not match the lecture numbers
   (there is no lecture 16 or 28, they are exam days) and they carry on
   counting into Projects, Discussions, and Activities, where they mean
   nothing at all. Hide them and let the entry titles speak.

   Targets only the generated numbering, which mdBook marks aria-hidden,
   so nothing an assistive reader relies on is affected.
   --------------------------------------------------------------------------- */

.chapter-item strong[aria-hidden="true"] {
    display: none;
}

/* ---------------------------------------------------------------------------
   Cut-and-sort activities
   ---------------------------------------------------------------------------
   Activity 3 is the first of these. Printed, it is three sheets: the full
   instructions, a page of strips to cut apart, and a sorting sheet. Only the
   last two get copied for students.

       <div class="page-break"></div>   start a fresh sheet of paper
       <div class="cut-strips">         a bordered box per list item
       <div class="worksheet">          two labelled areas to sort into

   If the strips spill onto a second page, lower --strip-pad in the print
   block below. That is the one number worth touching.
   --------------------------------------------------------------------------- */

.page-break {
    break-before: page;
    page-break-before: always;
}

.cut-strips {
    --strip-pad: 0.34rem;
    margin: 1.25rem 0;
}

.cut-strips ul {
    list-style: none;
    padding-left: 0;
    margin: 0;
}

.cut-strips li {
    border: 1px dashed #888;
    border-radius: 3px;
    padding: var(--strip-pad) 0.6rem;
    margin: 0.28rem 0;
    /* never let a strip be split across a page break */
    break-inside: avoid;
    page-break-inside: avoid;
}

/* the strips are code, but mdBook's code background fights the strip border */
.cut-strips li code {
    background: none;
    padding: 0;
}

.worksheet {
    display: flex;
    gap: 0.35in;
    margin-top: 0.2in;
}

.worksheet-col {
    flex: 1;
    min-width: 0;
}

.worksheet-col > strong {
    display: block;
    margin-bottom: 0.1in;
}

.worksheet-box {
    border: 1px solid #888;
    border-radius: 4px;
    min-height: 4in;
}

@media print {
    /* Activity 3 has 23 strips. At these values each one is about 0.37in, so
       the set comes to roughly 8.6in and lands on a single sheet. Screen
       padding would put it near 15in, which is three pages of strips.
       Raise --strip-pad for fewer, chunkier strips; lower it for more. */
    .cut-strips {
        --strip-pad: 0.07in;
        font-size: 10pt;
        line-height: 1.25;
    }

    .cut-strips li {
        margin: 0.02in 0;
        border-color: #444;
    }

    .worksheet-box {
        min-height: 6.4in;
        border-color: #444;
    }
}

/* ---------------------------------------------------------------------------
   Write-in space on the printout
   ---------------------------------------------------------------------------
   Announcements change the morning of, but handouts print days ahead. Rather
   than reprinting, leave ruled space and let students write the announcements
   in themselves. Copying them down beats reading them, so this is worth more
   than the reprint it saves.

       <div class="handout-only">

       **Announcements**

       <div class="write-in"><hr><hr><hr></div>

       </div>

   Nothing on screen or on the slides. Ruled lines when printed. One `<hr>` per
   line, so the number of lines is visible in the markup. Keep them on one line:
   a blank line inside the div ends the raw HTML block.
   --------------------------------------------------------------------------- */

.write-in {
    display: none;
}

@media print {
    .write-in {
        display: block;
        margin: 0.12in 0 0.2in;
    }

    /* One <hr> per line, and the rules are borders rather than a background
       gradient. Browsers print with "Background graphics" OFF by default, so
       the gradient version came out blank or partial on a Cmd-P handout;
       print-color-adjust: exact did not rescue it, tried 2026-09-13. Borders
       print either way. Headless Chrome prints backgrounds regardless, so a
       render that looks right is not evidence the paper will be: check a real
       print preview.

       The margin sits above each rule, so the gap is the space you write in
       and the rule is the line you write on. */
    .write-in hr {
        border: 0;
        border-top: 1px solid #999;
        height: 0;
        margin: 0.32in 0 0;
        break-inside: avoid;
        page-break-inside: avoid;
    }
}

/* ---------------------------------------------------------------------------
   Teaching staff grid
   ---------------------------------------------------------------------------
   Replaces the PowerPoint composite that fa25 used. Photos come in at
   different aspect ratios (some square, some 3:4), so every one is forced
   into the same portrait box with object-fit: cover. Nothing needs recropping;
   swapping a photo means dropping a new file in and changing the src.

   object-position sits high so a cover-crop takes it off the chin, not the
   forehead. Raise the percentage for a photo framed unusually tight.

   Groups wrap as units, so a narrow window never splits a section across
   two rows.
   --------------------------------------------------------------------------- */

.staff {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-start;
    gap: 1.4rem 2rem;
    margin: 1.5rem 0;
}

.staff-group-title {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    opacity: 0.6;
    text-align: center;
    margin-bottom: 0.5rem;
}

.staff-people {
    display: flex;
    gap: 0.7rem;
    justify-content: center;
}

.staff figure {
    margin: 0;
    width: clamp(5rem, 10vw, 9rem);
}

.staff img {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    object-position: center 22%;
    border-radius: 6px;
}

.staff figcaption {
    text-align: center;
    font-size: 0.82rem;
    line-height: 1.25;
    margin-top: 0.3rem;
}

.staff figcaption span {
    display: block;
    font-size: 0.72rem;
    opacity: 0.6;
}

@media print {
    .staff { gap: 0.5rem 1rem; }
    .staff figure { width: 1.05in; }
    .staff figcaption { font-size: 8pt; }
    .staff-group-title { font-size: 7pt; }
    .staff > div { break-inside: avoid; }
}

/* ---------------------------------------------------------------------------
   Lecture cover images
   ---------------------------------------------------------------------------
   One image under the lecture's H1, sized differently in each of the three
   views. No build flag: the image lives in the body and renders everywhere,
   and only its size changes.

       # Lecture 4 - Hello git: save points for your code

       <img class="lecture-cover" src="../images/cover_04_git.png" alt="...">

   Slides:   large, so the title slide is not a mostly-empty page.
             That rule is in slides.css, not here.
   Website:  a header image, capped so it does not dominate the page.
   Handout:  a thumbnail. Students carry a stack of stapled packets, and a
             distinct picture on page 1 is how you find lecture 12 without
             reading titles. Small enough that it costs almost no paper.

   Two rules for the images themselves:

   1. **No text baked into the picture.** The H1 sits right above it, so text
      in the image duplicates it, does not scale, and is invisible to a screen
      reader. Use the `alt` attribute to say what it shows.
   2. **Same aspect ratio every time**, 16:9. If it varies, the title slide
      jumps around from lecture to lecture and the effect is lost.
   --------------------------------------------------------------------------- */

.lecture-cover {
    display: block;
    width: 100%;
    /* !important because mdBook's general.css has `.content img { max-width: 100% }`,
       which is more specific than a bare class and would otherwise win. */
    max-width: 34rem !important;
    height: auto;
    margin: 1rem 0 1.5rem;
    border-radius: 6px;
}

@media print {
    .lecture-cover {
        max-width: 2.6in !important;   /* about 1.5in tall at 16:9 */
        margin: 0.15in 0 0.25in;
    }
}


/* ---------------------------------------------------------------------------
   Images that shrink on paper
   ---------------------------------------------------------------------------
   For pictures that earn their space on the slide and on the website but would
   eat a third of a printed page. Screenshots, jokes, and anything whose job is
   recognition rather than reading. Full size on screen, thumbnail on paper, so
   the packet keeps the visual cue without the page count.

   This is the alternative to hiding something from the handout. Nothing
   disappears, so the printout stays "the website page on paper" and there is
   no third view to keep track of.

   Do NOT use it on a diagram students need to read on paper. Those stay full
   width: file system trees, memory layouts, permission tables.

   Markdown carries no class, so write these as HTML:
     <img class="print-small" src="../images/zork.jpg" alt="Zork (1977)">
   --------------------------------------------------------------------------- */

.print-small {
    display: block;
    max-width: 100%;
    height: auto;
}

@media print {
    .print-small {
        /* !important: mdBook's `.content img { max-width: 100% }` is more
           specific than a bare class and wins without it. */
        max-width: 2.2in !important;
        margin: 0.1in 0 0.2in;
    }
}


/* ---------------------------------------------------------------------------
   Images at a third of the column
   ---------------------------------------------------------------------------
   For a small screenshot whose job is "here is the button I mean". A UI
   element photographed at full column width reads as the subject of the page
   rather than a pointer to something on someone else's screen.

   Unlike `.print-small`, this one is small in every view, on screen and on
   paper, because the picture was never worth the space to begin with.

   Markdown carries no class, so write these as HTML:
     <img class="third-width" src="../images/fork_button.png" alt="...">

   Below 700px the column is narrow enough that a third of it is unreadable,
   so the image goes back to full width.
   --------------------------------------------------------------------------- */

.third-width {
    display: block;
    /* !important because mdBook's general.css has `.content img { max-width: 100% }`,
       which is more specific than a bare class and would otherwise win. */
    max-width: 33% !important;
    height: auto;
    margin: 0.75rem 0 1rem;
}

@media (max-width: 700px) {
    .third-width {
        max-width: 100% !important;
    }
}


/* ---------------------------------------------------------------------------
   QR codes
   ---------------------------------------------------------------------------
   For a link students need to open on a phone mid-class, where typing a URL
   off the screen wastes two minutes and produces three typos.

   Sized differently in each of the three views, like .lecture-cover, and for
   the same reason: the image lives in the body with no build flag, so it is
   one line in the lecture file and only its size changes.

   Slides:   large. The slide sits on the projector for the whole activity and
             the back row has to scan it. That rule is in slides.css.
   Website:  modest. The link next to it is clickable here, so the code is a
             convenience rather than the point.
   Handout:  small, but never below about 1.2in or a phone stops finding it on
             paper at arm's length.

   Always put the URL next to the code as text too. A QR is unreadable to
   anyone whose camera is not working, and it tells a screen reader nothing.

   Markdown carries no class, so write these as HTML:
     <img class="qr-code" src="../images/L10_QR.svg" alt="QR code for the form">
   --------------------------------------------------------------------------- */

.qr-code {
    display: block;
    /* !important because mdBook's general.css has `.content img { max-width: 100% }`,
       which is more specific than a bare class and would otherwise win. */
    max-width: 13rem !important;
    height: auto;
    margin: 1rem 0;
}

@media print {
    .qr-code {
        max-width: 1.6in !important;
        margin: 0.15in 0;
    }
}
