/* Foxcairn — WAYFINDER.
 * ============================================================================
 * A theme layer in the shape of Lodestar's console, tonally fantasy.
 *
 * WHAT IS BORROWED IS STRUCTURE. Lodestar reads as a lamp-lit cockpit because
 * of specific devices: an emblem with a stacked mono wordmark, panels with a
 * grid printed INSIDE them, corner rivets, and a glow that lifts the surface
 * so it never reads as murk. Those are kept. The tone is not -- a 1950s
 * console becomes a cartographer's field desk:
 *   blueprint grid   ->  a surveyor's map rule
 *   steel rivets     ->  brass corner studs
 *   atomic tangerine ->  ember gold     (already Foxcairn's accent)
 *   electric aqua    ->  ward slate     (already Foxcairn's cool)
 *
 * ⚠️ ONE NAVIGATION PATTERN AT EVERY WIDTH. The first version had a full
 * sticky rail on desktop and a bar on narrow, which meant three layout states
 * to keep correct and it broke in two of them: the rail was sticky at 100vh
 * inside a taller row so its border stopped mid-page, and jumping to a section
 * landed the heading underneath the bar. A bar plus an overlay tray is ONE
 * state everywhere. Less to hold right, and the tray can be a better object
 * than a cramped rail ever was.
 *
 * LAYERING: tokens.css = colour, density.css = type/space scale and dense
 * primitives, this = shell and chrome. No colour is redefined here; every
 * value resolves against a --fc-* token so a theme change carries through.
 * ========================================================================= */

:root {
  --bar-h:      54px;
  --grid-step:  26px;            /* a survey chain, not graph paper */
  --grid-ink:   rgba(143,154,214,.055);
  --brass:      #7a5c2e;
  --brass-lit:  #b08843;
  --tray-w:     min(21rem, 86vw);
  --plate-fill: linear-gradient(180deg,
                  color-mix(in oklab, var(--fc-surface) 88%, #000) 0%,
                  var(--fc-surface) 58%,
                  color-mix(in oklab, var(--fc-surface) 94%, #000) 100%);
  --lamp:       radial-gradient(1100px 520px at 12% -12%, rgba(241,169,60,.13), transparent 58%),
                radial-gradient(820px 500px at 100% 4%, rgba(143,154,214,.085), transparent 56%);
}

/* Ruled ground with lamplight over it. The grid alone reads as murk; the two
   together read as a lit desk. */
.wf-body {
  background-color: var(--fc-bg);
  background-image:
    var(--lamp),
    linear-gradient(var(--grid-ink) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-ink) 1px, transparent 1px);
  background-size: 100% 100%, var(--grid-step) var(--grid-step),
                   var(--grid-step) var(--grid-step);
  background-attachment: fixed;
  min-height: 100vh;
}

/* ------------------------------------------------------------------ bar */
.wf-bar {
  position: sticky; top: 0; z-index: 40; height: var(--bar-h);
  display: flex; align-items: center; gap: var(--s-4);
  padding-inline: clamp(var(--s-3), 3vw, var(--s-6));
  border-bottom: 1px solid var(--fc-line);
  /* Opaque, not translucent: it sits over scrolling content, and a see-through
     bar lets text ghost through it at exactly the moment you are reading. */
  background-color: var(--fc-bg);
  background-image:
    linear-gradient(var(--grid-ink) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-ink) 1px, transparent 1px);
  background-size: var(--grid-step) var(--grid-step), var(--grid-step) var(--grid-step);
  box-shadow: 0 1px 0 rgba(241,169,60,.16), 0 12px 26px -22px rgba(0,0,0,.95);
}
.wf-brand { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; }
.wf-emblem { width: 30px; height: 30px; display: block;
             filter: drop-shadow(0 0 10px rgba(241,169,60,.4)); }
/* A tracked wordmark needs the matching indent, or the space after its last
   letter drags the whole thing off centre. */
.wf-word {
  font-family: var(--fc-font-mono); font-size: .74rem; font-weight: 700;
  letter-spacing: .26em; text-indent: .26em; color: var(--fc-accent);
  text-transform: uppercase;
}
/* Where you are, stated in the bar. On a long page the tray is shut most of
   the time, so this is the only persistent answer to "which part am I in". */
.wf-where {
  font-family: var(--fc-font-mono); font-size: var(--t-label);
  letter-spacing: .14em; text-transform: uppercase; color: var(--fc-muted);
  border-left: 1px solid var(--fc-line); padding-left: var(--s-4);
}
.wf-bar-end { margin-left: auto; display: flex; align-items: center; gap: var(--s-3); }

.wf-trigger {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font: inherit; font-family: var(--fc-font-mono); font-size: var(--t-label);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--fc-text); background: var(--fc-surface);
  border: 1px solid var(--fc-line); border-radius: var(--fc-radius);
  padding: 7px 12px; cursor: pointer;
  transition: border-color .16s ease, color .16s ease;
}
.wf-trigger:hover { border-color: var(--fc-accent); color: var(--fc-accent); }
.wf-trigger:focus-visible { outline: 2px solid var(--fc-accent); outline-offset: 2px; }
/* The glyph is a cairn, not a hamburger: three bars narrowing upward. It says
   what the tray contains rather than merely that a menu exists. */
