/* prose.css: the long-form reading primitive (.im-prose), its contents rail
   (.im-toc, .im-prose-toc), the reviewer byline and the inset callout. Moved
   whole from blocks.css so a surface that must not load blocks.css (the
   business portal, whose [data-reveal] blocks would stay hidden without
   reveal.js) can load reading styles alone. Loaded AFTER blocks.css on
   editorial pages, which changed who wins an equal-specificity tie. A
   deliberate override scoped to .im-svc (.im-svc .im-prose h2 and its
   siblings) is a compound selector and still wins on specificity, unaffected
   by the move. A plain blocks.css rule with no such scoping, such as .im-cxf,
   can tie a selector here (`.im-prose > * + *`) on specificity, and now loses
   that tie by file order where it used to win by position inside blocks.css
   alone. Any rule in that position carries its own higher-specificity
   selector to hold its result (see .im-cxf in blocks.css). Tokens only. */

/* ---- Prose primitive (.im-prose): the shared long-form/article style.
 * Aligned with the blog's existing .im-blog-content treatment; blog adopts
 * .im-prose in surface 3. Tokens only. ---- */
.im-prose { max-width: 73ch; font-family: var(--im-font-body, "Hanken Grotesk", system-ui, -apple-system, sans-serif); }
.im-prose > * + * { margin-top: var(--im-space-4); }
.im-prose p { font-size: 15.5px; line-height: 1.7; color: var(--im-text-200); }
/* h2 is serif, h3 is sans: the face change IS the hierarchy signal, so h3 does
   not need to shout with weight. Matches Harvey (serif h1-h3, sans from h4); we
   break one level earlier because h3 is where our service pages turn into
   per-requirement detail and lists, which read better in the grotesque. */
.im-prose h2 { font-family: var(--im-font-serif); font-weight: 400; font-size: 26px;
  line-height: 1.15; letter-spacing: var(--im-track-head); color: var(--im-ink);
  padding-left: var(--im-space-4); border-left: 3px solid var(--im-accent-200);
  text-wrap: balance; }
/* Display-face h2, opt-in per call site via the block's `modifier` param. Same
   move as .im-cta-band--display: one block, two type voices, chosen by the
   caller. The Sponsor Licence page asks for it because its education block now
   leads the page directly under the hero (2026-08-09) rather than sitting mid-
   article, so the h2 reads as a section head among display headings rather than
   as article prose. Weight 500, not the h3's 600: the sans section-head value
   this file already settled on at .im-svc (medium, "editorial, not shouty"), and
   the step the grotesque needs to hold the same presence the serif had at 400.
   Size is untouched: it stays the base 26px. */
.im-prose--display-head h2 { font-family: var(--im-font-display); font-weight: 500; }
.im-prose h3 { font-family: var(--im-font-display); font-weight: 600; font-size: 21px;
  letter-spacing: var(--im-track-head); color: var(--im-ink); text-wrap: balance; }
.im-prose a { color: var(--im-accent-200); text-decoration: underline; text-underline-offset: 2px; }
.im-prose ul { list-style: none; padding: 0; }
.im-prose ul li { position: relative; padding-left: var(--im-space-5); font-size: 15px;
  line-height: 1.65; color: var(--im-text-200); }
.im-prose ul li + li { margin-top: var(--im-space-2); }
.im-prose ul li::before { content: ""; position: absolute; left: 2px; top: 9px; width: 7px; height: 7px;
  background: var(--im-accent-200); border-radius: 2px; }
.im-prose blockquote { border-left: 3px solid var(--im-ink); background: var(--im-band);
  padding: var(--im-space-4) var(--im-space-5); border-radius: 0 var(--im-radius-control) var(--im-radius-control) 0;
  font-family: var(--im-font-display); font-size: 18px; color: var(--im-ink); }
.im-prose img { max-width: 100%; height: auto; border-radius: var(--im-radius-card); }
.im-inset { border-left: 3px solid var(--im-accent-200); background: var(--im-card-bg);
  padding: var(--im-space-4) var(--im-space-5); border-radius: 0 var(--im-radius-control) var(--im-radius-control) 0;
  font-size: 13.5px; color: var(--im-text-200); line-height: 1.6; }
.im-inset b, .im-inset__label { font-family: var(--im-font-display); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--im-accent-200); display: block; margin-bottom: var(--im-space-1); }

/* ---- Prose meta line (last-updated / contact) ---- */
.im-prose__meta { font-family: var(--im-font-display); font-size: 12px; letter-spacing: .02em; color: var(--im-text-200); }

