/* site/assets/styles.css — Prototype Cabinet landing page.
   "Specimen Press" risograph aesthetic: colored paper stock, plum ink,
   cut-paper specimen cards with hard offset shadows, printed plates.
   Dual themes, switched by data-theme="dark" on <html> (set pre-CSS by a
   head script; never prefers-color-scheme):
     light "Specimen Press" (paper/sage/ink/clay/sand) lives in :root and
     the base rules; dark "Night Press" (night/pit/plum/chalk/sage/clay/
     sand) is a block of html[data-theme="dark"] overrides at the end of
     this file. --chalk aliases the paper hex and --plum the ink hex.
   Palette-only hexes + rgba tints of their exact triples; the only new
   values in dark are --night #332528 and --pit #221518.
   System font stacks. No external resources. */

/* ---------- tokens ---------- */
:root {
  --paper: #c0caad;
  --sage: #9da9a0;
  --ink: #654c4f;
  --clay: #b26e63;
  --sand: #cec075;

  /* Night Press (dark theme) aliases: --chalk re-uses the paper hex and
     --plum the ink hex (both palettes share those values); --night and
     --pit are the only new inks. Dark styling keys off
     html[data-theme="dark"] overrides near the end of this file. */
  --chalk: var(--paper);
  --plum: var(--ink);
  /* native form controls/scrollbars follow the active theme */
  color-scheme: light;
  --night: #332528;
  --pit: #221518;

  --display: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --body-font: system-ui, -apple-system, "Segoe UI", sans-serif;

  --page-max: 1200px;
  /* full-bleed gutter: content column aligns across sections; the wordmark
     panel pulls itself left by this amount to bleed to the viewport edge */
  --gutter: max(20px, calc((100vw - var(--page-max)) / 2));
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }

[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body-font);
  font-size: 16px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}

h1, h2, p { margin: 0; }

img { max-width: 100%; }

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

/* visible keyboard focus everywhere */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--clay);
  outline-offset: 2px;
}

/* ---------- masthead ---------- */
.masthead { background: var(--paper); }

.masthead-inner {
  display: flex;
  align-items: stretch;
  gap: clamp(18px, 3vw, 44px);
  padding: 0 var(--gutter) 16px;
}

.wordmark {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  margin-left: calc(-1 * var(--gutter)); /* bleed to the page's left edge */
  padding: 16px var(--gutter) 14px var(--gutter);
  background: var(--ink);
  color: var(--paper);
}

#site-title {
  font-family: var(--display);
  font-size: clamp(26px, 3.6vw, 42px);
  font-weight: 900;
  line-height: 0.92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  max-width: 8ch;
}

.wordmark-mark {
  flex: none;
  width: 13px;
  height: 13px;
  background: var(--sand);
}

.masthead-copy {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 7px;
  padding: 16px 0 2px;
}

.kicker {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--clay);
}

.subtitle {
  max-width: 52ch;
  font-size: 0.86rem;
  line-height: 1.45;
}