.wf-cairnicon { display: block; width: 15px; height: 12px; position: relative; flex: none; }
.wf-cairnicon i {
  position: absolute; left: 50%; transform: translateX(-50%);
  height: 2px; border-radius: 1px; background: currentColor;
}
.wf-cairnicon i:nth-child(1) { bottom: 0; width: 15px; }
.wf-cairnicon i:nth-child(2) { bottom: 5px; width: 11px; }
.wf-cairnicon i:nth-child(3) { bottom: 10px; width: 7px; }

/* ----------------------------------------------------------------- tray */
.wf-scrim {
  position: fixed; inset: 0; z-index: 50; background: rgba(8,5,14,.66);
  opacity: 0; pointer-events: none; transition: opacity .28s ease;
  backdrop-filter: blur(2px);
}
.wf-tray {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 60;
  width: var(--tray-w); display: flex; flex-direction: column;
  padding: var(--s-5) var(--s-5) var(--s-4);
  border-left: 1px solid var(--fc-line);
  background:
    linear-gradient(var(--grid-ink) 1px, transparent 1px) 0 0 / var(--grid-step) var(--grid-step),
    linear-gradient(90deg, var(--grid-ink) 1px, transparent 1px) 0 0 / var(--grid-step) var(--grid-step),
    var(--plate-fill);
  background-color: var(--fc-bg);
  box-shadow: -18px 0 46px -20px rgba(0,0,0,.9), inset 1px 0 0 rgba(241,169,60,.16);
  transform: translateX(100%);
  visibility: hidden;
  overflow-y: auto;
  /* ⚠️ THE DELAY IS LOAD-BEARING, in one direction only.
     visibility must flip to `visible` INSTANTLY on open, because a
     visibility:hidden element CANNOT TAKE FOCUS -- calling focus() on it is a
     silent no-op, which is exactly why focus never entered the tray. Delaying
     it by the transition duration on CLOSE is what lets the drawer finish
     sliding out instead of vanishing on the first frame.
     visibility rather than display: display cannot transition at all, and
     leaving the tray merely translated off-screen keeps its links tabbable, so
     a keyboard user would tab into a drawer nobody can see. */
  transition: transform .3s cubic-bezier(.2,.75,.3,1), visibility 0s .3s;
}
.wf-open .wf-scrim { opacity: 1; pointer-events: auto; }
.wf-open .wf-tray  { transform: none; visibility: visible; transition: transform .3s cubic-bezier(.2,.75,.3,1), visibility 0s 0s; }

.wf-tray-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--fc-line);
}
.wf-close {
  font: inherit; font-family: var(--fc-font-mono); font-size: var(--t-label);
  letter-spacing: .14em; text-transform: uppercase; cursor: pointer;
  color: var(--fc-muted); background: transparent;
  border: 1px solid var(--fc-line); border-radius: var(--fc-radius); padding: 6px 10px;
}
.wf-close:hover { color: var(--fc-accent); border-color: var(--fc-accent); }
.wf-close:focus-visible { outline: 2px solid var(--fc-accent); outline-offset: 2px; }

/* THE TRAIL. This is the reason the nav is worth opening rather than being a
   list of links: it is drawn as the path itself, each entry a cairn, and the
   one you are standing level with is lit exactly as a cairn is when you reach
   it. On a dashboard a rail is borrowed furniture; here the device is the
   subject. */
