/* Library of Solana — a scholarly archive of Flesh and Blood cards.
   Two palettes: "dark academia" (default — espresso wood, brass, oxblood,
   parchment ink) and a scholarly light theme (aged paper, dark ink, brass).
   The reader's system preference picks the theme; with no stated preference
   browsers report neither light nor dark and the dark theme applies.

   The accents are the logo's own inks (assets/logo.svg): gold #f0b13f, its
   highlight #fec366, bronze #b7873a / #8c6026, and the banner reds #97281f /
   #b64d49. The dark theme takes the bright pair, the light theme the bronzes,
   so both read as the same brand. */

:root {
  color-scheme: dark;

  --bg: #171310;
  --bg-raise: #201a15;
  --bg-panel: #262019;
  --bg-input: #100d0a;
  --card-bg: #0d0a07;
  --text-block-bg: #1c1712;
  --line: #3a3126;
  --ink: #e9dfc9;          /* parchment text */
  --ink-dim: #a3927a;
  --faint: #6f604c;
  --gold: #f0b13f;
  --gold-bright: #fec366;
  --crimson: #97281f;      /* oxblood — the logo's banners */
  --crimson-bright: #b64d49;
  --danger: #f0a09a;

  --hover-tint: rgba(240, 177, 63, .12);
  --focus-ring: rgba(240, 177, 63, .25);
  --title-glow: rgba(240, 177, 63, .25);

  --header-bg: rgba(23, 18, 13, .72);
  --glass-bg: linear-gradient(160deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .02));
  --glass-border: rgba(255, 255, 255, .09);
  --glass-border-top: rgba(255, 255, 255, .16);
  --strip-bg: rgba(255, 255, 255, .03);
  --panel-glass: rgba(38, 31, 23, .9);
  --input-glass: rgba(16, 13, 10, .65);
  --overlay: rgba(10, 8, 5, .88);
  --kbd-bg: rgba(255, 255, 255, .06);
  --kbd-border: rgba(255, 255, 255, .18);

  /* Panels of glass (the quick reference). The pane is tinted with the page's
     own ground — espresso here, parchment in the light theme — mixed down to
     a translucent wash, so the glass reads as a denser piece of the same room
     rather than a white card laid over it. Only the light on it stays white:
     the sheen along its top edge, the specular streak, the rule that
     separates one compartment from the next. */
  --frost-bg: linear-gradient(155deg,
    color-mix(in srgb, var(--bg-panel) 46%, transparent),
    color-mix(in srgb, var(--bg-panel) 22%, transparent) 46%,
    color-mix(in srgb, var(--bg-panel) 38%, transparent));
  --frost-border: rgba(255, 255, 255, .18);
  --frost-sheen: rgba(255, 255, 255, .38);
  --frost-underside: rgba(255, 255, 255, .07);
  --frost-strip: color-mix(in srgb, var(--bg-raise) 45%, transparent);
  --frost-rule: rgba(255, 255, 255, .1);
  --frost-hover: rgba(255, 255, 255, .08);
  --frost-streak: rgba(255, 255, 255, .16);
  --frost-grain: .05;
  /* The etch, shared by every glass surface. feFuncA flattens the noise to
     full opacity: semi-transparent grain would wash the surface lighter
     instead of only modulating it. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='190' height='190'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='190' height='190' filter='url(%23g)'/%3E%3C/svg%3E");


  --tint-r: rgba(163, 74, 60, .12);
  --tint-b: rgba(92, 115, 134, .12);
  --tint-g: rgba(240, 177, 63, .12);

  /* Header social pills. The palette's own accents (steel, garnet, brass,
     verdigris) rather than each service's brand color, lifted enough to catch
     the eye. Bluesky gets verdigris so it doesn't twin Discord's steel. */
  --social-blue: #93b0c6;
  --social-red: #d08573;
  --social-gold: #fec366;
  --social-teal: #8fbfb4;

  --shadow: 0 4px 18px rgba(0, 0, 0, .55);
  --shadow-card: 0 3px 10px rgba(0, 0, 0, .5);
  --shadow-header: 0 2px 12px rgba(0, 0, 0, .4);
  --shadow-deep: 0 12px 40px rgba(0, 0, 0, .45);
  --shadow-img: 0 10px 40px rgba(0, 0, 0, .8);

  /* Pitch trio, tuned to the brass/parchment palette:
     garnet ember, aged amber, slate steel. */
  --pitch-red: #a34a3c;
  --pitch-red-hi: #d08573;
  --pitch-red-lo: #6e2e26;
  --pitch-yellow: #c2913a;
  --pitch-yellow-hi: #ecd9a0;
  --pitch-yellow-lo: #8a6224;
  --pitch-blue: #5c7386;
  --pitch-blue-hi: #a8bfd0;
  --pitch-blue-lo: #39485a;

  /* legality badges */
  --st-l-bg: #274d2b; --st-l-fg: #9fd8a4;
  --st-n-bg: #33302b; --st-n-fg: #8b8378;
  --st-b-bg: #58201d; --st-b-fg: #f0a09a;
  --st-s-bg: #574c1d; --st-s-fg: #e8d283;
  --st-v-bg: #45325c; --st-v-fg: #cbb3ec;
  --st-r-bg: #55381c; --st-r-fg: #ecc79a;

  --radius: 10px;
  --card-ratio: 88 / 63;   /* height / width of a FaB card */
}

