/* ==========================================================================
   ARTICLE — content blocks inside an article body
   ==========================================================================
   These are not page blocks. Page blocks (ANALYSIS §4) are sections an
   editor arranges; these are things an editor drops *into* running text —
   an image, a gallery, a quote, a table. They share the article's reading
   measure unless they explicitly break out of it.
   ========================================================================== */

/* --------------------------------------------------------------------
   Flow — a reading column that lets media break out of the measure.
   Three tracks: gutter · measure · gutter. Text sits in the middle one.
   Plain `.prose` is untouched, so the text page and docs viewer keep
   their simple centred column.

   Two levels of breakout, because "wider than the text" and "as wide as
   the page" are different needs. A table read at the full width of a
   cover photo makes the eye travel further between a row's first and
   last cell than it does across a whole paragraph — the extra width
   costs more than it gives. Photography is the opposite: it earns every
   pixel.
   -------------------------------------------------------------------- */
.prose--flow {
  display: grid;
  grid-template-columns: 1fr min(var(--measure), 100%) 1fr;
  max-width: none;
}

.prose--flow > * {
  grid-column: 2;
}

.prose--flow > .is-wide,
.prose--flow > .is-full {
  grid-column: 1 / -1;
  margin-block: var(--space-8);
}

/* A body part is a CHILD of this grid, never a grid of its own.

   The parts first shipped carrying their own `.prose--flow` wrapper, so
   that one could be dropped anywhere. Then the platform's block editor
   arrived and emits them INSIDE the page's prose flow — a grid inside a
   grid, and the inner one has already been handed exactly the measure, so
   its gutters compute to `0px 624px 0px` and `is-full` has nowhere to
   break out to. Every part rendered at the reading width, silently.

   So the wrapper went and the container supplies the flow: the article
   body already does (`<div class="prose prose--flow">`), and a page that
   composes parts by hand says so once around the run. The rhythm goes back
   to `.prose > * + *`, which is where it was before the wrapper existed. */

/* Wide — past the measure, nowhere near the edges. Tables, and anything
   else that is read rather than looked at. */
.prose--flow > .is-wide {
  /* `width: 100%` for the same reason `.container` needs it: auto inline
     margins on a grid item drop it out of stretch and size it to its
     content. Without this the table came out 505px — narrower than the
     text it was supposed to break out of. */
  width: 100%;
  max-width: 52rem;
  margin-inline: auto;
}

/* --------------------------------------------------------------------
   Article head and cover
   -------------------------------------------------------------------- */
/* The head shares the body's measure. Left-aligned to the container it
   sat a full gutter to the left of the first paragraph, so the title and
   the text it introduces read as two different columns. */
.article__head {
  max-width: var(--measure);
  margin-inline: auto;
  margin-block-end: var(--space-8);
}

/* The gap under a category tag, when there is one. It used to be an inline
   `margin-block-start` on the h1 — and a second one on the tag, which was
   the head's clearance from the breadcrumbs that lived inside this block.
   The trail is its own block now and owns that clearance, so the head's
   first element carries nothing and only the tag→title relationship is
   left. Stated once here rather than twice in every fragment that renders
   a head. */
.article__head .tag + h1,
.block-reference__head .tag + h1 {
  margin-block-start: var(--space-4);
}

.article__cover {
  margin-block-end: var(--space-12);
}

/* A 16:9 cover at the full page width stood 683px tall on a 892px
   screen: the reader arrived, saw one photo, and had to scroll before
   the article existed. Letterboxing it keeps the photograph large
   without letting it hold the page hostage. Mobile keeps 16:9 — at
   375px wide, 21:9 is a 160px strip. */
.article__cover .img-frame {
  aspect-ratio: 16 / 9;
}

@media (min-width: 48rem) {
  .article__cover .img-frame {
    aspect-ratio: 21 / 9;
  }
}

