/*
 * student-materials.css - the materials page and the surfaces it introduced.
 *
 * Owns: the top courses bar (the enrolled-course switcher that replaced the
 * pill strip), the materials page layout now that the left rail is gone, the
 * meeting page's tab bar, and the global Mac/Windows platform switch that sits
 * beside a page title.
 *
 * Linked immediately AFTER student.css and student-shell.css. The deck, the
 * reference sheets and session 1's own material each keep their own sheet and
 * are linked after this one, so they can still sit on top of it.
 */

/* ── The Mac / Windows switch ────────────────────────────────────────────────
 *
 * THE SWITCH IS A PAGE-LEVEL CONTROL NOW. It used to be three private copies,
 * one inside each panel that cared, each with its own `os` ref; it is one
 * component (StudentOsSwitch.vue) reading one account-wide value, and its home
 * is the page head beside the title rather than the top of a panel.
 *
 * Its shape still comes from `.stu-prep-os` in student.css - same pill track,
 * same active chip - because it must not read as a NEW control now that it
 * governs the whole page. That sheet is read-only for this work, so everything
 * the new placement needs is added here, on top of it, and only ever as an
 * addition: nothing below re-declares a property the base rule already sets in
 * a way the in-body instance still depends on.
 *
 * The base rule styles the buttons but leaves them without a focus ring, which
 * was survivable while they were two plain buttons in the middle of a panel
 * and is not now that the group is a radiogroup with a roving tabindex: with
 * one tab stop, an invisible focus is a control a keyboard reader cannot find
 * at all. Same ring as the rail's, for the same reason it is :focus-visible
 * and not :focus - a mouse press must not leave one behind.
 */
.stu-prep-os__btn:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

/* The page-head instance. Beside a title the switch is an aside, not the
   headline, so it loses the in-body size without losing the shape: a title at
   28px next to a 36px control reads as two headings arguing. */
.stu-prep-os--compact {
    padding: 2px;
}

.stu-prep-os--compact .stu-prep-os__btn {
    min-height: 30px;
    padding: 0 14px;
    gap: 6px;
    font-size: 13px;
}

.stu-prep-os--compact .stu-prep-os__btn i {
    font-size: 12px;
}

/* Phones give the page head one column, and a 44px touch target matters more
   there than the two pixels saved by the compact size. */
@media (max-width: 767px) {
    .stu-prep-os--compact .stu-prep-os__btn {
        min-height: 36px;
        padding: 0 18px;
    }
}

/* ── The page head that carries the switch ───────────────────────────────────
 *
 * The title on the reading start and the Mac/Windows control on the physical
 * LEFT, which under `direction: rtl` is the inline END. `.stu-page-head` itself
 * is only a bottom margin (student.css), so this modifier adds the row and
 * nothing else: a page head with no switch keeps the shipped block layout and
 * is not dragged through a flex container it has no use for.
 *
 * `align-items: center` and not `flex-end`: the title column is a title with a
 * sub-line under it, so aligning the boxes' bottoms drops the switch onto the
 * SUB-LINE and leaves the title with nothing beside it. Centred against the
 * whole column it reads as an aside to the heading, which is what it is, and it
 * behaves the same on the pages that carry no sub-line at all.
 */
.stu-page-head--os {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    flex-wrap: wrap;
}

/* The title column has to be allowed to shrink, or a long sub-line pushes the
   switch off the row before the wrap can help it. */
.stu-page-head--os .stu-page-head__main {
    flex: 1 1 320px;
    min-inline-size: 0;
}

/* ── The top courses bar ─────────────────────────────────────────────────────
 *
 * ONE BAR, not a row of pills - the owner's call. A single continuous glass
 * surface, one rule bounding it below, hairline dividers between the tabs, and
 * an indicator that rides the bar's own rule so the line reads as thickening
 * and colouring rather than as a second mark floating over it.
 *
 * WHAT A TAB IS: a course the student is enrolled in, named by its own product
 * mark through StudentCourseTitle. There is no `כללי` tab - `הכנה לקורס` and
 * `חומרי עזר` moved into the side menu - and never an intake or cohort number,
 * on the face or in the accessible name.
 *
 * ABOUT THE `var(..., fallback)` PAIRS BELOW. Every `--stu-*` token in this
 * area is declared once, on `.stu-shell`, in student-shell.css (see the token
 * block there and DESIGN-SPEC section 2.2). This sheet does not redeclare one.
 * The fallbacks are the same values written inline so that the bar is still a
 * bar if that sheet is missing from a build, and so this file can be read and
 * verified on its own; when the token block is present every fallback is inert.
 */