/* The scholarly light palette applies two ways: via the system preference
   (unless the reader has explicitly chosen dark) and via the header toggle
   (data-theme="light", set by js/theme.js). The custom-property blocks must
   stay identical — edit both together. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;

    --bg: #f4ecda;
    --bg-raise: #ede2cb;
    --bg-panel: #faf5e8;
    --bg-input: #fffdf5;
    --card-bg: #e8deca;
    --text-block-bg: #efe7d2;
    --line: #d8c9a9;
    --ink: #372b1b;
    --ink-dim: #7d6b50;
    --faint: #a28c69;
    --gold: #b7873a;
    --gold-bright: #8c6026;
    --crimson: #97281f;
    --crimson-bright: #b64d49;
    --danger: #97281f;

    --hover-tint: rgba(140, 96, 38, .13);
    --focus-ring: rgba(140, 96, 38, .28);
    --title-glow: rgba(140, 96, 38, .18);

    --header-bg: rgba(247, 240, 226, .82);
    --glass-bg: linear-gradient(160deg, rgba(255, 255, 255, .65), rgba(255, 255, 255, .35));
    --glass-border: rgba(96, 74, 42, .22);
    --glass-border-top: rgba(255, 255, 255, .85);
    --strip-bg: rgba(96, 74, 42, .05);
    --panel-glass: rgba(250, 245, 232, .96);
    --input-glass: rgba(255, 253, 245, .75);
    --overlay: rgba(48, 38, 24, .55);
    --kbd-bg: rgba(96, 74, 42, .08);
    --kbd-border: rgba(96, 74, 42, .3);

    --frost-bg: linear-gradient(155deg,
      color-mix(in srgb, var(--bg-panel) 62%, transparent),
      color-mix(in srgb, var(--bg-panel) 34%, transparent) 46%,
      color-mix(in srgb, var(--bg-panel) 52%, transparent));
    --frost-border: rgba(96, 74, 42, .22);
    --frost-sheen: rgba(255, 255, 255, .95);
    --frost-underside: rgba(96, 74, 42, .1);
    --frost-strip: color-mix(in srgb, var(--bg-raise) 55%, transparent);
    --frost-rule: rgba(96, 74, 42, .16);
    --frost-hover: rgba(255, 255, 255, .72);
    --frost-streak: rgba(255, 255, 255, .85);
    --frost-grain: .07;


    --tint-r: rgba(163, 74, 60, .09);
    --tint-b: rgba(92, 115, 134, .10);
    --tint-g: rgba(183, 135, 58, .12);

    --social-blue: #4f6d84;
    --social-red: #9c4335;
    --social-gold: #8c6026;
    --social-teal: #3f7367;

    --shadow: 0 4px 18px rgba(92, 70, 38, .22);
    --shadow-card: 0 3px 10px rgba(92, 70, 38, .25);
    --shadow-header: 0 2px 12px rgba(92, 70, 38, .15);
    --shadow-deep: 0 12px 40px rgba(92, 70, 38, .18);
    --shadow-img: 0 10px 40px rgba(60, 45, 25, .45);

    --st-l-bg: #d7e9d1; --st-l-fg: #2c5f33;
    --st-n-bg: #e7e1d3; --st-n-fg: #78705f;
    --st-b-bg: #f2d2cd; --st-b-fg: #8c2622;
    --st-s-bg: #efe4bd; --st-s-fg: #75601c;
    --st-v-bg: #e2d7f0; --st-v-fg: #59407e;
    --st-r-bg: #efdec2; --st-r-fg: #7a5220;
  }
}

:root[data-theme="light"] {
  color-scheme: light;

  --bg: #f4ecda;
  --bg-raise: #ede2cb;
  --bg-panel: #faf5e8;
  --bg-input: #fffdf5;
  --card-bg: #e8deca;
  --text-block-bg: #efe7d2;
  --line: #d8c9a9;
  --ink: #372b1b;
  --ink-dim: #7d6b50;
  --faint: #a28c69;
  --gold: #b7873a;
  --gold-bright: #8c6026;
  --crimson: #97281f;
  --crimson-bright: #b64d49;
  --danger: #97281f;

  --hover-tint: rgba(140, 96, 38, .13);
  --focus-ring: rgba(140, 96, 38, .28);
  --title-glow: rgba(140, 96, 38, .18);

  --header-bg: rgba(247, 240, 226, .82);
  --glass-bg: linear-gradient(160deg, rgba(255, 255, 255, .65), rgba(255, 255, 255, .35));
  --glass-border: rgba(96, 74, 42, .22);
  --glass-border-top: rgba(255, 255, 255, .85);
  --strip-bg: rgba(96, 74, 42, .05);
  --panel-glass: rgba(250, 245, 232, .96);
  --input-glass: rgba(255, 253, 245, .75);
  --overlay: rgba(48, 38, 24, .55);
  --kbd-bg: rgba(96, 74, 42, .08);
  --kbd-border: rgba(96, 74, 42, .3);

  --frost-bg: linear-gradient(155deg,
    color-mix(in srgb, var(--bg-panel) 62%, transparent),
    color-mix(in srgb, var(--bg-panel) 34%, transparent) 46%,
    color-mix(in srgb, var(--bg-panel) 52%, transparent));
  --frost-border: rgba(96, 74, 42, .22);
  --frost-sheen: rgba(255, 255, 255, .95);
  --frost-underside: rgba(96, 74, 42, .1);
  --frost-strip: color-mix(in srgb, var(--bg-raise) 55%, transparent);
  --frost-rule: rgba(96, 74, 42, .16);
  --frost-hover: rgba(255, 255, 255, .72);
  --frost-streak: rgba(255, 255, 255, .85);
  --frost-grain: .07;


  --tint-r: rgba(163, 74, 60, .09);
  --tint-b: rgba(92, 115, 134, .10);
  --tint-g: rgba(183, 135, 58, .12);

  --social-blue: #4f6d84;
  --social-red: #9c4335;
  --social-gold: #8c6026;
  --social-teal: #3f7367;

  --shadow: 0 4px 18px rgba(92, 70, 38, .22);
  --shadow-card: 0 3px 10px rgba(92, 70, 38, .25);
  --shadow-header: 0 2px 12px rgba(92, 70, 38, .15);
  --shadow-deep: 0 12px 40px rgba(92, 70, 38, .18);
  --shadow-img: 0 10px 40px rgba(60, 45, 25, .45);

  --st-l-bg: #d7e9d1; --st-l-fg: #2c5f33;
  --st-n-bg: #e7e1d3; --st-n-fg: #78705f;
  --st-b-bg: #f2d2cd; --st-b-fg: #8c2622;
  --st-s-bg: #efe4bd; --st-s-fg: #75601c;
  --st-v-bg: #e2d7f0; --st-v-fg: #59407e;
  --st-r-bg: #efdec2; --st-r-fg: #7a5220;
}

* { box-sizing: border-box; }

/* The hidden attribute must always win, even over display:flex/block rules. */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  background:
    radial-gradient(900px 480px at 15% -10%, var(--tint-r), transparent 65%),
    radial-gradient(1000px 520px at 85% -5%, var(--tint-b), transparent 65%),
    radial-gradient(1200px 600px at 50% 0%, var(--tint-g), transparent 70%),
    var(--bg);
  background-attachment: fixed;
  color: var(--ink);
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", sans-serif;
  line-height: 1.5;
}

/* position:fixed (not just overflow:hidden) is required to stop iOS Safari
   from rubber-banding the page behind the lightbox; app.js pairs this with a
   saved scrollY that gets restored on close. */
body.no-scroll { position: fixed; overflow: hidden; width: 100%; }

a { color: var(--gold-bright); text-decoration: none; }
a:hover { text-decoration: underline; }

code, .code {
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  background: var(--bg-input);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: .1em .4em;
  font-size: .92em;
  color: var(--gold-bright);
}

/* ---------- emblem: the temple of Solana rising from an open book ----------
   assets/logo.svg, the brand mark itself. It carries its own gold/oxblood
   inks (no currentColor), so it needs no per-theme treatment; it is taller
   than it is wide, and `contain` centres it in whichever box holds it. */

