﻿/* ============================================================================
   screens.css - what one screen says.

   Screen-specific blocks, each feature-prefixed (.collection-answer*,
   .feedback-*, .delivery-*, .auth-*, .userinfo-*, .styleguide-*) and each with
   a comment saying why it exists. What more than one screen carries belongs in
   portal.css.

   Loads LAST in the chain (tokens -> Bootstrap -> Kendo swatch -> font-icons ->
   bridge -> portal -> screens), so a screen rule wins on source order. That is
   the point: a deviation should win because it is a deviation, not because
   somebody threw an id or a second class at it. Where a block still carries an
   id, it is there to scope, not to add weight.

   No colour literals - only var(--tdm3-...) from tokens.css. Sizes on the 4px
   scale, exceptions named with their measurement in
   DesignSystemGuardTests.Every_spacing_literal_is_on_the_scale_or_named.

   Working rules and naming: docs/design-system/conventions.md.
   ========================================================================= */

/* Sticky footer.

   60px, three times, and it has to be the same number three times: the footer is
   out of flow, so <body>'s bottom margin is what reserves room for it and the
   line-height is what centres its text. Let them drift and the footer either
   overlaps the last line of the screen or leaves an empty band.

   Off the 4px scale on purpose: it comes from the project template, was never a
   design choice, and re-scaling it moves every screen. Named in
   DesignSystemGuardTests.Every_spacing_literal_is_on_the_scale_or_named. */
html {
  position: relative;
  min-height: 100%;
}

body {
  /* Margin bottom by footer height */
  margin-bottom: 60px;
}
.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  white-space: nowrap;
  /* Set the fixed height of the footer here */
  height: 60px;
  line-height: 60px; /* Vertically center the text there */
}

/* ============================================================================
   The answer dialog on the collection screen.

   THE SIZES IN THIS BLOCK AND IN .feedback-history BELOW ARE OFF THE 4px SCALE,
   and that is one decision rather than seven slips. This lays out five answer
   cards with a timeline under them, in a 500px dialog inside a grid row - the
   densest piece of the application. The scale starts at 4 and then jumps to 8
   and 12, and at this density that is the difference between "a list" and "five
   blocks". Measured when the screen was drawn: 2, 6, 7, 10, 14 and 20px. All of
   them are named in
   DesignSystemGuardTests.Every_spacing_literal_is_on_the_scale_or_named;
   rounding them is a design question for whoever redraws this screen.
   ========================================================================= */

.collection-answer-window .collection-answer-container {
    width: auto;
}

/* Who and how much on the left, the invoice on the right. Own flex rather than a Bootstrap row:
   this sits in a Kendo window, where .row/.col-* breaks on box-sizing (Screen and form
   conventions, "Layout inside Kendo contexts"). */
.collection-answer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--tdm3-space-3);
    padding-bottom: 6px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--tdm3-divider);
}

/* The name takes what is left. min-width: 0 because a flex item will not otherwise shrink below
   its min-content width, and a long payer name would push the button beside it out of the
   window. */
.collection-answer-identity {
    flex: 1 1 auto;
    min-width: 0;
}

/* A reserved slot rather than a bare button: Kendo's visible binding writes display: none, so on
   a request without an invoice document the header would fall back to the height of the text on
   the left. The height is derived from the same tokens .tdm3-btn builds its box from, so it
   follows a change in button size instead of needing to be measured again. */
.collection-answer-header-action {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    min-height: calc(var(--tdm3-font-size-base) * var(--tdm3-line-height-tight) + 2 * var(--tdm3-space-1) + 2px);
}

/* The label does not wrap: a two-line button would make the header taller than the slot above
   reserves. */
.collection-answer-download {
    white-space: nowrap;
}

/* Only under the answer that is selected. Five explanations at once made the list four times as
   tall as the choice it presents, and the one that mattered was whichever was being considered.
   Indented to line up under the option label, so it reads as belonging to that answer and not as
   the start of the next one. */
.collection-answer .answer-help {
    display: none;
    margin-left: var(--tdm3-space-5);
    font-size: 0.875rem;
    line-height: 1.35;
    color: var(--tdm3-text-muted);
}

.collection-answer .list-group-item.answer-selected .answer-help {
    display: block;
}

/* The whole row is the target, so it has to look like one. */
.collection-answer .list-group-item {
    padding: 7px 10px;
    cursor: pointer;
}

.collection-answer .list-group-item:hover {
    background-color: var(--tdm3-surface-muted);
}

.collection-answer .list-group-item .k-radio-label {
    cursor: pointer;
}

/* The answer on record, and the one being picked. Without it the selected radio is the only mark
   on a list of lines that otherwise look identical. --tdm3-color-primary on --tdm3-color-info-bg
   is the radio-card pattern from components.md; measured 5.49:1. */
.collection-answer .list-group-item.answer-selected {
    background-color: var(--tdm3-color-info-bg);
    border-left: 3px solid var(--tdm3-color-primary);
}

/* The slot around "pick an answer first". Revealing that message pushes what follows down 65px
   (measured, fr-BE) because it appears in answer to pressing Confirm - the button moves out from
   under the pointer. No height is reserved for it: that cost an empty band in EVERY dialog, and a
   missing answer is the exception. The shift is the cheaper of the two, and whoever sees the
   message has just noticed nothing happened.

   `display: flow-root` makes the slot its own formatting context, so the alert's bottom margin
   stays inside it instead of leaking through. Not `overflow: hidden` for the same effect: that
   would silently CLIP a longer translation, where flow-root lets the slot grow. */
.collection-answer .answer-required-slot {
    display: flow-root;
}

/* One thing left on this line: the history toggle. The invoice download moved to the header -
   history is material to check the answer against, the invoice is the subject of the dialog
   itself. Still a flex row with its margins, so the fold-out panel below starts where it always
   did; what went with the second item is the column rhythm it needed. */
.collection-answer .answer-references {
    display: flex;
    align-items: baseline;
    margin: var(--tdm3-space-2) 0;
    font-size: 0.875rem;
}

.collection-answer .answer-chevron {
    margin-right: 2px;
    vertical-align: -1px;
    transition: transform 0.12s ease-out;
}

.collection-answer #historyToggle.is-open .answer-chevron {
    transform: rotate(90deg);
}

.collection-answer #historyToggle:hover {
    text-decoration: underline;
}

/* Under the whole line rather than under the link that opened it, and always the full width - it
   used to be a <details> inside the flex row, which jumped to a row of its own on opening. */
.collection-answer .feedback-history-panel {
    margin: 0 0 10px;
}

/* One line per step, two columns of its own. The date column is wide enough for dd/mm/yyyy and
   nothing more, so what happened starts at the same place on every line.

   Drawn as the thing it is: a run of events on a line, newest at the top. The rail and the dots
   carry that; the rows themselves stay plain, because five steps do not need a table. */
.feedback-history {
    margin: 0;
    padding: 2px 0 2px 7px;
    list-style: none;
    font-size: 0.875rem;
    line-height: 1.5;
    border-left: 1px solid var(--tdm3-divider);
}

.feedback-history > li {
    position: relative;
    display: flex;
    gap: 10px;
    padding: 2px 0 2px 14px;
}

.feedback-history > li::before {
    content: "";
    position: absolute;
    left: -11px;
    top: 0.6em;
    width: var(--tdm3-station-size);
    height: var(--tdm3-station-size);
    border-radius: 50%;
    background-color: var(--tdm3-surface);
    border: var(--tdm3-station-ring) solid var(--tdm3-border);
}

/* Where the collection process stands. The steps arrive newest first, so that is this one. */
.feedback-history > li:first-child::before {
    background-color: var(--tdm3-color-primary);
    border-color: var(--tdm3-color-primary);
}

.feedback-history-date {
    flex: 0 0 5.5rem;
    color: var(--tdm3-text-muted);
    font-variant-numeric: tabular-nums;
}

