/* ==========================================================================
   bottom-bar.css  —  the persistent curved dock and its central AI button.
   ------------------------------------------------------------------------
   Extracted verbatim from site-chrome.css so that all four network sites share
   one definition. It used to live only inside site-chrome.css, which OSI alone
   linked: the other three rendered the dock markup from _includes/bottom-bar.html
   with no stylesheet behind it, so the bar came up position:static with a
   zero-height canvas and a 24x27 inline AI button.

   Kept in its own file rather than linking site-chrome.css everywhere, because
   that file also owns .site-header, where it sets position:static. FPM and
   neohiro ship a sticky header, so linking it wholesale would have silently
   changed their top bar too.

   Site identity for the bar branding is site.shell from _config.yml, read by
   _includes/bottom-bar.html.
   ========================================================================== */


:root {
  --bottom-bar-h: 72px;
  --ai-btn-size: 64px;
  --chrome-gap: 12px;
  /* Total always-on chrome at the bottom of the viewport. */
  --chrome-bottom: var(--bottom-bar-h);
}

/* Reserve room so content can scroll clear of the fixed chrome at the bottom
 * of the viewport. Every page carries the bottom bar, so every page needs its
 * height. The auth dock is now integrated into the bottom bar via the AI button. */
body {
  padding-bottom: var(--bottom-bar-h);
}

/* Ensure ecosystem network frame clears the curved bottom bar.
 * The shared ecosystem-network.css uses --ai-dock-h which no longer exists;
 * override with our actual bottom bar height. */
.footer-ecosystem {
  margin-bottom: var(--bottom-bar-h);
}

/* When conversation is open, the bottom bar slides down, so add extra space */
body.ai-conv-active .footer-ecosystem {
  margin-bottom: calc(var(--bottom-bar-h) + var(--conv-extra-space, 80px));
}

/* The custom scroll animation drives scroll position per-frame; CSS smooth
 * scrolling would fight it. assets/js/section-nav.js sets this attribute. */
html[data-scroll-anim] {
  scroll-behavior: auto;
}

/* style.css sets scroll-padding-top for a sticky header. The top bar here is
 * static, so that offset is no longer wanted; replace it with the gap we
 * actually want above a heading, plus room for the bottom chrome. Applies to
 * native fragment jumps too (browser back/forward, JS disabled). */
html {
  scroll-padding-top: var(--chrome-gap);
  scroll-padding-bottom: calc(var(--bottom-bar-h) + var(--chrome-gap));
}

/* ---------------------------------------------------------------------------
 * Bottom bar (persistent) — curved with central AI button
 * ------------------------------------------------------------------------- */

.bottom-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 900;
  height: var(--bottom-bar-h);
  pointer-events: none; /* Let clicks pass through to children */
  display: grid;
  /* Three columns: chips | AI button | CTA. The button is centred by the grid,
     not by flex spacing, because flex cannot centre an item while a sibling is
     flex:1 -- the leftover width all lands on one side and the button drifts. */
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
  column-gap: 8px;
  padding: 0 max(1rem, env(safe-area-inset-right)) 0 max(1rem, env(safe-area-inset-left));
  background: transparent;
}

/* Explicit column placement. `grid-template-columns` alone is not enough: grid
 * auto-placement fills cells in order, so on the three sites that have no
 * section chips (FPM, neohiro, transhumanists all render no `.bottom-bar__left`)
 * the AI button was the FIRST child and landed in column 1, with the CTA in
 * column 2. The middle `auto` track was then sized to the AI button but sat
 * empty, which pushed the button visibly off-centre. Pinning each child to its
 * own column keeps the AI button centred whether or not the chips exist. */
.bottom-bar__left {
  grid-column: 1;
}

.bottom-bar__ai {
  grid-column: 2;
}

.bottom-bar__right {
  grid-column: 3;
}

/* Curved canvas behind the bar — the top edge bows upward, so the bar reads as a
   curved shelf rather than a flat strip, and the central AI button sits in the
   dip of the sweep. */
