/* ==========================================================================
   GoldenSunAI — Components
   ========================================================================== */

/* -- Site header / navigation ---------------------------------------------*/

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(6, 5, 4, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--gs-border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--gs-space-4);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--gs-space-2);
  flex-shrink: 0;
  font-weight: 700;
  font-size: var(--gs-fs-md);
  letter-spacing: -0.01em;
}

.brand__name {
  color: var(--gs-text-primary);
  white-space: nowrap;
}

.brand__name .accent {
  color: var(--gs-accent-strong);
}

.nav {
  display: none;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--gs-space-6);
  font-size: var(--gs-fs-sm);
}

.nav__link {
  color: var(--gs-text-secondary);
  padding: var(--gs-space-2) 0;
  border-bottom: 2px solid transparent;
  transition: color var(--gs-duration-fast) var(--gs-ease),
    border-color var(--gs-duration-fast) var(--gs-ease);
}

.nav__link:hover,
.nav__link[aria-current="page"] {
  color: var(--gs-text-primary);
  border-bottom-color: var(--gs-accent);
}

.site-header__controls {
  display: flex;
  align-items: center;
  gap: var(--gs-space-3);
}

/* -- Theme picker -----------------------------------------------------------
   A native <select> — fully keyboard operable and screen-reader labeled
   without any custom menu logic. Options always pair the swatch emoji with
   the theme name, never color alone.
   ------------------------------------------------------------------------*/

.theme-picker__select {
  appearance: none;
  background: var(--gs-bg-raised)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23c9c0a8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    no-repeat right var(--gs-space-3) center;
  background-size: 10px 6px;
  border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius-sm);
  color: var(--gs-text-secondary);
  font-family: var(--gs-font-sans);
  font-size: var(--gs-fs-sm);
  padding: var(--gs-space-2) var(--gs-space-6) var(--gs-space-2) var(--gs-space-3);
  max-width: 9rem;
}

.theme-picker__select:hover {
  border-color: var(--gs-accent);
}

.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: var(--gs-space-2);
  border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius-sm);
}

.nav-toggle__bar {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--gs-text-primary);
  transition: transform var(--gs-duration-normal) var(--gs-ease),
    opacity var(--gs-duration-normal) var(--gs-ease);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Mobile navigation drawer */
.nav-drawer {
  position: fixed;
  inset: 0;
  top: 0;
  background: var(--gs-black-950);
  z-index: 60;
  display: flex;
  flex-direction: column;
  padding: var(--gs-space-5);
  transform: translateX(100%);
  transition: transform var(--gs-duration-normal) var(--gs-ease);
}

.nav-drawer[data-open="true"] {
  transform: translateX(0);
}

.nav-drawer__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--gs-space-8);
}

.nav-drawer__list {
  display: flex;
  flex-direction: column;
  gap: var(--gs-space-6);
  font-size: var(--gs-fs-xl);
}

.nav-drawer__link {
  color: var(--gs-text-primary);
}

.theme-picker--drawer {
  margin-top: var(--gs-space-8);
}

.theme-picker--drawer .theme-picker__select {
  width: 100%;
  max-width: none;
  font-size: var(--gs-fs-base);
  padding: var(--gs-space-3) var(--gs-space-4);
}

.nav-drawer__footer {
  margin-top: auto;
  color: var(--gs-text-muted);
  font-size: var(--gs-fs-sm);
}

body[data-drawer-open="true"] {
  overflow: hidden;
}

/* -- Buttons ----------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: var(--gs-space-2);
  padding: var(--gs-space-3) var(--gs-space-5);
  border-radius: var(--gs-radius-sm);
  font-size: var(--gs-fs-sm);
  font-weight: 600;
  white-space: nowrap;
  transition: transform var(--gs-duration-fast) var(--gs-ease),
    background var(--gs-duration-fast) var(--gs-ease),
    border-color var(--gs-duration-fast) var(--gs-ease);
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: linear-gradient(
    180deg,
    var(--gs-accent-strong),
    var(--gs-accent)
  );
  color: var(--gs-text-on-gold);
}

.btn--primary:hover {
  filter: brightness(1.08);
}

.btn--secondary {
  border: 1px solid var(--gs-border);
  color: var(--gs-text-primary);
}

.btn--secondary:hover {
  border-color: var(--gs-accent);
  color: var(--gs-accent-strong);
}

.btn--ghost {
  color: var(--gs-accent-strong);
}

.btn--ghost:hover {
  color: var(--gs-accent);
}

/* -- Hero ---------------------------------------------------------------*/