/* Where a step went, beside what it was - the e-mail address the invoice was sent to. Beside rather
   than in a column of its own: one step in five carries one, so a column would be four empty cells
   and an address. */
.feedback-history-detail {
    color: var(--tdm3-text-muted);
}

/* How long the wait before this step was, at the end of the line and never on its own: it reads as
   an annotation on what happened, not as a second thing that happened. Steps that fall on the same
   day carry none at all. */
.feedback-history-gap {
    color: var(--tdm3-text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}


/* The Info column of the collection grid. Every row is one line tall, answered or not: the badges
   used to wrap onto a second line as soon as a row carried an answer, so the grid changed row
   height as you worked through it. A badge never breaks inside itself either - a pill split over
   two lines is worse than one that is clipped, and the long form is in the tooltip. */
.k-grid td.feedback-info-cell {
    white-space: nowrap;
}

/* Both buttons on one line. Their column is the one the table squeezes when something else asks for
   room, and squeezed it puts the second button on a line of its own - which is the row height
   jumping again, from the other side. */
.k-grid td.feedback-command-cell {
    white-space: nowrap;
}

/* The expanded row under a collection request: what was said, and what happened, side by side.
   box-sizing is set explicitly because the grid does not leave it at Bootstrap's border-box, which
   is what made a pair of col-md-6 too wide for their own row and drop underneath each other. */
.feedback-context {
    display: flex;
    flex-wrap: wrap;
    /* 10px vertical stays literal - it is the distance between two wrapped halves of one panel,
       and 8 or 12 changes that legibility measurably. 48px is --tdm3-space-7 but shares the
       declaration, so the whole line is a named exception (see the spacing guard). */
    gap: 10px 48px;
    padding: var(--tdm3-space-1) 0 var(--tdm3-space-2);
}

/* Neither column grows. Letting them share the row equally put the steps against the right edge of
   a row that is over 1500px wide, with the gap between the two halves doing all the growing. */
.feedback-context > div {
    box-sizing: border-box;
    flex: 0 1 auto;
    min-width: 0;
}

/* Room for a remark of a few lines without the steps starting right against it, and a fixed place
   for the steps to begin whatever the remark says. */
.feedback-context > div:first-child {
    flex-basis: 360px;
    max-width: 360px;
}

.feedback-context-label {
    margin-bottom: var(--tdm3-space-1);
    font-weight: 500;
    color: var(--tdm3-text-subtle);
}

/* The hover suppression on an expanded row moved to portal.css in migration step 2, for the same
   reason as the dialog padding above - and because the colours it restored were the Metro theme's
   resting colours, which the TDM3 theme no longer uses. */

/* Column widths come from the colgroup, not from what happens to be in the cells. The grid lays its
   table out automatically, so every column shifted sideways the moment one cell's content changed
   width - answer a request and the whole grid moved under the pointer. Kendo already writes the
   widths into a colgroup; this is what makes them binding. */
.feedback-collection-grid table {
    table-layout: fixed;
}

/* ============================================================================
   The delivery method editor (Views/Shared/_DeliveryMethodEditor.cshtml).

   Everything here hangs on #DeliveryMethod-AddressForm to SCOPE it, not to win
   on weight - screens.css loads last and wins anyway. The class names inside
   (.delivery-note, .delivery-field, .delivery-actions) are general enough that
   without the id they would promise a shared pattern they are not; that pattern
   would belong in portal.css. The id is the container's own, read by the
   editor's script, so it is not a styling hook.

   What is shared with other screens (the k-invalid border, the validator
   tooltip, the k-label alignment) lives in portal.css.
   ========================================================================= */

/* Kendo gives a k-edit-form-container 400px; this holds three sections beside a card and needs
   more. The window itself is 780px (set in openEditWindow): 1 + 14 + 750 + 14 + 1, so the margin
   on the right equals the one on the left - at 850px all the slack hung on the right (measured:
   14px left, 84px right). */
#DeliveryMethod-AddressForm {
    width: 750px;
    padding-left: var(--tdm3-space-5);
    padding-right: var(--tdm3-space-5);
}

/* WHO AND HOW MUCH. The same shape as .collection-answer-header above: name in bold, number and
   amount muted beside it, a hairline under it.

   A <legend> is where three stylesheets contradict each other, so all four declarations were
   measured in the browser rather than reasoned out of the sources:

   - `border-bottom-style: solid` is REQUIRED. Bootstrap gives a legend no border, and a width
     without a style computes back to 0 - measured `0px none`, so the hairline was not there at
     all while the line below asked for it.
   - `font-size` has to be explicit: Bootstrap puts a legend at 1.5rem (21px), so this header was
     21px bold while the answer dialog puts its payer at the ordinary 14px. Two dialogs asking the
     same question have the same header.
   - `text-transform: none` against the theme, which uppercases a legend - a proper name never
     should be.
   - The bottom margin is a step off the scale instead of Bootstrap's 0.5rem.

   No flex row: there is one thing in it, and some browsers give a <legend> inside a <fieldset> a
   box model of its own that does not cooperate with flex. */
#DeliveryMethod-AddressForm .delivery-header {
    margin-bottom: var(--tdm3-space-3);
    padding-bottom: var(--tdm3-space-2);
    border-bottom: 1px solid var(--tdm3-divider);
    font-size: var(--tdm3-font-size-base);
    text-transform: none;
}

#DeliveryMethod-AddressForm .delivery-header-meta {
    font-weight: var(--tdm3-font-weight-normal);
}

/* WHY AM I HERE, in one block. The category message and TDM3's free remark used to be two
   callouts in two colours stacked on each other, with the bpost verdict in a third under them:
   three banners half repeating each other, in no order. One neutral base callout now - explanation,
   not status - with the two short sentences side by side rather than stacked, each under its own
   caption. That leaves the status variants in this dialog as what they should be: the cost warning
   and the bpost panel. */
#DeliveryMethod-AddressForm .delivery-context-columns {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tdm3-space-2) var(--tdm3-space-5);
}

/* Neither column grows past the other; on a narrow window they wrap and stack instead of
   squeezing two sentences onto unreadably thin columns. */
#DeliveryMethod-AddressForm .delivery-context-column {
    flex: 1 1 220px;
    min-width: 0;
}

#DeliveryMethod-AddressForm .delivery-context-line {
    margin: 0;
}

/* The caption above each sentence, not a bold "TDM3:" in front of it: that gives the attribution
   the weight of a heading, and a colon does not travel between languages (French puts a space
   before it). Both columns share this one label style, left and right alike.

   --tdm3-text-subtle rather than --tdm3-text-muted: this sits on the callout's tinted surface,
   where muted measures 4.30:1 and accessibility.md forbids it. Subtle measures 7.50:1. */
#DeliveryMethod-AddressForm .delivery-context-label {
    display: inline-flex;
    align-items: center;
    gap: var(--tdm3-space-1);
    margin-bottom: var(--tdm3-space-1);
    color: var(--tdm3-text-subtle);
    font-size: var(--tdm3-font-size-sm);
}

/* Same colour as the label it sits beside - a mark, not a status. */
#DeliveryMethod-AddressForm .delivery-context-human-mark {
    color: var(--tdm3-text-subtle);
}

/* The three delivery methods as one row of choices: equal width, the chosen one filled. */
#DeliveryMethod-AddressForm .delivery-button-group {
    display: flex;
    gap: var(--tdm3-space-3);
    margin-bottom: var(--tdm3-space-5);
}

/* Side padding is --tdm3-space-4, not -5: 20px sat exactly between two tokens and the
   measurement breaks the tie. Kendo puts `white-space: nowrap` on a k-button, so these three are
   together as wide as their labels, and in French the row fills its width exactly:
   217.0 + 244.0 + 217.0 plus two gaps = 702px in 702px available. Rounding up would overflow.

   The border is --tdm3-border-strong: #CCCCCC measures 1.61:1 against white, far under the 3:1
   WCAG 1.4.11 asks for the boundary of a control. This is the unchosen method; the chosen one
   sits on a filled surface and sets its own border colour. */
