/* Naszymi Oczami — a photobook, not a blog template.
   Rules this stylesheet keeps:
   1. Photographs are never cropped by the layout. Every image keeps its own aspect ratio.
   2. Colour lives in the photographs. The chrome is a neutral gallery-wall grey.
   3. Type steps back: one family, sentence case, no capitals used as decoration.
   4. Galleries break out of the text column; text never competes with a photograph.
   5. No card shadows and no hover lift. Separation is whitespace and the image edge. */

:root {
  --paper:     #f2f3f5;
  --surface:   #ffffff;
  --ink:       #191c22;
  --ink-soft:  #5d646f;
  --rule:      #dde0e5;
  --accent:    #2c5f8a;

  --measure: 66ch;
  --gap: 1.75rem;
  --page: 76rem;

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:    #14161a;
    --surface:  #1b1e24;
    --ink:      #e7e9ec;
    --ink-soft: #99a0ab;
    --rule:     #2a2e36;
    --accent:   #7fb2dc;
  }
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }

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

.muted { color: var(--ink-soft); }

/* ---------- frame ---------- */

header.site,
footer.site,
main {
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: 1.5rem;
}

header.site {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-block: 2.5rem 3rem;
}

/* The wordmark carries the one piece of colour in the chrome: the blue-over-green bar
   from the 2016 logo. Everything is sized off --wordmark-size, so the bar keeps its
   1:2 proportion and its cap-height alignment with the name at every viewport width.

   Rule 3 of this stylesheet — sentence case, no capitals used as decoration — does not
   apply to the name itself: the 2016 logo set it NASZYMI OCZAMI, so the capitals are the
   brand's own typography rather than emphasis. They are set as a wordmark, not merely
   uppercased: caps run wider and read heavier, so the size steps down, the weight comes
   off 620, and the tracking turns positive to open the letterfit back up. The tagline
   stays sentence case — it is a sentence, not part of the mark. */

.wordmark {
  --wordmark-size: clamp(1.2rem, 0.93rem + 1.05vw, 1.8rem);
  text-decoration: none;
  color: inherit;
  display: flex;
  align-items: flex-start;
  gap: calc(var(--wordmark-size) * 0.3);
}

.wordmark-mark {
  flex: none;
  width: calc(var(--wordmark-size) * 0.36);
  height: calc(var(--wordmark-size) * 0.72);
  margin-top: calc(var(--wordmark-size) * 0.17);
}

.wordmark-name {
  display: block;
  font-size: var(--wordmark-size);
  font-weight: 560;
  text-transform: uppercase;
  letter-spacing: 0.055em;
  /* The tracking is added after every letter, including the last one, which pushes the
     mark off-centre against the tagline below it. Pull the trailing space back. */
  margin-right: -0.055em;
  /* Left at 1.1 on purpose: the bar's margin-top above is tuned against this line box to
     land on the cap height, and capitals put the cap height at the top of the type. */
  line-height: 1.1;
}

