/* The menu: one control, in the top bar of every page, that opens a short drawer.

   Rendered from assets/hatch.js so the markup exists once rather than on all 41 pages.

   It was a filled dark block reading THE WHOLE MAP, and what it opened was a full-screen
   three-column takeover of the entire site. The reference site's is a small outlined
   shape at the top right of a bar that never moves, and what it opens is a 660px drawer
   over a dimmed page holding a dozen links. Their menu is not their navigation — their
   card deck and their search field are — so their menu can afford to be short. Ours is
   the same: the doors are the front page and the field is in this bar.

   Parcours: the outline is --ink-line, which is the colour our line work is already in,
   and the pill and the circle are both radii the system already uses
   (explorer.css:141). Two --rule hairlines touch a clickable edge, .upnav-help's top under
   1250px and the divider between .ssresults rows. Both separate rather than outline. */

/* Only a page that ended up with the floating fallback gives up the bottom 96px to it.
   hatch.js sets the class when it cannot find a bar to put the button in. */
html.hatchfloat body{padding-bottom:96px}

.hatchslot{display:flex; align-items:center}

.hatch{
  background:var(--ground); color:var(--ink-line);
  border:1px solid var(--ink-line); border-radius:999px;
  padding:11px 20px; cursor:pointer; white-space:nowrap;
  font:500 13px/1 var(--font-mono); letter-spacing:var(--track-label);
  text-transform:uppercase;
  transition:background var(--t-micro) var(--ease-quick), color var(--t-micro) var(--ease-quick);
}
.hatch:hover{background:var(--ink-line); color:var(--ground)}
.hatch:focus-visible{outline:2px solid var(--ink); outline-offset:3px}

/* Only a page with no bar to sit in. */
html.hatchfloat .hatch{position:fixed; right:24px; bottom:24px; z-index:60}

/* The drawer used to appear in a single frame, which on the route a reader takes after
   something has gone wrong reads as a jump rather than a movement. It now slides from the
   right edge it is anchored to.

   `display` is animated through `allow-discrete` rather than transitioned on its own, so the
   sheet is laid out for the whole of the entrance and removed only at the end of the exit;
   `@starting-style` supplies the value the drawer enters from. Browsers without either get
   the old instant open, which is the correct fallback here.

   The duration is --t-micro, not the --t-state used elsewhere for a change of this size.
   This is the emergency route and it must never feel like a wait. */
.hatchsheet{
  position:fixed; inset:0; z-index:61;
  transition:opacity var(--t-micro) var(--ease-quick),
             display var(--t-micro) allow-discrete;
}
.hatchsheet[hidden]{display:none; opacity:0}
@starting-style{.hatchsheet{opacity:0}}
.hatchscrim{position:absolute; inset:0; background:rgba(0,0,0,.2)}

/* Their drawer is 660 of 1512, a little over two fifths. Ours is the same fraction, and
   takes the whole width of a phone. Their page ground is cream and their drawer is white,
   so the edge shows on its own; ours are both white, so the edge is drawn. */
.hatchdrawer{
  position:absolute; top:0; right:0; bottom:0;
  width:min(660px, 100%); overflow-y:auto; overscroll-behavior:contain;
  background:var(--ground); border-left:1px solid var(--ink-line);
  padding:26px clamp(24px,4vw,52px) 60px;
  translate:0 0;
  transition:translate var(--t-micro) var(--ease-quick);
}
@starting-style{.hatchdrawer{translate:100% 0}}
.hatchsheet[hidden] .hatchdrawer{translate:100% 0}

/* Reduced motion takes the drawer, not just the page furniture: it arrives at once and
   leaves at once, with no discrete display step to wait on. */
@media (prefers-reduced-motion:reduce){
  .hatchsheet, .hatchdrawer{transition:none}
  .hatchdrawer{translate:0 0}
}
.hatchdrawer h2{
  font:500 clamp(38px,4vw,52px)/1.12 var(--font-display);
  color:var(--ink); margin:14px 0 40px; max-width:11ch;
}
.hatchx{
  float:right; width:44px; height:44px; border-radius:100%;
  background:var(--ground); color:var(--ink-line); border:1px solid var(--ink-line);
  font:400 22px/1 var(--font-body); cursor:pointer;
}
.hatchx:hover{background:var(--ink-line); color:var(--ground)}
.hatchx:focus-visible{outline:2px solid var(--ink); outline-offset:3px}

