/* ============================================================
   MitaCatalogue — style.css
   Red + black, pixel fonts. Mobile-first; desktop tweaks below.
   ============================================================ */

/* :root is where I keep "variables" — reusable values.
   Instead of typing the same red everywhere, I define it once
   here and use var(--red) later. Change it once here = changes everywhere. */
:root {
  --red: #d11a1a;
  --red-bright: #ff3b3b;
  --red-dim: #7a1010;
  --ink: #0c0c0c;
  --panel-bg: #15080a;
  --text: #f3e6e6;
  --font-head: "Press Start 2P", monospace;   /* chunky pixel font: headers/labels */
  --font-body: "Pixelify Sans", monospace;    /* readable pixel font: body text */
  --room-max: 620px;                          /* how wide the room image is allowed to get */
}

/* A "reset" — strips default browser margins/padding so I control spacing. */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* The [hidden] HTML attribute normally hides an element, but any CSS rule
   that sets display (like .panel { display: flex } below) overrides it.
   !important here makes [hidden] always win, so panels stay hidden until
   JS removes the attribute. Without this, panels show on load and the
   close button silently fails. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

/* When a panel or the lightbox is open, lock body scrolling so only the
   panel content scrolls (not the room behind it). JS adds this class. */
body.panel-open { overflow: hidden; }

/* Custom scrollbar for panel bodies — thin red, matches the theme.
   Only works in WebKit/Chromium browsers; Firefox falls back to default. */
.panel-body::-webkit-scrollbar { width: 8px; }
.panel-body::-webkit-scrollbar-track { background: #0a0404; }
.panel-body::-webkit-scrollbar-thumb { background: var(--red-dim); }
.panel-body::-webkit-scrollbar-thumb:hover { background: var(--red); }
/* Firefox */
.panel-body { scrollbar-width: thin; scrollbar-color: var(--red-dim) #0a0404; }

body {
  background: var(--ink);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.5;
  min-height: 100vh;
  overflow-x: hidden;
}

/* Tiny screen-glow behind everything for atmosphere */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: radial-gradient(circle at 50% 40%, #1a0606 0%, #000 70%);
  pointer-events: none;
  z-index: 0;
}

/* ============================================================
   Splash / click to enter
   ============================================================ */

#splash {
  /* Fixed overlay on ALL screen sizes — covers the room until clicked.
     Semi-transparent so the room is faintly visible behind it. */
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  background: rgba(8, 4, 4, 0.88);
  backdrop-filter: blur(2px);
  cursor: pointer;
  transition: opacity .6s ease;
}

.splash-inner { user-select: none; }

.splash-title {
  font-family: var(--font-head);
  font-size: clamp(20px, 6vw, 44px);
  color: var(--red-bright);
  letter-spacing: 1px;
  text-shadow: 0 0 12px rgba(209, 26, 26, 0.5);
  margin-bottom: 24px;
}

.splash-sub {
  font-family: var(--font-head);
  font-size: clamp(10px, 2.6vw, 14px);
  color: var(--text);
  margin-bottom: 10px;
}

.splash-hint {
  font-size: 14px;
  color: var(--red-dim);
  font-style: italic;
}

/* Loading indicator: shown by JS while the OST buffers.
   A simple blinking "loading audio..." text. */
.splash-loading {
  font-family: var(--font-head);
  font-size: 10px;
  color: var(--red-bright);
  margin-top: 18px;
  animation: blink 1s steps(2) infinite;
}
@keyframes blink {
  50% { opacity: 0.2; }
}

/* When loading, hide the "click to enter" text so the user knows
   something is happening, not that their click was ignored. */
#splash.is-loading .splash-sub,
#splash.is-loading .splash-hint {
  display: none;
}

/* After entering: fade the splash out. */
#splash.is-hidden {
  opacity: 0;
  pointer-events: none;
}
#splash.is-gone {
  display: none;
}

/* ============================================================
   The stage + room image + hotspots
   ============================================================ */