#DeliveryMethod-AddressForm .delivery-button-group button {
    flex: 1;
    padding: var(--tdm3-space-3) var(--tdm3-space-4);
    border: 2px solid var(--tdm3-border-strong);
    background-color: var(--tdm3-surface);
    font-weight: var(--tdm3-font-weight-medium);
    cursor: pointer;
    transition: all 0.2s;
}

#DeliveryMethod-AddressForm .delivery-button-group button:hover {
    border-color: var(--tdm3-color-primary);
}

/* Visible focus on the three delivery methods. They stood at `outline-style: none` and
   `box-shadow: none` - invisible with the mouse and unreachable with the keyboard, while this is
   the first choice the dialog asks for. Same ring as .tdm3-btn in portal.css, and accent blue for
   the same reason: --tdm3-sky does not make 3:1 for non-text (accessibility.md, rule 1). */
#DeliveryMethod-AddressForm .delivery-button-group button:focus {
    outline: 2px solid var(--tdm3-color-focus);
    outline-offset: 1px;
}

/* The chosen delivery method. The class name comes from the MVVM binding
   (attr: { class: buttonClass... }) and is ours: it used to be `k-primary`, but Kendo 2026 no
   longer knows that name as a button modifier, so it was a rule of ours aiming at a Kendo name.
   Both sides were renamed together. */
#DeliveryMethod-AddressForm .delivery-button-group button.delivery-button-selected {
    border-color: var(--tdm3-color-primary);
    background-color: var(--tdm3-color-primary);
    color: var(--tdm3-color-primary-contrast);
}

/* The icon sits on the baseline of the button text. */
#DeliveryMethod-AddressForm .delivery-button-icon {
    vertical-align: text-bottom;
}

/* `flow-root` is load-bearing: each section ends in a 12px bottom margin, and outside a block
   formatting context that margin escapes the container - so the `min-height` sizeEditWindowOnce
   reserves does not cover it, and the section that fills the reservation costs 12px more than the
   ones that do not. That is a 12px jump of the method buttons on switching. */
#DeliveryMethod-AddressForm .delivery-form-container {
    display: flow-root;
    margin-top: var(--tdm3-space-5);
}

/* Kendo spaces fields for a full-page form; in a dialog of three stacked sections that is too
   much air. */
#DeliveryMethod-AddressForm .k-form-field {
    margin-bottom: var(--tdm3-space-3);
}

/* One label column for all three sections. The theme gives a label 25% of its row, and with
   three sections of different field widths that is three different label columns.

   `flex: 0 0 100px` beside the width: a label is a flex item in a
   `.k-form-horizontal .k-form-field`, and without a fixed basis the column shrinks with whatever
   stands next to it - the French "Numéro de boîte" pulled one row's label column narrower than the
   row above, which is exactly the grid this rule sets out to hold. */
#DeliveryMethod-AddressForm .delivery-form-label {
    width: 100px;
    flex: 0 0 100px;
}

/* A row WITHOUT a label starts where the fields start, not against the margin. Those are the
   checkboxes and the practice e-mail address: their own text is the label, so there is no second
   one to put in the column. Binds on what actually distinguishes such a row - if the field wrapper
   comes first, no label preceded it - instead of on an empty <label> as column filler.

   110px is the label column (100px above) plus the 10px `margin-right` the theme gives a label in
   a horizontal form. The max-width corrects the theme's `calc(100% - 25% - 10px)`, which assumes
   25% and so not our column. */
#DeliveryMethod-AddressForm .k-form-field > .k-form-field-wrap:first-child {
    margin-left: 110px;
    max-width: calc(100% - 110px);
}

/* Two fields side by side, each at its own size: number + box, postal code + city. Kendo's
   `k-d-grid k-grid-cols-2` split the row into two EQUAL columns of ~325px for fields of 100 and
   75px, which is what left the box number stranded on the right. Own flex with explicit
   box-sizing, as docs/Screen and form conventions.md prescribes inside a Kendo container. */
#DeliveryMethod-AddressForm .delivery-field-row {
    display: flex;
    gap: var(--tdm3-space-3);
    box-sizing: border-box;
}

/* One field, `flex: 0 0 auto` so the column is as wide as the field in it rather than half the
   row. */
#DeliveryMethod-AddressForm .delivery-field {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    box-sizing: border-box;
}

/* A checkbox with its label text BESIDE it, also when that text does not fit on one line. As an
   inline-block beside an inline input, a label that did not fit dropped underneath the checkbox
   entirely - in French that happened to all three boxes.

   One consumer, so this block and not portal.css: conventions.md only allows a shared pattern once
   three screens needed it, and the other checkboxes in the application (Testdata) use Bootstrap's
   `.form-check`. */
#DeliveryMethod-AddressForm .delivery-checkbox-row {
    display: flex;
    align-items: flex-start;
    gap: var(--tdm3-space-2);
    box-sizing: border-box;
}

/* The box does not shrink and sits on the label's first line. The margin replaces the theme's
   `margin-right: .4ex` on a bare checkbox, which added to the gap. */
#DeliveryMethod-AddressForm .delivery-checkbox-row > input[type="checkbox"] {
    flex: 0 0 auto;
    margin: var(--tdm3-space-1) 0 0;
}

/* Everything belonging to the label text sits in this column: the text, the help line under it
   and the error message. They therefore line up under the LABEL TEXT rather than under the
   checkbox, without repeating a checkbox width as a number anywhere. */
#DeliveryMethod-AddressForm .delivery-checkbox-body {
    flex: 1 1 auto;
    min-width: 0;
}

/* WHAT THE CHECKBOX MEANS, always readable. It used to appear on ticking, out of a 275px column
   that reserved 78px for it - which bought 78px of dead height in the normal (unticked) case, and
   a consequence you could only read after choosing it. A permanent help line under the label costs
   neither: nothing is revealed, so nothing moves.

   Shape comes from .tdm3-help (portal.css). Only the reading width is set here - a help line
   across the full 592px of this column reads as a second paragraph rather than as a caption to the
   label above it. */
#DeliveryMethod-AddressForm .delivery-checkbox-help {
    max-width: 480px;
}

/* Bootstrap gives every label 0.5rem of bottom margin (7px on this root, off the scale); in a row
   of one label that is loose space under the text. */
#DeliveryMethod-AddressForm .delivery-checkbox-body > label {
    display: block;
    margin: 0;
}

/* A section in two columns: the fields on the left, the original value as a reference card on the
   right - it is what someone checks the fields against, so it belongs beside them and not under
   them. `align-items: flex-start` keeps the card from growing with the form.

   Named section-neutrally because the e-mail section has the same layout: field left, the bounced
   address right. */
#DeliveryMethod-AddressForm .delivery-section-layout {
    display: flex;
    align-items: flex-start;
    gap: var(--tdm3-space-5);
    box-sizing: border-box;
}

/* `min-width: 0` is what keeps the dialog free of horizontal overflow: without it a flex item
   refuses to go narrower than its content, and the French form pushes the card out of the window.

   The max-width holds the column at 428px even when the card is absent - the e-mail section's card
   hangs on `visible: hasOriginalEmail`, and a bare `flex: 1 1 auto` would let the same section be
   two different widths. The sum is the card beside it: 702 (section) - 250 (card) - 24 (gap). */
#DeliveryMethod-AddressForm .delivery-section-fields {
    flex: 1 1 auto;
    min-width: 0;
    max-width: calc(100% - 250px - var(--tdm3-space-5));
}

