/* hub.css
   The design system every course hub imports.
   A hub sets its own --accent and --lead in all three theme states and changes nothing else.
   States: bare :root, the dark media query guarded against a forced light theme,
   and an explicit :root[data-theme="dark"]. */

/* ---------- tokens ---------- */

:root {
  --paper:#ECEEF1; --surface:#F5F6F8; --sunk:#E1E4E9;
  --ink:#171A1E; --ink-soft:#404750; --muted:#6C737C;
  --rule:#D0D6DD; --rule-soft:#DFE3E9;
  --accent:#1C5D93; --lead:#2A5273; --hot:#8E6318; --done:#2E7D62;
  --c-y:#8A6A0B; --c-p:#AE2F73;
  --shadow-1:0 1px 2px rgba(16,24,20,.05),0 6px 18px -8px rgba(16,24,20,.16);
  --shadow-2:0 2px 4px rgba(16,24,20,.06),0 18px 34px -12px rgba(16,24,20,.3);
  --ghost:.045;
  --display:"Newsreader",Georgia,serif;
  --body:"Source Sans 3",-apple-system,"Segoe UI",sans-serif;
  --mono:"IBM Plex Mono","SF Mono",Menlo,monospace;
}

@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --paper:#131619; --surface:#1A1E22; --sunk:#0F1114;
  --ink:#E3E7EB; --ink-soft:#B2B9C1; --muted:#89909A;
  --rule:#2A3037; --rule-soft:#222830;
  --accent:#6BB4E8; --lead:#95BFDC; --hot:#D9A957; --done:#68C3A3;
  --c-y:#E3BE57; --c-p:#FF97C6;
  --shadow-1:0 1px 2px rgba(0,0,0,.4),0 8px 22px -10px rgba(0,0,0,.6);
  --shadow-2:0 2px 6px rgba(0,0,0,.5),0 20px 38px -14px rgba(0,0,0,.75);
  --ghost:.07;
} }

:root[data-theme="dark"] {
  --paper:#131619; --surface:#1A1E22; --sunk:#0F1114;
  --ink:#E3E7EB; --ink-soft:#B2B9C1; --muted:#89909A;
  --rule:#2A3037; --rule-soft:#222830;
  --accent:#6BB4E8; --lead:#95BFDC; --hot:#D9A957; --done:#68C3A3;
  --c-y:#E3BE57; --c-p:#FF97C6;
  --shadow-1:0 1px 2px rgba(0,0,0,.4),0 8px 22px -10px rgba(0,0,0,.6);
  --shadow-2:0 2px 6px rgba(0,0,0,.5),0 20px 38px -14px rgba(0,0,0,.75);
  --ghost:.07;
}

/* ---------- page frame and type scale ---------- */

*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);
  font-size:17.5px;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
.wrap{max-width:900px;margin:0 auto;padding:clamp(48px,9vh,110px) 26px 90px;
  display:flex;flex-direction:column;gap:52px}
.wrap.narrow{max-width:820px}
.eyebrow{font-family:var(--mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
h1{font-family:var(--display);font-weight:600;font-size:clamp(38px,7vw,62px);line-height:1.02;
  letter-spacing:-.02em;margin:14px 0 0;text-wrap:balance}
.standfirst{font-family:var(--display);font-size:clamp(18px,2.5vw,22px);line-height:1.5;
  color:var(--ink-soft);max-width:56ch;margin:20px 0 0}
h2{font-family:var(--display);font-weight:600;font-size:24px;margin:0;letter-spacing:-.01em}
/* An in-page link lands under the sticky top bar without this, so the heading it jumped to is
   the one thing the reader cannot see. */
[id]{scroll-margin-top:80px}
h3{font-family:var(--display);font-weight:600;font-size:19px;margin:0;letter-spacing:-.01em}
p{margin:0;max-width:70ch}
section{display:flex;flex-direction:column;gap:20px}
a{color:var(--accent)}
ul,ol{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:9px;color:var(--ink-soft);max-width:72ch}
ul b,ol b{color:var(--ink)}
ol{padding-left:23px}
.mono{font-family:var(--mono);font-size:14px}

/* ---------- the course card ---------- */

.cards{display:flex;flex-direction:column;gap:16px}
.card{position:relative;display:grid;grid-template-columns:1fr auto;gap:18px 22px;align-items:end;
  padding:30px 30px 26px;text-decoration:none;color:inherit;background:var(--surface);
  border:1px solid var(--rule);border-radius:12px;overflow:hidden;box-shadow:var(--shadow-1);
  transition:transform .18s cubic-bezier(.2,.7,.3,1),box-shadow .18s,border-color .18s}
.card::before{content:"";position:absolute;inset:0 auto 0 0;width:4px;background:var(--card-accent,var(--accent));
  opacity:.9;transition:width .18s}
.card:hover{transform:translateY(-3px);border-color:var(--card-accent,var(--accent));box-shadow:var(--shadow-2)}
.card:hover::before{width:6px}
.card:active{transform:translateY(-1px)}
.card:focus-visible{outline:2px solid var(--card-accent,var(--accent));outline-offset:3px}
.card .ghost{position:absolute;right:20px;top:-14px;font-family:var(--display);font-weight:600;
  font-size:110px;line-height:1;color:var(--ink);opacity:var(--ghost);pointer-events:none;user-select:none}
.card .t{display:flex;flex-direction:column;gap:7px;min-width:0;grid-column:1/-1}
.card .n{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--card-accent,var(--accent))}
.card h3{margin:0;font-family:var(--display);font-size:clamp(26px,3.6vw,32px);font-weight:600;
  line-height:1.14;letter-spacing:-.015em}
.card p{font-size:16px;color:var(--ink-soft);max-width:58ch}
.card .go{grid-column:1/-1;display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--card-accent,var(--accent));margin-top:4px}
.card .go svg{width:15px;height:15px;transition:transform .18s}
.card:hover .go svg{transform:translateX(4px)}
.card .meta{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:6px 18px;font-size:14px;color:var(--muted);margin-top:2px}
.card .meta b{color:var(--ink-soft);font-weight:600}