.stu-coursebar {
    display: flex;
    align-items: stretch;
    gap: 0;
    margin-block-end: var(--space-lg);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    background:
        radial-gradient(ellipse at 15% 10%, rgba(8, 148, 255, 0.08), transparent 65%),
        linear-gradient(180deg,
            var(--stu-glass-top, rgba(255, 255, 255, 0.88)),
            var(--stu-glass-bottom, rgba(239, 246, 255, 0.62)));
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border-block-end: 1px solid var(--border-default);
    box-shadow: var(--stu-lift-2, 0 10px 32px rgba(0, 60, 130, 0.10));

    /* THE BAR SCROLLS AT EVERY WIDTH. This was a phone-only treatment until
       2026-09-04, when a reader holding SIX courses opened it on a desktop and
       found the six wordmarks painted on top of each other in an unreadable
       pile. The tabs were dividing the bar evenly and squeezing to 155px each
       while a mark with its disambiguation suffix - `10x Developer & Architect
       (אפריל 2027)` - needs a little over 200px and is `white-space: nowrap`
       with nothing clipping it, so every mark simply drew over its neighbours.

       A desktop is not immune to this: it is wider, but the number of courses
       is not bounded by the viewport. Two intakes of each of the three courses
       is six, and staff read every cohort in the database. So the rule that
       held on a phone holds everywhere - a wordmark is never squeezed, and the
       bar overflows into a scroll instead. */
    overflow-x: auto;
    scroll-snap-type: inline mandatory;
    /* No edge mask, ever: a mask cuts through a wordmark, and a brand mark
       rendered half-faded is a mangled mark. The snap is what guarantees a tab
       is never left half-shown after a flick. */
    scrollbar-width: none;
}

.stu-coursebar::-webkit-scrollbar {
    display: none;
}

/* A MOUSE NEEDS TO BE TOLD. A touch reader discovers a scroller by dragging it;
   a mouse reader has to know it is there before shift-wheeling, and with six
   courses three of them are off-screen. The half-cut tab at the edge is the
   first signal and the snap keeps it half-cut rather than nearly whole, but on
   a fine pointer that is not enough on its own, so the scrollbar is drawn.

   It is 4px and sits UNDER the bar's own hairline rather than on it: the
   hairline is where the active indicator rides, and a scrollbar sharing that
   row would read as a second, longer indicator. Only on `hover: hover` and
   `pointer: fine`, so a touch device keeps the clean edge it already had. */
@media (hover: hover) and (pointer: fine) {
    /* NO `scrollbar-width` here, deliberately. Setting the standard property
       makes Chrome ignore the `::-webkit-scrollbar` rules below, and on macOS
       `thin` still resolves to an OVERLAY scrollbar - invisible at rest and
       painted only during a scroll gesture, which is exactly the "I did not
       know it scrolled" problem being fixed. The webkit pseudo-elements alone
       give a bar that is always drawn and always takes its 4px. */
    .stu-coursebar::-webkit-scrollbar {
        display: block;
        block-size: 4px;
    }

    .stu-coursebar::-webkit-scrollbar-thumb {
        background: rgba(0, 60, 130, 0.22);
        border-radius: 2px;
    }

    .stu-coursebar::-webkit-scrollbar-track {
        background: transparent;
    }
}

/* NO `overflow: hidden` at this width. There is nothing to clip, and hiding
   the overflow is what used to cut the focus ring off the first tab. */