/* Explanation above a section: smaller than the fields under it, and no wider than the field
   column under it. Across the full 702px the grey explanation and the cost warning read as banners
   over a form using half that width; now their right edge follows the fields and the card on the
   right stands free. Same sum as .delivery-section-fields above.

   The callouts ABOVE the button row (the context block and #address-general-error) stay full
   width on purpose: they belong to the whole dialog rather than to a section. They do not carry
   `delivery-note`, and neither does the bpost panel at the bottom. */
#DeliveryMethod-AddressForm .delivery-note {
    font-size: var(--tdm3-font-size-sm);
    max-width: calc(100% - 250px - var(--tdm3-space-5));
}

/* The postal section's two notes on ONE row. Stacked they were both 428px wide with empty space
   beside them - two rows costing vertical space the dialog used for nothing.

   The split follows the two-column rhythm the dialog already has: the explanation left at field
   column width (428px, from .delivery-note above), the warning right in the card's column (250px).
   That puts the right edge of everything in this panel on one line.

   WHY 428/250 AND NOT 50/50, measured in French where both texts are longest (height including
   the callout's 12px padding):

     width     explanation   warning
     250px     60px (2 ln)   78px (3 ln)   <-- chosen for the warning
     339px     60px (2 ln)   60px (2 ln)   (the 50/50 variant)
     428px     42px (1 ln)   60px (2 ln)   <-- chosen for the explanation

   At 250px the French warning stays on three lines; 50/50 would only have become the reasonable
   alternative at four. The row is as tall as the taller of the two (FR 90px against 126px stacked)
   and their tops line up.

   `flex: 1 1 auto` plus the max-width does two things at once: with the warning present the
   explanation grows to exactly 428, and WITHOUT it (`visible: isDeliveryCostBillable` takes it out
   of flow) it stays at 428 instead of filling the row. */
#DeliveryMethod-AddressForm .delivery-note-row {
    display: flex;
    align-items: flex-start;
    gap: var(--tdm3-space-5);
    box-sizing: border-box;
}

#DeliveryMethod-AddressForm .delivery-note-row > .delivery-note {
    flex: 1 1 auto;
}

/* The note beside the explanation, in the card's column. The `.delivery-note-row >` in front is
   not redundant: without it this selector weighs one class less than the rule above and the
   warning inherits its `flex: 1 1 auto` - measured, the two then split the row by text length
   (287.63 and 390.38px) instead of 428 and 250. */
#DeliveryMethod-AddressForm .delivery-note-row > .delivery-note-aside {
    flex: 0 0 250px;
}


/* This dialog's callouts came off Bootstrap's `.alert`, which carried margin-bottom: 1rem (14px
   on this root, off the scale). --tdm3-space-3 is the step below. The callout itself deliberately
   carries no margin - its other consumers (AccessDenied, LinkExpired, Expired) set their own. */
#DeliveryMethod-AddressForm .tdm3-callout {
    margin-bottom: var(--tdm3-space-3);
}

/* WHAT BPOST REPORTED BACK, with the action that belongs to it, AT THE BOTTOM OF THE SECTION -
   directly above the action buttons. Halfway down the form it put "Save anyway" floating in the
   middle of the dialog while "Save" sat bottom right - two equally weighted save choices in two
   places - and starting at the field column it read as a field rather than as the verdict on the
   whole address. Full section width now, with the footer Save stepping aside while the panel is up
   (showFooterSave).

   .delivery-bpost-slot reserves NO height, deliberately. A computed slot of ~111px stood in the
   ordinary case - address untouched, bpost not even consulted - as an empty gap in the form, and
   the gap is worse than the movement it prevents. The panel only appears in answer to pressing
   Save and brings its own buttons, so the footer buttons it pushes down are not the next click
   target. The exception is written up in docs/Screen and form conventions.md ("Dialogs that hold
   still"). */

/* Text above, buttons below. A flex column rather than blocks, so the space between them is a
   step off the scale instead of the margin of whatever happens to be in it. */
#DeliveryMethod-AddressForm .delivery-bpost-panel {
    display: flex;
    flex-direction: column;
    gap: var(--tdm3-space-2);
}

#DeliveryMethod-AddressForm .delivery-bpost-actions {
    display: flex;
    gap: var(--tdm3-space-2);
}

/* WHAT BPOST FOUND, PER FIELD. One line each, the field name in a 100px column - the width of
   .delivery-form-label, so the list keeps the label grid of the form above it and reads as a
   definition list. No bullets: these are two columns, not an enumeration.

   On section width, which is the whole reason the list exists: under a 100px number field the same
   sentence wrapped to four lines. The French "Numéro de boîte" is the longest field name and fits
   well inside 100px; should a name ever exceed it, only that line's text shifts - the column is a
   min-width, not a clip. */
#DeliveryMethod-AddressForm .delivery-bpost-findings {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--tdm3-font-size-sm);
}

#DeliveryMethod-AddressForm .delivery-bpost-finding-field {
    display: inline-block;
    min-width: 100px;
    padding-right: var(--tdm3-space-2);
    font-weight: var(--tdm3-font-weight-medium);
}

/* The city beside a street name in the lookup list: what tells two streets of the same name
   apart, not the name itself - so smaller and muted. */
.delivery-suggestion-place {
    color: var(--tdm3-text-muted);
    font-size: var(--tdm3-font-size-sm);
}

/* kendoAutoComplete wraps the street field in a <span class="k-autocomplete"> and copies the
   field's classes onto it. Without these two rules wrapper AND field both carry the 250px of
   .delivery-input-street, and the field runs outside its own wrapper by its padding. The wrapper
   takes the size, the field fills it. */
#DeliveryMethod-AddressForm span.k-autocomplete.delivery-input-street {
    width: 250px;
}

#DeliveryMethod-AddressForm span.k-autocomplete > input.delivery-input-street {
    width: 100%;
}

/* The message under Remark only appears on SAVE - "you did not change the address, so say why" -
   and Remark is the last field of the section, so without reserved room it pushes the action
   buttons down at the moment someone presses Save.

   This is the ONLY reserved slot left in the dialog, and the difference is the reason: what
   appears here is something the reader must NOT move to - the button they just pressed is below it
   - whereas the bpost panel IS the next click target and reserves nothing.

   The height is DERIVED rather than measured, like .collection-answer-header-action: two lines of
   --tdm3-font-size-sm at --tdm3-line-height-tight, plus the --tdm3-space-1 top margin .tdm3-error
   brings. Two lines is what the text needs at this field's width (Dutch just runs past one line,
   French fills two). If UserRemark_RequiredWhenAddressUnchanged gets longer, that 2 has to grow
   with it - too small and the buttons shift after all. */
#DeliveryMethod-AddressForm .delivery-remark-error-slot {
    min-height: calc(2 * var(--tdm3-font-size-sm) * var(--tdm3-line-height-tight) + var(--tdm3-space-1));
    box-sizing: border-box;
}

/* Each field as wide as what goes in it - a box number does not need a street-sized box. */
#DeliveryMethod-AddressForm .delivery-input-street { width: 250px; }
#DeliveryMethod-AddressForm .delivery-input-number { width: 100px; }
#DeliveryMethod-AddressForm .delivery-input-box { width: 75px; }
#DeliveryMethod-AddressForm .delivery-input-postalcode { width: 100px; }
#DeliveryMethod-AddressForm .delivery-input-city { width: 175px; }

/* 311px is derived, not chosen. The e-mail section carries the same two-column layout as the
   postal one, and at 400px the field did not fit: 110 (label column) + 400 + 24 (gap) + 250 (card)
   = 784 in a section of 702.

     702 (section) - 250 (card) - 24 (gap)   = 428  left column
     428 - 25% (Kendo's label column) - 10px = 311  field wrapper

   So 311 fills that wrapper exactly; one pixel more and the field sticks out of the column it
   shares with the address fields. Measured it shows over 40 characters, and a longer address
   scrolls inside the field the way any text box does. */
