/* Catalogo di ARCI Biblioteca di Sarajevo — stylesheet.

   Two constraints shape everything here:
   1. The site must run from file:// with no build step, so the serif is
      self-hosted rather than pulled from a CDN.
   2. Only about a third of the books will ever have a cover image. A grid
      that treats the cover as the main event would read as broken most of
      the time, so the coverless card is designed as the default and the
      photographed cover as the happy accident. */

@font-face {
  font-family: 'Cormorant Garamond';
  src: url('../fonts/cormorant-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url('../fonts/cormorant-latin-ext.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

:root {
  --serif: 'Cormorant Garamond', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --paper: #fbfaf7;
  --surface: #ffffff;
  --ink: #1c1a17;
  --muted: #6b6459;
  --faint: #786f62;   /* 4.74:1 on --paper; these labels are 11px so they need the full 4.5 */
  --rule: #e3ded2;
  --rule-strong: #cdc6b6;
  --accent: #8c2f26;
  --accent-tint: #f6eeec;
  --shadow: 0 1px 2px rgba(28, 26, 23, .05), 0 6px 16px -8px rgba(28, 26, 23, .12);

  --gap: 1.25rem;
  --radius: 3px;
  --z-modal: 50;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #161513;
    --surface: #1e1c19;
    --ink: #ece7dd;
    --muted: #9c9488;
    --faint: #8a8375;   /* 4.85:1 on dark --paper */
    --rule: #302d28;
    --rule-strong: #423e37;
    --accent: #d98a7e;
    --accent-tint: #2a201e;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 16px -8px rgba(0, 0, 0, .6);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 16px/1.6 var(--sans);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ---------- chrome ---------- */

.topbar {
  display: flex;
  align-items: baseline;
  gap: var(--gap);
  padding: 1.5rem var(--gap) 1rem;
  border-bottom: 1px solid var(--rule);
}
.topbar h1 {
  font: 500 1.9rem/1.1 var(--serif);
  letter-spacing: .01em;
  margin: 0;
}
.topbar nav { margin-left: auto; }
.topbar nav a {
  font-size: .875rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
  padding-bottom: 1px;
  transition: color .18s ease, border-color .18s ease;
}
.topbar nav a:hover { color: var(--accent); border-color: var(--accent); }

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  align-items: center;
  padding: .85rem var(--gap);
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
  position: sticky;
  top: 0;
  z-index: 20;
}

input[type=search], input[type=number], select, button {
  font: inherit;
  font-size: .875rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  padding: .45rem .6rem;
  transition: border-color .18s ease, background-color .18s ease;
}
input[type=search]:hover, select:hover, button:hover { border-color: var(--muted); }
button { cursor: pointer; }
button:hover { background: var(--accent-tint); }

.toolbar input[type=search] { flex: 1 1 20rem; min-width: 12rem; }
.toolbar label { font-size: .8rem; color: var(--muted); display: flex; align-items: center; gap: .4rem; }
.count {
  margin-left: auto;
  font-size: .8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.layout {
  display: grid;
  grid-template-columns: 15rem 1fr;
  gap: 2rem;
  padding: var(--gap);
  max-width: 96rem;
  margin: 0 auto;
}

/* ---------- filters ---------- */

.filters {
  display: flex;
  flex-direction: column;
  gap: .9rem;
  align-self: start;
  position: sticky;
  top: 4.2rem;
  max-height: calc(100vh - 5.5rem);
  overflow-y: auto;
  padding-right: .4rem;
}
.facet { border-bottom: 1px solid var(--rule); padding-bottom: .9rem; }
.facet:last-child { border-bottom: 0; }

.facet > summary {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--faint);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .2rem 0;
  transition: color .15s ease;
}
.facet > summary::-webkit-details-marker { display: none; }
.facet > summary::after {
  content: '';
  width: .4rem;
  height: .4rem;
  margin-left: auto;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform .18s ease;
}
.facet[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.facet > summary:hover { color: var(--accent); }
.facet-tally {
  font-size: .62rem;
  min-width: 1.05rem;
  height: 1.05rem;
  padding: 0 .3rem;
  display: inline-grid;
  place-items: center;
  border-radius: 99px;
  background: var(--accent);
  color: var(--surface);
  letter-spacing: 0;
}

/* No inner scrollbar: the sidebar is the only scroll container. Long lists
   are shortened by the "mostra tutti" button instead. */
.facet-list {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  padding-top: .45rem;
}
.facet-more {
  margin-top: .4rem;
  padding: .2rem .45rem;
  font-size: .72rem;
  color: var(--muted);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
}
.facet-more:hover { color: var(--accent); border-color: var(--accent); background: none; }
.facet-flat { padding-top: .2rem; }
.facet label {
  display: flex;
  align-items: baseline;
  gap: .45rem;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--ink);
  cursor: pointer;
  padding: .12rem .25rem;
  margin-left: -.25rem;
  border-radius: 2px;
  transition: background-color .15s ease;
}
.facet label:hover { background: var(--accent-tint); }
.facet input[type=checkbox] { accent-color: var(--accent); cursor: pointer; flex: none; }
.facet-search { width: 100%; margin: .5rem 0 .1rem; padding: .3rem .45rem; font-size: .8rem; }
.range { display: flex; align-items: center; gap: .5rem; font-size: .8rem; color: var(--muted); margin-bottom: .3rem; }
.range input { width: 100%; padding: .3rem .45rem; font-size: .8rem; }

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

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: 1.75rem 1.25rem;
  align-content: start;
}

.card { cursor: pointer; }
.card h3 {
  font: 500 1.02rem/1.25 var(--serif);
  margin: .55rem 0 .15rem;
  color: var(--ink);
}
.card .meta {
  font-size: .76rem;
  line-height: 1.4;
  color: var(--muted);
  margin: 0;
}

/* The cover slot. A real image and a generated stand-in share these
   dimensions so the grid never reflows depending on what was found. */
.cover {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  display: block;
  border-radius: 2px;
  background: var(--surface);
  box-shadow: var(--shadow);
  transition: transform .2s ease, box-shadow .2s ease;
}
.card:hover .cover,
.card:focus-visible .cover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(28, 26, 23, .08), 0 12px 22px -10px rgba(28, 26, 23, .25);
}