.wordmark-tag {
  display: block;
  margin-top: 0.3rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

header.site nav { display: flex; gap: 1.5rem; }
header.site nav a { color: var(--ink-soft); text-decoration: none; }
header.site nav a:hover { color: var(--ink); text-decoration: underline; }

footer.site {
  margin-top: 6rem;
  padding-block: 2rem 3.5rem;
  border-top: 1px solid var(--rule);
  color: var(--ink-soft);
  font-size: 0.9rem;
}
footer.site p { margin: 0.2rem 0; }

/* ---------- the wall: uncropped photographs in true masonry, no JavaScript ---------- */

.cards {
  columns: 3;
  column-gap: var(--gap);
}

@media (max-width: 60rem) { .cards { columns: 2; } }
@media (max-width: 34rem) { .cards { columns: 1; } }

.card {
  display: block;
  break-inside: avoid;
  margin-bottom: 2.75rem;
  color: inherit;
  text-decoration: none;
}

.card-img img { background: var(--rule); }

.card-body { padding-top: 0.7rem; }

.card-body h3 {
  margin: 0.1rem 0 0;
  font-size: 1.06rem;
  font-weight: 560;
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.card:hover h3 { text-decoration: underline; text-underline-offset: 3px; }

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

.page-head, .post-head { max-width: var(--measure); margin-bottom: 2.5rem; }

.post-head time {
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.post-head h1, .page-head h1 {
  margin: 0.35rem 0 0;
  font-size: clamp(1.9rem, 1.3rem + 2.4vw, 3rem);
  font-weight: 640;
  letter-spacing: -0.028em;
  line-height: 1.12;
  text-wrap: balance;
}

.terms { margin: 0.9rem 0 0; display: flex; flex-wrap: wrap; gap: 0.75rem; }
.terms a { color: var(--ink-soft); font-size: 0.9rem; }

/* The text keeps its measure; galleries are free to use the whole page frame.
   Constraining the children rather than .prose itself is what lets a gallery break out. */
.prose { max-width: none; }
.prose > *:not(.gallery) { max-width: var(--measure); }

.prose p, .prose ul, .prose ol, .prose blockquote { margin: 0 0 1.35em; }

.prose h2 {
  margin: 2.6rem 0 0.8rem;
  font-size: 1.45rem;
  font-weight: 620;
  letter-spacing: -0.018em;
}

.prose h3 { margin: 2rem 0 0.6rem; font-size: 1.15rem; font-weight: 600; }

.prose blockquote {
  margin-inline: 0;
  padding-left: 1.2rem;
  border-left: 2px solid var(--rule);
  color: var(--ink-soft);
}

.prose img { margin-block: 1.6rem; }

.prose iframe { max-width: 100%; border: 0; margin-block: 1.6rem; }

/* ---------- galleries break the text column ---------- */

.gallery {
  margin: 3rem 0;
  display: grid;
  gap: 0.75rem;
  width: 100%;
}

.gallery.cols-2 { grid-template-columns: repeat(2, 1fr); }
.gallery.cols-3 { grid-template-columns: repeat(3, 1fr); }
.gallery.cols-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 44rem) {
  .gallery.cols-3, .gallery.cols-4 { grid-template-columns: repeat(2, 1fr); }
}

.gallery figure { margin: 0; }

.gallery figcaption {
  margin-top: 0.5rem;
  color: var(--ink-soft);
  font-size: 0.85rem;
  line-height: 1.45;
}

/* A one-column gallery is the photobook spread: as wide as the page allows. */
.gallery.cols-1 img { width: 100%; }

/* ---------- footers of a post ---------- */

.more {
  max-width: var(--page);
  margin-top: 5rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--rule);
}

.more h2 {
  margin: 0 0 1.75rem;
  font-size: 1.1rem;
  font-weight: 560;
  color: var(--ink-soft);
}

.pager {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--rule);
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---------- category index ---------- */

.terms-list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 3;
  column-gap: var(--gap);
}

@media (max-width: 50rem) { .terms-list { columns: 2; } }
@media (max-width: 32rem) { .terms-list { columns: 1; } }

.terms-list li {
  break-inside: avoid;
  padding: 0.35rem 0;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: 1px solid var(--rule);
}

.terms-list span { font-variant-numeric: tabular-nums; font-size: 0.85rem; }

/* ---------- awards: quiet credentials at the foot of the wall ----------
   Small, grey, and set as a three-across row so the eye reads them as a strip of
   credits rather than a list of claims. The mark is a line drawing in currentColor:
   it carries no colour of its own, so the photographs above stay the only colour. */

.awards {
  margin-top: 5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  color: var(--ink-soft);
}

.awards h2 {
  margin: 0 0 1.1rem;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--ink-soft);
}

.awards ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.75rem var(--gap);
}

@media (max-width: 52rem) { .awards ul { grid-template-columns: 1fr; gap: 1.1rem; } }

.awards li {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 0.6rem;
  align-items: center;
  max-width: 24rem;
}

.award-mark { grid-row: 1; color: var(--ink-soft); opacity: 0.8; }

.award-year {
  grid-row: 1;
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
  color: var(--ink);
}

.award-text {
  grid-column: 2;
  grid-row: 2;
  font-size: 0.82rem;
  line-height: 1.45;
  margin-top: 0.15rem;
}

/* ---------- cards gain an excerpt ---------- */

.card-excerpt {
  margin: 0.4rem 0 0;
  color: var(--ink-soft);
  font-size: 0.92rem;
  line-height: 1.5;
}

/* ---------- countries, grouped by continent ---------- */

