@charset "UTF-8";
/* =============================================================================
   Nordicplan — global stylesheet entry point
   Globals only: design tokens, resets, shared button, header/footer template
   parts, search pill, chapter + plan-archive layouts. Each concern lives in its
   own partial below; this file just composes them in cascade order.

   Block-specific styles live in src/blocks/<slug>/style.scss and are
   auto-enqueued per-block by WordPress.

   Compiles to assets/css/main.css via `npm run build:css` (or watch:css).

   Conventions
   - SCSS with nesting. `&__suffix` BEM concatenation is allowed.
   - Tab indentation, blank line between rule blocks.
   - Order of the @use rules below IS the cascade order of the output.
   ============================================================================= */
/* ---------- Design tokens ---------- */
:root {
  --np-radius-pill: 9999px;
  --np-radius-card: 20px;
  --np-radius-card-foot: 30px;
  --np-radius-hero-arc: 300px;
  --np-container-max: 1360px;
  --np-content-max: 1200px;
  /* Height of the sticky header region used as the scroll offset for in-page
     anchors. The whole `.np-site-header-wrap` is `position: sticky`, and on the
     chapter/commentary/translation reading views it contains BOTH the white
     header bar (~111px: 28px padding-block ×2 + the logo) AND the breadcrumb
     (~87px: 30px bar + 18px padding-block ×2 + the trail line) — ~198px stuck at
     the viewport top. Add a small gap so an anchored heading lands clearly below
     it rather than flush against it. */
  --np-header-offset: 210px;
}

/* ---------- Resets ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* The site header is sticky, so a native jump to an in-page anchor (clause
   anchors like #clause-10-1, the TOC sidebar links, breadcrumb links) would land
   the target up underneath it. Inset the scroll container by the sticky header
   height + a small gap so anchored targets land just below the header. */
html {
  scroll-padding-top: var(--np-header-offset);
}

