/* Scribble-inspired styling for the course site.
   Kept as an override on top of the cosmo theme rather than a full
   theme replacement — this way Bootstrap components (tables, code
   blocks, listings) still render and we only tweak the character. */

/* ---- Palette ----
   Every colour below goes through one of these so the light and dark
   schemes cannot drift apart. Quarto adds .quarto-dark to <body> when the
   dark theme is selected; the page background, code highlighting and
   Bootstrap components come from the themes themselves (cosmo/darkly),
   so only the bits this file recolours need an entry here. */

:root {
  --course-fg:            #222;
  --course-link:          #0033aa;
  --course-chrome-bg:     #f0f0e0;
  --course-chrome-border: #d8d8c0;
  --course-chrome-fg:     #222;
  --course-muted:         #666;
  --course-th-bg:         #f5f5f5;
  /* Scribble's navigation silver (its .navsettop bar), which reads as a
     control rather than as part of the cream chrome. */
  --course-btn-bg:        #a7b0be;
  --course-btn-bg-hover:  #b9c1cc;
  --course-btn-border:    #7c8797;
  --course-btn-fg:        #1a1a1a;
  --course-code-bg:       #f8f9fa;
  --course-code-fg:       #7d12ba;
}

.quarto-dark {
  --course-fg:            #e2e2d8;
  --course-link:          #8ab4f8;
  --course-chrome-bg:     #26261f;
  --course-chrome-border: #3d3d33;
  --course-chrome-fg:     #e2e2d8;
  --course-muted:         #9a9a8d;
  --course-th-bg:         #2e2e26;
  /* Same hue, dropped in lightness so it stays a control against #222
     without glaring. */
  --course-btn-bg:        #57606f;
  --course-btn-bg-hover:  #667082;
  --course-btn-border:    #8a94a5;
  --course-btn-fg:        #f2f2ee;
  --course-code-bg:       #2e2e26;
  --course-code-fg:       #e0b3ff;
}

/* ---- Typography: sans body, monospace sidebar/navbar ---- */

body,
.quarto-container,
main.content {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--course-fg);
  line-height: 1.5;
}

.navbar,
.navbar-brand,
.navbar-title,
.sidebar,
.sidebar-item,
.sidebar-item-text,
.sidebar-search {
  font-family: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", monospace;
}

/* ---- Heading sizes: tighter, less flashy than Bootstrap defaults ---- */

h1 { font-size: 1.5em;  font-weight: 600; margin-top: 1.75em; }
h2 { font-size: 1.17em; font-weight: 600; margin-top: 1.75em; }
h3 { font-size: 1.05em; font-weight: 600; margin-top: 1.5em; }
h4 { font-size: 0.95em; font-weight: 600; margin-top: 1.25em; }

/* Content column: narrower for comfortable reading */
main.content {
  max-width: 44em;
}

/* ---- Links: classic blue ---- */

a, a:visited {
  color: var(--course-link);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

/* The active sidebar entry and the active "On this page" entry are accented
   by the Bootswatch theme, which would make them cosmo blue in light and
   darkly teal in dark. Point them at the site link colour so the accent is
   the same in both schemes. The theme sets the "On this page" ones with
   !important, marker bar included, so these have to match its selectors. */
.sidebar-navigation .sidebar-link.active {
  color: var(--course-link);
}
.sidebar nav[role="doc-toc"] ul > li > a.active,
.sidebar nav[role="doc-toc"] ul > li > ul > li > a.active {
  color: var(--course-link) !important;
  border-left-color: var(--course-link);
}
.sidebar nav[role="doc-toc"] ul > li > a:hover,
.sidebar nav[role="doc-toc"] ul > li > ul > li > a:hover {
  color: var(--course-link) !important;
}

/* ---- Sidebar + navbar: cream background, thin border ---- */

.navbar {
  background-color: var(--course-chrome-bg) !important;
  border-bottom: 1px solid var(--course-chrome-border);
}

/* Disable Quarto's Headroom.js sticky/hide-on-scroll behaviour for
   both the top navbar and the breadcrumbs bar. Let them scroll off
   with the rest of the page instead of pinning and mis-restoring
   partway down the viewport. */
.navbar,
.quarto-secondary-nav,
header#quarto-header {
  position: static !important;
  top: auto !important;
  transform: none !important;
  transition: none !important;
}