.count-line {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.byline {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.byline a,
.site-credit a {
  color: var(--clay);
  text-decoration: none;
  border-bottom: 1px solid rgba(178, 110, 99, 0.5);
  padding-bottom: 1px;
}
.byline a:hover,
.site-credit a:hover,
.byline a:focus-visible,
.site-credit a:focus-visible {
  border-bottom-color: var(--clay);
}

/* ---------- filter chips ---------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  border-top: 2px solid var(--ink);
  padding: 10px var(--gutter) 12px;
}

.chip,
.theme-toggle {
  appearance: none;
  -webkit-appearance: none;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--ink);
  padding: 5px 12px;
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease,
    background-color 140ms ease;
}
.chip:hover,
.theme-toggle:hover {
  color: var(--clay);
  border-color: var(--clay);
}
.chip.active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
/* the theme toggle rides at the end of the chip row; margin-left:auto
   right-aligns it inside the flex .filters container */
.theme-toggle { margin-left: auto; }

/* ---------- grid ---------- */
.grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  /* stretch (default): panels in a row share the tallest card's height */
  padding: 18px var(--gutter) 30px;
}

.empty-note {
  grid-column: 1 / -1;
  margin: 0;
  padding: 18px 20px;
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ---------- panels (cut-paper specimen cards) ---------- */
.panel {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: inherit;
  text-align: left;
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
  padding: 0;
  background: var(--paper);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  cursor: pointer;
  transition: transform 160ms ease, box-shadow 160ms ease;
}

.panel:nth-child(odd) { transform: rotate(-0.5deg); }
.panel:nth-child(even) { transform: rotate(0.5deg); }

.panel:hover,
.panel:focus-visible,
.panel:focus-within {
  transform: translateY(-2px) rotate(0deg);
  box-shadow: 6px 6px 0 var(--ink);
}

.panel-tab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 12px;
  background: var(--cat, var(--sage));
  color: var(--cat-text, var(--ink)); /* fill carries the text color */
  border-bottom: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
/* category = fill color: the panel carries data-piece-category and the tab
   reads --cat/--cat-text from it; unknown categories fall through to the
   var() defaults above (sage fill, ink text). */
.panel[data-piece-category="instrument"] { --cat: var(--clay); --cat-text: var(--paper); }
.panel[data-piece-category="sequencer"] { --cat: var(--sand); --cat-text: var(--ink); }
.panel[data-piece-category="synthesizer"] { --cat: var(--ink); --cat-text: var(--paper); }
.panel[data-piece-category="game"] { --cat: var(--sage); --cat-text: var(--ink); }

.panel-index { font-weight: 700; }

.panel-category { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.panel-media {
  display: block;
  aspect-ratio: 400 / 260;
  overflow: hidden;
  border-bottom: 2px solid var(--ink);
  background: rgba(157, 169, 160, 0.35); /* sage tint while the plate loads */
}
.panel-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.panel-body {
  display: flex;
  flex-direction: column;
  gap: 7px;
  flex: 1; /* absorb the extra height of stretched (equal-height) rows */
  padding: 12px 14px 15px;
}

.panel-title {
  font-family: var(--display);
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.panel-tagline {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--clay);
}
.panel-description {
  font-size: 0.82rem;
  line-height: 1.45;
}

/* ---------- footer ---------- */
.site-footer { border-top: 2px solid var(--ink); }

.site-footer p {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px var(--gutter) 18px;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.site-footer p:first-of-type::before {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  background: var(--clay); /* stamped square */
}

.site-footer .site-credit {
  padding-top: 0;
  padding-bottom: 16px;
}

/* ---------- live preview viewer ---------- */
#viewer {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  background: rgba(101, 76, 79, 0.55); /* plum ink wash */
}
body.viewer-open { overflow: hidden; }

.viewer-bar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 10px 18px;
  background: var(--ink);
  color: var(--paper);
}

#viewer-title {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.viewer-open-link,
.viewer-error-link {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--sand);
  border-bottom: 1px solid rgba(206, 192, 117, 0.5);
  padding-bottom: 2px;
}
.viewer-error-link {
  color: var(--clay);
  border-bottom-color: rgba(178, 110, 99, 0.5);
}
.viewer-open-link:hover,
.viewer-error-link:hover { color: var(--ink); }
.viewer-error-link:hover { color: var(--clay); opacity: 0.75; }

.viewer-close {
  appearance: none;
  -webkit-appearance: none;
  font-family: var(--mono);
  font-size: 1rem;
  line-height: 1;
  color: var(--paper);
  background: transparent;
  border: 2px solid var(--paper);
  border-radius: 0;
  padding: 6px 11px;
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease;
}
.viewer-close:hover {
  color: var(--clay);
  border-color: var(--clay);
}

#viewer-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  padding: 14px 18px 18px;
  background: var(--paper);
}

#viewer-frame {
  position: absolute;
  top: 14px;
  right: 18px;
  bottom: 18px;
  left: 18px;
  /* iframes are replaced elements: with `auto` size the browser keeps the
     intrinsic 300x150 and ignores the insets — use explicit sizes instead */
  width: calc(100% - 36px);
  height: calc(100% - 32px);
  border: 2px solid var(--ink);
  border-radius: 0;
  background: var(--paper);
  box-shadow: 6px 6px 0 var(--ink);
}