/* Issue #8: the column minimum is 16.75rem, not the 15rem it was. Leading, the flag takes
   1.25em off the front of the line, and "Zjednoczone Emiraty Arabskie" — the longest of the
   35 — then needs 262 px of the column to itself. auto-fill will squeeze a 15rem column down
   to 240 px before it gives up a column, which is 22 px short. At 16.75rem it drops to fewer,
   wider columns instead, and the name never wraps at any width from 320 px up. The full-width
   page still lays out four columns, exactly as before. */
.continents {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16.75rem, 1fr));
  gap: 2.5rem var(--gap);
}

.continent h2 {
  margin: 0 0 0.75rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--rule);
  font-size: 1rem;
  font-weight: 620;
  letter-spacing: -0.01em;
}

.continent ul { list-style: none; margin: 0; padding: 0; }

.continent li {
  display: flex;
  justify-content: space-between;
  /* space-between already holds the name and the count apart; this gap only bites on the
     one row long enough to fill its column, and 0.5rem is what that row can spare. */
  gap: 0.5rem;
  padding: 0.3rem 0;
}

.continent span { font-size: 0.85rem; font-variant-numeric: tabular-nums; }

/* ---------- the archive index ---------- */

.archive-year { margin-bottom: 2.75rem; }

.archive-year h2 {
  margin: 0 0 0.75rem;
  font-size: 1.35rem;
  font-weight: 620;
  font-variant-numeric: tabular-nums;
}

.archive-year ul { list-style: none; margin: 0; padding: 0; max-width: var(--measure); }

.archive-year li {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--rule);
}

.archive-year time {
  color: var(--ink-soft);
  font-size: 0.85rem;
  white-space: nowrap;
}

/* ---------- social marks ----------
   One rule set for the footer and for /kontakt/. The glyphs are inline SVG filled with
   currentColor, so they inherit whatever the surrounding text is: grey in the footer,
   link blue in the page body, and correct in both colour schemes with no second palette.

   Issue #6: the names are gone, so the mark is the whole link. Two things follow. The
   target can no longer be the glyph — 22 px is below any thumb — so the link is padded
   out to a 44 px square; and the row is pulled left by that padding so the marks still
   line up with the text edge above them rather than sitting in an accidental indent. */

/* ul.social, not .social: `.prose ul` above sets a margin on the list, and on /kontakt/
   that outranked the bare class and put the marks back in an 11 px indent. */
ul.social {
  list-style: none;
  margin: 0.35rem 0 0 -11px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0;
}

.social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  text-decoration: none;
}

.social-link svg { flex: none; }

/* In the footer the mark is part of the grey chrome, not a coloured accent. */
footer.site .social { margin-top: 0.45rem; }
footer.site .social-link { color: var(--ink-soft); }
footer.site .social-link:hover { color: var(--ink); }

/* A single photograph inside a page body, e.g. the portrait on /kontakt/. */
.page-photo { margin: 0 0 2rem; }

.page-photo figcaption {
  margin-top: 0.55rem;
  color: var(--ink-soft);
  font-size: 0.82rem;
}

/* ---------- card meta: the full date, and where it was ---------- */

/* The card gains no new line. The grey line that used to carry a bare year now carries the
   whole date and the place, so the wall reads no denser than before. Date and place are held
   apart by space, not by a middle dot — this theme does not join meta with dots.

   Issue #6: it is set smaller than the excerpt below it. This line is a label, and on the
   wall the title should be the first thing read, not the date. One rule covers all three
   places a card appears — the homepage, /category/<slug>/, and "Zobacz też" on a post.

   Issue #8: a point smaller again — 0.76rem was 9.1pt, this is 8.1pt — and set in
   capitals. The house style keeps capitals out of running text, but the owner asked for
   them here, as he did for the wordmark. Three things make that legible rather than
   merely loud: the tracking, because capitals set at their default fit are a wall at
   10.9px; the raised line-height, so the acute on Ś and Ż and the ogonek on Ą have room
   above and below rather than crowding the title; and leaving the colour alone, since
   capitals already read heavier than lowercase at the same size. */
.card-meta {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.05rem 1rem;
  color: var(--ink-soft);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.075em;
  line-height: 1.55;
}

.card-meta time { font-variant-numeric: tabular-nums; }

/* ---------- country flags on /kraje/ ----------
   Self-hosted SVGs (flag-icons, MIT — static/flags/README.txt). Not emoji: the regional
   indicator pairs render as bare letters on Windows, which is most of this audience.
   Issue #8: the flag leads the name at roughly the cap height of the type, so the list
   still reads as a list of names rather than a row of stickers. The room it needs at the
   front of the line is bought back in .continents above, not here. */