#stage {
  position: relative;
  z-index: 1;
  /* Center the room in the viewport on all screen sizes.
     Since the splash is now a fixed overlay (not in flow), the stage
     needs to fill the viewport and center its content. */
  min-height: 100vh;
  padding: 16px 12px 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* .room wraps the image. It shrinks to the image size, which is what lets
   the percentage-positioned hotspots line up with the picture. */
.room {
  position: relative;
  width: 100%;
  max-width: var(--room-max);
  line-height: 0; /* removes a tiny gap under the image */
}

.room-img {
  width: 100%;
  display: block;
  border: 2px solid var(--red-dim);
  box-shadow: 0 0 0 4px #000, 0 10px 40px rgba(0, 0, 0, 0.8);
}

/* CRT scanline overlay — the "one real aesthetic risk".
   A ::after pseudo-element draws faint horizontal lines over the room image
   for a retro CRT-screen feel. It's very low opacity so the image is still
   clearly visible, and it doesn't touch the panels (where content lives).
   pointer-events: none means clicks pass through it to the hotspots below. */
.room::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 2px,
    rgba(0, 0, 0, 0.15) 3px,
    rgba(0, 0, 0, 0) 4px
  );
  pointer-events: none;
  z-index: 2;                     /* above the image, below hotspots */
}

/* Caption under the room (shown on desktop only; see the media query below) */
.room-caption {
  display: none;                  /* hidden on mobile by default */
  font-family: var(--font-head);
  font-size: 10px;
  color: var(--red-dim);
  text-align: center;
  margin-top: 14px;
  letter-spacing: 1px;
}

/* ============================================================
   Dark room mode (before the light switch is clicked)
   The room starts dark. Hotspot dots are dimmed so they're hard
   to see. Only the light switch dot is bright. Clicking the
   light switch removes .is-dark and everything returns to normal.
   ============================================================ */

/* Dark room: dim the image. brightness(0.25) = 25% of normal brightness.
   Not pitch black — you can faintly see the shelf, but hotspots are
   hard to spot. */
.room.is-dark .room-img {
  filter: brightness(0.25);
}

/* Dark room: dim all hotspot dots so they're hard to see.
   The light switch dot stays bright (see below). */
.room.is-dark .hotspot:not(.light-switch) .hotspot-dot {
  opacity: 0.12;
  animation: none;
  box-shadow: none;
}

/* Light switch dot: ALWAYS bright, even in dark mode.
   It's the only hint the user has. We use a warmer gold color
   and a stronger glow so it reads as "a light to turn on". */
.hotspot.light-switch .hotspot-dot {
  background: #ffcc33;
  box-shadow: 0 0 12px 4px rgba(255, 204, 51, 0.8);
  width: 12px;
  height: 12px;
}

/* In dark mode, the light switch dot pulses more urgently. */
.room.is-dark .hotspot.light-switch .hotspot-dot {
  animation: pulse-urgent 1s ease-in-out infinite;
}
@keyframes pulse-urgent {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(1.6); }
}

/* Dark room: the CRT scanlines get stronger for atmosphere. */
.room.is-dark::after {
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 2px,
    rgba(0, 0, 0, 0.3) 3px,
    rgba(0, 0, 0, 0) 4px
  );
}

/* Smooth transition when the light turns on. */
.room-img, .room .hotspot-dot {
  transition: filter .8s ease, opacity .8s ease;
}

/* Hotspots: invisible clickable boxes over the image.
   They are positioned with inline left/top/width/height in percentages,
   so they track the image as it scales.
   transform: translate(-50%, -50%) means left/top marks the CENTER of the
   box, not its corner — so you can think "the object is at X%, Y%" and the
   box centers itself there. */
.hotspot {
  position: absolute;
  border: none;
  background: transparent;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translate(-50%, -50%);
}

/* A small pulsing dot so you can find clickable things.
   This is the "one real aesthetic risk" — a subtle scanline marker. */
.hotspot-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--red-bright);
  box-shadow: 0 0 8px 2px rgba(255, 59, 59, 0.7);
  animation: pulse 1.6s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 0.85; transform: scale(1); }
  50%      { opacity: 0.25; transform: scale(1.5); }
}