/* ---- Prose with sticky table of contents (legal docs: tc/pc). Tokens only. ---- */
.im-prose-toc { display: grid; grid-template-columns: 1fr; gap: var(--im-space-8); }
@media (min-width: 768px) {
  .im-prose-toc { grid-template-columns: 210px minmax(0, 1fr); gap: var(--im-space-12); }
  .im-prose-toc__nav { position: sticky; top: 7rem; align-self: start; }
}
.im-prose-toc__list { list-style: none; margin: var(--im-space-3) 0 0; padding: 0; }
.im-prose-toc__list li + li { margin-top: var(--im-space-2); }
.im-prose-toc__list a { display: block; padding-left: var(--im-space-3); border-left: 2px solid var(--im-hairline);
  color: var(--im-text-200); text-decoration: none; font-size: 14px; line-height: 1.45; }
.im-prose-toc__list a:hover, .im-prose-toc__list a:focus-visible { color: var(--im-ink); border-left-color: var(--im-accent-200); }
.im-prose-toc .im-prose { max-width: none; }
.im-prose-toc .im-prose h2 { scroll-margin-top: 7rem; }

/* ---- Prose convergence (Surface 3): elements the blog TinyMCE body uses that
 * the base .im-prose lacked (table / code / pre / ol / hr). Additive: the
 * already-shipped legal/about/service pages contain none of these. Tokens only. ---- */
.im-prose ol { padding-left: var(--im-space-6); }
.im-prose ol li { font-size: 15px; line-height: 1.7; color: var(--im-text-200); margin-top: var(--im-space-2); }
.im-prose hr { border: 0; border-top: 1px solid var(--im-hairline); margin: var(--im-space-8) 0; }
.im-prose code { font-family: var(--im-font-mono); font-size: 0.9em; background: var(--im-band);
  padding: 0.1em 0.35em; border-radius: var(--im-radius-control); }
.im-prose pre { background: var(--im-band); border: 1px solid var(--im-hairline); border-radius: var(--im-radius-card);
  padding: var(--im-space-4); overflow-x: auto; font-family: var(--im-font-mono); font-size: 13px; line-height: 1.6; }
.im-prose pre code { background: none; padding: 0; }
.im-prose table { width: 100%; border-collapse: collapse; margin: var(--im-space-6) 0; font-size: 14.5px; display: block; overflow-x: auto; }
.im-prose th, .im-prose td { text-align: left; padding: var(--im-space-3) var(--im-space-4); border-bottom: 1px solid var(--im-hairline); }
.im-prose th { font-family: var(--im-font-display); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--im-text-muted); }

/* ---- Reviewer / freshness byline (E-E-A-T): one inline line under the hero,
   hairline above and below. It replaced a bordered card in its own page section
   the signal is worth keeping, a full-width panel between
   the masthead and the first substance is not. The separator is a pseudo-element
   so an absent source or date leaves no orphan middot behind. ---- */
.im-byline { display: flex; flex-wrap: wrap; margin: 0;
  padding: var(--im-space-3) 0;
  border-top: 1px solid var(--im-hairline); border-bottom: 1px solid var(--im-hairline);
  font-size: 13px; line-height: 1.5; color: var(--im-text-muted); }
.im-byline__item + .im-byline__item::before { content: "·"; margin: 0 var(--im-space-3); }
.im-byline__lk { color: var(--im-text-200); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px; }
.im-byline__lk:hover, .im-byline__lk:focus-visible { color: var(--im-ink); }

/* ---- Service-page two-column body with sticky TOC ----
   IMPORTANT: no ancestor of .im-tocgrid may set overflow: hidden/clip:
   that silently disables position: sticky on the rail.

   minmax(0, 1fr), never a bare `1fr`. The article column holds long unbroken
   strings and wide tabular content, and a bare `1fr` floors the track at that
   min-content: measured 434px of page-level sideways scroll on
   germany/work-visas/eu-blue-card at 390px, from a 96-character
   processing-time sentence in a fee value (.im-ledger__figure in blocks.css). minmax(0, …)
   lets the track shrink, so a wide child scrolls inside its own overflow
   container rather than pushing the page. KEEP THIS even though the
   560px-min-width comparison table that first exposed it has been deleted: the
   floor it removes is min-content, whatever supplies it. */
.im-tocgrid { display: grid; grid-template-columns: 215px minmax(0, 1fr); gap: var(--im-space-12, 48px);
  align-items: start; }
/* Moved here from design-system/blocks.css verbatim: the
   rail's own "On this page" label is prose, not a marketing-block heading,
   and blocks.css and prose.css are always loaded together anyway (paired
   in parts/header.html's use_editorial branch), so no consumer's markup
   changes; a page that loads prose.css alone (the guide reading page) now
   gets the rule it always needed. */