.emblem {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ---------- header ---------- */

/* The same glass as the quick reference, laid as a bar: the page-ground tint
   over the header's own base (which stays opaque enough to carry the nav over
   scrolling card art), the light blur, and lit edges. Its surface layers are
   drawn by the pseudo-elements below. */
.site-header {
  border-bottom: 1px solid var(--frost-border);
  background-image: var(--frost-bg), linear-gradient(var(--header-bg), var(--header-bg));
  -webkit-backdrop-filter: blur(14px) saturate(1.7) brightness(1.03);
  backdrop-filter: blur(14px) saturate(1.7) brightness(1.03);
  padding: .65rem 1rem;
  padding-top: calc(.65rem + env(safe-area-inset-top));
  padding-left: calc(1rem + env(safe-area-inset-left));
  padding-right: calc(1rem + env(safe-area-inset-right));
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  z-index: 40;
  box-shadow:
    inset 0 1px 0 var(--frost-sheen),
    inset 0 -1px 0 var(--frost-underside),
    var(--shadow-header);
}
/* Sticky + z-index makes the header its own stacking context, so these sit
   above its background and below the nav without touching either. A bar this
   shallow only has room for one glint, placed off to the left where the mark
   is; the grain is the same etch the quick reference carries. */
.site-header::before,
.site-header::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.site-header::before {
  background-image:
    linear-gradient(104deg, transparent 6%, var(--frost-streak) 13%, transparent 22%),
    radial-gradient(120% 180% at 4% -40%, var(--frost-strip), transparent 60%);
}
.site-header::after {
  background: var(--grain) 0 0 / 190px 190px repeat;
  mix-blend-mode: overlay;
  opacity: var(--frost-grain);
}

.brand {
  display: flex;
  align-items: center;
  gap: .55rem;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.35rem;
  letter-spacing: .06em;
  color: var(--gold-bright);
  font-weight: 700;
  white-space: nowrap;
}
.brand:hover { text-decoration: none; }

.brand-glyph {
  width: 2rem; height: 2rem;
  flex: none;
}

.header-nav { margin-left: auto; display: flex; align-items: center; gap: 1rem; font-size: .95rem; }
.header-nav a { color: var(--ink-dim); }
.header-nav a:hover, .header-nav a.active { color: var(--gold-bright); }

/* ---------- header social pills ----------
   Discord, Patreon and Ko-fi share one shape and one recipe: a translucent
   wash of the link's accent, a border at the same hue, and the accent itself
   as the text/icon color. The accents are the palette's steel / garnet /
   brass rather than each service's brand color, so the row stays in the
   parchment scheme while still reading as three distinct, findable buttons. */
.header-nav .discord-link,
.header-nav .bsky-link,
.header-nav .patreon-link,
.header-nav .kofi-slot a.kofi-button {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .35rem;
  height: 1.95rem;
  padding: 0 .7rem;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  color: var(--accent);
  font-size: .85rem;
  font-weight: 600;
  white-space: nowrap;
}
.header-nav .discord-link:hover,
.header-nav .bsky-link:hover,
.header-nav .patreon-link:hover,
.header-nav .kofi-slot a.kofi-button:hover {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  border-color: var(--accent);
  color: var(--accent);
  text-decoration: none;
  opacity: 1;
}
.discord-link { --accent: var(--social-blue); }
.bsky-link    { --accent: var(--social-teal); }
.patreon-link { --accent: var(--social-red); }
.kofi-slot    { --accent: var(--social-gold); }

.discord-mark, .bsky-mark, .patreon-mark {
  width: .95rem; height: .95rem;
  flex: none;
  fill: currentColor;
}

/* Ko-fi ships its own stylesheet built for a standalone page button — 150px
   min-width, a 36px line, white text and a looping wiggle on the cup. All of
   it has to be unwound to match the two hand-built pills, and the selectors
   are prefixed with .header-nav to outrank the widget's own rules. */
.kofi-slot {
  flex: none;
  display: inline-flex;
  align-items: center;
}
/* The container reserves 160px on its own, which would keep forcing the nav
   onto a second row even after the button itself is trimmed. */
.header-nav .kofi-slot .btn-container { min-width: 0; }
.header-nav .kofi-slot a.kofi-button {
  min-width: 0;
  padding: 0 .7rem !important;
  line-height: 1.95rem !important;
  font-size: .85rem !important;
  display: inline-flex !important;
  background-color: color-mix(in srgb, var(--accent) 13%, transparent) !important;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent) !important;
  box-shadow: none;
}
.header-nav .kofi-slot a.kofi-button:hover {
  background-color: color-mix(in srgb, var(--accent) 26%, transparent) !important;
  border-color: var(--accent) !important;
}
/* Icon only, like the other three pills — but the widget's label is the
   button's only accessible name, so it is clipped rather than removed. */
.header-nav .kofi-slot a.kofi-button { position: relative; }
.header-nav .kofi-slot span.kofitext {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0 !important;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* The widget's cup is a white PNG swapped in via content:, which would vanish
   on the light parchment. Drop it and mask our own so it inherits the accent. */
.header-nav .kofi-slot img.kofiimg { display: none !important; }
.header-nav .kofi-slot a.kofi-button::before {
  content: "";
  width: .95rem; height: .95rem;
  flex: none;
  background-color: currentColor;
  -webkit-mask: var(--cup) center / contain no-repeat;
  mask: var(--cup) center / contain no-repeat;
  --cup: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 4.5h13.4v6.8a6.2 6.2 0 0 1-6.2 6.2H9.2A6.2 6.2 0 0 1 3 11.3V4.5zm14.6 1.6h1.2a3.6 3.6 0 0 1 0 7.2h-1.9v-2.1h1.9a1.5 1.5 0 0 0 0-3h-1.2v-2.1z'/%3E%3C/svg%3E");
}

/* Theme switcher: shows the theme a click will bring (sun while dark,
   moon while light). Icon choice mirrors the palette selectors above. */
.theme-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem; height: 2.1rem;
  padding: 0;
  background: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--ink-dim);
  cursor: pointer;
}
.theme-toggle:hover { border-color: var(--gold); color: var(--gold-bright); }
.theme-toggle svg {
  width: 1.1rem; height: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.theme-toggle .icon-moon { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .theme-toggle .icon-sun { display: none; }
  :root:not([data-theme="dark"]) .theme-toggle .icon-moon { display: block; }
}
:root[data-theme="light"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: block; }
/* An explicit dark choice must beat the system-light rule above. */
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* ---------- search bar ---------- */

.search-wrap {
  position: relative;
  flex: 1 1 320px;
  min-width: 240px;
  max-width: 720px;
}

#search-form { display: flex; }

#search {
  width: 100%;
  font-size: 1rem;
  padding: .6rem 2.6rem .6rem .9rem;
  color: var(--ink);
  background: var(--bg-input);
  border: 1px solid var(--gold);
  border-radius: var(--radius);
  outline: none;
  font-family: ui-monospace, Menlo, Consolas, monospace;
}
#search:focus { border-color: var(--gold-bright); box-shadow: 0 0 0 3px var(--focus-ring); }
#search::placeholder { color: var(--faint); font-family: inherit; }

.search-btn {
  position: absolute;
  right: .3rem; top: 50%;
  transform: translateY(-50%);
  background: none; border: none;
  color: var(--gold); font-size: 1.1rem;
  cursor: pointer; padding: .3rem .5rem;
}

.ac-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0; right: 0;
  margin: 0; padding: .3rem;
  list-style: none;
  background: var(--panel-glass);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  backdrop-filter: blur(16px) saturate(1.25);
  border: 1px solid var(--gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 60;
  max-height: 60vh;
  overflow: auto;
}