/* Pending hotspots: placed but not wired yet. Dimmer, no pulse —
   so you can tell the working one (laptop) from the not-yet ones. */
.hotspot.pending .hotspot-dot {
  background: #8a3b3b;
  box-shadow: 0 0 4px rgba(138, 59, 59, 0.4);
  animation: none;
  opacity: 0.55;
}

/* On hover (desktop), show a faint box so you see what you're clicking. */
.hotspot:hover .hotspot-dot { opacity: 1; transform: scale(1.4); }
.hotspot:hover {
  outline: 1px dashed rgba(255, 59, 59, 0.6);
  outline-offset: -2px;
}

/* ============================================================
   Panels (the little "windows" that open)
   ============================================================ */

#panels { z-index: 30; }

.panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(90vw, 460px);
  max-height: 80vh;
  background: var(--panel-bg);
  border: 2px solid var(--red);
  box-shadow: 0 0 0 4px #000, 0 0 30px rgba(209, 26, 26, 0.35),
              0 20px 50px rgba(0, 0, 0, 0.8);
  display: flex;
  flex-direction: column;
  font-family: var(--font-body);
  z-index: 30;
  animation: pop-in .18s ease;
}

/* A "backdrop" that darkens the room behind the panel. Added by JS. */
.panel-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 25;
}

@keyframes pop-in {
  from { opacity: 0; transform: translate(-50%, -48%) scale(0.96); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.panel-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: var(--red);
  color: #fff;
}

.panel-title {
  font-family: var(--font-head);
  font-size: 12px;
  letter-spacing: 1px;
}

.panel-close {
  font-family: var(--font-head);
  font-size: 12px;
  background: transparent;
  border: 1px solid #fff;
  color: #fff;
  width: 26px;
  height: 26px;
  cursor: pointer;
  line-height: 1;
}
.panel-close:hover { background: #fff; color: var(--red); }

.panel-body {
  padding: 18px 18px 22px;
  overflow-y: auto;
}

.panel-list { list-style: none; display: flex; flex-direction: column; gap: 14px; }

.list-label {
  display: block;
  font-family: var(--font-head);
  font-size: 11px;
  color: var(--red-bright);
  margin-bottom: 4px;
}
.list-desc {
  display: block;
  font-size: 18px;
  color: var(--text);
}

/* ----- Timeline panel (Brief 02 §1 / Brief 03) ----------------------- */
/* Two lists (.timeline-long, .timeline-recent) inside one panel, each
   with a vertical connector line down the left and a node dot per entry.
   The long arc is one entry per year (slow, generous spacing); the recent
   sprint is one per month (fast, tighter spacing + a brighter accent on its
   line/nodes) so the acceleration reads visually, not just from the headings.
   Reuses list-label/list-desc for the text — only the connector chrome is new. */

.timeline-heading {
  font-family: var(--font-head);
  font-size: 11px;
  color: var(--text);
  letter-spacing: 1px;
  margin: 20px 0 12px;
  padding-left: 22px;           /* aligns with the timeline text, past the line */
  position: relative;
}
/* A little tick where the heading meets the connector line. */
.timeline-heading::before {
  content: "";
  position: absolute;
  left: 7px;
  top: 50%;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  background: var(--red);
  box-shadow: 0 0 6px rgba(209, 26, 26, 0.7);
}
.timeline-heading:first-of-type { margin-top: 4px; }

.timeline {
  list-style: none;
  display: flex;
  flex-direction: column;
  position: relative;
  padding-left: 22px;           /* room for the line + node + gutter */
}
/* The vertical connector line itself, running down the left of each list. */
.timeline::before {
  content: "";
  position: absolute;
  left: 7px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: var(--red-dim);
}

/* Long arc: generous spacing — one slow beat per year. */
.timeline-long { gap: 18px; padding-bottom: 6px; }
.timeline-long li { margin-bottom: 4px; }

/* Recent sprint: tight spacing — brisk monthly beats. Its connector + nodes
   switch to the brighter red so the pace shift reads at a glance. */
.timeline-recent { gap: 8px; }
.timeline-recent::before { background: var(--red-bright); }

/* Node dot on the line for each entry. */
.timeline li { position: relative; }
.timeline-node {
  position: absolute;
  left: -22px;                  /* sits on the connector line (relative to padded li) */
  top: 2px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 6px rgba(209, 26, 26, 0.6);
  /* vertical center the dot on roughly the first text line */
  margin-top: 4px;
}
.timeline-recent .timeline-node {
  background: var(--red-bright);
  box-shadow: 0 0 6px rgba(255, 59, 59, 0.7);
}

/* Tighter type rhythm for the sprint so the months feel closer together. */
.timeline-recent .list-label { font-size: 10px; margin-bottom: 2px; line-height: 1.4; }
.timeline-recent .list-desc  { font-size: 15px; }
.timeline-long .list-label  { line-height: 1.5; }

/* ----- Text blocks (about me, intros, stubs) ----- */
.panel-body p { margin-bottom: 12px; }
.panel-body p:last-child { margin-bottom: 0; }

.panel-intro {
  font-family: var(--font-head);
  font-size: 10px;
  color: var(--red-bright);
  margin-bottom: 16px;
}

/* "coming soon" style for the clock stub */
.panel-stub {
  font-family: var(--font-head);
  font-size: 10px;
  color: var(--red-dim);
  text-align: center;
  padding: 20px 0;
}

/* ----- Image grids (drawings, photos) ----- */
/* CSS Grid: auto-fill makes as many columns as fit, each at least 90px wide.
   The gap is the space between thumbnails. */
.panel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: 8px;
}

/* Square thumbnail box. The aspect-ratio + width:100% gives every cell a
   definite square shape, no matter the original image's dimensions. */
.panel-thumb {
  aspect-ratio: 1 / 1;
  width: 100%;
  height: 100%;
  background: #2a0d0d;
  border: 1px solid var(--red-dim);
  overflow: hidden;
  display: block;
}
.panel-thumb:hover { border-color: var(--red); }

/* Placeholder <div class="panel-thumb">img</div>: center the "img" text */
div.panel-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-head);
  font-size: 9px;
  color: var(--red-dim);
}