body {
  margin: 0;
  background: var(--wp--preset--color--white);
  color: var(--wp--preset--color--black-mountain);
  font-family: var(--wp--preset--font-family--sans);
  font-size: var(--wp--preset--font-size--body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Lock body scroll when the search overlay is open. */
}
body.np-search-overlay-open {
  overflow: hidden;
}

main {
  margin-top: 0;
}

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

a {
  color: var(--wp--preset--color--deep-ocean);
  text-decoration: none;
}
a:hover {
  color: var(--wp--preset--color--orange);
}

.screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Content headings get 1.5× the default block-gap (24px) above them for clearer
   separation — scoped to real heading blocks that are direct flow children of
   the post content, so block-internal headings (e.g. the commentary callout's
   .np-clause-callout__heading, which is not a .wp-block-heading) and
   site/header/footer headings are untouched. Beats the `is-layout-flow > * + *`
   24px block gap. */
.wp-block-post-content > h2.wp-block-heading,
.wp-block-post-content > h3.wp-block-heading,
.wp-block-post-content > h4.wp-block-heading {
  margin-block-start: 36px; /* 24px block gap × 1.5 */
}

/* There is deliberately NO `scroll-margin-top` on anchored content headings.
   There used to be, "carrying the same scroll offset as the scroll container" —
   but the two do not substitute for each other, they **stack**: the container's
   scroll-padding-top and the target's scroll-margin-top both apply to the same
   jump, so every in-page anchor on the site landed two header-heights down.
   Measured before removal at 420px of a 633px viewport for `#clause-12-2`, with
   no JavaScript involved, which is to say it affected every TOC sidebar link,
   breadcrumb and clause link equally. `scroll-padding-top` on `html` above is the
   whole fix and covers every target, including the first element on the page —
   which is the case the removed rule was written for. */
/* Content list styling — markers, hanging indent and spacing — lives in
   `_lists.scss`. Two rules used to sit here adding a 12px half-block-gap above
   every `li + li` and above every nested list; they were the *cause* of Sally's
   *"De skal ha samme linjeavstand som brødteksten/paragraf"*, so they are gone
   rather than overridden. */
/* Table styling — the sand card, the presentational-attribute reset and the
   column geometry — lives in `_tables.scss`. The card and the reset used to sit
   here; they moved so that all table rules are in one file, the same way the list
   rules moved to `_lists.scss`. */
/* =============================================================================
   Content lists — markers, hanging indent, spacing.

   Everything here is scoped to `.wp-block-list`, the class core/list always
   renders (nested lists included — verified across all 600 lists in the corpus).
   That scope is deliberate: it is identical in the editor iframe and on the front
   end, so Sally sees the real markers while writing, and it never reaches the
   nav / footer / TOC `<ul>`s, which are hand-built markup without that class.
   (Those draw their own bullets from `list-style: none` + a `::before`, so they
   have no marker box and none of what follows applies to them.)

   The corpus expresses the same intent in several markups, because the importer
   and Gutenberg disagree and Gutenberg rewrites a list the moment an editor
   touches it. All six rendered forms that exist:

       389  <ol type="a" class="wp-block-list">                      (a) (b) (c)
        78  <ol style="list-style-type:lower-alpha" class="…">       (a) (b) (c)
        13  <ol type="i" class="wp-block-list">                      (i) (ii)
         1  <ol style="list-style-type:lower-roman" class="…">       (i) (ii)
        63  <ol class="wp-block-list">                               (1) (2) (3)
        56  <ul class="wp-block-list">                               bullet

   Both alpha spellings must be covered or a third of the lists silently keep
   `a.` — and the population shifts over time as pages are edited, so neither
   form can be treated as legacy. bin/test-list-styles.php asserts that every
   form present in the corpus is one this file handles.

   --- How a marker is drawn, and why it is not a marker ----------------------

   Every marker is generated content on an **absolutely positioned `::before`**,
   and the element's real marker is a zero-width character. That is two rejected
   mechanisms deep, and both rejections were measured rather than reasoned:

   1. `::marker { content: … }` — the obvious tool, and the one this file used
      until Aug 2026. **Safari ignores `content` on `::marker` in every version**
      (MDN: *"Safari support is limited to `color` and `font-size`"*), so every
      marker fell back to the native `a.` / `1.` / `•` there while Chrome looked
      correct. Nothing errored; the two browsers just disagreed silently.

   2. `@counter-style` + `list-style-type` — the correct standards answer, and it
      fixed (1) everywhere. But a real marker box sits *in the first line box*,
      and in Safari at fractional zoom it pushes that line right by roughly its
      own width in sub-pixels: measured at 3.35px and 3.53px on two items of the
      same list at `innerWidth 1760 / devicePixelRatio 1.7`, while every wrapped
      line stayed flush. The two values differ because the two markers differ in
      width — which is what identified the marker box as the cause. Dropping the
      trailing space from the suffix does **not** fix it (that variant was tested
      and still shifted); only removing the marker box does. It reproduces in
      Safari at particular zoom/DPR combinations and in no other engine, and not
      in Playwright's WebKit build either, so it cannot be regression-tested here
      — which is exactly why the mechanism below is chosen to make it structurally
      impossible rather than merely absent.

   An out-of-flow `::before` cannot contribute to a line box at all, so the first
   line and every wrapped line start at the same edge by construction. `right:
   100%` pins the generated box's right edge to the list item's text edge and lets
   it size to its content leftwards, which is exactly what a marker box does — no
   width to declare, and the hanging indent Sally asked for (*"teksten bør begynne
   likt med linje 1"*) still comes for free.

   The real marker is blanked with a counter style whose symbol is U+200B ZERO
   WIDTH SPACE rather than `list-style-type: none`, because `none` is the one
   value that makes Safari + VoiceOver stop treating the element as a list at all
   — a bad trade in a legal text where "list, 5 items" is part of reading a
   clause. Zero width is the load-bearing part: a blank-but-present marker still
   occupies the first line box, so a marker of literally any width would
   reintroduce (2). A single space was tried first and shifted the line.
   ============================================================================= */
/* The blanked real marker. Keeps the element a list for assistive technology
   while contributing nothing to layout. */
@counter-style np-blank {
  system: cyclic;
  symbols: "​";
  suffix: "";
}
/* `!important` is load-bearing: 78 of the alpha lists carry their numbering as an
   **inline** `style="list-style-type:lower-alpha"` — the spelling every list
   drifts into as pages are edited — and an inline declaration outranks any author
   rule without it. Left un-blanked, those 78 would draw the native `a.` marker
   *and* the `::before`, showing both. */
ol.wp-block-list,
ul.wp-block-list {
  list-style-type: np-blank !important;
}

/* Placement, shared by every marker in the file including the sub-numbering
   variation at the bottom.

   `white-space: pre` keeps the trailing space in the content strings below, which
   is the gap between marker and text — the space a marker's suffix used to
   provide — and stops a marker wrapping. */
.wp-block-list > li {
  position: relative;
}

.wp-block-list > li::before {
  position: absolute;
  right: 100%;
  white-space: pre;
}

/* --- Numbering -------------------------------------------------------------
   `counter(list-item, …)` is the browser's own implicit list counter, not a
   hand-rolled one. It is reset per list and incremented per item for free, at
   every nesting depth, and — the reason it is worth preferring — it honours the
   `start` attribute behind core/list's "Start value" control and any `value` on
   an `<li>`. A hand-rolled counter ignores both and would renumber such a list
   silently. Verified in both engines: `<ol start="5">` prints (e) (f).

   The corpus uses neither today (0 of 600 lists), so this changes nothing now;
   it is the editor's next `start` value that it protects. */
/* Which rendered forms mean which numbering style.

   There is deliberately no `[type="A"]` or `[type="I"]` here. `type` is on the
   HTML spec's list of attributes whose values selectors match ASCII
   *case-insensitively*, so `[type="A"]` also matches `<ol type="a">` — adding it
   would have silently re-lettered all 389 lowercase lists as (A), (B), (C),
   since the two rules have equal specificity and the later one wins. Matching
   case-sensitively needs the `[type="A" s]` flag, which Sass's quote-stripping
   fights, for a form that does not occur anywhere in the corpus.
   `style` is *not* on that list, so the inline-style spellings are safe — and
   they are the ones that matter, because Gutenberg writes a list style as
   `style="list-style-type:…"` (never as a `type` attribute) the moment an editor
   touches the block. Uppercase therefore stays covered the way it would actually
   arrive. */
/* Every ordered marker is parenthesised, decimal included: (1) (2) (3).

   This reverses the Aug 2026 decision to keep decimals bare. That decision read
   Sally's written *"også (1), (2), (3)"* as a slip and treated parentheses as
   belonging to the lettered sub-levels only; she has since restated it in a
   review meeting, with the numbered lists inside Cl. 2-8 and Cl. 18-54 named as
   the places where the missing parentheses show. So it is her considered form,
   not a slip, and the reversal is recorded here rather than argued again.

   It is also what the prose already assumes: Cl. 18-1 (e) ends *"The regulations
   in (1) and (2) are regarded as special safety regulations"* while its list
   drew `1.` `2.` `3.` — a cross-reference that did not match the thing it
   referred to. Parentheses on the decimal marker close that gap for free.

   The widest decimal marker the corpus renders is the Preface's 50-item
   amendment list, `(50) ` — wider than the `50. ` it replaces, and still inside
   the gutter below (see the measurements there). */
ol.wp-block-list > li::before {
  content: "(" counter(list-item, decimal) ") ";
}

/* Lettered and roman-numbered lists get the same treatment: (a), (b), (c) /
   (i), (ii). An attribute selector outranks the bare type selector above, so
   these win with no ordering dependency — the difference is now only which
   counter style is printed, not whether it is bracketed. */
ol.wp-block-list[type=a] > li::before, ol.wp-block-list[style*=lower-alpha] > li::before {
  content: "(" counter(list-item, lower-alpha) ") ";
}

ol.wp-block-list[type=i] > li::before, ol.wp-block-list[style*=lower-roman] > li::before {
  content: "(" counter(list-item, lower-roman) ") ";
}

ol.wp-block-list[style*=upper-alpha] > li::before {
  content: "(" counter(list-item, upper-alpha) ") ";
}

ol.wp-block-list[style*=upper-roman] > li::before {
  content: "(" counter(list-item, upper-roman) ") ";
}

/* One bullet shape at every depth. Browsers switch to a hollow `circle` at
   depth 1 and a `square` at depth 2, which reads as a mistake in a legal
   document rather than as deliberate hierarchy — and it contradicted the
   "Dot bullets" variation, which is one flat dot however deep it sits. */
ul.wp-block-list > li::before {
  content: "• ";
}

/* --- Layout ---------------------------------------------------------------
   The ordered-list gutter is the UA default's 40px restated in `em`, so it tracks
   the type instead of standing still against it. Nothing moves at the default
   16px — 2.5em *is* 40px — but this is the only measure in the text column that
   was in px, and the body size here is fluid (theme.json): it runs ~14.5px on a
   narrow column and 16px on a wide one, so the same list was indented 2.75em on
   one screen and 2.5em on another.

   The value stays deliberately generous, and that reasoning is unchanged by the
   markers moving out of flow — if anything it matters more now, because an
   out-of-flow marker wider than the gutter overflows to the left of the list
   instead of pushing anything. One gutter has to hold every marker this file
   prints, from `•` through `(vii)` to the sub-numbering variation's `1.1`.
   Measured in the site's own font, the widest marker the corpus actually renders
   is `(iii) ` at 1.66em, against `(a) ` at 1.44, `(50) ` at 2.11 — the Preface's
   50-item list, and now the widest marker the corpus prints, because bracketing
   the decimals added 0.4em to it — and `• ` at 0.63, so 2.5em clears all of
   them, with the least headroom on the decimal.

   **One gutter for every list**, ordered and unordered alike. Unordered lists
   used to sit at 1.5em — enough for a bullet and nothing more — which is why a
   `ul` and the `ol` above or below it started their text at different places on
   the same page, and why a `ul` nested inside an `ol` stepped in by a different
   amount than an `ol` nested inside an `ol`. Sally: *"alle nivåer i listene bør
   ha et konsekvent system for innrykk"*. Sizing both to the widest marker in the
   file is what makes the step between levels the same everywhere, at the cost of
   a bullet sitting further from its text than it strictly needs to — which is
   the side of the trade a legal text wants, because the alignment is what a
   reader uses to see which level they are on. */
ol.wp-block-list,
ul.wp-block-list {
  padding-left: 2.5em;
}

/* --- Spacing --------------------------------------------------------------
   Sally: *"De skal ha samme linjeavstand som brødteksten/paragraf"* — a list
   should read like the paragraph it belongs to, not as a spaced-out block.

   The gap she was seeing was ours: `_resets.scss` used to add a half-block-gap
   (12px) above every `li + li` and above every nested list, on the reasoning
   that "the default has none". The default having none is the correct default —
   items are lines of one sentence, and the extra leading broke the reading. Both
   rules are gone from `_resets.scss` and replaced by these.

   Lists also sit tight against their lead-in text: a clause reads "…as follows:"
   and then its items, which is one unit, so the 24px block gap above the list is
   removed too. Space *after* a list is opt-in — see `core/list` margin support in
   theme.json, which gives the Dimensions panel a bottom-margin control. That is
   the polarity Sally asked for: *"vi må kunne velge om vi legge inn en
   «linjeskift» etter bullets (de har noen ganger, men ikke alltid)"*. */
ol.wp-block-list,
ul.wp-block-list {
  margin-block: 0;
  /* `inherit` rather than a pinned value, so a list reads like whatever text
     surrounds it. On a page that is the body setting; inside a clause-callout
     preview, which sets its own slightly looser line-height, the quoted list
     follows the box — which is the point of the preview matching its source.
     theme.json is deliberately *not* used for this: a `styles.blocks` entry
     would pin lists to the body values everywhere, desyncing them from the
     callout, and it would be a second place saying the same thing. */
  font-size: inherit;
  line-height: inherit;
}

.wp-block-list > li + li,
.wp-block-list > li > .wp-block-list {
  margin-block-start: 0;
}

/* --- Continuation paragraphs inside a list item ----------------------------
   `core/list-item` forbids everything but a nested list; the theme widens that
   to `core/paragraph` in assets/js/list-item-paragraph.js. See that file for
   why. What matters here is that a list item can now hold real paragraphs after
   its own text, and they need no styling of their own: they inherit the body's
   1em block margin, which is the same rhythm as a paragraph anywhere else and
   is what puts air between the items in Cl. 18-1 — Sally's *"det er mye
   linjeskift under hvert punkt som ser rart ut når man ikke har mellomrom
   mellom punktene"*.

   The one thing that does need declaring is the trailing margin. A paragraph
   at the very end of the very last item has nothing below it inside the list,
   so its bottom margin collapses out through the `li` and the `ol` — neither
   has padding or a border to stop it — and lands as ~1em of space *after* the
   list. That silently reverses the polarity the block above is built on: space
   after a list is opt-in, via the editor's own Dimensions → Margin → Bottom
   control, precisely so *"vi må kunne velge om vi legge inn en «linjeskift»
   etter bullets"* stays a choice.

   Scoped to `li:last-child`, not to every `p:last-child`: the bottom margin of
   the last paragraph of a *non-final* item is the gap between that item and the
   next one, which is the whole reason to use paragraphs here. Zeroing it
   everywhere would give back exactly the run-together items this fixes. */
.wp-block-list > li:last-child > p:last-child {
  margin-block-end: 0;
}

/* --- Style variation: dash bullets ----------------------------------------
   Sally: *"Må også ha mulighet for bindestrek og prikk bullets"*. Registered in
   inc/block-styles.php. An en dash, not a hyphen, and it carries down into
   nested unordered lists inside the same list so a sub-list matches its parent
   without being styled separately — the descendant selector is what overrides
   the bullet the nested `<ul>` gets from the rule above. */
ul.wp-block-list.is-style-nordicplan-dash > li::before,
ul.wp-block-list.is-style-nordicplan-dash ul.wp-block-list > li::before {
  content: "– ";
}

/* --- Style variation: dot bullets -----------------------------------------
   The default shape, offered explicitly so switching back from dash is one
   click and the choice reads as a choice in the editor rather than "Default". */
ul.wp-block-list.is-style-nordicplan-dot > li::before,
ul.wp-block-list.is-style-nordicplan-dot ul.wp-block-list > li::before {
  content: "• ";
}

/* --- Style variation: sub-numbering ---------------------------------------
   Sally: *"Jeg får ikke til nummereringen (1.1, 1.2, osv) - Så trenger også
   denne opsjonen"*. Opt-in per list (decision D1), applied to the *nested* list,
   so the 24 nested lists nobody has reviewed stay exactly as they are.

   The marker is the parent's index in the parent's own numbering style, then a
   dot, then this item's index: `1 → 1.1` where the parent is numbered, `e →
   e.1, e.2` where it is lettered. Rendered without parentheses — Sally wrote
   "1.1, 1.2", and that is the conventional form for legal sub-numbering.

   This is the one marker that cannot read `counter(list-item, …)`, because that
   resolves to the *innermost* list's index and this marker needs an ancestor's
   too. Hence the depth-specific counters below: a nested list resets only its own
   level, so the outer levels stay readable from inside. The cost is that the
   parent segment ignores a `start` attribute where the main markers honour it —
   a discrepancy that only appears if someone sets a start value on a list that
   also has a sub-numbered child, and the corpus has neither.

   The parent's style is read off the ancestor list's own markup, which is why
   each parent form needs its own rule. Every selector here requires an ancestor
   ordered list, so applying the variation to a top-level list is harmless: it
   simply keeps its normal parenthesised marker. */
ol.wp-block-list {
  counter-reset: np-l1;
}

ol.wp-block-list > li {
  counter-increment: np-l1;
}

li ol.wp-block-list {
  counter-reset: np-l2;
}

li ol.wp-block-list > li {
  counter-increment: np-l2;
}

li li ol.wp-block-list {
  counter-reset: np-l3;
}

li li ol.wp-block-list > li {
  counter-increment: np-l3;
}

/* Depth 1 — parent is a plain (decimal) list. */
ol.wp-block-list > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, decimal) "." counter(np-l2, decimal) " ";
}