.hero {
  position: relative;
  overflow: hidden;
  padding-block: var(--gs-space-12) var(--gs-space-10);
  border-bottom: 1px solid var(--gs-border);
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--gs-space-2);
  color: var(--gs-accent-strong);
  font-family: var(--gs-font-mono);
  font-size: var(--gs-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.hero__title {
  font-size: clamp(2.25rem, 8vw, var(--gs-fs-3xl));
  margin-top: var(--gs-space-4);
}

.hero__tagline {
  color: var(--gs-accent-strong);
  font-size: clamp(1.25rem, 4vw, var(--gs-fs-xl));
  margin-top: var(--gs-space-2);
}

.hero__lede {
  max-width: var(--gs-measure);
  color: var(--gs-text-secondary);
  font-size: var(--gs-fs-md);
  margin-top: var(--gs-space-5);
}

.hero__signature {
  margin-top: var(--gs-space-6);
  color: var(--gs-text-muted);
  font-size: var(--gs-fs-sm);
}

.hero .page-actions {
  margin-top: var(--gs-space-8);
}

/* -- Hero globe motif -----------------------------------------------------
   A stylized data-globe: dotted "landmass" cluster, latitude/longitude
   wireframe, orbital arcs, and a warm horizon glow — the same visual
   language as the Team GoldenSun LinkedIn banners, rebuilt in inline SVG
   so it costs the page nothing to load. Rotation is implied by animating
   the meridian ellipses' rx (a true 2D projection of a sphere spinning on
   its axis), not by spinning the whole graphic in the picture plane.

   Every color here comes from the --gs-globe-* variables in tokens.css,
   never --gs-accent, --gs-gold-*, or --gs-cobalt-* directly, so the globe
   re-themes with the rest of the page across all five gemstones without
   any of these rules changing.
   ------------------------------------------------------------------------*/

.hero__globe {
  position: absolute;
  right: clamp(-60px, -4vw, -20px);
  bottom: -8%;
  width: min(48vw, 480px);
  opacity: 0.9;
  pointer-events: none;
  /* Fade the whole motif toward transparent past the sphere's own edge,
     so it blends into the page background instead of ending on a hard
     circular cutoff. */
  mask-image: radial-gradient(
    circle at 58% 54%,
    rgba(0, 0, 0, 1) 64%,
    rgba(0, 0, 0, 0) 96%
  );
  -webkit-mask-image: radial-gradient(
    circle at 58% 54%,
    rgba(0, 0, 0, 1) 64%,
    rgba(0, 0, 0, 0) 96%
  );
}

.hero__globe svg {
  width: 100%;
  height: auto;
  display: block;
}

.hg-silhouette {
  fill: none;
  stroke: var(--gs-border);
  stroke-width: 1;
}

.hg-atmosphere {
  fill: none;
  stroke: var(--gs-globe-primary);
  stroke-width: 0.5;
  opacity: 0.12;
}

.hg-lat {
  fill: none;
  stroke: var(--gs-globe-secondary);
  stroke-width: 0.75;
  opacity: 0.3;
}

.hg-meridian {
  fill: none;
  stroke: var(--gs-globe-primary);
  stroke-width: 1;
  animation: hg-sweep 18s linear infinite;
}

.hg-meridian--b {
  animation-delay: -9s;
}

@keyframes hg-sweep {
  0%,
  100% {
    rx: 152px;
    opacity: 0.55;
  }
  50% {
    rx: 3px;
    opacity: 0.15;
  }
}

.hg-node {
  fill: var(--gs-globe-primary);
}

.hg-node--dim {
  fill: var(--gs-globe-dim);
  opacity: 0.6;
}

/* A couple of the landmass points get a slow, occasional pulse instead of
   sitting perfectly still — a quiet "signal detected" flicker, staggered
   so the two never pulse in sync. */
.hg-node--pulse {
  transform-box: fill-box;
  transform-origin: center;
  animation: hg-node-pulse 6s ease-in-out infinite;
}

.hg-node--pulse-b {
  animation-delay: -3.2s;
}

@keyframes hg-node-pulse {
  0%,
  82%,
  100% {
    opacity: 0.6;
    transform: scale(1);
  }
  91% {
    opacity: 1;
    transform: scale(1.7);
  }
}

.hg-stop-1 {
  stop-color: var(--gs-globe-glow);
}

.hg-stop-2 {
  stop-color: var(--gs-globe-secondary);
}

.hg-stop-3 {
  stop-color: var(--gs-globe-secondary);
  stop-opacity: 0;
}

.hg-glow {
  animation: hg-glow-pulse 7s ease-in-out infinite;
}

@keyframes hg-glow-pulse {
  0%,
  100% {
    opacity: 0.7;
  }
  50% {
    opacity: 1;
  }
}

.hg-arc {
  fill: none;
  stroke: var(--gs-globe-arc);
  stroke-width: 1;
  opacity: 0.35;
  stroke-dasharray: 3 5;
}

/* A single point of light making a slow pass along one orbital arc — the
   globe's "live signal" cue. offset-path is a progressive enhancement: if
   a browser doesn't support CSS motion paths the dot simply never moves,
   which is an acceptable no-op fallback for a decorative element. */
.hg-signal {
  fill: var(--gs-globe-arc);
  offset-path: path("M 30 190 Q 280 100 500 250");
  offset-rotate: 0deg;
  animation: hg-signal-travel 9s ease-in-out infinite;
}

@keyframes hg-signal-travel {
  0% {
    offset-distance: 0%;
    opacity: 0;
  }
  10% {
    opacity: 0.9;
  }
  90% {
    opacity: 0.9;
  }
  100% {
    offset-distance: 100%;
    opacity: 0;
  }
}

.hg-label {
  fill: var(--gs-globe-secondary);
  font-family: var(--gs-font-mono);
  font-size: 11px;
  letter-spacing: 3px;
  opacity: 0.4;
}

@media (prefers-reduced-motion: reduce) {
  .hg-meridian,
  .hg-glow,
  .hg-node--pulse,
  .hg-signal {
    animation: none;
  }

  /* Freeze each on a clean resting frame rather than whatever the first
     keyframe happens to draw — the 0%/100% keyframe sits almost exactly on
     the clip circle's edge and all but disappears, so rest at a mid-sweep
     value instead, comfortably inside the clip and clearly a "meridian". */
  .hg-meridian {
    rx: 90px;
    opacity: 0.5;
  }

  .hg-glow {
    opacity: 0.85;
  }

  .hg-signal {
    opacity: 0;
  }
}

@media (min-width: 768px) and (max-width: 1024px) {
  /* Tablet: a smaller, quieter globe rather than the full desktop motif. */
  .hero__globe {
    width: min(38vw, 340px);
    opacity: 0.75;
  }

  .hg-label {
    display: none;
  }
}

@media (max-width: 767px) {
  .hero__globe {
    /* Not hidden outright — a faint, cropped sliver in the corner (the
       hero section clips overflow, so most of the sphere falls off-canvas
       and only a quarter-globe glow peeks through behind the copy). If
       this ever reads as competing with the hero text rather than sitting
       quietly behind it, go back to display: none — typography wins. */
    width: min(85vw, 380px);
    right: -30%;
    bottom: -34%;
    opacity: 0.16;
  }

  .hg-arc,
  .hg-signal,
  .hg-label,
  .hg-node--pulse {
    display: none;
  }
}

/* -- Page masthead ---------------------------------------------------------
   Shared shell for every secondary page: a small theme-aware emblem, a
   kicker label, the page title, and a short lede. Replaces one-off
   section-head markup + inline styles page-by-page.
   ------------------------------------------------------------------------*/

.page-head {
  max-width: var(--gs-measure);
  margin-bottom: var(--gs-space-8);
}

.page-mark {
  width: 48px;
  height: 48px;
  margin-bottom: var(--gs-space-4);
}

.page-kicker {
  color: var(--gs-accent-strong);
  font-family: var(--gs-font-mono);
  font-size: var(--gs-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.page-title {
  font-size: var(--gs-fs-2xl);
  margin-top: var(--gs-space-3);
}

.page-lede {
  color: var(--gs-text-secondary);
  margin-top: var(--gs-space-3);
}

.page-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gs-space-4);
  margin-top: var(--gs-space-6);
}

.page-actions--lg {
  margin-top: var(--gs-space-8);
}

.page-head--sub {
  margin-top: var(--gs-space-5);
}

.page-lede--muted {
  margin-top: var(--gs-space-4);
  color: var(--gs-text-muted);
}

/* -- Theme-aware emblem -----------------------------------------------------
   One mono source image, recolored per theme via CSS mask instead of
   shipping five colored files. Used for the nav mark, the drawer mark, and
   every page-mark.
   ------------------------------------------------------------------------*/

.gs-emblem {
  display: inline-block;
  flex-shrink: 0;
  background-color: var(--gs-accent-strong);
  -webkit-mask-image: url("../assets/logos/emblem-mono_512.png");
  -webkit-mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-image: url("../assets/logos/emblem-mono_512.png");
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
}

.gs-emblem--nav {
  width: 26px;
  height: 26px;
  filter: drop-shadow(0 0 8px rgba(232, 183, 75, 0.35));
}

/* -- Portfolio category filters ("Solar Index") -----------------------------
   A plain button group — no custom listbox/menu semantics needed since
   there's no multi-select or nested structure, just a flat set of
   mutually-exclusive toggles. Hidden by default in markup; js/main.js
   reveals it once JS has actually run, so a no-JS visitor never sees an
   inert filter and simply gets every card (progressive enhancement).

   Below 640px the rail scrolls horizontally instead of wrapping to a
   second row (a wrapped row of pills reads as a block of UI; a single
   scrollable row reads as a strip to flick through) — the edge fade is a
   mask, not a visible element, so it never shows up in the overflow scan.
   ------------------------------------------------------------------------*/

.filter-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gs-space-2);
  margin-bottom: var(--gs-space-4);
}