/* The coverless card: a bound spine rather than an empty box. Hue comes from
   the shelf, so a shelf reads as a colour family while you scroll. */
.cover.placeholder {
  --hue: 30;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: .3rem;
  padding: .7rem .7rem .8rem 1.05rem;
  overflow: hidden;
  position: relative;
  background:
    linear-gradient(180deg,
      hsl(var(--hue) 22% 90%) 0%,
      hsl(var(--hue) 20% 85%) 100%);
  border: 1px solid hsl(var(--hue) 18% 78%);
}
.cover.placeholder::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: .42rem;
  background: hsl(var(--hue) 30% 62%);
  box-shadow: inset -1px 0 0 hsl(var(--hue) 25% 55%);
}
.cover.placeholder .ph-title {
  font: 600 .84rem/1.25 var(--serif);
  color: hsl(var(--hue) 45% 22%);
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cover.placeholder .ph-author {
  font-size: .64rem;
  line-height: 1.3;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: hsl(var(--hue) 25% 40%);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

@media (prefers-color-scheme: dark) {
  .cover.placeholder {
    background: linear-gradient(180deg,
      hsl(var(--hue) 14% 22%) 0%,
      hsl(var(--hue) 13% 17%) 100%);
    border-color: hsl(var(--hue) 12% 30%);
  }
  .cover.placeholder::before { background: hsl(var(--hue) 22% 42%); box-shadow: none; }
  .cover.placeholder .ph-title { color: hsl(var(--hue) 30% 84%); }
  .cover.placeholder .ph-author { color: hsl(var(--hue) 18% 62%); }
}

.badge {
  display: inline-block;
  font-size: .64rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: .1rem .4rem;
  margin-top: .35rem;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  color: var(--muted);
}

/* ---------- list view ---------- */

.list { display: flex; flex-direction: column; }
.list .card {
  display: grid;
  grid-template-columns: 2.4rem 1fr auto;
  gap: 1rem;
  align-items: center;
  padding: .6rem .5rem;
  margin: 0 -.5rem;
  border-bottom: 1px solid var(--rule);
  border-radius: 2px;
  transition: background-color .15s ease;
}
.list .card:hover { background: var(--surface); }
.list .cover { width: 2.4rem; box-shadow: none; }
.list .card:hover .cover { transform: none; box-shadow: none; }
.list .cover.placeholder { padding: 0; }
.list .cover.placeholder .ph-title,
.list .cover.placeholder .ph-author { display: none; }
.list .card h3 { margin: 0; font-size: .95rem; }
.list .card .meta { grid-column: 2; }
.list .badge { margin: 0; }

.empty { color: var(--muted); font-style: italic; padding: 2rem 0; }

/* ---------- modal ---------- */

.modal { position: fixed; inset: 0; display: grid; place-items: center; z-index: var(--z-modal); padding: 1rem; }
/* `display: grid` beats the `hidden` attribute's own `display: none`, so
   without this the closed modal's backdrop covers the page and swallows every
   click. Must stay ahead of any later rule that sets .modal's display. */
.modal[hidden] { display: none; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(24, 22, 19, .5); backdrop-filter: blur(2px); }
.modal-body {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  max-width: 42rem;
  width: 100%;
  max-height: 86vh;
  overflow-y: auto;
  padding: 2rem 2.25rem 2.25rem;
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .45);
}
.modal-body h2 {
  font: 500 1.75rem/1.2 var(--serif);
  margin: 0 0 1.25rem;
  padding-right: 2rem;
  max-width: 28ch;
}
.modal-body .cover { width: 8.5rem; float: right; margin: .2rem 0 1rem 1.5rem; box-shadow: var(--shadow); }
.modal-body .cover:hover { transform: none; }
.modal-body .description {
  font-size: .92rem;
  line-height: 1.65;
  color: var(--ink);
  margin: 0 0 1.5rem;
  max-width: 62ch;
}
.modal-close {
  position: absolute;
  top: .75rem;
  right: .75rem;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--muted);
  background: none;
  border: 0;
  border-radius: 50%;
}
.modal-close:hover { background: var(--accent-tint); color: var(--accent); }
.modal-body dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: .45rem 1.25rem;
  margin: 0;
  clear: both;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}
