/* =============================================================================
   THE SITE HEADER — one component, two documents.

   Beans is a static page that fetches its own content; the Journal is rendered
   on the server for search engines. They will stay two documents. But the bar
   across the top of both is one thing, and it has to be *literally* one thing,
   not two that were drawn to look alike.

   It was two. The Beans page carried its own copy in an inline <style> and the
   Journal's lived in styles.css, and the copies had drifted:

     - a different logo image (a dripper on one, a leaf on the other)
     - the padding was on .nav in one and on the wrapper in the other, so the
       element's box differed by ~74px across and ~46px down
     - a 14px bottom padding on one side only
     - the Journal's copy had no phone breakpoints at all, so it ran off the
       right edge below ~700px

   None of that shows while you sit on one page. It shows the moment you cross
   between them: the view transition names the header in both documents, so the
   browser morphs one box into the other — and animating a box that "should"
   be identical from one wrong position to another is exactly the jitter this
   file exists to remove. With one stylesheet and one piece of markup there is
   nothing left to animate, so the header simply stays put.

   Values are literal rather than var()-based on purpose: the two documents
   define different custom properties, and a token that resolves differently on
   either side would put the drift straight back.

   Loaded by index.html and by the Journal's <head> (see routes/web/blog/
   shared.ts). Anything page-specific — the Beans entrance animation, the
   Journal's own layout — stays with its page.
   ========================================================================== */

/* Cross-document view transitions. Both documents opt in, and both name the
   nav, which is what tells the browser the two headers are the same object
   rather than two things to cross-fade. */
@view-transition { navigation: auto; }

/* Reserve the scrollbar's gutter whether or not the page happens to need one.
   On any platform with classic scrollbars a page that scrolls is ~15px
   narrower than one that does not, so crossing from a long page to a short one
   slides the whole header sideways — the same jump this file exists to remove,
   arriving by a different route. Costs a strip nobody looks at; macOS, with
   overlay scrollbars, never even reserves it. */
html { scrollbar-gutter: stable; }

.site-header {
  position: relative;
  z-index: 20;
  padding: clamp(22px, 3vh, 46px) clamp(28px, 4.2vw, 74px) 14px;
}

/* On a coffee, the Beans page is one composed 100svh stage and the bar floats
   over it. Only the wrapper moves — .nav keeps the same box either way, which
   is what keeps the transition still. */
body[data-view="detail"] .site-header {
  position: absolute;
  inset: 0 0 auto 0;
}

.nav {
  view-transition-name: site-header;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  color: #2a1d14;
}

/* Columns are assigned explicitly rather than left to auto-placement, so the
   logo stays left and the pill stays centred whatever else the row holds. */
.nav .logo {
  grid-column: 1;
  justify-self: start;
  display: flex;
  align-items: center;
  gap: 10px;
  /* It is an <a>, and nothing had ever said otherwise — so the browser drew it
     with its own link colour and underline, which is why the wordmark once
     came out purple. */
  color: #2a1d14;
  text-decoration: none;
  font-family: "Noto Serif", Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(18px, 1.35vw, 26px);
  letter-spacing: .3px;
  white-space: nowrap;
  /* A light halo, not a dark one: it has to survive a pale sheet of paper. */
  text-shadow: 0 1px 0 rgba(255, 252, 244, .6);
}

.nav .logo .mark {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: #ffffff;
  display: grid;
  place-items: center;
  box-shadow: 0 3px 10px rgba(30, 14, 4, .22);
  flex: none;
}

/* The dripper is 160x227 — taller than it is wide. Fitting rather than filling
   keeps it from being squashed into the circle, and the height cap is what
   leaves it a margin instead of touching the rim. */
.nav .logo .mark img {
  width: auto;
  height: 62%;
  max-width: 64%;
  object-fit: contain;
  display: block;
}

.nav ul {
  grid-column: 2;
  justify-self: center;
  list-style: none;
  display: flex;
  gap: 4px;
  margin: 0;
  padding: 8px;
  background: rgba(255, 252, 244, .5);
  border: 1px solid rgba(122, 95, 42, .22);
  border-radius: 999px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 10px 26px rgba(90, 66, 30, .12);
}

.nav li {
  padding: 13px 28px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background .25s, color .25s;
}

.nav li a {
  color: inherit;
  text-decoration: none;
}

.nav li.active {
  background: #2a1d14;
  color: #f6efe2;
  font-weight: 700;
}

@media (hover: hover) {
  .nav li:not(.active):hover { background: rgba(122, 95, 42, .1); }
}

.nav li:not(.active):active { background: rgba(122, 95, 42, .16); }

/* ---- the trail ----
   There used to be a round "‹ back" button in the third column here, which on
   a phone collapsed to a chevron in a circle and said nothing at all — one
   step, no destination, no context. A breadcrumb is the same escape hatch with
   the answer written on it, and it is what the Journal already used. So the
   button is gone and the trail is the way up on both sides.

   It sits under the bar rather than in it: the bar is three fixed slots and a
   path is as long as the path is. */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: #6b584a;
}

.breadcrumb a {
  color: #6b4f1f;
  text-decoration: none;
}

@media (hover: hover) {
  .breadcrumb a:hover { text-decoration: underline; }
}

.breadcrumb [aria-current] { color: #2a1d14; }

/* In the bar it is the second row; the Journal keeps its own placement, since
   there the trail belongs to the article, not to the chrome. */
.site-header .breadcrumb { margin-top: 11px; }
.site-header .breadcrumb[hidden] { display: none; }

@supports (padding: env(safe-area-inset-left)) {
  .site-header {
    padding-left: max(clamp(28px, 4.2vw, 74px), env(safe-area-inset-left));
    padding-right: max(clamp(28px, 4.2vw, 74px), env(safe-area-inset-right));
  }
}

/* ---- tablet landscape: same bar, less room ---- */
@media (min-width: 700px) and (max-width: 1199px) and (orientation: landscape) {
  .site-header { padding: clamp(14px, 2.4vh, 26px) clamp(20px, 3vw, 38px) 12px; }
  .nav .logo { font-size: 19px; }
  .nav .logo .mark { width: 46px; height: 46px; }
  .nav li { padding: 12px 22px; }
}

/* ---- tablet portrait ---- */
@media (min-width: 700px) and (max-width: 1199px) and (orientation: portrait) {
  .site-header { padding: clamp(16px, 2.2vh, 30px) clamp(24px, 4vw, 44px) 12px; }
  .nav .logo .mark { width: 50px; height: 50px; }
}

/* ---- phones ----
   Two links fit any phone, so nothing is hidden behind a burger. The back
   button drops its label — the chevron plus the section pill already say
   where the tap leads. */
@media (max-width: 699px) {
  .site-header { padding: 18px 16px 12px; }
  .nav { gap: 10px; }
  .nav .logo { font-size: 17px; }
  .nav .logo .mark { width: 38px; height: 38px; }
  .nav ul { padding: 5px; }
  .nav li { padding: 9px 15px; font-size: 13px; }
  .site-header .breadcrumb { margin-top: 9px; }
}

/* Narrower still: the wordmark goes rather than squeezing the pill, which is
   the one thing on this bar that has to stay readable. */
@media (max-width: 430px) {
  .nav .logo strong { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
  .nav li { transition: none; }
}