/* Real <img class="panel-thumb">: crop to fill the square (no stretching).
   object-fit: cover = fill the box, cropping overflow. */
img.panel-thumb {
  object-fit: cover;
  cursor: zoom-in;                /* hint that clicking opens the full image */
  padding: 0;
  background: #000;
}

/* ----- Lightbox (full image view) ----- */
#lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 40;                    /* above panels (30) and backdrops (25) */
  cursor: zoom-out;
  padding: 20px;
}
/* .lightbox-frame wraps the image + caption so they stack vertically and
   clicks on the caption don't close the lightbox (only clicks on the dark
   area around the frame do). */
.lightbox-frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: 100%;
  max-height: 100%;
  cursor: default;
}
#lightbox img {
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;            /* show the WHOLE image, no crop */
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.8);
}
.lightbox-caption {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--text);
  text-align: center;
  max-width: 600px;
  line-height: 1.5;
  padding: 0 12px;
}
.lightbox-caption .cap-title {
  font-family: var(--font-head);
  font-size: 11px;
  color: var(--red-bright);
  display: block;
  margin-bottom: 6px;
}
.lightbox-caption .cap-meta {
  font-size: 13px;
  color: var(--red-dim);
  display: block;
  margin-bottom: 6px;
}
.lightbox-caption .cap-desc {
  font-size: 15px;
  color: var(--text);
}

/* ----- Journal posts ----- */
.post {
  margin-bottom: 22px;
  padding-bottom: 18px;
  border-bottom: 1px dashed var(--red-dim);
}
.post:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }

.post-date {
  font-family: var(--font-head);
  font-size: 9px;
  color: var(--red-bright);
  margin-bottom: 8px;
}

/* ----- Gallery section headings (cats / people) ----- */
.gallery-section {
  font-family: var(--font-head);
  font-size: 11px;
  color: var(--red-bright);
  margin: 18px 0 10px;
  letter-spacing: 1px;
}
.gallery-section:first-of-type { margin-top: 0; }