#DeliveryMethod-AddressForm .delivery-input-email { width: 311px; }

/* The country picker is a plain <select>, and its whole appearance is ours. It used to carry
   `k-dropdown` beside this class; in Kendo 2026 that class only lives inside the pivot
   configurator, the filter menu and the calculated-field buttons, so on a bare select everything
   the 2021 theme gave it fell away. Measured with the dialog open, 2021 against 2026:

     border   #6C757D          ->  rgb(118,118,118), the browser's own
     padding  5.25px / 10.5px  ->  0 / 0
     width    150px            ->  100px (intrinsic)

   The four declarations below put exactly that back and no more, with the values of the text field
   beside it. They belong here rather than in portal.css: this is not widget chrome but the field
   look from components.md on an element that is not a widget.

   The height is a min-height because neither padding nor line-height does anything: Chrome fixes
   the height of a <select> with appearance:auto to its own text metrics. Measured in the running
   app, padding 7px and line-height 1.5 both left 31.83px untouched; only min-height moved it.
   33.5px is the measured height of the text field beside it, so the two kinds line up. */
#DeliveryMethod-AddressForm .delivery-select-country {
    width: 100%;
    max-width: 150px;
    min-height: 33.5px;
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--tdm3-border-field);
    border-radius: var(--tdm3-radius);
    vertical-align: middle;
    background-color: var(--tdm3-surface);
    color: var(--tdm3-text);
}

#DeliveryMethod-AddressForm .delivery-select-country:focus {
    border-color: var(--tdm3-color-focus);
    outline: 2px solid var(--tdm3-color-focus);
    outline-offset: 1px;
}

/* Reading width for the explanation of delivery by the practice. */
#DeliveryMethod-AddressForm .delivery-practice-text {
    max-width: 600px;
}

/* The delivered address, as a card beside the form. A delivered address is reference information,
   not a warning, so it sits on .tdm3-card rather than Bootstrap's `.card.border-warning` - which
   gave it a yellow border with !important out of bootstrap.css. A flex item of
   .delivery-section-layout: `flex: 0 0 250px` rather than a max-width, so the card keeps its
   column beside a form that fills the rest. */
#DeliveryMethod-AddressForm .delivery-input-address-card,
#DeliveryMethod-AddressForm .delivery-original-email-card {
    flex: 0 0 250px;
}

/* The bounced-e-mail card shares the column, and the rule, of the address card above. What it
   adds: an e-mail address is one word without break points, so without this a long one pushes the
   card wider than its column. */
#DeliveryMethod-AddressForm .delivery-original-email-card {
    overflow-wrap: anywhere;
}

/* On .tdm3-card the title is simply the card's first line, so only the text size is set here:
   16px navy over a 14px address reads, in a 250px card, as a second dialog title. */
#DeliveryMethod-AddressForm .delivery-card-title {
    font-size: var(--tdm3-font-size-base);
}

/* WHAT DIFFERS, marked. The card showed the delivered address as three lines of text and left
   the reader to compare it to the fields themselves, line by line. The street line and the place
   line now mark themselves when they deviate.

   THE MARK IS NOT A STATUS. components.md says under Cards that a reference value carries none -
   this card once sat on Bootstrap's `.card.border-warning`, which was exactly the mistake. So not
   yellow and not red, but the mark the answer dialog uses for "this is the line in question":
   --tdm3-color-primary as a left accent on --tdm3-color-info-bg, literally the two tokens of
   .collection-answer .answer-selected.

   The 3px border is on EVERY line, transparent where nothing is marked, so the text does not shift
   when a line starts deviating. */
#DeliveryMethod-AddressForm .delivery-card-line {
    padding-left: var(--tdm3-space-2);
    border-left: 3px solid transparent;
}

#DeliveryMethod-AddressForm .delivery-card-line-diff {
    border-left-color: var(--tdm3-color-primary);
    background-color: var(--tdm3-color-info-bg);
}

/* What the mark means, in one line under the card, and only when something is marked. A legend
   for a mark that is not there is the legend under the grid the conventions forbid. */
#DeliveryMethod-AddressForm .delivery-card-note {
    margin: var(--tdm3-space-2) 0 0;
    color: var(--tdm3-text-muted);
    font-size: var(--tdm3-font-size-sm);
}

/* Cancel and send, with air around them. A flex row: with `text-right` and inline layout the
   space between two <button> tags was the gap, which is whitespace in the markup rather than a
   decision. Side padding is 0 because it stacked on #DeliveryMethod-AddressForm's own 24px, so the
   buttons sat 48px from the edge while every field above sits at 24. */
#DeliveryMethod-AddressForm .delivery-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--tdm3-space-2);
    padding: var(--tdm3-space-5) 0;
    /* The button row stays in view when the window's content scrolls. openEditWindow clamps the
       dialog to the viewport (see sizeEditWindowOnce in _DeliveryMethodEditor.cshtml) and then
       `.k-window-content` scrolls - but at 1280x800 the postal section is 844px of content in a
       741px window, so without this rule Save sat 86px below the window's bottom edge and you had
       to scroll to find the dialog's most important button. Measured WITH the rule: y 719.5, inside
       the 798px the window occupies.

       `sticky` and not `fixed`: the row belongs to the form and has to travel with the dialog when
       someone drags it. The scroll container is `.k-window-content` itself (`overflow: auto` from
       `scrollable: true`), and nothing in between clips, so the sticky finds it.

       The surface under it is not decoration but what makes sticky usable: without a background
       the last field's text scrolls visibly behind the buttons. --tdm3-surface is the window's own
       colour, so no extra panel appears - only the border above says there is more below. */
    position: sticky;
    bottom: 0;
    border-top: 1px solid var(--tdm3-divider);
    background-color: var(--tdm3-surface);
}


/* ============================================================================
   The two bundle screens (Views/InvoiceDownloadLink/Index.cshtml and Detail.cshtml).

   What is left of those views' <style> blocks once the shared part moved to
   portal.css: three rules, none of which says anything about colour. The sidebar
   is not among them - it became a component (.tdm3-vnav) because half its markup
   lives in _Layout.
   ========================================================================= */

/* The two buttons in the bundle overview's action column would otherwise touch. Only the gap is
   screen-specific; their shape comes from `.k-grid .k-button` in portal.css. The `.k-grid` in
   front scopes it: this margin is for the button IN A GRID CELL, not for `.btn-resend` wherever
   it appears. */
.k-grid .btn-resend {
    margin-left: var(--tdm3-space-1);
}

/* 24px, the step above the 20 that stood here as an inline style; rounding up costs nothing,
   there is air above this card. Expired.cshtml shares the rule - same card in the same place, only
   saying the link has expired. */
.invoice-download-detail,
.invoice-download-expired {
    margin-top: var(--tdm3-space-5);
}

/* This screen's grid grows with its content instead of taking a fixed height and a scrollbar of
   its own: it sits in a card that already scrolls with the page. */
.k-grid.invoice-download-grid {
    height: auto;
}

/* The action column holds its rows still. The width itself is in Detail.cshtml with the
   measurement of all four button labels; these are the two rules the width alone does not give.

   NO WRAPPING. On `white-space: normal` the second button drops to a second line as soon as the
   two do not fit: measured 75.8px row height against 42.3 for the row above. The column is wide
   enough today; this keeps a longer translation from silently taking the row height over. Same
   rule and reason as `.k-grid td.feedback-command-cell` on the collection screen.

   A RESERVED FIRST SLOT. The first button differs per row - "Change delivery" while the practice
   may change it, "Submitted" once it has - so without a reservation the button beside it starts
   somewhere else in every row. 158px is the widest of the four, the nl "Wijzig verzending" with its
   pencil (157.97px); at that width the second button shares one x per row and nothing is clipped. */
.k-grid.invoice-download-grid td.k-command-cell {
    white-space: nowrap;
}

