/* Библиотека Эммы — каталог и разворот для чтения.

   Reference lock: this file EXTENDS `styles.css`'s existing lock (Symbolic paper layers +
   Waka Waka page artifact + Anthropic editorial metadata) rather than opening a second visual
   language. The sheet on the dark field, the serif/Onest pairing, the mono metadata line and
   the red used only as punctuation all come from there and are not restated.

   Two narrow borrowings, each with a bounded job (Refero research, 2026-08-28):

   - Monocle (monocle.com) owns the CATALOGUE STRUCTURE only: a persistent category
     navigation above the grid, the "category label + read time" meta line over a
     tight-tracked headline, and depth from a background shift rather than a shadow. Its
     accent DISCIPLINE is adopted ("reserve the accent for interactive states"); its accent
     VALUES are not -- yellow and sky blue stay at Monocle, ours stays `--red`.
   - Alison Roman (alisoneroman.com) owns the READING PAGE rhythm only: a generous section
     gap, 0px radius on content blocks, hairline rules between passages, and a refusal to make
     the column dense. Its parchment canvas is deliberately NOT taken: this site's signature is
     a bright sheet floating on `--canvas` #202020, and swapping that for cream would collapse
     the direction into the warm-ivory default.

   Rejected on purpose: card shadows and rounded SaaS cards, a second accent colour, the
   landing hero's tilt (a signature move; repeating it 15 times spends it), and decorative
   serif/italic word swaps inside headlines. */

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

.lib-back {
  justify-self: start;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  text-decoration: none;
}
/* Hover and focus marks for every label link on this page live in `styles.css`, in one
   grouped rule -- the site has one such mark, not one per surface. */

/* --- catalogue -------------------------------------------------------------------------- */

/* No horizontal padding of its own: `.wrap` already centres it at `--content-width`, which is
   exactly what `.bar-inner` does above, so the first crumb starts on the same vertical line as
   the ЭММА wordmark. Adding the gutter here pushed the whole row one gutter to the right, which
   is what the owner saw. */
/* No rule of its own under this row. The masthead above already draws one, and two hairlines a
   few lines apart read as a mistake rather than as structure -- the owner's call, 2026-08-29.
   The `padding-bottom: .9rem` that used to sit here went with it: the `padding` shorthand three
   lines below had been silently resetting it to 0 since this row was written, so the border was
   sitting flush against the text anyway. */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: .6rem 1.5rem;
  padding: 1.4rem 0 0;
  margin-inline: auto;
  color: var(--muted);
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .07em;
  text-transform: uppercase;
}
.crumbs a { text-decoration: none; }
.crumbs span[aria-current] { color: var(--ink); }
.crumbs-meta { color: var(--muted); white-space: nowrap; }

@media (max-width: 760px) {
  .crumbs { padding-inline: var(--gutter); }
}

/* Taken out of the layout, not out of the document: the page keeps exactly one `h1` for a
   crawler and a screen reader while the visible identity is carried by the wordmark and the
   breadcrumb. `clip-path` rather than `display:none`, which would hide it from both. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Kept for the 404 page, which still has a headline to set. */
/* Headline left, standfirst right and set on the headline's last baseline -- the masthead
   arrangement the landing already uses for its own section heads. The top padding is small on
   purpose: the breadcrumb row above is part of this block, not a separate band, and `section`'s
   own clamp() left a hole between them. */
.lib-intro {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  align-items: end;
  column-gap: clamp(1.5rem, 4vw, 3.5rem);
  padding-top: 1.6rem;
  padding-bottom: 2.4rem;
}
.lib-intro h1 {
  max-width: 20ch;
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(2.2rem, 5vw, 3.9rem);
  font-weight: 400;
  letter-spacing: -.045em;
  line-height: .98;
  text-wrap: balance;
}
.lib-lead {
  max-width: 34ch;
  margin: 0 0 .5rem;
  color: var(--muted);
  font-size: .86rem;
  line-height: 1.5;
  text-wrap: pretty;
}