/* --------------------------------------------------------------------
   Reference detail — head, fact sheet, cover

   Deliberately not the article's head reused under another name. Both
   open with a title on the measure, but they are selling different
   things: an article opens with who wrote it and when, a reference opens
   with what the thing is, where it went and what it is made of. One is a
   byline, the other is a spec plate — and the page has to feel like a
   portfolio piece rather than a post about one.
   -------------------------------------------------------------------- */
.block-reference__head {
  max-width: var(--measure);
  margin-inline: auto;
}

/* The fact sheet. Rules above and below rather than a card: it reads as
   a plate screwed to the work, which is the register a reference wants —
   documentary, checkable, not decorated. Each pair is wrapped in a div
   because a `dl` laid out as a grid otherwise scatters its terms and
   definitions into separate cells. */
.block-reference__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--space-6);
  /* Wider than the reading measure, narrower than the cover. Squeezed
     into the measure the four facts broke three-and-one, which reads as
     a list that ran out of room; given the breakout width they sit in one
     even row. It also puts a small ladder into the page — head, plate,
     photograph — so each part announces itself as a different kind of
     thing. */
  width: 100%;
  max-width: 52rem;
  margin-inline: auto;
  margin-block-start: var(--space-8);
  padding-block: var(--space-6);
  border-block: var(--border-width) solid var(--color-border);
}

.block-reference__facts dt {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
}

.block-reference__facts dd {
  margin: 0;
  margin-block-start: var(--space-1);
  font-weight: var(--font-weight-bold);
}

.block-reference__cover {
  margin-block: var(--space-12);
}

/* Taller than the article's cover, on purpose. The article letterboxes
   its photograph so it does not hold the page hostage before the writing
   starts; here the photograph *is* the argument, and cropping it thin to
   hurry the reader on to the text gets the priority backwards. */
.block-reference__cover .img-frame {
  aspect-ratio: 4 / 3;
}

@media (min-width: 48rem) {
  .block-reference__cover .img-frame {
    aspect-ratio: 16 / 9;
  }
}

/* Project numbers. Same `.stat` parts the About block uses, so a theme
   only ever styles one kind of figure — only the container differs,
   because these sit in running text rather than beside a portrait. */
.reference-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8) var(--space-12);
  justify-content: center;
  padding: 0;
  list-style: none;
  text-align: center;
}

/* --------------------------------------------------------------------
   Byline — author and publication date
   -------------------------------------------------------------------- */
.byline {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-sm);
}

.byline__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background: var(--color-primary-100);
  /* 800 — the ramp's ink step. Same change and same reason as the
     testimonial avatar in components.css. */
  color: var(--color-primary-800);
  font-weight: var(--font-weight-bold);
  overflow: hidden;
}

.byline__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

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

/* --------------------------------------------------------------------
   Figure — a single image with an optional caption
   -------------------------------------------------------------------- */
.figure figcaption,
.gallery__caption {
  margin-block-start: var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  text-align: center;
}

/* --------------------------------------------------------------------
   Gallery — thumbnails that open in the lightbox
   -------------------------------------------------------------------- */
.gallery__grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}

.gallery__item {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.gallery__item img {
  width: 100%;
  /* `height: auto` is not decoration. The `width`/`height` attributes on
     an <img> map to presentational hints, and a declared height makes
     both axes definite — at which point `aspect-ratio` is ignored
     entirely. The thumbnails were rendering at their source height (746
     and 1200px), which is why a gallery of mixed portraits and
     landscapes came out ragged. The attributes stay: they are what
     reserves the right space before the file arrives. */
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: scale 600ms var(--ease-out-expo);
}

.gallery__item:hover img {
  scale: 1.04;
}

/* --------------------------------------------------------------------
   Lightbox
   -------------------------------------------------------------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-6);
  background: color-mix(in srgb, var(--color-surface-inverse) 92%, transparent);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--motion-duration-slow) var(--ease-out-expo),
    visibility var(--motion-duration-slow);
}

.lightbox.is-open {
  opacity: 1;
  visibility: visible;
}

.lightbox__img {
  max-width: min(100%, 72rem);
  max-height: 76vh;
  object-fit: contain;
  border-radius: var(--radius-lg);
  /* Drag to browse. `pan-y pinch-zoom` hands the horizontal axis to the
     script and keeps the vertical one and pinch-zoom native — a photo
     viewer that cannot be zoomed is a worse photo viewer than one that
     cannot be swiped. `grab` says the same thing to a mouse that the
     gesture says to a thumb. */
  touch-action: pan-y pinch-zoom;
  cursor: grab;
  user-select: none;
  -webkit-user-drag: none;
}