.stu-coursetab {
    position: relative;
    /* `1 0 auto`: GROW on, SHRINK OFF. Shrink was the defect - `1 1 0` gave
       every tab an equal share of the bar and let it fall below the width of
       the mark inside it, which then overflowed and painted over the next tab.
       Grow has to stay ON because the student holding ONE course is the common
       case, and without it that single tab sits at its intrinsic width with the
       rest of the bar left as empty glass. Growing costs the crowded case
       nothing: past the line there is no free space to distribute. */
    flex: 1 0 auto;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: var(--space-md) var(--space-md) var(--stu-s-5, 20px);
    border: 0;
    background: transparent;
    font-family: var(--font-body);
    cursor: pointer;
    transition: background var(--stu-dur-2, 0.22s) ease;
}

/* THE DIVIDER, on the correct logical edge. Under RTL `inset-inline-start` is
   the physical RIGHT, which for every tab after the first is its boundary with
   the tab BEFORE it. `inset-inline-end` would put the line on the physical
   left, leaving the first boundary bare and a stray hairline flush against the
   bar's outer edge. */
.stu-coursetab + .stu-coursetab::before {
    content: '';
    position: absolute;
    inset-inline-start: 0;
    inset-block: 14px;
    inline-size: 1px;
    background: linear-gradient(180deg, transparent, rgba(98, 98, 234, 0.20), transparent);
}

.stu-coursetab:hover {
    background: rgba(255, 255, 255, 0.45);
}

.stu-coursetab[aria-selected="true"] {
    background: rgba(255, 255, 255, 0.66);
}

/* The bar is rounded at the block start and the tabs are not clipped to it -
   `overflow: hidden` here is what used to cut the focus ring off the first tab,
   and the ring is the one thing on this control a keyboard reader has. So the
   two end tabs carry the bar's own corner instead, on the logical edge, which
   is what stops a lit tab's fill from squaring off the bar's corner behind it. */
.stu-coursetab:first-child {
    border-start-start-radius: var(--radius-lg);
}

.stu-coursetab:last-child {
    border-start-end-radius: var(--radius-lg);
}

/* NO focus rule here, and that is deliberate rather than an omission.
   student-shell.css declares ONE ring for the whole area and this control wants
   the same one at every width where it can have it (DESIGN-SPEC 9.1).

   THE RING HAS TO SIT INSIDE THE SCROLL BOX, at every width since 2026-09-04.
   The bar is a scroll container now, and a scroll container clips at its
   padding edge in BOTH axes (a `visible` cross axis computes to `auto` beside
   an `auto` one). The shell's area-wide ring is `outline-offset: 2px` plus an
   outset `box-shadow`, so every side of it lands in the clipped region:
   focusing a tab painted a single 2px vertical stripe on its inline-start edge,
   in the same place and colour as the divider already there. A keyboard reader
   could not tell the tab was focused.

   `.stu-shell` in front is load-bearing, not decoration. The shell's rule is
   `.stu-shell :is(a, button, summary, input, select, textarea,
   [tabindex]):focus-visible`, and `:is()` takes the specificity of its WIDEST
   argument, so `[tabindex]` makes it (0,3,0) - one class more than a bare
   `.stu-coursetab:focus-visible` at (0,2,0), which is why the earlier attempt
   at this rule never applied at all. With `.stu-shell` in front it ties and
   wins on order, this sheet being the later one. If you add a focus
   declaration to this control, count the classes first.

   The shadow goes because it can only ever be clipped here, and the radius with
   it, so the ring traces the tab's own square corners instead of an 8px
   rounding that appears only while focused. */
.stu-shell .stu-coursetab:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: -3px;
    box-shadow: none;
    border-radius: 0;
}

/* THE INDICATOR. Solid --primary-color, 2px, riding the bar's own hairline at
   `inset-block-end: -1px` so the rule and the mark read as one line.
   `inset-inline: 18px` hugs the wordmark rather than the padding box.

   SOLID, NEVER THE BRAND GRADIENT. The three logo components are themselves
   gradient-filled SVGs, so a gradient indicator would be the fourth gradient in
   one 90px strip and would blow the page's gradient budget on the one mark that
   is not identity. */