.wf-nav { display: flex; flex-direction: column; margin-top: var(--s-4); position: relative; }
.wf-nav::before {
  content: ""; position: absolute; left: 10px; top: 18px; bottom: 18px; width: 2px;
  background: var(--fc-line); border-radius: 2px;
}
.wf-nav a {
  position: relative; display: block;
  padding: var(--s-3) var(--s-3) var(--s-3) calc(var(--s-6) + 4px);
  text-decoration: none; color: var(--fc-text-2);
  border-radius: var(--fc-radius);
  transition: color .2s ease, background .2s ease;
}
.wf-nav a .n {
  display: block; font-family: var(--fc-font-display); font-size: 1.12rem; line-height: 1.2;
}
.wf-nav a .d {
  display: block; font-family: var(--fc-font-mono); font-size: var(--t-label);
  letter-spacing: .1em; text-transform: uppercase; color: var(--fc-muted); margin-top: 3px;
}
.wf-nav a::before {                       /* the cairn: two stacked stones */
  content: ""; position: absolute; left: 4px; top: 50%; margin-top: -3px;
  width: 15px; height: 6px; border-radius: 2px; background: var(--fc-line);
  box-shadow: 0 -5px 0 -1px var(--fc-line);
  transition: background .3s ease, box-shadow .3s ease;
}
.wf-nav a:hover { color: var(--fc-text); background: var(--fc-surface-2); }
.wf-nav a:focus-visible { outline: 2px solid var(--fc-accent); outline-offset: -2px; }
.wf-nav a.is-here { color: var(--fc-accent); }
.wf-nav a.is-here .d { color: var(--fc-link); }
.wf-nav a.is-here::before {
  background: var(--fc-accent);
  box-shadow: 0 -5px 0 -1px var(--fc-link), 0 0 14px rgba(241,169,60,.65);
}
.wf-tray-foot { margin-top: auto; padding-top: var(--s-5); }

/* --------------------------------------------------------------- plates
   A panel that reads as something MADE: ruled inside, gradient-filled, brass
   studs at the corners. Used sparingly -- studs on every card is noise, and
   the device only carries weight while it stays rare. */
.wf-plate {
  position: relative;
  background:
    linear-gradient(var(--grid-ink) 1px, transparent 1px) 0 0 / var(--grid-step) var(--grid-step),
    linear-gradient(90deg, var(--grid-ink) 1px, transparent 1px) 0 0 / var(--grid-step) var(--grid-step),
    var(--plate-fill);
  border: 1px solid var(--fc-line);
  border-top-color: color-mix(in oklab, var(--fc-accent) 42%, var(--fc-line));
  border-radius: var(--fc-radius-lg);
  box-shadow: 0 10px 30px rgba(0,0,0,.34);
}
.wf-plate::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background:
    radial-gradient(circle 2.5px at 12px 12px, var(--brass-lit) 62%, var(--brass) 99%, transparent),
    radial-gradient(circle 2.5px at calc(100% - 12px) 12px, var(--brass-lit) 62%, var(--brass) 99%, transparent),
    radial-gradient(circle 2.5px at 12px calc(100% - 12px), var(--brass-lit) 62%, var(--brass) 99%, transparent),
    radial-gradient(circle 2.5px at calc(100% - 12px) calc(100% - 12px), var(--brass-lit) 62%, var(--brass) 99%, transparent);
  background-repeat: no-repeat;
}
.wf-plate > .wf-plate-body { padding: clamp(var(--s-4), 2.4vw, var(--s-6)); }
/* A label stamped into the case edge rather than printed on the page. */
.wf-stamp {
  position: absolute; top: -9px; left: var(--s-4);
  font-family: var(--fc-font-mono); font-size: var(--t-label);
  letter-spacing: .18em; text-transform: uppercase; color: var(--fc-accent);
  background: var(--fc-bg); padding: 0 var(--s-2);
}

/* Arriving somewhere is not an animation. A section reached by anchor is
   revealed outright, because the reader is already looking at the place they
   asked for and a fade there reads as the page failing to load. */
.js section.in-now .rise { transition: none !important; opacity: 1 !important;
                           transform: none !important; }

/* Prose capped in CHARACTERS. A percentage width keeps growing on a wide
   monitor until lines are too long to track back from; ~68 stops at the point
   the eye starts losing the start of the next line. */
.wf-measure { max-width: 68ch; }

/* ⚠️ Anchor targets must clear the sticky bar. Without this, jumping to a
   section puts its heading exactly underneath the bar -- the content is there
   and simply cannot be seen, which is indistinguishable from a broken link. */
:target, .wf-anchor { scroll-margin-top: calc(var(--bar-h) + var(--s-4)); }

@media (max-width: 34rem) {
  .wf-where { display: none; }        /* the tray states it; the bar need not */
}
@media (max-width: 26rem) {
  .wf-word { display: none; }         /* the emblem carries it at this width */
}
@media (prefers-reduced-motion: reduce) {
  .wf-tray, .wf-open .wf-tray { transition: none; }
  .wf-scrim { transition: none; }
}