/* ----- Music panel: bio line + audio players ----- */
.music-bio {
  font-size: 18px;
  margin-bottom: 18px;
  color: var(--text);
}
.music-bio strong { color: var(--red-bright); font-weight: 700; }

.music-list li { margin-bottom: 14px; }
.music-list .list-label { margin-bottom: 6px; }

/* <audio controls> is the browser's built-in audio player. We just make it
   fill the panel width and dark-ify it a little. */
audio {
  width: 100%;
  height: 34px;
}

/* ----- Song cards (rendered from songs.js) ----- */
/* Each song is a "card" with a clickable title, an audio player, and a
   hidden details section that expands when the title is clicked. */
.song-card {
  margin-bottom: 18px;
  padding: 12px;
  background: #1a0a0c;
  border: 1px solid var(--red-dim);
  border-radius: 0;
}
.song-card:hover { border-color: var(--red); }

/* The title button: clicking it toggles the details view. */
.song-title {
  font-family: var(--font-head);
  font-size: 11px;
  color: var(--red-bright);
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  padding: 0;
  margin-bottom: 8px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.song-title:hover { color: var(--text); }

/* Small "details" indicator that hints there's more to see */
.song-title::after {
  content: "[ + ]";
  font-size: 9px;
  color: var(--red-dim);
}
.song-card.is-expanded .song-title::after {
  content: "[ - ]";
}

.song-meta {
  font-size: 14px;
  color: var(--red-dim);
  margin-bottom: 8px;
}

/* Details section: hidden by default, shown when .is-expanded is added. */
.song-details {
  display: none;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--red-dim);
}
.song-card.is-expanded .song-details { display: block; }

.song-story {
  font-size: 17px;
  color: var(--text);
  line-height: 1.6;
  margin-bottom: 12px;
}

/* SoundCloud link — a clear, deliberate link (not a whole-card redirect).
   Only shown when soundcloudUrl is not null. */
.song-link {
  font-family: var(--font-head);
  font-size: 9px;
  color: var(--red-bright);
  text-decoration: none;
  border: 1px solid var(--red-dim);
  padding: 6px 10px;
  display: inline-block;
}
.song-link:hover {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
}

/* "No SoundCloud" note for tracks without a URL */
.song-nolink {
  font-family: var(--font-head);
  font-size: 8px;
  color: var(--red-dim);
}

/* ----- About me block ----- */
/* Photo on top, text below on mobile; side by side on wider panels. */
.about-block {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: center;
}
.about-photo {
  width: min(100%, 220px);
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 2px solid var(--red-dim);
}
.about-text {
  font-size: 18px;
  line-height: 1.6;
  color: var(--text);
}
.about-text p { margin-bottom: 10px; }
.about-text p:last-child { margin-bottom: 0; }

/* ----- Project links ----- */
.project-item { margin-bottom: 20px; }
.project-desc {
  display: block;
  font-size: 17px;
  color: var(--text);
  line-height: 1.5;
  margin: 6px 0 10px;
}
.project-links { display: flex; gap: 10px; flex-wrap: wrap; }
.project-link {
  font-family: var(--font-head);
  font-size: 9px;
  color: var(--red-bright);
  text-decoration: none;
  border: 1px solid var(--red-dim);
  padding: 6px 10px;
}
.project-link:hover {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
}

/* In-card thumbnail strip for project cards that have screenshots.
   Reuses img.panel-thumb so the existing delegated lightbox listener
   (script.js) opens any thumbnail at full size on click — no new zoom
   component. The strip is a 3-up grid so landscape screenshots keep a
   uniform preview height without being squashed into a single row. */
.project-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin: 10px 0 12px;
}
/* Screenshots are landscape; square-crop would cut data-table columns, so
   widen the aspect and crop with cover (the full image is one click away
   in the lightbox). */