.dgroup{
  margin:34px 0 14px; font:500 13px/1.5 var(--font-mono);
  letter-spacing:var(--track-label); text-transform:uppercase; color:var(--muted);
}
.dgroup:first-of-type{margin-top:0}

/* The things somebody opens a menu in a hurry to find. Pills, because the reference
   gives its two most-asked-for cards the same treatment, and because a pill reads as a
   thing to press where a row of text reads as a list to scan. */
.dpill{
  display:block; margin-bottom:10px; padding:15px 22px;
  border:1px solid var(--ink-line); border-radius:999px;
  color:var(--ink); text-decoration:none; font:400 19px/1.3 var(--font-body);
  transition:background var(--t-micro) var(--ease-quick);
}
.dpill:hover, .dpill:focus-visible{background:var(--raised)}

.drow{
  display:flex; justify-content:space-between; align-items:baseline; gap:20px;
  padding:15px 0;
  color:var(--ink); text-decoration:none;
}
.dnm{font:400 19px/1.35 var(--font-body)}
.drow:hover .dnm, .drow:focus-visible .dnm{text-decoration:underline}
.dnote{
  font:500 13px/1.4 var(--font-mono); letter-spacing:var(--track-label);
  text-transform:uppercase; color:var(--muted); white-space:nowrap;
}
.drow.at .dnote{color:var(--ink-line)}
.drow:focus-visible{outline:2px solid var(--ink-line); outline-offset:2px}

/* The page's own parts, first in the drawer when it has a list of them. The same rows as
   the rest of the drawer, and a question or entry under a part is set in beneath it. */
.donpage + .dgroup{margin-top:34px}
.drow.sub{padding:11px 0 11px 22px}
.drow.sub .dnm{font-size:17px}

@media (max-width:560px){
  .hatch{padding:10px 15px}
  .hatchdrawer{border-left:0}
  /* A note in the right-hand column and a name in the left one cannot both fit here. */
  .drow{display:block}
  .dnote{display:block; margin-top:3px; white-space:normal}
}
@media (prefers-reduced-motion:reduce){
  .hatch, .dpill{transition:none}
}

/* The site foot: one ruled line on the rail, a mono label in the 200px column and the
   links side by side in the content column, like closing credits rather than a menu.
   Links are apparatus, so 17px; 10px above and below makes each a 45px tap target. */
.sitefoot{
  margin:56px 0 0; display:grid; grid-template-columns:200px minmax(0,1fr);
  gap:4px 40px; align-items:baseline; border-top:1px solid var(--rule); padding-top:6px;
}
.sitefoot .sfl{
  font:500 13px/1.5 var(--font-mono); letter-spacing:var(--track-label);
  text-transform:uppercase; color:var(--muted); margin:0;
}
.sitefoot ul{list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; column-gap:32px}
.sitefoot a{
  display:inline-block; padding:10px 0; font:400 17px/1.5 var(--font-body);
  color:var(--ink-line); text-decoration-line:none;
}
.sitefoot a:hover, .sitefoot a:focus-visible{text-decoration-line:underline}
@media (max-width:820px){
  .sitefoot{grid-template-columns:minmax(0,1fr); padding-top:14px}
}

/* The way back up.
   ------------------------------------------------------------------------------------
   Before this, only the seven stage pages had one. The six doors, the directory index
   and the twelve province pages offered nothing above the fold: the way out was the
   fixed hatch button, which opens a full-screen sheet, or the site foot at the end of
   three thousand words. Neither is navigation for somebody who just wants to go back a
   step, and both cost more than the browser control they were competing with.

   Sticky rather than fixed, so it takes its 49px from the top of the document once and
   then travels with the reader instead of standing on top of the text. It sits in the
   same sheet as .sitefoot because they are the same thing at the two ends of a page. */