/* Quarto's quarto-nav.js measures the (previously) fixed header
   and sets body { padding-top } and sidebar { top, max-height }
   inline based on that height, which now shows up as a blank
   band at the top of the page. Beat the inline styles with
   !important to zero it out. */
body {
  padding-top: 0 !important;
}
/* Desktop only. On mobile the sidebar is a fixed overlay and Quarto's inline
   top is what keeps it below the header — see the .show rule further down. */
@media (min-width: 992px) {
  :root {
    /* Quarto gives .sidebar-menu-container min-width: 225px; matching it here
       keeps the fixed sidebar and the inset below in step. */
    --course-sidebar-w: 225px;
  }

  /* Run the sidebar from the top of the viewport, with the header starting to
     its right. Quarto's default lays a full-width navbar across the top and
     begins the sidebar underneath it, which spends the first ~55px of the
     sidebar column on nothing. */
  #quarto-sidebar.docked {
    position: fixed;
    top: 0 !important;
    left: 0;
    bottom: 0;
    width: var(--course-sidebar-w);
    max-height: none !important;
    overflow-y: auto;
  }

  /* The header and footer are full-width siblings of the content div, so they
     have to be inset by hand. #quarto-content deliberately is not: its grid
     keeps the left tracks that used to hold the sidebar, so insetting it too
     would clear the same 225px twice. */
  header#quarto-header,
  footer.footer {
    margin-left: var(--course-sidebar-w);
  }
}
.navbar .navbar-brand,
.navbar .navbar-title,
.navbar .nav-link {
  color: var(--course-chrome-fg) !important;
}

/* Let the site title wrap onto multiple lines on narrow screens
   instead of being truncated with an ellipsis.

   The size is interpolated rather than stepped at 992px. A step left the
   whole tablet band at the phone size, where the bar is wide enough to sit
   the title on one line with a third of the width to spare — legible on a
   phone, lost on a tablet. The ramp runs 1rem at 576px to 1.75rem at 992px,
   and the two clamp ends then reproduce the fixed sizes outside that range,
   so this one declaration replaces the old pair and needs no breakpoint.

   1.75rem is safe at the top of the ramp even though the title area is at
   its narrowest there: at 992px the sidebar opens and takes 225px off the
   bar, which is more than the 115px Quarto holds back for the tools below
   it. The desktop side of the boundary is the tighter of the two. */
.navbar-brand,
.navbar-title {
  white-space: normal;
  overflow: visible;
  text-overflow: unset;
  line-height: 1.25;
  max-width: none;
  font-size: clamp(1rem, 2.885vw - 0.04rem, 1.75rem);
}

/* ---- Brand mark ----
   The same file is declared as both the sidebar and the navbar logo, and
   exactly one of them is visible at any width. Quarto tags the sidebar copy
   d-none/d-lg-inline, so it goes away with the sidebar below 992px; the
   navbar copy covers those widths instead. */

/* Quarto's default is max-width: 90%, which on a 225px sidebar renders the
   mark ~200px wide — loud for what the style guide calls a tertiary mark. */
.sidebar-logo {
  max-width: 120px;
}
/* Centre the mark in its column. The header div carries Bootstrap 4's
   .text-left, which BS5 no longer defines, so nothing contests this. */
.sidebar-header {
  text-align: center;
}

/* Quarto caps the navbar logo at 24px, where the CU ring closes up into a
   blob. It also sets object-fit: cover, which would crop a non-square mark;
   the icon is 225×240, so switch to contain and let it scale whole. */
.navbar-logo {
  max-height: 36px;
  object-fit: contain;
}
@media (min-width: 992px) {
  .navbar-logo {
    display: none;
  }
}

