/* ============================================================
   portfolio.css — shared tokens and components
   jamisonbourque.com

   Loaded by every current page. Archived snapshots under
   /versions/ are deliberately self-contained and do NOT link
   this file — an archive that changes isn't an archive.
   ============================================================ */
:root{
  /* Workshop palette: machine enamel, brass, oxidized copper. */
  --ink:      #0D141B;   /* ground */
  --ink-2:    #121C25;   /* raised surface */
  --ink-3:    #18242F;   /* hover / inset */
  --rule:     #22303C;   /* hairlines */
  --paper:    #E8EDF1;   /* primary text */
  --muted:    #8CA0B0;   /* secondary text */
  --signal:   #E0A526;   /* brass — the accent, used sparingly */
  --patina:   #5FA895;   /* verdigris — resolved / live states */

  --ff-display: "Archivo", system-ui, sans-serif;
  --ff-body:    "Newsreader", Georgia, serif;
  --ff-mono:    "IBM Plex Mono", ui-monospace, monospace;

  --shell: 1180px;
  --gut: clamp(1.25rem, 4vw, 3rem);
}

[data-bs-theme="dark"]{
  --bs-body-bg: var(--ink);
  --bs-body-color: var(--paper);
  --bs-emphasis-color: var(--paper);
  --bs-secondary-color: var(--muted);
  --bs-border-color: var(--rule);
  --bs-border-color-translucent: var(--rule);
  --bs-link-color: var(--signal);
  --bs-link-hover-color: #F2C25C;
  --bs-body-font-family: var(--ff-body);
  --bs-body-font-size: 1.0625rem;
  --bs-body-line-height: 1.65;
}

body{
  background:
    radial-gradient(120% 70% at 50% -10%, #16222D 0%, transparent 60%),
    var(--ink);
  -webkit-font-smoothing: antialiased;
}

::selection{ background: var(--signal); color: var(--ink); }

a{ text-decoration-thickness: 1px; text-underline-offset: .22em; }

:focus-visible{
  outline: 2px solid var(--signal);
  outline-offset: 3px;
  border-radius: 2px;
}

.shell{
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* ---- Utility type roles ---- */
.u-mono{
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.u-display{
  font-family: var(--ff-display);
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: .98;
}

/* ---- Masthead ---- */
.mast{
  position: sticky; top: 0; z-index: 50;
  background: rgba(13,20,27,.82);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--rule);
}
.mast__inner{
  display: flex; align-items: center; gap: 1.5rem;
  height: 56px;
}
.mast__id{
  font-family: var(--ff-display);
  font-weight: 800;
  font-stretch: 112%;
  letter-spacing: -.02em;
  font-size: .95rem;
  color: var(--paper);
  text-decoration: none;
  white-space: nowrap;
}
.mast__nav{
  display: flex; gap: .25rem; margin-left: auto;
  align-items: center;
}
.mast__links{ display: flex; gap: .25rem; align-items: center; }
.mast__link{
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  padding: .45rem .7rem;
  border-radius: 2px;
}
.mast__link:hover{ color: var(--paper); background: var(--ink-3); }
.mast__link[aria-current="page"]{ color: var(--signal); }

/* ---- Hamburger ----
   Hidden until the nav actually runs out of room. Three bars that become an
   X when open, so the control reports its own state without a label. */
.mast__burger{
  display: none;
  flex-direction: column; justify-content: center;
  gap: 4px;
  width: 38px; height: 34px;
  padding: 0 8px;
  background: none;
  border: 1px solid var(--rule);
  border-radius: 2px;
  cursor: pointer;
}
.mast__burger span{
  display: block; height: 1.5px; width: 100%;
  background: var(--paper);
  transition: transform .22s ease, opacity .18s ease;
}
.mast__burger[aria-expanded="true"]{ border-color: var(--signal); }
.mast__burger[aria-expanded="true"] span{ background: var(--signal); }
.mast__burger[aria-expanded="true"] span:nth-child(1){ transform: translateY(5.5px) rotate(45deg); }
.mast__burger[aria-expanded="true"] span:nth-child(2){ opacity: 0; }
.mast__burger[aria-expanded="true"] span:nth-child(3){ transform: translateY(-5.5px) rotate(-45deg); }

@media (max-width: 760px){
  .mast__inner{ gap: .75rem; }
  .mast__burger{ display: flex; }

  /* "v7 history" -> "v7". The dropdown header still says what it is. */
  .vers__word{ display: none; }
  .vers__btn{ padding: .5rem .55rem; }
  .mast__id{ font-size: .875rem; }

  /* Version history sits to the LEFT of the hamburger on small screens,
     and stays on the right of the links everywhere else. */
  .mast__nav .vers{ order: 1; }
  .mast__burger{ order: 2; }

  /* The links drop out of the bar into a panel under it. Absolute rather
     than in-flow so opening the menu doesn't shove the page down. */
  .mast__links{
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch;
    gap: 0;
    padding: .5rem var(--gut) 1rem;
    background: var(--ink-2);
    border-bottom: 1px solid var(--rule);
    box-shadow: 0 24px 40px -24px rgba(0,0,0,.9);
  }
  .mast__links[data-open]{ display: flex; }
  .mast__links .mast__link{
    padding: .85rem .25rem;
    font-size: .8125rem;
    border-bottom: 1px solid var(--rule);
  }
  .mast__links .mast__link:last-child{ border-bottom: 0; }
  .mast__links .mast__link:hover{ background: none; color: var(--signal); }
}

/* ---- Result chip: carries the actual outcome, not decoration ---- */
.chip{
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--ff-mono);
  font-size: .6875rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--signal);
  border: 1px solid rgba(224,165,38,.35);
  background: rgba(224,165,38,.07);
  padding: .3rem .6rem;
  border-radius: 2px;
}
.chip--live{
  color: var(--patina);
  border-color: rgba(95,168,149,.38);
  background: rgba(95,168,149,.08);
}
.chip__dot{
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor;
}

