/* ============================================================================
   NEAR MINT — base design system

   The premise: this app is printed, not rendered. Aged newsprint, heavy ink,
   four-colour process. The signature is MISREGISTRATION — the cyan/magenta plate
   offset you see on every comic printed before digital prepress. It appears on
   the wordmark and page titles and nowhere else, so it stays a signature rather
   than a texture.

   Colour encodes grade, not publisher. 77% of this collection is Marvel, so
   publisher-coding would produce one red wall; grade spans the full range, it is
   ordinal, and it is the thing the product is named after. The ramp runs gold at
   Near Mint down to oxblood at Poor, so a wall of 900 books reads as warmth.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Big+Shoulders+Display:wght@400;700;800;900&family=Archivo:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap');

:root {
  /* --- paper & ink ------------------------------------------------------ */
  --ink:        #14121A;
  --ink-soft:   #4A4350;
  --paper:      #E9DFC3;   /* aged newsprint — yellower than a neutral cream */
  --paper-2:    #DCCFA9;
  --paper-3:    #CFC095;
  --paper-hi:   #F6EFDC;

  /* --- four-colour process ---------------------------------------------- */
  --cyan:       #00A0DC;
  --magenta:    #E02B7B;
  --yellow:     #FFC629;
  --red:        #D6202B;

  /* --- grade ramp: gold (best) to oxblood (worst) ----------------------- */
  --g-nm:       #FFC629;
  --g-vfnm:     #F2A03D;
  --g-vf:       #E5762F;
  --g-fn:       #D6202B;
  --g-vg:       #A01E38;
  --g-gd:       #6E1B33;
  --g-pr:       #3F1A28;
  --g-none:     #8A8070;

  /* --- type ------------------------------------------------------------- */
  --display: 'Big Shoulders Display', 'Arial Narrow', sans-serif;
  --body:    'Archivo', system-ui, -apple-system, sans-serif;

  /* --- geometry --------------------------------------------------------- */
  --gutter:  14px;          /* the space between panels */
  --rule:    2px;           /* ink weight */
  --rule-hi: 3px;
  --radius:  2px;           /* comics are printed on rectangles */

  --shadow-panel: 3px 3px 0 var(--ink);
  --shadow-lift:  5px 5px 0 var(--ink);
}

/* ============================================================================
   Reset & base
   ========================================================================== */

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

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

body {
  margin: 0;
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink);
  background-color: var(--paper);
  /* newsprint tooth: a very low-contrast dot screen across the whole page */
  background-image: radial-gradient(rgba(20, 18, 26, 0.055) 0.5px, transparent 0.6px);
  background-size: 3px 3px;
  min-height: 100vh;
}

a { color: inherit; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: var(--rule-hi) solid var(--cyan);
  outline-offset: 2px;
}

/* ============================================================================
   Type
   ========================================================================== */

.nm-display {
  font-family: var(--display);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 0.86;
  letter-spacing: 0.005em;
}

h1.nm-title {
  font-family: var(--display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: clamp(2.4rem, 7vw, 4.5rem);
  line-height: 0.84;
  margin: 0;
}

/* THE SIGNATURE — plate misregistration. Used on the wordmark and page titles only. */
.nm-misreg {
  text-shadow:
    -0.055em 0 rgba(0, 160, 220, 0.85),
     0.055em 0 rgba(224, 43, 123, 0.8);
}

.nm-eyebrow {
  font-family: var(--body);
  font-weight: 700;
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* The indicia — every page credits the cover it is an homage to. */
.nm-indicia {
  font-family: var(--body);
  font-size: 0.62rem;
  line-height: 1.35;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-top: 1px solid rgba(20, 18, 26, 0.25);
  padding-top: 6px;
  max-width: 34ch;
}

/* ============================================================================
   Panels — the structural unit. A comic page is panels separated by gutters.
   ========================================================================== */

.nm-panel {
  background: var(--paper-hi);
  border: var(--rule) solid var(--ink);
  border-radius: var(--radius);
  box-shadow: var(--shadow-panel);
}

/* ============================================================================
   Header
   ========================================================================== */

.nm-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--ink);
  color: var(--paper-hi);
  border-bottom: var(--rule-hi) solid var(--ink);
}

.nm-header__bar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 9px 16px;
  max-width: 1800px;
  margin: 0 auto;
}

.nm-wordmark {
  font-family: var(--display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
}

.nm-nav {
  display: flex;
  gap: 2px;
  overflow-x: auto;
  scrollbar-width: none;
  flex: 1;
}
.nm-nav::-webkit-scrollbar { display: none; }

.nm-nav a {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-decoration: none;
  padding: 5px 11px;
  white-space: nowrap;
  border: 2px solid transparent;
  color: var(--paper-2);
}

.nm-nav a:hover { color: var(--yellow); border-color: rgba(255, 198, 41, 0.35); }

.nm-nav a[aria-current='page'] {
  color: var(--ink);
  background: var(--yellow);
  border-color: var(--yellow);
}

/* ============================================================================
   Buttons
   ========================================================================== */

.nm-btn {
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 1rem;
  letter-spacing: 0.03em;
  padding: 7px 16px;
  background: var(--paper-hi);
  border: var(--rule) solid var(--ink);
  border-radius: var(--radius);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  transition: transform 0.08s, box-shadow 0.08s;
}

.nm-btn:hover { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--ink); }
.nm-btn:active { transform: translate(3px, 3px); box-shadow: 0 0 0 var(--ink); }

.nm-btn--primary { background: var(--yellow); }
.nm-btn--danger  { background: var(--red); color: var(--paper-hi); }
.nm-btn--ghost   { background: transparent; box-shadow: none; }
.nm-btn--ghost:hover { background: var(--paper-2); transform: none; box-shadow: none; }