.ac-item {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: .45rem .6rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: .95rem;
}
.ac-item.active, .ac-item:hover { background: var(--hover-tint); }
.ac-value {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  color: var(--ink);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ac-hint { flex: none; color: var(--ink-dim); font-size: .85rem; }

/* ---------- layout ---------- */

main { max-width: 1400px; margin: 0 auto; padding: 1rem; }

.status-line {
  color: var(--ink-dim);
  font-size: .9rem;
  min-height: 1.3rem;
  margin: .3rem .2rem .8rem;
}
/* The reserved line keeps result counts from jittering between searches, but
   on the landing view it is empty — and that dead band is 2.4rem of the fold
   budget the hero needs. Collapse it while there is nothing to say. */
.status-line:empty { display: none; }

/* ---------- glass ---------- */

.glass {
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  backdrop-filter: blur(16px) saturate(1.25);
  border: 1px solid var(--glass-border);
  border-top-color: var(--glass-border-top);
  border-radius: 14px;
  box-shadow: var(--shadow-deep);
}

/* ---------- home hero ---------- */

.header-search-slot { display: contents; }
.header-search-slot:empty { display: none; }

/* The landing fold is budgeted against the viewport height, not just its
   width: mark, title, tagline and search bar all shrink on a short screen so
   that the whole introduction plus the top fifth of the quick reference stay
   on screen at once. The reference peeking above the fold is what tells a
   first-time reader there is a notation to learn. Every vertical step below
   is therefore a vh-driven clamp; changing one to a fixed length will push
   the panel off a laptop screen. */

.home-hero {
  position: relative;
  text-align: center;
  padding: clamp(.6rem, 3vh, 3rem) 1rem 1rem;
  max-width: 880px;
  margin: 0 auto;
}
/* The light behind the pane. Clear glass has nothing of its own to show, so
   it needs something behind it worth seeing: this warm wash sits under the
   panel and reads straight through the glazing, only softened by the blur. */
.home-hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  bottom: -4%;
  width: 118%;
  height: 62%;
  transform: translateX(-50%);
  pointer-events: none;
  background:
    radial-gradient(50% 60% at 28% 52%, var(--tint-g), transparent 70%),
    radial-gradient(46% 56% at 76% 72%, var(--tint-r), transparent 70%);
}

.hero-mark {
  /* Scales with the viewport like the h1 beneath it; the ratio is the mark's
     own, so `contain` never leaves slack around it. */
  width: clamp(72px, min(22vw, 20vh), 230px);
  aspect-ratio: 1236 / 1509;
  margin: 0 auto clamp(.35rem, 1.4vh, .9rem);
  filter: drop-shadow(0 6px 18px var(--title-glow));
}

.home-hero h1 {
  font-family: Georgia, serif;
  font-size: clamp(1.6rem, min(6vw, 5.5vh), 3rem);
  color: var(--gold-bright);
  letter-spacing: .12em;
  margin: 0 0 .3rem;
  text-shadow: 0 2px 20px var(--title-glow);
}
.home-hero .tagline {
  color: var(--ink-dim);
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: clamp(.88rem, 1.8vh, 1.02rem);
  margin: 0 0 clamp(.7rem, 2.4vh, 1.6rem);
}

.hero-search-slot { margin: 0 auto clamp(.7rem, 2.4vh, 1.6rem); max-width: 640px; }
.hero-search-slot .search-wrap { max-width: none; }
.hero-search-slot #search {
  font-size: 1.08rem;
  padding: .85rem 3rem .85rem 1.1rem;
  border-radius: 13px;
  background: var(--input-glass);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: var(--shadow);
}
.hero-search-slot .search-btn { font-size: 1.3rem; }

/* Very short viewports — landscape phones, half-height windows — cannot hold
   the whole introduction and still show the reference. The least load-bearing
   pieces step aside in order: first the header's own padding, then the flavour
   line, the advanced-search link and the social row (all reachable again the
   moment the reader scrolls or rotates), so the mark, the search bar and the
   top of the quick reference survive. */
@media (max-height: 620px) {
  .site-header { padding-top: .4rem; padding-bottom: .4rem; }
}
@media (max-height: 440px) {
  .header-nav .discord-link,
  .header-nav .bsky-link,
  .header-nav .patreon-link,
  .header-nav .kofi-slot { display: none; }
  .home-hero { padding-top: .3rem; }
  .home-hero .tagline,
  .hero-alt { display: none; }
  .home-hero h1 { font-size: 1.25rem; margin-bottom: .2rem; }
  .hero-mark { width: clamp(48px, 15vh, 96px); }
  .hero-search-slot { margin-bottom: .5rem; }
  .hero-search-slot #search { font-size: 1rem; padding: .55rem 2.6rem .55rem .9rem; }
}

/* ---------- quick reference ----------
   A pane of clear glass rather than frosted: the blur is light enough to read
   as glazing instead of etching, the white veil is thin, and what sells it is
   light rather than haze — a lit rim, specular highlights raking across the
   surface, and the warm wash behind it (.home-hero::after) showing through.
   The grain is only a whisper, enough to keep the surface from reading as
   plastic. The three coloured dots are the pitch trio, not window chrome. */

.quickref {
  position: relative;
  text-align: left;
  margin: 0 auto 1.4rem;
  overflow: hidden;
  border-radius: 18px;
  border: 1px solid var(--frost-border);
  background: var(--frost-bg);
  /* Light blur: enough to soften what is behind the pane, not enough to
     obscure it. Past ~20px the panel starts reading as frosted again. */
  -webkit-backdrop-filter: blur(14px) saturate(1.7) brightness(1.03);
  backdrop-filter: blur(14px) saturate(1.7) brightness(1.03);
  /* The edges are where glass announces its thickness: a lit top rim, a
     brighter underside where light bounces back up, and an interior glow that
     falls off before it reaches the middle. */
  box-shadow:
    inset 1px 1px 0 var(--frost-sheen),
    inset -1px -1px 0 var(--frost-underside),
    inset 0 0 70px -24px var(--frost-sheen),
    var(--shadow-deep);
}
/* Two surface layers, both under the content so the type stays crisp. */
.quickref::before,
.quickref::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* Light on the surface: a bloom off the top-left corner, a specular streak
   raking across the pane, and the streak's counterpart at the bottom-right so
   the lower half of a tall panel never goes flat. */
.quickref::before {
  background-image:
    linear-gradient(104deg, transparent 21%, var(--frost-streak) 33%, transparent 43%),
    radial-gradient(150% 55% at 50% -22%, var(--frost-streak), transparent 70%),
    radial-gradient(120% 80% at 6% -14%, var(--frost-strip), transparent 62%),
    radial-gradient(90% 60% at 108% 112%, var(--frost-strip), transparent 58%);
}
/* A whisper of grain, blended into the glass rather than laid on top of it
   and kept under the type by the z-index below. Turned right down: enough to
   keep the surface off perfectly flat, not enough to etch it. */
.quickref::after {
  z-index: 0;
  background: var(--grain) 0 0 / 190px 190px repeat;
  mix-blend-mode: overlay;
  opacity: var(--frost-grain);
}
.quickref > * { position: relative; z-index: 1; }