.also{display:flex;gap:16px;flex-wrap:wrap;padding-left:2px}
.also a{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;color:var(--muted);text-decoration:none;
  border:1px solid var(--rule);border-radius:20px;padding:7px 14px;transition:border-color .15s,color .15s}
.also a:hover{color:var(--ink);border-color:var(--muted)}
.soon{padding:22px 30px;border:1px dashed var(--rule);border-radius:12px;
  display:flex;flex-direction:column;gap:5px;color:var(--muted)}
.soon .n{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase}
.soon .t{font-size:16px}

/* ---------- the fact grid ---------- */

.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin-top:4px}
.fact{background:var(--surface);border:1px solid var(--rule);border-radius:10px;padding:18px 20px;
  display:flex;flex-direction:column;gap:5px}
.fact .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.fact .v{font-size:16px;color:var(--ink);line-height:1.45}
.fact .v b{font-weight:600}

/* ---------- the scrolling table ---------- */

.scroll{overflow-x:auto;border:1px solid var(--rule);border-radius:10px;background:var(--surface);margin-top:6px}
table{border-collapse:collapse;width:100%;min-width:720px;font-size:15px}
caption{text-align:left;padding:16px 20px 0;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
th,td{text-align:left;padding:13px 16px;border-bottom:1px solid var(--rule-soft);vertical-align:top}
thead th{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);font-weight:500;border-bottom:1px solid var(--rule);white-space:nowrap}
tbody tr:last-child td{border-bottom:none}
td.num{font-family:var(--mono);font-weight:500;color:var(--accent);white-space:nowrap}
td.prob{font-family:var(--mono);font-size:13px;line-height:1.55;color:var(--ink-soft);min-width:190px}
td.ch{font-family:var(--mono);color:var(--muted);text-align:center}
td.topic{min-width:170px}
td.src{font-size:13.5px;min-width:120px}
td.src a{text-decoration:none;border-bottom:1px solid currentColor}
td.src .none{color:var(--muted);border:0;font-style:italic}
/* A drawn figure: an inline SVG that inherits the page colours, with its caption under it. */
.fig{margin:0;display:flex;flex-direction:column;gap:9px}
.fig .plate{background:var(--surface);border:1px solid var(--rule-soft);border-radius:10px;
  padding:14px 12px;overflow-x:auto}
.fig svg{display:block;width:100%;min-width:430px;height:auto;color:var(--ink-soft)}
.fig figcaption{font-size:12.5px;color:var(--muted);max-width:72ch}
td.src .lec{display:block;background:var(--sunk);border-radius:8px;padding:6px 9px;text-align:center}
td.src .lec + .lec{margin-top:6px}
td.src .lec .lecnote{display:block;margin-top:1px;font-size:11px;font-weight:400;line-height:1.2;color:var(--muted);
  background:none;border:0;padding:0;border-radius:0}
tr.gate td{background:var(--sunk);padding:15px 16px;border-top:2px solid var(--accent);border-bottom:2px solid var(--accent)}
tr.gate .g{display:flex;flex-wrap:wrap;gap:6px 16px;align-items:baseline}
tr.gate .lbl{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);font-weight:500}
tr.gate .det{font-size:14.5px;color:var(--ink-soft)}

/* ---------- the note block ---------- */

.note{background:var(--sunk);border-radius:10px;padding:20px 24px;display:flex;flex-direction:column;gap:10px;
  font-size:16px;color:var(--ink-soft);margin-top:4px}
.note b{color:var(--ink)}
.banner{border:1px dashed var(--accent);border-radius:12px;padding:24px 26px;
  display:flex;flex-direction:column;gap:10px;background:var(--surface)}
.banner .n{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--accent)}
.banner p{color:var(--ink-soft);font-size:16px}

/* ---------- the task list ---------- */

.stack{display:flex;flex-direction:column;gap:12px;margin-top:4px}
.task{display:flex;gap:15px;padding:17px 20px;background:var(--surface);border:1px solid var(--rule);
  border-radius:10px;align-items:flex-start}
.task .box{flex:0 0 auto;width:15px;height:15px;margin-top:4px;border:1.6px solid var(--muted);
  border-radius:3.5px;cursor:pointer;transition:background .15s,border-color .15s}
.task .box:hover{border-color:var(--accent)}
.task .box:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.task .box[aria-checked="true"]{background:var(--done);border-color:var(--done);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size:contain}
.task .b{display:flex;flex-direction:column;gap:5px;min-width:0}
.task .h{font-weight:600;color:var(--ink);font-size:16.5px}
.task .d{font-size:15px;color:var(--ink-soft);max-width:64ch}
.task .tag{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:3px 8px;
  border-radius:20px;border:1px solid var(--rule);color:var(--muted);align-self:flex-start;margin-top:3px}
.task.now{border-color:var(--accent)}
.task.now .box{border-color:var(--accent)}
.task.now .tag{color:var(--accent);border-color:var(--accent)}
/* A finished item is struck through on its heading only. A line through three lines of
   description is harder to read than the description is worth. */
.task.done .h{text-decoration:line-through;text-decoration-thickness:1px;color:var(--muted)}
.task.done .d{color:var(--muted)}
.task.done{opacity:.72}
.task.done:hover,.task.done:focus-within{opacity:1}

/* ---------- a tick box in a table row ---------- */