.modal-body dt {
  color: var(--faint);
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  padding-top: .18rem;
}
.modal-body dd { margin: 0; font-size: .9rem; }
body.modal-open { overflow: hidden; }

/* ---------- statistics ---------- */

.stats {
  padding: 2rem var(--gap) 4rem;
  display: flex;
  flex-direction: column;
  gap: 2.75rem;
  max-width: 52rem;
  margin: 0 auto;
}
.stats h2 {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--faint);
  margin: 0 0 .9rem;
  font-weight: 600;
}
.summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: 1rem; }
.summary div {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 1.1rem 1rem;
}
.summary strong {
  display: block;
  font: 500 2rem/1 var(--serif);
  font-variant-numeric: tabular-nums;
  margin-bottom: .3rem;
}
.summary span { color: var(--muted); font-size: .78rem; }

.bar-row {
  display: grid;
  grid-template-columns: 11rem 1fr 3rem;
  gap: .75rem;
  align-items: center;
  font-size: .82rem;
  padding: .18rem 0;
}
.bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
.bar-track { background: var(--rule); height: .55rem; border-radius: 99px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--accent); border-radius: 99px; }
.bar-count { text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- responsive ---------- */

@media (max-width: 800px) {
  .layout { grid-template-columns: 1fr; gap: 1.25rem; }
  .filters { position: static; max-height: none; overflow: visible; }
  .facet-list { max-height: 11rem; }
  .topbar { padding: 1rem var(--gap) .85rem; }
  .topbar h1 { font-size: 1.5rem; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr)); gap: 1.25rem .9rem; }
  .modal-body { padding: 1.5rem 1.25rem; }
  .bar-row { grid-template-columns: 7rem 1fr 2.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
  .card:hover .cover, .card:focus-visible .cover { transform: none; }
}