.nm-btn[disabled] { opacity: 0.4; cursor: not-allowed; transform: none; box-shadow: 3px 3px 0 var(--ink); }

/* ============================================================================
   Form controls
   ========================================================================== */

.nm-input, .nm-select {
  width: 100%;
  padding: 7px 10px;
  background: var(--paper-hi);
  border: var(--rule) solid var(--ink);
  border-radius: var(--radius);
  font-size: 0.9rem;
}

.nm-input::placeholder { color: rgba(20, 18, 26, 0.42); }

.nm-label {
  display: block;
  font-family: var(--body);
  font-weight: 700;
  font-size: 0.63rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 3px;
}

/* ============================================================================
   Grade chips — the ordinal colour ramp
   ========================================================================== */

.nm-grade {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  font-family: var(--display);
  font-weight: 800;
  font-size: 0.82rem;
  line-height: 1;
  padding: 3px 5px;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--g-none);
  color: var(--ink);
  white-space: nowrap;
}

.nm-grade--nm   { background: var(--g-nm); }
.nm-grade--vfnm { background: var(--g-vfnm); }
.nm-grade--vf   { background: var(--g-vf); }
.nm-grade--fn   { background: var(--g-fn);  color: var(--paper-hi); }
.nm-grade--vg   { background: var(--g-vg);  color: var(--paper-hi); }
.nm-grade--gd   { background: var(--g-gd);  color: var(--paper-hi); }
.nm-grade--pr   { background: var(--g-pr);  color: var(--paper-hi); }

/* ============================================================================
   Status stamps — UXM 141's APPREHENDED / SLAIN, doing real work
   ========================================================================== */

.nm-stamp {
  font-family: var(--display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  padding: 2px 5px;
  border: 2px solid currentColor;
  border-radius: var(--radius);
  transform: rotate(-4deg);
  white-space: nowrap;
}

.nm-stamp--wanted { color: var(--red); }
.nm-stamp--loaned { color: var(--cyan); }
.nm-stamp--sold   { color: var(--ink-soft); }

/* ============================================================================
   Page turn

   Cross-document view transitions. A literal page fold across a real navigation
   is a jank machine; a short rotateY off the left spine with a shadow reads as a
   turn and holds 60fps. Browsers without support just navigate — plain, never janky.
   ========================================================================== */

@view-transition { navigation: auto; }

::view-transition-group(root) { perspective: 2000px; }

/* The outgoing page stays fully opaque for most of the turn and only vanishes at
   the end. Cross-fading both layers at once looked like a double exposure — you
   could read the next page straight through the current one. A turned page
   occludes what's behind it until it's out of the way. */
::view-transition-old(root) {
  animation: nm-turn-out 420ms cubic-bezier(0.36, 0.06, 0.28, 1) both;
  transform-origin: left center;
  backface-visibility: hidden;
  z-index: 2;
}

/* No opacity on the incoming page at all — it sits underneath, already solid. */
::view-transition-new(root) {
  animation: nm-turn-in 420ms cubic-bezier(0.36, 0.06, 0.28, 1) both;
  transform-origin: left center;
  z-index: 1;
}

/* perspective() lives inside the transform rather than on the group — the
   pseudo-element tree doesn't reliably inherit a `perspective` property, and
   without it the turn flattens into a plain horizontal slide. */
@keyframes nm-turn-out {
  0%   { transform: perspective(1600px) rotateY(0deg);   filter: brightness(1); opacity: 1; }
  72%  { opacity: 1; }
  100% { transform: perspective(1600px) rotateY(-28deg); filter: brightness(0.5); opacity: 0; }
}

@keyframes nm-turn-in {
  0%   { transform: perspective(1600px) rotateY(6deg) scale(0.988); }
  100% { transform: perspective(1600px) rotateY(0deg) scale(1); }
}

/* A full-viewport rotation reads as much bigger on a phone than on a desktop,
   so the turn is shallower and quicker there. */
@media (max-width: 640px) {
  ::view-transition-old(root) { animation-duration: 320ms; }
  ::view-transition-new(root) { animation-duration: 320ms; }
  @keyframes nm-turn-out {
    0%   { transform: perspective(1200px) rotateY(0deg);   filter: brightness(1); opacity: 1; }
    72%  { opacity: 1; }
    100% { transform: perspective(1200px) rotateY(-18deg); filter: brightness(0.55); opacity: 0; }
  }
  @keyframes nm-turn-in {
    0%   { transform: perspective(1200px) rotateY(4deg) scale(0.992); }
    100% { transform: perspective(1200px) rotateY(0deg) scale(1); }
  }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ============================================================================
   Utility
   ========================================================================== */

.nm-shell { max-width: 1800px; margin: 0 auto; padding: 18px 16px 64px; }

.nm-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.nm-empty {
  padding: 40px 20px;
  text-align: center;
  border: var(--rule) dashed rgba(20, 18, 26, 0.4);
  border-radius: var(--radius);
}

.nm-empty h2 {
  font-family: var(--display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 1.8rem;
  margin: 0 0 6px;
}

/* Toast — bottom centre, out of the way of the grid */
.nm-toast {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--paper-hi);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
  font-size: 0.86rem;
  max-width: calc(100vw - 32px);
}

.nm-toast[hidden] { display: none; }
.nm-toast button {
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  background: var(--yellow);
  border: none;
  padding: 4px 10px;
  border-radius: var(--radius);
  cursor: pointer;
}

@media (max-width: 640px) {
  .nm-shell { padding: 12px 10px 80px; }
  .nm-header__bar { padding: 8px 10px; gap: 10px; }
  .nm-wordmark { font-size: 1.2rem; }
}
