/* ─────────────────────────────────────────────────────────────────────────────
   project-chrome.css — the one bar every ernan.dev project page wears.
   CANONICAL SOURCE: portfolio/shared/project-chrome.css
   Vendored copies in watch-timegrapher/static/ and aic/viz/ are written by
   `npm run sync:projects` in the portfolio. Do not edit the copies.

   Two rules keep this safe to drop into any page:
     1. Every token and class is `--pc-*` / `.pc-*`, so it cannot collide with
        a project's own variables — the projects keep their own palettes.
     2. Every property a host's global element rules might set (button, a, svg)
        is reset explicitly here. `.pc-bar button` outranks a bare `button`
        selector, which is exactly what the timegrapher's full-width accent
        button rule would otherwise do to the theme toggle.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Tokens ───────────────────────────────────────────────────────────────────
   The bar takes its colours from the page it sits on. A host sets four tokens
   to its own palette, in a plain :root block, and the rest is derived:

     --pc-host-solid   the page background the bar sits flush against
     --pc-host-fg      primary text (also the hover colour)
     --pc-host-muted   resting colour of the back link and toggle
     --pc-host-line    the hairline under the bar

   Reference the host's own variables rather than copying values — a single
   `--pc-host-solid: var(--bg)` tracks light and dark automatically, because
   custom properties resolve where they are used, not where they are declared.

   The `-host-` indirection is what makes that one block enough. The fallbacks
   below have to live in `:root[data-theme="dark"]` to switch with the theme,
   and that selector (0,2,0) outranks a host's plain `:root` (0,1,0) no matter
   the source order — so fallbacks assigned directly to `--pc-solid` would
   silently win back in dark mode and undo the host's palette. Resolving
   `--pc-solid` from `--pc-host-solid` with the fallback as var()'s second
   argument moves the choice out of the cascade, where specificity cannot
   reach it.

   Structure — the bar's height, layout and control styling — is fixed for
   everyone; only the colours follow the host.
   ────────────────────────────────────────────────────────────────────────── */

/* Fallbacks: ernan.dev's shell, used by the portfolio's own pages and by any
   host that sets nothing. */
:root {
  --pc-fallback-solid: #f8f7f5;
  --pc-fallback-fg:    #1a1a1a;
  --pc-fallback-muted: #5f5f5f;
  --pc-fallback-line:  #e5e7eb;
}

/* No-JS / pre-hydration only: the chrome script always writes an explicit
   data-theme, so this decides the first paint just when scripting is off. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --pc-fallback-solid: #1a1a1a;
    --pc-fallback-fg:    #e5e5e5;
    --pc-fallback-muted: #a3a3a3;
    --pc-fallback-line:  #374151;
  }
}

/* Both mechanisms, because the site shell toggles a `.dark` class while the
   project pages key off `data-theme`. The chrome script writes both. */
:root[data-theme="dark"],
:root.dark {
  --pc-fallback-solid: #1a1a1a;
  --pc-fallback-fg:    #e5e5e5;
  --pc-fallback-muted: #a3a3a3;
  --pc-fallback-line:  #374151;
}

:root {
  --pc-solid: var(--pc-host-solid, var(--pc-fallback-solid));
  --pc-fg:    var(--pc-host-fg,    var(--pc-fallback-fg));
  --pc-muted: var(--pc-host-muted, var(--pc-fallback-muted));
  --pc-line:  var(--pc-host-line,  var(--pc-fallback-line));

  /* Derived, so a host never restates them: the translucent fill is the page
     colour, and the hover wash is the text colour at low opacity — which lands
     correctly on a dark page and a light one without a second block. */
  --pc-bg:    color-mix(in srgb, var(--pc-solid) 92%, transparent);
  --pc-hover: color-mix(in srgb, var(--pc-fg) 8%, transparent);

  --pc-height: 52px;
  /* Host pages that already pad their own <body> restate that padding here so
     the bar's offset adds to it instead of replacing it. */
  --pc-body-pad: 0px;
}

/* ── The bar ──────────────────────────────────────────────────────────────── */
.pc-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  height: var(--pc-height);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 16px;
  margin: 0;
  background: var(--pc-bg);
  border-bottom: 1px solid var(--pc-line);
  color: var(--pc-fg);
  /* Manrope is the one piece of typography shared across all three projects;
     each keeps its own body face below the bar. */
  font-family: Manrope, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
}

@supports (backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px)) {
  .pc-bar {
    -webkit-backdrop-filter: saturate(1.6) blur(10px);
    backdrop-filter: saturate(1.6) blur(10px);
  }
}

/* Opaque where blur is unavailable, so page content never shows through. */
@supports not ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
  .pc-bar { background: var(--pc-solid); }
}

html.pc-has-bar body {
  padding-top: calc(var(--pc-height) + var(--pc-body-pad));
}

/* For hosts that lay the bar out themselves rather than letting the script
   inject it — the Product Agent island is a flex column that owns its own
   full-height layout, and a fixed bar would float over its first row. Same
   bar, same tokens, just in flow. */
.pc-bar--static {
  position: static;
  flex: none;
}

.pc-left,
.pc-right {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* ── Back link ────────────────────────────────────────────────────────────── */
.pc-bar .pc-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  margin: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--pc-muted);
  font: inherit;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.15s, background-color 0.15s;
}
.pc-bar .pc-back:hover { color: var(--pc-fg); background: var(--pc-hover); }
.pc-bar .pc-back:focus-visible {
  outline: 2px solid var(--pc-fg);
  outline-offset: 1px;
}

/* ── Theme toggle ─────────────────────────────────────────────────────────── */
.pc-bar .pc-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: none;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--pc-muted);
  font: inherit;
  cursor: pointer;
  transition: color 0.15s, background-color 0.15s;
  -webkit-appearance: none;
  appearance: none;
}
.pc-bar .pc-toggle:hover { color: var(--pc-fg); background: var(--pc-hover); }
.pc-bar .pc-toggle:focus-visible {
  outline: 2px solid var(--pc-fg);
  outline-offset: 1px;
}

.pc-bar svg {
  display: block;
  width: 16px;
  height: 16px;
  flex: none;
  color: inherit;
}

/* Only one of the two icons is ever in the DOM's flow; swapping visibility in
   CSS rather than JS keeps the toggle instant and avoids a re-render. */
.pc-bar .pc-sun  { display: none; }
:root[data-theme="dark"] .pc-bar .pc-sun,
:root.dark .pc-bar .pc-sun  { display: block; }
:root[data-theme="dark"] .pc-bar .pc-moon,
:root.dark .pc-bar .pc-moon { display: none; }

/* ── Mobile ───────────────────────────────────────────────────────────────── */
@media (max-width: 560px) {
  .pc-bar { padding: 0 10px; }
  .pc-bar .pc-back-label { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .pc-bar, .pc-bar * { transition: none !important; }
}