.qr-titlebar {
  display: flex;
  align-items: center;
  gap: .45rem;
  padding: .6rem 1rem;
  border-bottom: 1px solid var(--frost-rule);
  background: var(--frost-strip);
}
.qr-dot {
  width: .72rem; height: .72rem;
  border-radius: 50%;
  border: 1px solid var(--frost-border);
  box-shadow:
    inset 0 -1px 2px rgba(0, 0, 0, .45),
    0 1px 3px rgba(0, 0, 0, .25);
}
.qr-dot-r { background: radial-gradient(circle at 35% 30%, var(--pitch-red-hi), var(--pitch-red) 55%, var(--pitch-red-lo)); }
.qr-dot-y { background: radial-gradient(circle at 35% 30%, var(--pitch-yellow-hi), var(--pitch-yellow) 55%, var(--pitch-yellow-lo)); }
.qr-dot-b { background: radial-gradient(circle at 35% 30%, var(--pitch-blue-hi), var(--pitch-blue) 55%, var(--pitch-blue-lo)); }
.qr-title {
  margin-left: .5rem;
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: .85rem;
  letter-spacing: .04em;
  color: var(--ink-dim);
}
.qr-man {
  margin-left: auto;
  padding: .15rem .6rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: Georgia, "Times New Roman", serif;
  font-size: .85rem;
  color: var(--gold-bright);
  transition: background .16s ease, border-color .16s ease;
}
.qr-man:hover {
  background: var(--frost-hover);
  border-color: var(--frost-border);
  text-decoration: none;
}

.qr-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  padding: 1rem .6rem .8rem;
}
/* Each column is a compartment of the pane, divided by a hairline that fades
   out at both ends rather than butting into the panel edges. The divider is
   keyed to the column count, so it moves with the grid at each breakpoint. */
.qr-group {
  position: relative;
  padding: 0 .9rem;
}
.qr-group:not(:nth-child(4n + 1))::before {
  content: "";
  position: absolute;
  left: 0;
  top: .2rem;
  bottom: .2rem;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--frost-rule) 16%, var(--frost-rule) 84%, transparent);
}
.qr-group h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-size: .74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--gold);
  margin: 0 0 .35rem;
}
.qr-line {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .05rem;
  width: 100%;
  padding: .38rem .55rem;
  margin: 0 -.55rem .1rem;
  background: none;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  text-align: left;
  transition: background .16s ease, box-shadow .16s ease, transform .16s ease;
}
/* Hovered rows lift into their own little pane of glass. */
.qr-line:hover, .qr-line:focus-visible {
  background: var(--frost-hover);
  box-shadow: inset 0 1px 0 var(--frost-sheen), 0 2px 10px rgba(0, 0, 0, .12);
  transform: translateY(-1px);
  outline: none;
}
.qr-line:focus-visible { box-shadow: inset 0 0 0 1px var(--gold), 0 2px 10px rgba(0, 0, 0, .12); }
.qr-line:active { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .qr-line { transition: background .16s ease; }
  .qr-line:hover, .qr-line:focus-visible, .qr-line:active { transform: none; }
}
.qr-line code {
  background: none; border: none; padding: 0;
  font-size: .85rem;
  color: var(--ink);
}
.qr-line:hover code { color: var(--gold-bright); }
.qr-line span {
  font-size: .72rem;
  color: var(--ink-dim);
}

.qr-foot {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1.3rem;
  padding: .6rem 1rem;
  border-top: 1px solid var(--frost-rule);
  background: var(--frost-strip);
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: .72rem;
  color: var(--ink-dim);
}

kbd {
  display: inline-block;
  min-width: 1.4em;
  text-align: center;
  padding: .05em .35em;
  border: 1px solid var(--kbd-border);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--kbd-bg);
  font-family: inherit;
  font-size: .95em;
  color: var(--ink);
}

.db-meta { color: var(--faint); font-size: .8rem; }

/* ---------- sorting bar ---------- */

.sort-bar {
  display: flex;
  align-items: center;
  gap: .6rem;
  max-width: 980px;
  margin: 0 auto 1.1rem;
}
.sort-bar label {
  color: var(--ink-dim);
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: .95rem;
}
.sort-bar select {
  background: var(--bg-input);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .35rem .5rem;
  font: inherit;
  font-size: .9rem;
  cursor: pointer;
}
.sort-bar select:hover { border-color: var(--gold); }
.sort-dir {
  background: none;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .35rem .7rem;
  font: inherit;
  font-size: .9rem;
  cursor: pointer;
  white-space: nowrap;
}
.sort-dir:hover { border-color: var(--gold); color: var(--gold-bright); }

/* ---------- results grid ---------- */

/* Mobile-first: two large cards side by side. On wider viewports the grid
   fills with as many ~210px cards as fit (auto-fill), so desktop uses the
   whole width instead of a narrow two-card column with dead space on the
   sides. Capped at a comfortable reading width and centered. */
.results-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.6rem 1.4rem;
  max-width: 1500px;
  margin: 0 auto;
}
@media (min-width: 700px) {
  .results-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
}

.card-cell {
  cursor: zoom-in;
  border-radius: 4.5% / 3.2%;
  transition: transform .12s ease;
  /* Also disables the browser's double-tap zoom so the double-tap-to-save
     gesture lands on us instead. */
  touch-action: manipulation;
}
.card-cell:hover { transform: translateY(-3px); }

.card-img {
  width: 100%;
  aspect-ratio: 63 / 88;
  object-fit: contain;
  border-radius: 4.5% / 3.2%;
  background: var(--card-bg);
  box-shadow: var(--shadow-card);
  display: block;
}
/* --rot is set inline per-printing (some scans need 90deg, some 270deg;
   a fixed 90deg here would render 270deg printings upside down). */
.card-img.rotated { transform: rotate(var(--rot, 90deg)) scale(0.715); }

.card-bar {
  display: flex; align-items: center; gap: .45rem;
  padding: .4rem .2rem 0;
  font-size: .95rem;
}
.card-bar-name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink);
}
.card-bar-price { flex: none; color: var(--gold-bright); font-variant-numeric: tabular-nums; }

/* Bookmark toggle in the caption line beside the name and price. */
.save-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  background: none;
  border: none;
  padding: .1rem .15rem;
  cursor: pointer;
  color: var(--ink-dim);
}
.save-btn svg {
  width: 1.15em; height: 1.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linejoin: round;
}
.save-btn:hover { color: var(--gold-bright); }
.save-btn.saved { color: var(--gold-bright); }
.save-btn.saved svg { fill: currentColor; }
.save-btn.pop { animation: save-pop .35s ease; }
@keyframes save-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.5); }
  100% { transform: scale(1); }
}

.pitch-gems {
  display: inline-flex;
  align-items: center;
  gap: .18em;
  flex: none;
}