.bottom-bar__canvas {
  position: absolute;
  inset: 0;
  /* The elliptical horizontal/vertical radii give the top edge a wide, shallow
     arc instead of two circular corner arcs. A plain `3rem 3rem 0 0` only rounds
     the two corners and leaves the middle of the edge dead flat, which is what
     made it read as a rectangle. */
  border-radius: 3rem 3rem 0 0 / 2.25rem 2.25rem 0 0;
  /* Fallbacks first, then the --color-* names. This file is shared by all four
     sites and the token vocabulary differs: OSI defines --color-surface /
     --color-border, while FPM, neohiro and transhumanists define --bg-card /
     --bg-elevated / --border. Without both lists the canvas resolved to an
     invalid colour and rendered fully transparent, so the bar had no surface
     and no visible curve on three of the four sites. */
  background: var(--bg-card, var(--color-surface, #ffffff));
  border-top: 1px solid var(--border, var(--color-border, rgba(127, 127, 127, 0.25)));
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.1), 0 -1px 0 var(--border, var(--color-border, rgba(127, 127, 127, 0.25)));
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  pointer-events: none;
  z-index: -1;
}

/* The upward sweep, drawn as a light-catching highlight along the arc so the
   curvature is legible on a surface-coloured bar. Purely decorative. */
.bottom-bar__canvas::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.5),
    rgba(255, 255, 255, 0) 38%
  );
  opacity: 0.6;
  pointer-events: none;
}

@media (prefers-color-scheme: dark) {
  .bottom-bar__canvas::after {
    background: linear-gradient(
      to bottom,
      rgba(255, 255, 255, 0.09),
      rgba(255, 255, 255, 0) 38%
    );
  }
}

/* Dark-mode tint. Uses the shared token vocabulary with the --color-* names as
   a second choice, because this file is shared by all four sites and they do not
   agree on names: OSI defines --color-surface / --color-border, the other three
   define --bg-card / --border. Resolving only one set left the canvas untinted,
   or transparent, on three of the four. */
