/* ==========================================================================
   Zine Rack — design system
   A cozy, collage-inspired space for DIY publishers and curious readers.

   Purely presentational. Nothing here changes behaviour, routes, form
   fields or context variables.

   Layers, in cascade order:
     1. tokens      — colour, type, space, elevation
     2. base        — reset, page ground, typography
     3. collage     — paper, tape, torn edges, stamps, textures
     4. components  — buttons, chips, cards, inputs, nav, panels, badges
     5. layout      — shells, grids, racks
     6. theming     — creator-controlled rack colours (sovereign)
     7. responsive  — mobile bottom nav and stacking
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {
  /* -- Night neutrals ---------------------------------------------------- */
  --zr-night-900: #0B0E14;
  --zr-night-800: #181F2A;
  --zr-night-700: #232A38;
  --zr-night-600: #2D3346;
  --zr-night-500: #3A4154;

  /* -- Accent hues ------------------------------------------------------- */
  --zr-violet:  #886CFF;
  --zr-amber:   #FFB570;
  --zr-sage:    #7FD1B2;
  --zr-gold:    #F4D06F;
  --zr-rose:    #FF6B8B;

  /* Deeper violet from the desktop guide, for pressed states and rules. */
  --zr-violet-deep: #5E3FA4;

  /* -- Paper & ink ------------------------------------------------------- */
  --zr-paper:      #F3EFE6;
  --zr-paper-mid:  #D9D2C3;
  --zr-paper-dim:  #B9AFA1;
  --zr-ink:        #2A241C;
  --zr-white:      #FFFFFF;

  /* -- Semantic surfaces ------------------------------------------------- */
  --zr-bg:            var(--zr-night-900);
  --zr-surface:       var(--zr-night-800);
  --zr-surface-raised:var(--zr-night-700);
  --zr-surface-sunk:  #070A0F;
  --zr-line:          rgba(243, 239, 230, 0.13);
  --zr-line-strong:   rgba(243, 239, 230, 0.26);

  /* -- Semantic text ----------------------------------------------------- */
  --zr-text:        var(--zr-paper);
  --zr-text-muted:  rgba(243, 239, 230, 0.66);
  --zr-text-faint:  rgba(243, 239, 230, 0.42);
  --zr-text-on-paper: var(--zr-ink);

  /* -- Status ------------------------------------------------------------ */
  --zr-ok:      var(--zr-sage);
  --zr-pending: var(--zr-amber);
  --zr-draft:   var(--zr-paper-dim);
  --zr-alert:   var(--zr-rose);

  /* -- Typography -------------------------------------------------------- */
  --zr-font-display: "Special Elite", "Courier New", ui-monospace, monospace;
  --zr-font-body:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --zr-font-hand:    "Just Another Hand", "Bradley Hand", cursive;

  --zr-track-display: 0.02em;   /* style guide: all caps, tracking 2% */

  --zr-fs-xs:   0.6875rem;  /* 11px */
  --zr-fs-sm:   0.8125rem;  /* 13px */
  --zr-fs-base: 0.9375rem;  /* 15px */
  --zr-fs-md:   1.0625rem;  /* 17px */
  --zr-fs-lg:   1.375rem;   /* 22px */
  --zr-fs-xl:   1.875rem;   /* 30px */
  --zr-fs-2xl:  2.5rem;     /* 40px */
  --zr-fs-3xl:  3.25rem;    /* 52px */

  --zr-lh-tight: 1.18;
  --zr-lh-snug:  1.4;
  --zr-lh-body:  1.65;

  /* -- Space (4px base) --------------------------------------------------- */
  --zr-1: 4px;   --zr-2: 8px;   --zr-3: 12px;  --zr-4: 16px;
  --zr-5: 20px;  --zr-6: 24px;  --zr-8: 32px;  --zr-10: 40px;
  --zr-12: 48px; --zr-16: 64px; --zr-20: 80px;

  /* -- Radius: small and slightly uneven, like cut paper ------------------ */
  --zr-r-sm: 3px;
  --zr-r:    5px;
  --zr-r-lg: 8px;
  --zr-r-pill: 999px;

  /* -- Elevation: soft, warm-tinted, never harsh -------------------------- */
  --zr-shadow-sm: 0 1px 2px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.28);
  --zr-shadow:    0 2px 4px rgba(0,0,0,.5), 0 8px 20px rgba(0,0,0,.36);
  --zr-shadow-lg: 0 4px 8px rgba(0,0,0,.5), 0 18px 44px rgba(0,0,0,.46);
  --zr-glow-violet: 0 0 0 1px rgba(136,108,255,.4), 0 6px 22px rgba(136,108,255,.28);

  /* -- Motion ------------------------------------------------------------- */
  --zr-ease: cubic-bezier(.22,.61,.36,1);
  --zr-fast: 120ms;
  --zr-med:  220ms;

  /* -- Asset paths -------------------------------------------------------
     Overridden once in the base template with {% static %} so this file
     never has to know where staticfiles lives. Defaults assume
     /static/zinerack/img/. */
  --zr-img: "/static/zinerack/img";

  --zr-tex-grain:    url("../img/texture/grain.webp");
  --zr-tex-speckle:  url("../img/texture/speckle.webp");
  --zr-tex-scratch:  url("../img/texture/scratch.webp");
  --zr-tex-halftone: url("../img/texture/halftone.webp");
  --zr-tex-splatter: url("../img/texture/splatter.webp");

  --zr-paper-cream:  url("../img/paper/tile-dot-cream.webp");
  --zr-paper-kraft:  url("../img/paper/tile-kraft.webp");
  --zr-paper-ledger: url("../img/paper/tile-ledger-cream.webp");
  --zr-paper-grey:   url("../img/paper/tile-grey-fiber.webp");
  --zr-paper-violetp:url("../img/paper/tile-violet.webp");
  --zr-paper-dark:   url("../img/paper/tile-charcoal.webp");
  --zr-paper-griddk: url("../img/paper/tile-grid-dark.webp");
}