td.tick{width:44px;padding-right:0}
td.tick .box{width:15px;height:15px;margin-top:2px;border:1.6px solid var(--muted);border-radius:3.5px;
  display:block;cursor:pointer;transition:background .15s,border-color .15s}
td.tick .box:hover{border-color:var(--accent)}
td.tick .box:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
td.tick .box[aria-checked="true"]{background:var(--done);border-color:var(--done);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size:contain}
tbody tr.done td{color:var(--muted)}
tbody tr.done td.num{color:var(--done)}
tbody tr.done td.prob,tbody tr.done td.topic{opacity:.6}
thead th.tick{width:44px}

/* A label a screen reader announces and the eye never sees, for the tick column header. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------- a link the reader fills in herself ---------- */

/* shared/links.js writes what is inside a .lnk span. Empty, it holds one small invitation in
   --muted under a dashed line, which reads as something to fill in. Filled, it holds the link
   and a twelve pixel pencil, and that is all, because the filled state is the one the reader
   is in on nearly every visit. The pencil is the only way back to the input, so it stays small
   and grey until the cursor reaches it.

   The link and its pencil hold one line, so the pencil can never drop underneath and read as a
   second thing in the cell. The input is the one state that wraps, because the line refusing an
   address goes under it. The label is two words at most and holds its line too, so the column
   widens to take it and no word is ever broken in half. */

.lnk{display:inline-flex;flex-wrap:nowrap;align-items:baseline;gap:7px;max-width:100%}
.lnk.editing{display:flex;flex-wrap:wrap;gap:5px 7px;width:100%}
.lnk .lnk-a{color:var(--accent);text-decoration:none;border-bottom:1px solid currentColor;
  white-space:nowrap}
.lnk .lnk-a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

.lnk .lnk-add{font-family:var(--body);font-size:13.5px;line-height:inherit;color:var(--muted);
  background:none;border:0;padding:0;cursor:pointer;text-decoration:underline;
  text-decoration-style:dashed;text-decoration-thickness:1px;text-underline-offset:3px;
  transition:color .15s}
.lnk .lnk-add:hover{color:var(--accent)}
.lnk .lnk-add:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}

.lnk .lnk-edit{flex:0 0 auto;align-self:center;width:12px;height:12px;padding:0;border:0;
  background:none;line-height:0;color:var(--muted);cursor:pointer;transition:color .15s}
.lnk .lnk-edit svg{display:block;width:12px;height:12px}
.lnk .lnk-edit:hover{color:var(--accent)}
.lnk .lnk-edit:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}

.lnk .lnk-in{flex:1 1 auto;min-width:0;font-family:var(--body);font-size:13.5px;color:var(--ink);
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:4px 7px}
.lnk .lnk-in:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
.lnk .lnk-in.bad{border-color:var(--hot)}
.lnk .lnk-no{flex:1 0 100%;font-family:var(--body);font-size:12.5px;line-height:1.35;color:var(--hot)}


/* ---------- a column holding several links ---------- */

/* The same parts as .lnk, laid out down the cell. Each entry holds its own line with its
   pencil beside it, and the add button comes after the last one. An entry with no name of its
   own is drawn as the host it points at, which keeps a stack of them readable. */

.lnks{display:flex;flex-direction:column;align-items:flex-start;gap:5px;max-width:100%}
.lnks .lnks-i{display:inline-flex;flex-wrap:nowrap;align-items:baseline;gap:7px;max-width:100%}
.lnks .lnk-a{color:var(--accent);text-decoration:none;border-bottom:1px solid currentColor;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:22ch}
.lnks .lnk-a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
.lnks .lnk-edit{flex:0 0 auto;align-self:center;width:12px;height:12px;padding:0;border:0;
  background:none;line-height:0;color:var(--muted);cursor:pointer;transition:color .15s}
.lnks .lnk-edit svg{display:block;width:12px;height:12px}
.lnks .lnk-edit:hover{color:var(--accent)}
.lnks .lnk-edit:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
.lnks .lnk-add{font-family:var(--body);font-size:13.5px;line-height:inherit;color:var(--muted);
  background:none;border:0;padding:0;cursor:pointer;text-decoration:underline;
  text-decoration-style:dashed;text-decoration-thickness:1px;text-underline-offset:3px;
  transition:color .15s;text-align:left}
.lnks .lnk-add:hover{color:var(--accent)}
.lnks .lnk-add:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
.lnks.editing{width:100%}
.lnks .lnk-in{width:100%;min-width:0;font-family:var(--body);font-size:13.5px;color:var(--ink);
  background:var(--paper);border:1px solid var(--rule);border-radius:5px;padding:4px 7px}
.lnks .lnk-in:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
.lnks .lnk-in.bad{border-color:var(--hot)}
.lnks .lnk-no{font-family:var(--body);font-size:12.5px;line-height:1.35;color:var(--hot)}

/* ---------- a section that folds, and the ones that carry the work ---------- */

/* A whole section behind one summary line, for the two blocks a reader opens on purpose. The
   summary carries the heading, the done count and a line saying what is inside, so the section
   can be judged shut. Keystone marks the blocks that are the reason the page exists: an accent
   edge, a filled summary and a chip. Nothing here defines a colour of its own, so the page
   keeps its three-state palette. */

details.block{border:1px solid var(--rule);border-radius:12px;background:var(--paper);
  overflow:hidden}
details.block>summary{cursor:pointer;list-style:none;display:flex;align-items:center;
  gap:9px 12px;flex-wrap:wrap;padding:16px 20px}
details.block>summary::-webkit-details-marker{display:none}

/* The arrow goes in front of the heading, in the accent, because a marker at the far end of a
   wide bar was read as decoration and the block was taken for a heading that does not open.
   The word beside it says which way the press goes, for the same reason. */
