/* Site header: the logo, the refresh button, the faux address bar, the credential
   dropdown behind it, and the site nav.

   THE SOURCE OF TRUTH FOR EVERY defaultcreds.lol SURFACE. The apex site, the guides
   subdomain and the podcast player all load this exact file, and all take their header
   markup from partials/header.html. Edit either one, then run

       .venv/bin/python scripts/build-header.py

   and the change lands on all three. honeypot/tests/test_header.py fails the suite when a
   page has drifted from the partial, so keeping them in step is not anyone's job to
   remember.

   Self-contained on purpose. The three sites ship three different stylesheets with three
   different sets of design tokens, so a header that borrowed each site's tokens would go
   on looking different on each site, which is the thing this file exists to stop. Every
   value the header needs is declared below as --hdr-*, scoped to .site-header so it
   cannot reach the rest of the page, and this file is linked last so it wins the cascade
   against whatever the host stylesheet says.

   --header-height is the one token left unprefixed and on :root, because it is genuinely
   shared: the apex sidebar and main column offset themselves against the header, and
   guides.css sizes its own layout from it. It is defined here and nowhere else.
*/

:root {
  --header-height: 64px;
}

.site-header {
  --hdr-max: 1280px;
  --hdr-color-bg: #121212;
  --hdr-color-bg-elevated: #1e1e1e;
  --hdr-color-bg-hover: #2a2a2a;
  --hdr-color-text: #e5e5e5;
  --hdr-color-text-secondary: #a0a0a0;
  --hdr-color-text-muted: #6b6b6b;
  --hdr-color-border: #2e2e2e;
  --hdr-color-border-strong: #404040;
  --hdr-color-accent: #22c55e;
  --hdr-color-accent-soft: rgba(34, 197, 94, 0.15);
  --hdr-color-success: #34d399;
  /* Orange, not the amber the rest of the palette uses for warnings. The honeypot
     pages already overrode it to this and they are the ones to match. */
  --hdr-color-warning: #fb923c;
  --hdr-font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --hdr-font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', Consolas, monospace;
  --hdr-text-sm: 0.875rem;
  --hdr-space-1: 0.25rem;
  --hdr-space-2: 0.5rem;
  --hdr-space-3: 0.75rem;
  --hdr-space-4: 1rem;
  --hdr-space-6: 1.5rem;
  --hdr-border-radius: 8px;
  --hdr-border-radius-sm: 6px;
  --hdr-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
  --hdr-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
  --hdr-transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* --- Site Header --- */
.site-header {
  position: sticky;
  top: 0;
  /* Must out-rank .sidebar (z:100). The faux-URL dropdown (#creds-history) is
     a descendant of this header's stacking context, so whatever z-index the
     dropdown carries is clamped by this root. When the dropdown extends
     downward past the header and overlaps the pinned sidebar, the header
     subtree needs to win the paint order. See AUDIT.md F053. */
  z-index: 110;
  background: var(--hdr-color-bg-elevated);
  border-bottom: 1px solid var(--hdr-color-border);
  height: var(--header-height);
}

.header-content {
  display: flex;
  align-items: center;
  gap: var(--hdr-space-4);
  /* One width on every surface. It used to be 1600 here and 1280 on the honeypot pages,
     which overrode it, so the header ran wider on news, guides and the podcast player
     than on the two pages it was designed against. 1280 is the one that looked right. */
  max-width: var(--hdr-max);
  margin: 0 auto;
  padding: 0 var(--hdr-space-6);
  height: 100%;
}

.logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--hdr-color-border);
  border-radius: var(--hdr-border-radius-sm);
  background: var(--hdr-color-bg-elevated);
  color: var(--hdr-color-text-secondary);
  text-decoration: none;
  transition: all var(--hdr-transition-fast);
}

.logo:hover {
  background: var(--hdr-color-bg-hover);
  color: var(--hdr-color-text);
  border-color: var(--hdr-color-border-strong);
}

.logo:focus-visible {
  outline: 2px solid var(--hdr-color-accent);
  outline-offset: 2px;
}

.logo-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  stroke-width: 2;
}

.refresh-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--hdr-color-border);
  border-radius: var(--hdr-border-radius-sm);
  background: var(--hdr-color-bg-elevated);
  color: var(--hdr-color-text-secondary);
  cursor: pointer;
  transition: all var(--hdr-transition-fast);
  font-family: inherit;
  font-size: inherit;
}

.refresh-btn:hover {
  background: var(--hdr-color-bg-hover);
  color: var(--hdr-color-text);
  border-color: var(--hdr-color-border-strong);
}

.refresh-btn:active {
  background: var(--hdr-color-bg);
}

.refresh-btn:focus-visible {
  outline: 2px solid var(--hdr-color-accent);
  outline-offset: 2px;
}