/* ==========================================================================
   2. BASE
   ========================================================================== */

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

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

body {
  margin: 0;
  min-height: 100%;
  background-color: var(--zr-bg);
  color: var(--zr-text);
  font-family: var(--zr-font-body);
  font-size: var(--zr-fs-base);
  line-height: var(--zr-lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The night sky: a deep radial wash, a drift of stars, and a fine grain.
   All three are decorative and sit behind everything at z-index 0. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(1100px 620px at 78% -8%,  rgba(94, 63, 164, .30), transparent 62%),
    radial-gradient(820px  520px at 12% 4%,   rgba(136,108,255, .14), transparent 60%),
    radial-gradient(900px  700px at 50% 108%, rgba(45, 51, 70,  .55), transparent 64%),
    var(--zr-night-900);
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .30;
  mix-blend-mode: screen;
  background-image: var(--zr-tex-speckle), var(--zr-tex-grain);
  background-size: 420px auto, 260px auto;
  background-repeat: repeat, repeat;
}

/* Reduce the two decorative layers where the user has asked for less. */
@media (prefers-reduced-transparency: reduce) {
  body::after { opacity: .12; }
}

img, svg, video { max-width: 100%; height: auto; display: block; }

a {
  color: var(--zr-violet);
  text-decoration-color: rgba(136,108,255,.45);
  text-underline-offset: 3px;
  transition: color var(--zr-fast) var(--zr-ease);
}
a:hover { color: #A38FFF; text-decoration-color: currentColor; }

:focus-visible {
  outline: 2px solid var(--zr-gold);
  outline-offset: 2px;
  border-radius: var(--zr-r-sm);
}

::selection { background: rgba(136,108,255,.45); color: var(--zr-white); }

hr, .zr-rule {
  border: 0;
  height: 1px;
  margin: var(--zr-6) 0;
  background-image: linear-gradient(
    to right,
    transparent, var(--zr-line-strong) 12%, var(--zr-line-strong) 88%, transparent);
}

/* -- Headings ------------------------------------------------------------ */

h1, h2, h3, h4, .zr-display {
  font-family: var(--zr-font-display);
  font-weight: 400;
  letter-spacing: var(--zr-track-display);
  line-height: var(--zr-lh-tight);
  color: var(--zr-paper);
  margin: 0 0 var(--zr-3);
}

h1, .zr-h1 { font-size: var(--zr-fs-2xl); }
h2, .zr-h2 { font-size: var(--zr-fs-xl); }
h3, .zr-h3 { font-size: var(--zr-fs-lg); }
h4, .zr-h4 { font-size: var(--zr-fs-md); }

.zr-caps {
  text-transform: uppercase;
  letter-spacing: .12em;
  font-size: var(--zr-fs-xs);
  color: var(--zr-text-faint);
  font-family: var(--zr-font-body);
}

/* Section label with a dotted rule trailing off to the right, as in the
   style guide's "COLOR PALETTE ·············" headers. */
.zr-section-label {
  display: flex;
  align-items: center;
  gap: var(--zr-3);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: var(--zr-fs-xs);
  color: var(--zr-text-muted);
  font-family: var(--zr-font-body);
  margin: 0 0 var(--zr-4);
}
.zr-section-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background-image: repeating-linear-gradient(
    to right, var(--zr-line-strong) 0 3px, transparent 3px 7px);
}

/* Handwritten accent, for asides and small human notes. */
.zr-hand {
  font-family: var(--zr-font-hand);
  font-size: 1.5em;      /* Just Another Hand runs small; scale up */
  line-height: 1.05;
  color: var(--zr-paper-mid);
  letter-spacing: .01em;
}

.zr-muted { color: var(--zr-text-muted); }
.zr-faint { color: var(--zr-text-faint); }

.zr-mono-sm {
  font-size: var(--zr-fs-sm);
  color: var(--zr-text-muted);
}

/* Screen-reader-only, for icon-only controls that still need a name. */
.zr-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ==========================================================================
   3. COLLAGE — paper, tape, torn edges, stamps
   ========================================================================== */

/* -- Paper surfaces -----------------------------------------------------
   A .zr-paper element is a light paper card with dark ink on it. Use for
   quotes, callouts, empty states, and anything meant to read as a physical
   scrap pinned to the page. */

.zr-paper-scrap {
  position: relative;
  background-color: var(--zr-paper);
  background-image: var(--zr-paper-cream);
  background-size: 260px auto;
  background-blend-mode: multiply;
  color: var(--zr-text-on-paper);
  padding: var(--zr-6) var(--zr-8);
  box-shadow: var(--zr-shadow);
  /* Uneven cut edges — no two scraps line up exactly. */
  clip-path: polygon(
    0 1.4%, 24% 0, 51% 1.2%, 77% 0, 100% 1.6%,
    99.4% 26%, 100% 52%, 99.3% 78%, 100% 98.6%,
    76% 100%, 49% 98.8%, 23% 100%, 0 98.4%,
    0.7% 74%, 0 48%, 0.6% 25%);
}

/* clip-path clips pseudo-elements too, so a torn scrap cannot draw its own
   tape. Wrap it: <span class="zr-pin zr-taped zr-tape-grid">
                   <div class="zr-paper-scrap"> … </div>
                 </span>
   .zr-taped still works directly on anything unclipped (panels, cards, media). */
.zr-pin { position: relative; display: block; }

.zr-paper-scrap--kraft  { background-image: var(--zr-paper-kraft);  background-color: #C79A62; }
.zr-paper-scrap--ledger { background-image: var(--zr-paper-ledger); background-color: #E8DFCB; }
.zr-paper-scrap--grey   { background-image: var(--zr-paper-grey);   background-color: #D6D3CB; }

/* A dark paper panel — the default surface for content blocks. Reads as
   charcoal handmade paper rather than a flat UI card. */
.zr-panel {
  position: relative;
  background-color: var(--zr-surface);
  background-image: var(--zr-paper-dark);
  background-size: 300px auto;
  background-blend-mode: overlay;
  border: 1px solid var(--zr-line);
  border-radius: var(--zr-r);
  box-shadow: var(--zr-shadow-sm);
  padding: var(--zr-5);
}

.zr-panel--raised { background-color: var(--zr-surface-raised); box-shadow: var(--zr-shadow); }
.zr-panel--sunk   { background-color: var(--zr-surface-sunk); box-shadow: inset 0 1px 3px rgba(0,0,0,.55); }
.zr-panel--grid   { background-image: var(--zr-paper-griddk); background-size: 220px auto; }

/* -- Washi tape ---------------------------------------------------------
   Decorative only. Add .zr-taped to a positioned element and pick a corner
   with a modifier; the tape is drawn by ::before so it never occupies
   layout space and never intercepts clicks. */

.zr-taped { position: relative; }

.zr-taped::before {
  content: "";
  position: absolute;
  z-index: 3;
  width: 104px;
  height: 30px;
  background-image: var(--zr-tape, url("../img/tape/tape-kraft-speckle.webp"));
  background-size: 100% 100%;
  background-repeat: no-repeat;
  opacity: .92;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.5));
  pointer-events: none;
  /* default: top-left, tilted */
  top: -14px; left: -18px;
  transform: rotate(-24deg);
}

.zr-taped--tr::before { top: -14px; left: auto; right: -18px; transform: rotate(22deg); }
.zr-taped--bl::before { top: auto; bottom: -14px; left: -18px; transform: rotate(16deg); }
.zr-taped--br::before { top: auto; bottom: -14px; left: auto; right: -18px; transform: rotate(-18deg); }
.zr-taped--top::before {
  top: -13px; left: 50%; right: auto;
  transform: translateX(-50%) rotate(-1.5deg);
  width: 132px;
}

/* Tape variants — set --zr-tape on the element or use a modifier. */
.zr-tape-kraft   { --zr-tape: url("../img/tape/tape-kraft-speckle.webp"); }
.zr-tape-grid    { --zr-tape: url("../img/tape/tape-grid.webp"); }
.zr-tape-night   { --zr-tape: url("../img/tape/tape-night-moon.webp"); }
.zr-tape-violet  { --zr-tape: url("../img/tape/tape-violet-speckle.webp"); }
.zr-tape-star    { --zr-tape: url("../img/tape/tape-star-navy.webp"); }
.zr-tape-stardk  { --zr-tape: url("../img/tape/tape-star-dark.webp"); }
.zr-tape-floral  { --zr-tape: url("../img/tape/tape-floral.webp"); }
.zr-tape-botany  { --zr-tape: url("../img/tape/tape-botanical.webp"); }
.zr-tape-music   { --zr-tape: url("../img/tape/tape-music.webp"); }
.zr-tape-linen   { --zr-tape: url("../img/tape/tape-linen-light.webp"); }
.zr-tape-burlap  { --zr-tape: url("../img/tape/tape-burlap.webp"); }
.zr-tape-charcoal{ --zr-tape: url("../img/tape/tape-charcoal.webp"); }

/* A standalone strip you can drop anywhere in markup. */
.zr-tape-strip {
  display: block;
  width: 132px;
  height: 30px;
  background-image: var(--zr-tape, url("../img/tape/tape-violet-speckle.webp"));
  background-size: 100% 100%;
  background-repeat: no-repeat;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.45));
  transform: rotate(-1.5deg);
  pointer-events: none;
}

