/* ---------------------------------------------------------------
   SHIIINY // shared styles
   Loaded by every page. Edit here once instead of in all five files.
   Page-specific rules stay in each page's own <style> block.

   Layout: masthead across the top, sidebar nav on the left,
   content on the right.
   --------------------------------------------------------------- */

:root{
  --bg: #f2f8f7;
  --panel: #ffffff;
  --ink: #201a35;
  --sidebar-bg: #1c1730;
  --sidebar-text: #a9c9e8;
  --mint: #7fd9c4;
  --blue: #3aa0d8;
  --pink: #e8437e;
  --dim: #6b6480;
  --rule: #d8e6e2;

  /* one spacing scale, used everywhere — no more magic numbers */
  --s1: 6px; --s2: 12px; --s3: 20px; --s4: 32px; --s5: 52px; --s6: 80px;

  --nav-w: 265px;   /* sidebar width; the navy gradient matches it */

  /* pride flags for the sidebar stripe — trans at rest, vincian on hover */
  --flag-trans:   linear-gradient(to right, #5bc8f5 0 20%, #f5a9c5 20% 40%, #ffffff 40% 60%, #f5a9c5 60% 80%, #5bc8f5 80% 100%);
  --flag-vincian: linear-gradient(to right, #078d70 0 20%, #99e8c2 20% 40%, #ffffff 40% 60%, #7bade2 60% 80%, #3d1a78 80% 100%);
}

*{ box-sizing: border-box; }
html{ -webkit-text-size-adjust: 100%; }
body{
  margin: 0;
  min-height: 100vh;
  display: flex; flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Space Mono', monospace;
  font-size: 17px;
  line-height: 1.7;
}
/* on a big monitor, scale the whole thing up rather than leaving dead space */
@media (min-width: 1600px){ body{ font-size: 18px; } }
a{
  color: var(--blue);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: rgba(58,160,216,.45);
}
a:hover{ color: var(--pink); text-decoration-color: var(--pink); }
:focus-visible{ outline: 2px solid var(--pink); outline-offset: 3px; }
img{ max-width: 100%; }

/* ---------- masthead ----------
   Runs the full width of the page and joins the sidebar, so the navy forms
   one continuous shape. The pink accent is an underline that starts where
   the sidebar ends — a full border would draw a line between the header and
   the sidebar and put the old seam right back. */
.masthead{
  background: var(--sidebar-bg);
  padding: var(--s6) var(--s4) var(--s5);
  text-align: center;
  position: relative;
}
.masthead::after{
  content: "";
  position: absolute;
  left: var(--nav-w); right: 0; bottom: 0;
  height: 6px;
  background: var(--pink);
}
.wordmark{
  display: inline-block;
  font-family: 'Press Start 2P', monospace;
  color: var(--mint);
  font-size: clamp(1.5rem, 6.5vw, 3.7rem);
  line-height: 1;
  letter-spacing: 3px;
  margin: 0;
  text-decoration: none;
  /* pink offset, like a misregistered print */
  text-shadow: 3px 3px 0 var(--pink);
  /* eases back to pink when the pointer leaves mid-cycle */
  transition: text-shadow .7s ease;
}
/* while hovered, the offset drifts back and forth between pink and blue */
@keyframes wordmark-drift{
  from{ text-shadow: 3px 3px 0 var(--pink); }
  to  { text-shadow: 3px 3px 0 var(--blue); }
}
a.wordmark:hover{
  color: var(--mint);
  animation: wordmark-drift 1.8s ease-in-out infinite alternate;
}
.tagline{
  color: var(--sidebar-text);
  font-size: .82rem;
  letter-spacing: 4px;
  text-transform: uppercase;
  margin: var(--s3) 0 0;
}
/* the ✦ separators sit larger than the words they divide */
.tagline .sep{
  font-size: 1.5em;
  vertical-align: -0.06em;
  margin: 0 .08em;
  line-height: 0;
}
/* ---------- corner mark ----------
   Sits in the top-left of the masthead, over the sidebar column.
   Same sparkle as the favicon; doubles as a link home. */
.cornermark{
  position: absolute;
  left: 0; top: 0; bottom: 0;      /* fills the corner above the nav links */
  width: var(--nav-w);
  padding: var(--s3);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  text-decoration: none;
}
.cornermark svg{
  width: clamp(110px, 11vw, 190px);
  height: auto;
  display: block;
  transform: rotate(6deg);
  transition: transform .2s ease;
}
.cornermark:hover svg{ transform: rotate(14deg) scale(1.08); }

/* Trans flag at rest. Hovering crossfades to vincian and back, on a loop.
   The vincian flag rides on a pseudo-element so it can fade over the top —
   gradients can't tween between colour stops, but opacity can. */
.flagstripe{
  position: relative;
  margin-top: var(--s4);
  height: 8px;
  border-radius: 3px;
  background: var(--flag-trans);
}
.flagstripe::before{
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--flag-vincian);
  opacity: 0;
}
.flagstripe:hover::before{ animation: flagcycle-vincian 5s ease-in-out infinite; }

/* each flag holds ~1.5s, with a ~1s crossfade either side */
@keyframes flagcycle-vincian{
  0%,  10%  { opacity: 0; }
  30%, 60%  { opacity: 1; }
  80%, 100% { opacity: 0; }
}

/* ---------- layout ----------
   The masthead is its own floating block on row 1. Below it, the sidebar
   and the content sit side by side with real space between them. */
.layout{
  display: grid;
  grid-template-columns: var(--nav-w) minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  flex: 1;
  /* paints the navy column from the very top of the page; the .sidebar
     element itself stays on row 2 so the nav text keeps its position */
  background: linear-gradient(to right, var(--sidebar-bg) 0 var(--nav-w), transparent var(--nav-w));
}
.masthead{ grid-column: 1 / -1; grid-row: 1; }
.sidebar { grid-column: 1; grid-row: 2; }
.content { grid-column: 2; grid-row: 2; }

.sidebar{
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  padding: var(--s5) var(--s3) var(--s4);
  display: flex; flex-direction: column;
}
.cat{
  color: var(--pink);
  font-size: .7rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin: var(--s4) 0 var(--s1);
}
.cat:first-of-type{ margin-top: 0; }
.nav-link{
  display: block;
  color: var(--sidebar-text);
  text-decoration: none;
  font-size: .97rem;
  padding: var(--s2) 0 var(--s2) var(--s3);
  border-left: 2px solid transparent;
  transition: color .15s, border-color .15s, padding-left .15s;
}
.nav-link:hover{ color: var(--mint); border-left-color: var(--mint); padding-left: 26px; }
.nav-link.active{ color: var(--mint); border-left-color: var(--pink); }

.content{
  min-width: 0;
  padding: var(--s5) var(--s6) var(--s6);
  max-width: 1180px;
  /* left-aligned, not centred: short pages (links, music) would otherwise
     float out in the middle with a dead gap beside the sidebar */
}

/* ---------- headings ---------- */
.bar{
  font-family: 'Press Start 2P', monospace;
  background: var(--sidebar-bg);
  color: var(--mint);
  padding: var(--s3) var(--s4);
  font-size: 1.4rem;
  line-height: 1;
  display: inline-block;
  margin: 0 0 var(--s4);
}
h2.bar{ font-size: 1.05rem; margin-top: var(--s6); }

.crumb{ color: var(--dim); font-size: .85rem; margin: 0 0 var(--s3); }
.crumb a{ color: var(--dim); }

p{ line-height: 1.7; }
.note{ color: var(--dim); margin-top: var(--s4); font-size: .85rem; }

/* ---------- taped polaroid (pagedoll, ref sheets) ---------- */
.polaroid{
  margin: 0;                          /* <figure> ships with a 40px margin */
  background: var(--panel);
  padding: var(--s3) var(--s3) var(--s4);
  border: 1px solid var(--rule);
  box-shadow: 6px 7px 0 rgba(28,23,48,.12);
  transform: rotate(-2.5deg);
  position: relative;
}
.polaroid::before{                    /* strip of tape */
  content: "";
  position: absolute;
  top: -16px; left: 50%;
  transform: translateX(-50%) rotate(1.5deg);
  width: 124px; height: 34px;
  background: rgba(127,217,196,.55);
  border-left: 1px dashed rgba(28,23,48,.18);
  border-right: 1px dashed rgba(28,23,48,.18);
}
.polaroid img{ width: 100%; display: block; image-rendering: -webkit-optimize-contrast; }
.credit{
  font-size: .78rem;
  color: var(--dim);
  margin: var(--s3) 0 0;
  text-align: center;
  line-height: 1.4;
}
.credit a{ color: var(--pink); }

/* framed character image (shared by characters.html and the template) */
.portrait{
  margin: 0;
  background: var(--panel);
  border: 1px solid var(--rule);
  padding: var(--s3);
  box-shadow: 6px 7px 0 rgba(28,23,48,.10);
}
.portrait img{ width: 100%; display: block; image-rendering: -webkit-optimize-contrast; }

/* ---------- annotated / layered character images ----------
   See template-character.html for a working example and full markup notes.

     <div class="scene">
       <img class="layer" src="base.png" alt="...">              always visible
       <img class="layer" data-layer="body" src="body.png" alt=""> starts hidden
       <button class="hotspot" style="left:30%;top:20%">          note only
         <span class="detail">...</span>
       </button>
       <button class="hotspot swap" data-show="body" data-hide="base"
               style="left:50%;top:60%"></button>                 layer swap
     </div>

   Note-only hotspots are pure CSS. Layer swaps need layers.js. */
.scene, .annotated{ position: relative; display: block; line-height: 0; }

/* every layer sits in the same box; the first one sets the size */
.scene .layer{
  display: block;
  width: 100%;
  transition: opacity .45s ease;
}
.scene .layer[data-layer]{
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  opacity: 0;                 /* extra layers start hidden */
}
.scene .layer[data-layer].on{ opacity: 1; }
.scene .layer.off{ opacity: 0; }
.hotspot{
  position: absolute;
  transform: translate(-50%, -50%);
  width: 28px; height: 28px;
  padding: 0;
  border: 2px solid var(--mint);
  border-radius: 50%;
  background: rgba(28,23,48,.78);
  color: var(--mint);
  font-family: inherit; font-size: .72rem; line-height: 1;
  display: grid; place-items: center;
  cursor: help;
  z-index: 2;
}
.hotspot:hover, .hotspot:focus-visible{
  background: var(--mint);
  color: var(--sidebar-bg);
}
.hotspot .detail{
  position: absolute;
  bottom: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content; max-width: 230px;
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  border: 1px solid var(--mint);
  padding: var(--s2);
  font-size: .78rem; line-height: 1.5;
  text-align: left;
  opacity: 0; visibility: hidden;
  /* animates up into place rather than just appearing */
  transform: translateX(-50%) translateY(8px) scale(.96);
  transition: opacity .22s ease, transform .22s ease, visibility .22s;
  pointer-events: none;
  z-index: 3;
}
.hotspot:hover .detail, .hotspot:focus-visible .detail{
  opacity: 1; visibility: visible;
  transform: translateX(-50%) translateY(0) scale(1);
}
/* swap hotspots read differently from note hotspots */
.hotspot.swap{ border-color: var(--pink); color: var(--pink); }
.hotspot.swap:hover, .hotspot.swap:focus-visible{ background: var(--pink); color: #fff; }
/* soft pulse so hotspots are findable on a busy image — delete if unwanted */
.hotspot::before{
  content: "";
  position: absolute; inset: -5px;
  border-radius: 50%;
  border: 2px solid currentColor;
  opacity: .55;
  animation: hotspot-pulse 2.6s ease-out infinite;
  pointer-events: none;
}
@keyframes hotspot-pulse{
  0%  { transform: scale(.75); opacity: .55; }
  100%{ transform: scale(1.5); opacity: 0; }
}
/* for hotspots near the top edge, so the note doesn't run off the image */
.hotspot.below .detail{ bottom: auto; top: calc(100% + 12px); }

/* ---------- lightbox ---------- */
.lightbox{
  border: 0; padding: 0;
  background: transparent;
  max-width: 100vw; max-height: 100vh;
}
.lightbox::backdrop{ background: rgba(28,23,48,.9); }
.lb-inner{
  background: var(--panel);
  border: 1px solid var(--rule);
  padding: var(--s3);
  position: relative;
}
.lb-stage{ position: relative; display: block; line-height: 0; }
.lb-stage .art-face{
  width: min(74vh, 86vw);
  aspect-ratio: 1/1;
  font-size: 1rem;
}
.lb-stage img{
  display: block;
  max-width: 86vw; max-height: 74vh;
  width: auto; height: auto;
}
.lb-stage .face-b{
  display: flex;
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity .35s ease;
}
.lb-stage .callout{
  display: block;
  opacity: 0;
  font-size: .85rem;          /* scaled up with the rest of the enlarged view */
  padding: 6px 10px;
  transition: opacity .35s ease;
}
/* the second layer now lives here, on the enlarged view */
.lb-stage.has-alt:hover .face-a{ opacity: 0; }
.lb-stage.has-alt:hover .face-b,
.lb-stage.has-alt:hover .callout{ opacity: 1; }

.lb-bar{
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3);
  margin-top: var(--s3);
  line-height: 1.6;
}
.lb-caption{ color: var(--pink); font-size: .95rem; }
.lb-hint{ color: var(--dim); font-size: .78rem; }
.lb-close{
  /* inside the panel — negative offsets put it outside the dialog box,
     where it got clipped */
  position: absolute;
  top: var(--s2); right: var(--s2);
  z-index: 4;
  background: var(--sidebar-bg); color: var(--mint);
  border: 1px solid var(--mint);
  font-family: 'Press Start 2P', monospace; font-size: .6rem;
  padding: var(--s2) var(--s3);
  cursor: pointer;
}
.lb-close:hover{ background: var(--pink); border-color: var(--pink); color: #fff; }

@media (max-width: 720px){
  .lb-inner{ padding: var(--s2); }
  .lb-stage .art-face{ font-size: .7rem; }
}

/* ---------- mobile ---------- */
@media (max-width: 720px){
  .masthead{ padding: var(--s4) var(--s3); }
  .masthead::after{ left: 0; }
  .cornermark{ width: auto; padding: var(--s3) 0 0 var(--s3); }
  .cornermark svg{ width: 46px; height: 46px; }
  .tagline{ font-size: .7rem; letter-spacing: 2px; margin-top: var(--s2); }

  /* single column: masthead, nav, content — in document order */
  .layout{ display: block; background: none; }
  .sidebar{ width: 100%; padding: var(--s3); }   /* full-bleed band, as before */
  .flagstripe{ margin-top: var(--s3); }
  .cat{ display: none; }
  /* wrap onto a second row rather than scrolling links off the edge */
  .sidebar nav{
    display: flex;
    flex-wrap: wrap;
    gap: var(--s1) var(--s2);
  }
  .nav-link{
    border-left: none;
    border-bottom: 2px solid transparent;
    padding: var(--s1) var(--s2);
    white-space: nowrap;
  }
  .nav-link:hover{ padding-left: var(--s2); border-left: none; border-bottom-color: var(--mint); }
  .nav-link.active{ border-left: none; border-bottom-color: var(--pink); }

  .content{ padding: var(--s4) var(--s3) var(--s5); }
  .bar{ font-size: .95rem; }
  h2.bar{ margin-top: var(--s4); }
}

@media (prefers-reduced-motion: reduce){
  *{ transition: none !important; }
  .polaroid{ transform: none; }
  /* a colour cycling on a loop is exactly what this setting is for —
     hold the resting pink instead */
  a.wordmark:hover{ animation: none; text-shadow: 3px 3px 0 var(--pink); }
  /* another looping colour cycle — hold the resting trans flag */
  .flagstripe:hover::before{ animation: none; opacity: 0; }
  .hotspot::before{ animation: none; opacity: .4; }
  .hotspot .detail{ transform: translateX(-50%); }
  .hotspot:hover .detail, .hotspot:focus-visible .detail{ transform: translateX(-50%); }
}