.project-gallery img.panel-thumb {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Expandable full description toggle (reuses song-card .is-expanded
   convention). The "more" button flips .is-expanded on the .project-item;
   CSS reveals .project-full below. */
.project-more {
  font-family: var(--font-head);
  font-size: 9px;
  color: var(--red-dim);
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px 0 0;
  display: block;
}
.project-more::after  { content: " [ + ]"; }
.project-item.is-expanded .project-more::after { content: " [ - ]"; }
.project-more:hover { color: var(--red-bright); }

.project-full {
  display: none;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--red-dim);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
}
.project-item.is-expanded .project-full { display: block; }
.project-full p { margin-bottom: 10px; }
.project-full p:last-child { margin-bottom: 0; }
/* The CGPA call-out at the end of the Project 4flat full description. */
.project-full .p4f-highlight {
  font-family: var(--font-head);
  font-size: 10px;
  color: var(--red-bright);
  letter-spacing: 0.5px;
  margin-top: 6px;
}

/* ----- Clock panel ----- */
.clock-body {
  text-align: center;
  padding: 30px 18px;
}
.clock-display {
  font-family: var(--font-head);
  font-size: clamp(24px, 6vw, 36px);
  color: var(--red-bright);
  text-shadow: 0 0 16px rgba(209, 26, 26, 0.4);
  margin-bottom: 12px;
  letter-spacing: 2px;
}
.clock-label {
  font-family: var(--font-head);
  font-size: 10px;
  color: var(--red-dim);
}

/* ----- Shuffle music player (fixed bar at bottom) ----- */
/* Non-invasive: a thin bar at the bottom of the screen. Doesn't block the
   room. Always visible once the visitor has entered (JS removes [hidden]
   on the splash click); there is deliberately no close button. */
#shuffle-player {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 15;                   /* below panels (30) and lightbox (40) */
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: rgba(8, 4, 4, 0.95);
  border-top: 2px solid var(--red);
  font-family: var(--font-head);
  font-size: 10px;
  color: var(--text);
}
.shuffle-btn {
  font-family: var(--font-head);
  font-size: 10px;
  background: transparent;
  border: 1px solid var(--red-dim);
  color: var(--red-bright);
  padding: 5px 8px;
  cursor: pointer;
  line-height: 1;
}
.shuffle-btn:hover { background: var(--red); color: #fff; border-color: var(--red); }
.shuffle-play { min-width: 50px; }
.shuffle-label {
  flex: 1;                       /* takes up remaining space */
  font-size: 9px;
  color: var(--red-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* "Stopped" state (JS toggles .is-stopped): a YouTube embed killed the
   site music. The bar stays visible — it is the manual restart point —
   but drops to a dashed dim border, and the label gains a blinking square
   as a clear "deck stopped" indicator. Reuses the splash's blink anim. */
#shuffle-player.is-stopped {
  border-top-style: dashed;
  border-top-color: var(--red-dim);
}
#shuffle-player.is-stopped .shuffle-label { color: var(--red); }
#shuffle-player.is-stopped .shuffle-label::before {
  content: "\25A0  ";            /* two spaces: the first terminates the escape */
  animation: blink 1s steps(2) infinite;
}

/* ----- Devlog panel (colored pens hotspot) -----
   Reusable "devlog entry" pattern: caption + image set. Each entry is an
   <article> separated by a dashed rule, so future build-stage entries can be
   appended without touching layout. Images reuse img.panel-thumb so the
   existing delegated lightbox listener opens them full-size on click — no
   new zoom component. Unlike the square-cropped gallery thumbs, devlog
   images keep their natural aspect (sketches shouldn't be cropped). */
.devlog-entry {
  margin-bottom: 22px;
  padding-bottom: 18px;
  border-bottom: 1px dashed var(--red-dim);
}
.devlog-entry:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }

.devlog-caption {
  font-family: var(--font-head);
  font-size: 11px;
  color: var(--red-bright);
  letter-spacing: 0.5px;
  margin-bottom: 10px;
}

.devlog-images {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* Natural aspect ratio (no square crop), capped height so two side-by-side
   sketches fit a typical panel viewport. Click opens the lightbox. */
.devlog-images img.panel-thumb {
  flex: 1 1 200px;
  min-width: 0;
  aspect-ratio: auto;
  width: auto;
  height: auto;
  max-height: 340px;
  object-fit: contain;
  background: #000;
}

/* ----- Full-image panel (corkboard) ----- */
.full-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 72vh;          /* leave room for the description above */
  object-fit: contain;       /* show the whole image, don't crop */
  background: #000;
}

