/* One stylesheet for every page.
 *
 * There were two, and the second opened by admitting it: "Duplicated in prose.css, which is what
 * a site with no build step costs." That cost was payable while the tool was one page and the
 * prose was two. It is five pages now, and a colour that has to be changed in two files is a
 * colour that will eventually be two colours. So: one file, cached once, used by all of them.
 *
 * Order: tokens, the page frame and masthead, then the tool's own furniture, then the prose
 * pages' typography, then the two media queries everything shares.
 */
  :root{
    --paper:#f3efe4; --paper-2:#ece6d6; --card:#fbf9f3;
    --ink:#26221a; --ink-soft:#6b6353; --line:#d8cfba;
    --green:#5b7d3a; --green-soft:#dde7cb;
    --orange:#c66a25; --orange-soft:#f3ddc6;
    --char:#3a3631; --char-soft:#d7d2c8;
    --slate:#6a7080; --slate-soft:#cdd2dc;
    --accent:#7a2e1e; --good:#3b6d3b; --hi:#1d9e75;
    /* The quietest of the three text tiers, darkened from #9a9080. At 11px it needs 4.5:1 to be
       readable and it had 2.7:1 on paper, which is the kind of grey that looks like restraint on
       a designer's monitor and like nothing at all in a library at arm's length. This clears 4.5
       against all three surfaces (paper 4.93, card 5.38, paper-2 4.54). It sits closer to
       --ink-soft than it used to, which is the honest cost: three visibly distinct greys cannot
       all pass AA on a light background, so the tier that had to give was the decorative one. */
    --ink-faint:#6f6656; --r:12px;
    /* The fallbacks are chosen to break lines in the same places as the real fonts, not because
       anyone would pick them for looks.

       Loading the web fonts without blocking the first paint means the page is laid out twice:
       once in whatever is already on the machine, then again when Fraunces and Spline Sans Mono
       land. If the two layouts wrap text differently, everything below the rewrapped line jumps,
       and on this page that meant the 615px shelf map sliding down for a layout shift of 0.37 on
       desktop, which is well into the range a reader notices and swears at.

       Measured at 100px over a 40-character sample: Spline Sans Mono advances 0.600em per
       character and Courier New advances exactly the same, while ui-monospace resolves to 0.522em
       on this machine and Consolas to 0.550em. So Courier New goes first: it is the one stand-in
       that puts every mono line break exactly where the real font will put it. Fraunces is
       narrower than any installed serif, so its stand-in is scaled to match instead, defined
       below as `disp-fallback`. Line heights are unitless throughout, so they scale with the
       font size rather than with the font's own metrics and need no matching. */
    --mono:'Spline Sans Mono', 'Courier New', ui-monospace, monospace;
    --disp:'Fraunces', 'disp-fallback', Georgia, serif;
  }
  /* Times New Roman and its metric clones are 8% wider than Fraunces over the same text, so they
     are asked to render 8% smaller while standing in for it. Unsupported anywhere `size-adjust`
     is missing, where this rule is skipped and Georgia takes over as before. */
  @font-face{
    font-family:'disp-fallback';
    src:local('Times New Roman'), local('Tinos'), local('Liberation Serif'), local('Times');
    size-adjust:92%;
    ascent-override:90%;
    descent-override:22%;
  }
  *{box-sizing:border-box}
  body{margin:0; background:var(--paper); color:var(--ink); font-family:var(--mono); font-size:13px; line-height:1.5; -webkit-font-smoothing:antialiased;
    background-image:radial-gradient(var(--paper-2) 0.5px, transparent 0.5px); background-size:14px 14px;}
  .wrap{max-width:1060px; margin:0 auto; padding:30px 22px 80px}
  /* The mark is drawn inline rather than fetched: it is smaller than the request that would
     collect it, and it inherits --ink and --accent instead of hardcoding them twice. */
  .brand{display:flex; align-items:center; gap:12px; text-decoration:none; color:var(--ink)}
  /* The wordmark only. The tagline under it keeps its own quieter colour, and the mark keeps its
     accent spine, so the hover reads as one word lighting up rather than the whole block moving.
     The wordmark used to be an <h1> on the tool and a <b> on the prose pages, which meant the
     same bar exposed two different heading structures depending on where you stood. It is a <b>
     everywhere now, and the <h1> belongs to the page rather than to the site. */
  a.brand:focus-visible{outline:none; border-radius:6px; box-shadow:0 0 0 3px var(--orange-soft)}
  .brand .mark{flex:none; width:38px; height:38px; display:block}
  .brand .mark .stack{fill:var(--ink)}
  .brand .mark .marked{fill:var(--accent)}
  .site-nav{display:flex; gap:6px; flex-wrap:wrap}
  .site-nav a{font-family:var(--mono); font-size:11px; text-transform:uppercase; letter-spacing:.09em;
    text-decoration:none; color:var(--ink-soft); background:var(--card); border:1px solid var(--line);
    border-radius:99px; padding:7px 13px; min-height:32px; line-height:18px}
  .site-nav a:hover{border-color:var(--ink-soft); color:var(--ink)}
  .site-nav a:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .site-nav a[aria-current="page"]{background:var(--ink); border-color:var(--ink); color:var(--paper)}

  /* The library picker is page context, not a search option, so it reads as a line above the
     box rather than as another control inside it. */
  .whereami{display:flex; gap:9px; align-items:center; flex-wrap:wrap; margin:18px 0 0; padding:0 2px}
  .whereami label{font-size:11px; letter-spacing:0.08em; text-transform:uppercase; color:var(--ink-soft)}
  .whereami select{font:inherit; font-size:13px; font-weight:500; padding:7px 10px; border:1px solid var(--line);
    border-radius:8px; background:var(--card); color:var(--ink); max-width:100%}
  .whereami select:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .whereami-note{font-size:12px; color:var(--ink-faint)}
  .lookup{display:flex; gap:8px; align-items:center; margin:10px 0 10px; padding:12px 14px; background:var(--card); border:1px solid var(--line); border-radius:var(--r); flex-wrap:wrap}
  .lookup label{font-size:11px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:1px}
  .lookup input{flex:1; font-family:var(--mono); font-size:15px; padding:11px 13px; border:1px solid var(--line); border-radius:8px; background:var(--paper); color:var(--ink); min-width:180px}
  .lookup input:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .btn{font-family:var(--mono); font-size:11px; font-weight:600; padding:11px 16px; background:var(--ink); color:var(--paper); border:1px solid var(--ink); border-radius:8px; cursor:pointer; text-transform:uppercase; letter-spacing:.8px}
  .btn.ghost{background:transparent; color:var(--ink-soft); border-color:var(--line)}
  .btn:hover{opacity:.88}

  .result{margin:12px 0 0; min-height:20px}
  .hit{background:var(--green-soft); border:1px solid #bcce9e; border-radius:10px; padding:11px 14px; margin-bottom:7px}
  .hit .loc{font-size:13px; font-weight:600; color:var(--ink)}
  .hit .rng{font-size:12px; color:var(--ink-soft); margin-top:4px; letter-spacing:.2px}
  .miss{font-size:13px; color:var(--accent); padding:8px 2px}
  .examples{font-size:12px; color:var(--ink-soft); margin-top:8px}
  /* These were <b> elements with a click handler: they looked like controls, behaved like
     controls, and could not be reached with a keyboard or announced as anything. */
  .examples .ex{font:inherit; font-weight:500; color:var(--ink); background:none; border:0; padding:0;
    cursor:pointer; border-bottom:1px dotted var(--ink-faint)}
  .examples .ex:hover{color:var(--accent); border-color:var(--accent)}
  .examples .ex:focus-visible{outline:none; border-radius:3px; box-shadow:0 0 0 3px var(--orange-soft)}

  /* Sits above the levels bar, so the gap below it is the one that closes onto the map. */
  .sect{display:flex; gap:6px; align-items:center; margin:22px 2px 9px; flex-wrap:wrap}
  .sect-label{font-size:11px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:1px; margin-right:4px}
  .pill{font-family:var(--mono); font-size:11px; padding:6px 13px; background:var(--card); color:var(--ink-soft); border:1px solid var(--line); border-radius:99px; cursor:pointer; transition:.15s}
  .pill:hover{border-color:var(--ink-soft); color:var(--ink)}
  .pill.active{background:var(--ink); color:var(--paper); border-color:var(--ink)}

  .levels{display:flex; flex-wrap:wrap; gap:5px; align-items:center; margin:0 0 8px}
  .lvl-total{margin-left:auto; padding-left:12px; font-size:12px; color:var(--ink-faint); line-height:1.5; text-align:right}
  .lvl-total .n{color:var(--accent); font-size:13px}
  .lvl{font-family:var(--mono); font-size:13px; font-weight:500; min-width:48px; padding:7px 5px 6px; text-align:center; background:var(--card); border:1px solid var(--line); border-radius:8px; cursor:pointer; color:var(--ink-soft)}
  .lvl:hover{border-color:var(--ink-soft); color:var(--ink)}
  .lvl:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .lvl.active{background:var(--ink); color:var(--paper); border-color:var(--ink); font-weight:600}
  .lvl.empty{opacity:.45}
  .lvl.special{opacity:1; border-style:dashed; border-color:var(--ink-soft)}
  .lvl.special small{color:var(--accent)}
  .lvl small{display:block; font-size:9.5px; font-weight:400; margin-top:3px; letter-spacing:.2px; opacity:.9}

  .stage{margin-top:6px; background:var(--card); border:1px solid var(--line); border-radius:var(--r); padding:8px 12px 12px}
  svg{display:block; width:100%; height:auto}
  .shelf{cursor:pointer}
  .shelf:focus{outline:none}
  .shelf:focus-visible .frame{stroke:var(--accent); stroke-width:2.6}
  .shelf:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
  .shelf .frame{fill:none; stroke:var(--ink); stroke-width:1.4}
  .shelf.absent{cursor:default}
  .shelf.absent .frame{stroke:var(--line); stroke-dasharray:3 4; stroke-width:1}
  .shelf.sel .frame{stroke:var(--accent); stroke-width:2.6}
  .shelf.flash .frame{stroke:var(--hi); stroke-width:2.6}
  .idx{font-family:var(--mono); font-size:11px; fill:var(--ink-soft)}
  .face{font-family:var(--mono); font-size:8px; fill:var(--ink-faint)}

  .detail{margin-top:14px; background:var(--card); border:1px solid var(--line); border-radius:var(--r); padding:16px 20px}
  .detail.empty{color:var(--ink-soft); text-align:center; padding:22px; font-size:13px}
  .detail h2{font-family:var(--disp); font-size:18px; font-weight:600; margin:0 0 3px}
  .detail .meta{font-size:11px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.8px; margin-bottom:8px}
  .detail .face-row{display:flex; gap:12px; padding:8px 0; border-top:1px solid var(--line); font-size:13px}
  .detail .face-row .fl{min-width:64px; color:var(--ink-soft); text-transform:uppercase; font-size:11px; letter-spacing:.5px; padding-top:1px}
  .detail .face-row .rg{font-weight:500}
  /* 12px, not 11px. The footer is the longest prose on the page — 85% of the document's text by
     Lighthouse's count — and it was the one block set below the size a phone can comfortably
     read. Everything else here is a label; this is meant to be read. */
  footer{margin-top:28px; padding-top:16px; border-top:1px solid var(--line); font-size:12px; color:var(--ink-soft); line-height:1.75; max-width:760px}
  footer a{color:var(--accent)}
  footer .by{display:block; margin-top:10px; color:var(--ink-faint)}
  footer .by a{color:var(--ink-soft)}
  .legend{display:flex; gap:14px; flex-wrap:wrap; margin-top:12px; padding-left:2px; font-size:12px; color:var(--ink-soft)}
  .legend span{display:inline-flex; align-items:center; gap:6px}
  .sw{width:11px; height:11px; border-radius:3px; display:inline-block; border:1px solid rgba(0,0,0,.12)}

  /* ── collapsible panels (route planner, catalog search) ── */
  .route,.cat{margin:18px 0 6px; background:var(--card); border:1px solid var(--line); border-radius:var(--r); overflow:hidden}
  .route-head,.cat-head{display:flex; align-items:center; justify-content:space-between; gap:10px; padding:12px 16px; cursor:pointer}
  .route-head h2,.cat-head h2{font-family:var(--disp); font-size:17px; font-weight:600; margin:0; display:flex; align-items:baseline; gap:9px; flex-wrap:wrap}
  .h2-sub{font-family:var(--mono); font-size:12px; font-weight:400; color:var(--ink-faint); letter-spacing:0.03em}
  .route-head .tag,.cat-head .tag{font-size:9.5px; letter-spacing:1.2px; text-transform:uppercase; color:var(--accent); background:var(--orange-soft); padding:2px 7px; border-radius:99px; margin-left:9px}
  .route-body,.cat-body{padding:0 16px 16px; border-top:1px solid var(--line)}
  /* A panel that is the whole page has no header to be separated from, so the rule that would
     divide them is a line hanging off the top of nothing. */
  .cat.open{margin-top:14px}
  .cat.open>.cat-body{border-top:0; padding-top:16px}

  /* ── article access (OpenURL resolver) ── */
  .art-lookup{margin-top:14px}
  .prov .pick{margin-top:8px}
  .prov-note{font-size:11.5px; color:var(--ink-soft); margin-top:11px; padding-left:2px; line-height:1.8}
  .prov-note .chip{margin:0 1px}
  .art-ex{font-size:12px; color:var(--ink-soft); margin:8px 2px 0; display:flex; gap:7px; align-items:center; flex-wrap:wrap}
  .art-ftog{margin-left:auto}
  .art-ftog[aria-expanded="true"]{background:var(--ink); color:var(--paper); border-color:var(--ink)}
  .art-filters{margin:10px 0 0; padding:11px 13px 13px; background:var(--card); border:1px solid var(--line); border-radius:var(--r)}
  .af-row{display:flex; gap:14px; align-items:flex-end; flex-wrap:wrap}
  .af-row + .af-row{margin-top:11px; padding-top:11px; border-top:1px dashed var(--line)}
  .af{display:flex; flex-direction:column; gap:4px; font-size:10.5px; letter-spacing:.07em;
    text-transform:uppercase; color:var(--ink-soft)}
  .af select,.af input{font:inherit; font-family:var(--mono); font-size:12.5px; letter-spacing:0;
    text-transform:none; padding:6px 8px; border:1px solid var(--line); border-radius:7px;
    background:var(--paper); color:var(--ink)}
  .af input{width:64px}
  .af select:focus-visible,.af input:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .af-years{display:flex; gap:8px; align-items:flex-end}
  .af-quick{display:flex; gap:5px; align-items:center; flex-wrap:wrap}
  .af-quick .pill{padding:5px 11px}
  .af-check{display:flex; gap:6px; align-items:center; font-size:12px; color:var(--ink); cursor:pointer}
  .af-check input{accent-color:var(--accent); width:15px; height:15px; margin:0}
  /* A filter set from a result rather than from a control needs to be visible somewhere, or the
     next search narrows for a reason the reader cannot see. */
  .af-jt{font-size:11.5px; color:var(--ink-soft); background:var(--orange-soft); border:1px solid var(--line);
    border-radius:99px; padding:4px 6px 4px 11px; display:inline-flex; gap:6px; align-items:center}
  .af-jt b{color:var(--ink); font-weight:500}
  /* `display` on a class outranks the `hidden` attribute's UA rule, so an empty "Journal: ×"
     chip sat in the row whenever no journal was set. Said again at higher specificity. */
  .af-jt[hidden]{display:none}
  .af-x{font:inherit; font-size:14px; line-height:1; padding:0 5px; color:var(--ink-soft); background:none;
    border:none; cursor:pointer; border-radius:99px}
  .af-x:hover{color:var(--accent)}
  .af-clear{margin-left:auto}
  /* The journal is a filter you can apply, so it looks like the other soft controls on the page
     rather than like the citation text it sits inside. */
  .art-jt{font:inherit; color:inherit; background:none; border:none; padding:0; cursor:pointer;
    border-bottom:1px dotted var(--ink-faint)}
  .art-jt:hover{color:var(--accent); border-color:var(--accent)}
  @media (max-width:560px){
    .af-row{gap:10px}
    .af-clear{margin-left:0}
    .art-ftog{margin-left:0}
  }
  .prov{border:1px solid var(--line); border-radius:9px; padding:11px 13px; margin-top:9px; background:var(--paper)}
  .prov-h{display:flex; align-items:baseline; gap:9px; flex-wrap:wrap}
  .prov-n{font-weight:600; font-size:13.5px}
  .prov-i{font-size:11px; color:var(--ink-soft)}
  .prov-c{font-size:12px; color:var(--ink-soft); margin-top:4px; line-height:1.6}
  .prov a.go{display:inline-block; margin-top:8px; font-size:12px; color:var(--accent); text-decoration:none;
    border:1px solid var(--line); border-radius:7px; padding:6px 11px; min-height:34px; line-height:20px}
  .prov a.go:hover{background:var(--orange-soft)}
  .prov a.go:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .chip.free{background:var(--green-soft); color:var(--good)}

  /* An article card is a link first. The title carries the click, the provider buttons are
     there for the reader who wants a particular one, and nothing needs a round trip. */
  a.prov-n{color:var(--ink); text-decoration:none; border-bottom:1px solid var(--line)}
  a.prov-n:hover{color:var(--accent); border-bottom-color:var(--accent)}
  a.prov-n:focus-visible{outline:none; color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft); border-radius:3px}
  /* Results are a list, so they are drawn as one. Ten bordered, filled cards each holding two
     chips and up to eight buttons put a box around every line of text on the page and left the
     reader nothing to scan down; hairlines and one action per row do the same work quietly. */
  .art-list{margin-top:12px; border-top:1px solid var(--line)}
  .hit-row{padding:12px 6px 13px; border-bottom:1px solid var(--line); transition:background .15s}
  .hit-row:hover{background:var(--card)}
  .hr-top{display:flex; gap:10px; align-items:baseline; justify-content:space-between}
  .hr-t{font-size:13.5px; font-weight:600; line-height:1.45; color:var(--ink); text-decoration:none;
    border-bottom:1px solid transparent}
  a.hr-t:hover{color:var(--accent); border-color:var(--accent)}
  a.hr-t:focus-visible{outline:none; color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .hr-top .chip{flex:none}
  .hr-m{font-size:11.5px; color:var(--ink-soft); margin-top:5px; line-height:1.55}
  .hr-etal{color:var(--ink-faint)}
  .hr-a{display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:10px}
  /* One primary action per row, sized for a thumb. Ink by default; green only when the link
     behind it opens for anybody, so the colour keeps meaning something. */
  .hr-go{font-family:var(--mono); font-size:11px; font-weight:600; text-transform:uppercase;
    letter-spacing:.8px; text-decoration:none; padding:8px 14px; min-height:34px; line-height:18px;
    border:1px solid var(--ink); border-radius:8px; background:var(--ink); color:var(--paper)}
  .hr-go:hover{opacity:.88}
  .hr-go:focus-visible{outline:none; box-shadow:0 0 0 3px var(--orange-soft)}
  .hr-go.free{background:var(--good); border-color:var(--good)}
  .hr-via{font-size:12px; color:var(--ink-faint)}
  .hr-more{font-size:12px; margin-top:7px}
  /* No underline at rest: ten of these down a page drew ten dotted rules that read as dividers
     between rows that already have one. The caret carries the affordance. */
  .hr-more summary{cursor:pointer; color:var(--ink-soft); list-style:none; padding:6px 2px;
    display:inline-block; border-bottom:1px solid transparent}
  .hr-more summary:hover{border-bottom-style:dotted}
  .hr-more summary::-webkit-details-marker{display:none}
  .hr-more summary::after{content:' \25b8'}
  .hr-more[open] summary::after{content:' \25be'}
  .hr-more summary:hover{color:var(--accent); border-color:var(--accent)}
  .hr-more summary:focus-visible{outline:none; color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .hr-more[hidden]{display:none}
  /* `display` on a closed `<details>`'s content beats the UA rule that hides it, so setting
     `display:flex` here put every provider pill back on the page with the disclosure shut —
     the exact clutter it exists to fold away. The flex row is only turned on when open. */
  .hr-list{display:none; gap:6px; flex-wrap:wrap; padding:9px 0 3px}
  .hr-more[open] .hr-list{display:flex}
  /* Under the list, not floating beside it: this is the end of the results, and saying how many of
     how many are on screen is the other half of the offer. */
  .art-more{display:flex; gap:12px; align-items:center; flex-wrap:wrap; margin-top:14px}
  .art-more .btn{padding:9px 15px}
  .art-more-n{font-size:12px; color:var(--ink-faint)}
  @media (max-width:560px){
    .hr-top{flex-direction:column; gap:5px}
  }
  /* The secondary ways in, inside a row's disclosure. The identifier lookup lists providers as
     its whole answer and styles them as `.prov` cards; these are the same links demoted. */
  .hr-list a.at{display:inline-block; font-size:11.5px; color:var(--accent); background:var(--card); text-decoration:none;
    border:1px solid var(--line); border-radius:99px; padding:6px 11px; min-height:32px; line-height:19px}
  .hr-list a.at:hover{background:var(--orange-soft)}
  .hr-list a.at:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .hr-list a.at.free{border-color:#bcce9e; background:var(--green-soft); color:var(--good)}
  .hr-list a.at.free:hover{border-color:var(--green)}
  /* The catalogue record is somewhere to go, not somewhere to read: same pill, quieter ink. */
  .hr-list a.at.rec{color:var(--ink-soft)}
  .hr-list a.at.rec:hover{color:var(--accent)}

  /* ── hours ── */
  .hr-when{display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:14px; font-size:11.5px; color:var(--ink-soft)}
  .hr-when input[type=date]{font-family:var(--mono); font-size:12px; color:var(--ink); background:var(--card);
    border:1px solid var(--line); border-radius:8px; padding:6px 9px; min-height:34px}
  .hr-when input[type=date]:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .hr-when .cat-example{margin-top:0}
  .hr-wk{display:inline-flex; gap:4px; margin-left:auto}
  .hr-when input[type=date]:disabled{opacity:.5}
  .hr-days{display:flex; gap:5px; flex-wrap:wrap; margin:10px 0 4px}
  .hr-days .pill{font-size:12px}
  .hr-d{color:var(--ink-faint)}
  .hr-days .pill.active .hr-d{color:inherit; opacity:.8}
  .hr-today{font-size:9px; letter-spacing:.6px; text-transform:uppercase; color:var(--accent)}
  .hr-days .pill.active .hr-today{color:var(--orange-soft)}
  .hr-lib{border-top:1px solid var(--line); padding:10px 2px}
  .hr-lib:first-child{border-top:0}
  .hr-row{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap}
  .hr-n{font-weight:600; font-size:13.5px; flex:1 1 auto}
  .hr-t{font-size:12.5px; color:var(--ink-soft)}
  /* Status is a dot plus a word: colour alone must never carry the meaning. */
  .hr-s{display:inline-flex; align-items:center; gap:6px; font-size:11px; text-transform:uppercase; letter-spacing:.6px}
  .hr-s i{width:8px; height:8px; border-radius:99px; display:inline-block; background:var(--ink-faint)}
  .hr-s.open{color:var(--good)}   .hr-s.open i{background:var(--good)}
  .hr-s.shut{color:var(--accent)} .hr-s.shut i{background:var(--accent)}
  .hr-sub{margin:6px 0 0 12px; padding-left:10px; border-left:2px solid var(--line)}
  .hr-sub .hr-row{padding:3px 0}
  .hr-sub .hr-n{font-weight:400; font-size:12.5px; color:var(--ink-soft)}
  .skel{height:13px; border-radius:4px; background:var(--paper-2); animation:pulse 1.3s ease-in-out infinite}
  @keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}
  @media (prefers-reduced-motion: reduce){ .skel{animation:none} }
  .route-hint,.cat-hint{font-size:12px; color:var(--ink-soft); line-height:1.65; margin:13px 0}
  .route-hint b,.cat-hint b{color:var(--ink)}
  .drop{display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:16px; border:1.5px dashed var(--line); border-radius:10px; background:var(--paper); transition:.15s}
  .drop.over{border-color:var(--accent); background:var(--orange-soft)}
  .drop-hint{font-size:11px; color:var(--ink-soft)}
  .ocr-status{font-size:12px; color:var(--ink-soft); min-height:18px; margin:9px 2px 0}
  .ocr-status.err{color:var(--accent)}
  .thumbs{display:flex; flex-wrap:wrap; gap:8px; margin:8px 0 0}
  .thumbs img{width:50px; height:50px; object-fit:cover; border-radius:6px; border:1px solid var(--line)}
  .cn-label{display:block; font-size:11px; text-transform:uppercase; letter-spacing:1px; color:var(--ink-soft); margin:14px 0 5px}
  #cnList{width:100%; font-family:var(--mono); font-size:14px; padding:10px 12px; border:1px solid var(--line); border-radius:8px; background:var(--paper); color:var(--ink); resize:vertical}
  #cnList:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .route-actions{display:flex; gap:8px; margin:10px 0 0}
  .itinerary{margin-top:12px}
  .itin-summary{font-size:12px; color:var(--ink); background:var(--paper-2); border:1px solid var(--line); border-radius:8px; padding:10px 12px; margin-bottom:10px; line-height:1.6}
  .itin-summary b{color:var(--accent)}
  .itin-transit{display:flex; align-items:center; gap:9px; font-size:12px; color:var(--ink-soft); margin:9px 0; padding-left:4px}
  .itin-transit .ic{display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px; border-radius:6px; font-size:12px; color:var(--paper); flex:none}
  .itin-transit .ic.st{background:var(--orange)}
  .itin-transit .ic.el{background:var(--accent)}
  .itin-floor{border:1px solid var(--line); border-radius:10px; overflow:hidden; margin:8px 0}
  .itin-floor-h{display:flex; justify-content:space-between; align-items:center; gap:8px; padding:9px 13px; background:var(--green-soft); border-bottom:1px solid #bcce9e; cursor:pointer}
  .itin-floor-h .lv{font-family:var(--disp); font-size:15px; font-weight:600}
  .itin-floor-h .ct{font-size:10.5px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.5px}

  /* ── per-floor walking map ── */
  .walkwrap{padding:12px 13px 0; overflow-x:auto; -webkit-overflow-scrolling:touch}
  .walkmap{min-width:520px}   /* below this the aisle numbers collide; scroll instead of lying */
  .ramp{display:flex; align-items:center; gap:8px; padding:6px 13px 2px; font-size:10px; color:var(--ink-soft)}
  .ramp .bar{display:flex; flex:1 1 auto; height:7px; border-radius:99px; overflow:hidden; max-width:260px}
  .ramp .bar span{flex:1 1 auto}
  .ramp .rl{white-space:nowrap}
  /* One row per stop. Everything a stop is — the move, the face, the books, the shelf-end label
     — used to be printed twice, once as an instruction and again as a location line saying the
     same thing in other words. It is one line now, and the columns line up down the floor so you
     can read any one of them without reading the rest. */
  .itin-steps{list-style:none; margin:8px 0 4px; padding:0 13px}
  .itin-steps li{display:flex; flex-wrap:wrap; gap:2px 12px; align-items:baseline; padding:7px 0; border-top:1px solid var(--line)}
  .itin-steps li:first-child{border-top:0}
  .itin-steps .sn{flex:none; width:21px; height:21px; border-radius:99px; color:#fff; font-family:var(--mono); font-size:11px; font-weight:700; display:inline-flex; align-items:center; justify-content:center; align-self:flex-start}
  .itin-steps .sn.out{background:var(--slate)}
  .itin-steps .sd{flex:0 0 auto; min-width:170px; font-size:12px; line-height:1.6; color:var(--ink-soft)}
  .itin-steps .sd .k{color:var(--ink)}
  .itin-steps .sat{flex:0 0 auto; min-width:80px; font-size:12px; line-height:1.6; color:var(--ink-soft)}
  .itin-steps .sat .k{color:var(--ink)}
  .itin-steps .scn{flex:1 1 auto; font-family:var(--mono); font-size:11.5px; color:var(--accent)}
  /* The shelf-end label is what you check when you get there, so it goes last and gives way
     first: on a narrow screen it drops to its own line rather than squeezing the instruction. */
  .itin-steps .srng{flex:0 1 auto; margin-left:auto; font-family:var(--mono); font-size:11px; color:var(--ink-soft)}
  .itin-miss{font-size:12px; color:var(--accent); background:var(--orange-soft); border:1px solid var(--line); border-radius:8px; padding:9px 12px; margin-top:10px; line-height:1.65}

  /* ── catalog search (Alma SRU) ── */
  .sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0}
  /* Out of the way until it is tabbed to, which is the first thing a keyboard reader does and
     the only way past a masthead and a twenty-one-item library select. */
  .skip{position:absolute; left:-9999px; top:0; z-index:10; background:var(--card); color:var(--accent);
    font-size:13px; padding:11px 16px; border:1px solid var(--accent); border-radius:0 0 8px 0; text-decoration:none}
  .skip:focus{left:0}
  .cat-form{display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:12px 0 0}
  .cat-form input{flex:1 1 240px; min-width:0; font-family:var(--mono); font-size:15px; padding:11px 13px; border:1px solid var(--line); border-radius:8px; background:var(--paper); color:var(--ink)}
  .cat-form input:focus-visible,.cat-form input:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .cat-modes{display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin:13px 0 0}
  .cat-opts{display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin:11px 0 0}
  .chk{display:inline-flex; align-items:center; gap:7px; font-size:12px; color:var(--ink-soft); cursor:pointer; min-height:32px}
  .chk input{width:16px; height:16px; accent-color:var(--accent); cursor:pointer}
  .cat-status{font-size:12px; color:var(--ink-soft); min-height:18px; margin:11px 2px 0; line-height:1.65}
  .cat-diag{display:block; margin-top:4px; font-size:12px; color:var(--ink-faint)}
  .cat-status.err{color:var(--accent)}
  .cat-results{margin-top:10px}

  /* A-Z list. One line each, because the feed carries a name and a link and nothing else, and a
     card would be mostly padding around two words. */
  .db-filters{display:flex; gap:14px; align-items:center; flex-wrap:wrap; margin:9px 0 0}
  .db-list{margin:10px 0 0; border:1px solid var(--line); border-radius:10px; overflow:hidden; background:var(--paper)}
  .db-row{display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; padding:9px 13px; border-bottom:1px solid var(--line)}
  .db-row:last-child{border-bottom:0}
  .db-row:nth-child(even){background:var(--paper-2)}
  .db-row a{font-size:13.5px; color:var(--accent); text-decoration:none; border-bottom:1px solid transparent}
  .db-row a:hover{border-bottom-color:var(--accent)}
  .db-row a:focus-visible{outline:none; border-radius:3px; box-shadow:0 0 0 3px var(--orange-soft)}
  .db-tag{font-family:var(--mono); font-size:9.5px; letter-spacing:.06em; text-transform:uppercase; padding:2px 7px; border-radius:99px; border:1px solid var(--line); color:var(--ink-faint); background:var(--card); white-space:nowrap}
  .db-tag.best{border-color:#bcce9e; background:var(--green-soft); color:var(--good)}
  .db-tag.open{border-color:var(--accent); color:var(--accent); background:var(--orange-soft)}
  .db-more{margin:10px 2px 0; font-size:12px; color:var(--ink-soft)}

  /* The "where is it" line on the hours page. Sits between the lede and the controls, quiet
     enough not to compete with the hours and findable enough to be the thing you grab when a
     patron is standing in front of you. */
  .hr-where{margin:12px 0 0; padding:9px 13px; font-size:12.5px; color:var(--ink-soft);
    background:var(--card); border:1px solid var(--line); border-left:3px solid var(--accent);
    border-radius:8px; max-width:720px}
  .hr-where b{color:var(--ink)}
  .hr-where a{color:var(--accent)}
  .hr-where a:hover{text-decoration:none}
  .hr-where a:focus-visible{outline:none; border-radius:3px; box-shadow:0 0 0 3px var(--orange-soft)}
  /* The map is the one you grab, so it looks like a thing to press rather than a word in a
     sentence — 44px tall, because the hand reaching for it is usually holding something else. */
  .hr-where .hr-map{display:inline-block; font-weight:600; text-decoration:none;
    background:var(--paper-2); border:1px solid var(--line); border-radius:8px;
    padding:8px 13px; min-height:36px; line-height:20px; margin:2px 0}
  .hr-where .hr-map:hover{border-color:var(--accent); background:var(--orange-soft)}
  .hr-where .hr-meta{font-size:11px; color:var(--ink-faint); white-space:nowrap}

  .chk-note{color:var(--ink-faint)}
  .work{border:1px solid var(--line); border-radius:10px; overflow:hidden; margin:9px 0; background:var(--paper)}
  .work-h{display:flex; gap:12px; align-items:flex-start; padding:10px 13px; background:var(--paper-2); border-bottom:1px solid var(--line)}
  .work-t{flex:1 1 auto; min-width:0}
  /* Reserve the box before the image lands so results don't jump as covers stream in. */
  .cover{flex:none; width:96px; height:144px; object-fit:contain; object-position:top;
    border:1px solid var(--line); border-radius:5px; background:var(--card)}
  .work-h .ti{font-family:var(--disp); font-size:15px; font-weight:600; line-height:1.28}
  /* The title carries the link to Primo. It is not painted link-blue: on a page where every
     card has one, a coloured title would be the loudest thing in the results and the call
     number is what the reader came for. The underline appears on hover and focus. */
  .work-h .ti a.ti-l{color:inherit; text-decoration:none}
  .work-h .ti a.ti-l:hover{color:var(--accent); text-decoration:underline; text-underline-offset:2px}
  .work-h .ti a.ti-l:focus-visible{outline:none; border-radius:4px; box-shadow:0 0 0 3px var(--orange-soft)}
  .work-h .by{font-size:11.5px; color:var(--ink-soft); margin-top:3px; line-height:1.5}
  .work-h .tags{display:flex; flex-wrap:wrap; gap:5px; align-items:center; margin-top:8px}
  .work-h .ed{display:inline-block; font-size:9.5px; text-transform:uppercase; letter-spacing:1px; color:var(--accent); background:var(--orange-soft); border-radius:99px; padding:3px 9px}
  /* The carrier chip is loud on purpose: an audiobook filed as the newest "edition" of a
     novel has to be visible before the year is, not after the walk. */
  .carr{display:inline-block; font-size:9.5px; text-transform:uppercase; letter-spacing:1px;
    color:var(--paper); background:var(--slate); border-radius:99px; padding:3px 9px}
  .carr.audio,.carr.music{background:#7a5c9e}
  .carr.video{background:#9e5c5c}
  .carr.online{background:var(--slate)}
  .carr.microform{background:#6b6b5c}
  /* Same pill as the other chips, drawn as an action rather than a label. */
  .work-h .catlink{display:inline-block; font-size:9.5px; text-transform:uppercase; letter-spacing:1px;
    color:var(--ink-soft); background:var(--card); border:1px solid var(--line); border-radius:99px;
    padding:2px 9px; text-decoration:none}
  .work-h .catlink:hover{color:var(--accent); border-color:var(--accent)}
  .work-h .catlink:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .lib{padding:10px 13px; border-top:1px solid var(--line)}
  .lib-n{font-size:10.5px; text-transform:uppercase; letter-spacing:1px; color:var(--ink-soft); margin-bottom:3px}
  .lib.away{background:var(--paper-2)}
  .hold{padding:8px 0 2px; border-top:1px dotted var(--line)}
  .lib .hold:first-of-type{border-top:0; padding-top:4px}
  .hold-l{display:flex; flex-wrap:wrap; align-items:center; gap:5px 10px}
  .hold .cn{font-size:13px; font-weight:600; letter-spacing:.2px}
  .hold .cn.none{font-weight:400; color:var(--ink-faint)}
  .hold .where{display:block; font-size:11.5px; color:var(--ink-soft); line-height:1.55; margin-top:4px}
  .chip{font-size:10px; text-transform:uppercase; letter-spacing:.7px; padding:3px 8px; border-radius:99px; border:1px solid var(--line); color:var(--ink-soft); background:var(--card); white-space:nowrap}
  .chip.ok{color:var(--good); border-color:#bcce9e; background:var(--green-soft)}
  .chip.no{color:var(--accent); border-color:#e0bfa2; background:var(--orange-soft)}
  .chip.vol{color:var(--slate); border-color:var(--slate-soft); background:var(--slate-soft)}

  /* An anchor now, not a button: the map is its own page, so a shelf hit is somewhere you go. */
  .found{display:block; width:100%; text-align:left; font-family:var(--mono); font-size:13px; color:var(--ink);
    text-decoration:none;
    background:var(--green-soft); border:1px solid #bcce9e; border-radius:8px; padding:9px 12px; margin-top:6px; cursor:pointer; min-height:44px}
  .found:hover{border-color:var(--green)}
  .found:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .found .lead{display:block; font-weight:600}
  .found .rng{display:block; font-size:11px; color:var(--ink-soft); margin-top:3px}

  /* The home page's shelf preview: the same drawing the map page makes, at a size that answers
     "which floor, roughly where" without becoming the page. The matching faces are the only
     coloured thing on it — everything else drops to paper — because at this width the reader is
     looking for one mark, not reading a floor plan. */
  .prevwrap{margin:10px 0 0; padding:10px 12px; background:var(--card); border:1px solid var(--line);
    border-radius:10px; overflow-x:auto; -webkit-overflow-scrolling:touch; text-align:center}
  /* Capped by width, not by height. A preview that fills the screen is not a preview — at full
     width this plan runs past 500px tall and pushes the result it illustrates off the top. But
     capping the height instead makes the SVG letterbox itself inside a box it will not fill,
     which is a drawing with two margins rather than a smaller drawing. Bounding the width lets
     the aspect ratio set the height, and 480px lands it at about 310. */
  .prevmap{display:block; margin:0 auto; width:100%; max-width:480px; height:auto}
  .prevmap .shelf{cursor:default}
  a.tomap{display:inline-block; font-size:12px; color:var(--accent); text-decoration:none;
    border-bottom:1px solid var(--line); padding-bottom:1px}
  a.tomap:hover{border-bottom-color:var(--accent)}
  a.tomap:focus-visible{outline:none; border-radius:3px; box-shadow:0 0 0 3px var(--orange-soft)}
  a.tomap::after{content:' \2192'}
  .nofind,.elsewhere{font-size:11.5px; border:1px solid var(--line); border-radius:8px; padding:8px 11px; margin-top:6px; line-height:1.6}
  .nofind{color:var(--accent); background:var(--orange-soft)}
  .elsewhere{color:var(--ink-soft); background:var(--paper-2)}
  /* Indeterminate on purpose. A search here is a chain of requests whose length is not known
     when it starts — how many depends on what the catalog says to the first one — so a filling
     bar would have to invent a denominator, and a bar that reaches the end and sits there is
     worse than no bar. This says "still working" and leaves the account of *what* is being
     worked on to the status line underneath, which already narrates each step. */
  .busy{height:3px; margin:10px 2px 0; border-radius:99px; background:var(--paper-2); overflow:hidden}
  .busy[hidden]{display:none}
  .busy::after{content:''; display:block; width:36%; height:100%; border-radius:99px;
    background:var(--accent); animation:busy-slide 1.15s ease-in-out infinite}
  /* Transform only, so this never costs a layout pass while requests are in flight. */
  @keyframes busy-slide{
    0%{transform:translateX(-100%)}
    100%{transform:translateX(315%)}
  }
  .cat-empty{font-size:12.5px; color:var(--ink-soft); background:var(--paper-2); border:1px solid var(--line); border-radius:8px; padding:12px 14px; line-height:1.7}
  .cat-empty .k{color:var(--ink)}
  .cat-more{display:flex; justify-content:center; margin:12px 0 2px}
  .routed{font-size:11.5px; color:var(--ink-soft); margin:9px 2px 0; line-height:1.6}
  .linky{font:inherit; font-size:11.5px; color:var(--accent); background:none; border:0; border-bottom:1px solid currentColor; padding:0; cursor:pointer}
  .linky:hover{color:var(--ink)}
  .cat-scope{display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin:13px 0 0}
  .cat-libnote{font-size:11.5px; color:var(--ink-soft); background:var(--paper-2); border:1px solid var(--line); border-radius:8px; padding:8px 11px; margin:9px 0 0; line-height:1.65}
  .cat-opts select{font:inherit; font-size:12px; padding:5px 7px; border:1px solid var(--line); border-radius:7px; background:var(--paper); color:var(--ink)}
  .cat-adv{margin:11px 0 0; border:1px solid var(--line); border-radius:9px; background:var(--paper-2)}
  .cat-adv>summary{cursor:pointer; list-style:none; padding:9px 13px; font-size:11px; text-transform:uppercase; letter-spacing:1px; color:var(--ink-soft); min-height:38px; display:flex; align-items:center}
  .cat-adv>summary::-webkit-details-marker{display:none}
  .cat-adv>summary::before{content:'\25b8'; margin-right:8px; color:var(--accent)}
  .cat-adv[open]>summary::before{content:'\25be'}
  .cat-adv>summary:focus-visible{outline:none; box-shadow:inset 0 0 0 2px var(--accent)}
  .filt{display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:9px 12px; padding:4px 13px 12px}
  .filt .f{display:flex; flex-direction:column; gap:4px; font-size:11px; color:var(--ink-soft)}
  .filt .f>span{text-transform:uppercase; letter-spacing:.6px; font-size:9.5px}
  .filt .f input[type=text],.filt .f input:not([type]),.filt .f select{font:inherit; font-size:13px; padding:7px 9px; border:1px solid var(--line); border-radius:7px; background:var(--paper); color:var(--ink); min-width:0}
  .filt .f input:focus-visible,.filt .f select:focus-visible{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--orange-soft)}
  .filt .chk2{flex-direction:row; align-items:center; gap:7px; font-size:12px; min-height:34px}
  .filt .chk2 input{width:16px; height:16px; accent-color:var(--accent); flex:none}
  .filt-note{font-size:11.5px; color:var(--ink-soft); line-height:1.7; margin:0; padding:0 13px 12px}
  .filt-note code,.cheat code{font-family:var(--mono); font-size:11px; background:var(--card); border:1px solid var(--line); border-radius:4px; padding:1px 5px; color:var(--accent)}
  .cheat{display:grid; grid-template-columns:auto 1fr; gap:6px 14px; padding:0 13px 12px; font-size:11.5px; color:var(--ink-soft); line-height:1.6; align-items:baseline}
  .cheat>div:nth-child(odd){white-space:nowrap}
  .cheat .cheat-h{font-size:9.5px; text-transform:uppercase; letter-spacing:1px; color:var(--ink-faint); padding-top:8px; border-top:1px solid var(--line); white-space:normal}
  .cat-example{font:inherit; font-size:11.5px; color:var(--accent); background:var(--card); border:1px solid var(--line); border-radius:99px; padding:5px 11px; margin:3px 4px 0 0; cursor:pointer; min-height:30px}
  .cat-example:hover{border-color:var(--accent)}
  .cat-applied{margin:10px 0 0; font-size:11.5px; line-height:1.7}
  .cat-applied .ap-row{display:flex; flex-wrap:wrap; gap:5px; align-items:baseline; color:var(--ink-soft)}
  .cat-applied .ap-n{background:var(--green-soft); border:1px solid #bcce9e; border-radius:99px; padding:2px 9px; font-size:11px}
  .cat-applied .ap-eq{color:var(--ink-faint); margin-top:5px}
  .cat-applied .ap-eq code{font-family:var(--mono); font-size:11px; color:var(--ink-soft)}
  .cat-applied .ap-err{color:var(--accent); background:var(--orange-soft); border:1px solid #e0bfa2; border-radius:8px; padding:7px 11px; margin-top:6px}
  .cat-status code{font-family:var(--mono); font-size:11px}
  .cat-note{font-size:11.5px; color:var(--ink-soft); text-align:center; margin:10px 0 0}
  .edcount{display:inline-block; font-size:9.5px; text-transform:uppercase; letter-spacing:1px; color:var(--slate); background:var(--slate-soft); border-radius:99px; padding:3px 9px}
  .eds{border-top:1px solid var(--line); background:var(--paper-2)}
  .eds>summary{cursor:pointer; list-style:none; padding:8px 13px; font-size:11px; color:var(--ink-soft); min-height:36px; display:flex; align-items:center}
  .eds>summary::-webkit-details-marker{display:none}
  .eds>summary::before{content:'\25b8'; margin-right:8px; color:var(--accent)}
  .eds[open]>summary::before{content:'\25be'}
  .eds-body{padding:0 0 4px}
  .edrow{border-top:1px dotted var(--line)}
  .edrow-h{display:flex; gap:9px; align-items:baseline; padding:8px 13px 2px}
  .edrow-h .edy{font-family:var(--mono); font-size:12px; font-weight:600; color:var(--accent); flex:none}
  .edrow-h .edt{font-size:12px; color:var(--ink-soft); line-height:1.45}
  .edrow-h a.edt{text-decoration:none}
  .edrow-h a.edt:hover{color:var(--accent); text-decoration:underline; text-underline-offset:2px}
  .edrow-h a.edt:focus-visible{outline:none; border-radius:4px; box-shadow:0 0 0 3px var(--orange-soft)}

  /* ── responsive / mobile ── */
  .planwrap{width:100%}
  @media (hover:hover) and (pointer:fine){ #shoot{display:none} }
  @media (max-width:620px){
    .wrap{padding:16px 12px 56px}
    h1{font-size:22px; line-height:1.12}
    h1 .sub{letter-spacing:1.2px}
    .top{gap:8px; padding-bottom:12px}
    .lookup{padding:10px; gap:7px}
    .lookup label{flex:1 0 100%}
    .lookup input{flex:1 1 100%; min-width:0; font-size:16px}
    .lookup .btn{flex:1 1 0}
    .planwrap{overflow-x:auto; -webkit-overflow-scrolling:touch}
    #plan{min-width:560px}
    #cnList{font-size:16px}
    .drop{padding:13px}
    .drop .btn{flex:1 1 auto}
    .route-head,.cat-head{padding:11px 13px}
    /* The panel subtitles sit inline beside the heading and wrap onto a second line when they are
       long. That is fine until one of them changes after load: "loading…" fits on the heading's
       line, "20 of 27 locations open now" does not, so the hours header grew a line the moment
       LibCal answered and shoved every panel below it down the page. That single reflow was the
       whole of this page's 0.068 layout shift on a phone. Given a line of its own from the start,
       the box is the same height before and after the text arrives. */
    .route-head h2,.cat-head h2{display:block}
    .route-head h2 .h2-sub,.cat-head h2 .h2-sub{display:block; margin-top:3px}
    .route-body,.cat-body{padding:0 13px 14px}
    .detail{padding:14px 15px}
    .itin-steps .sd,.itin-steps .sat,.itin-steps .scn,.itin-steps .srng{flex:1 1 100%; min-width:0; margin-left:0}
    /* 16px keeps iOS from auto-zooming the field. The 44px tap floor is not here — it belongs to
       fingers rather than to narrow windows, so it lives in the pointer:coarse block below. */
    .cat-form input{font-size:16px; flex:1 1 100%}
    .cat-form .btn{flex:1 1 0}
    .whereami select{font-size:16px; flex:1 1 100%}
    .whereami-note{flex:1 1 100%}
    .filt{grid-template-columns:1fr}
    .filt .f input,.filt .f select{font-size:16px}
    .cheat{grid-template-columns:1fr; gap:2px 0}
    .cheat>div:nth-child(even){padding-bottom:7px}
    .work-h{padding:9px 11px; gap:10px}
    .cover{width:74px; height:111px}
    .lib{padding:9px 11px}
  }
  /* A tap target is about the finger, not the window. These used to live inside the 620px block,
     so a tablet — a touch screen with room on it — got the 32px mouse-sized pills. */
  @media (pointer:coarse){
    .cat-form .btn,.cat-head .btn,.route-head .btn{min-height:44px}
    .cat-modes .pill,.cat-scope .pill,.sect .pill,.af-quick .pill,.hr-days .pill{min-height:44px; padding:8px 16px}
    .whereami select{min-height:44px}
    .chk{min-height:44px}
    .lvl{min-height:44px}
    .cat-example{min-height:44px; padding:9px 14px}
    .examples .ex{display:inline-block; padding:6px 0; min-height:34px}
  }
  @media (prefers-reduced-motion:reduce){
    *,*::before,*::after{animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; scroll-behavior:auto !important}
    /* That rule stops the bar's animation dead, which would leave a short accent stub parked at
       the left of the track and reading as "36% done, stuck". A hatch across the whole width is
       a texture rather than a measurement: it says something is happening without claiming how
       much of it is finished, and it needs no motion to say it. */
    .busy::after{width:100%;
      background:repeating-linear-gradient(90deg, var(--accent) 0 5px, var(--paper-2) 5px 10px)}
  }

/* ============================================================================
   The text pages: /about, /methodology, /404 — and the page headings every tool page now
   carries. Only what the block above does not already say: the masthead is shared, so the
   wordmark, the mark, the nav and the footer are all defined once, up there.
   ============================================================================ */
.top{display:flex; align-items:flex-end; justify-content:space-between; gap:14px; flex-wrap:wrap;
  border-bottom:2px solid var(--ink); padding-bottom:16px}
/* The text column. 1060px of 13.5px prose is a measure nobody reads comfortably; the tool at that
   width is a map and a set of panels rather than sentences, so only this is narrowed. */
.prose{max-width:720px}

/* The wordmark is inline text inside a link, so it picks up the body's reading line-height unless
   told otherwise. Left alone that put 11px of air under it and made the masthead 79px tall. */
.brand>span{display:block; line-height:1.05}
.brand b{font-family:var(--disp); font-size:30px; font-weight:600; letter-spacing:-0.4px}
.brand .tag{display:block; font-size:12px; font-weight:400; color:var(--ink-soft);
  letter-spacing:1.6px; text-transform:uppercase; margin-top:6px; line-height:1.05}
.brand:hover b{color:var(--accent)}

/* The masthead carries the site name, so the page title is the next step down rather than a
   second thing competing at the same size. Every page has one now, tool pages included. */
h1{font-family:var(--disp); font-size:26px; font-weight:600; letter-spacing:-0.3px;
  line-height:1.2; margin:26px 0 0}
.lede{font-size:14.5px; color:var(--ink-soft); margin:9px 0 0; max-width:720px}
.prose h2{font-family:var(--disp); font-size:19px; font-weight:600; margin:34px 0 0; line-height:1.3}
.prose h3{font-family:var(--mono); font-size:12px; font-weight:600; text-transform:uppercase;
  letter-spacing:.09em; color:var(--ink-soft); margin:22px 0 0}
.prose p{margin:11px 0 0}
.prose ul{margin:11px 0 0; padding-left:20px}
.prose li{margin:5px 0}
.prose li::marker{color:var(--ink-faint)}
.prose a{color:var(--accent)}
.prose a:hover{text-decoration:none}
.prose code{font-family:var(--mono); font-size:12px; background:var(--card); border:1px solid var(--line);
  border-radius:4px; padding:1px 5px; color:var(--accent); white-space:nowrap}
.prose strong{font-weight:600}
.prose hr{border:none; border-top:1px solid var(--line); margin:30px 0 0}

/* A definition row: the term on the left at any width the term needs, the sentence beside it. */
.rows{display:grid; grid-template-columns:auto 1fr; gap:7px 16px; margin:12px 0 0; align-items:baseline}
.rows>div:nth-child(odd){white-space:nowrap; color:var(--ink)}
.rows>div:nth-child(even){color:var(--ink-soft)}

.note{background:var(--card); border:1px solid var(--line); border-left:3px solid var(--accent);
  border-radius:8px; padding:12px 15px; margin:16px 0 0; color:var(--ink-soft)}
.note b{color:var(--ink)}

footer a{color:var(--ink-soft)}

@media (max-width:620px){
  .top{gap:8px; padding-bottom:12px}
  .brand b{font-size:25px}
  .brand .tag{letter-spacing:1.2px}
  h1{font-size:23px}
}
@media (max-width:560px){
  .rows{grid-template-columns:1fr; gap:2px 0}
  .rows>div:nth-child(even){padding-bottom:8px}
  .prose code{white-space:normal}
}

/* Keyboard focus in Windows High Contrast.
 *
 * Focus is drawn here as `outline:none` plus a soft box-shadow ring, in twenty-six places. Under
 * forced colours the browser throws box-shadow away and honours the `outline:none`, so a keyboard
 * user gets no focus indicator at all — on every link, button, select and input on the site.
 *
 * Restored in one place rather than by rewriting all twenty-six declarations: the ring is the
 * house style and it is right in the normal case, so the media query puts the outline back only
 * where the ring cannot be seen. `currentColor` because forced colours have already replaced the
 * text colour with one guaranteed to contrast against the forced background. */
@media (forced-colors: active){
  :focus-visible, :focus{outline:3px solid currentColor !important; outline-offset:2px}
}