/* 61px: 14px of padding either side of a 32px row, plus the 1px rule. See --bar in
   explorer.css for why this is a copied measurement and what keeps it honest. */
:root{--bar:61px}
.upnav{
  position:sticky; top:0; z-index:50;
  background:var(--ground); border-bottom:1px solid var(--rule);
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  --pad:40px; padding:0 var(--pad);
}
/* The ways up, grouped, so the bar can hold something that is not a way up beside them.
   They keep their width and the search field gives way: shrunk, their nowrap links spilled
   out under the field, and at 1000px the bar read "THE FRAUD CLSEARCH". */
.upways{display:flex; align-items:center; gap:28px; flex:0 0 auto}
.upnav .up{
  display:inline-flex; align-items:center; gap:10px;
  padding:14px 0; text-decoration-line:none; color:var(--ink-line);
  font:400 23px/1.4 var(--font-body); white-space:nowrap;
}
.upnav .up:hover, .upnav .up:focus-visible{text-decoration-line:underline}
/* The arrow moves and the label does not, so the target never shifts under a finger. */
.upnav .up .ar{
  font:500 17px/1 var(--font-mono); color:var(--muted);
  transition:transform var(--t-micro) var(--ease-quick);
}
.upnav .up:hover .ar{transform:translateX(-3px)}
.upnav .home{
  font:500 13px/1.4 var(--font-mono); letter-spacing:var(--track-label);
  text-transform:uppercase; color:var(--muted);
  padding:14px 0; text-decoration-line:none; white-space:nowrap;
}
.upnav .home:hover, .upnav .home:focus-visible{color:var(--ink-line); text-decoration-line:underline}
.upnav :is(a):focus-visible{outline:2px solid var(--ink-line); outline-offset:2px; border-radius:var(--radius)}

/* The same ask as the front page's band, in the band's colour, so it reads as that band
   carried onto every page rather than as one more control. */
.upnav-help{
  font:500 17px/1.3 var(--font-body); color:var(--ink); background:var(--closing);
  padding:9px 14px; border-radius:var(--radius); text-decoration-line:none; white-space:nowrap;
}
.upnav-help:hover, .upnav-help:focus-visible{text-decoration-line:underline; text-underline-offset:4px}
/* On door 2 itself the page's own closing block carries the colour, and one per view. */
.upnav-help[aria-current]{background:none}

/* Anything jumped to by an anchor has to clear the bar it would otherwise sit under. */
:target, [id]{scroll-margin-top:calc(var(--bar) + 3px)}

/* Below 1251 the row cannot hold the way to door 2 beside everything else: at 1000 it
   pushed the back link onto four lines and the bar to 190px. So it takes a line of its
   own, the full width of the bar, and --bar grows by exactly that line.

   Placed into reserved padding rather than wrapped onto a second flex line, because a
   wrapping row breaks at its items' flex-basis before it shrinks them: the search field's
   460px sent the field and the map onto a line of their own at 901 to 1250, where they
   would have fitted shrunk. A row that never wraps is also what lets --bar be one number
   per width instead of one per page. */
@media (max-width:1250px){
  :root{--bar:108px}
  .upnav{padding-bottom:47px}
  .upnav-help{
    position:absolute; left:0; right:0; bottom:0; height:47px; box-sizing:border-box;
    display:flex; align-items:center; padding:0 var(--pad);
    border-radius:0; border-top:1px solid var(--rule);
  }
}
/* The wordmark is the one thing in the row that has a second route, the map beside it, so
   it is what goes when the row runs out of width. */
@media (max-width:900px){
  .upnav .home{display:none}
}
@media (max-width:820px){
  .upnav{--pad:22px}
}
@media (max-width:600px){
  :root{--bar:100px}
  .upnav .up{font-size:17px}
  /* At 320 the longest way back and the map button do not fit one line: "Who to call in
     Canada" ran 53px past the edge of the screen. The label takes a second line instead,
     inside the 52px one line already had, so --bar stays one number. */
  .upways{flex:0 1 auto; min-width:0}
  .upnav .up{line-height:1.3; white-space:normal; text-wrap:balance; min-height:52px; padding:0}
}
@media (prefers-reduced-motion:reduce){
  .upnav .up .ar{transition:none}
  .upnav .up:hover .ar{transform:none}
}