details.block>summary::before{content:"";flex:0 0 auto;width:0;height:0;
  border-left:7px solid currentColor;border-top:6px solid transparent;
  border-bottom:6px solid transparent;color:var(--accent);transition:transform .18s}
details.block[open]>summary::before{transform:rotate(90deg)}
details.block>summary .cue{margin-left:auto;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted);border:1px solid var(--rule);
  border-radius:20px;padding:4px 11px;white-space:nowrap;transition:color .15s,border-color .15s}
details.block>summary .cue::after{content:"Show"}
details.block[open]>summary .cue::after{content:"Hide"}
details.block>summary:hover{background:var(--sunk)}
details.block>summary:hover .cue{color:var(--accent);border-color:var(--accent)}
details.block>summary:focus-visible{outline:2px solid var(--accent);outline-offset:-3px}
details.block>summary h2{margin:0}
/* a housekeeping line sits beside the thing it explains: small, muted, a thin
   rule down the side, and no fill, so it never reads as content. */
.sidenote{font-family:var(--body);font-size:13.5px;line-height:1.55;color:var(--muted);
  border-left:2px solid var(--rule);padding-left:12px}
details.block>summary .sidenote{flex:1 1 100%;margin-top:2px}
details.block .in{display:flex;flex-direction:column;gap:20px;padding:2px 22px 24px}

details.block.keystone{border-color:var(--accent);border-left-width:3px}
details.block.keystone>summary{background:var(--sunk)}
.keychip{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent);border:1px solid var(--accent);border-radius:20px;padding:3px 10px;
  white-space:nowrap}

@media (max-width:620px){
  details.block>summary{padding:15px 16px}
  details.block .in{padding:2px 16px 20px}
}


/* ---------- the block a guide page exists for ---------- */

/* On a laboratory quick guide, the stages that carry the marks are the reason the page is
   open. Everything under them is a note. The accent edge and the chip say so without the
   reader having to scroll and compare. No colour of its own, so the palette still holds in
   all three theme states. */

.keyblock{border:1px solid var(--accent);border-left-width:3px;border-radius:12px;
  background:var(--sunk);padding:22px 24px;display:flex;flex-direction:column;gap:14px}
.keyblock .kb-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.keyblock h2{margin:0}
.keyblock ol{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:11px}
@media (max-width:620px){.keyblock{padding:18px 16px}}

/* ---------- the done count beside a heading ---------- */

.meter{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);border:1px solid var(--rule);border-radius:20px;padding:4px 11px;white-space:nowrap}
.meter.all-done{color:var(--done);border-color:var(--done)}
.head-row{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}

/* ---------- the detail toggle ---------- */

code{font-family:var(--mono);font-size:12.5px;background:var(--sunk);padding:1px 5px;border-radius:4px}

/* Preamble on a page that opens on the work. The explanation a reader needs once goes below
   what she came for, behind a summary line small enough to skip and specific enough to decide
   from. The lecture notes page grew this first and kept its own copy; the laboratory guides are
   the second use, so it lives here. */

details.about{border-top:1px solid var(--rule);padding-top:13px}
details.about summary{cursor:pointer;font-family:var(--mono);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);list-style:none;display:flex;align-items:center;gap:9px}
details.about summary::-webkit-details-marker{display:none}
details.about summary::before{content:"";width:0;height:0;border-left:5px solid currentColor;
  border-top:4px solid transparent;border-bottom:4px solid transparent;transition:transform .15s}
details.about[open] summary::before{transform:rotate(90deg)}
details.about summary:hover{color:var(--accent)}
details.about summary:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
details.about .in{display:flex;flex-direction:column;gap:11px;padding:15px 0 4px;font-size:15.5px;
  color:var(--ink-soft);max-width:70ch}
details.about .in b{color:var(--ink)}

/* ---------- a task that is itself the toggle ---------- */

/* The whole card opens. Its summary carries the tick box, the heading, the one-line
   description and the tags, so a closed list reads as headings with a line each, and the
   long specification stays out of sight until it is asked for.
   The tick box calls preventDefault on its own click, which cancels the summary's activation
   behaviour, so marking an item done never opens or closes it. shared/tasks.js does that. */

details.task.fold{display:block;padding:0}
details.task.fold>summary{display:flex;gap:15px;align-items:flex-start;padding:17px 20px;
  cursor:pointer;list-style:none;border-radius:10px}
details.task.fold>summary::-webkit-details-marker{display:none}
details.task.fold>summary::after{content:"";flex:0 0 auto;margin-top:7px;width:0;height:0;
  border-left:5px solid var(--muted);border-top:4px solid transparent;
  border-bottom:4px solid transparent;transition:transform .15s}
details.task.fold[open]>summary::after{transform:rotate(90deg)}
details.task.fold>summary:hover::after{border-left-color:var(--accent)}
details.task.fold>summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
details.task.fold .b{flex:1 1 auto}
details.task.fold>.in{margin:0 20px 0 50px;padding:12px 0 18px;border-top:1px solid var(--rule-soft);
  font-size:14.5px;color:var(--ink-soft);display:flex;flex-direction:column;gap:10px}
details.task.fold>.in b{color:var(--ink)}
details.task.fold>.in ol,details.task.fold>.in ul{padding-left:19px;display:flex;
  flex-direction:column;gap:7px;font-size:14.5px;color:var(--ink-soft)}

/* Two pills on one line: the course an item belongs to, and how far along it is. */
.task .tagrow{display:flex;flex-wrap:wrap;gap:7px;margin-top:3px}
.task .tagrow .tag{margin-top:0}
.tag.who{color:var(--ink-soft);border-color:var(--rule-soft);background:var(--sunk)}