.filter-bar__count {
  width: 100%;
  color: var(--gs-text-muted);
  font-family: var(--gs-font-mono);
  font-size: var(--gs-fs-xs);
  letter-spacing: 0.04em;
  margin-bottom: var(--gs-space-4);
}

.filter-bar__rail {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gs-space-2);
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  min-height: 44px;
  padding: var(--gs-space-2) var(--gs-space-4);
  border-radius: 999px;
  border: 1px solid var(--gs-border);
  color: var(--gs-text-secondary);
  font-size: var(--gs-fs-sm);
  font-weight: 600;
  transition: border-color var(--gs-duration-fast) var(--gs-ease),
    color var(--gs-duration-fast) var(--gs-ease),
    background var(--gs-duration-fast) var(--gs-ease);
}

.filter-chip:hover {
  border-color: var(--gs-accent);
  color: var(--gs-text-primary);
}

.filter-chip[aria-pressed="true"] {
  background: var(--gs-accent);
  border-color: var(--gs-accent);
  color: var(--gs-text-on-gold);
}

@media (max-width: 639px) {
  .filter-bar__rail {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-bottom: 2px;
    margin: 0 calc(var(--gs-space-5) * -1);
    padding-inline: var(--gs-space-5);
    mask-image: linear-gradient(
      to right,
      black calc(100% - 28px),
      transparent 100%
    );
    -webkit-mask-image: linear-gradient(
      to right,
      black calc(100% - 28px),
      transparent 100%
    );
  }

  .filter-bar__rail::-webkit-scrollbar {
    display: none;
  }
}