/* Linked variant — the status doubles as the way in */
.chip--link{
  text-decoration: none;
  cursor: pointer;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.chip--link::after{
  content: "↗";
  font-size: .85em;
  opacity: .75;
  margin-left: .1rem;
}
.chip--link:hover{
  color: #7DC4B0;
  border-color: var(--patina);
  background: rgba(95,168,149,.16);
}
.chip--link:hover::after{ opacity: 1; }
.chip--link:active{ transform: translateY(1px); }
.chip--link .chip__dot{
  animation: chipPulse 2.4s ease-in-out infinite;
}
@keyframes chipPulse{
  0%, 100%{ opacity: 1; }
  50%{ opacity: .35; }
}

/* ---- Section rhythm ---- */
.band{ padding-block: clamp(3.5rem, 8vw, 6.5rem); }
.band + .band{ border-top: 1px solid var(--rule); }

.band__label{
  display: flex; align-items: baseline; gap: 1rem;
  margin-bottom: 2.5rem;
}
.band__label::after{
  content: ""; flex: 1; height: 1px; background: var(--rule);
}

/* ---- Footer ---- */
.foot{
  border-top: 1px solid var(--rule);
  padding-block: 3rem 4rem;
}
.foot__grid{
  display: grid; gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* Footers previously borrowed .media__cap, which only exists in one page's
   stylesheet — so three of them rendered unstyled. Owned here now. */
.foot__v{
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: .06em;
  line-height: 1.95;
  color: var(--muted);
  margin: .5rem 0 0;
}
.foot__v a{
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.foot__v a:hover{ color: var(--signal); border-bottom-color: var(--signal); }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}


/* ---- Zoomable image + lightbox ----
   A button, not a div: expanding an image is an action, so it has to be
   reachable and operable from the keyboard. Without JS the markup still
   renders the image; only the expand is lost. */
.zoom{
  display: block; width: 100%;
  padding: 0; margin: 0;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--ink-2);
  position: relative; overflow: hidden;
  cursor: zoom-in;
}
.zoom img{ display: block; width: 100%; height: auto; }
.zoom__hint{
  position: absolute; right: .5rem; bottom: .5rem;
  font-family: var(--ff-mono);
  font-size: .625rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--paper);
  background: rgba(13,20,27,.88);
  border: 1px solid var(--rule); border-radius: 2px;
  padding: .35rem .55rem;
  opacity: 0; transition: opacity .18s ease;
}
.zoom:hover .zoom__hint,
.zoom:focus-visible .zoom__hint{ opacity: 1; }
/* Touch devices have no hover to reveal it, so it stays put. */
@media (hover: none){ .zoom__hint{ opacity: 1; } }