@media (max-width: 760px) {
  .lib-intro { grid-template-columns: minmax(0, 1fr); row-gap: 1.1rem; }
  .lib-lead { margin-bottom: 0; }
}

/* No rule under the masthead on these pages.
   Owner, 2026-08-29: «тут два подчеркивания!!! нам зачем два? верхнее убери». On the library the
   bar's hairline lands a few pixels above the subsection strip and its red mark, so two
   horizontal lines stack in one small band and the upper one reads as underlining the
   navigation rather than closing the masthead. The landing keeps its rule: nothing sits under
   the bar there to double it. Scoped by this sheet, which only these pages load. */
.bar { border-bottom: 0; }

/* The subsection strip sits above the materials, where the owner put it back after seeing it
   at the foot: at the top it reads as one line of navigation, at the bottom it became three
   large boxes competing with the materials themselves.
   Each entry is its own page (ADR-040's three subsections), so this is a nav rather than a
   filter — which is why the current one stays in it and is marked, instead of being dropped the
   way a "where to next" list would drop it. A subsection with nothing in it still appears:
   two of them ship declared-empty and hiding them would be a quieter claim than the truth. */
/* The strip now rides on the breadcrumb row, right-aligned against it: one line that says
   where you are on the left and where else you can go on the right, instead of two bands of
   small uppercase type stacked with a rule between them. */
.lib-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: .4rem 1.3rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.lib-tab {
  display: inline-flex;
  align-items: baseline;
  gap: .35rem;
  color: var(--muted);
  text-decoration: none;
}
/* The typewriter face, which is what this sheet already uses for every label and every piece
   of metadata — the edition line, the section label, the reading time. The strip is a row of
   labels, so it belongs to that family rather than to the sans the running text uses. */
.lib-tab b {
  font-family: var(--mono);
  font-size: .64rem;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink);
}
.lib-tab i {
  font-family: var(--mono);
  font-size: .62rem;
  font-style: normal;
  letter-spacing: .07em;
}
/* The line marks the label and nothing else. It is drawn as a border on `b` rather than as
   `text-decoration`, because decoration set anywhere on the link propagates to every inline
   child: the count in `i` was picking it up, and the flex `gap` between them stayed unpainted,
   so one word read as "line, gap, line". A border cannot escape the element it is on.

   The reserved transparent border keeps the row from shifting a pixel on hover, and the two
   states differ only in how much of `--red` shows through -- hovering is a hint, being here is
   a statement. */
/* Both marker states live in `styles.css` with every other link mark on the site. */
.lib-tab i { font-size: .58rem; }

.lib-body { padding-top: 2rem; padding-bottom: clamp(2.6rem, 6vw, 4.4rem); }

.lib-section + .lib-section { margin-top: 3.4rem; }
.lib-section > h2 {
  max-width: none;
  margin: 0 0 1.4rem;
  font-size: 1.05rem;
  font-family: var(--sans);
  letter-spacing: .01em;
}

/* Two per row, stated rather than derived: at the landing's width two cards are the size worth
   clicking, and `auto-fit` would quietly become three if the sheet ever widened again. */
.lib-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.8rem 1.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* CORRECTION, 2026-08-28: this block first said "flat by instruction", taking that from Monocle
   and Waka Waka, both of which build depth from surface change rather than elevation. That was
   the wrong authority. This site already casts a soft warm shadow on every card it has —
   `rgba(111, 104, 72, α)` on `.story-card-wide`, `.story-card-accent`, the quote panel and two
   more — and its own language outranks a reference brought in from outside. The owner caught it.
   The shadow below is `.story-card-wide`'s, unchanged, so a library card and a landing card sit
   at the same height.

   The hover treatment is a third, owner-supplied reference — смыслокод, the owner's own site,
   shown as the target the same day: the whole card takes an accent outline, the headline turns
   accent, and the cover scales a little inside a frame that does not move. Adopted as behaviour,
   not as palette: смыслокод is dark with an orange accent, this sheet stays paper with `--red`. */