/* -- Torn edges ---------------------------------------------------------
   A soft-mask torn bottom (or top) edge for banners and headers. Uses an
   inline SVG mask so it recolours with the element's own background. */

.zr-torn-bottom {
  --zr-torn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 12' preserveAspectRatio='none'%3E%3Cpath d='M0 0h400v5.6c-9 3.4-17 1.1-26-.8s-18-2.1-27 .6-18 4-27 1.3-18-4.6-27-3.1-18 4.6-27 5.4-18-1.4-27-3.1-18-.3-27 1.6-18 3.1-27 1.1-18-4.9-27-4.4-18 3.4-27 4.9-18 .6-27-1.1-18-2.9-27-1.4-18 3.7-27 4.2-18-1.7-26-3.6z' fill='%23fff'/%3E%3C/svg%3E");
  -webkit-mask-image: var(--zr-torn);
  mask-image: var(--zr-torn);
  -webkit-mask-size: 400px 12px;
  mask-size: 400px 12px;
  -webkit-mask-repeat: repeat-x;
  mask-repeat: repeat-x;
  -webkit-mask-position: bottom left;
  mask-position: bottom left;
  padding-bottom: var(--zr-5);
}

.zr-torn-top {
  --zr-torn-t: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 12' preserveAspectRatio='none'%3E%3Cpath d='M0 12h400V6.4c-9-3.4-17-1.1-26 .8s-18 2.1-27-.6-18-4-27-1.3-18 4.6-27 3.1-18-4.6-27-5.4-18 1.4-27 3.1-18 .3-27-1.6-18-3.1-27-1.1-18 4.9-27 4.4-18-3.4-27-4.9-18-.6-27 1.1-18 2.9-27 1.4-18-3.7-27-4.2-18 1.7-26 3.6z' fill='%23fff'/%3E%3C/svg%3E");
  -webkit-mask-image: var(--zr-torn-t);
  mask-image: var(--zr-torn-t);
  -webkit-mask-size: 400px 12px;
  mask-size: 400px 12px;
  -webkit-mask-repeat: repeat-x;
  mask-repeat: repeat-x;
  -webkit-mask-position: top left;
  mask-position: top left;
  padding-top: var(--zr-5);
}

/* -- Stamps, seals and postmarks ---------------------------------------- */

.zr-stamp-img {
  display: block;
  width: var(--zr-stamp-w, 62px);
  filter: drop-shadow(0 3px 6px rgba(0,0,0,.55));
  transform: rotate(var(--zr-stamp-rot, -4deg));
  pointer-events: none;
}