/* Depth 1 — parent is lettered or numbered by roman numerals. */
ol.wp-block-list[type=a] > li > ol.wp-block-list.is-style-nordicplan-substep > li::before, ol.wp-block-list[style*=lower-alpha] > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, lower-alpha) "." counter(np-l2, decimal) " ";
}

ol.wp-block-list[type=i] > li > ol.wp-block-list.is-style-nordicplan-substep > li::before, ol.wp-block-list[style*=lower-roman] > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, lower-roman) "." counter(np-l2, decimal) " ";
}

ol.wp-block-list[style*=upper-alpha] > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, upper-alpha) "." counter(np-l2, decimal) " ";
}

ol.wp-block-list[style*=upper-roman] > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, upper-roman) "." counter(np-l2, decimal) " ";
}

/* Depth 2 — the deepest level the corpus reaches (7 lists). Continues the chain
   when the level above is itself sub-numbered, so `1.1` gains `1.1.1`. */
ol.wp-block-list > li > ol.wp-block-list.is-style-nordicplan-substep > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, decimal) "." counter(np-l2, decimal) "." counter(np-l3, decimal) " ";
}

ol.wp-block-list[type=a] > li > ol.wp-block-list.is-style-nordicplan-substep > li > ol.wp-block-list.is-style-nordicplan-substep > li::before, ol.wp-block-list[style*=lower-alpha] > li > ol.wp-block-list.is-style-nordicplan-substep > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, lower-alpha) "." counter(np-l2, decimal) "." counter(np-l3, decimal) " ";
}