.lightbox.is-dragging .lightbox__img {
  cursor: grabbing;
}

/* Only the settle is animated; the drag itself follows the pointer with
   no transition at all, because a lag between finger and image is the
   one thing that makes direct manipulation feel broken. */
.lightbox__img.is-settling {
  transition:
    translate var(--motion-duration-slow) var(--ease-out-expo),
    opacity var(--motion-duration-slow) var(--ease-out-expo);
}

@media (prefers-reduced-motion: reduce) {
  .lightbox__img.is-settling {
    transition: none;
  }
}

.lightbox__caption {
  color: var(--color-text-on-inverse);
  font-size: var(--text-sm);
  text-align: center;
}

.lightbox__btn {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: var(--border-width) solid color-mix(in srgb, currentColor 30%, transparent);
  border-radius: var(--radius-full);
  background: none;
  color: var(--color-text-on-inverse);
  cursor: pointer;
  transition: background-color var(--motion-duration) var(--ease-out-expo);
}

.lightbox__btn:hover {
  background: color-mix(in srgb, currentColor 15%, transparent);
}

.lightbox__btn--prev { inset-inline-start: var(--space-4); }
.lightbox__btn--next { inset-inline-end: var(--space-4); }
.lightbox__btn--close { inset-block-start: var(--space-4); inset-inline-end: var(--space-4); }

/* Embeds moved to components.css — the contact page's map is one, and a
   component only articles could use was in the wrong file. */

/* --------------------------------------------------------------------
   File download
   -------------------------------------------------------------------- */
.file-card {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  text-decoration: none;
  color: inherit;
  /* The card may be a <button> as well as an <a> — vitarent's e-book
     opens a dialog instead of serving a file. A link in flow fills its
     container; a button shrinks to its content and brings the UA's
     font, so the three declarations below make the two elements
     render identically. */
  width: 100%;
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition:
    border-color var(--motion-duration) var(--ease-out-expo),
    box-shadow var(--motion-duration-slow) var(--ease-out-expo),
    translate var(--motion-duration-slow) var(--ease-out-expo);
}

/* The hover edge is the card's slot, not the ramp — see `.next-item:hover`
   below for the measurement and the argument. The same omission in the same
   shape: a panel that lifts on hover, taking its hover edge from a step the
   ramp keeps near-white. Default unchanged. */
.file-card:hover {
  border-color: var(--card-border-hover, var(--color-primary-200));
  box-shadow: var(--shadow-md);
  translate: 0 -2px;
}

.file-card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  /* **Two slots, and this pair was a real failure rather than a
     preference.** `primary-100` as a tint with `primary-700` as the ink on
     top of it is a light-page assumption: it works because on a light ramp
     700 is a dark shade. A dark theme may invert that step deliberately —
     Ingrade's 700 sits *above* the brand in lightness so hovers brighten
     instead of going out — and then this is a pale glyph on a near-white
     square. Measured at **1.17:1** where a non-text graphic owes 3
     (WCAG 1.4.11), which is invisible rather than merely weak.

     Seventh place in this theme where a ramp step used as an ink assumed
     the page under it was light, and the last to be found because the file
     card only appears on the article page. Defaults are what they always
     were, so no existing theme moves. */
  background: var(--file-icon-surface, var(--color-primary-100));
  color: var(--file-icon-ink, var(--color-primary-700));
}

.file-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  flex: 1;
}

.file-card__name {
  font-weight: var(--font-weight-bold);
}

.file-card__meta {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------
   Audio player
   -------------------------------------------------------------------- */
.audio {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.audio__toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: var(--color-text-on-primary);
  cursor: pointer;
  transition: background-color var(--motion-duration) var(--ease-out-expo);
}

.audio__toggle:hover {
  background: var(--color-primary-700);
}

.audio__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.audio__title {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-bold);
}