/* ---- Header tools ----
   Quarto gives the navbar magnifier 26px but leaves the theme toggle at 16px,
   and the toggle then reads smaller than even that gap suggests: its glyph is
   a wide flat switch filling about half the height of its box, where the
   magnifier fills its own. Enlarging the toggle is what makes the two look
   like a pair; the magnifier is already the size it should be, and any rule
   aimed at it here would lose to Quarto's anyway, which is more specific.

   The toggle is a background image on a ::before with a fixed 1rem box, so
   font-size does nothing to it and all three lengths have to move together;
   the SVG is a 16px viewBox scaled by background-size, so it stays sharp.

   Deliberately unscoped. This is the one part of the header work that is not
   about how much width is left, so it takes no breakpoint. */
.navbar .quarto-color-scheme-toggle .bi::before {
  height: 1.4rem;
  width: 1.4rem;
  background-size: 1.4rem 1.4rem;
}

/* Between the phone stack and the desktop layout, the two tools drift apart:
   the search carries an unscoped margin-left: auto while Quarto only groups
   the pair back together inside its own min-width: 992px block. Two auto
   margins each claim a share of the free space, which strands the toggle
   against the title as though it belonged to it, with the search alone at
   the far edge. Give the brand the only auto margin so it absorbs the lot
   and the tools stay a pair, in the same order as on desktop. */
@media (min-width: 576px) and (max-width: 991.98px) {
  .navbar > .navbar-container > .navbar-brand-container {
    margin-left: 0 !important;
    margin-right: auto !important;
  }
  .navbar > .navbar-container > .quarto-navbar-tools {
    margin-left: 0 !important;
  }
  .navbar > .navbar-container > #quarto-search {
    margin-left: 0.25rem;
  }
}

/* On a phone the navbar row holds three children — the brand, the theme
   toggle, and the search — and Quarto gives the brand Bootstrap's .mx-auto,
   whose auto margins claim the leftover width instead of letting the title
   use it. The title wraps to three lines while an empty gap sits between the
   two tools.

   Grid rather than flex: the brand takes the first column and both tools
   stack in the second, which is then one icon wide instead of two icons plus
   the gap. They are separate siblings in Quarto's markup — the toggle is
   inside .quarto-navbar-tools, the search is its own div — so nothing can
   wrap them in a flex column without editing the DOM, but placing them in
   one grid column needs no such wrapper.

   Only below 576px. The stack trades height for width, and that is a good
   trade only while width is scarce: on a tablet the title already fits on
   one line, so stacking would just make the bar taller for nothing. */
@media (max-width: 575.98px) {
  .navbar > .navbar-container {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    column-gap: 0.5rem;
  }
  .navbar > .navbar-container > .navbar-brand-container {
    grid-column: 1;
    grid-row: 1 / span 2;
    /* Bootstrap's utilities are !important, so .mx-auto needs this to match. */
    margin-left: 0 !important;
    margin-right: 0 !important;
    /* Quarto's max-width: calc(100% - 115px) holds back room for two tools
       side by side. Stacked they need ~40px, and the grid track already
       reserves it, so the reservation would only shrink the title twice. */
    max-width: none;
  }
  .navbar > .navbar-container > .quarto-navbar-tools {
    grid-column: 2;
    grid-row: 1;
  }
  .navbar > .navbar-container > #quarto-search {
    grid-column: 2;
    grid-row: 2;
    justify-self: center;
  }
  /* The mark sits against the first letter otherwise. */
  .navbar-brand-container > .navbar-brand-logo {
    margin-right: 0.6rem;
  }
}

/* Quarto paints the sidebar white through
   `nav.sidebar.sidebar-navigation:not(.rollup)` — an element plus four
   classes, which a plain `.sidebar.docked` cannot outrank, so the cream never
   took. Going through the id does. */