.viewer-loading {
  position: absolute;
  top: 14px;
  right: 18px;
  bottom: 18px;
  left: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--ink);
  background: rgba(192, 202, 173, 0.94); /* paper veil while loading */
  pointer-events: none;
  z-index: 2;
}
.viewer-loading::before {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(101, 76, 79, 0.25);
  border-top-color: var(--clay);
  animation: viewer-spin 900ms linear infinite;
}
@keyframes viewer-spin { to { transform: rotate(360deg); } }

/* small cut-paper card centered via inset + auto margins (no transforms,
   so reduced-motion can safely kill transforms page-wide) */
.viewer-error {
  position: absolute;
  inset: 0;
  margin: auto;
  width: max-content;
  max-width: calc(100% - 72px);
  height: max-content;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 26px 34px;
  text-align: center;
  background: var(--paper);
  border: 2px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  z-index: 2;
}
.viewer-error p {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
}
.viewer-error-link { pointer-events: auto; }

/* ---------- responsive ---------- */
@media (min-width: 760px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1100px) {
  .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 759px) {
  .masthead-inner {
    flex-direction: column;
    gap: 0;
    padding-bottom: 14px;
  }
  .wordmark {
    margin-right: calc(-1 * var(--gutter)); /* full-bleed strip on mobile */
    align-items: baseline;
    padding-top: 18px;
    padding-bottom: 16px;
  }
  #site-title { max-width: none; }
  .masthead-copy { padding-bottom: 4px; }
  .grid { padding-top: 16px; gap: 14px; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  html { scroll-behavior: auto; }
  .panel,
  .panel:hover,
  .panel:focus-visible,
  .panel:focus-within {
    transform: none; /* no tilt, no lift */
  }
}

/* ---------- night press (dark theme) ----------
   Keyed off html[data-theme="dark"] on <html> (set by the pre-CSS script;
   there is no prefers-color-scheme path). Seven-ink Night Press palette:
   ground/faces/text night, shadows/wells pit, elevated surfaces plum,
   keylines/bright fills chalk, secondary text sage, accents sand; clay
   only keys edges (hover borders, stamps) — never small text on night.
   --chalk aliases the paper hex and --plum the ink hex (see :root).
   Every rule below is color-only; geometry, type, and motion stay in the
   light rules above. */
html[data-theme="dark"] { color-scheme: dark; }

/* base */
html[data-theme="dark"] body {
  background: var(--night);
  color: var(--chalk);
}
html[data-theme="dark"] ::selection {
  background: var(--sand);
  color: var(--night);
}
html[data-theme="dark"] :focus-visible {
  outline-color: var(--sand); /* ring must clear 3:1 on night, plum, chalk */
}

/* masthead */
html[data-theme="dark"] .masthead { background: var(--night); }
html[data-theme="dark"] .wordmark {
  background: var(--chalk); /* the brightest block on the page */
  color: var(--night);
}
html[data-theme="dark"] .wordmark-mark { background: var(--clay); }
html[data-theme="dark"] .kicker { color: var(--sand); }
html[data-theme="dark"] .count-line { color: var(--sage); }
html[data-theme="dark"] .byline a,
html[data-theme="dark"] .site-credit a {
  color: var(--sand);
  border-bottom-color: rgba(206, 192, 117, 0.5);
}
html[data-theme="dark"] .byline a:hover,
html[data-theme="dark"] .site-credit a:hover,
html[data-theme="dark"] .byline a:focus-visible,
html[data-theme="dark"] .site-credit a:focus-visible {
  border-bottom-color: var(--sand);
}

/* filter chips and the theme toggle */
html[data-theme="dark"] .filters { border-top-color: var(--chalk); }
html[data-theme="dark"] .chip,
html[data-theme="dark"] .theme-toggle {
  color: var(--chalk);
  background: var(--night);
  border-color: var(--chalk);
}
html[data-theme="dark"] .chip:hover,
html[data-theme="dark"] .theme-toggle:hover {
  color: var(--chalk); /* the border carries the hover; text stays chalk */
  border-color: var(--clay);
}
html[data-theme="dark"] .chip.active {
  background: var(--chalk);
  border-color: var(--chalk);
  color: var(--night);
}

/* grid */
html[data-theme="dark"] .empty-note {
  border-color: var(--chalk);
  box-shadow: 4px 4px 0 var(--pit);
}

/* panels (cut-paper specimen cards) */
html[data-theme="dark"] .panel {
  background: var(--night);
  border-color: var(--chalk);
  box-shadow: 4px 4px 0 var(--pit);
}
html[data-theme="dark"] .panel:hover,
html[data-theme="dark"] .panel:focus-visible,
html[data-theme="dark"] .panel:focus-within {
  box-shadow: 6px 6px 0 var(--pit);
}
/* category tab fills re-inked per spec §1.3; unknown categories fall back
   to the var() defaults (sage fill, night text) */
html[data-theme="dark"] .panel-tab {
  color: var(--cat-text, var(--night));
  border-bottom-color: var(--chalk);
}
html[data-theme="dark"] .panel[data-piece-category="instrument"] { --cat: var(--sand); --cat-text: var(--night); }
html[data-theme="dark"] .panel[data-piece-category="sequencer"] { --cat: var(--sage); --cat-text: var(--night); }
html[data-theme="dark"] .panel[data-piece-category="synthesizer"] { --cat: var(--plum); --cat-text: var(--chalk); }
html[data-theme="dark"] .panel[data-piece-category="game"] { --cat: var(--chalk); --cat-text: var(--night); }
html[data-theme="dark"] .panel-media {
  border-bottom-color: var(--chalk);
  background: var(--plum); /* elevated stock wash while the plate loads */
}
html[data-theme="dark"] .panel-tagline { color: var(--sand); }

/* footer */
html[data-theme="dark"] .site-footer { border-top-color: var(--chalk); }

/* live preview viewer (spec §5) */
html[data-theme="dark"] #viewer { background: rgba(34, 21, 24, 0.72); } /* pit wash */
html[data-theme="dark"] .viewer-bar {
  background: var(--chalk);
  color: var(--night);
}
html[data-theme="dark"] .viewer-open-link {
  /* sand cannot carry small text on chalk (1.1:1, outside the §1 ledger),
     so the link text is plum — the ledger's one sanctioned AA text pair
     on chalk (4.6:1) — and sand lives in the underline, per §5's wording */
  color: var(--plum);
  border-bottom-color: rgba(206, 192, 117, 0.5); /* sand underline */
}
html[data-theme="dark"] .viewer-open-link:hover {
  color: var(--night); /* fades into the bar, the light theme's hover move */
}
html[data-theme="dark"] .viewer-close {
  color: var(--night);
  border-color: var(--night);
}
html[data-theme="dark"] .viewer-close:hover {
  color: var(--clay);
  border-color: var(--clay);
}
html[data-theme="dark"] #viewer-stage { background: var(--night); }
html[data-theme="dark"] #viewer-frame {
  border-color: var(--chalk);
  background: var(--night);
  box-shadow: 6px 6px 0 var(--pit);
}
html[data-theme="dark"] .viewer-loading {
  color: var(--chalk);
  background: rgba(51, 37, 40, 0.94); /* night veil while loading */
}
html[data-theme="dark"] .viewer-loading::before {
  border-color: rgba(51, 37, 40, 0.25);
  border-top-color: var(--sand);
}
html[data-theme="dark"] .viewer-error {
  background: var(--night);
  border-color: var(--chalk);
  box-shadow: 6px 6px 0 var(--pit);
}
html[data-theme="dark"] .viewer-error-link {
  color: var(--sand);
  border-bottom-color: rgba(206, 192, 117, 0.5);
}
html[data-theme="dark"] .viewer-error-link:hover {
  color: var(--sand);
  opacity: 0.75;
}