.lib-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: .6rem;
  background: var(--paper-bright);
  box-shadow: 0 5px 16px rgba(111, 104, 72, .13);
  text-decoration: none;
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
/* The cover runs edge to edge and the card clips it, so the artwork carries the card's own
   corner rather than floating inside a frame with a second radius of its own. Only the words
   are inset. */
.lib-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: .55rem;
  padding: .95rem 1.05rem 1.15rem;
}
.story-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .7rem;
}
.story-views {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: .28rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .07em;
  line-height: 1;
}
.story-views svg {
  width: .9rem;
  height: .9rem;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.55;
}
.lib-summary { color: var(--muted); font-size: .84rem; line-height: 1.45; }
.lib-card:hover,
.lib-card:focus-visible {
  border-color: var(--red);
  box-shadow: 0 9px 24px rgba(111, 104, 72, .18);
  transform: translateY(-2px);
}
.lib-card:hover h3,
.lib-card:focus-visible h3 { color: var(--red); }
.lib-card:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }

/* The frame is what holds the 16:9 box and clips the zoom; the image scales inside it. */
.lib-shot {
  display: block;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  width: 100%;
}

.lib-cover {
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
  transition: transform .4s ease;
}
.lib-card:hover .lib-cover,
.lib-card:focus-visible .lib-cover { transform: scale(1.045); }
/* No cover yet: the slot keeps its size and says so, rather than collapsing the grid or
   faking an illustration with a gradient. */