/* -- Cards ----------------------------------------------------------------*/

.card-grid {
  display: grid;
  /* minmax(0, 1fr), not bare 1fr (which implies minmax(auto, 1fr)) — a bare
     1fr lets one card's unbreakable content (a long no-space project name,
     a wide badge) inflate every card sharing that track past the viewport.
     Clamping the minimum to 0 forces oversized content to wrap/shrink
     inside the track instead of growing it. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gs-space-5);
}

.card {
  background: var(--gs-bg-card);
  border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius-lg);
  padding: var(--gs-space-6);
  box-shadow: var(--gs-shadow-card);
  transition: border-color 180ms var(--gs-ease), transform 180ms var(--gs-ease),
    box-shadow 180ms var(--gs-ease);
}

.card:hover {
  border-color: var(--gs-accent-strong);
  box-shadow: var(--gs-shadow-card), 0 0 0 1px var(--gs-accent-strong) inset;
  transform: translateY(-2px);
}

/* .card__top is still used by index.html's small homepage preview grid
   (title + corner badge, inline). The Work page grid below uses a plain
   stacked hierarchy instead — see .card__status. */
.card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--gs-space-3);
}

.card__title {
  font-size: var(--gs-fs-lg);
  overflow-wrap: break-word;
}

/* A plain understated status line directly under the title — no pill, no
   corner badge, no decorative container, per the Work page's card
   hierarchy. Same small-caps-meta treatment as .project-meta dt. */