ol.wp-block-list[type=i] > li > ol.wp-block-list.is-style-nordicplan-substep > li > ol.wp-block-list.is-style-nordicplan-substep > li::before, ol.wp-block-list[style*=lower-roman] > li > ol.wp-block-list.is-style-nordicplan-substep > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, lower-roman) "." counter(np-l2, decimal) "." counter(np-l3, decimal) " ";
}

ol.wp-block-list[style*=upper-alpha] > li > ol.wp-block-list.is-style-nordicplan-substep > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, upper-alpha) "." counter(np-l2, decimal) "." counter(np-l3, decimal) " ";
}

ol.wp-block-list[style*=upper-roman] > li > ol.wp-block-list.is-style-nordicplan-substep > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l1, upper-roman) "." counter(np-l2, decimal) "." counter(np-l3, decimal) " ";
}

/* A sub-numbered list nested under a level that is *not* sub-numbered still
   shows its own two-part marker rather than inheriting a three-part chain. */
li ol.wp-block-list:not(.is-style-nordicplan-substep) > li > ol.wp-block-list.is-style-nordicplan-substep > li::before {
  content: counter(np-l2, decimal) "." counter(np-l3, decimal) " ";
}

/* =============================================================================
   Content tables.

   There are four tables on the entire site, all in the Commentary, and none of
   them is a `core/table` block yet — they are `core/html` blocks holding raw
   `<table border="1" cellspacing="10">` from the import, with inline
   `text-align: right` on the figure columns:

       #181 part-one/chapter-4/section-3 (Clause 4-14) × 2
            label + 3 columns: A's hull insurer | A | B and/or B's insurers
       #198 part-two/chapter-12          × 2
            label + 2 columns (Yard A | Yard B) + an entirely empty one, and
            label + 1 column + an entirely empty one

   Converting them to `core/table` is a content task, as is dropping #198's empty
   column. Everything here therefore has to work **identically for both forms**,
   which is why nothing below depends on `core/table`'s attribute markup: the
   selectors reach `.wp-block-table` (present on the `<figure>` in both cases) and
   otherwise use only element and position selectors.

   Sally, on Clause 4-14: *"de tre kolonnene til høyre bør ha samme bredde (Tittel
   i 3. kan gå over to linjer) … Tabellen under denne bør også følge de samme
   margene for kolonnene."* Auto table layout sizes each column to its content, so
   "A's hull insurer" came out wide, "A" narrow and "B and/or B's insurers" wide
   again — three different widths, and the widest header pushing the figures
   around. That is the whole complaint, and `table-layout: fixed` is the fix.

   The presentational-attribute reset (`border="1"` / `cellspacing="10"`) and the
   sand card these sit in moved here from `_resets.scss`, so all table rules are in
   one file rather than split across two.
   ============================================================================= */
/* The figure-column width, and the single lever on how a table divides its
   width: `table-layout: fixed` hands every declared width to the column that
   declares it and dumps the whole remainder on the label column, which is the
   only one without a declaration. Two tiers — see the rules near the bottom of
   this file for why the grouped shape needs its own. */
/* Tables read as a soft card: a sand panel padded by the card radius, with the
   table stretched to fill it. (`sand` == #fff5ee.)

   `overflow-x: auto` makes the *card* the scroll container. Without it a table
   too wide for a phone forces the whole page to scroll sideways, which is the
   one thing a reader cannot recover from — the body text goes off-screen too.
   Here the page stays put and the table scrolls inside its own panel. */
figure.wp-block-table {
  background: var(--wp--preset--color--sand);
  padding: 32px;
  border-radius: var(--wp--custom--radius--card, 20px);
  overflow-x: auto;
}

/* The card's 32px inset is generous on a phone, where it costs a quarter of the
   viewport and squeezes the table for no benefit. */
@media (max-width: 600px) {
  figure.wp-block-table {
    padding: 16px;
  }
}
/* Imported tables keep the source's border="1" / cellspacing="10" presentational
   attributes, which render a boxy, gap-spaced grid. Reset to a clean borderless
   table; cells keep a little padding so columns stay legible. `border-collapse:
   collapse` is what neutralises `cellspacing` — it has no effect once the borders
   are collapsed — so no `border-spacing: 0` is needed alongside it.

   `table-layout: fixed` is the load-bearing declaration. It sizes columns from
   the first row and the declared widths instead of from the content, which gives
   three properties at once:

     - the figure columns below are all exactly as wide as each other, because
       they are given the same width;
     - a header that needs two lines takes two lines instead of widening its
       column, which is Sally's *"Tittel i 3. kan gå over to linjer"*;
     - any column with no declared width shares what is left over equally, so the
       label column simply takes the remainder — and this keeps working whether a
       table has one figure column or four. That is why the widths below are set
       on the figure columns rather than on the label: it makes the rule
       independent of how many columns a table has, and #198's two tables have
       different counts from #181's.

   `min-width` is the other half of the scroll container: below it the cells would
   be crushed narrower than their content rather than the card scrolling. It
   tracks the figure-column width below — three figure columns at 10em plus a
   label column that still has to hold a caption is 42em, so a card narrower than
   that scrolls rather than crushing the label to nothing. */
