/*
  Component styles — gary.design (Kirby)

  Ported from the per-component <style> blocks in the Astro build. Astro scoped these
  automatically; Kirby has no scoping, so they live here as ordinary CSS. Class names were
  already component-prefixed (.site-header, .nav-list, .social, .theme-toggle), so no
  renaming was needed. Astro's :global(...) wrappers are simply dropped.

  Order: header → nav → theme toggle → footer.
*/

/* ============================================================
   HEADER
   ============================================================ */

.site-header {
  border-bottom: 1px solid var(--border);
  /* Solid semi-opaque, NOT backdrop-blur — deliberate choice (§3). */
  background: color-mix(in srgb, var(--bg) 95%, transparent);
  position: sticky;
  top: 0;
  z-index: 50;
}

/* Skip to content — off-screen until it receives keyboard focus. */
.skip-link {
  position: absolute;
  left: var(--space-sm);
  top: var(--space-sm);
  z-index: 100;
  background: var(--surface);
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  padding: 0.6rem 1rem;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  transform: translateY(-250%);
  transition: transform 0.15s ease;
}
.skip-link:focus {
  transform: translateY(0);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding-block: var(--space-sm);
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-1);
  letter-spacing: -0.03em;
  color: var(--text);
  text-decoration: none;
  margin-inline-end: auto;
}
.wordmark span { color: var(--accent); }

/* ---- Primary nav ---- */

.nav-list {
  display: flex;
  gap: var(--space-md);
  align-items: center;
}
.nav-list a {
  color: var(--text-soft);
  text-decoration: none;
  font-weight: 500;
  padding-block: 0.25rem;
  border-bottom: 2px solid transparent;
}
.nav-list a:hover { color: var(--text); }
.nav-list a[aria-current="page"] {
  color: var(--text);
  border-bottom-color: var(--accent);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Hamburger — hidden on desktop */
.nav-toggle {
  display: none;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
}
.nav-toggle:hover { color: var(--accent); border-color: var(--accent); }
.nav-toggle .ico {
  inline-size: 1.25rem;
  block-size: 1.25rem;
}
.nav-toggle .ico-close { display: none; }
.nav-toggle[aria-expanded="true"] .ico-open { display: none; }
.nav-toggle[aria-expanded="true"] .ico-close { display: block; }

/* ---- Mobile: nav becomes a dropdown panel ---- */
@media (max-width: 40rem) {
  .nav-toggle { display: grid; }

  .nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow);
    /* collapsed by default */
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.2s ease;
  }
  .nav[data-open="true"] {
    grid-template-rows: 1fr;
  }
  /* NOTE: `.nav .nav-list`, not `.nav-list`. global.css sets `ul[role="list"] { padding: 0 }`
     at specificity (0,1,1), which beats a lone class (0,1,0) and would flatten the inline
     padding. Astro's scoped styles hid this by compiling to (0,2,0); without scoping the
     descendant selector is what earns the win. Don't "simplify" this back. */
  .nav .nav-list {
    overflow: hidden;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-inline: var(--space-md);
  }
  /* Keep collapsed content unfocusable/invisible until open */
  .nav:not([data-open="true"]) .nav-list {
    visibility: hidden;
  }
  .nav[data-open="true"] .nav-list {
    visibility: visible;
  }
  .nav-list li + li {
    border-top: 1px solid var(--border);
  }
  .nav-list a {
    display: block;
    padding-block: var(--space-md);
    font-size: var(--step-1);
    border-bottom: 0;
  }
  .nav-list a[aria-current="page"] {
    border-bottom: 0;
    color: var(--accent);
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
}

/* ============================================================
   THEME TOGGLE  (cycles system → light → dark)
   ============================================================ */

.theme-toggle {
  display: inline-grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0;
  background: var(--surface);
  color: var(--text-soft);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.theme-toggle:hover {
  color: var(--accent);
  border-color: var(--accent);
}
.theme-toggle .ico {
  display: none;
  inline-size: 1.15rem;
  block-size: 1.15rem;
}
.theme-toggle[data-pref="system"] .ico-system { display: block; }
.theme-toggle[data-pref="light"]  .ico-light  { display: block; }
.theme-toggle[data-pref="dark"]   .ico-dark   { display: block; }

/* ============================================================
   FOOTER
   ============================================================ */

.site-footer {
  border-top: 1px solid var(--border);
  /* No top margin: the border-top sits directly below the page content. Breathing room
     comes from the footer's own padding-block, which is inside the rule. */
  padding-block: var(--space-xl);
}
.footer-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
  text-align: center;
}
.social {
  display: flex;
  gap: var(--space-xs);
  align-items: center;
}
.social a {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border-radius: 999px;
  color: var(--text-soft);
  text-decoration: none;
  transition: color 0.15s ease, background 0.15s ease;
}
.social a:hover {
  color: var(--accent);
  background: var(--surface-alt);
}
.social .social-ico {
  inline-size: 1.3rem;
  block-size: 1.3rem;
}

/* BaconWorks lettermark — stands out in the blue accent (mirrors garybacon.com,
   where the B is specially colored). Higher specificity so it wins over .social a:hover. */
.social a.bw-link { color: var(--accent); }
.social a.bw-link:hover { color: var(--accent-hover); background: var(--surface-alt); }
.bw-mark {
  font-family: "Zilla Slab", Georgia, serif;
  font-weight: 700;
  font-size: 1.75rem;
  line-height: 1;
}

/* Tooltip on hover/focus — matches garybacon.com (bubble + downward caret). */
.social a::after,
.social a::before {
  position: absolute;
  left: 50%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.social a::after {
  content: attr(data-tip);
  bottom: calc(100% + 0.55rem);
  transform: translateX(-50%) translateY(4px);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  padding: 5px 11px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}
/* Caret: points down, and overlaps the bubble by 1px.
   The overlap is deliberate. Butting it exactly against the bubble's bottom edge is
   correct per the box model — caret top and bubble bottom both compute to 48.797px —
   but the browser rasterises the bubble's background box and the triangle's border edge
   separately, and at a fractional position they round independently, leaving a hairline
   gap. Subtracting 11px instead of the caret's full 12px height pushes it 1px INSIDE the
   bubble, so no rounding can separate them. The overlap is invisible because the caret's
   border-top-color and the bubble's background are the same token. */
.social a::before {
  content: "";
  bottom: calc(100% + 0.55rem - 11px);
  transform: translateX(-50%) translateY(4px);
  border: 6px solid transparent;
  border-top-color: var(--surface);
  z-index: 1;                 /* above the bubble's shadow so the caret stays clean white */
}
.social a:hover::after,
.social a:hover::before,
.social a:focus-visible::after,
.social a:focus-visible::before {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.copyright {
  color: var(--text-soft);
  font-size: var(--step--1);
  max-width: none;
}

/* ============================================================
   PAGE SHELL
   ============================================================ */

/* Astro's <body> was flex-column via global.css; main needs to take the slack so the
   footer sits at the bottom on short pages. */
main {
  flex: 1;
  /* The footer has no top margin — the space above it belongs to the page. Setting it
     here rather than per-template means any new page gets it automatically. */
  padding-bottom: var(--space-2xl);
}

/* Home is the exception. It ends with the full-bleed testimonials band, which already
   carries its own internal padding and is meant to meet the footer's rule directly.
   Extra padding here is what made the homepage gap look excessive.
   <main> gets a t-<template> class from snippets/header.php. */
.t-home {
  padding-bottom: 0;
}