/* The wrapper holding flag + name is a <span>, and .continent span above sets the small
   count size — put the name back to the body size it had when the <a> sat in the <li>
   directly. inherit, not 1rem: the body runs at 17px while the root is 16px.

   A flex row, not inline flow: the name is then its own item, so if a column ever does get
   narrow enough to wrap one, it wraps under itself with the flag hanging in the margin
   rather than starting its second line underneath the flag. min-width: 0 is what lets that
   item shrink and wrap at all instead of overflowing the row. */
.continent li .country {
  display: flex;
  align-items: baseline;
  gap: 0.3em;
  font-size: inherit;
  min-width: 0;
}

.continent li .country a { min-width: 0; }

.flag {
  /* 0.95em wide is 0.71em tall, which is the cap height of this face almost exactly: the
     flag sits level with the capital letter beside it. flex: none so it never squeezes
     when the name beside it is long. */
  flex: none;
  width: 0.95em;
  height: auto;
  /* A replaced element's baseline is its bottom edge, so baseline alignment would stand
     the flag exactly on the baseline. Nudge it down the same 0.1em the old inline
     vertical-align did — position, not margin, so the row's metrics do not move. */
  position: relative;
  top: 0.1em;
  /* border-radius clips a replaced element's own painting, so an <img> pointing at an SVG
     does come out with rounded corners — no wrapper with overflow: hidden needed. */
  border-radius: 2px;
  /* A hairline ring, drawn outside the image. An inset shadow would be painted behind the
     bitmap and never seen. Without it Japan and Malta dissolve into the light background. */
  box-shadow: 0 0 0 1px rgba(25, 28, 34, 0.18);
}

@media (prefers-color-scheme: dark) {
  .flag { box-shadow: 0 0 0 1px rgba(231, 233, 236, 0.22); }
}

/* ---------- issue #10: the post page ---------- */

/* The dateline over the title, set like the one on the cards.
   The listing already reads date-then-title in small capitals; the post page read it in
   plain 0.9rem text, so arriving at a post changed the voice of the line. Same size, same
   tracking, same line-height as .card-meta above — a label, not a sentence.

   The place is deliberately not repeated here. A card carries it because a card has nothing
   else to say where it was; a post prints its categories under the title, as links, in
   .terms. Putting them in the dateline as well would print Islandia twice, two lines apart. */
.post-head time {
  display: inline-block;
  color: var(--ink-soft);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.075em;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
}

/* A photograph written into the prose as Markdown. layouts/_markup/render-image.html gives
   it a <figure> of its own, and this lets that figure out of the 66ch measure the rule at
   `.prose > *:not(.gallery)` holds every other child to — the same freedom a gallery has.
   Higher specificity than that rule (two classes and an element against two classes), and
   later in the file, so it wins without the earlier rule being rewritten.

   No width is set on the image: `img { max-width: 100%; height: auto }` from the reset is
   the whole of its sizing, which means it draws at its own pixel size and never above it.
   A 1200 px photograph now fills the frame it used to sit half-way across; a 500 px one
   stays 500 px and sharp rather than being stretched to 1168 and going soft. That is why
   the widths in a post are not all identical — the alternative is upscaling, and a soft
   photograph is worse than a small one. */
.prose > figure.photo {
  max-width: none;
  margin: 2.5rem 0;
}

/* The margin belongs to the figure now, or the caption would be pushed a whole line clear
   of the picture it names. */
.prose > figure.photo img { margin-block: 0; }

.prose > figure.photo figcaption {
  max-width: var(--measure);
  margin-top: 0.5rem;
  color: var(--ink-soft);
  font-size: 0.85rem;
  line-height: 1.45;
}

/* Every photograph is a link to the file behind it — see the note in shortcodes/gallery.html.
   display: block so the anchor is exactly the picture: an inline box would leave the
   descender gap of an empty line under each frame and open a 4 px seam in the gallery grid.
   The anchor carries no text, so there is nothing for the link colour or the underline to
   land on; both are left alone rather than reset, and the focus ring from :focus-visible
   draws around the photograph, which is what a keyboard reader needs to see. */
.gallery figure a,
.prose > figure.photo a { display: block; }

/* ---------- issue #16: the consent notice ---------- */