.pitch-dot {
  width: .68em; height: .68em;
  border-radius: 50%;
  flex: none;
  border: 1px solid rgba(240, 177, 63, .45);
  box-shadow: inset 0 -1px 2px rgba(0, 0, 0, .55), 0 1px 2px rgba(0, 0, 0, .4);
}
.pitch-red {
  background: radial-gradient(circle at 35% 30%, var(--pitch-red-hi), var(--pitch-red) 55%, var(--pitch-red-lo));
}
.pitch-yellow {
  background: radial-gradient(circle at 35% 30%, var(--pitch-yellow-hi), var(--pitch-yellow) 55%, var(--pitch-yellow-lo));
}
.pitch-blue {
  background: radial-gradient(circle at 35% 30%, var(--pitch-blue-hi), var(--pitch-blue) 55%, var(--pitch-blue-lo));
}
.pitch-none {
  background: radial-gradient(circle at 35% 30%, #b3ac9e, #6d675c 55%, #46413a);
  border-color: rgba(240, 177, 63, .25);
}

.load-more {
  display: block;
  margin: 1.5rem auto 2.5rem;
  background: var(--bg-panel);
  color: var(--gold-bright);
  border: 1px solid var(--gold);
  border-radius: var(--radius);
  font-size: 1rem;
  padding: .6rem 1.6rem;
  cursor: pointer;
}
.load-more:hover { background: var(--hover-tint); }

.empty-state { text-align: center; color: var(--ink-dim); padding: 3rem 1rem; }

/* ---------- advanced search ---------- */

.hero-alt {
  /* Negative top margin tucks it under the search bar; the bottom edge is the
     last step of the vh budget described at .home-hero. */
  margin: clamp(-.9rem, -1.4vh, -.5rem) 0 clamp(.7rem, 2.2vh, 1.5rem);
  font-family: Georgia, "Times New Roman", serif;
  font-size: .9rem;
}
.hero-alt a { color: var(--ink-dim); text-decoration: none; }
.hero-alt a:hover { color: var(--gold-bright); }

.advanced { max-width: 880px; margin: .3rem auto 2.5rem; }

.adv-panel { overflow: hidden; }

.adv-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem 1.4rem;
  padding: 1.1rem 1.2rem;
}

.adv-field { display: flex; flex-direction: column; gap: .35rem; }

.adv-field > label,
.adv-fieldset legend {
  font-family: Georgia, "Times New Roman", serif;
  font-size: .74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--gold);
  padding: 0;
}

.adv-field input[type="text"],
.adv-field select {
  width: 100%;
  background: var(--bg-input);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .55rem .7rem;
  font: inherit;
  font-size: .95rem;
}
.adv-field select { cursor: pointer; }
.adv-field input[type="text"]:hover,
.adv-field select:hover { border-color: var(--gold); }
.adv-field input[type="text"]:focus,
.adv-field select:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* Autocomplete for the comma-list boxes: floats over whatever follows so the
   form does not jump as suggestions come and go. */
.adv-combo { position: relative; }

.adv-ac {
  position: absolute;
  z-index: 30;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  margin: 0;
  padding: .25rem;
  list-style: none;
  max-height: 18rem;
  overflow-y: auto;
  background: var(--bg-panel);
  border: 1px solid var(--gold);
  border-radius: 8px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .45);
}
.adv-ac[hidden] { display: none; }

.adv-ac-opt {
  padding: .38rem .55rem;
  border-radius: 6px;
  font-size: .92rem;
  color: var(--ink);
  cursor: pointer;
}
.adv-ac-opt:hover,
.adv-ac-opt.is-active {
  background: var(--focus-ring);
  color: var(--gold);
}

.adv-hint {
  margin: 0;
  font-size: .74rem;
  color: var(--faint);
}

.adv-wide { grid-column: 1 / -1; }

.adv-fieldset { border: none; margin: 0; padding: 0; }
.adv-fieldset legend { margin-bottom: .35rem; }

.adv-pitch,
.adv-syms { display: flex; flex-wrap: wrap; gap: .4rem; }

/* Number filters sit three across, each one line of symbol + operator + value:
   the card symbol names the stat the way the cards themselves do, so the row
   reads as one bank of controls without three headings above it. */
.adv-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(9rem, 14rem));
  gap: .6rem .9rem;
}
.adv-stat {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: .4rem;
}
.adv-stat-sym {
  display: inline-flex;
  cursor: pointer;
}
.adv-stat-sym img { width: 1.35rem; height: 1.35rem; object-fit: contain; }
.adv-field .adv-op {
  width: auto;
  padding: .4rem .3rem;
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
}
.adv-field .adv-stat input[type="number"] {
  min-width: 0;
  background: var(--bg-input);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .4rem .5rem;
  font: inherit;
  font-size: .95rem;
}
.adv-field .adv-stat input[type="number"]:hover { border-color: var(--gold); }
.adv-field .adv-stat input[type="number"]:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.sym-chip img { width: 1.05em; height: 1.05em; object-fit: contain; }
.sym-chip .sym-glyph {
  width: 1.05em;
  text-align: center;
  color: var(--gold);
  font-size: 1.05em;
  line-height: 1;
}

.pitch-chip,
.sym-chip {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  background: var(--bg-input);
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .4rem .8rem;
  font: inherit;
  font-size: .88rem;
  cursor: pointer;
  transition: border-color .12s, color .12s, background .12s;
}
.pitch-chip:hover,
.sym-chip:hover { border-color: var(--gold); color: var(--ink); }
.pitch-chip[aria-pressed="true"],
.sym-chip[aria-pressed="true"] {
  border-color: var(--gold);
  background: var(--hover-tint);
  color: var(--gold-bright);
  box-shadow: inset 0 0 0 1px var(--gold), 0 0 0 3px var(--focus-ring);
}
.pitch-chip .pitch-num { color: var(--faint); font-size: .8em; }
.pitch-chip[aria-pressed="true"] .pitch-num { color: var(--gold); }

.adv-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem 1rem;
  padding: .7rem 1.2rem;
  border-top: 1px solid var(--glass-border);
  background: var(--strip-bg);
}
.adv-preview {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  min-width: 0;
  flex: 1 1 16rem;
}
.adv-preview-label {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: .8rem;
  color: var(--ink-dim);
  flex: none;
}
#adv-query {
  font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: .82rem;
  line-height: 1.5;
  color: var(--gold-bright);
  /* A long query wraps rather than scrolling in its own strip — the footer is
     the one place the whole search is readable at a glance. */
  overflow-wrap: anywhere;
}
.adv-actions { display: flex; gap: .5rem; margin-left: auto; }
.adv-submit {
  background: var(--bg-panel);
  color: var(--gold-bright);
  border: 1px solid var(--gold);
  border-radius: 7px;
  padding: .35rem 1.1rem;
  font: inherit;
  font-size: .9rem;
  cursor: pointer;
}
.adv-submit:hover { background: var(--hover-tint); }

/* ---------- reading list ---------- */

.saved-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .8rem;
  max-width: 980px;
  margin: .3rem auto 1.1rem;
}
.saved-title {
  font-family: Georgia, "Times New Roman", serif;
  color: var(--gold-bright);
  font-size: 1.35rem;
  letter-spacing: .05em;
  margin: 0 .4rem 0 0;
}
.saved-actions { margin-left: auto; display: flex; gap: .5rem; }
.tool-btn {
  background: none;
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--ink-dim);
  padding: .3rem .8rem;
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
}
.tool-btn:hover { border-color: var(--gold); color: var(--gold-bright); }
.tool-btn.danger:hover { border-color: var(--crimson-bright); color: var(--danger); }

/* ---------- lightbox ---------- */

.lightbox {
  position: fixed; inset: 0;
  z-index: 100;
  background: var(--overlay);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: stretch;
  justify-content: center;
  padding: 1rem;
}

