/* Site tweaks, loaded after the theme stylesheet. */

/* Colours: a paper trail map. Cream paper and dark ink, forest green for the
   header, links and "now" (an earthy, dirt green), brown for contours and secondary text, sienna for
   the trail. These replace the theme's dark slate palette; the theme's SCSS is
   left alone and its colours are overridden here. */
:root {
  --paper: #f3eedf;
  --paper-deep: #e7dfc8;   /* inline code, selection */
  --ink: #2b2925;
  --ink-soft: #6b5e4b;     /* dates, places, footnotes */
  --rule: #b7a98a;         /* hairlines */
  --forest: #56642f;       /* links, "now": an earthy olive */
  --forest-deep: #4a5530;  /* header: moss, dirt-green */
  --header-text: #f3eedf;  /* cream, in both modes */
  --forest-light: #e2e3c6; /* light olive, for link underlines and marks */
  --trail: #a0522d;        /* the trail (also hard-coded in the trail SVGs) */
  --sign-green: #3d8b46;   /* trail difficulty signs */
  --sign-blue: #2e5ea8;
  --sign-black: #1f1d1a;
}
/* The whole page is a topo map: a tiling contour drawing on cream paper,
   made by tools/make-contours.py. */
html {
  background: var(--paper);
}
body {
  position: relative;
  isolation: isolate;
  min-height: 100vh;
  background: var(--paper) url(/images/contours.svg) repeat 0 0 / 900px;
}

/* Night ride: an easter egg. The headlight button in the header (shown by
   main.js) switches it on for the rest of the visit; the site is always in
   daylight otherwise. Everything is in the dark, text included, until you
   shine a light on it: the beam follows the pointer (or a tap, or keyboard
   focus) and shows the page, with the map in lamplight (contours-night.svg)
   under it. main.js aims it by setting --cx/--cy (on screen) and --mx/--my
   (on the page); Esc or the button again switches it off. */
:root.night-ride {
  --paper: #15140f;
  --paper-deep: #26241c;
  --ink: #ded7c5;
  --ink-soft: #a39782;
  --rule: #4a4436;
  --forest: #aab67b;
  --forest-deep: #2b311b;
  --forest-light: #3b4027;
  --trail: #c27443;
  --sign-black: #e3dccb;   /* black diamonds would vanish on a dark map */
}
/* A dark wash over the day contours leaves them barely visible. */
.night-ride body {
  background-image: linear-gradient(rgba(21, 20, 15, 0.65), rgba(21, 20, 15, 0.65)), url(/images/contours.svg);
}
.night-ride body {
  --cx: 50vw;
  --cy: 45vh;
  --mx: 50vw;
  --my: 45vh;
  --beam: 240px;
}
/* The darkness: over the whole page, with a hole where the light is. */
.night-ride body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1000;
  pointer-events: none;
  background: radial-gradient(circle var(--beam) at var(--cx) var(--cy),
    transparent 0, transparent 30%, rgba(10, 9, 7, 0.6) 70%, rgba(10, 9, 7, 0.94) 100%);
}
.night-ride body::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(circle var(--beam) at var(--mx) var(--my), rgba(255, 224, 160, 0.09), transparent 75%),
    url(/images/contours-night.svg) repeat 0 0 / 900px;
  -webkit-mask-image: radial-gradient(circle var(--beam) at var(--mx) var(--my), #000 30%, transparent 100%);
  mask-image: radial-gradient(circle var(--beam) at var(--mx) var(--my), #000 30%, transparent 100%);
}

/* The headlight button: faint until you look for it, lit while riding. */
#night-btn {
  opacity: 0.45;
  vertical-align: middle;
  transition: opacity 0.2s;
}
#night-btn:hover,
#night-btn:focus-visible,
.night-ride #night-btn {
  opacity: 1;
}
.night-ride #night-btn {
  color: #ffd98a;
}