.k-grid.invoice-download-grid .k-grid-EditDelivery,
.k-grid.invoice-download-grid .k-grid-DeliveryPublished {
    min-width: 158px;
}

/* The two sizes from the resend dialog, which used to be style attributes in the markup. Bound to
   #resendEmailWindow to scope it: `.resend-label-column` and `.resend-email-input` only exist
   inside this window, and the selector should say so.

   Only the first label cell carries the width, as the inline style did: the table lays itself out
   automatically, so that one cell sets the column and the four below follow. */
#resendEmailWindow .resend-label-column {
    width: 140px;
}

#resendEmailWindow .resend-email-input {
    width: 100%;
}


/* ============================================================================
   The two centred card pages: sign-in (Views/Home/SignIn.cshtml) and
   sign-out-succeeded (Views/Home/SignOutSuccess.cshtml).

   Both set ViewBag.UseFullWidth, so they get no menu and no main column:
   RenderBody() sits directly in the body. They are the only two screens with that
   shape - one card, vertically centred - and therefore share one block.

   The vertical rhythm is set here rather than left to Bootstrap's margins: mb-2/3/4
   compute in rem and the root is 14px, so they gave 7, 14 and 21px - none of them a
   step off the 4px scale. Now 24px between blocks, 8px within a block, 32px under
   the logo.
   ========================================================================= */

/* 80vh, not 100vh: the footer should stay in view without scrolling. */
.auth-viewport {
    min-height: 80vh;
}

/* A ceiling on the sign-in card. The Bootstrap ladder that stood here
   (col-11 col-sm-8 col-md-6 col-lg-5 col-xl-4) has no upper bound - every step is a percentage of
   the window - so the card grew with the screen: measured 640px at 1920, and 853px at 2560. One
   card with four lines of text should not do that.

   At 420px the button is 354.67px and the description stays on two lines in both languages, which
   makes the card 21px taller - exactly one line.

   Below the ceiling .col-11 still does its work: this overrides only its max-width and not its
   flex-basis, so on a phone the card still grows (measured 344.05px in a 375px window). One class
   against one class, and this file loads after bootstrap.css, so source order decides.

   The same 420px is on .home-column below; change one and you change both. */
.auth-column {
    max-width: 420px;
}

/* .tdm3-card gives --tdm3-space-4 (16px) all round, the size for a form block in a full screen.
   This is one card on an otherwise empty page, where 16px reads as a dialog rather than as the
   front door. --tdm3-space-6 (32px) is the nearest step down from the 42px that stood here, and
   down because this application's density was signed off after step 4.

   The doubled `.tdm3-card` reads as what it is: the card component, at this page's size. */
.tdm3-card.auth-card {
    padding: var(--tdm3-space-6);
}

/* The TDM3 logo at the top of the card. 160px wide is 4.23cm at 96dpi, well over the 2cm minimum
   branding.md sets; the height follows the source (256 x 73) so it does not distort. The img also
   carries width/height as attributes - not styling, but the ratio the browser reserves space with
   before the file arrives.

   White space around it: the 32px card padding left and right plus the free space beside a centred
   160px logo, and 32px below. branding.md asks for 1cm (37.8px); the 4px scale has no step between
   32 and 48, and 48 would unbalance the card on a narrow screen. A deliberate deviation, to the
   nearest step. */
.auth-logo {
    display: block;
    width: 160px;
    max-width: 100%;
    height: auto;
    margin: 0 auto var(--tdm3-space-6);
}

/* The card's rhythm. A block is a heading with what belongs under it: 24px between blocks, 8px
   within one, and the last child of either carries nothing - otherwise the card padding adds to
   it. */
.auth-block {
    margin-bottom: var(--tdm3-space-5);
}

.auth-block > * {
    margin-bottom: var(--tdm3-space-2);
}

.auth-block > :last-child,
.tdm3-card.auth-card > :last-child {
    margin-bottom: 0;
}

/* The two buttons on the sign-out page: a real gap off the scale, rather than a margin left
   hanging on the last button. */
.auth-actions {
    display: flex;
    flex-direction: column;
    gap: var(--tdm3-space-2);
}

/* What `btn-block` did. .tdm3-btn is inline-flex (components.md), so the content has to be
   centred too - otherwise the label sits left in a full-width button. */
.auth-btn-block {
    display: flex;
    justify-content: center;
    width: 100%;
}

/* Replaces Bootstrap's .border-top, which sets its #DEE2E6 with !important - a token does not win
   against that. 24px on both sides of the line puts the language switcher as far from the sign-in
   button as the blocks are from each other. */
.auth-divider {
    margin-top: var(--tdm3-space-5);
    padding-top: var(--tdm3-space-5);
    border-top: 1px solid var(--tdm3-divider);
}

/* The language switcher was a .btn-group: two buttons stuck together. Own flex with a real gap;
   the button shape comes from .tdm3-btn. */
.auth-language {
    display: flex;
    justify-content: center;
    gap: var(--tdm3-space-2);
}

/* The language in force. This is navigation, not an action, so the pair is that of the active
   vnav item in components.md ("Navigatie"): --tdm3-color-link on --tdm3-color-info-bg.
   Bootstrap's `.active` made a dark grey panel of it.

   `.auth-language` in front scopes the mark to the switcher; `.auth-language-current` on its own
   could just as well land on any button. */
.auth-language .auth-language-current {
    border-color: var(--tdm3-color-info-bg);
    background-color: var(--tdm3-color-info-bg);
    color: var(--tdm3-color-link);
    font-weight: var(--tdm3-font-weight-bold);
}

/* The tick on the sign-out page. Big enough to read as a confirmation: .k-icon puts itself at
   16px, so the size has to be set here. --tdm3-color-success measures 6.62:1 against Bootstrap's
   .text-success at 3.13:1. */
.auth-icon-success {
    color: var(--tdm3-color-success);
    line-height: 1;
}

.auth-icon-success .k-icon {
    font-size: var(--tdm3-space-6);
}


/* ============================================================================
   The tenant picker (Views/Home/Index.cshtml).

   There was nothing here, and it showed. The view put its tenant list in a bare
   <div class="col-md-4"> with no .row and no container: a grid column outside a
   grid. Bootstrap gives such a div a width (33.33%) but nothing places it, so
   heading, list and button all started against the left edge - measured at 1920,
   the list sat at x=36 with 1288px of empty space beside it.

   The owner asked for centring only - no card, and the list and button stay what
   they are. Hence one centred column and nothing else.
   ========================================================================= */

/* The same ceiling as .auth-column above, deliberately: this is where signing in lands, so the
   two should be equally wide. Change the 420 here and you change it there.

   Measured after the swap: 420px with 750px free on either side at 1920, and 430px at 1280. In a
   375px window the column stays at 333.33px - the width of main inside its px-4 - and horizontal
   overflow is 0.

   The text inside stays left-aligned: this is a list, not a card, so there is no text-align here.
   What centres the column is the automatic side margins. */
.home-column {
    max-width: 420px;
    margin-inline: auto;
}


/* ============================================================================
   The claim table of the user info screen (Views/Home/UserInfo.cshtml).

   What is left of that view's <style> block once the components took over: the
   width split of the two columns and the shape of a claim value. Everything about
   colour lapsed - the table wears .tdm3-table and takes header, alternation and
   hover from it.
   ========================================================================= */

/* Needed because a claim value can be a token of hundreds of characters: without this split that
   column squeezes the name beside it to one word per line. */
.userinfo-claims .userinfo-claim-type {
    width: 35%;
}

/* The claim URI under the friendly name. It wears .tdm3-help for size and spacing but not for its
   colour: this table's rows alternate between white and --tdm3-table-row-alt, and --tdm3-text-muted
   measures 4.30:1 on that grey - accessibility.md forbids muted text on tinted surfaces.
   --tdm3-text-subtle measures 7.50:1.

   A finding for components.md: the system has one class for small secondary text and it is defined
   for white. A variant for tinted surfaces is missing. */