.stu-coursetab::after {
    content: '';
    position: absolute;
    /* Flush at 0, not the -1px overhang the design spec asks for. A scroll
       container clips at its padding edge and the bar's bounding rule lives
       outside that edge on the border, so the overhang is clipped away. At 0 it
       sits on the last row inside the tab, directly over the rule, which reads
       the same at every DPR this ships to. */
    inset-block-end: 0;
    inset-inline: 18px;
    block-size: 2px;
    border-radius: 2px 2px 0 0;
    background: var(--primary-color);
    opacity: 0;
    transform: scaleX(0.4);
    transition: opacity var(--stu-dur-3, 0.28s) ease,
                transform var(--stu-dur-3, 0.28s) var(--stu-ease, cubic-bezier(0.2, 0.8, 0.2, 1));
}

.stu-coursetab[aria-selected="true"]::after {
    opacity: 1;
    transform: none;
}

/* The tab's name is a course label: the brand token painted as a mark, and
   whatever Hebrew the server wrapped around it (`קורס`, and the month-and-year
   mark `courseTitles()` adds to a colliding pair). Both must stay on one line -
   a wrap would break the mark away from its own word - and the whole name is
   one line-height box so the marks sit on a common baseline. */
.stu-coursetab__mark {
    display: block;
    white-space: nowrap;
    line-height: 1.5;
    font-size: 15px;
    color: var(--text-secondary);
    transition: color var(--stu-dur-2, 0.22s) ease;
}

.stu-coursetab[aria-selected="true"] .stu-coursetab__mark {
    color: var(--text-color);
}

/* THE MARK IS NEUTRALISED, NEVER DIMMED, and the filter is on the SVG rather
   than on the whole name. `opacity` on a gradient wordmark puts two of the
   three course names near 3.4:1 and reads as "not yours" - on courses the
   student has paid for. `grayscale(1)` resolves in sRGB, so #0894FF lands on
   #7E7E7E and the brightness step takes it to about #5A5A5A, which is this
   page's own --text-secondary to within a hair. It also removes two of the
   three brand gradients from the strip, so the active mark is the only colour
   in it.

   ON THE SVG AND NOT ON `.stu-coursetab__mark`: the whole justification for
   --stu-mark-quiet is that the three logo components are gradient-FILLED SVGs
   with no solid-ink variant. The Hebrew beside them is already solid ink, and
   putting a brightness step over it would leave the INACTIVE word darker than
   the active one - the state inverted on the one channel that is not the
   indicator.

   THE THREE MARKS ARE SIZED 22 / 21 / 25 AND NOT ALL AT 22. Each mark's
   letterforms occupy a different fraction of its own viewBox, which is why
   logo-10x.css states 1.1em, logo-10x-architect.css 1.05em and
   logo-10x-course.css 1.25em and why the first two carry a comment saying not
   to bump one without the other. Setting one box height for all three is what
   that comment warns against: at a flat 22px the Architect wordmark renders
   visibly larger than the Developer one standing next to it. These are the same
   three ratios resolved against a 20px step, so the Developer mark lands on the
   22px the design asks for and the family keeps its relationship.

   Each selector is a class plus a descendant class plus a type, so it outranks
   the logo sheets outright rather than relying on link order. */
.stu-coursetab__mark svg {
    inline-size: auto;
    max-inline-size: 100%;
    filter: var(--stu-mark-quiet, grayscale(1) brightness(0.72));
    transition: filter var(--stu-dur-2, 0.22s) ease;
}

.stu-coursetab__mark .logo-10x-inline svg {
    block-size: 22px;
}

.stu-coursetab__mark .logo-10x-architect-inline svg {
    block-size: 21px;
}

.stu-coursetab__mark .logo-10x-course-inline svg {
    block-size: 25px;
}

.stu-coursetab:hover .stu-coursetab__mark svg {
    filter: grayscale(0.45) brightness(0.86);
}

.stu-coursetab[aria-selected="true"] .stu-coursetab__mark svg {
    filter: none;
}

/* The meta line. It carries the meeting count, and the selected tab adds the
   WORD for its state: colour alone is not a channel every reader has, and the
   indicator is a 2px line. */
.stu-coursetab__meta {
    font-size: var(--stu-t-xs, 12px);
    letter-spacing: 0;
    color: var(--text-secondary);
}