.lb-panel {
  display: grid;
  grid-template-columns: minmax(320px, 560px) minmax(300px, 480px);
  gap: 1.5rem;
  max-width: 1140px;
  width: 100%;
  margin: auto;
  overflow: auto;
  max-height: 100%;
  padding: 1rem;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

#lb-image-wrap { display: flex; align-items: flex-start; justify-content: center; }
#lb-image {
  width: 100%;
  max-height: calc(100vh - 4rem);
  object-fit: contain;
  border-radius: 4.5% / 3.2%;
  box-shadow: var(--shadow-img);
}
#lb-image.rotated { transform: rotate(var(--rot, 90deg)) scale(.715); }
.lb-noimg {
  width: 100%; aspect-ratio: 63/88;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--line); border-radius: var(--radius);
  color: var(--ink-dim);
}

.lb-details {
  background: var(--panel-glass);
  -webkit-backdrop-filter: blur(18px) saturate(1.25);
  backdrop-filter: blur(18px) saturate(1.25);
  border: 1px solid var(--glass-border);
  border-top-color: var(--glass-border-top);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem 1.4rem;
  box-shadow: var(--shadow);
  height: fit-content;
}

.lb-name {
  font-family: Georgia, serif;
  color: var(--gold-bright);
  font-size: 1.35rem;
  margin: 0 0 .1rem;
  display: flex; align-items: center; gap: .5rem;
}
.lb-type { color: var(--ink-dim); margin: 0 0 .7rem; font-style: italic; }

.lb-stats { display: flex; flex-wrap: wrap; gap: .4rem .9rem; margin-bottom: .7rem; }
.lb-stat { color: var(--ink-dim); font-size: .9rem; }
.lb-stat b { color: var(--ink); font-size: 1.05rem; }

.lb-text {
  background: var(--text-block-bg);
  border-left: 3px solid var(--gold);
  padding: .6rem .8rem;
  border-radius: 0 6px 6px 0;
  margin-bottom: .8rem;
  font-size: .95rem;
}
/* Keyword reminder text — italic parentheticals, dimmed like printed cards. */
.lb-text em { color: var(--ink-dim); }

/* Split (melded) cards, e.g. "Arcane Seeds // Life": both halves print on one
   physical card, so both get their own labeled section here regardless of
   viewport — stacked rather than side-by-side keeps oracle text readable at
   any width instead of cramming it into narrow columns. */
.split-card { display: flex; flex-direction: column; }
.split-name {
  font-family: Georgia, serif;
  color: var(--gold);
  font-size: 1rem;
  margin: 0 0 .15rem;
}
.split-divider {
  display: flex; align-items: center; gap: .6rem;
  margin: .1rem 0 .7rem;
  color: var(--ink-dim);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: .8rem;
}
.split-divider::before, .split-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
}

.lb-flavor { color: var(--ink-dim); font-style: italic; font-size: .9rem; margin-bottom: .6rem; }
.lb-artist { color: var(--ink-dim); font-size: .85rem; margin: .2rem 0 .8rem; }

.lb-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: .3rem 0 .4rem; }
.lb-save {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  background: var(--bg-panel);
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .45rem .85rem;
  font: inherit;
  font-size: .88rem;
  font-weight: 600;
  cursor: pointer;
}
.lb-save svg {
  width: 1.1em; height: 1.1em;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round;
}
.lb-save:hover { border-color: var(--gold); color: var(--gold-bright); }
.lb-save.saved { border-color: var(--gold); color: var(--gold-bright); background: var(--hover-tint); }
.lb-save.saved svg { fill: currentColor; }

.lb-h3 {
  font-family: Georgia, serif;
  color: var(--gold);
  font-size: .95rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--line);
  padding-bottom: .25rem;
  margin: 1rem 0 .55rem;
}
.lb-pricenote { text-transform: none; letter-spacing: 0; color: var(--ink-dim); font-size: .75rem; font-family: inherit; float: right; }

.legality-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .3rem .8rem; font-size: .85rem; }
.legality-row { display: flex; align-items: center; gap: .5rem; }
.legality-status {
  width: 5.6em; text-align: center;
  border-radius: 4px; padding: .05em 0;
  font-size: .75rem; font-weight: 600;
  flex: none;
}
.st-L { background: var(--st-l-bg); color: var(--st-l-fg); }
.st-N { background: var(--st-n-bg); color: var(--st-n-fg); }
.st-B { background: var(--st-b-bg); color: var(--st-b-fg); }
.st-S { background: var(--st-s-bg); color: var(--st-s-fg); }
.st-V { background: var(--st-v-bg); color: var(--st-v-fg); }
.st-R { background: var(--st-r-bg); color: var(--st-r-fg); }

.printings { display: flex; flex-direction: column; gap: .35rem; max-height: 300px; overflow: auto; }
.printing-row {
  /* Plain block + width:100% instead of relying on the button stretching as
     a flex item — some engines size a styled <button> to fit its content
     regardless of flex align-items:stretch, which was squeezing this whole
     row down to the width of "FLR013" instead of filling the sheet. Block
     layout has no such ambiguity. */
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  text-align: left;
  background: var(--text-block-bg);
  border: 1px solid var(--line);
  color: var(--ink);
  border-radius: 7px;
  padding: .5rem .6rem;
  cursor: pointer;
  font-size: .85rem;
  font-family: inherit;
}
.printing-row:hover { border-color: var(--gold); }
.printing-row.current { border-color: var(--gold-bright); background: var(--hover-tint); }
.pr-row1 { display: flex; align-items: baseline; gap: .6rem; min-width: 0; margin-bottom: .3rem; }
.pr-set { font-family: ui-monospace, Menlo, Consolas, monospace; color: var(--gold-bright); flex: none; }
.pr-name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600;
}
.pr-row2 { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; min-width: 0; }
.pr-meta {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink-dim); font-size: .78rem;
}
.pr-price-group {
  flex: none;
  font-variant-numeric: tabular-nums;
  color: var(--gold-bright);
  font-weight: 600;
  white-space: nowrap;
}
.pr-foil { color: var(--ink-dim); font-weight: 400; font-size: .78rem; margin-left: .5rem; }

.lb-buy {
  display: inline-block; margin-top: .9rem;
  background: var(--crimson);
  color: #fbeee7;
  border-radius: 7px;
  padding: .5rem .9rem;
  font-weight: 600; font-size: .9rem;
}
.lb-buy:hover { background: var(--crimson-bright); text-decoration: none; }

.lb-close {
  position: fixed; top: .8rem; right: .9rem;
  z-index: 110;
  background: var(--bg-panel);
  color: var(--ink);
  border: 1px solid var(--gold);
  border-radius: 50%;
  width: 2.75rem; height: 2.75rem;
  font-size: 1.2rem;
  cursor: pointer;
  top: calc(.8rem + env(safe-area-inset-top));
  right: calc(.9rem + env(safe-area-inset-right));
}
.lb-nav {
  position: fixed; top: 50%;
  transform: translateY(-50%);
  z-index: 110;
  background: var(--bg-panel);
  color: var(--gold-bright);
  border: 1px solid var(--gold);
  border-radius: 50%;
  width: 2.75rem; height: 2.75rem;
  font-size: 1.15rem;
  cursor: pointer;
}
.lb-nav:disabled { opacity: .3; cursor: default; }
#lb-prev { left: .7rem; }
#lb-next { right: .7rem; }

/* ---------- game symbols ---------- */