.userinfo-claims .userinfo-claim-uri {
    color: var(--tdm3-text-subtle);
}

/* A claim value is a technical string that may break where it must and keeps its own line breaks
   (`white-space: pre-wrap` used to be a style attribute on the <code> element). The grey chip
   around it is the one from before, now in tokens. */
.userinfo-claim-value {
    display: inline-block;
    max-width: 100%;
    padding: var(--tdm3-space-1) var(--tdm3-space-2);
    border-radius: var(--tdm3-radius);
    background-color: var(--tdm3-surface-muted);
    font-size: var(--tdm3-font-size-sm);
    white-space: pre-wrap;
}


/* ============================================================================
   /Styleguide - the layout of the reference screen itself.

   Only what that one screen needs to put the components side by side: grids,
   specimen frames, colour swatches. The components themselves live in portal.css;
   this block contains none of them, and nothing here is selected by another
   screen.

   The typography specimens (.styleguide-type-*) carry the token values on a class
   of their own rather than on h1-h3, so this page shows the scale without
   imposing it.
   ========================================================================= */

.styleguide-section {
    margin-bottom: var(--tdm3-space-7);
}

.styleguide-section-title {
    margin-bottom: var(--tdm3-space-1);
    color: var(--tdm3-blue);
    font-size: var(--tdm3-font-size-h2);
    font-weight: var(--tdm3-font-weight-bold);
}

.styleguide-section-intro {
    max-width: 900px;
    margin-bottom: var(--tdm3-space-4);
    color: var(--tdm3-text-subtle);
}

/* One row of specimens that wraps on narrow screens. Own flex, not a Bootstrap .row: that
   computes with negative margins and a box-sizing that does not hold inside Kendo containers, and
   this screen is the example. */
.styleguide-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tdm3-space-4);
    align-items: flex-start;
}

.styleguide-specimen {
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: var(--tdm3-space-2);
    padding: var(--tdm3-space-3);
    border: 1px dashed var(--tdm3-divider);
    border-radius: var(--tdm3-radius);
    min-width: 0;
}