/* A perforated postage frame around any content (used on cover thumbs). */
.zr-perforated {
  padding: 5px;
  background: var(--zr-paper);
  --zr-perf: radial-gradient(circle at 50% 0, transparent 3px, var(--zr-paper) 3.4px);
  -webkit-mask-image:
    radial-gradient(circle at 50% 0,   #0000 3.2px, #000 3.6px),
    radial-gradient(circle at 50% 100%,#0000 3.2px, #000 3.6px),
    radial-gradient(circle at 0 50%,   #0000 3.2px, #000 3.6px),
    radial-gradient(circle at 100% 50%,#0000 3.2px, #000 3.6px);
  -webkit-mask-size: 9px 100%, 9px 100%, 100% 9px, 100% 9px;
  -webkit-mask-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
  -webkit-mask-position: top, bottom, left, right;
  -webkit-mask-composite: source-in;
  mask-image:
    radial-gradient(circle at 50% 0,   #0000 3.2px, #000 3.6px),
    radial-gradient(circle at 50% 100%,#0000 3.2px, #000 3.6px),
    radial-gradient(circle at 0 50%,   #0000 3.2px, #000 3.6px),
    radial-gradient(circle at 100% 50%,#0000 3.2px, #000 3.6px);
  mask-size: 9px 100%, 9px 100%, 100% 9px, 100% 9px;
  mask-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
  mask-position: top, bottom, left, right;
  mask-composite: intersect;
}

/* Icons ----------------------------------------------------------------- */

.zr-i {
  width: 1.25em;
  height: 1.25em;
  flex: none;
  color: currentColor;
  vertical-align: -0.22em;
}
.zr-i--lg { width: 1.6em; height: 1.6em; }
.zr-i--sm { width: 1em;   height: 1em; }

/* ==========================================================================
   4. COMPONENTS
   ========================================================================== */

/* -- Buttons ------------------------------------------------------------- */

.zr-btn {
  --zr-btn-bg: var(--zr-night-700);
  --zr-btn-fg: var(--zr-paper);
  --zr-btn-bd: var(--zr-line-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--zr-2);
  padding: 10px var(--zr-5);
  min-height: 40px;
  border: 1px solid var(--zr-btn-bd);
  border-radius: var(--zr-r);
  background: var(--zr-btn-bg);
  color: var(--zr-btn-fg);
  font-family: var(--zr-font-body);
  font-size: var(--zr-fs-sm);
  font-weight: 500;
  letter-spacing: .01em;
  text-decoration: none;
  cursor: pointer;
  position: relative;
  transition: transform var(--zr-fast) var(--zr-ease),
              box-shadow var(--zr-fast) var(--zr-ease),
              background-color var(--zr-fast) var(--zr-ease),
              border-color var(--zr-fast) var(--zr-ease);
}
.zr-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: var(--zr-shadow-sm); }
.zr-btn:active:not(:disabled) { transform: translateY(0); }
.zr-btn:disabled, .zr-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; transform: none; }

/* Primary carries a small strip of washi tape at its right edge, echoing
   the style guide's button row. */
.zr-btn--primary {
  --zr-btn-bg: var(--zr-violet);
  --zr-btn-fg: var(--zr-white);
  --zr-btn-bd: transparent;
  box-shadow: var(--zr-glow-violet);
  font-weight: 600;
}
.zr-btn--primary:hover:not(:disabled) { --zr-btn-bg: #9A81FF; }
.zr-btn--primary:active:not(:disabled) { --zr-btn-bg: var(--zr-violet-deep); }

.zr-btn--secondary {
  --zr-btn-bg: transparent;
  --zr-btn-fg: var(--zr-paper);
  --zr-btn-bd: var(--zr-line-strong);
}
.zr-btn--secondary:hover:not(:disabled) {
  --zr-btn-bd: var(--zr-paper-dim);
  --zr-btn-bg: rgba(243,239,230,.05);
}

/* Tertiary reads as a paper label taped onto the page. */
.zr-btn--tertiary {
  --zr-btn-bg: var(--zr-paper-mid);
  --zr-btn-fg: var(--zr-ink);
  --zr-btn-bd: transparent;
  background-image: var(--zr-paper-ledger);
  background-size: 180px auto;
  background-blend-mode: multiply;
  font-family: var(--zr-font-display);
  letter-spacing: var(--zr-track-display);
  transform: rotate(-1.2deg);
}
.zr-btn--tertiary:hover:not(:disabled) { transform: rotate(-1.2deg) translateY(-1px); }

.zr-btn--ghost {
  --zr-btn-bg: transparent;
  --zr-btn-bd: transparent;
  --zr-btn-fg: var(--zr-text-muted);
}
.zr-btn--ghost:hover:not(:disabled) { --zr-btn-fg: var(--zr-paper); --zr-btn-bg: rgba(243,239,230,.05); }

.zr-btn--danger { --zr-btn-bg: transparent; --zr-btn-fg: var(--zr-rose); --zr-btn-bd: rgba(255,107,139,.45); }
.zr-btn--danger:hover:not(:disabled) { --zr-btn-bg: rgba(255,107,139,.12); }

.zr-btn--sm  { min-height: 32px; padding: 6px var(--zr-3); font-size: var(--zr-fs-xs); }
.zr-btn--lg  { min-height: 48px; padding: 13px var(--zr-6); font-size: var(--zr-fs-base); }
.zr-btn--block { display: flex; width: 100%; }

/* Round action button — the "+" in the nav bar. */
.zr-btn-fab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px; height: 48px;
  border-radius: var(--zr-r-pill);
  border: 1px solid rgba(255,255,255,.16);
  background: linear-gradient(160deg, #9A81FF, var(--zr-violet-deep));
  color: var(--zr-white);
  box-shadow: var(--zr-glow-violet), var(--zr-shadow);
  cursor: pointer;
  transition: transform var(--zr-fast) var(--zr-ease);
}
.zr-btn-fab:hover { transform: translateY(-2px) scale(1.03); }

/* -- Chips / tags -------------------------------------------------------- */

.zr-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--zr-r-pill);
  border: 1px solid var(--zr-line-strong);
  background: rgba(243,239,230,.05);
  color: var(--zr-text-muted);
  font-size: var(--zr-fs-xs);
  font-family: var(--zr-font-body);
  letter-spacing: .02em;
  text-decoration: none;
  transition: all var(--zr-fast) var(--zr-ease);
}
a.zr-chip:hover, button.zr-chip:hover {
  color: var(--zr-paper);
  border-color: var(--zr-paper-dim);
  background: rgba(243,239,230,.09);
}

.zr-chip--on,
.zr-chip[aria-pressed="true"],
.zr-chip[aria-selected="true"] {
  background: var(--zr-violet);
  border-color: transparent;
  color: var(--zr-white);
  font-weight: 500;
}

.zr-chip-row { display: flex; flex-wrap: wrap; gap: var(--zr-2); }

/* Segmented control: For You / Recent / Popular. */
.zr-segmented {
  display: inline-flex;
  gap: var(--zr-2);
  padding: 0;
  flex-wrap: wrap;
}

/* -- Status badges ------------------------------------------------------- */

.zr-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: var(--zr-r-sm);
  border: 1px solid currentColor;
  font-size: var(--zr-fs-xs);
  font-family: var(--zr-font-body);
  text-transform: uppercase;
  letter-spacing: .08em;
  background: rgba(0,0,0,.25);
}
.zr-badge--pending  { color: var(--zr-pending); }
.zr-badge--approved { color: var(--zr-ok); }
.zr-badge--draft    { color: var(--zr-draft); }
.zr-badge--failed   { color: var(--zr-alert); }
.zr-badge--private  { color: var(--zr-violet); }

/* -- Inputs -------------------------------------------------------------- */

.zr-field { display: block; margin-bottom: var(--zr-5); }

.zr-label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--zr-fs-sm);
  color: var(--zr-text-muted);
  letter-spacing: .02em;
}

.zr-input,
.zr-select,
.zr-textarea,
input[type="text"], input[type="email"], input[type="password"],
input[type="url"], input[type="search"], input[type="number"],
input[type="date"], input[type="datetime-local"],
select, textarea {
  width: 100%;
  padding: 10px var(--zr-4);
  min-height: 42px;
  background: var(--zr-surface-sunk);
  border: 1px solid var(--zr-line-strong);
  border-radius: var(--zr-r);
  color: var(--zr-paper);
  font-family: var(--zr-font-body);
  font-size: var(--zr-fs-base);
  transition: border-color var(--zr-fast) var(--zr-ease),
              box-shadow var(--zr-fast) var(--zr-ease);
}
.zr-textarea, textarea { min-height: 120px; line-height: var(--zr-lh-body); resize: vertical; }

::placeholder { color: var(--zr-text-faint); opacity: 1; }

.zr-input:focus, .zr-select:focus, .zr-textarea:focus,
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--zr-violet);
  box-shadow: 0 0 0 3px rgba(136,108,255,.22);
}