.wp-block-table table {
  width: 100%;
  min-width: 42em;
  table-layout: fixed;
  border-collapse: collapse;
  border: 0;
}

.wp-block-table th,
.wp-block-table td {
  border: 0;
  padding: 0.2em;
  text-align: left;
  vertical-align: top;
  /* With a fixed column width, an unbreakable token longer than its column
     would otherwise spill across the neighbouring cell. */
  overflow-wrap: break-word;
}

/* An empty cell generates no line box, so a cell with no content collapses to
   just its padding — and a spacer row (every cell empty), which the source
   tables use for vertical breathing space between groups, collapses to a ~6px
   sliver instead of a blank line. A zero-width space in generated content gives
   the cell its line box back: the row keeps one full line-height, and because
   U+200B has no width it neither disturbs the `table-layout: fixed` columns nor
   prints anything. Generated rather than typed into the cells, so an editor
   cannot lose it on the next edit and the stored table markup needs no change —
   it works for the `core/html` and `core/table` forms alike. Same character, and
   the same reason (a box that contributes height but not width), as the
   list-marker blanking in `_lists.scss`. */
.wp-block-table th:empty::after,
.wp-block-table td:empty::after {
  content: "​";
}

/* Core's own table stylesheet puts a 3px `border-bottom` on `thead` and a 3px
   `border-top` on `tfoot`, which is the heavy near-black rule under the header
   row. It is the one part of core's table styling that survives the `border: 0`
   above, because it sits on the row-group elements rather than on the cells —
   which is also why it only appears once a table has a real `<thead>`, i.e. on a
   converted `core/table` and not on the four imported `core/html` ones.

   Gone at the base level, so both forms look the same: on a sand card a black
   rule is the loudest thing on the page, and the header already reads as a
   header from its weight and from sitting on the same baseline as its
   neighbours. This covers the "Bordered" variation below too — folding the
   header rule into the uniform 1px grid is what that variation wanted anyway, so
   it no longer needs a rule of its own. Delete this block to get the underline
   back everywhere. */
.wp-block-table thead,
.wp-block-table tfoot {
  border: 0;
}

/* Every column except the label column is figures, in all four tables. The width
   is what makes them equal — Sally's ask — and applies unconditionally.

   Selecting by position rather than by column count is what lets one rule serve
   tables with different shapes: #181's two tables have three figure columns,
   #198's have two and one. It is also row-relative, so it covers the legacy
   markup (a `<tr>` of `<th>` inside `<tbody>`) and `core/table`'s `<thead>`
   equally — the latter matters because converting these tables is a content task
   and the two forms will coexist for a while.

   The width is 10em, raised from the 7.5em this rule shipped with. Sally:
   *"tabellene oppleves som for smale, særlig midterste kolonne, og det er
   ubrukt plass som kan fordeles bedre"*. There is no CSS that distributes that
   space on its own — `table-layout: fixed` gives every declared width to the
   column that declares it and dumps *all* the remainder on the one column
   without one, which here is always the label. So this number is the only lever
   on the balance, and every em added to it is an em taken off the label column,
   once per figure column.

   Measured on #181 at desktop width, in the site's own font, before the change:
   the table is 49.5em wide, its three figure columns took 7.5em each and the
   label column took the other 27em — against a longest label of 11.5em
   (`Liability for 1/2 of B's loss`). Half the table was slack in one cell. At
   10em the figures take 30em and the label column keeps 19.5em, still ~8em clear
   of its longest line, which is the "fordeles bedre" she asked for.

   10em is **not** one-size-fits-all, and the grouped shape below is why: the
   content column is only ~49.5em, so the number of figure columns decides how
   much there is to give. One to three of them (#181, #198) leave the label
   column comfortable at 10em; four of them do not, and the two-tier rule at the
   bottom of this section is what keeps the same declaration from breaking the
   tables it was widened for.

   The other ceiling is #198, whose labels are sentences rather than captions
   (`Reduced emissions 150 MT *3.15kg CO2 / kg MDO = 472,5 MT CO2` is 30em and
   wraps at any width this rule could sensibly declare). Its first table also
   carries an entirely empty fourth column, which at 10em now costs 10em of the
   card — deleting it is the content task already noted at the top of this file,
   and doing so is what buys #198's labels their line back. Nothing here can
   detect an empty column, so this is deliberately left as a visible cost rather
   than papered over with a table-specific selector. */
.wp-block-table tr > *:not(:first-child) {
  width: 10em;
}

/* A header cell spanning several figure columns has to declare the width of all
   of them, because `table-layout: fixed` reads column widths from the first row
   *only* — a width on the body cells below is ignored. The rule is therefore
   `n × 10em`, so each spanned column ends up as wide as an unspanned one and a
   grouped table lines up with the rest of the site. Keep the two in step: this
   is the same width as the rule above, multiplied.

   Without this, the rule above hands a `colspan="2"` header the 10em meant for
   one column and the browser splits it 5em/5em — narrower than the figures
   those columns hold, so each one wraps to two lines. This is the shape a source
   table has when two sub-columns sit under one heading (a "N days" column beside
   its monetary equivalent), which is why the width has to follow the span rather
   than the cell.

   Same specificity as the rule above (0,2,1), so it wins on source order only —
   keep it below. */
.wp-block-table tr > *[colspan="2"] {
  width: 20em;
}

/* --- The grouped shape: four figure columns, and its own narrower column ----

   `colspan="2"` is the proxy for "this table has two sub-columns under each of
   two headings", i.e. four figure columns rather than one to three. It is the
   shape the Cl. 16-9 examples take (`Alternative A:` over a days column and a
   money column, then the same for B).

   Four columns at the 10em above is 40em, which does not fit: the content column
   is ~49.5em, so the table hits its own `min-width`, overflows the sand card and
   scrolls sideways **on a desktop** — measured, with `330,000` and `405,000`
   clipped at the card's right edge and the label column crushed to 12em, its
   sentences broken over four lines. That is strictly worse than the 7.5em this
   round set out to improve on, so the widening cannot be unconditional.

   6.5em is what the source artwork uses. These two tables are still `core/image`
   screenshots of a Word table on the live page (converting them is the content
   task); measured off `image849k.png`, the label column is 53% of the table and
   the four figure columns share the rest at ~6.2em each. At 6.5em the rendered
   table comes out at 49.46em — inside the card, no scroll — with a 23.5em label
   column, which is the same proportion the artwork has and the reason to prefer
   it over any rounder number.

   Both declarations are needed, and both are (0,3,3): the prefix
   `.wp-block-table table:has(tr > *[colspan="2"])` is (0,2,2) and each suffix
   adds (0,1,1). They therefore tie with each other exactly as the two base rules
   do, so the colspan one has to stay second here too. */