.lib-cover-empty {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background: var(--paper-muted);
  color: var(--muted);
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.lib-card h3 {
  margin: 0;
  font-size: 1.24rem;
  letter-spacing: -.025em;
  line-height: 1.1;
  text-wrap: balance;
  transition: color .2s ease;
}
.lib-card .lib-more { display: block; margin-top: auto; padding-top: .8rem; font-size: .72rem; }
.lib-card .lib-more span { margin-left: .4rem; }

.lib-all { margin: 1.8rem 0 0; font-size: .82rem; }
.lib-all a { text-decoration: none; }
.lib-all span { margin-left: .4rem; }

.lib-intro .section-label a { text-decoration: none; }

.lib-empty {
  margin: 0;
  padding: 1.6rem;
  border: 1px dashed var(--line);
  color: var(--muted);
  font-size: .86rem;
}

/* --- the reading page ------------------------------------------------------------------- */

.read { padding-top: 2rem; }

.read-head { margin-bottom: 1.7rem; }
.read-folio { margin: 0 0 1.5rem; }
.read-head h1 {
  margin: .9rem 0 1.1rem;
  font-family: var(--serif);
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  font-weight: 400;
  letter-spacing: -.04em;
  line-height: 1.02;
  text-wrap: balance;
}
.read-standfirst {
  margin: 0;
  color: var(--muted);
  font-size: 1.02rem;
  line-height: 1.5;
  text-wrap: pretty;
}

/* ADR-096 — кто написал и когда.

   Новая часть страницы, собранная из устройств §2–§3 замороженного языка, а не из новых: та же
   мелкая моноширинная строка в `--muted`, что у `.crumbs-meta` несколькими блоками выше, тот же
   разделитель «·», та же полутоновая красная отметка ссылки (Поправка 5). Ни одного нового
   цвета, размера или радиуса — заморозка защищает то, как портал выглядит, а не запрещает ему
   иметь подпись автора, которой требует ЭПОС Вебмастера от тем здоровья.

   `flex-wrap` здесь не украшение: имя и квалификация вместе длиннее узкого экрана, и без
   переноса строка вытолкнула бы страницу в горизонтальную прокрутку. */
.read-byline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem;
  margin: 1rem 0 0;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.read-byline > * + *::before {
  content: "·";
  margin-right: .5rem;
  color: var(--line);
}
.byline-who {
  color: var(--ink);
  border-bottom: 1px solid transparent;
}
.byline-who:hover,
.byline-who:focus-visible { border-bottom-color: var(--mark); }
.byline-what,
.byline-when { color: var(--muted); }

/* `height: auto` is load-bearing, not tidiness. `styles.css` sets only `img { max-width: 100% }`,
   so without it the browser keeps the intrinsic height from the `height` attribute while the
   width shrinks to the column: the box ends up taller than 16:9 and the SVG letterboxes itself
   inside it, painting paper-coloured bands above and below the artwork. That is what the owner
   saw. `aspect-ratio` states the shape explicitly so the row cannot collapse before the file
   loads either.

   The radius is the sheet's own language — `.paper-shell` is 2.4rem, the landing's story cards
   rather than Alison Roman's flat 0px, which the reference lock borrowed for the prose rhythm
   and not for the imagery.
   Tightened on 2026-08-29 on the owner's instruction ("в библиотеке скругления бы сделал
   меньшего размера"): 1.4rem -> .7rem here and 1.2rem -> .6rem on the catalogue card. The two
   move together and keep their old ratio, so the reading cover stays a shade rounder than the
   card it was opened from. */
.read-cover {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  margin-bottom: 2rem;
  border: 1px solid var(--line);
  border-radius: .7rem;
  object-fit: cover;
}

/* Prose is serif because the landing already reserves serif for anything meant to be read
   rather than scanned.

   The measure was 34rem -- Alison Roman's, and the typographically conventional ~65 characters.
   The owner asked on 2026-08-29 for the text to run the full page, headings included, and that
   set it to the shared `--content-width`, 62rem -- past 100 characters a line, longer than a
   reader's eye returns comfortably.

   Narrowed to a named midpoint, 2026-09-08, after the font and leading fixes alone didn't read
   as "beautiful": measured live at 62rem, the article's line was still ~99 characters, unchanged
   by either fix. The owner chose an intermediate value over both "back to 34rem" and "leave it"
   when asked directly. 48rem is the arithmetic midpoint of 34 and 62, and measures to ~75-77
   characters at this size -- the upper edge of the conventional range rather than its centre,
   which is what "intermediate" means applied to a line-length judgement.

   Scoped to `.read.wrap` rather than lowering the shared `--content-width`: that token also
   sizes the footer, every landing section, and the cabinet page, none of which the owner's
   instruction was about. Overriding the custom property on this selector changes only what
   `.wrap`'s own rule computes for an element matching both classes -- headings, standfirst and
   body narrow together, nothing outside the article does. */
.read.wrap { --content-width: 48rem; }
/* Leading raised 1.38 -> 1.6 on the owner's instruction, 2026-09-07 ("почему у меня статьи на
   нашем лендинге смотрятся ужасно"). 1.38 is display leading; running prose wants 1.5-1.7. It
   matters more here than it would elsewhere because of the measure fixed directly above: the
   longer the line, the more vertical air the eye needs to find the start of the next one, and at
   62rem this column had the site's longest line running at its tightest step. Paragraph spacing
   stays at .85rem -- with the taller line box a paragraph break is still 1.5x a line gap, which
   keeps paragraphs reading as separate blocks. */
/* Prose is `--sans`, not `--serif`, from 2026-09-08 — the owner chose it after seeing the same
   article set in four faces side by side: «Onest и с карточками вот теперь статья стала красивой».

   This settles a contradiction that had been sitting in the documents unnoticed:
   `PORTAL_VISUAL_LANGUAGE.md` §3 device 5 says "Running text is `--sans`; headings are `--serif`",
   while the comment above said prose is serif "because the landing reserves serif for anything
   meant to be read". Both were in force and they disagreed. The owner's choice resolves it the
   way §3 already had, so the library now matches the rest of the site instead of arguing with it.

   What made the old setting feel foreign was never the serif idea — it was that `--serif` is a
   system stack whose first name, Iowan Old Style, is an Apple font that cannot be served, so the
   reader got Palatino on Windows and something else everywhere else. Nobody chose it. `--sans` is
   Onest, vendored in `assets/fonts/` since Amendment 10 and identical on every device.

   Headings stay serif and must say so explicitly: they sit inside `.read-body` and would
   otherwise inherit the sans set here. The owner was exact about this — «поменял шрифт не
   заголовков, а основного текста». */
.read-body {
  font-family: var(--sans);
  font-size: 1.06rem;
  line-height: 1.6;
}
.read-body p { margin: 0 0 .85rem; text-wrap: pretty; }
.read-body h2,
.read-body h3,
.read-body h4 {
  max-width: none;
  margin: 2.1rem 0 .7rem;
  padding-top: .95rem;
  border-top: 1px solid var(--line);
  font-family: var(--serif);
  font-size: 1.5rem;
  letter-spacing: -.03em;
  line-height: 1.14;
}
.read-body h3 { font-size: 1.24rem; }
.read-body h4 { font-size: 1.08rem; border-top: 0; padding-top: 0; margin-top: 2rem; }
.read-body ul,
.read-body ol { margin: 0 0 .85rem; padding-left: 1.2rem; }
.read-body li { margin-bottom: .3rem; }
.read-body blockquote {
  margin: 1.5rem 0;
  padding: 0 0 0 1.1rem;
  border-left: 2px solid var(--red);
  color: var(--muted);
  font-style: italic;
}
.read-body a { text-underline-offset: .2em; }
.read-body a:hover,
.read-body a:focus-visible { text-decoration-thickness: 2px; }

/* A card lifts one passage out of the flow: a checklist the reader is meant to run, or a warning
   they must not scroll past. Added 2026-09-08 on the owner's instruction after the comparison
   page — «побольше карточек».

   Nothing here is a new visual idea. The shape is the torn corner of §3.3, at the same radius
   pair the landing's `.story-card-accent` and `#kak .hit` already use; the ground is
   `--paper-muted`, the recessed tone the palette already defines; the shadow is the warm
   `rgba(111, 104, 72, α)` the freeze names as a device; the label is `--mono`, uppercase and
   letter-spaced, which §3.5 assigns to section labels. A card is those four existing pieces put
   together for a passage, not a new surface.

   Deliberately no border and no red fill: the ground and the corner already separate it, and
   `--red` is punctuation here (the label) rather than an area — §3.4. */
.read-card {
  margin: 1.7rem 0;
  padding: 1.15rem 1.35rem 1.25rem;
  border-radius: 1.1rem .4rem 1.1rem .4rem;
  background: var(--paper-muted);
  box-shadow: 0 4px 14px rgba(111, 104, 72, .11);
}
.read-card-label {
  margin: 0 0 .55rem;
  color: var(--red);
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.read-card > :last-child { margin-bottom: 0; }
.read-card ul,
.read-card ol { padding-left: 1.1rem; }

.read-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  margin-top: 2.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--ink);
}
.read-foot p { max-width: 24ch; margin: 0; color: var(--muted); font-size: .86rem; }

/* --- narrow screens --------------------------------------------------------------------- */

@media (max-width: 760px) {
  .lib-grid { grid-template-columns: minmax(0, 1fr); }
  .lib-tabs { gap: 1rem 1.2rem; }
  .read-body { font-size: 1.05rem; }
}

/* A zoom is decoration; a reader who has asked the system not to animate gets the card without
   it, and every other rule above still applies. */
@media (prefers-reduced-motion: reduce) {
  .lib-card,
  .lib-cover,
  .lib-card h3 { transition: none; }
  .lib-card:hover,
  .lib-card:focus-visible { transform: none; }
  .lib-card:hover .lib-cover,
  .lib-card:focus-visible .lib-cover { transform: none; }
}

.lib-pages {
  display: flex;
  gap: 1.4rem;
  align-items: baseline;
  margin-top: 2.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line);
  font-size: .8rem;
}
.lib-pages a { text-decoration: none; }
.lib-pages .lib-pages-at { margin-left: auto; color: var(--muted); font-family: var(--mono); font-size: .64rem; letter-spacing: .07em; text-transform: uppercase; }