/* Search field with a hand-drawn magnifier on the right. */
.zr-search { position: relative; }
.zr-search .zr-input, .zr-search input { padding-right: 44px; border-radius: var(--zr-r-pill); }
.zr-search .zr-i {
  position: absolute;
  right: var(--zr-4);
  top: 50%;
  transform: translateY(-50%);
  color: var(--zr-text-faint);
  pointer-events: none;
}

.zr-help  { display: block; margin-top: 6px; font-size: var(--zr-fs-xs); color: var(--zr-text-faint); }

/* Errors are friendly, never harsh — the guide's voice rule. */
.zr-error, .errorlist {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--zr-fs-sm);
  color: var(--zr-rose);
}
.zr-field--invalid .zr-input,
.zr-field--invalid input { border-color: rgba(255,107,139,.6); }

/* Checkbox and radio, drawn as small hand-inked marks. */
.zr-check, .zr-radio {
  display: flex;
  align-items: flex-start;
  gap: var(--zr-3);
  padding: var(--zr-2) 0;
  cursor: pointer;
  font-size: var(--zr-fs-base);
}
.zr-check input[type="checkbox"], .zr-radio input[type="radio"] {
  appearance: none;
  width: 19px; height: 19px;
  margin: 2px 0 0;
  flex: none;
  border: 1.6px solid var(--zr-line-strong);
  background: var(--zr-surface-sunk);
  cursor: pointer;
  transition: all var(--zr-fast) var(--zr-ease);
}
.zr-check input[type="checkbox"] { border-radius: var(--zr-r-sm); }
.zr-radio input[type="radio"]    { border-radius: var(--zr-r-pill); }

.zr-check input:checked, .zr-radio input:checked {
  background-color: var(--zr-violet);
  border-color: var(--zr-violet);
}
.zr-check input:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.6 12.6 4.8 5.1L19.6 6.4'/%3E%3C/svg%3E");
  background-size: 13px; background-position: center; background-repeat: no-repeat;
}
.zr-radio input:checked {
  box-shadow: inset 0 0 0 3.5px var(--zr-surface-sunk);
}

/* Toggle switch. */
.zr-switch { position: relative; display: inline-block; width: 46px; height: 26px; flex: none; }
.zr-switch input { appearance: none; margin: 0; width: 100%; height: 100%; cursor: pointer;
  background: var(--zr-night-600); border: 1px solid var(--zr-line-strong);
  border-radius: var(--zr-r-pill); transition: background var(--zr-med) var(--zr-ease); }
.zr-switch input::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: var(--zr-r-pill);
  background: var(--zr-paper); box-shadow: var(--zr-shadow-sm);
  transition: transform var(--zr-med) var(--zr-ease);
}
.zr-switch input:checked { background: var(--zr-violet); border-color: transparent; }
.zr-switch input:checked::after { transform: translateX(20px); }