.refresh-btn svg {
  width: 18px;
  height: 18px;
  color: inherit;
  stroke: currentColor;
}

.address-bar-wrapper {
  position: relative;
  flex: 1;
  max-width: 600px;
  /* min-width: auto would be the min-content width of the faux URL, and
     creds.js picks a random pair up to ~590px wide. With the nav competing
     for the row that refused to shrink and pushed the header past the
     viewport between 769 and 1024px. The .url-text ellipsis handles the
     overflow once the wrapper is allowed to shrink. */
  min-width: 0;
}

.faux-url {
  display: flex;
  align-items: center;
  gap: var(--hdr-space-2);
  font-family: var(--hdr-font-mono);
  font-size: var(--hdr-text-sm);
  padding: var(--hdr-space-2) var(--hdr-space-3);
  background: var(--hdr-color-bg-elevated);
  border: 1px solid var(--hdr-color-border);
  border-radius: var(--hdr-border-radius);
  cursor: pointer;
  transition: all var(--hdr-transition-base);
  user-select: none;
  min-width: 280px;
  position: relative;
  z-index: 1;
}

.faux-url:hover {
  background: var(--hdr-color-bg-hover);
  border-color: var(--hdr-color-border-strong);
}

.faux-url:focus,
.faux-url[aria-expanded="true"] {
  outline: none;
  border-color: var(--hdr-color-accent);
  box-shadow: 0 0 0 3px var(--hdr-color-accent-soft);
  background: var(--hdr-color-bg);
}

.faux-url[aria-expanded="true"] {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  border-bottom-color: transparent;
}

.address-bar-icon {
  flex-shrink: 0;
  color: var(--hdr-color-success);
  opacity: 0.8;
}

.url-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.address-bar-dropdown-icon {
  flex-shrink: 0;
  color: var(--hdr-color-text-muted);
  opacity: 0.6;
  transition: transform var(--hdr-transition-fast);
}

.faux-url[aria-expanded="true"] .address-bar-dropdown-icon {
  transform: rotate(180deg);
  opacity: 1;
}

.url-protocol { color: var(--hdr-color-accent); }
.url-creds { color: var(--hdr-color-text-secondary); }
.url-password { color: var(--hdr-color-warning); }
.url-host { color: var(--hdr-color-success); }
/* The path used to borrow .url-creds, which coloured it as though it were part of the
   credential. It is the only true part of the address, so it gets the plain text colour. */
.url-path { color: var(--hdr-color-text); }

/* --- Site Nav (shared by index.html and news.html) --- */
/* Palette-only, no radii: the honeypot page's hard rules apply to this block
   unchanged, so news.html needs no exceptions for it. */
.site-nav {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-left: auto;
  flex-shrink: 0;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 2px;
  font-family: var(--hdr-font-sans);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hdr-color-text-secondary);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.site-nav a:hover {
  color: var(--hdr-color-text);
}

.site-nav a[aria-current="page"] {
  color: var(--hdr-color-text);
  border-bottom-color: var(--hdr-color-accent);
}

.site-nav a:focus-visible {
  outline: 2px solid var(--hdr-color-accent);
  outline-offset: 2px;
}


/* --- Credentials History Dropdown --- */
.creds-history {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  width: 100%;
  background: var(--hdr-color-bg-elevated);
  border: 1px solid var(--hdr-color-accent);
  border-top: none;
  border-radius: 0 0 var(--hdr-border-radius) var(--hdr-border-radius);
  box-shadow: var(--hdr-shadow-lg);
  font-family: var(--hdr-font-mono);
  font-size: var(--hdr-text-sm);
  max-height: 400px;
  overflow-y: auto;
  overflow-x: hidden;
  z-index: 201;
  /* Can't use var(--hdr-transition-base) here — it expands to "200ms cubic-
     bezier(...)", and combining that with ease-out would put two timing
     functions in the shorthand, making the whole declaration invalid and
     the animation a no-op. Duration written explicitly to match. */
  animation: slideDown 200ms ease-out;
  margin-top: -1px;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.creds-history:not([hidden]) {
  display: block;
}

/* --- Pages group: the real destinations, above the joke credentials ---
   A browser's address bar drops down to history. This one drops down to history AND to
   somewhere you can actually go, which is the one place the joke and the navigation can
   sit together without either getting in the way. These are real anchors, rendered into
   the markup by scripts/build-header.py, so they work with scripting off. */
.creds-group {
  margin: 0;
  padding: var(--hdr-space-3) var(--hdr-space-4) var(--hdr-space-2);
  font-size: var(--hdr-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hdr-color-text-muted);
  background: var(--hdr-color-bg);
  border-bottom: 1px solid var(--hdr-color-border);
  user-select: none;
}

.creds-page {
  display: flex;
  align-items: baseline;
  gap: var(--hdr-space-3);
  padding: var(--hdr-space-3) var(--hdr-space-4);
  text-decoration: none;
  border-bottom: 1px solid var(--hdr-color-border);
  transition: background var(--hdr-transition-fast);
}

.creds-page:hover,
.creds-page:focus-visible {
  background: var(--hdr-color-bg-hover);
}

.creds-page[aria-current="page"] {
  background: var(--hdr-color-accent-soft);
}

/* The marker is a border rather than a tick glyph: the row is a URL in a monospace
   address bar, and a glyph in the text would read as part of the address. */
.creds-page[aria-current="page"] .creds-page-label {
  color: var(--hdr-color-accent);
}

.creds-page-label {
  flex: 0 0 auto;
  min-width: 5.5rem;
  font-family: var(--hdr-font-sans);
  font-size: var(--hdr-text-sm);
  color: var(--hdr-color-text);
}

.creds-page-url {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--hdr-text-xs);
}