/* Site search.
   ------------------------------------------------------------------------------------
   The field is furniture, so it lives in the furniture sheet beside .upnav and .sitefoot.
   Two placements, one control: "bar" rides the up-nav on every page that has one, "block"
   sits in the front page's rail where there is no bar to ride.

   Fill only, and the same construction as every other control here: a mono label, an ink
   underline rather than a hairline box, and one filled ink block where a button is needed.
   The panel is a real border, not a hairline, because it bounds something clickable. */
/* Above the deck on the front page, whose cards reach z-index 41 and were painting over
   the field on a phone, and above the up-nav's own 50 so the panel is not clipped by the
   bar it hangs from. Below the map button at 60 and its overlay at 61: the map covers the
   page, and a search field poking through it would be a hole in the map. */
.sitesearch{position:relative; z-index:55; display:flex; align-items:baseline; gap:14px; min-width:0}
.sitesearch label{
  font:500 13px/1.5 var(--font-mono); letter-spacing:var(--track-label);
  text-transform:uppercase; color:var(--muted); white-space:nowrap;
}
.sitesearch .ssline{position:relative; display:flex; align-items:baseline; gap:12px; min-width:0; flex:1}
.sitesearch input{
  flex:1; min-width:0; font:400 17px/1.4 var(--font-body); color:var(--ink);
  background:var(--ground); border:0; border-bottom:2px solid var(--rule);
  border-radius:0; padding:6px 2px 7px;
}
.sitesearch input::placeholder{color:var(--muted); opacity:1}
.sitesearch input:focus{outline:0; border-bottom-color:var(--ink-line)}
/* The browser's own clear button is drawn in the system accent, which is a second accent
   in the view and never this site's. Escape clears the panel, the field clears by hand. */
.sitesearch input::-webkit-search-cancel-button{-webkit-appearance:none; appearance:none}
.sitesearch input:focus-visible{outline:0}
.sitesearch :is(input,a):focus-visible{outline:2px solid var(--ink-line); outline-offset:2px}

/* The count is for a screen reader first. It is announced on every search and shown only
   when the panel is closed and there is nothing to show, which is the one case where
   silence would read as the field being broken. It sits over the page, so it takes the
   panel's surface: with no ground of its own it was set on top of the heading beneath. */
.sitesearch .sscount{
  position:absolute; top:100%; left:0; right:0; z-index:1; margin:8px 0 0; padding:16px 18px;
  background:var(--ground); border:1px solid var(--ink-line); border-radius:var(--radius);
  box-shadow:0 18px 40px rgba(31,75,85,.13);
  font:400 17px/1.4 var(--font-body); color:var(--muted);
}
.sitesearch .sscount:empty{display:none}

/* Anchored to the field line and exactly its width, which is the reference site's
   `.search_results`: pinned to the field's own box rather than hung off the whole control.
   The stacking is the form's, above. */