/* One named group inside a task list, with its own count. */
.tgroup{display:flex;flex-direction:column;gap:13px}
.tgroup+.tgroup{margin-top:14px}
.tgroup>p{font-size:15px;color:var(--ink-soft)}

/* ---------- the done section at the foot of a task list ---------- */

/* Ticking an item moves it out of its group and down into here, under a copy of the heading
   it came from, so the list above holds only what is outstanding. shared/tasks.js does the
   moving, driven by data-group on the item and data-done-group on the list it is moved into.
   A group here is hidden while it is empty, and `hidden` needs saying twice because the
   .tgroup rule above would otherwise put its display back. */
.tdone{display:flex;flex-direction:column;gap:13px;margin-top:26px;padding-top:22px;
  border-top:1px solid var(--rule)}
.tdone>p{font-size:15px;color:var(--ink-soft)}
.tdone h4{margin:0;font-family:var(--display);font-weight:600;font-size:16px;
  letter-spacing:-.01em;color:var(--ink-soft)}
.tdone [hidden]{display:none}

/* ---------- the site footer ---------- */

/* Every page in the hub carries the same one, and the columns are always in this order:

     .brand        the course code and one line saying what the site is
     On this page  the sections of the page you are on, as anchors
     This course   every page of this course, the one you are on marked
     Elsewhere     the outbound links that page already had, and the way back to all four

   A page reachable from one spot only, such as the GNG2101 lecture notes, belongs in the
   third column, so the bottom of any page of that course reaches it.

   The grid lays four tracks, because every page in the hub carries four columns. A footer
   that ever drops one leaves the last track empty, and the brand column is the wide one so
   that empty space falls on the right, away from the text the eye starts on. */

.sitefoot{border-top:1px solid var(--rule);background:var(--surface);margin-top:30px}
.sitefoot .in{max-width:900px;margin:0 auto;padding:40px 26px 30px;display:grid;
  grid-template-columns:1.5fr repeat(3,minmax(0,1fr));gap:30px 26px}
.sitefoot .col{display:flex;flex-direction:column;gap:8px;align-items:flex-start;min-width:0}
.sitefoot h2{margin:0 0 2px;font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--muted);font-weight:500}
.sitefoot a{font-family:var(--body);font-size:14px;line-height:1.45;color:var(--ink-soft);
  text-decoration:none;border-bottom:1px solid transparent}
.sitefoot a:hover{color:var(--accent);border-bottom-color:var(--accent)}
.sitefoot a:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:3px}
.sitefoot .brand a{font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}
.sitefoot p{margin:0;font-size:13.5px;line-height:1.5;color:var(--muted);max-width:32ch}
.sitefoot .brand p{font-size:14px}

/* The page you are on, marked the way the top bar marks the current course, in the accent on
   the sunk colour. The negative side margin holds the words on the same left edge as the
   links above and below, so the mark reads as a highlight and never as an indent. */
.sitefoot a[aria-current]{color:var(--accent);background:var(--sunk);border-radius:6px;
  padding:2px 8px;margin:0 -8px}

.sitefoot .colophon{max-width:900px;margin:0 auto;padding:16px 26px 34px;border-top:1px solid var(--rule);
  display:flex;flex-wrap:wrap;gap:6px 28px;font-size:12.5px;color:var(--muted)}

/* ---------- the way back to the umbrella ---------- */

.uplink{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted);text-decoration:none;
  border-bottom:1px solid transparent;align-self:flex-start}
.uplink:hover{color:var(--accent);border-bottom-color:var(--accent)}
.uplink svg{width:14px;height:14px}

/* ---------- lecture notes she writes herself ---------- */

/* shared/notes.js fills a [data-notes] container: the button that adds a lecture, then the
   lectures, newest first. One lecture is one details element carrying two things she wrote,
   a heading in the summary and the notes inside.

   Every toggle is closed on load and which ones were open is never stored, so the page opens
   on the button and a list of headings, with last month's notes out of sight until one of them
   is asked for. */

/* The bar and the list sit in a plain block with no gap of its own, so the button was
   touching the first lecture. 18px is the rhythm the rest of a section uses. */
.lecbar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:18px}
.lecadd{display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:11.5px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--accent);background:var(--surface);
  border:1px solid var(--rule);border-radius:9px;padding:9px 15px;cursor:pointer;
  transition:border-color .15s,background .15s,color .15s}
.lecadd svg{width:14px;height:14px;flex:0 0 auto}
.lecadd:hover{border-color:var(--accent);background:var(--sunk)}
.lecadd:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.leclist{display:flex;flex-direction:column;gap:12px}
.lecnone{font-size:15px;color:var(--muted);max-width:60ch}
.lecnone[hidden]{display:none}

/* scroll-margin so a jump from the bar at the foot of the window leaves the lecture clear of the
   sticky top bar. The same 80px the anchors on a hub page use. */
.lec{background:var(--surface);border:1px solid var(--rule);border-radius:10px;scroll-margin-top:80px}
.lec>summary{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:14px 17px;
  cursor:pointer;list-style:none;border-radius:10px}
.lec>summary::-webkit-details-marker{display:none}
.lec>summary::before{content:"";flex:0 0 auto;width:0;height:0;border-left:5px solid var(--muted);
  border-top:4px solid transparent;border-bottom:4px solid transparent;transition:transform .15s}
.lec[open]>summary::before{transform:rotate(90deg)}
.lec>summary:hover::before{border-left-color:var(--accent)}
.lec>summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}

/* The heading is hers to name, so it is a line she types into. Clicking it places the caret and
   leaves the toggle alone; shared/notes.js cancels the click that would otherwise open the
   lecture. */