.card__status {
  margin-top: var(--gs-space-2);
  color: var(--gs-text-muted);
  font-family: var(--gs-font-mono);
  font-size: var(--gs-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.card__tagline {
  color: var(--gs-accent-strong);
  font-size: var(--gs-fs-sm);
  margin-top: var(--gs-space-2);
}

.card__desc {
  color: var(--gs-text-secondary);
  margin-top: var(--gs-space-4);
}

.card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gs-space-2);
  margin-top: var(--gs-space-4);
}

.card__actions {
  margin-top: var(--gs-space-5);
  display: flex;
  align-items: center;
  gap: var(--gs-space-3);
  flex-wrap: wrap;
}

/* -- Status badges --------------------------------------------------------*/

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--gs-space-1);
  padding: var(--gs-space-1) var(--gs-space-3);
  border-radius: 999px;
  font-family: var(--gs-font-mono);
  font-size: var(--gs-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1px solid var(--gs-accent);
  color: var(--gs-accent-strong);
  white-space: nowrap;
}

/* -- Callout / support panels ----------------------------------------------*/

.panel {
  background: var(--gs-bg-raised);
  border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius-lg);
  padding: var(--gs-space-6);
}

.panel + .panel {
  margin-top: var(--gs-space-5);
}

.panel-heading {
  font-size: var(--gs-fs-lg);
}

.panel .card-grid {
  margin-top: var(--gs-space-5);
}

.divider {
  height: 1px;
  background: var(--gs-border);
  border: 0;
  margin: var(--gs-space-8) 0;
}

/* -- Contact actions --------------------------------------------------------*/

.contact-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gs-space-4);
}

@media (max-width: 479px) {
  .contact-actions {
    flex-direction: column;
    align-items: stretch;
  }
}

/* -- Project meta (Built by / Status / Platform) ---------------------------*/

.project-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gs-space-5);
  margin: 0;
}

.project-meta > div {
  min-width: 8rem;
}

.project-meta dt {
  font-family: var(--gs-font-mono);
  font-size: var(--gs-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--gs-text-muted);
}

.project-meta dd {
  margin: var(--gs-space-1) 0 0;
  color: var(--gs-text-primary);
  font-size: var(--gs-fs-sm);
}

/* -- Footer -----------------------------------------------------------------*/

.site-footer {
  position: relative;
  border-top: 1px solid var(--gs-border);
  padding-block: var(--gs-space-8);
  color: var(--gs-text-muted);
}

.site-footer__inner {
  display: flex;
  flex-direction: column;
  gap: var(--gs-space-5);
}

.site-footer__inner .stack {
  gap: var(--gs-space-2);
}

.site-footer__brand {
  color: var(--gs-text-secondary);
  font-weight: 600;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gs-space-5);
  font-size: var(--gs-fs-sm);
}

.site-footer__links a:hover {
  color: var(--gs-accent-strong);
}

.site-footer__meta {
  font-size: var(--gs-fs-xs);
  font-family: var(--gs-font-mono);
}

/* -- Simple two-column layout helper ------------------------------------ */

.split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gs-space-8);
}

/* -- Philosophy steps ("Understand -> Organize -> Discover -> Act") ------*/

.step-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gs-space-4);
}

.step {
  border: 1px solid var(--gs-border);
  border-radius: var(--gs-radius-md);
  padding: var(--gs-space-5);
}

.step__index {
  font-family: var(--gs-font-mono);
  color: var(--gs-accent-strong);
  font-size: var(--gs-fs-xs);
}

.step__title {
  margin-top: var(--gs-space-2);
  font-size: var(--gs-fs-md);
}

.step__desc {
  margin-top: var(--gs-space-2);
  color: var(--gs-text-secondary);
  font-size: var(--gs-fs-sm);
}