body,
button,
input,
select,
textarea,
a,
code,
mark,
.bg-img-copyright {
  color: var(--ink);
}
a:hover {
  color: var(--ink);
  text-shadow: none;
}
::selection {
  background: var(--paper-deep);
}
code {
  background: var(--paper-deep);
}
/* Code blocks keep a dark background: the highlighter's colours need it. */
pre,
pre code {
  color: #eeeeee;
}
mark {
  background-color: var(--forest-light);
}
ins {
  text-decoration-color: var(--forest);
}
.content a,
.bg-img-copyright a {
  box-shadow: inset 0 -3px 0 var(--forest-light), inset 0 -4px 0 var(--forest);
}
.content a:hover,
.bg-img-copyright a:hover {
  color: var(--paper);
  box-shadow: inset 0 calc(-1.5em - 5px) 0 var(--forest);
}
.content a.anchor:hover {
  color: var(--forest);
}
a.footnote-ref {
  background-color: var(--ink-soft);
  color: var(--paper);
}
a.footnote-ref:hover {
  background-color: var(--forest);
}
.posts-group .post-item {
  border-bottom-color: var(--rule);
}
.pinned-posts-group {
  border-bottom-color: var(--rule);
}
.post-description a:hover,
#TableOfContents a:hover {
  border-bottom-color: var(--forest);
}
#site-footer {
  color: var(--ink-soft);
}
#site-footer a {
  color: var(--ink-soft);
}

/* Header and small-screen menu: a forest-green bar, like a park sign. */
#site-header,
#mobile-menu {
  background-color: var(--forest-deep);
  color: var(--header-text);
}
#mobile-menu {
  border-color: var(--forest-deep);
}
#site-header a,
#site-header button,
#mobile-menu a {
  color: var(--header-text);
}
.hdr-wrapper .site-nav .has-children {
  border-right-color: var(--rule);
}

/* Navigation sits at the top of the page and scrolls away with it,
   instead of floating at the bottom of the screen. */
#site-header {
  position: static;
  box-shadow: none;
}

/* On wide screens, centre the title and links to match the centred text below. */
@media (min-width: 761px) {
  .hdr-wrapper {
    justify-content: center;
  }
  /* When title and links don't fit on one line, centre the second line too. */
  .hdr-left {
    text-align: center;
  }
}

/* The small-screen menu drops down from the top-right instead of popping up. */
#mobile-menu {
  top: 3.5em;
  bottom: auto;
  right: 1em;
}

/* The theme leaves a tall gap above the page (growing with screen width) and
   96px below it to clear the floating bar. Neither is needed now. */
.site-main {
  margin-top: 2.5em;
}
#site-footer {
  margin-bottom: 2em;
}

/* Home page timeline (layouts/home.html), drawn as singletrack on a trail map. The dashed line
   switchbacks down beside each entry, then wanders over to the
   other side for the next one, so the entries take turns sitting left and
   right of it. Where it lands changes a little each time (--x, in a cycle of
   four), and the crossings come in two twisty shapes, so no two look alike. A dot marks
   each entry: filled green for what's happening now, ringed for the past.
   Each piece is a small SVG stretched to fit (non-scaling-stroke keeps the
   line 2px and the dashes even): the run beside an entry is .tl-body::before,
   positioned against the entry, and the bend below it is the entry's ::after. */
/* The motto: a mountain-biking rule (look at the line, not the tree) that is
   also what the eye-tracking work was about. */
.tl-motto {
  margin: -0.4em 0 0.6em;
  font-size: 1.15em;
  font-style: italic;
  color: var(--forest);
}
.tl-intro {
  margin-top: 0;
  color: var(--ink-soft);
}
.timeline {
  --gutter: 1.8em;   /* from the line to the text */
  --pad: 2.6em;      /* padding inside each entry, where bends start and end */
  --gap: 2.5em;      /* space between entries */
  position: relative;
  list-style: none;
  margin: 2.5em 0 7em;   /* room for the trail to breathe before the legend */
  padding: 0;
}
/* The rider: a bike badge that main.js moves along the trail as you scroll.
   It sits just after the timeline list and is placed against its parent. */