.lec .lech{position:relative;flex:1 1 200px;min-width:0;font-family:var(--display);font-weight:600;
  font-size:19px;line-height:1.3;letter-spacing:-.01em;color:var(--ink);cursor:text;outline:none;
  border-radius:4px;padding:1px 3px;margin:-1px -3px}
.lec .lech:focus{box-shadow:0 0 0 2px var(--accent)}
.lec .lech.is-empty::before{content:attr(data-ph);position:absolute;left:3px;top:0;
  font-family:var(--body);font-size:15.5px;font-weight:400;font-style:italic;color:var(--muted);
  pointer-events:none;white-space:nowrap}

/* The size and weight of the pencil in links.js, because it does the same kind of job: a small
   grey control that waits at the end of a row until it is wanted. Three dots are what an overflow
   menu looks like everywhere else, and they carry no verb of their own, so a slip of the mouse
   opens a list she can walk away from. A cross in this spot read as close, and closing a lecture
   is the one thing the summary beside it already does.

   The dots are drawn at twelve pixels and pressed at twenty four: the padding and the matching
   negative margin grow what a finger has to hit without moving anything in the row or changing
   what the eye sees. */
.lec .lecmore{flex:0 0 auto;width:24px;height:24px;padding:6px;margin:-6px;border:0;background:none;
  line-height:0;color:var(--muted);cursor:pointer;transition:color .15s}
.lec .lecmore svg{display:block;width:12px;height:12px}
.lec .lecmore:hover,.lec .lecmore[aria-expanded="true"]{color:var(--accent)}
.lec .lecmore:focus-visible{outline:2px solid var(--accent);outline-offset:-1px;border-radius:7px}
.lec .lecmore[hidden]{display:none}

/* THE MENU IS DRAWN AT THE END OF THE DOCUMENT and placed over the page in page coordinates by
   shared/notes.js. A menu nested inside the lecture it belongs to is cut off by the rounded
   details around it the moment it is taller than the row, and the same happens on a phone, where
   the block reaches the window edge. Page coordinates also mean the menu travels with the lecture
   as the page scrolls.

   One item today. The column and the gap are there so a second and a third arrive without any of
   this being rewritten. */
.lecpop{position:absolute;z-index:65;display:flex;flex-direction:column;gap:2px;min-width:194px;
  max-width:calc(100vw - 16px);padding:5px;background:var(--surface);border:1px solid var(--rule);
  border-radius:9px;box-shadow:var(--shadow-2)}
.lecpop button{display:block;width:100%;text-align:left;font-family:var(--body);font-size:14.5px;
  line-height:1.3;padding:9px 11px;border:0;border-radius:6px;background:none;color:var(--ink-soft);
  cursor:pointer;transition:background .15s,color .15s}
.lecpop button:hover{background:var(--sunk);color:var(--ink)}
/* A plain :focus, because the arrow keys and the opening keystroke both move focus here by script,
   and Chrome withholds :focus-visible from a focus it did not see a key press behind. */
.lecpop button:focus{outline:2px solid var(--accent);outline-offset:-2px;background:var(--sunk)}
.lecpop button.hot{color:var(--hot)}
.lecpop button.hot:hover,.lecpop button.hot:focus{color:var(--hot)}

.lec .lecsure{display:inline-flex;align-items:center;gap:9px;flex-wrap:wrap;margin-left:auto}
.lec .lecsure .q{font-size:13.5px;color:var(--ink-soft)}
.lec .lecsure button{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  padding:4px 10px;border-radius:20px;border:1px solid var(--rule);background:var(--paper);
  color:var(--muted);cursor:pointer;transition:color .15s,border-color .15s}
.lec .lecsure button:hover{color:var(--ink);border-color:var(--muted)}
.lec .lecsure .yes{color:var(--hot);border-color:var(--hot)}
.lec .lecsure .yes:hover{color:var(--hot);border-color:var(--hot);background:var(--sunk)}
.lec .lecsure button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.lec .lecin{padding:2px 17px 17px}

/* ---------- a place she writes ---------- */

/* Recessed, because a raised surface reads as something presented to be read and a well reads
   as somewhere to put things in. The left edge holds the rule colour while the block is empty
   and the course accent once it holds something, so a page of blocks says at a glance where
   she has got to. The text inside keeps the page's own body type. */

.nbwrap{display:flex;flex-direction:column}
.nbpad{position:relative;padding:14px 16px;background:var(--sunk);border:1px solid var(--rule);
  border-left:3px solid var(--rule);border-radius:8px;box-shadow:inset 0 1px 0 rgba(0,0,0,.06);
  transition:border-color .15s}
.nbwrap.has .nbpad{border-left-color:var(--accent)}
.nbwrap:focus-within .nbpad{border-color:var(--accent)}

/* 16px on 1.62 is what the philosophy notes use. Without it the editor inherited the page
   body at 17.5px on 28px, which read as a different, looser text in the same place. */
.nb{position:relative;font-size:16px;line-height:1.62;min-height:190px;outline:none;color:var(--ink)}
.nb.is-empty::before{content:attr(data-ph);position:absolute;left:0;top:0;color:var(--muted);
  font-style:italic;pointer-events:none}
.nb p{margin:0 0 9px;max-width:none}
.nb p:last-child{margin-bottom:0}
.nb ul,.nb ol{margin:6px 0 9px;padding-left:22px;display:block;max-width:none;color:inherit}
.nb li{margin-bottom:4px}
.nb b,.nb strong{font-weight:600}
.nb h3,.nb h4,.nb h5{margin:14px 0 6px;font-family:var(--display);font-weight:600;line-height:1.25;
  color:var(--ink)}