/* Corkboard description text (sits above the full image) */
.corkboard-desc {
  font-size: 17px;
  color: var(--text);
  line-height: 1.6;
  margin-bottom: 16px;
}

/* ----- Visitor counter (retro GeoCities-style badge) (Feature 2) ----- */
/* An amber LCD readout that fits the CRT-desk vibe. The number itself is a
   plain text node filled by loadVisitorCount() in script.js — no user data,
   nothing to escape. */
.visitor-counter {
  display: flex;
  justify-content: center;
  margin: 14px 0 14px;
}
.visitor-count {
  font-family: var(--font-head);
  font-size: clamp(28px, 8vw, 44px);
  color: #000;
  background: #ffcc33;
  border: 3px solid #000;
  box-shadow: 0 0 0 3px var(--red-dim), 0 0 22px rgba(255, 204, 51, 0.4);
  padding: 10px 18px;
  letter-spacing: 4px;
  min-width: 6ch;
  text-align: center;
  /* faint scanline texture so it reads as a little screen, not a flat tile */
  background-image: repeating-linear-gradient(
    to bottom,
    #ffcc33 0px, #ffcc33 2px,
    #e6b520 3px, #e6b520 4px
  );
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
}
.visitor-count.is-error {
  color: var(--red-dim);
  background: #1a0a0c;
  box-shadow: none;
  border-color: var(--red-dim);
  background-image: none;
  text-shadow: none;
}
.visitor-fine {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--red-dim);
  text-align: center;
}

/* Adblocker warning — only visible when the counter shows "\u2014".
   Muted enough to be helpful, not an alarm. */
.visitor-warn {
  font-size: 11px;
  color: #8a5a3a;
  margin-top: 6px;
}

/* ----- Credits panel: museum plaque wall + spotlight (Brief 04 §3) -----
   This is the one hotspot Fred explicitly wants distinct UI/UX for, so it
   does NOT reuse .panel-list/.list-label from the Projects/Books panels.
   Each credit renders as a small "plaque" card: a header strip with the name
   in the chunky pixel font, and a body line in the readable pixel font below.
   Plaques are grouped under two wing headings (.credits-wing) — structurally
   the same role as the Timeline panel's "the search" / "the sprint" headings
   but visually its own thing.

   Spotlight reveal (CSS-only, no JS): plaques sit dim by default; on
   :hover/:focus-within a radial-gradient "spotlight" glow brightens the
   plaque from above. This deliberately echoes the room's own dark/light
   switch mechanic, but scoped to this panel — a callback without new JS.

   The plaque background is a subtle dark brass gradient. Fred's mum's
   brand (Jess Boubie Craft) works in brass, so this ties the panel to that
   visual language without being literal. Kept low-key so it doesn't fight
   the red/black palette. */
.credits-wing {
  font-family: var(--font-head);
  font-size: 11px;
  color: var(--red-bright);
  letter-spacing: 1px;
  margin: 18px 0 10px;
}
.credits-wing:first-of-type { margin-top: 0; }

.plaque-wall { list-style: none; display: flex; flex-direction: column; gap: 10px; }

.plaque {
  position: relative;
  /* Dark brass gradient — a quiet nod to Jess Boubie Craft's material
     without competing with the red/black palette. */
  background: linear-gradient(160deg, #2a1d0c 0%, #1c1308 55%, #150f06 100%);
  border: 1px solid #574017;
  box-shadow: inset 0 1px 0 rgba(255, 215, 130, 0.08);
  /* Dim by default — the spotlight reveal lifts this on hover/focus. */
  opacity: 0.72;
  transition: opacity .25s ease, border-color .25s ease, box-shadow .25s ease;
}

/* The spotlight: a radial glow from above the plaque, hidden by default and
   faded in on hover/focus-within. pointer-events:none so it never blocks
   links inside the plaque (mxrza.xyz badge, header link). */
.plaque::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(130px 90px at 50% -12%, rgba(255, 220, 150, 0.22), transparent 70%);
  opacity: 0;
  transition: opacity .3s ease;
  pointer-events: none;
}
.plaque:hover,
.plaque:focus-within {
  opacity: 1;
  border-color: var(--red-bright);
  box-shadow: inset 0 1px 0 rgba(255, 215, 130, 0.18),
              0 0 14px rgba(255, 59, 59, 0.18);
}
.plaque:hover::before,
.plaque:focus-within::before { opacity: 1; }