.wp-block-table table:has(tr > *[colspan="2"]) {
  /* Four figure columns need more room before scrolling than the 42em above,
     which was sized for tables with one to three of them. */
  min-width: 46em;
}
.wp-block-table table:has(tr > *[colspan="2"]) tr > *:not(:first-child) {
  width: 6.5em;
}
.wp-block-table table:has(tr > *[colspan="2"]) tr > *[colspan="2"] {
  width: 13em;
}

/* Right alignment as a *default*, so a converted `core/table` looks the same as
   one still waiting to be converted: the imported markup carries inline
   `style="text-align: right"` on these cells, and the conversion does not
   necessarily preserve it.

   `:not([class*="has-text-align"])` is what keeps this a default rather than a
   diktat. The editor's own alignment control does not emit an inline style — it
   adds a `has-text-align-*` class, which core styles at `:root .has-text-align-*`,
   specificity (0,2,0). This selector without the guard is (0,2,1) and would
   silently beat it, so an editor could not left-align a text column no matter
   what they clicked. Excluding the class instead of trying to out-specify it
   means the editor's choice always wins, whichever way core's specificity
   changes. */
.wp-block-table tr > *:not(:first-child):not([class*=has-text-align]) {
  text-align: right;
}

/* A header that wraps to two lines should still sit on the same baseline as its
   one-line neighbours, or the row reads as misaligned — the cells default to
   `vertical-align: top` above, which pushes a short header up away from a tall
   one. */
.wp-block-table th {
  vertical-align: bottom;
}

/* =============================================================================
   Block style variation: "Bordered" (`core/table`).

   Registered in `inc/block-styles.php`; this is its whole implementation. The
   borderless table above is the default because most of the corpus reads as prose
   with figures in it, but a dense grid — one where a reader has to track which
   figure belongs to which column across several rows — needs ruled cells to be
   followable. That is the shape the old nordicplan.org used, and #cebeb3 is its
   rule colour: a warm grey that sits on the sand card without the harshness of a
   grey or black line.

   Selected by class rather than offered as the default so nothing about the four
   existing tables changes: a block style adds `is-style-…` to the block's root
   element, which for `core/table` is the same `<figure>` that carries
   `.wp-block-table`, so `.wp-block-table.is-style-…` (0,2,1) beats the `border: 0`
   defaults above (0,1,1) with no `!important` anywhere.

   `border-collapse: collapse` is already declared on the table, so adjacent cells
   share one 1px rule instead of doubling it, and the cells' own outer edges draw
   the table's outer frame — hence no separate border on the table element.

   The heavy `thead` / `tfoot` rules core draws are cleared for every table above,
   not here: they would cut across this grid at a different weight *and* a
   different colour, but they are just as unwanted on the borderless default, so
   there is one rule rather than a variation-specific copy of it.
   ============================================================================= */
.wp-block-table.is-style-nordicplan-bordered th,
.wp-block-table.is-style-nordicplan-bordered td {
  border: 1px solid #cebeb3;
}

/* ---------- Shared button (used in blocks + core/button overrides) ---------- */
.np-btn,
.np-btn--outline,
.wp-block-button__link.wp-element-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 4px 24px;
  border: 1px solid #000;
  border-radius: var(--np-radius-pill);
  background: transparent;
  color: #000;
  font-family: var(--wp--preset--font-family--sans);
  font-size: 14px;
  font-weight: 500;
  line-height: 24px;
  letter-spacing: 0.002em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.np-btn:hover,
.np-btn--outline:hover,
.wp-block-button__link.wp-element-button:hover {
  background: #000;
  color: #fff;
}

/* ---------- Site header (template part: parts/header.html) ----------
   The header wrapper carries `has-global-padding` so root padding-inline is
   applied by WP's built-in class. The inner box just constrains width and
   centres — exactly the pattern WP uses for constrained children of a
   `has-global-padding` parent. Don't add padding-inline here or content will
   sit further inset than the page's constrained content below.
*/
/* The template-part wrapper (`<div class="np-site-header-wrap …">`) is the
   sticky element, not `.np-site-header` inside it: sticky only travels within
   its parent's box, and the wrap is the child of the tall page flow whereas
   `.np-site-header`'s parent (the wrap) is only header-height. */
.np-site-header-wrap {
  position: sticky;
  top: 0;
  z-index: 10;
  box-shadow: none;
  transition: all 0.3s ease-in-out;
}
.np-site-header-wrap.scrolled {
  box-shadow: 0 4px 18px 0px rgba(0, 0, 0, 0.05);
}
.np-site-header-wrap {
  /* Offset the stuck header below the WP admin bar (fixed over the viewport
     top: 32px desktop, 46px at ≤782px). Without this the header sticks behind
     the bar for logged-in users. */
}
body.admin-bar .np-site-header-wrap {
  top: 32px;
}
@media screen and (max-width: 782px) {
  body.admin-bar .np-site-header-wrap {
    top: 46px;
  }
}

.np-site-header {
  background: var(--wp--preset--color--white);
  padding-block: 28px;
  position: relative;
}
.np-site-header .np-site-header__inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 32px;
  width: 100%;
  max-width: var(--wp--style--global--content-size, 1200px);
  margin-inline: auto;
}
.np-site-header .np-site-header__brand img,
.np-site-header .wp-block-site-logo img {
  max-height: 64px;
  width: auto;
}

.np-primary-nav .wp-block-navigation__container,
.np-primary-nav ul {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  gap: 32px;
  justify-content: end;
  flex-wrap: wrap;
}
.np-primary-nav a,
.np-primary-nav .wp-block-navigation-item__content {
  position: relative;
  color: var(--wp--preset--color--deep-ocean);
  font-weight: 600;
  font-size: 16px;
  line-height: 30px;
  letter-spacing: 0.01em;
  text-decoration: none;
}
.np-primary-nav a:hover,
.np-primary-nav .wp-block-navigation-item__content:hover {
  color: var(--wp--preset--color--orange);
}
.np-primary-nav {
  /* Active section — orange underline under the current top-level item. The
     `current-menu-item` class and `aria-current` are injected by the
     render_block filter in inc/nav-active.php so deep CPT pages (e.g.
     /the-plan/…/chapter-1/) still light up their section's menu entry. The
     underline is a pseudo-element so it never shifts the menu layout. */
}
.np-primary-nav .current-menu-item > a,
.np-primary-nav a[aria-current=page] {
  color: var(--wp--preset--color--navy);
}
.np-primary-nav .current-menu-item > a::after,
.np-primary-nav a[aria-current=page]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 2px;
  background: var(--wp--preset--color--orange);
  border-radius: 2px;
}