.nb h3{font-size:21px}
.nb h4{font-size:19px}
.nb h5{font-size:17px}
.nb>:first-child{margin-top:0}
.nb hr{border:0;border-top:1px solid var(--rule);margin:14px 0}
.nb blockquote{margin:9px 0;padding-left:13px;border-left:2px solid var(--rule);color:var(--ink-soft)}

/* The four colours the editor writes. c-n is normal text spelled out, for a run inside a
   coloured span where dropping the class would recolour words she meant to keep. */
.c-y{color:var(--c-y)}
.c-p{color:var(--c-p)}
.c-m{color:var(--muted)}
.c-g{color:var(--accent)}
.c-n{color:var(--ink)}

/* The bar that appears over a selection inside a note. */
#nb-bar{position:absolute;z-index:60;display:flex;gap:2px;padding:3px;background:var(--surface);
  border:1px solid var(--rule);border-radius:6px;box-shadow:var(--shadow-1)}
#nb-bar[hidden]{display:none!important}
#nb-bar button{min-width:24px;height:22px;border:0;border-radius:3px;background:none;cursor:pointer;
  color:var(--ink-soft);font-family:var(--display);font-size:14px;padding:0 5px}
#nb-bar button:hover{background:var(--sunk);color:var(--ink)}
#nb-bar button.i{font-style:italic}
#nb-bar button.l{font-family:var(--mono);font-size:11px}
#nb-bar .sep{width:1px;background:var(--rule);margin:3px 2px}
#nb-bar button.sw{width:18px;min-width:18px;height:18px;border-radius:3px;align-self:center;
  border:1px solid var(--rule);font-size:0}
#nb-bar button.sw.y{background:var(--c-y)}
#nb-bar button.sw.p{background:var(--c-p)}
#nb-bar button.sw.g{background:var(--accent)}
#nb-bar button.sw.m{background:var(--muted)}
#nb-bar button.sw.x{background:none;font-size:12px;color:var(--muted);border-color:transparent}

/* Whether anything was saved. A browser refusing to store is the one thing that has to be said
   out loud, because staying silent is how somebody loses an evening believing it was kept. */
#save{position:fixed;right:16px;bottom:16px;z-index:70;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.04em;padding:6px 10px;border-radius:5px;background:var(--surface);
  border:1px solid var(--rule);color:var(--muted);opacity:0;transition:opacity .25s;pointer-events:none}
#save.on{opacity:1}
#save.bad{color:#9B2C2C;border-color:#9B2C2C;opacity:1;pointer-events:auto}
:root[data-theme="dark"] #save.bad{color:#F09B9B;border-color:#F09B9B}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) #save.bad{color:#F09B9B;border-color:#F09B9B}}

/* ---------- the bar pinned to the bottom of the window ---------- */

/* A footer that behaves like the top bar: it holds its place as the page scrolls, so the few
   controls a long page keeps needing are one press away from the middle of it. This is the bar
   the philosophy reading guide carries, at the same height and weight, so a page reached from
   either side of the hub ends in the same row.

   A page opts in with `has-dock` on <body> and one .dock block written at the end, and
   shared/dock.js wires whichever controls it finds. The markup is documented in that file.

   --dock-h IS THE WHOLE BAR: the row of controls, the progress line above it and the rule above
   that. Three rules read it. The row is the token less those three pixels, the document is given
   that much more height at its end so its last line clears the bar, and the saved pill is lifted
   by that much so it stands above the bar and stays readable.

   Z INDEX 55 puts the bar over the page and under everything a press opens. The top bar is 50,
   the format bar over a selection is 60, the three dots menu on a lecture is 65, the list this
   bar opens is 66 and the saved pill is 70. A menu opened on the last lecture on the page draws
   over this bar. */

:root{--dock-h:48px}

.dock{position:fixed;left:0;right:0;bottom:0;z-index:55;background:var(--paper);
  border-top:1px solid var(--rule)}
/* How far through the page this is, drawn along the bar's top edge. */
.dock .prog{height:2px;width:0;background:var(--accent);transition:width .1s linear}
.dock .in{max-width:900px;margin:0 auto;padding:0 20px;height:calc(var(--dock-h) - 3px);
  display:flex;align-items:center;gap:2px}
.dock button,.dock a{display:flex;align-items:center;gap:7px;background:none;border:0;
  padding:8px 10px;border-radius:5px;cursor:pointer;text-decoration:none;
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);transition:color .15s,background .15s}
.dock button:hover,.dock a:hover{color:var(--ink);background:var(--surface)}
.dock button:focus-visible,.dock a:focus-visible{outline:2px solid var(--accent);outline-offset:-1px}
.dock button[aria-expanded="true"]{color:var(--ink);background:var(--surface)}
.dock svg{width:13px;height:14px;flex:none}
.dock .end{margin-left:auto}
.dock .n{font-family:var(--mono);font-size:10px;line-height:1.6;background:var(--sunk);
  color:var(--ink-soft);border-radius:9px;padding:0 6px;min-width:18px;text-align:center}
.dock .n:empty{display:none}
/* Below 620px the icons carry the row on their own. Every control keeps an aria-label written
   into the page, so dropping the words takes nothing away from a screen reader. */
@media (max-width:620px){.dock .in{padding:0 8px}.dock .lab{display:none}}

body.has-dock{padding-bottom:var(--dock-h)}
body.has-dock #save{bottom:calc(var(--dock-h) + 14px)}

/* The list the bar opens, built at the end of the document and placed in window coordinates by
   shared/dock.js, because the bar it hangs off is fixed to the window too. */
.dockpop{position:fixed;z-index:66;display:flex;flex-direction:column;gap:2px;min-width:236px;
  max-width:calc(100vw - 16px);max-height:min(48vh,340px);overflow-y:auto;padding:5px;
  background:var(--surface);border:1px solid var(--rule);border-radius:9px;box-shadow:var(--shadow-2)}