/* ==========================================================================
   Zine cards — the heart of the rack
   ========================================================================== */

.zr-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--zr-card-bg, var(--zr-surface));
  border: 1px solid var(--zr-line);
  border-radius: var(--zr-r);
  overflow: visible;
  text-decoration: none;
  color: inherit;
  transition: transform var(--zr-med) var(--zr-ease),
              box-shadow var(--zr-med) var(--zr-ease);
}
a.zr-card:hover, .zr-card--hoverable:hover {
  transform: translateY(-3px) rotate(-.35deg);
  box-shadow: var(--zr-shadow-lg);
}

.zr-card__cover {
  display: block;
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--zr-r-sm) var(--zr-r-sm) 0 0;
  background: var(--zr-night-700) var(--zr-paper-griddk);
  background-size: cover;
}
.zr-card__cover img { width: 100%; height: 100%; object-fit: cover; }

/* Cover placeholder when a zine has no image yet. */
.zr-card__cover--empty {
  display: grid;
  place-items: center;
  color: var(--zr-text-faint);
  background-image: var(--zr-paper-griddk);
  background-size: 140px auto;
}

/* A small gold star seal in the cover's corner. */
.zr-card__seal {
  position: absolute;
  right: 7px; bottom: 7px;
  color: var(--zr-gold);
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.7));
}

.zr-card__body { display: block; padding: var(--zr-3) var(--zr-4) var(--zr-4); }

.zr-card__title {
  display: block;
  font-family: var(--zr-font-display);
  font-size: var(--zr-fs-md);
  line-height: var(--zr-lh-tight);
  letter-spacing: var(--zr-track-display);
  color: var(--zr-card-ink, var(--zr-paper));
  margin: 0 0 3px;
}
.zr-card__meta { display: block; font-size: var(--zr-fs-xs); color: var(--zr-text-muted); }
.zr-card__byline { display: block; font-size: var(--zr-fs-xs); color: var(--zr-text-faint); }

/* Horizontal list row (Explore / Library lists). */
.zr-row {
  display: flex;
  align-items: center;
  gap: var(--zr-4);
  padding: var(--zr-3) 0;
  border-bottom: 1px solid var(--zr-line);
  text-decoration: none;
  color: inherit;
}
.zr-row:last-child { border-bottom: 0; }
.zr-row__thumb {
  display: block;
  width: 56px; aspect-ratio: 3/4; flex: none;
  border-radius: var(--zr-r-sm);
  overflow: hidden;
  background: var(--zr-night-700);
  box-shadow: var(--zr-shadow-sm);
}
.zr-row__thumb img { width: 100%; height: 100%; object-fit: cover; }
.zr-row__main { flex: 1; min-width: 0; }
.zr-row__title {
  display: block;
  font-family: var(--zr-font-display);
  font-size: var(--zr-fs-base);
  letter-spacing: var(--zr-track-display);
  color: var(--zr-paper);
  margin: 0;
}
.zr-row__aside { flex: none; color: var(--zr-text-faint); }

/* ==========================================================================
   Navigation
   ========================================================================== */

.zr-topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--zr-5);
  padding: var(--zr-3) var(--zr-6);
  background: rgba(11,14,20,.86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--zr-line);
}

/* Ransom-note wordmark. Each letter is its own paper tile, alternating
   between light and dark scraps, sitting at slightly different angles. */
.zr-wordmark {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  text-decoration: none;
  font-family: var(--zr-font-display);
  letter-spacing: 0;
  line-height: 1;
  padding: 3px 0;
}
.zr-wordmark span {
  display: inline-block;
  padding: 3px 6px 4px;
  font-size: var(--zr-wm-size, 1.05rem);
  background: var(--zr-paper);
  color: var(--zr-ink);
  border-radius: 1.5px;
  box-shadow: 0 1px 2px rgba(0,0,0,.6);
}
.zr-wordmark span:nth-child(2n)  { background: var(--zr-night-700); color: var(--zr-paper); transform: rotate(2.5deg); }
.zr-wordmark span:nth-child(3n)  { background: var(--zr-paper-mid); transform: rotate(-2deg); }
.zr-wordmark span:nth-child(4n)  { background: var(--zr-ink); color: var(--zr-paper); transform: rotate(1.5deg); }
.zr-wordmark span:nth-child(5n)  { background: var(--zr-paper-dim); color: var(--zr-ink); transform: rotate(-3deg); }
.zr-wordmark span:nth-child(7n)  { transform: rotate(3deg); }
.zr-wordmark span.zr-wordmark__gap { background: none; box-shadow: none; width: var(--zr-2); padding: 0; }
.zr-wordmark--lg { --zr-wm-size: 2.1rem; }

.zr-nav { display: flex; align-items: center; gap: var(--zr-1); margin-left: auto; }

.zr-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px var(--zr-3);
  border-radius: var(--zr-r);
  color: var(--zr-text-muted);
  font-size: var(--zr-fs-sm);
  text-decoration: none;
  transition: all var(--zr-fast) var(--zr-ease);
}
.zr-nav__link:hover { color: var(--zr-paper); background: rgba(243,239,230,.06); }
.zr-nav__link[aria-current], .zr-nav__link.is-active {
  color: var(--zr-violet);
  background: rgba(136,108,255,.13);
}

/* Mobile bottom bar — hidden on wide screens, shown below the breakpoint. */
.zr-tabbar {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 50;
  align-items: center;
  justify-content: space-around;
  gap: var(--zr-1);
  padding: 7px max(var(--zr-3), env(safe-area-inset-left))
           calc(7px + env(safe-area-inset-bottom))
           max(var(--zr-3), env(safe-area-inset-right));
  background: rgba(11,14,20,.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--zr-line);
}
.zr-tabbar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  flex: 1;
  min-width: 0;
  padding: 5px 6px;
  border-radius: var(--zr-r);
  color: var(--zr-text-faint);
  font-size: 10px;
  text-decoration: none;
  transition: color var(--zr-fast) var(--zr-ease);
}
.zr-tabbar__item[aria-current], .zr-tabbar__item.is-active {
  color: var(--zr-violet);
  background: rgba(136,108,255,.13);
}