.history-item {
  display: flex;
  align-items: center;
  gap: var(--hdr-space-3);
  padding: var(--hdr-space-3) var(--hdr-space-4);
  cursor: pointer;
  transition: background var(--hdr-transition-fast);
  border-bottom: 1px solid var(--hdr-color-border);
  position: relative;
}

.history-item:last-child {
  border-bottom: none;
}

.history-item:hover {
  background: var(--hdr-color-bg-hover);
}

.history-item:active {
  background: var(--hdr-color-accent-soft);
}

.history-item-icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: var(--hdr-color-text-muted);
  opacity: 0.6;
}

.history-item-content {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.history-item-time {
  flex-shrink: 0;
  font-size: 10px;
  color: var(--hdr-color-text-muted);
  opacity: 0.7;
  margin-left: auto;
  padding-left: var(--hdr-space-2);
}

@media (max-width: 768px) {
  /* Side by side, the label's fixed column leaves the URL about 60px, which ellipsises to
     "https:…" and tells you nothing. Stacked, the URL gets the whole width, which is the
     only reason it is in the list. */
  .creds-page {
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
  }

  .creds-page-label {
    min-width: 0;
  }

  /* The dropdown is only as wide as the address bar, and on a phone that is about 180px.
     "https://" costs a third of it and carries no information the other four rows do not
     already repeat, so the host and path get the space instead. */
  .creds-page-url .url-protocol {
    display: none;
  }

  /* And a size down from there, which is what gets "defaultcreds.lol/sessions", the
     longest of the five, inside the width without an ellipsis. The label above it
     already carries the meaning, so this row only has to stay readable. */
  .creds-page-url {
    font-size: 0.6875rem;
  }

  :root {
    --header-height: 56px;
  }

  .header-content {
    padding: 0 var(--hdr-space-4);
  }

  /* The nav wraps onto its own 40px strip under the header row. The header
     loses its fixed height so the strip fits; the first row keeps 56px via
     the 8px vertical margins on its children. */
  .site-header {
    height: auto;
    min-height: var(--header-height);
  }

  .header-content {
    flex-wrap: wrap;
    height: auto;
    row-gap: 0;
  }

  .header-content > :not(.site-nav) {
    margin-top: 8px;
    margin-bottom: 8px;
  }

  .site-nav {
    flex-basis: calc(100% + 2 * var(--hdr-space-4));
    justify-content: space-between;
    gap: 0;
    height: 40px;
    margin: 0 calc(-1 * var(--hdr-space-4));
    padding: 0 var(--hdr-space-4);
    border-top: 1px solid var(--hdr-color-border);
  }

  .site-nav a {
    font-size: 12px;
  }

  .faux-url {
    font-size: 11px;
    padding: var(--hdr-space-1) var(--hdr-space-2);
  }

  .address-bar-wrapper {
    max-width: 200px;
    margin: 0 var(--hdr-space-2);
  }

  /* The 280px desktop floor beats the wrapper's 200px cap and pushed /news
     31px past a 400px viewport. A narrow, ellipsised address bar is the
     correct phone behaviour. */
  .faux-url {
    min-width: 0;
  }

  .address-bar-icon,
  .address-bar-dropdown-icon {
    display: none;
  }
}

/* Previously in honeypot.css, where they applied to two pages out of seven. They are
   part of how the header looks and behaves, so they belong with the rest of it.
   .is-busy is set by the apex board's own script; elsewhere it is simply never set. */
.faux-url[aria-expanded="true"] {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.refresh-btn.is-busy svg {
  animation: hdr-refresh-spin 600ms linear 1;
}

@keyframes hdr-refresh-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .refresh-btn.is-busy svg {
    animation: none;
  }
}