.sym {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.25em; height: 1.25em;
  border-radius: 50%;
  font-size: .82em;
  vertical-align: -0.2em;
  font-style: normal;
  border: 1px solid rgba(0,0,0,.45);
  color: #171310;
  margin: 0 .06em;
}
/* Card-stat tokens with real artwork (site/data/res/): pitch, attack, block,
   life, intellect. Sized to match the .sym gradient badges they replace. */
.sym-img {
  display: inline-block;
  width: 1.25em; height: 1.25em;
  vertical-align: -0.28em;
  margin: 0 .06em;
  object-fit: contain;
}
.sym-r { background: radial-gradient(circle at 35% 30%, #fee3b0, #d9a338 70%); }
.sym-p { background: radial-gradient(circle at 35% 30%, #f0a49e, #c03a34 70%); color: #2a0b0a; }
.sym-d { background: radial-gradient(circle at 35% 30%, #cfd8e2, #7d8b9c 70%); }
/* Life is deliberately violet, not red: at a glance it must not be mistaken
   for the red Power symbol (a card-scan complaint from players). */
.sym-h { background: radial-gradient(circle at 35% 30%, #e0c4f2, #8a4fc0 70%); color: #2a1042; }
.sym-i { background: radial-gradient(circle at 35% 30%, #bcd6f0, #4f7fb5 70%); color: #0c1c2e; }
.sym-t, .sym-u { background: radial-gradient(circle at 35% 30%, #e6e0d2, #9c937f 70%); }
.sym-c { background: radial-gradient(circle at 35% 30%, #d8f0d2, #6ba062 70%); }
.sym-x { background: radial-gradient(circle at 35% 30%, #e6e0d2, #9c937f 70%); }

/* ---------- syntax docs page ---------- */

.doc { max-width: 900px; margin: 0 auto; padding: 1rem 1rem 4rem; }
.doc h1 { font-family: Georgia, serif; color: var(--gold-bright); letter-spacing: .03em; }
.doc h2 {
  font-family: Georgia, serif;
  color: var(--gold);
  margin-top: 2.2rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: .3rem;
}
.doc p { color: var(--ink); }
.doc .lead { color: var(--ink-dim); font-size: 1.05rem; }

.doc-table { width: 100%; border-collapse: collapse; margin: .8rem 0; font-size: .92rem; }
.doc-table th {
  text-align: left; color: var(--gold);
  border-bottom: 1px solid var(--gold);
  padding: .4rem .6rem;
  font-weight: 600;
}
.doc-table td { border-bottom: 1px solid var(--line); padding: .45rem .6rem; vertical-align: top; }
.doc-table td:first-child { white-space: nowrap; }

.example-block {
  display: flex; flex-wrap: wrap; gap: .5rem; margin: .6rem 0 1rem;
}
a.example {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  background: var(--bg-input);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .35rem .7rem;
  font-size: .88rem;
  color: var(--gold-bright);
}
a.example:hover { border-color: var(--gold); text-decoration: none; }

/* ---------- footer ---------- */

.site-footer {
  border-top: 1px solid var(--line);
  color: var(--faint);
  font-size: .8rem;
  text-align: center;
  padding: 1.4rem 1rem calc(2rem + env(safe-area-inset-bottom));
  margin-top: 2rem;
}
.site-footer a { color: var(--ink-dim); }

/* ---------- mobile ---------- */

@media (max-width: 860px) {
  /* Full-screen bottom-sheet layout: the image is pinned at the top and
     everything else (stats, oracle text, legality, printings & prices)
     lives in a single scrollable region below it. The old layout let
     .lb-panel and the nested .printings list both scroll independently,
     which on iOS Safari captures touch input in the inner list and makes
     the rest of the sheet (including prices) effectively unreachable. */
  .lightbox { padding: 0; }
  .lb-panel {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    max-width: none;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    margin: 0;
    padding: 0;
    overflow: hidden;
  }
  #lb-image-wrap {
    flex: 0 0 auto;
    align-items: center;
    height: 56vh;
    height: 56dvh;
    overflow: hidden;
    padding: calc(.7rem + env(safe-area-inset-top)) .8rem .6rem;
  }
  #lb-image { width: auto; max-width: 100%; max-height: 100%; }
  .lb-noimg { width: auto; height: 100%; }
  .lb-details {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    border-radius: 18px 18px 0 0;
    padding: 1rem 1rem calc(1.7rem + env(safe-area-inset-bottom));
  }
  /* Let printings flow with the rest of the sheet instead of scrolling
     in their own nested box, so prices are always reachable by continuing
     the same scroll gesture. */
  .printings { max-height: none; overflow: visible; }
  .lb-nav { top: auto; bottom: calc(1rem + env(safe-area-inset-bottom)); }
}

@media (max-width: 900px) {
  .qr-grid { grid-template-columns: 1fr 1fr; gap: .8rem 0; }
  /* Two columns: the divider follows, and rows past the first gain a rule of
     their own so the compartments stay legible. */
  .qr-group:not(:nth-child(4n + 1))::before { content: none; }
  .qr-group:not(:nth-child(2n + 1))::before {
    content: "";
    position: absolute;
    left: 0;
    top: .2rem;
    bottom: .2rem;
    width: 1px;
    background: linear-gradient(180deg, transparent, var(--frost-rule) 16%, var(--frost-rule) 84%, transparent);
  }
}

@media (max-width: 640px) {
  .site-header {
    padding: .5rem .6rem;
    padding-top: calc(.5rem + env(safe-area-inset-top));
    padding-left: calc(.6rem + env(safe-area-inset-left));
    padding-right: calc(.6rem + env(safe-area-inset-right));
    gap: .5rem;
  }
  .qr-grid { grid-template-columns: 1fr; gap: 0; }
  /* Single column: the hairlines lie down and become horizontal rules. */
  .qr-group::before { content: none !important; }
  .qr-group + .qr-group {
    margin-top: .7rem;
    padding-top: .7rem;
    border-top: 1px solid var(--frost-rule);
  }
  .qr-foot { gap: .4rem .9rem; }
  .adv-grid { grid-template-columns: 1fr; }
  .adv-stats { grid-template-columns: 1fr 1fr; }
  .adv-actions { width: 100%; }
  .adv-submit { flex: 1; }
  .brand { font-size: 1.1rem; }
  .header-nav { gap: .7rem; font-size: .85rem; }
  /* Nav is tight once the search bar wraps to its own row, so every pill
     matches the theme toggle's footprint. */
  .patreon-label { display: none; }
  .discord-link,
  .bsky-link,
  .patreon-link,
  .header-nav .kofi-slot a.kofi-button {
    padding: 0 .5rem !important;
    gap: 0;
  }
  .search-wrap { order: 3; flex-basis: 100%; max-width: none; }
  .results-grid { gap: .9rem .7rem; }
  .card-bar { font-size: .8rem; }
  .saved-actions { margin-left: 0; }
  .printing-row { padding: .6rem .7rem; min-height: 44px; }
  .lb-h3 { margin-top: 1.3rem; }
  main { padding: .6rem; }
  .legality-grid { grid-template-columns: 1fr; }
  /* main already provides the edge inset; home-hero's own horizontal padding
     would double it up, making the hero (search bar, quick reference) sit
     noticeably narrower than the results grid below it. */
  .home-hero { padding-left: 0; padding-right: 0; }
}