/* ==========================================================================
   Panels with a purpose
   ========================================================================== */

/* Privacy / share notice — a locked paper band. */
.zr-notice {
  display: flex;
  align-items: center;
  gap: var(--zr-3);
  padding: var(--zr-4) var(--zr-5);
  border-radius: var(--zr-r);
  border: 1px solid var(--zr-line-strong);
  background: rgba(136,108,255,.09);
  font-size: var(--zr-fs-sm);
}
.zr-notice__icon { color: var(--zr-violet); flex: none; }
.zr-notice__main { flex: 1; min-width: 0; }
.zr-notice__title { color: var(--zr-paper); margin: 0; font-size: var(--zr-fs-sm); }
.zr-notice__sub   { color: var(--zr-text-faint); font-size: var(--zr-fs-xs); }
.zr-notice--warn { background: rgba(255,181,112,.10); }
.zr-notice--ok   { background: rgba(127,209,178,.10); }

/* Action bar — Stamp / Save / Share, each a taped paper button. */
.zr-actions { display: flex; gap: var(--zr-3); }
.zr-action {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: var(--zr-3) var(--zr-2);
  border: 0;
  border-radius: var(--zr-r);
  background: var(--zr-paper-mid);
  background-image: var(--zr-paper-ledger);
  background-size: 160px auto;
  background-blend-mode: multiply;
  color: var(--zr-ink);
  font-family: var(--zr-font-display);
  font-size: var(--zr-fs-sm);
  letter-spacing: var(--zr-track-display);
  cursor: pointer;
  box-shadow: var(--zr-shadow-sm);
  transition: transform var(--zr-fast) var(--zr-ease);
}
.zr-action:nth-child(1) { transform: rotate(-1.4deg); }
.zr-action:nth-child(2) { transform: rotate(.8deg); }
.zr-action:nth-child(3) { transform: rotate(-.6deg); }
.zr-action:hover { transform: translateY(-2px) rotate(0deg); }
.zr-action__count { font-family: var(--zr-font-body); font-size: var(--zr-fs-xs); opacity: .7; }

/* Stepper — the upload flow's 1 · 2 · 3 · ✦ */
.zr-steps { display: flex; align-items: center; gap: var(--zr-2); }
.zr-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  flex: 1;
  font-size: var(--zr-fs-xs);
  color: var(--zr-text-faint);
}
.zr-step__dot {
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  border-radius: var(--zr-r-pill);
  border: 1.5px solid var(--zr-line-strong);
  font-size: var(--zr-fs-xs);
}
.zr-step.is-current { color: var(--zr-paper); }
.zr-step.is-current .zr-step__dot { background: var(--zr-violet); border-color: transparent; color: var(--zr-white); }
.zr-step.is-done .zr-step__dot { border-color: var(--zr-sage); color: var(--zr-sage); }

/* Dropzone. */
.zr-drop {
  display: grid;
  place-items: center;
  gap: var(--zr-3);
  padding: var(--zr-12) var(--zr-6);
  text-align: center;
  border: 1.5px dashed var(--zr-line-strong);
  border-radius: var(--zr-r-lg);
  background: rgba(0,0,0,.22);
  color: var(--zr-text-muted);
  transition: border-color var(--zr-fast) var(--zr-ease), background var(--zr-fast) var(--zr-ease);
}
.zr-drop:hover, .zr-drop.is-over { border-color: var(--zr-violet); background: rgba(136,108,255,.07); }

/* Empty state — a paper scrap with a handwritten line. */
.zr-empty {
  text-align: center;
  padding: var(--zr-12) var(--zr-6);
  color: var(--zr-text-muted);
}
.zr-empty__art { color: var(--zr-night-500); margin: 0 auto var(--zr-4); }

/* Messages framework output. */
.zr-messages { display: grid; gap: var(--zr-2); margin-bottom: var(--zr-5); list-style: none; padding: 0; }
.zr-message {
  padding: var(--zr-3) var(--zr-4);
  border-radius: var(--zr-r);
  border-left: 3px solid var(--zr-violet);
  background: rgba(136,108,255,.10);
  font-size: var(--zr-fs-sm);
}
.zr-message.success { border-left-color: var(--zr-sage); background: rgba(127,209,178,.10); }
.zr-message.warning { border-left-color: var(--zr-amber); background: rgba(255,181,112,.10); }
.zr-message.error   { border-left-color: var(--zr-rose);  background: rgba(255,107,139,.10); }

/* Pagination. */
.zr-pager { display: flex; align-items: center; justify-content: center; gap: var(--zr-3); margin: var(--zr-10) 0; }

/* Table (admin-ish lists). */
.zr-table { width: 100%; border-collapse: collapse; font-size: var(--zr-fs-sm); }
.zr-table th {
  text-align: left;
  padding: var(--zr-2) var(--zr-3);
  border-bottom: 1px solid var(--zr-line-strong);
  color: var(--zr-text-faint);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .08em;
  font-size: var(--zr-fs-xs);
}
.zr-table td { padding: var(--zr-3); border-bottom: 1px solid var(--zr-line); }

/* ==========================================================================
   5. LAYOUT
   ========================================================================== */

.zr-shell { min-height: 100vh; display: flex; flex-direction: column; }
.zr-main  { flex: 1; width: 100%; }

.zr-container {
  width: 100%;
  max-width: 1120px;
  margin-inline: auto;
  padding-inline: var(--zr-6);
}
.zr-container--narrow { max-width: 720px; }
.zr-container--wide   { max-width: 1360px; }

.zr-stack   > * + * { margin-top: var(--zr-4); }
.zr-stack-lg> * + * { margin-top: var(--zr-8); }