.stu-coursetab__meta b {
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

.stu-coursetab[aria-selected="true"] .stu-coursetab__meta {
    color: var(--primary-color);
}

/* ── The materials page's one column ─────────────────────────────────────────
 *
 * The left rail is gone: everything it navigated to is in the side menu now,
 * and the page is a single content column under the bar. There is no grid here
 * on purpose - the old `.stu-mat` two-track grid is what this replaces, and
 * with it goes `student.css`'s `.stu-main:has(.stu-mat)` full-width escape, so
 * the column falls back to the shell's own 1040px reading width. That is the
 * width the redesign asks for; nothing here re-lifts the cap.
 */
.stu-materials {
    min-inline-size: 0;
}

/* ── Tablet ──────────────────────────────────────────────────────────────── */
@media (max-width: 1024px) {
    .stu-coursetab {
        padding: var(--stu-s-3, 12px) var(--space-sm) var(--space-md);
    }
}

/* ── Phone ───────────────────────────────────────────────────────────────── */
@media (max-width: 767px) {
    /* Only the padding is phone business now. The scroller, the no-shrink flex,
       the inset focus ring and the flush indicator all moved to the base rules
       on 2026-09-04, because a desktop with six courses needs every one of them
       just as much as a phone with three. */
    .stu-coursetab {
        padding: var(--stu-s-3, 12px) 14px var(--space-md);
    }

    /* The head stacks: the title column takes the whole row and the switch
       wraps onto a line of its own under it.

       IT STAYS ON THE PHYSICAL LEFT. `justify-content: space-between` puts a
       lone item on a wrapped line at the line's MAIN START, which under RTL is
       the physical RIGHT - so without the auto margin the control crossed the
       page and sat under the title instead of under where it sits at every
       other width. `margin-inline-start: auto` is the RTL-correct way to push
       it back: inline-start is the physical right, so the margin grows there
       and the control is driven to the left. Item 11 asks for the physical
       left, and a control that changes sides at a breakpoint is a control the
       reader has to find twice. */
    .stu-page-head--os {
        align-items: stretch;
    }

    .stu-page-head--os .stu-page-head__main {
        flex: 1 1 100%;
    }

    .stu-page-head--os .stu-prep-os {
        margin-inline-start: auto;
    }
}

/* ── The meeting head on the materials page ──────────────────────────────────
 *
 * StudentMaterialsPanel: which meeting the column is showing, above the deck.
 * Deliberately NOT a card - the deck player under it is the single opaque
 * surface on this page and the thing the reader came for, and a bordered box
 * between the courses bar and the slide would be a third competing surface in
 * 200px of screen.
 *
 * The title takes the reading start and the way through to the meeting's own
 * page takes the inline end, which under RTL is the physical left - the same
 * side the Mac/Windows control takes in the page head above, so the column has
 * one line of asides rather than two.
 */
.stu-meethead {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-md);
    flex-wrap: wrap;
    margin-block-end: var(--space-lg);
}

.stu-meethead__main {
    flex: 1 1 320px;
    min-inline-size: 0;
}

/* `.stu-section-title` carries a 16px bottom margin for the card it was built
   for; here the meta line sits directly under the title. */
.stu-meethead__title {
    margin-block-end: 6px;
}

.stu-meethead__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    min-block-size: 36px;
    padding-inline: var(--space-md);
    border-radius: var(--radius-full);
    border: 1px solid var(--border-default);
    background: rgba(255, 255, 255, 0.72);
    font-size: 14px;
    color: var(--primary-color);
    text-decoration: none;
    white-space: nowrap;
    transition: border-color var(--stu-dur-2, 0.22s) ease,
                background var(--stu-dur-2, 0.22s) ease;
}

.stu-meethead__link:hover {
    border-color: var(--primary-color);
    background: var(--primary-light);
}

.stu-meethead__link:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

.stu-meethead__note {
    margin-block: var(--space-md) 0;
}

/* On a phone the head stacks and the link goes full width, because a 36px pill
   floated on its own line beside nothing reads as a stray control. */
@media (max-width: 767px) {
    .stu-meethead__link {
        min-block-size: 44px;
        justify-content: center;
        inline-size: 100%;
    }
}