.content:has(> .tl-rider) {
  position: relative;
}
.tl-rider {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  border: 2px solid var(--trail);
  border-radius: 50%;
  background: var(--paper);
  color: var(--ink);
  pointer-events: none;
}
.tl-rider svg {
  display: block;
  width: 100%;
  height: 100%;
}
.tl-item {
  position: relative;
  margin: 0 0 var(--gap);
  padding: var(--pad) 0;
}
.tl-item:last-child {
  margin-bottom: 0;
}
/* Where the line runs beside this entry (--x) and the next (--x-next). Odd
   entries have it on the right, even ones on the left. */
.tl-item:nth-child(4n+1) { --x: 78%; --x-next: 25%; }
.tl-item:nth-child(4n+2) { --x: 25%; --x-next: 72%; }
.tl-item:nth-child(4n+3) { --x: 72%; --x-next: 19%; }
.tl-item:nth-child(4n+4) { --x: 19%; --x-next: 78%; }
.tl-item:nth-child(odd) .tl-body {
  margin-right: calc(100% - var(--x) + var(--gutter));
}
.tl-item:nth-child(even) .tl-body {
  margin-left: calc(var(--x) + var(--gutter));
}
/* The run beside the entry. */
.tl-body::before {
  content: "";
  position: absolute;
  top: var(--pad);
  bottom: var(--pad);
  left: calc(var(--x) - 20px);   /* a 40px band for the switchbacks */
  width: 40px;
  background: no-repeat 0 0 / 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 100' preserveAspectRatio='none'%3E%3Cpath d='M20 0C20 8 30 10 31 18S22 30 14 34S8 46 15 52S32 60 30 70S16 82 12 88S20 96 20 100' fill='none' stroke='%23a0522d' stroke-width='2.5' stroke-dasharray='7 4' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
}
.tl-item:nth-child(even) .tl-body::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 100' preserveAspectRatio='none'%3E%3Cpath d='M20 0C20 8 10 10 9 18S18 30 26 34S32 46 25 52S8 60 10 70S24 82 28 88S20 96 20 100' fill='none' stroke='%23a0522d' stroke-width='2.5' stroke-dasharray='7 4' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
}
/* The bend from this entry's run to the next one's. */
.tl-item::after {
  content: "";
  position: absolute;
  top: calc(100% - var(--pad));
  height: calc(var(--gap) + 2 * var(--pad));
  background: no-repeat 0 0 / 100% 100%;
}
.tl-item:nth-child(odd)::after {
  left: var(--x-next);
  right: calc(100% - var(--x));
}
.tl-item:nth-child(even)::after {
  left: var(--x);
  right: calc(100% - var(--x-next));
}
.tl-item:nth-child(4n+1)::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M100 0C100 18 88 22 74 24S48 22 46 34S62 50 58 58S30 64 22 70S0 84 0 100' fill='none' stroke='%23a0522d' stroke-width='2.5' stroke-dasharray='7 4' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
}
.tl-item:nth-child(4n+2)::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M0 0C0 18 12 22 26 24S52 22 54 34S38 50 42 58S70 64 78 70S100 84 100 100' fill='none' stroke='%23a0522d' stroke-width='2.5' stroke-dasharray='7 4' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
}
.tl-item:nth-child(4n+3)::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M100 0C100 25 80 30 64 28S36 18 30 30S44 52 36 60S12 62 8 74S0 90 0 100' fill='none' stroke='%23a0522d' stroke-width='2.5' stroke-dasharray='7 4' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
}
.tl-item:nth-child(4n+4)::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M0 0C0 25 20 30 36 28S64 18 70 30S56 52 64 60S88 62 92 74S100 90 100 100' fill='none' stroke='%23a0522d' stroke-width='2.5' stroke-dasharray='7 4' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
}
.tl-item:last-child::after {
  content: none;
}
/* The dot sits where the trail arrives at an entry, level with its date.
   The run starts exactly on --x, so the dot is centred on the line whatever
   the wobble does further down. A ring in the background colour clears the
   dashes around it. */