.im-seclab { font-family: var(--im-font-display); font-size: 12px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--im-text-muted); margin-bottom: var(--im-space-3); }
/* max-height + scroll because the rail is sticky: a grouped rail carries two
   headings and both audiences' entries, which on a short laptop viewport runs
   past the fold with no way to reach the bottom of it. Reset in the <=900px
   branch below, where the rail is static and scrolls with the page. */
.im-toc { position: sticky; top: 72px;
  max-height: calc(100vh - var(--im-nav-h) - var(--im-space-6)); overflow-y: auto; }
.im-toc__list { list-style: none; margin: var(--im-space-3, 12px) 0 0; padding: 0;
  border-left: 1px solid var(--im-hairline, #E4DFD2); }
.im-toc__list a { display: block; padding: 6px 0 6px 16px; font-size: 13.5px;
  color: var(--im-text-muted); text-decoration: none; border-left: 2px solid transparent;
  margin-left: -1.5px; line-height: 1.35; }
.im-toc__list a:hover, .im-toc__list a:focus-visible { color: var(--im-accent-200, #00668c); }
.im-toc__list a.is-current { color: var(--im-ink); border-left-color: var(--im-accent-200, #00668c);
  font-weight: 600; }
/* Audience heading inside the rail, on a route serving a worker and an employer.
   Ranks below "On this page" (.im-seclab) and above the links, so the rail reads
   as one list divided rather than as two lists stacked. */
.im-toc__group { font-family: var(--im-font-display); font-size: 12px; font-weight: 600;
  color: var(--im-ink); margin-top: var(--im-space-5); }
/* The first group sits under "On this page" and takes the smaller gap. Keyed on
   the label it follows, not on :first-of-type: the first DIV sibling in the rail
   is the .im-seclab, so :first-of-type matched nothing and the rule was dead.
   :where() holds the selector at one class of specificity so the <=900px
   override below still wins on its own. */
:where(.im-seclab) + .im-toc__group { margin-top: var(--im-space-3); }
/* Narrow: the rail stops being a rail and sits above the article, but the list
   inside it stays VERTICAL. It used to go horizontal flex-wrap here, and that
   cost more than it saved. Measured at 390px, 15 links: the strip is 304px tall
   against 563px vertical, so it buys back a third of a screen, and in exchange
   the links run together as one unpunctuated line, the tap targets fall from
   328px wide to 63px, and both border-lefts go, which is where `is-current`
   lives. Scrollspy on a phone was reduced to a colour change with no position
   marker on a page whose whole job is orienting a reader through fifteen
   sections. Vertical is the same design at both widths, and the extra 259px is
   one flick of a thumb. Sticky still goes: in one column the rail sits above
   the prose, so pinning it would cover what it points at. */
@media (max-width: 900px) {
  .im-tocgrid { grid-template-columns: minmax(0, 1fr); }
  .im-toc { position: static; max-height: none; overflow-y: visible; }
  .im-toc__group { margin-top: var(--im-space-4); }
}

/* Each half of the document is wrapped in a <section> named by its band, so a
   screen-reader user can identify and skip the half that is not addressed to
   them (WCAG 2.2 SC 1.3.1; the band alone was a visual-only signal). Those
   wrappers are SEMANTICS, not layout, and .im-prose's rhythm is the
   child-combinator `> * + *` above, which stops at the wrapper and would leave
   every section inside it flush against its neighbour. These two rules carry the
   rhythm through: the same 4-step gap inside a region, and the void the band used
   to own between them. Only the route pages that carry an employer block render
   any <section> here at all. */
.im-prose > section > * + * { margin-top: var(--im-space-4); }
.im-prose > section + section { margin-top: var(--im-space-10); }

/* Guide callouts (ADR-021). Colour is never the only signal: each carries a visible label. */
.im-inset--scope { border-left-color: var(--im-ink); background: var(--im-band); }
.im-inset--recommendation { border-left-color: var(--im-accent-200); }
.im-inset--important { border-left-color: var(--im-danger-ink); }
.im-inset--scope .im-inset__label { color: var(--im-ink); }
.im-inset--important .im-inset__label { color: var(--im-danger-ink); }
.im-prose__num { color: var(--im-accent-200); margin-right: var(--im-space-1); }
.im-prose__table { overflow-x: auto; }
.im-prose__table:focus-visible { outline: 2px solid var(--im-accent-200); outline-offset: 2px; }
/* .im-prose table (above) makes the <table> itself scroll, so inside this
   region the table never overflows and the focusable div's own overflow-x
   never engages: arrow keys on the focused region do nothing. Undo that here
   so the region is the one thing that scrolls, and the table can be wider
   than it. */
.im-prose__table table { display: table; overflow: visible; }