/* ── "which platform does this section follow" ───────────────────────────────
 *
 * The Mac / Windows control itself is in the page head, once per page. These
 * notes are the sentence the head cannot say from up there: they name what the
 * choice governs in THIS section, which differs by section - the reference
 * sheets change what their tables CONTAIN, while the exercise card only changes
 * which of two command columns is emphasised and hides neither.
 *
 * Secondary ink and a small size on purpose. It is an aside about a control the
 * reader has already met at the top of the page, not a heading and not an
 * instruction, and a section that opened with a loud line about operating
 * systems would bury the step the reader actually came for.
 */
.stu-prep-osnote {
    margin: 0 0 var(--space-md);
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.6;
}

/* ── The "הורדה כ-PDF" control ───────────────────────────────────────────────
 *
 * A <button> wearing the pill `.stu-meethead__link` already draws, because it
 * stands next to that link in the meeting head and the two are the same kind of
 * thing: an aside on the inline end, one leading out to another page and one to
 * the browser's print dialog. A second pill shape beside it would read as two
 * unrelated controls that happen to be adjacent.
 *
 * What a <button> does NOT inherit from that rule is the page's own typeface -
 * a button falls back to the UA font, which in Hebrew is a visibly different
 * face from the one the link beside it is set in.
 */
.stu-mat-print {
    font: inherit;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

/* The pair of asides in the meeting head. `.stu-meethead` is a wrapping flex
   row of two children - the title block and this - so the pill that used to be
   the second child keeps its place and gains a neighbour. */
.stu-meethead__actions {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    flex-wrap: wrap;
}

/* A general subject renders one component that owns its heading, so its control
   gets a row of its own above the panel. `flex-end` is the physical LEFT under
   RTL, which is where the meeting head's pair sits and where the Mac/Windows
   switch sits in the page head. */
.stu-mat__actions {
    display: flex;
    justify-content: flex-end;
    margin: 0 0 var(--space-md);
}

/* Phones: the head stacks, and `.stu-meethead__link` is already full width
   there (see the rule above), so both pills want the whole column and a column
   to stack in. */
@media (max-width: 767px) {
    .stu-meethead__actions {
        flex-direction: column;
        align-items: stretch;
        inline-size: 100%;
    }
}

/* The deck's print copy is built by StudentSessionDeck while a print is in
   flight and is never part of the page on screen - not even for the moment the
   dialog is open over it.

   IT MUST BE DECLARED BEFORE THE `@media print` BLOCK BELOW, which is the one
   that shows it. Both rules are a single class, so they tie on specificity and
   SOURCE ORDER decides: written after that block, this `display: none` would
   win in the print medium too and every PDF of a deck would come out with the
   slides missing and nothing to say so. */
.stu-deck__print {
    display: none;
}

/* ── PRINT: the subject the reader has open, and nothing else ────────────────
 *
 * Reached by the "הורדה כ-PDF" control (StudentMaterialsView.printSubject) and
 * by a plain Ctrl+P alike. The button adds two things CSS cannot: every slide
 * of a deck in the document, and the `v-if` collapsibles opened. Everything
 * else about a printed page is here.
 *
 * WHY THE DECK'S OWN PRINT RULES ARE IN THIS FILE and not in
 * student-session-deck.css: the print copy is not a deck feature, it is what
 * this page's button produces, and the two halves of the swap - hide the
 * carousel, show the copy - have to be read together or one of them gets
 * "tidied" and the PDF silently loses every slide but one.
 *
 * SCOPE. Every selector below is a `.stu-*` or `.ses1-*` class, which exist
 * only in the student area; this sheet is in the PUBLIC bundle and is loaded by
 * every page on the site. That is also why there is NO `@page` rule here -
 * @page cannot be scoped to a subtree, so a margin set here would land on the
 * printed invoice, the printed deposit report and every public page too.
 */
@media print {
    /* The chrome, in one list: the side menu and the phone top bar, the drawer
       and its overlay, the live-meeting banner, the courses bar, the meeting's
       tab bar, the prev/next meeting arrows, the platform switch, the controls
       marked `.stu-no-print` (the print button itself, and the link out to the
       meeting page), and the two in-content controls that do nothing on paper:
       "copy this command" and "open all the summaries". */
    .stu-topbar,
    .stu-nav,
    .stu-drawer-overlay,
    .stu-live-banner,
    .stu-coursebar,
    .stu-meeting__tabs,
    .stu-meetnav,
    .stu-prep-os,
    .stu-no-print,
    .stu-prep-code__copy,
    .ses1-bulk {
        display: none !important;
    }

    /* The mascots. They are the area's warmth on screen and a quarter page of
       ink on paper. */
    .stu-empty__mascot,
    .stu-deck__empty-mascot,
    .stu-meeting__pending-mascot {
        display: none !important;
    }

    /* The shell is a flex row with a sticky rail beside a capped column, and
       the rail is gone by the rule above. Black on white, no fixed gradient:
       every printer drops a background image, and the ones that do not spend a
       cartridge on it. */
    .stu-shell {
        display: block;
        min-block-size: 0;
        background: #fff;
        color: #000;
    }

    .stu-main {
        max-inline-size: none;
        padding: 0;
    }

    /* Glass reads as glass over a gradient and as a grey smear on paper, so the
       panels keep their EDGE and lose their surface. */
    .stu-card,
    .stu-deck,
    .stu-deck__notes,
    .stu-deck__ask {
        background: #fff !important;
        box-shadow: none !important;
        backdrop-filter: none !important;
    }

    /* ── The deck, whose on-screen player prints one slide of many ──
       The carousel goes only when there IS a copy to print in its place
       (`is-printing`, raised by the button's own render). Ctrl+P on a deck runs
       none of that code and has no copy, and for that reader the open slide is
       the honest answer - a blank page is not. */
    .stu-deck.is-printing .stu-deck__layer,
    .stu-deck.is-printing .stu-deck__progress {
        display: none !important;
    }

    /* `overflow: clip` is what holds the player's furniture inside the card's
       rounded corners on screen, and it has nothing left to hold once the layer
       above is hidden. It is lifted anyway: a clipped box is one browser
       disagreement away from cutting a thirty-page copy off at the first fold,
       and this is a page nobody sees before the PDF is filed. */
    .stu-deck.is-printing {
        overflow: visible;
    }

    .stu-deck__print {
        display: block;
    }

    /* ONE SLIDE, ONE PAGE - and the last one must not ask for a page after it,
       which is where a trailing blank sheet comes from.

       `break-inside: auto` is still not the default being restated. The SLIDE
       can no longer outgrow a sheet (it is a fixed 16:9 box now, see the pair of
       rules below), but the page around it can: a poll with eight options, every
       one of them answered in free text, plus a note, is taller than what is
       left of the sheet under the stage. It flows onto the next page rather than
       being clipped at the fold. */
    .stu-deck__print-slide {
        break-inside: auto;
        break-after: page;
        page-break-after: always;
        padding-block-end: var(--space-lg);
        /* Nothing above this element supplies horizontal room: `.stu-deck` has
           no padding of its own and `.stu-deck__print` only toggles display, so
           without this the text sat flush against the printed card's edge.
           Logical, so the RTL page decides which side is which. */
        padding-inline: var(--space-md);

        /* ── THE CANVAS ON PAPER, AND THE ONE NUMBER THAT SIZES IT ───────────
           The printed slide is the SAME article the screen draws: a literally
           1920x1080 `container-type: inline-size` canvas, transform-scaled into
           a 16:9 frame, so every `cqw` in deck-slides.css / deck-kit.css /
           deck-slide-templates.css resolves against 1920 exactly as it does on
           the screen and on the projector. Print it any other way and the PDF
           becomes the one surface still drawing a design the site has dropped.

           WHY A DECLARED NUMBER AND NOT A MEASUREMENT. On screen a
           ResizeObserver on the stage computes the fit. There is no observer per
           printed page: print layout happens inside `window.print()`, against a
           page box no script here can measure, and re-fitting after the fact is
           not a thing paper offers. So the scale is declared, ONCE, here - and
           the frame's width and height are derived from it (`1920px * scale`,
           `1080px * scale`) rather than typed a second time, because a frame and
           a transform that disagree is a slide cropped on two edges with nothing
           to say so.

           WHY 0.34. It puts the frame at 652.8 x 367.2px. A4 is 793.7px wide at
           96dpi and Letter is 816px, so with the browser's default print margins
           (~0.4in a side, leaving about 717px on A4) the frame plus this rule's
           own 32px of padding clears the page with room to spare, and body text
           at `2cqw` lands at about 13px - roughly 10pt, ordinary reading size.

           WHAT THE FIXED SCALE COSTS, plainly: the slide prints at one size
           whatever the paper is, so a wider sheet gets white space at the
           outside edge rather than a bigger slide. And a reader who chooses
           margins wider than about 0.65in a side gets a slide cropped at the
           inline edge - `max-inline-size` below keeps that damage inside the
           frame instead of letting it push the whole page sideways, which is the
           failure that makes a browser shrink an entire document to fit. If that
           ever needs to stop being true, the honest fix is a wider page box
           (an `@page` rule is NOT available here - see this block's header), not
           a second rendering path. */
        --stu-print-scale: 0.34;
    }

    /* `direction: ltr` IS NOT A TYPO AND IT IS NOT COSMETIC. Read the canvas
       rule below with it: the two are one decision.

       It puts the canvas's top-LEFT corner on the stage's top-left corner,
       which is the point `transform-origin: top left` scales about. The stage
       itself is still placed by the RTL page around it - it sits against the
       sheet's right edge, where a Hebrew reader starts - and the slide inside
       restores RTL on its own `dir="rtl"` attribute, exactly as it does on the
       screen and in the room. `SlideRenderer.vue` restates that attribute for
       this reason: the canvas is a coordinate system, and the markup inside it
       must not read its direction off whatever the page happens to be. */
    .stu-deck__print-stage {
        position: relative;
        direction: ltr;
        inline-size: calc(1920px * var(--stu-print-scale));
        block-size: calc(1080px * var(--stu-print-scale));
        max-inline-size: 100%;
        overflow: hidden;
        border: 1px solid #ccc;
    }

    /* IN FLOW, NOT `position: absolute`, AND THAT IS A CHROMIUM PRINT BUG THIS
       WORKS AROUND. Measured, not reasoned about: an absolutely positioned
       1920px box inside an `overflow: hidden` box lays out fine on ONE printed
       page, and the moment there is more than one such page Chromium lays the
       whole DOCUMENT out at half the paper width and anchors it to the left
       edge, outside the margin box. Every page then prints the slide cropped
       down its inline edge, with the deck's own head cropped too - the failure
       looks like a stylesheet problem and is not one. Two print pages are
       enough to reproduce it; `overflow: clip` and `contain: paint` on the
       stage do not help, and only taking the canvas out of absolute
       positioning does. The screen stage keeps `position: absolute` and is
       unaffected, because a screen is one page.

       The rest is the screen's canvas verbatim. `container-type` IS REQUIRED
       here: it is what makes every `cqw` in the three deck sheets resolve
       against 1920 rather than against the page, which is the whole reason a
       printed slide is the same slide. The containment it brings is wanted
       rather than tolerated - this box is 367px tall and cannot outgrow a
       sheet, so being monolithic is what stops a slide being split down the
       middle by a page fold. (An earlier version of this file argued against
       `container-type` for the opposite reason. That was written when the print
       copy was a reflowed reading column with no height of its own.) */
    .stu-deck__print-canvas {
        inline-size: 1920px;
        block-size: 1080px;
        transform-origin: top left;
        transform: scale(var(--stu-print-scale));
        container-type: inline-size;
    }

    /* Which slide of how many, since the player's counter is not printed.
       `break-after: avoid` because a number stranded at the foot of a page
       belongs to the slide overleaf, which on a one-slide-per-page document is a
       plain lie. It replaces the same rule on `.stu-deck__slide-title`, which
       this copy no longer renders: the title is the slide's own `h1` now, inside
       the canvas, where it cannot be separated from what it names. */
    .stu-deck__print-num {
        margin: 0 0 6px;
        font-size: 11px;
        color: #555;
        break-after: avoid;
    }

    /* A link is a label with an address behind it, and the address is the half
       that survives being printed. Only inside the print copy: on the page the
       reader can just press the thing. */
    .stu-deck__print .stu-deck__link-row a::after {
        content: " (" attr(href) ")";
        font-size: 11px;
        color: #555;
    }
}