.dockpop button{display:flex;align-items:baseline;gap:9px;width:100%;text-align:left;
  font-family:var(--body);font-size:14.5px;line-height:1.35;letter-spacing:0;text-transform:none;
  padding:9px 11px;border:0;border-radius:6px;background:none;color:var(--ink-soft);cursor:pointer}
.dockpop button:hover{background:var(--sunk);color:var(--ink)}
/* A plain :focus, because the arrow keys and the opening keystroke both move focus here by script,
   and Chrome withholds :focus-visible from a focus it did not see a key press behind. */
.dockpop button:focus{outline:2px solid var(--accent);outline-offset:-2px;background:var(--sunk)}
.dockpop button .i{flex:0 0 auto;font-family:var(--mono);font-size:10.5px;color:var(--muted)}
.dockpop button .t{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dockpop button .t.none{font-style:italic;color:var(--muted)}
.dockpop .empty{margin:0;padding:9px 11px;font-size:14px;color:var(--muted);max-width:30ch}

/* The bar and its list are screen furniture, so both leave the paper, and the height kept clear
   for the bar goes with them. */
@media print{
  .dock,.dockpop{display:none!important}
  body.has-dock{padding-bottom:0}
}

@media (max-width:620px){
  .lec>summary{padding:13px 14px;gap:10px}
  .lec .lecin{padding:2px 14px 14px}
  .lec .lecsure{margin-left:0;flex-basis:100%}
  /* The question takes its own line so the two answers stay together under it. */
  .lec .lecsure .q{flex:1 0 100%}
  .nbpad{padding:13px 14px}
}

/* ---------- small screens and reduced motion ---------- */

/* Four columns need more width than three did, so the footer folds in two steps: to a pair of
   columns while there is still room for two, and to a single column on a phone. */
@media (max-width:860px){
  .sitefoot .in{grid-template-columns:repeat(2,minmax(0,1fr));gap:28px}
}
@media (max-width:560px){
  .sitefoot .in{grid-template-columns:1fr;gap:24px;padding:30px 16px 22px}
  .sitefoot .colophon{padding:14px 16px 26px;flex-direction:column}
}
@media (max-width:620px){
  .card{padding:24px 22px 22px}
  .card .ghost{font-size:82px;right:12px}
  .soon{padding:20px 22px}
  .task{padding:15px 16px;gap:12px}
  details.task.fold>summary{padding:15px 16px;gap:12px}
  details.task.fold>.in{margin:0 16px;padding-bottom:16px}
}
@media (prefers-reduced-motion: reduce){*{transition:none!important}.card:hover{transform:none}}

/* rail
   The assigned problems on an assignment page, hanging beside the scanned source pages so the
   list of what to do stays on screen while the reader scrolls through them. Styled after
   .topnav, mono type on a translucent ground with the same blur, so the two read as one family.
   Below 1100px it stops hanging and becomes an ordinary block above the content.

   The grid needs both classes, .wrap.railed. The assignment pages carry their own <style>
   block after this file, so a single class would lose the cascade to it. */
.wrap.railed{display:grid;grid-template-columns:minmax(0,1fr);gap:30px;align-content:start}
@media (min-width:1100px){
  .wrap.railed{grid-template-columns:250px minmax(0,1fr);gap:20px 46px;max-width:1180px;align-items:start}
  .wrap.railed>header,.wrap.railed>.back{grid-column:1/-1}
  .rail{position:sticky;top:64px;max-height:calc(100vh - 88px);overflow-y:auto}
}
.rail{background:var(--surface);background:color-mix(in srgb,var(--surface) 88%,transparent);
  backdrop-filter:saturate(1.4) blur(10px);-webkit-backdrop-filter:saturate(1.4) blur(10px);
  border:1px solid var(--rule);border-radius:12px;padding:15px 15px 13px;
  display:flex;flex-direction:column;gap:11px}
.rail .rail-head{display:flex;flex-direction:column;gap:3px}
.rail h2{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);font-weight:500;margin:0}
.rail .prog{font-family:var(--mono);font-size:11px;letter-spacing:.04em;color:var(--muted)}
.rail .prog.all-done{color:var(--done)}
.rail ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px}
.rail-item{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  gap:10px;padding:7px 7px;border-radius:8px;transition:background .15s}
.rail-item:hover{background:var(--sunk)}
.rail-item .box{width:14px;height:14px;border:1.6px solid var(--muted);border-radius:3.5px;
  cursor:pointer;transition:background .15s,border-color .15s}
.rail-item .box:hover{border-color:var(--accent)}
.rail-item .box:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.rail-item .box[aria-checked="true"]{background:var(--done);border-color:var(--done);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size:contain}
.rail-item .h{display:flex;align-items:baseline;gap:8px;min-width:0}
.rail-item .h a{font-family:var(--mono);font-size:13px;font-weight:500;color:var(--accent);
  text-decoration:none;border-bottom:0;white-space:nowrap}
.rail-item .h a:hover{text-decoration:underline}
.rail-item .h a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
.rail-item .h em{font-family:var(--mono);font-size:11px;font-style:normal;color:var(--ink-soft);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rail-item .pg{font-family:var(--mono);font-size:11px;color:var(--muted);white-space:nowrap}
.rail-item.done .h a,.rail-item.done .h em{color:var(--muted);text-decoration:line-through}
.rail .foot{font-size:12px;line-height:1.45;color:var(--muted);
  border-top:1px solid var(--rule);padding-top:9px}
@media print{.rail{position:static;max-height:none;break-inside:avoid;backdrop-filter:none}}
@media (prefers-reduced-motion:reduce){.rail-item,.rail-item .box{transition:none}}