/* The one piece of chrome on this site that appears uninvited, so it is built to be as
   quiet as a thing can be while still being a real question: the same neutral surface, the
   same rule, the same type as the rest of the page, sitting on the bottom edge rather than
   over the middle of it. Not a modal, not a scrim, no shadow, nothing dimmed behind it —
   the photographs stay readable while it is up, and it goes away for good on either answer.

   position: fixed rather than sticky so it does not consume layout at the foot of a short
   page, and z-index kept low; nothing else on the site stacks. */
.consent {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 50;
  background: var(--surface);
  border-top: 1px solid var(--rule);
}

.consent:focus { outline: none; }

.consent-inner {
  max-width: var(--page);
  margin-inline: auto;
  padding: 1.1rem 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem 2rem;
}

.consent-text { flex: 1 1 30rem; }

.consent-text p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
}

.consent-text p + p { margin-top: 0.3rem; }

.consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

/* Both answers are the same control. One class, one size, one weight, one border, one
   background — the difference between accepting and refusing is the word on the button and
   nothing else. This is deliberate and it is the point: the moment "accept" is a filled
   button and "reject" is a grey link, the choice has been made for the reader.

   44 px minimum height for the same reason the social marks have it: a thumb. */
.consent-btn {
  min-height: 44px;
  padding: 0.55rem 1.15rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 0.9rem;
  line-height: 1.2;
  cursor: pointer;
}

.consent-btn:hover { border-color: var(--ink-soft); }

/* ---------- the footer's legal line ---------- */

.footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  margin: 0.35rem 0 0;
  font-size: 0.85rem;
}

/* A <button> because it does something to this page rather than going to another one, but
   it belongs in a line of footer links, so it is dressed as one. Everything a button
   inherits from the user agent — the box, the background, the centred 13 px system font —
   is taken back off, and the 44 px target the other controls get would be wrong here: this
   sits inside a paragraph of text and is the size of the text around it. */
.linklike {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  text-align: left;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  cursor: pointer;
}

/* ---------- the trip pages, indexed on /archiwum/ ---------- */

.trips {
  margin-bottom: 3.5rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--rule);
}

.trips h2 {
  margin: 0 0 1rem;
  font-size: 1.35rem;
  font-weight: 620;
}

.trips ul {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: var(--measure);
}

.trips li {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--rule);
}

.trips time {
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- issue #16: two things the privacy policy needs and no other page had ---------- */

/* A short statement of fact set apart from the argument around it — used once, for the line
   that says whether analytics is on or off in this build. Same grey as a blockquote's rule,
   but boxed rather than barred: a blockquote is someone else speaking, this is the site
   answering a question about itself. */
.prose .notice {
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--surface);
  font-size: 0.92rem;
}

.prose .notice code {
  font-size: 0.95em;
  word-break: break-all;
}

/* The cookie table. The site had no table style because it had never had a table; this is
   the first, and it exists because a list of what gets written into someone's browser is
   read by scanning down a column, not by reading sentences.

   It is allowed past the 66ch measure — five columns will not fit in it — and scrolls inside
   its own box on a phone rather than pushing the page sideways. Hugo wraps a Markdown table
   in a plain <table>, so the wrapper is the table itself: display: block gives it something
   to overflow.

   The selector repeats .prose on purpose. `.prose > *:not(.gallery)` above holds every child
   to the 66ch measure and outweighs a plain `.prose table`; doubling the class matches its
   specificity without editing the rule that every other page depends on — the same escape
   `.prose > figure.photo` takes, which buys its width with an element and two classes. */
.prose.prose > table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  margin: 0 0 1.35em;
  border-collapse: collapse;
  font-size: 0.88rem;
  line-height: 1.45;
}

.prose th,
.prose td {
  padding: 0.55rem 0.9rem;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}

.prose th {
  font-weight: 600;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  white-space: nowrap;
}

.prose td code { font-size: 0.95em; }

/* ---------- embedded frames, and the box that stands in for them ---------- */

/* Every third-party frame on this site now arrives as the embed shortcode: a wrapper, a
   box, and — until the reader has accepted statistics and embedded content — a short note
   inside the box instead of an <iframe>. See layouts/shortcodes/embed.html for why the
   frame cannot simply ship with its src.

   .embed-box is the whole reason nothing on the page moves when the frames arrive. It is
   sized here, from the two custom properties the shortcode writes, and it is the same box
   in both states: the note sits inside it, and the <iframe> replaces the note inside it.
   No reflow, no jump, no scroll position lost. */