/* Cover-art / screenshot thumbnail for inspiration plaques (Brief 04 §2).
   Sits between the header strip and the body description. Capped height
   keeps the plaque wall scannable; object-fit: cover crops letterboxed art
   cleanly. */
.plaque-thumb {
  display: block;
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  background: #000;
  border-top: 1px solid rgba(255, 204, 51, 0.18);
  border-bottom: 1px solid rgba(255, 204, 51, 0.18);
}

/* Header strip — name in the chunky pixel font on a slightly brighter
   brass line. */
.plaque-header {
  font-family: var(--font-head);
  font-size: 11px;
  color: #f4d488;
  padding: 8px 10px 6px;
  border-bottom: 1px solid rgba(255, 204, 51, 0.22);
  letter-spacing: 0.5px;
}
/* Body text — must stay legible against the dark brass.
   --text (#f3e6e6) on #1c1308 passes WCAG AA comfortably. */
.plaque-body {
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--text);
  padding: 8px 10px 10px;
  line-height: 1.5;
  /* monospace width so the typewriter reveal doesn't reflow the plaque as
     characters stream in (data-typewriter targets live in this element). */
  font-variant-numeric: tabular-nums;
  min-height: 1.5em;
}

/* Header link (mxrza.xyz only — matches .project-link convention). */
.plaque-link {
  color: #f4d488;
  text-decoration: none;
  border-bottom: 1px dotted rgba(255, 204, 51, 0.5);
}
.plaque-link:hover {
  color: var(--red-bright);
  border-bottom-color: var(--red-bright);
}

/* Old-school 88x31 webring badge — displayed at its native size, standard
   webring-button placement. target=_blank rel=noopener set in the markup,
   matching .project-link. */
.webring-badge {
  display: inline-block;
  margin: 2px 10px 10px;
  border: 1px solid var(--red-dim);
  line-height: 0;
  background: #000;
}
.webring-badge img {
  display: block;
  width: 88px;
  height: 31px;
}
.webring-badge:hover { border-color: var(--red-bright); }

/* ============================================================
   Desktop (>= 768px)
   The room is a tall portrait image. On a wide screen we want it to feel
   like a deliberate centerpiece — vertically centered, sized to fit the
   viewport height, with a caption and ambient glow. Not a phone layout
   stretched out with empty space below.
   ============================================================ */

@media (min-width: 768px) {
  /* Stage already centers from the base styles; desktop just adds
     the height-based room sizing and stronger glow. */

  /* Room: size to viewport HEIGHT (not width) since the image is portrait 3:4.
     calc(82vh * 0.75) = "82% of screen height, times the 3/4 aspect ratio"
     This keeps the whole room visible without scrolling on desktop.
     max-width caps it so the image doesn't get huge on very tall screens. */
  .room {
    max-width: min(700px, calc(82vh * 0.75));
  }

  /* Stronger spotlight glow on desktop — makes the room feel displayed. */
  .room-img {
    box-shadow: 0 0 0 4px #000, 0 0 60px rgba(209, 26, 26, 0.15),
                0 20px 60px rgba(0, 0, 0, 0.9);
  }

  /* Show the caption on desktop. */
  .room-caption { display: block; }

  /* Wider panels on desktop. */
  .panel { width: min(70vw, 520px); }
}

/* ============================================================
   Small desktop / large tablet (768px–1024px)
   Slightly smaller room so it doesn't dominate narrow laptop screens.
   ============================================================ */

@media (min-width: 768px) and (max-width: 1024px) {
  .room { max-width: min(560px, calc(80vh * 0.75)); }
}