/* Says which state the specimen beside it shows: rest, hover, focus. */
.styleguide-specimen-label {
    color: var(--tdm3-text-muted);
    font-size: var(--tdm3-font-size-sm);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.styleguide-swatch-card {
    box-sizing: border-box;
    flex: 1 1 260px;
    max-width: 340px;
    padding: var(--tdm3-space-3);
    border: 1px solid var(--tdm3-divider);
    border-radius: var(--tdm3-radius);
}

.styleguide-swatch {
    height: 56px;
    margin-bottom: var(--tdm3-space-2);
    border: 1px solid var(--tdm3-border);
    border-radius: var(--tdm3-radius);
}

.styleguide-swatch-name {
    display: block;
    font-size: var(--tdm3-font-size-sm);
}

.styleguide-swatch-note {
    margin: var(--tdm3-space-2) 0 0;
    font-size: var(--tdm3-font-size-sm);
}

/* What the colour may NOT carry. Red as text, not as a surface: this is a prohibition in a table,
   not an error message. */
.styleguide-swatch-forbidden {
    margin: var(--tdm3-space-1) 0 0;
    color: var(--tdm3-color-danger);
    font-size: var(--tdm3-font-size-sm);
}

/* The measured value the script writes into the page. Empty until it does, so there is never a
   number on screen that did not come from tokens.css. */
.styleguide-measure {
    display: inline-block;
    padding: 0 var(--tdm3-space-1);
    border-radius: var(--tdm3-radius);
    background-color: var(--tdm3-surface-muted);
    color: var(--tdm3-text-subtle);
    font-family: var(--tdm3-font-family-mono);
    font-size: var(--tdm3-font-size-sm);
    font-variant-numeric: tabular-nums;
}

.styleguide-measure-mismatch {
    background-color: var(--tdm3-color-danger-bg);
    color: var(--tdm3-color-danger);
}

/* Every swatch gets a rule of its own rather than a style attribute in the markup: the colour
   belongs in CSS and the token is the only source. */
.styleguide-swatch-navy { background-color: var(--tdm3-navy); }
.styleguide-swatch-blue { background-color: var(--tdm3-blue); }
.styleguide-swatch-sky { background-color: var(--tdm3-sky); }
.styleguide-swatch-green { background-color: var(--tdm3-green); }
.styleguide-swatch-lime { background-color: var(--tdm3-lime); }
.styleguide-swatch-orange { background-color: var(--tdm3-orange); }
.styleguide-swatch-red { background-color: var(--tdm3-red); }
.styleguide-swatch-muted { background-color: var(--tdm3-text-muted); }
.styleguide-swatch-blue-hover { background-color: var(--tdm3-blue-hover); }
.styleguide-swatch-orange-text { background-color: var(--tdm3-orange-text); }
.styleguide-swatch-green-tint { background-color: var(--tdm3-green-tint); }
.styleguide-swatch-orange-tint { background-color: var(--tdm3-orange-tint); }
.styleguide-swatch-red-tint { background-color: var(--tdm3-red-tint); }
.styleguide-swatch-sky-tint { background-color: var(--tdm3-sky-tint); }
.styleguide-swatch-sky-tint-light { background-color: var(--tdm3-sky-tint-light); }
.styleguide-swatch-gray-100 { background-color: var(--tdm3-gray-100); }
.styleguide-swatch-gray-200 { background-color: var(--tdm3-gray-200); }
.styleguide-swatch-border { background-color: var(--tdm3-border); }

/* The pairs from accessibility.md, each on the surface it actually sits on. */
.styleguide-pair {
    display: block;
    padding: var(--tdm3-space-2) var(--tdm3-space-3);
    border-radius: var(--tdm3-radius);
}

.styleguide-pair-primary { background-color: var(--tdm3-color-primary); color: var(--tdm3-color-primary-contrast); }
.styleguide-pair-primary-hover { background-color: var(--tdm3-color-primary-hover); color: var(--tdm3-color-primary-contrast); }
.styleguide-pair-navy { background-color: var(--tdm3-navy); color: var(--tdm3-color-primary-contrast); }
.styleguide-pair-info { background-color: var(--tdm3-sky-tint); color: var(--tdm3-navy); }
.styleguide-pair-success { background-color: var(--tdm3-green-tint); color: var(--tdm3-green); }
.styleguide-pair-warning { background-color: var(--tdm3-orange-tint); color: var(--tdm3-orange-text); }
.styleguide-pair-danger { background-color: var(--tdm3-red-tint); color: var(--tdm3-red); }
.styleguide-pair-row-alt { background-color: var(--tdm3-gray-100); color: var(--tdm3-text); }
.styleguide-pair-section { background-color: var(--tdm3-gray-200); color: var(--tdm3-navy); }
/* The active vnav item carries its accent bar too - that is the half of the pair that has to make
   3:1 for non-text. */
.styleguide-pair-row-hover { background-color: var(--tdm3-table-row-hover); color: var(--tdm3-text); }
.styleguide-pair-vnav { background-color: var(--tdm3-surface-muted); color: var(--tdm3-text-subtle); }
/* A surface only, no text colour: this swatch shows a FIELD on a tinted background, and the field
   brings its own colours. */
.styleguide-pair-muted { background-color: var(--tdm3-surface-muted); }
.styleguide-pair-vnav-active {
    background-color: var(--tdm3-color-info-bg);
    box-shadow: inset 3px 0 0 0 var(--tdm3-color-primary);
    color: var(--tdm3-color-link);
    font-weight: var(--tdm3-font-weight-bold);
}

/* The topbar specimen in the Navigation section. Same component, but with a radius and without
   the shadow: it is a specimen on a page, not a second bar hanging over the content. The REAL bar
   is at the top of this screen, as it is above every screen. */
.styleguide-topbar {
    border-radius: var(--tdm3-radius);
    box-shadow: none;
}

/* The topbar. Four pairs that only exist on navy, so all four on that same surface - a specimen
   on white would give a different number from the pair the bar actually carries, which is exactly
   what this table has to rule out. */
.styleguide-pair-topbar {
    background-color: var(--tdm3-topbar-bg);
    color: var(--tdm3-topbar-text);
}

.styleguide-pair-topbar-current {
    background-color: var(--tdm3-topbar-bg);
    color: var(--tdm3-topbar-current);
    font-weight: var(--tdm3-font-weight-bold);
}

/* The ring of an open station and the chip's border are borders, not text: they are shown as
   borders, because as text they say nothing about the role. */
.styleguide-pair-topbar-station {
    background-color: var(--tdm3-topbar-bg);
    border: 1px solid var(--tdm3-topbar-station);
    color: var(--tdm3-topbar-text);
}

.styleguide-pair-topbar-chip {
    background-color: var(--tdm3-topbar-bg);
    border: 1px solid var(--tdm3-topbar-chip-border);
    border-radius: var(--tdm3-radius-pill);
    color: var(--tdm3-topbar-current);
}

/* The rail: not a text pair but a line at the bottom of the bar. As an inset shadow rather than a
   background layer - the same construction .styleguide-pair-vnav-active uses for its accent bar,
   and it leaves background-color alone. */
.styleguide-pair-topbar-rail {
    box-shadow: inset 0 -1px 0 0 var(--tdm3-topbar-rail);
    background-color: var(--tdm3-topbar-bg);
    color: var(--tdm3-topbar-text);
}

/* The typography scale. See the block comment above for why it sits on classes of its own rather
   than on h1-h3. */
.styleguide-type-title {
    color: var(--tdm3-color-heading);
    font-size: var(--tdm3-font-size-title);
    font-weight: var(--tdm3-font-weight-bold);
    line-height: var(--tdm3-line-height-tight);
}

.styleguide-type-h1 {
    color: var(--tdm3-color-heading);
    font-size: var(--tdm3-font-size-h1);
    font-weight: var(--tdm3-font-weight-bold);
    line-height: var(--tdm3-line-height-tight);
}

.styleguide-type-h2 {
    color: var(--tdm3-blue);
    font-size: var(--tdm3-font-size-h2);
    font-weight: var(--tdm3-font-weight-bold);
    line-height: var(--tdm3-line-height-tight);
}

.styleguide-type-h3 {
    color: var(--tdm3-color-heading);
    font-size: var(--tdm3-font-size-lg);
    font-weight: var(--tdm3-font-weight-bold);
    line-height: var(--tdm3-line-height-tight);
}

.styleguide-type-body {
    color: var(--tdm3-text);
    font-size: var(--tdm3-font-size-base);
    font-weight: var(--tdm3-font-weight-normal);
    line-height: var(--tdm3-line-height);
}

.styleguide-type-small {
    color: var(--tdm3-text-muted);
    font-size: var(--tdm3-font-size-sm);
    font-weight: var(--tdm3-font-weight-normal);
    line-height: var(--tdm3-line-height);
}

/* The form specimen at the width a field actually has in this portal, rather than stretched
   across the full screen. */
.styleguide-form {
    max-width: 420px;
}

/* A specimen that stands on its own: reading width and air underneath. */
.styleguide-block {
    max-width: 900px;
    margin-bottom: var(--tdm3-space-4);
}

/* Two cards side by side as long as the screen allows it, stacked below that. */
.styleguide-card {
    box-sizing: border-box;
    flex: 1 1 320px;
    max-width: 420px;
}

.styleguide-toc {
    margin-bottom: var(--tdm3-space-6);
    padding-left: 0;
    list-style: none;
}

.styleguide-toc li {
    display: inline-block;
    margin: 0 var(--tdm3-space-4) var(--tdm3-space-1) 0;
}


/* ============================================================================
   The help page (Views/Help/Index.cshtml): the topic list for a narrow screen,
   the article and the contact block under the article. A table in the article
   wears .tdm3-table from portal.css; HelpMarkdown writes that class.
   ========================================================================= */

/* The topic list below md, where the layout hides the side nav. The element also
   wears .tdm3-vnav, which gives it the panel (surface, radius, 8px top and bottom)
   and the look of every item; this block adds only what a disclosure needs.
   Bootstrap's reboot already gives a <summary> its marker and its pointer, so
   neither is written here. */
.help-topics-compact {
    margin-bottom: var(--tdm3-space-4);
}

/* The summary lines up with the items under it (.tdm3-vnav .nav-link) and
   answers the pointer the way they do, with the shared hover surface. */
.help-topics-compact > summary {
    padding: var(--tdm3-space-1) var(--tdm3-space-3);
    border-radius: var(--tdm3-radius);
    color: var(--tdm3-text);
    font-weight: var(--tdm3-font-weight-medium);
}

.help-topics-compact > summary:hover {
    background-color: var(--tdm3-surface-hover);
}

/* The ring .tdm3-btn and .tdm3-input carry, on keyboard focus only. */
.help-topics-compact > summary:focus-visible {
    outline: 2px solid var(--tdm3-color-focus);
    outline-offset: 1px;
}

/* The article is Markdig's output: bare elements (h1-h3, p, ul, ol, table).
   These rules therefore style the elements inside the article, not classes on
   each element. The line stops at --tdm3-prose-measure. The main column beside
   the side nav is over 1000px on a desktop, and a line that long is read with
   the head instead of the eyes. */
.help-article {
    max-width: var(--tdm3-prose-measure);
}

/* One rhythm between blocks, set as the space ABOVE each block. Bootstrap's
   reboot puts 1rem under p, ul and ol and 0.5rem under a heading - 14px and
   7px on this root, neither of them a step of the scale - and a margin below
   one block would add up with a margin above the next. */
.help-article > * {
    margin-top: 0;
    margin-bottom: 0;
}

.help-article > * + * {
    margin-top: var(--tdm3-space-3);
}

/* A new section stands further from the text before it than a paragraph does
   from the next one. */
.help-article > h2 {
    margin-top: var(--tdm3-space-6);
}

.help-article > h3 {
    margin-top: var(--tdm3-space-5);
}

/* A heading belongs to what follows it, so that gap is the smallest. After the
   two rules above: a heading right after a heading weighs the same there, and
   source order makes it bind to the one above. */
.help-article > h1 + *,
.help-article > h2 + *,
.help-article > h3 + * {
    margin-top: var(--tdm3-space-2);
}

.help-article ul,
.help-article ol {
    padding-left: var(--tdm3-space-5);
}

.help-article li + li,
.help-article li > ul,
.help-article li > ol {
    margin-top: var(--tdm3-space-1);
}

/* A list with a blank line between its items is "loose" in Markdown, and Markdig
   wraps every item in a <p>. The reboot's 1rem under that <p> would open a gap
   inside each item. */
.help-article li > p {
    margin: 0;
}

/* Below md the article is as wide as the screen minus the padding of main:
   333px at 375px. A glossary table needs more for its longest words (measured
   at 375px: nl-BE 390, 420 and 339px, fr-BE 351px), and the nl-BE page then
   scrolls sideways by 66px. The table scrolls in its own box instead, as a grid
   does in .tdm3-grid-scroll, and every word stays whole. From md up the tables
   fit, so the desktop table keeps its layout. */
@media (max-width: 767.98px) {
    .help-article .tdm3-table {
        display: block;
        overflow-x: auto;
    }
}

/* The contact block closes the article, so it stands as far from the last
   paragraph as a new section does from the text above it (.help-article > h2).
   Same weight as `.help-article > * + *`, and it comes after that rule. */
.help-contact {
    margin-top: var(--tdm3-space-6);
}