#quarto-sidebar.sidebar {
  background-color: var(--course-chrome-bg);
  /* And the theme's matching border is itself !important, so this has to be. */
  border-right: 1px solid var(--course-chrome-border) !important;
}
.sidebar .sidebar-item-text {
  font-size: 1.25em;
}

/* Vertical breathing room between sidebar entries. Quarto's default
   is very tight; loosen it. */
.sidebar .sidebar-item {
  padding: 0.35em 0;
}
.sidebar .sidebar-item-container {
  margin: 0.15em 0;
}

/* ---- Breadcrumbs ---- */

/* darkly gives .breadcrumb a filled #434343 chip with padding and a radius,
   cosmo leaves it bare, so in dark mode the crumbs sat in a pale box. Reset
   through Bootstrap's own variables so both schemes render the crumbs as
   plain text. */
.quarto-page-breadcrumbs .breadcrumb,
.quarto-title-breadcrumbs .breadcrumb {
  --bs-breadcrumb-bg: transparent;
  --bs-breadcrumb-padding-x: 0;
  --bs-breadcrumb-padding-y: 0;
  --bs-breadcrumb-border-radius: 0;
}

/* ---- Tables: keep the existing subtle header shading ---- */

table {
  margin: 1rem 0;
}
table th {
  background-color: var(--course-th-bg);
}

/* ---- Assignment listing ----
   The table on assignments.qmd, built from assignments.yml through
   config/assignment-listing.ejs: the three dates on the left, title and
   description on the right. Headerless on purpose — each date carries its
   own label, so a header row would only repeat them. */

.assignment-listing {
  width: 100%;
  border-collapse: collapse;
}
.assignment-listing td {
  vertical-align: top;
  padding: 0.9em 0;
  border-top: 1px solid var(--course-chrome-border);
}
/* width:1% with nowrap is the shrink-to-fit idiom: the column ends up as
   wide as its widest row instead of taking a share of the table. */
.assignment-listing .assignment-when {
  width: 1%;
  white-space: nowrap;
  padding-right: 1.5em;
  font-size: 0.85em;
}
.assignment-when-label {
  display: inline-block;
  min-width: 5.5em;
  color: var(--course-muted);
}
.assignment-title {
  font-weight: 600;
}
.assignment-description p:last-child {
  margin-bottom: 0;
}

/* Two columns stop fitting well before the sidebar breakpoint, so below
   phone width the cells stack and the dates run along one line. */
@media (max-width: 575.98px) {
  .assignment-listing,
  .assignment-listing tbody,
  .assignment-listing tr,
  .assignment-listing td {
    display: block;
    width: auto;
  }
  /* Releasing the shrink-to-fit width takes this selector rather than the
     one above: `.assignment-listing .assignment-when` outranks
     `.assignment-listing td`, so `width: auto` there would not have won. */
  .assignment-listing .assignment-when {
    width: auto;
    white-space: normal;
    padding-right: 0;
    padding-bottom: 0.25em;
  }
  .assignment-listing .assignment-what {
    border-top: 0;
    padding-top: 0;
  }
  /* Label and date travel together; the line breaks between groups. */
  .assignment-when-row {
    display: inline-block;
    white-space: nowrap;
    margin-right: 1.25em;
  }
  .assignment-when-label {
    min-width: 0;
    margin-right: 0.35em;
  }
}

/* ---- "Next due" block on the home page ----
   Same source as the table above, rendered through config/next-due.ejs.
   Every assignment is in the markup and the script there hides all but one,
   so these rules have to look right for a list as well as for a single
   entry — that list is what a reader with scripting off gets. */

.next-due-caption {
  color: var(--course-muted);
  font-size: 0.85em;
  margin-bottom: 0.35em;
}
.next-due-caption:empty {
  display: none;
}
.next-due-date {
  color: var(--course-muted);
  font-size: 0.85em;
}
.next-due-title {
  font-weight: 600;
}
.next-due-item + .next-due-item {
  margin-top: 1em;
  padding-top: 1em;
  border-top: 1px solid var(--course-chrome-border);
}
.next-due-description p:last-child {
  margin-bottom: 0;
}