/* Mobile header: logo on the left, the mobile-nav toggle on the right. Below
   900px the custom nordicplan/mobile-nav block takes over with its own
   multi-page drill-down overlay, so the inline desktop nav (and core's own
   responsive hamburger, nested inside it) plus the header search pill are
   hidden — search lives inside the mobile menu. The grid collapses to a
   simple two-item flex row.

   The nav selector is scoped under .np-site-header (0,2,0) so it outranks
   WP's layout rule (.wp-block-navigation-is-layout-flex, 0,1,0) that would
   otherwise keep the nav `display:flex` on source order. */
@media (max-width: 900px) {
  .np-site-header .np-site-header__inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .np-site-header .np-primary-nav,
  .np-site-header .np-search-pill--trigger {
    display: none;
  }
}
/* ---------- Search pill (used in header + footer) ----------
   Custom HTML form (parts/header.html, parts/footer.html). Layout is icon
   first (submit button) followed by the input — both share one rounded border
   so the pill reads as a single unit, matching the Figma design.
*/
.np-search-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 140px;
  padding: 4px 16px;
  margin: 0;
  border: 1px solid var(--wp--preset--color--black);
  border-radius: var(--np-radius-pill);
  background: transparent;
  color: var(--wp--preset--color--black);
}
.np-search-pill .np-search-pill__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
  color: inherit;
  cursor: pointer;
  flex-shrink: 0;
}
.np-search-pill .np-search-pill__icon svg {
  display: block;
}
.np-search-pill .np-search-pill__input {
  flex: 1;
  min-width: 0;
  width: 100%;
  border: 0;
  background: transparent;
  color: inherit;
  font-family: var(--wp--preset--font-family--sans);
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
  padding: 0;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.np-search-pill .np-search-pill__input::placeholder {
  color: inherit;
  opacity: 1;
}
.np-search-pill .np-search-pill__input::-webkit-search-decoration, .np-search-pill .np-search-pill__input::-webkit-search-cancel-button {
  display: none;
}
.np-search-pill .np-search-pill__label {
  flex: 1;
  text-align: left;
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
}

/* Dark-background variant (footer). */
.np-search-pill--on-dark {
  border-color: var(--wp--preset--color--sand);
  color: var(--wp--preset--color--sand);
}
.np-search-pill--on-dark .np-search-pill__input::placeholder {
  color: var(--wp--preset--color--sand);
  opacity: 0.85;
}

/* Search-trigger variant (button instead of form). Uses the same pill chrome. */
.np-search-pill--trigger {
  cursor: pointer;
  background: transparent;
  width: auto;
  min-width: 110px;
}

/* ---------- Site footer (template part: parts/footer.html) ---------- */
.np-site-footer-wrap {
  margin-top: 0;
}

.np-site-footer {
  background: var(--wp--preset--color--deep-ocean);
  color: var(--wp--preset--color--white);
}
.np-site-footer a {
  color: var(--wp--preset--color--white);
}
.np-site-footer a:hover {
  color: var(--wp--preset--color--sand);
}
.np-site-footer {
  /* Parent has `has-global-padding`, so no own padding-inline here.
        Same constrained-child pattern as the header. */
}
.np-site-footer .np-site-footer__inner {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr auto;
  column-gap: 48px;
  row-gap: 24px;
  align-items: start;
  width: 100%;
  max-width: var(--wp--style--global--content-size, 1200px);
  margin-inline: auto;
  padding-block: 48px;
}
.np-site-footer .np-site-footer__search {
  grid-column: 4;
  justify-self: end;
}
.np-site-footer .np-site-footer__brand p {
  margin: 0;
}
.np-site-footer .np-site-footer__logo img {
  width: 180px;
  height: auto;
}
.np-site-footer .np-site-footer__tagline {
  font-size: 18px;
  font-weight: 500;
  line-height: 1.25;
}
.np-site-footer .np-site-footer__orgnr {
  font-size: 14px;
  opacity: 0.9;
}
.np-site-footer .np-site-footer__heading {
  font-size: 18px;
  font-weight: 500;
  line-height: 30px;
  letter-spacing: 0.02em;
  margin: 0 0 4px;
  color: var(--wp--preset--color--white);
}
.np-site-footer .np-site-footer__body {
  font-size: 14px;
  line-height: 23px;
  letter-spacing: 0.02em;
  margin: 0;
}
.np-site-footer .np-site-footer__body strong {
  font-weight: 500;
}
.np-site-footer .np-site-footer__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 14px;
  font-weight: 500;
  line-height: 30px;
}
.np-site-footer .np-site-footer__links a {
  text-decoration: underline;
}
@media (max-width: 900px) {
  .np-site-footer .np-site-footer__inner {
    grid-template-columns: 1fr 1fr;
  }
  .np-site-footer .np-site-footer__search {
    grid-column: 2;
    justify-self: end;
  }
}
@media (max-width: 600px) {
  .np-site-footer .np-site-footer__inner {
    grid-template-columns: 1fr;
  }
  .np-site-footer .np-site-footer__search {
    grid-column: 1;
    justify-self: start;
  }
}

/* =============================================================================
   Chapter layout (templates/single-np_chapter.html, single-np_commentary.html)
   Two-column grid: sticky TOC sidebar (300px) + main content. The sidebar
   block has its own `position: sticky`; we just need the column to not collapse.
   ============================================================================= */
.np-chapter-layout__columns {
  align-items: flex-start;
}
@media (max-width: 900px) {
  .np-chapter-layout__columns {
    flex-direction: column;
    /* The columns blockGap is `0 48px` (row-gap 0, for the desktop row),
             so the stacked TOC and content touch. Restore the theme's default
             block spacing as a row-gap. The `&.wp-block-columns` bump (0,2,0)
             outranks WP's generated single-class `gap: 0 48px` rule. */
  }
  .np-chapter-layout__columns.wp-block-columns {
    row-gap: 24px;
  }
}

.np-chapter-layout__sidebar {
  flex: 0 0 300px;
  /* Stretch the column to the full row height so the sticky TOC inside it has
     somewhere to travel. The block carries `is-vertically-aligned-top`, whose
     `align-self: flex-start` otherwise shrink-wraps the column to the sidebar's
     own height — leaving `position: sticky` with zero room and no effect.
     `!important` beats WP core's `.wp-block-column.is-vertically-aligned-top`
     (0,2,0). On mobile the row is flex-direction: column, so this just keeps the
     stacked column full-width, matching the width:100% below. */
  align-self: stretch !important;
}
@media (max-width: 900px) {
  .np-chapter-layout__sidebar {
    /* The column carries an inline `flex-basis:300px` (from the block's
             width:300px). Once the row flips to `flex-direction: column`, that
             basis becomes a reserved 300px *height* — an empty gap below the
             collapsed TOC. Override it (!important to beat the inline style) so
             the column is just as tall as its content. */
    flex: 0 0 auto !important;
    width: 100%;
  }
}

.np-chapter-layout__main {
  flex: 1;
  min-width: 0;
}