.zr-section { padding-block: var(--zr-10); }

.zr-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--zr-3); }
.zr-between { display: flex; align-items: center; justify-content: space-between; gap: var(--zr-4); }

/* The rack: a responsive shelf of zine covers. */
.zr-rack {
  display: grid;
  gap: var(--zr-6) var(--zr-5);
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
}
.zr-rack--wide { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }

/* Give the shelf a hand-placed feel: every few cards sits a hair off-true. */
.zr-rack > *:nth-child(4n+1) { transform: rotate(-.5deg); }
.zr-rack > *:nth-child(4n+3) { transform: rotate(.45deg); }

/* A horizontally scrolling shelf, for "New & Noteworthy". */
.zr-shelf {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(150px, 1fr);
  gap: var(--zr-4);
  overflow-x: auto;
  padding-bottom: var(--zr-3);
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--zr-night-500) transparent;
}
.zr-shelf > * { scroll-snap-align: start; }
.zr-shelf::-webkit-scrollbar { height: 7px; }
.zr-shelf::-webkit-scrollbar-thumb { background: var(--zr-night-500); border-radius: var(--zr-r-pill); }

/* Hero: the masthead over a night sky, with a taped tagline card. */
.zr-hero {
  position: relative;
  padding: var(--zr-16) 0 var(--zr-12);
  text-align: center;
  overflow: hidden;
}
.zr-hero__moon {
  position: absolute;
  top: var(--zr-8); right: 8%;
  width: 78px;
  color: var(--zr-gold);
  opacity: .82;
  pointer-events: none;
}
.zr-hero__stars {
  position: absolute;
  inset: 0;
  color: var(--zr-paper-dim);
  opacity: .5;
  pointer-events: none;
}
.zr-hero__tagline {
  display: inline-block;
  margin-top: var(--zr-6);
  padding: var(--zr-5) var(--zr-10);
  font-family: var(--zr-font-display);
  font-size: var(--zr-fs-lg);
  line-height: 1.5;
  transform: rotate(-1.2deg);
}

/* Footer. */
.zr-footer {
  margin-top: var(--zr-16);
  padding: var(--zr-10) 0 var(--zr-12);
  border-top: 1px solid var(--zr-line);
  color: var(--zr-text-faint);
  font-size: var(--zr-fs-sm);
}

/* ==========================================================================
   6. RACK THEMING — creator colours are sovereign
   --------------------------------------------------------------------------
   A creator picks their rack's colours; the server validates only that each
   value is a well-formed #rrggbb (CSS-injection safety) and never contrast.
   Black on black is a legitimate editorial choice and must render exactly as
   chosen. These rules therefore set colour and nothing else — no minimum
   lightness, no automatic text flip, no fallback that would override the
   creator's value once it is present.
   ========================================================================== */

/* The app skin implements this against the real class name (.rack-themed)
   and the real variables the server emits: --rack-bg, --rack-ink,
   --rack-accent and --rack-font (see zines/theming.py). The aliases below
   let the same pattern be used on any container. */

.zr-themed {
  background-color: var(--rack-bg, var(--zr-bg));
  color: var(--rack-ink, var(--zr-text));
  font-family: var(--rack-font, inherit);
}
.zr-themed .zr-card {
  --zr-card-bg: transparent;
  --zr-card-ink: var(--rack-ink, var(--zr-paper));
  border-color: currentColor;
}
.zr-themed .zr-card__title { color: var(--rack-ink, var(--zr-paper)); }
.zr-themed .zr-panel { background-color: transparent; border-color: currentColor; }
.zr-themed a { color: var(--rack-accent, var(--zr-violet)); }
.zr-themed .zr-btn--primary { --zr-btn-bg: var(--rack-accent, var(--zr-violet)); }

/* Inside a themed rack the page's own star/grain wash is suppressed, so the
   creator's chosen background is the background — not a tint over ours. */
.zr-themed--solid { background-image: none; }
.zr-themed--solid::before, .zr-themed--solid::after { display: none; }

/* ==========================================================================
   7. RESPONSIVE
   ========================================================================== */

@media (max-width: 860px) {
  :root {
    --zr-fs-2xl: 2rem;
    --zr-fs-3xl: 2.4rem;
  }

  .zr-container { padding-inline: var(--zr-4); }

  /* Swap the top nav links for the bottom tab bar. */
  .zr-topbar .zr-nav { display: none; }
  .zr-tabbar { display: flex; }
  .zr-shell { padding-bottom: 78px; }

  .zr-rack { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--zr-5) var(--zr-4); }
  .zr-hero { padding: var(--zr-10) 0 var(--zr-8); }
  .zr-hero__moon { width: 54px; right: 6%; }
  .zr-hero__tagline { padding: var(--zr-4) var(--zr-6); font-size: var(--zr-fs-md); }

  .zr-section { padding-block: var(--zr-8); }

  /* Mobile keeps the collage but calms it: less tilt, tape only where it
     helps orientation. The guide's rule — clean and easy to read. */
  .zr-rack > * { transform: none !important; }
  .zr-action  { transform: none !important; }
  .zr-btn--tertiary { transform: none; }
}

@media (max-width: 560px) {
  .zr-actions { flex-direction: column; }
  .zr-wordmark { --zr-wm-size: .95rem; }
  .zr-wordmark--lg { --zr-wm-size: 1.6rem; }
  .zr-taped::before { width: 78px; height: 22px; }
}

/* Respect a request for less motion: keep the collage, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  a.zr-card:hover, .zr-card--hoverable:hover { transform: none; }
}

/* Print: drop the night, keep the words. */
@media print {
  body { background: #fff; color: #000; }
  body::before, body::after { display: none; }
  .zr-topbar, .zr-tabbar, .zr-actions, .zr-btn { display: none !important; }
  .zr-panel, .zr-card { border: 1px solid #999; box-shadow: none; background: #fff; color: #000; }
}
