/* blueshed.co.uk's own look.

   templates/site.html links it after site.css — duckdown's base, which the
   site no longer carries a copy of: duckdown supplies it, so upgrading
   duckdown upgrades the base. Every page has both, and nothing has to be
   written on the pages themselves.

   The base draws everything from the variables below; the rules after them
   are what a variable can't say — tracking, weight, rhythm, and the header
   that carries the mark. Nothing the base already says is repeated here. */

:root {
  /* The platform's own interface face: SF on a Mac, Segoe UI Variable on
     Windows, Roboto on Android. Nothing to download, and always current.
     (The logo's wordmark is Helvetica Neue Light — it stays artwork, so it
     renders the same everywhere rather than falling back to Arial.) */
  --font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI Variable Text",
               "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-heading: var(--font-body);
  --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;

  /* Straight off the logo: the roundel's blue-grey and the tree's grey. */
  --brand: #a3b2c7;
  --brand-ink: #666666;

  /* A panel wash at the brand's hue (215°). Not a mix of --brand itself: at
     24% saturation it lands on grey the moment it's lightened, which is what
     --surface already is. This holds the hue and raises the saturation, so a
     pale tint still reads as blue. */
  --wash: #eaf1fb;

  /* The same hue as --brand (215°), taken dark enough to read as a link:
     #a3b2c7 on white is 2.2:1, which fails; this is 6.9:1. */
  --accent: #3e5b84;

  --measure: 45rem;
  --radius: 10px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --accent: #94add1; /* the brand hue again, 8.3:1 on the dark background */
    --wash: #18202c;   /* and the panel, lifted off the page by the same hue */
  }
}

/* --- The header: the mark, then the navigation, under one rule --- */

header.site {
  position: relative;      /* the search panel hangs off it on a narrow screen */
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin-bottom: 3rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--border);
}

/* The nav element is the flex item, so growing it is what pushes anything
   after it — the search button — to the right edge. Growing the ul inside it
   does nothing; that was harmless while the nav was the last thing here. */
header.site > nav {
  flex: 1;
  min-width: 0;
}

header.site ul.nav {
  margin: 0;
  padding: 0;
  border-bottom: 0;
}

.mark {
  flex: none;
  line-height: 0;
}

.mark img {
  display: block;
}

/* A heading the page doesn't show. The menu already says the name, so the
   masthead went — but the document still needs somewhere to say what it is,
   for a screen reader and for search. */
h1.offscreen {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- The brand blue where it decorates rather than informs --- */

/* The roundel's blue is too light to carry text (2.2:1 on white, so --accent
   is the darker relative for links). As a rule or an underline it has no
   contrast to meet, and it lifts the page. The current page is still named by
   its darker text as well, so the colour isn't carrying the state alone. */

ul.nav a[aria-current] {
  text-decoration-color: var(--brand);
  text-decoration-thickness: 3px;
}

nav.toc {
  border-left-width: 4px;
  border-left-color: var(--brand);
  background: var(--wash);
}

/* A diagram on its own line is a figure: give it room and centre it. */
p > img:only-child {
  display: block;
  margin: 2.4rem auto;
}

/* --- Typography --- */

/* Tight tracking and real weight, the way an interface face wants to be set.
   The default 700 at these sizes reads heavy in a variable font. */
:is(h1, h2, h3, h4) {
  font-weight: 650;
  letter-spacing: -0.021em;
}

h1 {
  font-size: clamp(2.1rem, 1.6rem + 2vw, 3rem);
  letter-spacing: -0.032em;
  margin-bottom: 0.7em;
}

h2 {
  margin-top: 2.6em;
  font-size: 1.6rem;
}

/* The date line under a journey heading. It asks for an explicit class
   rather than matching an italic: CSS :only-child counts elements and
   ignores text, so `h2 + p em:only-child` also caught every paragraph whose
   one element happened to be an emphasis — a sentence, quietly shrunk. */
p.standfirst {
  margin-top: -0.9em;
  color: var(--muted);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

/* The code line under a journey section: a footnote, not part of the prose. */
p.code {
  margin-top: -0.4em;
  color: var(--muted);
  font-size: 0.875rem;
}

p.code code {
  font-size: 0.95em;
}

/* An article's standfirst — Medium shows it under the title. */
p.kicker {
  margin-top: -0.2em;
  margin-bottom: 1.6em;
  color: var(--muted);
  font-size: 1.15rem;
  line-height: 1.4;
}

/* A title photograph: full measure, and it sets the page going. Matched by
   folder — the photographs live under articles/ and journey/, the diagrams
   sit in images/ itself and keep their own size. */
p > img[src^="/static/images/articles/"],
p > img[src^="/static/images/journey/"],
p > img[src^="/static/images/home/"] {
  width: 100%;
  border-radius: var(--radius);
  margin: 0 0 1.8rem;
}

/* A kicker sitting above the title, as a kicker traditionally does: it needs
   less air beneath it than one used as a standfirst. */
p.kicker + h1 {
  margin-top: 0.1em;
}


/* --- Search ---
   duckdown's own site.css draws the search: the magnifier, the panel, the
   results, and its move to below the header on a narrow screen. Two things
   are this site's: the magnifier takes the brand's blue when it's wanted,
   and the panel takes the wash. */

.search-toggle:hover,
.search[data-open] .search-toggle {
  color: var(--accent);
}

.search-panel {
  background: var(--wash, var(--bg));
}

/* Below 34rem the base puts the panel under the header; the header's own
   gap closes up a little to give the wrapped navigation room. */
@media (max-width: 34rem) {
  header.site {
    gap: 0.8rem;
  }

  /* Three names in a row at a phone's width, rather than "Journey" wrapping
     under the rest: a little smaller, a little closer. */
  header.site ul.nav {
    column-gap: 1rem;
    font-size: 0.9em;
  }
}

/* Narrower still there isn't room for all three, and the mark beside them
   already says blueshed.co.uk and goes home — so the name gives way to it. */
@media (max-width: 22rem) {
  header.site ul.nav li:first-child {
    display: none;
  }
}

/* A dated page says when, above its title: an article from 2021 about Vue 3
   reads differently from one written last week, and a reader arriving from a
   search result has no other way to know. Pages without a date: say nothing. */
body > time {
  display: block;
  margin-bottom: -0.5rem;
  color: var(--muted);
  font-size: 0.9em;
}