/* ---- Subtitle (course term) muted below the main title ---- */

.quarto-title-block .subtitle {
  color: var(--course-muted);
  font-weight: 400;
  font-size: 1.1em;
}

/* ---- Code: monospace, slightly smaller ---- */

code, pre, kbd, samp {
  font-family: "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 0.9em;
}

/* Inline code. Both Bootswatch bundles hardcode a near-white chip, so on a
   dark page it glares; recolour it from the palette instead. Deliberately a
   bare `code` selector: the themes zero the background of `pre code` at
   higher specificity, which keeps code blocks on their own highlighting. */
code {
  background-color: var(--course-code-bg);
  color: var(--course-code-fg);
  border-radius: 3px;
}
/* The themes repeat the chip at higher specificity for the common contexts,
   so these have to be matched selector for selector. */
p code:not(.sourceCode),
li code:not(.sourceCode),
td code:not(.sourceCode) {
  background-color: var(--course-code-bg);
}

/* ---- Mobile: <992px collapses the sidebar into a toggle ---- */

@media (max-width: 991.98px) {
  /* Content column: full width with breathing room, no 44em cap */
  main.content {
    max-width: 100%;
    padding: 0.75em 1em 2em;
  }

  /* Hide the magnifying-glass search icon in the mobile secondary
     nav — the sidebar already has a search box below. */
  .quarto-secondary-nav .quarto-search-button {
    display: none;
  }

  /* Menu button — the sidebar toggle Quarto puts in the mobile
     breadcrumbs bar. A small JS block in _quarto.yml adds a
     "Menu" text label; this rule turns it into a proper button. */
  .menu-btn {
    display: inline-flex !important;
    align-items: center;
    gap: 0.4em;
    padding: 0.3em 0.75em;
    border: 1px solid var(--course-btn-border);
    border-radius: 4px;
    background: var(--course-btn-bg);
    color: var(--course-btn-fg);
    font-family: system-ui, "Segoe UI", Arial, sans-serif;
    font-size: 0.85rem;
    line-height: 1;
  }
  .menu-btn:hover,
  .menu-btn:focus {
    background: var(--course-btn-bg-hover);
  }

  /* Keep the breadcrumbs off the button. The theme gives the toggle
     margin-right: .15rem and then pulls the crumbs back over it with
     margin-left: -0.25em, so the first crumb lands flush against the border.
     Both selectors match the theme's own specificity; this file is loaded
     last, so the tie breaks our way. */
  .quarto-secondary-nav button.menu-btn {
    margin-right: 0.75em;
  }
  .quarto-secondary-nav nav.quarto-page-breadcrumbs {
    margin-left: 0;
  }
  .menu-btn .menu-btn-text {
    font-weight: 500;
  }

  /* Full-width drawer below the header. The vertical offsets are left to
     Quarto's inline styles (top and max-height, computed from the header
     height) — forcing top to 0 painted the drawer over the header at
     z-index 1055 vs 1030, hiding the Menu button and leaving no way to
     dismiss the menu but tapping an entry. min-height has to be released or
     it wins over max-height and the drawer spills past the bottom of the
     screen. Width is pinned with left/right rather than `width: 100%`: the
     drawer is Bootstrap `.collapse-horizontal`, and past a certain content
     height a percentage width stops resolving against the viewport and the
     drawer snaps back to its 225px shrink-to-fit size. */
  #quarto-sidebar.docked.show {
    left: 0 !important;
    right: 0 !important;
    width: auto !important;
    min-height: 0 !important;
  }

  /* Slightly smaller page title so it doesn't dominate a phone screen */
  .quarto-title-block .title {
    font-size: 1.35em;
  }
}

/* Small phones: bump body text down a hair for line-length */
@media (max-width: 480px) {
  body {
    font-size: 15px;
  }
  .navbar-brand,
  .navbar-title {
    font-size: 0.9rem;
  }
}