.embed { margin-block: 1.6rem; }

.embed-box {
  width: var(--embed-w, 100%);
  max-width: 100%;
  height: var(--embed-h, auto);
  aspect-ratio: var(--embed-ratio, 16 / 9);
}

.embed-box > iframe {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
}

/* The placeholder. Not a warning and not a nag — the same neutral surface and rule as the
   consent notice and the tables, the same type as the rest of the page, saying in one line
   what the frame is and in one more why it is not there yet. Centred in the box because the
   box is the frame's shape, not the note's: a 702 px Facebook post leaves a lot of room
   around three short lines, and pinning them to the top would read as a broken image. */
.embed:not(.is-loaded) .embed-box {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  overflow: auto;
  border: 1px solid var(--rule);
  background: var(--surface);
}

.embed-note { max-width: 34rem; text-align: center; }

.embed-note p { margin: 0; font-size: 0.9rem; line-height: 1.5; }
.embed-note .embed-what { font-weight: 600; }
.embed-note .embed-why { margin-top: 0.3rem; }
.embed-note .embed-do { margin-top: 0.9rem; }

/* ---------- issue #18: a map is a picture of a place, not a paragraph ---------- */

/* Every Google map on this site is a direct child of .prose, so `.prose > *:not(.gallery)`
   was holding it to the 66ch measure — about 605 px — and the 2010 markup then took
   width="90%" of that, landing the maps of a 30 000 km journey at roughly 545 px. Two
   constraints, one visible symptom; the inline attribute alone was never the whole of it.

   This is the same freedom `.prose > figure.photo` and `.gallery` already have, bought the
   same way: an element plus two classes, later in the file, so the rule above is left as
   written. The rule used to select the <iframe> by its src; there is no src in the document
   any more, so it selects the wrapper the shortcode puts the map in — and it now overrides
   the shortcode's own width and height rather than a presentational HTML attribute, which
   is why the two custom properties are reset here instead of merely being outweighed.

   The shape is chosen, not inherited. 380 px across the full 1168 px frame is a 3:1 strip
   that shows a route and none of the country it crosses; 16/9 is the ratio the eye already
   reads as a map or a landscape, and holds from a phone to a wide monitor. The two bounds
   are where a fixed ratio stops making sense: max-height keeps a desktop map inside the
   window rather than pushing the text under the fold, and min-height stops a 272 px column
   on a 320 px phone from drawing a 153 px letterbox — there the map goes taller than wide,
   which is the right shape for that screen. The placeholder gets exactly the same box, so
   a map's footprint is the same before and after the reader answers. */
.prose > .embed--mapa { max-width: none; }

.embed--mapa .embed-box {
  --embed-w: 100%;
  --embed-h: auto;
  --embed-ratio: 16 / 9;
  max-height: 68vh;
  min-height: 20rem;
}

/* ---------- issue #20: the footer on one line ---------- */

/* The footer used to stack four blocks — the site line, the two marks, the copyright, the
   legal link — down the page, which is four rows of chrome under a full-width rule. They
   are all one thought, so they go on one line.

   Laid out as the header is: two groups, pushed to the two edges of the same 1168 px frame,
   so the line reads left to right as what the site is, then who owns it. Nothing is joined
   with a middle dot; the separation is whitespace, the same as between the header's nav
   items, and the rule already above the footer is the only line drawn.

   Everything wraps. Below roughly 730 px the two groups fall onto their own rows, and below
   about 360 px each group breaks internally as well — back to the old stack, which is the
   right shape for a phone. No item is ever shrunk, so nothing overflows and no text gets
   smaller: at the 320 px floor the widest thing on the page is still the tagline, wrapping
   inside the frame the way any paragraph would. */
footer.site {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem 2rem;
}

.footer-brand,
.footer-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 1.5rem;
}

/* The paragraphs were spaced for a stack; in a row the gap above does that job. */
footer.site p { margin: 0; }

/* The marks keep their 44 px targets and their labels — the target is what issue #6 was
   about and it is not paid for here. The list is only pulled in by the 11 px of padding
   that sits either side of a 22 px glyph inside that box, so the whitespace around the
   marks measures the same as the whitespace everywhere else on the line. */
footer.site ul.social { margin: 0 -11px; }