/* =============================================================================
   Plan archive (templates/archive-np_chapter.html)
   Full-bleed sand-soft band. `<main>` is alignfull + constrained +
   has-global-padding so it follows the same container rules as the rest of
   the site — the inner block aligns with the header/breadcrumb above. The
   ship image is alignfull (escapes the max-width) and absolutely positioned
   to bleed past the viewport's right edge.
   ============================================================================= */
.np-plan-archive {
  position: relative;
  overflow: hidden;
  min-height: 720px;
  /* Constrained child — gets max-width + centering from WP's constrained
        layout on the parent. No own padding-inline; parent's has-global-padding
        handles the viewport-edge inset. */
}
.np-plan-archive .np-plan-archive__inner {
  position: relative;
  z-index: 2;
  /* Neutralise the TOC sidebar's chapter-sidebar chrome so it reads as
           a plain title + list flush inside the band. */
}
.np-plan-archive .np-plan-archive__inner .np-toc-sidebar {
  max-width: 360px;
  margin-inline: 0; /* override constrained centering */
  background: transparent;
  border-radius: 0;
  position: static;
  padding: 0;
  max-height: none;
  overflow: visible;
  /* This landing IS the TOC — never collapse it on mobile, and drop
              the rail's tap-to-expand affordances. */
}
.np-plan-archive .np-plan-archive__inner .np-toc-sidebar .np-toc-sidebar__subtitle,
.np-plan-archive .np-plan-archive__inner .np-toc-sidebar .np-toc-sidebar__chevron {
  display: none;
}
.np-plan-archive .np-plan-archive__inner .np-toc-sidebar .np-toc-sidebar__panel {
  display: block !important;
}
.np-plan-archive .np-plan-archive__inner .np-toc-sidebar .np-toc-sidebar__header {
  cursor: default;
  margin: 0;
  padding: 0;
  border-bottom: none;
}
.np-plan-archive .np-plan-archive__inner .np-toc-sidebar__title {
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--display);
  line-height: 1.1;
  margin: 0 0 28px;
}
.np-plan-archive .np-plan-archive__inner .np-toc-sidebar__item {
  padding: 12px 0;
}
.np-plan-archive {
  /* Right-hand image panel. Anchored to the viewport's right edge and filling
        the band's full height, with a large convex curve on its LEFT edge so it
        reads as a rounded shape bulging into the sand band. The panel's
        background is the artwork's own water colour (#97c0d9): the ship image is
        pinned to the left at its natural aspect ratio (so it never distorts),
        and the matching blue fills the space to its right — on wide screens the
        sea appears to continue past the artwork instead of the image stretching.
        (The alignfull negative margins WP adds are irrelevant: position:absolute
        takes the element out of flow.) */
}
.np-plan-archive .np-plan-archive__ships {
  position: absolute;
  /* Pin to the top-right and cap the height at the viewport: a long,
           fully-expanded TOC can make the band very tall, and stretching the
           artwork to match would blow it up. Anchoring top + max-height keeps
           it a fixed-feeling panel; the sand band simply shows below it. */
  top: 0;
  right: 0;
  height: 100%;
  max-height: 100vh;
  /* Anchor the panel just past the centred TOC column rather than at a raw
           viewport %. The inner content is `constrained` (max 1200px, centred),
           so its right side drifts inward at ~½ the added width; tracking that
           same rate keeps a constant gap to the list at every width instead of
           the list eventually colliding with the artwork on ultra-wide screens.
           (1200px = theme.json contentSize; 400px ≈ TOC width + gutter.) */
  left: max(430px, (100vw - 1200px) / 2 + 400px);
  margin: 0;
  background: #97c0d9;
  border-radius: 600px 0 0 600px;
  overflow: hidden;
  z-index: 1;
  pointer-events: none;
}
.np-plan-archive .np-plan-archive__ships img {
  position: absolute;
  top: 0;
  bottom: 0;
  /* Shift the artwork left so the empty water on its left third is
              clipped by the bulge and the vessels read centred. The band height
              is fixed (min-height), so the image width is stable and a px nudge
              holds across desktop widths; as the viewport widens the panel's
              left edge (a %) outruns this offset, growing the blue sea on the
              right — the "continues to the right" illusion. */
  left: 0;
  height: 100%;
  width: auto;
  max-width: none;
}
.np-plan-archive .np-plan-archive__ships {
  /* Concentric arc line hugging the top-right corner. Fixed size so it
           reads identically however wide the panel grows — "always in the same
           position". */
}
.np-plan-archive .np-plan-archive__ships::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 269px;
  height: 269px;
  background: url(../images/overlay-line.svg) top right/contain no-repeat;
  pointer-events: none;
}
.np-plan-archive {
  /* Stack on small screens: title + list on top, the image as a full-width
        band pinned to the bottom (curved on its top-left instead of its left). */
}
@media (max-width: 900px) {
  .np-plan-archive {
    min-height: 0;
    padding-bottom: 340px !important;
  }
  .np-plan-archive .np-plan-archive__inner .np-toc-sidebar {
    max-width: none;
  }
  .np-plan-archive .np-plan-archive__ships {
    inset: auto 0 0 0;
    height: 320px;
    border-radius: 0;
  }
  .np-plan-archive .np-plan-archive__ships img {
    inset: 0;
    width: 100%;
    object-fit: cover;
    object-position: 55% 35%;
  }
  .np-plan-archive .np-plan-archive__ships::after {
    width: 160px;
    height: 160px;
  }
}

/* The translations archive reuses this section but with a full-colour dusk
   photo instead of the flat-water ship illustration, so the "blue continues
   right" fill has no single edge colour to blend into. Cover the whole panel
   with the photo there and drop the leftward nudge; the dark fallback only
   shows before the image loads. */
.post-type-archive-np_translation .np-plan-archive__ships {
  background: #093164;
}
.post-type-archive-np_translation .np-plan-archive__ships img {
  inset: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/**
 * Search-term highlighting.
 *
 * Two places show a `mark.np-hl`: the search results list, where the server marks
 * the matched words in each excerpt, and the destination page, where
 * assets/js/search-highlight.js marks them after the reader follows a result.
 * One rule serves both, which is what keeps them looking like the same idea.
 *
 * The slug is `orange` — theme.json has no `brand`, and a wrong slug yields an
 * undefined var that silently collapses to the fallback, quietly cutting the
 * palette out of the loop.
 *
 * Deliberately not that orange at full strength: this sits *inside* running
 * legal prose, often next to a link, and a saturated block would read as emphasis
 * the drafters put there. A pale wash of the same hue reads as "the software
 * found this" instead.
 */
mark.np-hl {
  background-color: color-mix(in srgb, var(--wp--preset--color--orange, #eb5d40) 22%, transparent);
  color: inherit;
  padding: 0 0.12em;
  border-radius: 2px;
}
a mark.np-hl {
  color: inherit;
}