.tl-item::before {
  content: "";
  position: absolute;
  z-index: 1;
  top: calc(var(--pad) + 0.6em);
  left: calc(var(--x) - 7px);   /* 14px wide including the border */
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--ink-soft);
  box-shadow: 0 0 0 4px var(--paper);
}
/* Trail difficulty signs, used for the waypoints and the legend. */
.tl-green::before {
  background: var(--sign-green);
  border-color: var(--sign-green);
  border-radius: 50%;
}
.tl-blue::before {
  background: var(--sign-blue);
  border-color: var(--sign-blue);
  border-radius: 2px;
}
.tl-black::before,
.tl-double::before {
  background: var(--sign-black);
  border-color: var(--sign-black);
  border-radius: 1px;
  transform: scale(0.85) rotate(45deg);
}
/* Two diamonds side by side: the second is a shadow, offset along the
   rotated axes, and the pair is shifted left to stay centred on the line. */
.tl-double::before {
  transform: translateX(-8px) scale(0.85) rotate(45deg);
  box-shadow: 0 0 0 4px var(--paper), 12px -12px 0 0 var(--sign-black), 12px -12px 0 4px var(--paper);
}
/* The legend sits under the trail, like the key on a map. */
.content .tl-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em 1.6em;
  list-style: none;
  margin: 0 0 1.4em;
  padding: 0;
  font-size: 0.8em;
  color: var(--ink-soft);
}
.tl-legend li::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 0.6em;
  vertical-align: -1px;
  border-width: 2px;   /* colour and shape come from the sign rules above */
  border-style: solid;
}
/* Room for the second diamond. */
.tl-legend .tl-double::before {
  margin: 0 calc(0.6em + 15px) 0 8px;
}
.tl-when {
  margin: 0;
  font-size: 0.85em;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.tl-now .tl-when {
  color: var(--forest);
}
.tl-item h2 {
  margin: 0.15em 0 0;
  font-size: 1.2em;
}
.tl-where {
  margin: 0.1em 0 0.4em;
  font-style: italic;
  color: var(--ink-soft);
}
/* Labs projects: name and tagline in two columns, no rules. */
.tl-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35em 1.2em;
  margin: 0.8em 0 0;
}
.tl-list dt {
  font-weight: normal;
  margin: 0;
}
.tl-list dd {
  margin: 0;
  color: var(--ink-soft);
}
.tl-body p:last-child {
  margin: 0;
}
.tl-more {
  margin-bottom: 4em;   /* and before the footer */
  font-size: 0.9em;
  color: var(--ink-soft);
}

/* Map labels: "You are here" by the first waypoint and "Trailhead" by the
   last. */
.tl-item:first-child .tl-body::after,
.tl-item:last-child .tl-body::after {
  position: absolute;
  /* Level with the dot. Ems here are the label's smaller ones, hence / 0.7. */
  top: calc((var(--pad) + 0.6em) / 0.7);
  left: calc(var(--x) + 16px);
  transform: translateY(-50%);
  font-size: 0.7em;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}
.tl-item:first-child .tl-body::after {
  content: "You are here";
  color: var(--forest);
}
.tl-item:last-child .tl-body::after {
  content: "Trailhead";
  color: var(--trail);
}
/* The trail starts at the trailhead, so nothing runs on past it. */
.tl-item:last-child .tl-body::before {
  content: none;
}

/* On phones the trail runs down the left edge, with every entry to its right. */
@media (max-width: 600px) {
  .tl-item:nth-child(n) {
    --x: 0.6em;
    margin: 0;
    padding: 0.6em 0 2.5em;
  }
  .tl-item:nth-child(n):last-child {
    padding-bottom: 0.6em;
  }
  .tl-item:nth-child(n) .tl-body {
    margin: 0 0 0 calc(var(--x) + 1.5em);
  }
  .tl-body::before {
    top: 0;
    bottom: 0;
  }
  .tl-item::before {
    top: 1.2em;
  }
  /* Legend: two by two, so no sign ends up alone on a line. */
  .content .tl-legend {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: start;
    gap: 0.6em 2em;
  }
  /* A smaller rider, so it clears the text beside the trail. */
  .tl-rider {
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
  }
  /* Labs projects: tagline under the name, so neither column gets squeezed. */
  .tl-list {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .tl-list dd {
    margin-bottom: 0.5em;
  }
  .tl-item::after,
  .tl-item:nth-child(n) .tl-body::after {
    content: none;
  }
}