.lb{
  padding: 0; border: 0;
  background: transparent;
  max-width: 96vw; max-height: 96vh;
  overflow: visible;
  color: var(--paper);
}
.lb::backdrop{ background: rgba(6,10,14,.94); }
.lb img{
  display: block;
  max-width: 96vw; max-height: 84vh;
  width: auto; height: auto;
  background: var(--ink-2);
  border: 1px solid var(--rule);
  border-radius: 3px;
}
.lb__bar{
  display: flex; align-items: baseline; gap: 1rem;
  margin-top: .75rem;
}
.lb__cap{
  font-family: var(--ff-mono);
  font-size: .6875rem; letter-spacing: .06em;
  color: var(--muted); margin: 0;
}
.lb__close{
  margin-left: auto;
  font-family: var(--ff-mono);
  font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--paper);
  background: none;
  border: 1px solid var(--rule); border-radius: 2px;
  padding: .4rem .7rem;
  cursor: pointer;
}
.lb__close:hover{ color: var(--signal); border-color: var(--signal); }

/* ---- Version switcher ---- */
.vers{ position: relative; display: flex; align-items: center; }
.vers__btn{
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--ff-mono); font-size: .6875rem;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); background: none;
  border: 1px solid var(--rule); border-radius: 2px;
  padding: .38rem .6rem; cursor: pointer;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
.vers__btn:hover{ color: var(--paper); border-color: #2E3F4E; background: var(--ink-3); }
.vers__btn[aria-expanded="true"]{ color: var(--signal); border-color: rgba(224,165,38,.5); }
.vers__btn::after{
  content: "▾"; font-size: .8em; opacity: .7;
  transition: transform .18s ease;
}
.vers__btn[aria-expanded="true"]::after{ transform: rotate(180deg); }

.vers__menu{
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 290px;
  background: var(--ink-2);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--signal);
  border-radius: 3px;
  box-shadow: 0 24px 60px -24px rgba(0,0,0,.85);
  padding: .4rem;
  display: none;
}
.vers__menu[data-open]{ display: block; }
.vers__hd{
  font-family: var(--ff-mono); font-size: .5625rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--muted);
  padding: .6rem .7rem .5rem;
}
.vers__item{
  display: block; width: 100%; text-align: left;
  background: none; border: 0; border-radius: 2px;
  padding: .6rem .7rem; cursor: pointer; text-decoration: none;
  transition: background-color .15s ease;
}
.vers__item:hover{ background: var(--ink-3); }
.vers__item[aria-current="true"]{ background: rgba(224,165,38,.08); }
.vers__id{
  font-family: var(--ff-mono); font-size: .6875rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--signal);
}
.vers__item[aria-current="true"] .vers__id::after{
  content: " · current"; color: var(--muted); letter-spacing: .06em;
}
.vers__ttl{
  font-family: var(--ff-display); font-weight: 600; font-size: .875rem;
  letter-spacing: -.01em; color: var(--paper); margin-top: .2rem;
}
.vers__note{
  font-family: var(--ff-body); font-size: .8125rem; line-height: 1.45;
  color: var(--muted); margin-top: .15rem;
}

/* ---- Archive banner: injected on any page under /versions/ ---- */
.archived{
  background: rgba(224,165,38,.1);
  border-bottom: 1px solid rgba(224,165,38,.35);
}
.archived__inner{
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem;
  padding-block: .7rem;
  font-family: var(--ff-mono); font-size: .6875rem;
  letter-spacing: .06em; color: var(--signal);
}
.archived__inner a{ color: var(--paper); }

@media (max-width: 700px){
  .vers__menu{ right: auto; left: 0; min-width: min(290px, calc(100vw - 2.5rem)); }
}
