/* ============================================================
   Shared left-rail styles — used by BOTH the list view and the
   map view so the two screens render the exact same rail. These
   components have no id; they're targeted by the classes below.
   ============================================================ */

/* The rail column shell (list sidebar + map index rail share this) */
.rail-shell {
  background: var(--surface);
  display: flex;
  flex-direction: column;
}

/* Name / pronunciation / bio block — one source of truth for the
   top margin, so the header sits at the same height on both screens. */
.rail-head { padding: 32px 24px 0; }
.rail-name {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 400;
  color: var(--fg-1);
  line-height: 1.1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.rail-pron {
  font-family: var(--font-body);
  font-size: 9px;
  color: var(--fg-3);
  letter-spacing: 0.04em;
  margin-top: 3px;
}
.rail-bio {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--fg-3);
  line-height: 1.6;
  margin-top: 16px;
}
.rail-div { height: 1px; background: var(--border-strong); margin: 18px 0; }

/* Primary nav (work / writing / about / chat). Orientation flips
   between the two screens — vertical in the list view, horizontal
   on the map — and the View Transitions API morphs between them. */
.rail-nav { display: flex; }
.rail-nav.is-vertical   { flex-direction: column; gap: 2px; }
.rail-nav.is-horizontal { flex-direction: row; flex-wrap: wrap; gap: 18px; }
/* Horizontal (map) reads as a tidy single row: drop the dash marker so the four
   items fit, and let the active state carry through color alone. */
.rail-nav.is-horizontal .rail-navlink { gap: 0; }
.rail-nav.is-horizontal .rail-navlink .dash { display: none; }

.rail-navlink {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 400;
  color: var(--fg-2);
  text-decoration: none;
  text-transform: lowercase;
  background: none;
  border: none;
  cursor: pointer;
  transition: color 150ms ease;
}
.rail-navlink:hover { color: var(--fg-1); }
.rail-navlink.is-active { color: var(--accent); }
.rail-navlink .dash {
  width: 8px;
  height: 2px;
  background: var(--border-strong);
  flex-shrink: 0;
  transition: width 200ms var(--ease-smooth), background 150ms ease;
}
.rail-navlink:hover .dash { background: var(--fg-1); }
.rail-navlink.is-active .dash { width: 16px; background: var(--accent-fill); }

/* Entrance: nav items and the LinkedIn/Resume links slide up into place on load —
   a simple A→B move with ease-in-out, staggered, no rotation. Vertical rail only,
   and only on the first mount (is-entrance): remounts mid view-transition must
   not restart it or the nav is captured at opacity 0. */
@keyframes railSlideIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.rail-nav.is-vertical.is-entrance .rail-navlink,
.rail-links.is-vertical.is-entrance .rail-link {
  animation: railSlideIn 420ms cubic-bezier(0.42, 0, 0.58, 1) both;
}
.rail-nav.is-vertical .rail-navlink:nth-child(1) { animation-delay: 120ms; }
.rail-nav.is-vertical .rail-navlink:nth-child(2) { animation-delay: 180ms; }
.rail-nav.is-vertical .rail-navlink:nth-child(3) { animation-delay: 240ms; }
.rail-nav.is-vertical .rail-navlink:nth-child(4) { animation-delay: 300ms; }
.rail-links.is-vertical .rail-link:nth-child(1) { animation-delay: 360ms; }
.rail-links.is-vertical .rail-link:nth-child(2) { animation-delay: 420ms; }
@media (prefers-reduced-motion: reduce) {
  .rail-nav.is-vertical .rail-navlink,
  .rail-links.is-vertical .rail-link { animation: none !important; }
}

/* LinkedIn / Resume links — shared between the list sidebar (vertical) and the
   foot of the map rail (a two-cell bar, standing in for the old Fit/Read buttons). */
.rail-links.is-vertical   { display: flex; flex-direction: column; gap: 6px; }
.rail-links.is-horizontal { display: flex; flex-direction: row; border-top: 1px solid var(--border-strong); }
.rail-link {
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--fg-3);
  text-decoration: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 0;
  transition: color 140ms ease;
}
.rail-link:hover { color: var(--accent); }
.rail-link-arrow { font-size: 9px; color: var(--fg-4); }
.rail-links.is-horizontal .rail-link { flex: 1; justify-content: center; gap: 8px; padding: 12px 8px; }
.rail-links.is-horizontal .rail-link:first-child { border-right: 1px solid var(--border); }

/* The content crossfade between views reads best kept short. */
::view-transition-group(*) { animation-duration: 300ms; animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1); }
/* Content changes (work / writing / about) are just a quick, subtle crossfade. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 140ms; }
/* Nav buttons slide between their vertical (list) and horizontal (map) spots as
   ONE crisp label: the outgoing snapshot is dropped and the incoming one keeps
   its natural size, left-anchored. Without this the browser stretches and
   cross-fades both copies to the morphing box — text visibly scales and the
   double exposure reads as a twist. */
::view-transition-old(rail-nav-work), ::view-transition-old(rail-nav-writing),
::view-transition-old(rail-nav-about), ::view-transition-old(rail-nav-chat) { display: none; }
::view-transition-new(rail-nav-work), ::view-transition-new(rail-nav-writing),
::view-transition-new(rail-nav-about), ::view-transition-new(rail-nav-chat) {
  animation: none;
  width: auto;
  height: auto;
}
/* The labels move in nav order — work, then writing, about, chat — each a soft
   ease-in-out glide with a small stagger. fill-mode: both holds a still-waiting
   label at its old spot until its turn (otherwise it would snap to the
   destination during the delay). */
::view-transition-group(rail-nav-work), ::view-transition-group(rail-nav-writing),
::view-transition-group(rail-nav-about), ::view-transition-group(rail-nav-chat) {
  animation-duration: 280ms;
  animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
  animation-fill-mode: both;
}
::view-transition-group(rail-nav-writing) { animation-delay: 45ms; }
::view-transition-group(rail-nav-about)   { animation-delay: 90ms; }
::view-transition-group(rail-nav-chat)    { animation-delay: 135ms; }
/* Name + pronunciation are one fixed identity block — they never animate. */
::view-transition-group(rail-identity),
::view-transition-old(rail-identity),
::view-transition-new(rail-identity) { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* Fallback for browsers without the View Transitions API: fade each view in on
   switch so the change never reads as a hard pop. (Where VT runs, it wins.) */
@keyframes viewFade { from { opacity: 0; } to { opacity: 1; } }
@supports not (view-transition-name: none) {
  .view-fade { animation: viewFade 240ms ease both; }
}
@media (prefers-reduced-motion: reduce) { .view-fade { animation: none !important; } }