@media (prefers-color-scheme: dark) {
  .bottom-bar__canvas {
    background: color-mix(in srgb, var(--bg-card, var(--color-surface, #111820)) 92%, transparent);
    box-shadow: 0 -4px 32px rgba(0, 0, 0, 0.5),
                0 -1px 0 var(--border, var(--color-border, rgba(127, 127, 127, 0.25)));
  }
}

/* Left section chips — horizontally scrollable, with arrow affordances that
   only appear when the strip genuinely overflows. */
.bottom-bar__left {
  pointer-events: auto;
  /* Grid child now, so flex sizing no longer applies. min-width:0 keeps the
     scroll strip shrinkable inside its 1fr column. */
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding-right: calc(var(--ai-btn-size) / 2 + 1rem);
  margin-left: -0.5rem;
}

/* The scrollable strip IS the list.
   This used to be a wrapper (.bottom-bar__scroller) around .bottom-bar__list,
   and both carried overflow-x: auto. That split the responsibility in a way that
   silently disabled the arrow buttons: the wrapper's scrollWidth equalled its
   clientWidth (the overflowing content belonged to the inner <ul>), so
   bottom-bar.js measured "no overflow" and never revealed the arrows -- while the
   chips were in fact 1078px wide inside a 176px strip, i.e. nine tenths of the
   navigation unreachable except by touch-scrolling a strip with no visible
   affordance. One element now scrolls, and that is the element measured. */
.bottom-bar__list {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  list-style: none;
  margin: 0;
  padding: 0.5rem 0.5rem 0.5rem 1rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* Smooth horizontal scrolling is motion. Under reduced-motion the arrow buttons
   have to move the strip instantly or the control looks like it is ignoring the
   click. */
@media (prefers-reduced-motion: reduce) {
  .bottom-bar__list {
    scroll-behavior: auto;
  }
}

/* Arrow buttons. Hidden by default because a bar whose chips fit has nothing to
   scroll; `data-bar-overflow="true"` is set on .bottom-bar__left by
   bottom-bar.js once the strip is measured wider than its box. Without JS they
   stay hidden, which degrades to the previous plain chip strip. */
.bottom-bar__scroll-btn {
  flex: 0 0 auto;
  display: none;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  margin: 0 2px;
  padding: 0;
  border: 1px solid var(--border, var(--color-border, rgba(127, 127, 127, 0.25)));
  border-radius: 50%;
  background: var(--bg-elevated, var(--color-surface, #ffffff));
  color: var(--color-text, #1a1a1a);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  pointer-events: auto;
  transition: background var(--transition), opacity var(--transition);
}

.bottom-bar__left[data-bar-overflow="true"] .bottom-bar__scroll-btn {
  display: inline-flex;
}

.bottom-bar__scroll-btn:hover:not(:disabled) {
  background: var(--color-stage, var(--bg-elevated, #f0f0f0));
}

.bottom-bar__scroll-btn:focus-visible {
  outline: 3px solid #b8860b;
  outline-offset: 2px;
}

/* Disabled means "already at that end", not "broken" -- kept at reduced opacity
   rather than hidden so the strip does not reflow as you reach an end. */
.bottom-bar__scroll-btn:disabled {
  opacity: 0.3;
  cursor: default;
}

/* The .bottom-bar__list rule itself lives with .bottom-bar__left above, together
   with the scroll-affordance buttons that measure it. This used to be a second
   definition of the same selector further down this sheet, which silently won
   (same specificity, later in the file) and reset `flex` to 0 1 auto -- undoing
   the sizing that keeps the strip shrinkable inside its grid column. One
   definition, one place. */
.bottom-bar__list::-webkit-scrollbar {
  display: none;
}

.bottom-bar__item {
  flex: 0 0 auto;
}

.bottom-bar__link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.45rem 0.85rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--color-text, var(--fg, #eceff1));
  text-decoration: none;
  transition: background var(--transition), color var(--transition), transform var(--transition);
}
.bottom-bar__link:hover,
.bottom-bar__link:focus-visible {
  background: var(--color-surface-alt, var(--bg-elevated, #161e26));
  color: var(--color-heading, var(--fg, #eceff1));
  text-decoration: none;
  transform: translateY(-1px);
}

/* Current-section marker, driven by assets/js/section-nav.js. */
.bottom-bar__link[aria-current="true"] {
  background: var(--color-stage, var(--accent, #7c4dff));
  color: #fff;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(255, 77, 141, 0.35);
}

/* Central AI Button — protrudes upward from the curved bar */
.bottom-bar__ai {
  pointer-events: auto;
  position: relative;
  z-index: 10;
  width: var(--ai-btn-size);
  height: var(--ai-btn-size);
  margin: 0 0.5rem;
  transform: translateY(calc(var(--ai-btn-size) * -0.45));
  border: none;
  border-radius: 50%;
  background: var(--color-stage, var(--accent, #7c4dff));
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 20px rgba(255, 77, 141, 0.45), 0 0 0 3px var(--color-surface, var(--bg-card, #111820));
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 0.25s ease,
              background 0.2s ease;
  flex-shrink: 0;
}

.bottom-bar__ai:hover {
  transform: translateY(calc(var(--ai-btn-size) * -0.55)) scale(1.08);
  box-shadow: 0 8px 32px rgba(255, 77, 141, 0.55), 0 0 0 3px var(--color-surface, var(--bg-card, #111820));
  background: var(--color-stage-hover, var(--accent-strong, #9d7aff));
}

.bottom-bar__ai:focus-visible {
  outline: 3px solid #b8860b;
  outline-offset: 3px;
}

.bottom-bar__ai[aria-expanded="true"] {
  background: var(--color-stage-hover, var(--accent-strong, #9d7aff));
  box-shadow: 0 8px 32px rgba(255, 77, 141, 0.55), 0 0 0 3px var(--color-surface, var(--bg-card, #111820));
}

@media (prefers-reduced-motion: no-preference) {
  .bottom-bar__ai {
    animation: ai-btn-float 3s ease-in-out infinite;
  }
}

@keyframes ai-btn-float {
  0%, 100% { transform: translateY(calc(var(--ai-btn-size) * -0.45)); }
  50% { transform: translateY(calc(var(--ai-btn-size) * -0.52)); }
}

.bottom-bar__ai-ring {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.25) 0%, transparent 70%);
}

.bottom-bar__ai-icon {
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.bottom-bar__ai:hover .bottom-bar__ai-icon {
  transform: scale(1.15) rotate(-10deg);
}

.bottom-bar__ai-pulse {
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: var(--color-stage, var(--accent, #7c4dff));
  opacity: 0.4;
  animation: ai-pulse-ring 2.5s ease-out infinite;
  pointer-events: none;
}

@keyframes ai-pulse-ring {
  0% { transform: scale(1); opacity: 0.4; }
  70% { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

/* Right side CTA */
.bottom-bar__right {
  pointer-events: auto;
  /* Grid child now: no flex sizing. justify-self pushes the CTA to the outer
     edge of its 1fr column so it sits hard right regardless of how wide the
     left chip strip happens to be. */
  justify-self: end;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-left: calc(var(--ai-btn-size) / 2 + 1rem);
  margin-right: -0.5rem;
}

.bottom-bar__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 1rem;
  border-radius: 999px;
  background: var(--color-stage, var(--accent, #7c4dff));
  color: #fff;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  text-decoration: none;
  box-shadow: 0 2px 10px rgba(255, 77, 141, 0.35);
  transition: all var(--transition);
}
.bottom-bar__cta:hover,
.bottom-bar__cta:focus-visible {
  background: var(--color-stage-hover, var(--accent-strong, #9d7aff));
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 4px 16px rgba(255, 77, 141, 0.45);
}
.bottom-bar__cta:focus-visible {
  outline: 3px solid #b8860b;
  outline-offset: 2px;
}

.bottom-bar__cta-icon {
  font-size: 1rem;
  line-height: 1;
}

/* When conversation is open, slide the bottom bar down */
body.ai-conv-active .bottom-bar {
  transform: translateY(calc(var(--bottom-bar-h) + 16px));
  pointer-events: none;
}

body.ai-conv-active .bottom-bar__ai {
  pointer-events: none;
}

/* Responsive */
@media (max-width: 600px) {
  :root {
    --bottom-bar-h: 68px;
    --ai-btn-size: 56px;
  }
  .bottom-bar__list {
    gap: 0.2rem;
    padding: 0.4rem 0.4rem 0.4rem 0.8rem;
  }
  .bottom-bar__link {
    padding: 0.4rem 0.7rem;
    font-size: 0.8rem;
  }
  .bottom-bar__cta {
    padding: 0.45rem 0.85rem;
    font-size: 0.8rem;
  }
  .bottom-bar__cta-icon {
    display: none;
  }
  .guide-section > h2 {
    font-size: 1.35rem;
  }

  /* On a phone the three-column grid cannot hold fifteen section chips, a 56px
     AI button and a CTA: measured at 544px the strip was squeezed to 176px,
     which showed about three chips out of fifteen. The CTA is the first thing
     that should go -- it is the one affordance on the page that also exists as a
     normal link in the header and the footer, whereas the chip strip and the AI
     button only exist here. Dropping it lets the two 1fr tracks share the width,
     and the arrows make the remaining overflow navigable. */
  .bottom-bar__right {
    display: none;
  }

  /* With the right column gone the AI button still owns the middle track, so the
     chips get the left one at full width rather than half. */
  .bottom-bar__left {
    padding-right: calc(var(--ai-btn-size) / 2 + 0.5rem);
    margin-left: -0.35rem;
  }
}