.ssresults{
  position:absolute; top:calc(100% + 8px); left:0; right:0; z-index:1;
  background:var(--ground); border:1px solid var(--ink-line); border-radius:var(--radius);
  max-height:min(62vh, 560px); overflow-y:auto; overscroll-behavior:contain;
  box-shadow:0 18px 40px rgba(31,75,85,.13);
}
.ssresults ul{list-style:none; margin:0; padding:0}
.ssresults li + li{border-top:1px solid var(--rule)}
.ssresults a{
  display:block; padding:14px 18px 16px; text-decoration-line:none; color:inherit;
}
.ssresults li a:hover, .ssresults li a[aria-selected="true"]{background:var(--raised)}
.ssresults .nm{
  display:block; font:500 23px/1.3 var(--font-display); color:var(--ink);
  text-wrap:balance;
}
.ssresults li a:hover .nm, .ssresults li a[aria-selected="true"] .nm{text-decoration-line:underline}
.ssresults .where{
  display:block; margin-top:6px;
  font:500 13px/1.5 var(--font-mono); letter-spacing:var(--track-label);
  text-transform:uppercase; color:var(--muted);
}
.ssresults mark{background:var(--r7); color:var(--ink); border-radius:var(--radius); padding:0 3px}
.ssresults .ssall{
  position:sticky; bottom:0; background:var(--raised);
  border-top:1px solid var(--ink-line); color:var(--ink-line);
  font:500 13px/1.5 var(--font-mono); letter-spacing:var(--track-label); text-transform:uppercase;
}
.ssresults .ssall:hover{background:var(--ink); color:var(--ground)}
.ssresults .ssempty{padding:16px 18px; color:var(--muted); font-size:17px}

/* In the bar, taking the space the ways up do not, down to a floor. */
.upnav .ss-bar{flex:0 1 460px; margin-left:auto; padding:8px 0}

/* In the front page's rail, where the label goes above the field the way every other
   form on the site puts it. */
/* Opaque, because on a phone the deck's cards lift up over the tail of the rail and a
   field you can read through is a field that looks broken. */
.sitesearch.ss-block{display:block; margin-top:28px; background:var(--ground); padding:8px 0 10px}
.sitesearch.ss-block label{display:block; margin:0 0 10px}
.sitesearch.ss-block input{font-size:23px; padding:8px 2px 10px}


/* Below this the bar cannot hold a way back and an open field both without taking a second
   line, which on a phone costs every page a line of prose for a control most readers will
   never touch. So the field collapses and the label becomes the button that opens it.

   No script: a <label> focuses its own field when it is tapped, and focus is what opens the
   collapse. The reference site does the same thing with :hover on the wrapper. The label
   stays a word rather than a magnifier, because an unlabelled icon is the wrong ask of a
   reader who is 80.

   970 rather than 900, the width the wordmark goes: with it still in the row, a province
   page's field was 140px wide at 910 and reached 200px only at 970. */
@media (max-width:970px){
  .upnav .ss-bar{flex:0 0 auto; margin-left:auto; padding:0; gap:0}
  .upnav .ss-bar label{
    background:var(--ink); color:var(--ground); border-radius:var(--radius);
    padding:9px 13px; cursor:pointer;
    transition:background var(--t-micro) var(--ease-quick), color var(--t-micro) var(--ease-quick);
  }
  /* Zero width and no ink, but never `visibility` or `display`: the field has to stay
     focusable, because focusing it is the only thing that reopens it. */
  .upnav .ss-bar .ssline{width:0; opacity:0; transition:width var(--t-micro) var(--ease), opacity var(--t-micro)}
  @media (prefers-reduced-motion:reduce){
    .upnav .ss-bar label, .upnav .ss-bar .ssline{transition:none}
  }
  .upnav .ss-bar .ssline input{padding:0; border-bottom-width:0}
  .upnav .ss-bar:focus-within .ssline{width:min(58vw,320px); opacity:1}
  .upnav .ss-bar:focus-within .ssline input{padding:6px 2px 7px; border-bottom-width:2px}
  .upnav .ss-bar:focus-within{gap:14px}
  .upnav .ss-bar:focus-within label{background:none; color:var(--muted); padding:0}
  /* Open, the field needs the room the ways up hold. They give it up for as long as the
     reader is typing, cut at their own edge rather than running under the field; held at
     full width, they pushed the field and the map past the edge of the screen. */
  .upnav:has(.ss-bar:focus-within) .upways{flex:0 1 auto; min-width:0; overflow:hidden}
  /* The wordmark goes whole rather than cut to its first two letters, as it goes at 900. */
  .upnav:has(.ss-bar:focus-within) .home{display:none}
}

/* Gone below this, the way the reference site drops its own field at 600. What is left is
   the map at the bottom right, which reaches every page on the site, and the front page,
   which still carries the field in its rail. */