.audio__bar {
  position: relative;
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--color-primary-100);
  cursor: pointer;
}

.audio__played {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 0;
  border-radius: var(--radius-full);
  background: var(--color-primary);
}

.audio__time {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------
   Pull quote — louder than a blockquote inside running text
   -------------------------------------------------------------------- */
.pull-quote {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-8);
  border-radius: var(--radius-lg);
  background: var(--color-surface-alt);
  border-inline-start: 4px solid var(--color-secondary);
}

.pull-quote p {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
}

.pull-quote footer {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------
   Next article
   -------------------------------------------------------------------- */

/* This block is the article's coda, not a section that follows it, and it
   was not reading that way: a full section rhythm above it against the
   article's own full rhythm below made 237px of empty page between the
   last paragraph and "Další článek" — the piece looked finished twice.

   Half the rhythm at the top, the article's own below it unchanged, so the
   pair still sits inside the page's spacing system rather than beside it.
   Trimmed rather than closed up: the gap is doing a real job, which is to
   say the article is over before the offer of another one starts. */
.block-next {
  padding-block-start: calc(var(--section-space) / 2);
}

/* The way out to everything else, for a reader the single suggestion above
   did not land with. Deliberately the same `link-arrow` the homepage uses
   under its blog and reference grids — the job is identical, so a second
   affordance for it would be a second thing to learn. Quiet on purpose:
   the item above is the offer, this is the fallback.

   Centred, which it can be now that the eyebrow above the card is gone.
   With that label there the block read left-aligned and a centred link
   under it would have been a third alignment in one small block. */
.block-next__all {
  margin-block-start: var(--space-6);
  text-align: center;
}

.next-item {
  display: grid;
  gap: var(--space-6);
  align-items: center;
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  text-decoration: none;
  color: inherit;
  transition:
    border-color var(--motion-duration) var(--ease-out-expo),
    box-shadow var(--motion-duration-slow) var(--ease-out-expo),
    translate var(--motion-duration-slow) var(--ease-out-expo);
}

@media (min-width: 40rem) {
  .next-item {
    grid-template-columns: 12rem 1fr;
  }

  /* No picture, no picture column. The block's own markup always renders a
     frame — an empty one when the item has no photograph, because a card
     that loses its picture must not lose its shape. This is for a
     placement that predates that: without it the text lands in the 12rem
     column meant for the image and the title wraps four words at a time
     beside a hole. Found on the drga demo, on the one reference with no
     cover. */
  .next-item:not(:has(.img-frame)) {
    grid-template-columns: 1fr;
  }
}

/* The hover edge asks the theme what a panel's edge does under the pointer,
   the way `.card` already does. It was reaching straight into the ramp, and
   on a dark page that is the difference between a hover and a headlight:
   `primary-200` is a near-white by construction, so measured on Ingrade the
   edge went from **1.47:1** at rest to **18.05:1** on hover — against body
   text that measures 7.28 on the same page. The single loudest thing on the
   article was the outline of the card offering the next one. With the slot
   the theme's own answer applies and it lands at **2.27:1**: a step up of
   1.5×, which is a card acknowledging the pointer rather than switching on.

   `--card-border-hover` rather than a slot of its own, because there is one
   question here and it has been answered once. Any theme that has said what
   a liftable panel's edge does has said it for this one too.

   The resting surface deliberately stays `--color-surface` / `--color-border`
   and does not take `--card-surface`. That is a separate question and the
   answer would go the wrong way for this block — see BACKLOG. */
.next-item:hover {
  border-color: var(--card-border-hover, var(--color-primary-200));
  box-shadow: var(--shadow-lg);
  translate: 0 -4px;
}

/* `.next-item__label` — the "Další článek" eyebrow — is gone. The card
   already says what it is: a picture, a date, a title and "Číst článek".
   A label above it was naming the obvious, and on a page that has just
   ended it read as one more heading the reader did not need. */