@media (max-width:600px){
  .upnav .ss-bar{display:none}
}

/* ---- Blocks arrive as you reach them ------------------------------------------------
   The reference site animates every block into place as it enters the viewport: the
   section title comes in from the left, images grow from half size, and the cells of a
   grid step in 0.05s apart. We had exactly one animated moment on the whole site, the
   front-page deck, and every page after it appeared already finished. That absence is
   most of what "theirs moves better than ours" was measuring - more than any curve was.

   Three things move, and nothing else does. Their .cell is a short cell in a grid that
   fits on screen, so ours is .three, not .act: an .act is a full screen of instructions,
   and sliding those around under somebody who is following them is a different thing
   entirely from a page arriving.

   Their values, with one sign flipped: their cells enter from translate(5vw,5vw), and
   rightward overflow would put a horizontal scrollbar on every content page. Clipping is
   not available to us, because two sticky bars live in this same sheet and a clipped
   ancestor breaks them. Entering from the left costs nothing, since overflow past the
   left edge does not extend the scrollable area, and it makes the vocabulary agree on a
   direction.

   The resting states apply only under html.rv, which hatch.js sets once the observer
   exists. A script that fails, or never loads at all, leaves every block plainly visible
   rather than permanently transparent. */
html.rv .rail[data-rv]{
  opacity:0; translate:-10vw 0;
  transition:translate var(--t-reveal) var(--ease-back), opacity var(--t-reveal) var(--ease);
}
html.rv figure[data-rv]{
  opacity:0; scale:.5;
  transition:scale var(--t-reveal) var(--ease-back), opacity var(--t-reveal) var(--ease);
}
html.rv .three[data-rv] > *{
  opacity:0; translate:-5vw 5vw; scale:1.05;
  transition:translate var(--t-reveal) var(--ease-back), scale var(--t-reveal) var(--ease-back),
             opacity var(--t-reveal) var(--ease);
}
/* Their .highl_long_block moves a tall block 50px rather than sliding it a tenth of the
   viewport: a long block travelling that far is a lurch, not an arrival. */
html.rv .m[data-rv]{
  opacity:0; translate:0 -50px;
  transition:translate var(--t-reveal) var(--ease-back), opacity var(--t-reveal) var(--ease);
}
html.rv :is(.rail, figure, .m)[data-rv].on,
html.rv .three[data-rv].on > *{opacity:1; translate:0 0; scale:1}

/* Their .table_module steps its children 0.05s at a time across twenty-eight cells. Our
   longest group is the eight topic rows, so the ladder stops at eight. */
html.rv .three[data-rv] > :nth-child(2){transition-delay:.05s}
html.rv .three[data-rv] > :nth-child(3){transition-delay:.1s}
html.rv .three[data-rv] > :nth-child(4){transition-delay:.15s}
html.rv .three[data-rv] > :nth-child(5){transition-delay:.2s}
html.rv .three[data-rv] > :nth-child(6){transition-delay:.25s}
html.rv .three[data-rv] > :nth-child(7){transition-delay:.3s}
html.rv .three[data-rv] > :nth-child(n+8){transition-delay:.35s}

/* Reduced motion switches the whole mechanism off rather than speeding it up, so nothing
   here waits for an observer to be reached.

   The selector has to carry the resting rules' own weight. `html.rv [data-rv]` is (0,2,1)
   and loses to `html.rv .rail[data-rv]` at (0,3,1) and to `html.rv figure[data-rv]` at
   (0,2,2), so this block was inert in every browser: a reader who had asked for less motion
   still got every off-screen block at opacity 0 and every figure at half size until they
   scrolled it into view. It read as working only because stage.css:227 sets
   `transition:none!important` on everything, which is a different rule doing a third of
   this one's job. :is() takes the weight of its most specific argument, so the list below
   is (0,3,1) whichever branch matches. */
@media (prefers-reduced-motion:reduce){
  html.rv :is(.rail, figure, .m, .three)[data-rv],
  html.rv .three[data-rv] > *{
    opacity:1; translate:0 0; scale:1; transition:none;
  }
}
