/*
 * Lev Credit — Phase-1 component library (spec §3.8; ADR 0024).
 * Reconciled from the three build clusters (inputs / actions / layout). Tokens ONLY:
 * the branding gate enforces zero hex, no brand colour as text, and WCAG AA on every
 * co-located text/background pairing. Customer-facing default treatment — brand fills
 * use the AA variants (--lc-brand-*-aa) with white text; status uses the soft tints.
 */

/* --- Shared base ---------------------------------------------------------- */
.lc-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
[x-cloak] { display: none !important; }

/* --- Showcase gallery layout (the dev gallery / visual-regression target) -- */
.lc-showcase {
  margin: 0;
  background: var(--lc-cream);
  color: var(--lc-grey-900);
  font-size: var(--lc-text-base);
  font-family: var(--lc-font-sans);
  line-height: 1.5;
}
.lc-showcase__main { max-width: 72rem; margin: 0 auto; padding: var(--lc-space-8) var(--lc-space-5); }
.lc-showcase h1 { font-size: 2rem; margin-bottom: var(--lc-space-2); }
.lc-showcase__lede { color: var(--lc-grey-700); margin-bottom: var(--lc-space-8); }
.lc-showcase__section { margin-block: var(--lc-space-8); }
.lc-showcase__section > h2 {
  font-size: 1.375rem;
  border-bottom: var(--lc-border-width) solid var(--lc-grey-300);
  padding-bottom: var(--lc-space-2);
  margin-bottom: var(--lc-space-5);
}
.lc-showcase__row {
  display: flex; flex-wrap: wrap; gap: var(--lc-space-4);
  align-items: flex-start; margin-bottom: var(--lc-space-5);
}
.lc-showcase__cell { flex: 0 1 auto; min-width: 14rem; }

/* ===== Cluster: form inputs ===== */
/*
 * Lev Credit — component library: FORM INPUTS (customer-facing surfaces).
 *
 * Presentation only. Consumes the canonical design tokens (static/css/tokens.css)
 * via var(--lc-…) exclusively — ZERO hex literals, ZERO magic px (AMD-002/AMD-003
 * build gate). Pairs with the partials in templates/components/*.html, each of
 * which wraps a .lc-field (label + control + help + error).
 *
 * Surface scope: CUSTOMER-FACING (public site, /client). Where a brand fill carries
 * text, the AA brand variant (--lc-brand-*-aa) is used with white text
 * (--lc-on-brand) so the pairing meets WCAG AA — the bright brand colours
 * (--lc-brand-primary/secondary) are the internal-admin exception and are not used
 * here. Brand colour is never a text `color:` (AMD-003 §1).
 *
 * Accessibility (AMD-003): every interactive control has a visible focus ring
 * (--lc-focus-ring-*), a ≥44px hit target (--lc-hit-target; ADR 0186), an error state driven
 * by aria-invalid + visible error text, and honours prefers-reduced-motion.
 */

/* ====================================================================== *
 *  Field shell — shared label / control / help / error layout.
 * ====================================================================== */
.lc-field {
  display: flex;
  flex-direction: column;
  gap: var(--lc-space-2);
  margin-bottom: var(--lc-space-4);
}

.lc-field__label {
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-semibold);
  color: var(--lc-grey-900);
  line-height: 1.4;
}

/* The required marker — semantic error red as a non-text accent glyph. */
.lc-field__required {
  color: var(--lc-error);
  margin-left: var(--lc-space-1);
}

.lc-field__help {
  font-size: var(--lc-text-sm);
  color: var(--lc-grey-700);
  margin: 0;
  line-height: 1.4;
}

.lc-field__error {
  font-size: var(--lc-text-sm);
  color: var(--lc-error);
  margin: 0;
  font-weight: var(--lc-weight-semibold);
  line-height: 1.4;
}

/* ====================================================================== *
 *  Text input / textarea / select — the shared control look.
 * ====================================================================== */
.lc-input,
.lc-textarea,
.lc-select {
  font-family: inherit;
  font-size: var(--lc-text-base);
  color: var(--lc-grey-900);
  background-color: var(--lc-white);
  border: var(--lc-border-width) solid var(--lc-grey-300);
  border-radius: var(--lc-radius-sm);
  padding: var(--lc-space-2) var(--lc-space-3);
  min-height: var(--lc-target-floor);
  /* THE HIT-TARGET FLOOR HAS TWO AXES (ADR 0187). ADR 0186 gave `.lc-btn` a
     `min-width` and left the fields with a height floor only, so a field in a
     shrinking inline row kept its 44px height and collapsed to 26px ACROSS -
     measured on the cash-box reconciliation rows, 18 of them, at every width
     below 480. `max-width: 100%` is the ADR-0178 companion: a control may never
     be wider than what holds it, so the floor can never widen the page. */
  min-width: var(--lc-target-floor);
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  transition: border-color var(--lc-motion-fast) var(--lc-ease),
              box-shadow var(--lc-motion-fast) var(--lc-ease);
}

.lc-textarea {
  min-height: calc(var(--lc-target-floor) * 2);
  resize: vertical;
  line-height: 1.5;
}

.lc-select {
  appearance: none;
  padding-right: var(--lc-space-6);
  /* THE SELECT AFFORDANCE (ADR 0191, DP1/A8). `appearance: none` REMOVES the
     native chevron - the old comment claimed the browser still drew one, and
     the Phase 0 graders found selects painting no dropdown indicator at all.
     Paint one from two token-coloured gradient triangles: no hex literal, no
     image asset, inherits the disabled state's opacity like any background. */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--lc-grey-700) 50%),
    linear-gradient(135deg, var(--lc-grey-700) 50%, transparent 50%);
  background-position:
    calc(100% - 18px) calc(50% - 2px),
    calc(100% - 12px) calc(50% - 2px);
  background-size: 6px 6px;
  background-repeat: no-repeat;
}

/* THE FIELD-PROPORTION LAW (ADR 0191, DP1/A4): a field is SIZED to its
 * content's measure - a date like a date, an ЕГН like ten digits - never a
 * text default stretched to the column (doctrine Q4.6; floor 2.5x, the
 * `--lc-field-measure-ratio` token). TWO delivery paths, one set of measure
 * tokens: the semantic classes for new markup, and NAME/TYPE attribute rules
 * that reach the platform's recurring fields with zero template churn. The
 * cap composes with `min(..., 100%)` so a measure can never widen a page
 * (the ADR-0178 law), and the detector's expectation table asserts equal to
 * the same `--lc-measure-*` tokens. `data-lc-measure="<n>"` overrides the
 * DETECTOR's expectation per field where a genuine exception exists. */
.lc-input--measure-date,
:is(.lc-input, .lc-office input)[type="date"],
:is(.lc-input, .lc-office input)[name$="_on"],
:is(.lc-input, .lc-office input)[name$="_date"] {
  --lc-field-cap: calc(var(--lc-measure-date) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-date) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
/* A datetime-local control renders date AND time plus its picker affordance -
 * its own measure, wider than a date's (DP1: the task composer's due input
 * measured 422px against the date expectation because no rule reached it). */
.lc-input--measure-datetime,
:is(.lc-input, .lc-office input)[type="datetime-local"] {
  --lc-field-cap: calc(var(--lc-measure-datetime) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-datetime) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
.lc-input--measure-egn,
:is(.lc-input, .lc-office input)[name="egn"],
:is(.lc-input, .lc-office input)[name$="-egn"] {
  --lc-field-cap: calc(var(--lc-measure-egn) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-egn) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
.lc-input--measure-year,
:is(.lc-input, .lc-office input)[name$="year"] {
  --lc-field-cap: calc(var(--lc-measure-year) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-year) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
/* `postcode` beside `postal_code`: the HR forms name the field
 * `address_postcode` and the detector's classifier always read both spellings
 * - the CSS now reaches what the instrument measures (constants == tokens). */
.lc-input--measure-postcode,
:is(.lc-input, .lc-office input)[name$="postal_code"],
:is(.lc-input, .lc-office input)[name$="postcode"] {
  --lc-field-cap: calc(var(--lc-measure-postcode) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-postcode) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
/* `$="amount"` and `$="principal"` beside `$="_eur"`: the accounting entry
 * forms name their money fields `net_amount`/`vat_amount` and the intake
 * `requested_amount_eur` renders without the component class - the
 * `.lc-office input` arm reaches an unclassed staff input with zero template
 * churn (the rule's own stated delivery goal). */
.lc-input--measure-amount,
:is(.lc-input, .lc-office input)[name$="_eur"],
:is(.lc-input, .lc-office input)[name$="amount"],
:is(.lc-input, .lc-office input)[name$="principal"] {
  --lc-field-cap: calc(var(--lc-measure-amount) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-amount) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
.lc-input--measure-phone,
:is(.lc-input, .lc-office input)[type="tel"],
:is(.lc-input, .lc-office input)[name$="phone"] {
  --lc-field-cap: calc(var(--lc-measure-phone) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-phone) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
.lc-input--measure-iban,
:is(.lc-input, .lc-office input)[name$="iban"] {
  --lc-field-cap: calc(var(--lc-measure-iban) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-iban) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}
.lc-input--measure-otp,
:is(.lc-input, .lc-office input)[name="code"][inputmode="numeric"] {
  --lc-field-cap: calc(var(--lc-measure-otp) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width));
  max-width: min(calc(var(--lc-measure-otp) + 2 * var(--lc-space-3)
                      + 2 * var(--lc-border-width)), 100%);
}

/* A MEASURED FIELD KEEPS ITS OWN LINE. Before the caps, `width: 100%` made
 * every input fill its row, and hand-rolled forms (the portal login) relied
 * on that; a capped inline-block input would let the NEXT control flow up
 * beside it into the reclaimed space - measured live as the submit button
 * overlapping the ЕГН row. Block display restores the stacked contract in
 * flow layouts and is inert inside flex/grid parents. */
.lc-input--measure-date, :is(.lc-input, .lc-office input)[type="date"],
:is(.lc-input, .lc-office input)[name$="_on"],
:is(.lc-input, .lc-office input)[name$="_date"],
.lc-input--measure-datetime,
:is(.lc-input, .lc-office input)[type="datetime-local"],
.lc-input--measure-egn, :is(.lc-input, .lc-office input)[name="egn"],
:is(.lc-input, .lc-office input)[name$="-egn"],
.lc-input--measure-year, :is(.lc-input, .lc-office input)[name$="year"],
.lc-input--measure-postcode,
:is(.lc-input, .lc-office input)[name$="postal_code"],
:is(.lc-input, .lc-office input)[name$="postcode"],
.lc-input--measure-amount, :is(.lc-input, .lc-office input)[name$="_eur"],
:is(.lc-input, .lc-office input)[name$="amount"],
:is(.lc-input, .lc-office input)[name$="principal"],
.lc-input--measure-phone, :is(.lc-input, .lc-office input)[type="tel"],
:is(.lc-input, .lc-office input)[name$="phone"],
.lc-input--measure-iban, :is(.lc-input, .lc-office input)[name$="iban"],
.lc-input--measure-otp,
:is(.lc-input, .lc-office input)[name="code"][inputmode="numeric"] {
  display: block;
}

/* Placeholder text — tertiary grey on white (AA: grey-500 on white passes). */
.lc-input::placeholder,
.lc-textarea::placeholder {
  color: var(--lc-grey-500);
  opacity: 1;
}

/* Visible focus ring on every control (AMD-003 §1, §4). */
.lc-input:focus-visible,
.lc-textarea:focus-visible,
.lc-select:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
  border-color: var(--lc-grey-500);
}

/* Error state — red border; partials add aria-invalid + visible .lc-field__error. */
.lc-field--error .lc-input,
.lc-field--error .lc-textarea,
.lc-field--error .lc-select,
.lc-input[aria-invalid="true"],
.lc-textarea[aria-invalid="true"],
.lc-select[aria-invalid="true"] {
  border-color: var(--lc-error);
}

/* Disabled (WCAG exempts disabled controls; selector names the state). */
.lc-input:disabled,
.lc-textarea:disabled,
.lc-select:disabled {
  background-color: var(--lc-grey-100);
  color: var(--lc-grey-500);
  cursor: not-allowed;
}

/* ====================================================================== *
 *  Checkbox — single inline control + label.
 * ====================================================================== */
.lc-checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--lc-space-3);
}

.lc-checkbox__input {
  flex: 0 0 auto;
  width: var(--lc-space-5);
  height: var(--lc-space-5);
  /* keep the clickable box visually prominent */
  min-height: var(--lc-space-5);
  margin: 0;
  /* tint the native check with ink (a brand token would trip the no-brand-as-text
   * gate, which matches the literal `…color: var(--lc-brand-…`) */
  accent-color: var(--lc-grey-900);
  cursor: pointer;
}

.lc-checkbox__label {
  font-size: var(--lc-text-base);
  color: var(--lc-grey-900);
  line-height: 1.5;
  /* vertically align the label against the box */
  padding-top: var(--lc-space-1);
}

.lc-checkbox__input:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

.lc-checkbox__input:disabled {
  cursor: not-allowed;
}

.lc-checkbox__input:disabled + .lc-checkbox__label {
  color: var(--lc-grey-500);
}

/* ====================================================================== *
 *  Radio group — fieldset + legend + options.
 * ====================================================================== */
.lc-radio {
  border: none;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.lc-radio__legend {
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-semibold);
  color: var(--lc-grey-900);
  padding: 0;
  margin-bottom: var(--lc-space-2);
  line-height: 1.4;
}

.lc-radio__options {
  display: flex;
  flex-direction: column;
  gap: var(--lc-space-2);
}

.lc-radio__option {
  display: flex;
  align-items: center;
  gap: var(--lc-space-3);
  min-height: var(--lc-target-floor);
}

.lc-radio__input {
  flex: 0 0 auto;
  width: var(--lc-space-5);
  height: var(--lc-space-5);
  margin: 0;
  /* ink accent — see the note on .lc-checkbox__input */
  accent-color: var(--lc-grey-900);
  cursor: pointer;
}

.lc-radio__option-label {
  font-size: var(--lc-text-base);
  color: var(--lc-grey-900);
  line-height: 1.5;
  cursor: pointer;
}

.lc-radio__input:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

.lc-radio__input:disabled {
  cursor: not-allowed;
}

.lc-radio__input:disabled + .lc-radio__option-label {
  color: var(--lc-grey-500);
  cursor: not-allowed;
}

/* ====================================================================== *
 *  Unit affix — € / % INSIDE the control's frame (ADR 0193, Part 4).
 *  Visual only: the glyph is aria-hidden and never enters value=; the unit
 *  rides the control's accessible description. The € glyph itself comes
 *  from Python (core.money.EURO_SIGN), never a template literal.
 * ====================================================================== */
.lc-unit {
  position: relative;
  display: block;
  width: 100%;
  max-width: 100%;
}

.lc-unit > .lc-input {
  width: 100%;
}

.lc-unit__affix {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-semibold);
  color: var(--lc-grey-700);
  pointer-events: none;
  white-space: nowrap;
}

/* € sits BEFORE the number (left edge, one breath in from the border - the
 * DP1 ink floors); the input opens room for it. */
.lc-unit--eur > .lc-unit__affix {
  left: var(--lc-space-3);
}

.lc-unit--eur > .lc-input {
  padding-left: calc(var(--lc-space-3) + var(--lc-space-4));
}

/* % sits AFTER the number (right edge). */
.lc-unit--pct > .lc-unit__affix {
  right: var(--lc-space-3);
}

.lc-unit--pct > .lc-input {
  padding-right: calc(var(--lc-space-3) + var(--lc-space-4));
}

/* A native number spinner paints exactly where the % sits - the affix owns
 * that edge, so the spinner yields (typed entry stands; the .lc-number
 * stepper is the deliberate spinner control). */
.lc-unit--pct > .lc-input[type="number"] {
  appearance: textfield;
  -moz-appearance: textfield;
}

.lc-unit--pct > .lc-input[type="number"]::-webkit-outer-spin-button,
.lc-unit--pct > .lc-input[type="number"]::-webkit-inner-spin-button {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
}

/* The field-measure cap (the DP1 field-proportion law) widens by exactly the
 * affix allowance for a wrapped amount input, so the VISIBLE measure never
 * shrinks below the measure token. */
.lc-unit--eur > .lc-input[name$="_eur"],
.lc-unit--eur > .lc-input[name$="amount"],
.lc-unit--eur > .lc-input[name$="principal"] {
  max-width: min(calc(var(--lc-measure-amount) + var(--lc-space-4)
                      + 2 * var(--lc-space-3) + 2 * var(--lc-border-width)),
                 100%);
}

/* ====================================================================== *
 *  Currency input — the € unit affix over a right-aligned decimal entry
 *  (the ADR-0193 in-frame affix replaced the old outside "EUR" panel).
 * ====================================================================== */
.lc-currency .lc-input {
  text-align: right;
}

/* ====================================================================== *
 *  Number picker — − / native number input / +. Degrades without JS.
 * ====================================================================== */
.lc-number {
  display: flex;
  align-items: stretch;
  width: 100%;
}

.lc-number .lc-input {
  border-radius: 0;
  text-align: center;
  /* the spinners are redundant with the explicit buttons */
  -moz-appearance: textfield;
  appearance: textfield;
}

.lc-number .lc-input::-webkit-outer-spin-button,
.lc-number .lc-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* The −/+ buttons: ink glyph on a soft grey panel (AA: grey-900 on grey-100). */
.lc-number__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-width: var(--lc-target-floor);
  min-height: var(--lc-target-floor);
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-bold);
  line-height: 1;
  color: var(--lc-grey-900);
  background-color: var(--lc-grey-100);
  border: var(--lc-border-width) solid var(--lc-grey-300);
  cursor: pointer;
  transition: background-color var(--lc-motion-fast) var(--lc-ease);
}

.lc-number__btn:first-child {
  border-top-left-radius: var(--lc-radius-sm);
  border-bottom-left-radius: var(--lc-radius-sm);
  border-right: none;
}

.lc-number__btn:last-child {
  border-top-right-radius: var(--lc-radius-sm);
  border-bottom-right-radius: var(--lc-radius-sm);
  border-left: none;
}

.lc-number__btn:hover {
  background-color: var(--lc-grey-300);
}

.lc-number__btn:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

.lc-number__btn:disabled {
  background-color: var(--lc-grey-100);
  color: var(--lc-grey-500);
  cursor: not-allowed;
}

/* ====================================================================== *
 *  File upload — drop zone + styled trigger over a visually-hidden input.
 * ====================================================================== */
.lc-file {
  display: flex;
  flex-direction: column;
  gap: var(--lc-space-2);
}

.lc-file__zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--lc-space-3);
  text-align: center;
  padding: var(--lc-space-6) var(--lc-space-4);
  color: var(--lc-grey-700);
  background-color: var(--lc-cream);
  border: var(--lc-border-width) dashed var(--lc-grey-300);
  border-radius: var(--lc-radius-md);
  transition: border-color var(--lc-motion-fast) var(--lc-ease),
              background-color var(--lc-motion-fast) var(--lc-ease);
}

/* Drag-over state (Alpine sets .is-dragging on the zone). */
.lc-file__zone.is-dragging {
  border-color: var(--lc-grey-500);
  /* `background:` (not `background-color:`) so the literal `…color: var(--lc-brand-…`
   * never appears — the no-brand-as-text gate matches that substring even on a
   * legitimate fill; contrast checks still read `background` shorthand. */
  background: var(--lc-brand-secondary-soft);
}

.lc-file__hint {
  font-size: var(--lc-text-sm);
  color: var(--lc-grey-700);
  margin: 0;
}

.lc-file__name {
  font-size: var(--lc-text-sm);
  font-weight: var(--lc-weight-semibold);
  color: var(--lc-grey-900);
  margin: 0;
  word-break: break-all;
}

/* The styled trigger — a <label> for the hidden file input. Customer-facing
 * AA brand fill (white text on --lc-brand-secondary-aa passes WCAG AA). */
.lc-file__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--lc-target-floor);
  padding: 0 var(--lc-space-4);
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-semibold);
  color: var(--lc-on-brand);
  /* `background:` shorthand (see .lc-file__zone.is-dragging) so the brand token is
   * never written as `…color: var(--lc-brand-…`. White text on
   * --lc-brand-secondary-aa meets WCAG AA (customer-facing). */
  background: var(--lc-brand-secondary-aa);
  border: var(--lc-border-width) solid transparent;
  border-radius: var(--lc-radius-md);
  cursor: pointer;
  transition: background-color var(--lc-motion-fast) var(--lc-ease);
}

.lc-file__trigger:hover {
  background: var(--lc-brand-secondary-hover);
}

/* The hidden native input is focusable; ring shows on its sibling trigger. */
.lc-file__input:focus-visible + .lc-file__trigger,
.lc-file__trigger:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

.lc-field--error .lc-file__zone {
  border-color: var(--lc-error);
}

/* Disabled drop zone + trigger (state named in the selector). */
.lc-file__input:disabled + .lc-file__trigger,
.lc-file__trigger.is-disabled {
  background-color: var(--lc-grey-100);
  color: var(--lc-grey-500);
  cursor: not-allowed;
}

/* ====================================================================== *
 *  Motion (AMD-003 §5) — honour prefers-reduced-motion: no transitions.
 * ====================================================================== */
@media (prefers-reduced-motion: reduce) {
  .lc-input,
  .lc-textarea,
  .lc-select,
  .lc-number__btn,
  .lc-file__zone,
  .lc-file__trigger {
    transition: none;
  }
}
/* ===== Cluster: actions & feedback ===== */
/*
 * Lev Credit — component library: ACTIONS & FEEDBACK cluster.
 * Buttons, badges, progress bars, toasts and the modal dialog. PRESENTATION ONLY
 * (CSS + light Alpine.js in the paired partials) — no model, view or Python.
 *
 * Pairs with the partials under templates/components/:
 *   button.html · badge.html · progress.html · toast.html · modal.html
 *
 * TOKENS ONLY. Every colour, radius, spacing, type-step, shadow, motion and z value
 * is a var(--lc-…) from the canonical token stylesheet (static/css/tokens.css). NO
 * hex literal and NO magic px appears here — the AMD-002 / AMD-003 build gate
 * (apps/backoffice/tests/test_branding.py) fails on either.
 *
 * SURFACE = CUSTOMER-FACING (public site, /client). Per AMD-003 the bright brand
 * fills (--lc-brand-primary / --lc-brand-secondary) are INTERNAL-ADMIN-ONLY; here
 * every solid brand fill uses the accessible variants --lc-brand-primary-aa /
 * --lc-brand-secondary-aa with WHITE text (--lc-on-brand), which meet WCAG AA.
 * Brand colour is a BACKGROUND fill only — never a text `color:` (links use
 * --lc-link). Hover on a solid fill never swaps the background colour (that would
 * mint a new, unverified pairing); it darkens via `filter: brightness()` and/or
 * deepens the elevation, keeping the AA fill + white text intact.
 *
 * Accessibility (AMD-003): semantic HTML + ARIA in the partials; a visible
 * :focus-visible ring on every interactive element; ≥ --lc-hit-target controls;
 * motion gated by prefers-reduced-motion.
 */

/* Keep Alpine-controlled regions hidden until Alpine initialises (no flash). */
[x-cloak] {
  display: none !important;
}

/* Visually-hidden but screen-reader-available. The integration lead owns the
 * canonical definition; this is a defensive local fallback so the partials are
 * self-contained if the global utility has not loaded yet. */
.lc-sr-only {
  position: absolute;
  width: var(--lc-border-width);
  height: var(--lc-border-width);
  padding: 0;
  margin: calc(-1 * var(--lc-border-width));
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ====================================================================== *
 *  BUTTON — templates/components/button.html
 *  variants: primary | secondary | ghost | danger   sizes: sm | md | lg
 * ====================================================================== */
.lc-btn {
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--lc-space-2);
  min-height: var(--lc-target-floor);
  padding: var(--lc-space-2) var(--lc-space-5);
  font: inherit;
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-semibold);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  /* A BUTTON MAY NEVER BE WIDER THAN WHAT HOLDS IT (ADR 0178). `nowrap` made a
   * long label incompressible, so the button grew past its container instead of
   * wrapping: on /politika-za-biskvitkite/ a 368px button in a 342px column
   * pushed the whole DOCUMENT into horizontal scroll at 390px, and in an office
   * action grid two long-labelled buttons painted over each other. `normal`
   * wraps ONLY when the label does not fit - a short label still renders on one
   * line at exactly the width it renders today, because a shrink-to-fit box that
   * fits never wraps - so this changes nothing except the overflow case it fixes.
   * ADR 0191 (DP1/A1) re-cut the WRAP GRAIN: `overflow-wrap: anywhere` here
   * shredded labels MID-WORD (`Edi/t/clie/nt` on the 390 client detail); a
   * label wraps BETWEEN its words and never inside one - a button's words are
   * dictionary words, and `max-width` stays the backstop. The final sweep
   * re-cut `normal` -> `break-word`: under `normal` a word that cannot fit
   * its line OVERFLOWS (measured as clipped glyphs at 360), while
   * `break-word` still never breaks a word that fits - the anti-shred
   * property and the overflow safety together. */
  white-space: normal;
  overflow-wrap: break-word;
  max-width: 100%;
  border: var(--lc-border-width) solid transparent;
  border-radius: var(--lc-radius-md);
  cursor: pointer;
  transition: filter var(--lc-motion-fast) var(--lc-ease),
              border-color var(--lc-motion-fast) var(--lc-ease),
              box-shadow var(--lc-motion-fast) var(--lc-ease),
              color var(--lc-motion-fast) var(--lc-ease);
}

/* Visible focus ring on every interactive element (AMD-003 §1 / §4). */
.lc-btn:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

/* --- Sizes: padding + type + hit target. Every size clears --lc-hit-target. --- */
.lc-btn--sm {
  min-height: var(--lc-target-floor);
  /* Block padding space-1 -> space-2 (DP1/Q2.5): a WRAPPED two-line small
   * label outgrows the min-height and its ink then sat ~2px from the pill's
   * own border; a single-line pill is unchanged (min-height still sizes it). */
  padding: var(--lc-space-2) var(--lc-space-3);
  font-size: var(--lc-text-sm);
}
.lc-btn--md {
  min-height: var(--lc-target-floor);
  padding: var(--lc-space-2) var(--lc-space-5);
  font-size: var(--lc-text-base);
}
.lc-btn--lg {
  min-height: var(--lc-hit-target-touch);
  padding: var(--lc-space-3) var(--lc-space-6);
  font-size: var(--lc-text-base);
}

.lc-btn--full {
  width: 100%;
}

/* --- Primary — accessible orange fill + white text (AA on customer surfaces). --- */
.lc-btn--primary {
  background: var(--lc-brand-primary-aa);
  color: var(--lc-on-brand);
}
.lc-btn--primary:hover {
  filter: brightness(0.93);
  box-shadow: var(--lc-shadow-md);
}
.lc-btn--primary:active {
  filter: brightness(0.88);
  box-shadow: var(--lc-shadow-sm);
}

/* --- Secondary — accessible blue fill + white text (AA). --- */
.lc-btn--secondary {
  background: var(--lc-brand-secondary-aa);
  color: var(--lc-on-brand);
}
.lc-btn--secondary:hover {
  filter: brightness(0.93);
  box-shadow: var(--lc-shadow-md);
}
.lc-btn--secondary:active {
  filter: brightness(0.88);
  box-shadow: var(--lc-shadow-sm);
}

/* --- Danger — error-red fill + white text (white on --lc-error is AA). --- */
.lc-btn--danger {
  background: var(--lc-error);
  color: var(--lc-on-brand);
}
.lc-btn--danger:hover {
  filter: brightness(0.93);
  box-shadow: var(--lc-shadow-md);
}
.lc-btn--danger:active {
  filter: brightness(0.88);
  box-shadow: var(--lc-shadow-sm);
}

/* --- Ghost — transparent fill, link-coloured label, grey border (AA on white). --- */
.lc-btn--ghost {
  background: transparent;
  color: var(--lc-link);
  border-color: var(--lc-grey-300);
}
.lc-btn--ghost:hover {
  color: var(--lc-link-hover);
  border-color: var(--lc-grey-500);
  box-shadow: var(--lc-shadow-sm);
}
.lc-btn--ghost:active {
  box-shadow: none;
}

/* --- Disabled / loading — WCAG 1.4.3 exempts disabled controls; grey on grey. --- */
.lc-btn:disabled,
.lc-btn.lc-btn--disabled,
.lc-btn[aria-disabled="true"] {
  background: var(--lc-grey-100);
  color: var(--lc-grey-500);
  border-color: var(--lc-grey-300);
  cursor: not-allowed;
  box-shadow: none;
  filter: none;
}

/* Loading spinner — a small CSS ring shown before the label while aria-busy. */
.lc-btn__spinner {
  display: inline-block;
  width: var(--lc-space-4);
  height: var(--lc-space-4);
  border: var(--lc-border-width) solid currentColor;
  border-top-color: transparent;
  border-radius: var(--lc-radius-pill);
  animation: lc-spin var(--lc-motion-base) linear infinite;
}
@keyframes lc-spin {
  to { transform: rotate(360deg); }
}
.lc-btn__icon {
  display: inline-flex;
  align-items: center;
}

/* ====================================================================== *
 *  BADGE — templates/components/badge.html
 *  variants: success | warning | error | info | neutral  (soft tint + dot)
 * ====================================================================== */
.lc-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--lc-space-2);
  padding: var(--lc-space-1) var(--lc-space-3);
  font-size: var(--lc-text-sm);
  font-weight: var(--lc-weight-semibold);
  /* DP1/A1: a badge word wraps between words, never inside one (the
   * inherited anywhere grain shredded status words at 360). */
  overflow-wrap: break-word;
  line-height: 1.2;
  color: var(--lc-grey-900);              /* ink on every soft tint is AA */
  background: var(--lc-grey-100);
  border-left: var(--lc-space-1) solid var(--lc-grey-500);
  border-radius: var(--lc-radius-pill);
  /* A BADGE MAY NEVER BE WIDER THAN WHAT HOLDS IT (ADR 0187) - the ADR-0178
   * rule that took `.lc-btn`'s `nowrap`, applied to the other incompressible
   * label in the library. The ADR-0119 o8 wording „Politically exposed person
   * (PEP)" is a 349px badge, so on a 360px window it put the WHOLE loan-detail
   * page into horizontal scroll. A badge that fits still renders on one line -
   * an inline-flex box is shrink-to-fit and only wraps when it must. */
  white-space: normal;
  max-width: 100%;
}

/* Leading dot echoes the semantic colour for non-colour-only signalling. */
.lc-badge__dot {
  display: inline-block;
  width: var(--lc-space-2);
  height: var(--lc-space-2);
  border-radius: var(--lc-radius-pill);
  background: var(--lc-grey-500);
  flex: none;
}

.lc-badge--success {
  background: var(--lc-success-soft);
  border-left-color: var(--lc-success);
}
.lc-badge--success .lc-badge__dot { background: var(--lc-success); }

.lc-badge--warning {
  background: var(--lc-warning-soft);
  border-left-color: var(--lc-warning);
}
.lc-badge--warning .lc-badge__dot { background: var(--lc-warning); }

.lc-badge--error {
  background: var(--lc-error-soft);
  border-left-color: var(--lc-error);
}
.lc-badge--error .lc-badge__dot { background: var(--lc-error); }

.lc-badge--info {
  background: var(--lc-info-soft);
  border-left-color: var(--lc-info);
}
.lc-badge--info .lc-badge__dot { background: var(--lc-info); }

.lc-badge--neutral {
  background: var(--lc-grey-100);
  border-left-color: var(--lc-grey-500);
}

/* ====================================================================== *
 *  PROGRESS — templates/components/progress.html
 *  determinate (value 0–100) | indeterminate (no value, animated)
 * ====================================================================== */
.lc-progress {
  display: block;
}
.lc-progress__label {
  display: flex;
  justify-content: space-between;
  gap: var(--lc-space-3);
  margin-bottom: var(--lc-space-2);
  font-size: var(--lc-text-sm);
  font-weight: var(--lc-weight-semibold);
  color: var(--lc-grey-700);
}
.lc-progress__value {
  color: var(--lc-grey-900);
  font-variant-numeric: tabular-nums;
}
.lc-progress__track {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: var(--lc-space-2);
  background: var(--lc-grey-100);
  border-radius: var(--lc-radius-pill);
}
/* No text ever sits on the fill, so the accessible blue fill needs no contrast pair. */
.lc-progress__fill {
  height: 100%;
  background: var(--lc-brand-secondary-aa);
  border-radius: var(--lc-radius-pill);
  transition: width var(--lc-motion-base) var(--lc-ease);
}

/* Indeterminate — a travelling partial bar when no value is known. */
.lc-progress--indeterminate .lc-progress__fill {
  width: 40%;
  animation: lc-progress-slide calc(var(--lc-motion-base) * 6) var(--lc-ease) infinite;
}
@keyframes lc-progress-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

/* ====================================================================== *
 *  TOAST — templates/components/toast.html
 *  variants: success | info | warning | error  (soft tint + semantic border)
 * ====================================================================== */
.lc-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--lc-space-3);
  max-width: 28rem;
  padding: var(--lc-space-3) var(--lc-space-4);
  color: var(--lc-grey-900);              /* ink on every soft tint is AA */
  background: var(--lc-grey-100);
  border-left: var(--lc-space-1) solid var(--lc-grey-500);
  border-radius: var(--lc-radius-md);
  box-shadow: var(--lc-shadow-lg);
  z-index: var(--lc-z-toast);
  transition: opacity var(--lc-motion-base) var(--lc-ease),
              transform var(--lc-motion-base) var(--lc-ease);
}
.lc-toast__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--lc-space-5);
  height: var(--lc-space-5);
  font-weight: var(--lc-weight-bold);
  line-height: 1;
}
.lc-toast__body {
  flex: 1 1 auto;
  min-width: 0;
}
.lc-toast__title {
  margin: 0 0 var(--lc-space-1);
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-bold);
}
.lc-toast__message {
  margin: 0;
  font-size: var(--lc-text-sm);
  line-height: 1.5;
}
.lc-toast__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--lc-target-floor);
  min-height: var(--lc-target-floor);
  margin: calc(-1 * var(--lc-space-2)) calc(-1 * var(--lc-space-2)) 0 0;
  padding: 0;
  font: inherit;
  font-size: var(--lc-text-base);
  line-height: 1;
  color: var(--lc-grey-700);
  background: transparent;
  border: var(--lc-border-width) solid transparent;
  border-radius: var(--lc-radius-sm);
  cursor: pointer;
  transition: color var(--lc-motion-fast) var(--lc-ease);
}
.lc-toast__close:hover {
  color: var(--lc-grey-900);
}
.lc-toast__close:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

.lc-toast--success {
  background: var(--lc-success-soft);
  border-left-color: var(--lc-success);
}
.lc-toast--success .lc-toast__icon { color: var(--lc-success); }

.lc-toast--info {
  background: var(--lc-info-soft);
  border-left-color: var(--lc-info);
}
.lc-toast--info .lc-toast__icon { color: var(--lc-info); }

.lc-toast--warning {
  background: var(--lc-warning-soft);
  border-left-color: var(--lc-warning);
}
.lc-toast--warning .lc-toast__icon { color: var(--lc-warning); }

.lc-toast--error {
  background: var(--lc-error-soft);
  border-left-color: var(--lc-error);
}
.lc-toast--error .lc-toast__icon { color: var(--lc-error); }

/* ====================================================================== *
 *  MODAL — templates/components/modal.html
 *  sizes: sm | md | lg     role="dialog" aria-modal, focus-trapped, Esc closes
 * ====================================================================== */
.lc-modal__trigger {
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--lc-space-2);
  min-height: var(--lc-target-floor);
  padding: var(--lc-space-2) var(--lc-space-5);
  font: inherit;
  font-weight: var(--lc-weight-semibold);
  line-height: 1.2;
  color: var(--lc-link);
  background: transparent;
  border: var(--lc-border-width) solid var(--lc-grey-300);
  border-radius: var(--lc-radius-md);
  cursor: pointer;
  transition: color var(--lc-motion-fast) var(--lc-ease),
              border-color var(--lc-motion-fast) var(--lc-ease),
              box-shadow var(--lc-motion-fast) var(--lc-ease);
}
.lc-modal__trigger:hover {
  color: var(--lc-link-hover);
  border-color: var(--lc-grey-500);
  box-shadow: var(--lc-shadow-sm);
}
.lc-modal__trigger:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

/* Backdrop — covers the viewport; the modal layer sits above page chrome. */
.lc-modal__overlay {
  position: fixed;
  inset: 0;
  z-index: var(--lc-z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--lc-space-4);
  background: rgba(var(--lc-shadow-color-rgb), 0.55);
  transition: opacity var(--lc-motion-base) var(--lc-ease);
}

.lc-modal__dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 32rem;
  max-height: 90vh;
  overflow: hidden;
  background: var(--lc-white);
  color: var(--lc-grey-900);
  border-radius: var(--lc-radius-lg);
  box-shadow: var(--lc-shadow-lg);
  transition: opacity var(--lc-motion-base) var(--lc-ease),
              transform var(--lc-motion-base) var(--lc-ease);
}
.lc-modal__dialog:focus {
  outline: none;
}
.lc-modal__dialog:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}
.lc-modal__dialog--sm { max-width: 24rem; }
.lc-modal__dialog--md { max-width: 32rem; }
.lc-modal__dialog--lg { max-width: 48rem; }

.lc-modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--lc-space-4);
  padding: var(--lc-space-5);
  border-bottom: var(--lc-border-width) solid var(--lc-grey-300);
}
.lc-modal__title {
  margin: 0;
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-bold);
  color: var(--lc-grey-900);
}
.lc-modal__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--lc-target-floor);
  min-height: var(--lc-target-floor);
  margin: calc(-1 * var(--lc-space-2)) calc(-1 * var(--lc-space-2)) 0 0;
  padding: 0;
  font: inherit;
  font-size: var(--lc-text-base);
  line-height: 1;
  color: var(--lc-grey-700);
  background: transparent;
  border: var(--lc-border-width) solid transparent;
  border-radius: var(--lc-radius-sm);
  cursor: pointer;
  transition: color var(--lc-motion-fast) var(--lc-ease);
}
.lc-modal__close:hover {
  color: var(--lc-grey-900);
}
.lc-modal__close:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}
.lc-modal__body {
  padding: var(--lc-space-5);
  overflow-y: auto;
}

/* ====================================================================== *
 *  Responsive — give toasts room on narrow viewports. 40rem is the
 *  canonical sm breakpoint (ADR 0108 — the pinned breakpoint scale).
 * ====================================================================== */
@media (max-width: 40rem) {
  .lc-toast {
    max-width: none;
  }
}

/* ====================================================================== *
 *  Motion (AMD-003 §5) — honour prefers-reduced-motion: no animation, no
 *  transition; the indeterminate progress bar becomes a static partial fill.
 * ====================================================================== */
@media (prefers-reduced-motion: reduce) {
  .lc-btn,
  .lc-modal__trigger,
  .lc-modal__close,
  .lc-toast,
  .lc-toast__close,
  .lc-modal__overlay,
  .lc-modal__dialog,
  .lc-progress__fill {
    transition: none;
  }
  .lc-btn__spinner,
  .lc-progress--indeterminate .lc-progress__fill {
    animation: none;
  }
  .lc-progress--indeterminate .lc-progress__fill {
    width: 40%;
    transform: none;
  }
}
/* ===== Cluster: layout & data ===== */
/*
 * Lev Credit — Phase-1 component library: LAYOUT & DATA cluster.
 * Partials: templates/components/{card,tabs,table}.html.
 *
 * Presentation only (HTML/CSS/Alpine) — NO Python, model, view or templatetag.
 *
 * TOKENS ONLY. Every colour, radius, spacing, type-step, shadow, border and motion
 * value is a var(--lc-…) from the canonical token stylesheet (static/css/tokens.css).
 * NO hex literal and NO magic px appears here — the AMD-002/AMD-003 build gate
 * (apps/backoffice/tests/test_branding.py) fails on either.
 *
 * Contrast (AMD-003): grey-900 ink on white / cream / *-soft tints, grey-700/500 on
 * white — all WCAG AA. No brand colour is ever used as text (brand is a BACKGROUND
 * fill only); the selected-tab indicator is an underline + --lc-link text on a
 * brand-secondary-soft tint, never brand-as-text. Every interactive control carries
 * a visible :focus-visible ring, a ≥ --lc-hit-target hit area, and respects
 * prefers-reduced-motion.
 */

/* ====================================================================== *
 *  CARD — templates/components/card.html
 *  .lc-card / __header / __title / __body / __footer.
 *  Elevation sm|md; padded (default) | flush body.
 * ====================================================================== */
.lc-card {
  background: var(--lc-white);
  color: var(--lc-grey-900);
  border: var(--lc-border-width) solid var(--lc-grey-300);
  border-radius: var(--lc-radius-lg);
  font-size: var(--lc-text-base);
  line-height: 1.5;
  overflow: hidden;
}

.lc-card--elev-sm {
  box-shadow: var(--lc-shadow-sm);
}

.lc-card--elev-md {
  box-shadow: var(--lc-shadow-md);
}

.lc-card__header {
  padding: var(--lc-space-4) var(--lc-space-5);
  border-bottom: var(--lc-border-width) solid var(--lc-grey-300);
}

.lc-card__title {
  margin: 0;
  font-size: var(--lc-text-base);
  font-weight: var(--lc-weight-bold);
  color: var(--lc-grey-900);
  line-height: 1.3;
}

/* Padded body (default). The flush variant removes body padding so the caller can
 * place an edge-to-edge child (e.g. a table) inside the card. */
.lc-card--padded .lc-card__body {
  padding: var(--lc-space-5);
}

.lc-card--flush .lc-card__body {
  padding: 0;
}

.lc-card__footer {
  padding: var(--lc-space-4) var(--lc-space-5);
  border-top: var(--lc-border-width) solid var(--lc-grey-300);
  background: var(--lc-cream);
  color: var(--lc-grey-900);
}

/* ====================================================================== *
 *  TABS — templates/components/tabs.html
 *  .lc-tabs / __list / __tab (--active) / __panel.
 *  Roving-tabindex tablist (Alpine); selected = underline indicator + ink/link
 *  text on a brand-secondary-soft tint — NEVER brand-as-text.
 * ====================================================================== */
.lc-tabs {
  font-size: var(--lc-text-base);
  color: var(--lc-grey-900);
}

.lc-tabs__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--lc-space-1);
  border-bottom: var(--lc-border-width) solid var(--lc-grey-300);
}

.lc-tabs__tab {
  appearance: none;
  margin: 0;
  display: inline-flex;
  align-items: center;
  min-height: var(--lc-target-floor);
  padding: var(--lc-space-2) var(--lc-space-4);
  background: transparent;
  color: var(--lc-grey-700);
  border: none;
  border-bottom: var(--lc-space-1) solid transparent;
  border-top-left-radius: var(--lc-radius-md);
  border-top-right-radius: var(--lc-radius-md);
  font: inherit;
  font-weight: var(--lc-weight-semibold);
  cursor: pointer;
  transition: background-color var(--lc-motion-fast) var(--lc-ease),
              color var(--lc-motion-fast) var(--lc-ease),
              border-color var(--lc-motion-fast) var(--lc-ease);
}

.lc-tabs__tab:hover {
  background: var(--lc-grey-100);
  color: var(--lc-grey-900);
}

/* Selected tab: brand-secondary-soft tint + ink text (AA) and a --lc-link
 * underline indicator. Brand colour appears only as a fill / indicator, not text. */
.lc-tabs__tab--active {
  background: var(--lc-brand-secondary-soft);
  color: var(--lc-grey-900);
  border-bottom-color: var(--lc-link);
}

.lc-tabs__tab:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

.lc-tabs__panel {
  padding: var(--lc-space-5) 0;
  color: var(--lc-grey-900);
}

.lc-tabs__panel:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

/* ====================================================================== *
 *  TABLE — templates/components/table.html
 *  .lc-table__container (bordered, rounded) > .lc-table.
 *  __caption / __head / __th / __sort / __body / __row / __td.
 *  Zebra + hover via grey tints; ink stays on white/tints (AA). Dense steps
 *  the type down to --lc-text-sm with tighter padding for regulated tables.
 * ====================================================================== */
.lc-table__container {
  border: var(--lc-border-width) solid var(--lc-grey-300);
  border-radius: var(--lc-radius-sm);
  overflow-x: auto;
  background: var(--lc-white);
  /* Anchor absolutely-positioned descendants (sr-only sort hints) INSIDE the
   * scroll container — unanchored they extend the PAGE scroll width when the
   * table overflows (ADR 0131: the portal 390px horizontal-scroll defect). */
  position: relative;
}

.lc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--lc-text-base);
  color: var(--lc-grey-900);
}

.lc-table__caption {
  text-align: left;
  padding: var(--lc-space-3) var(--lc-space-4);
  font-weight: var(--lc-weight-bold);
  color: var(--lc-grey-900);
  background: var(--lc-white);
}

.lc-table__th {
  text-align: left;
  padding: var(--lc-space-3) var(--lc-space-4);
  background: var(--lc-cream);
  color: var(--lc-grey-900);
  font-size: var(--lc-text-sm);
  font-weight: var(--lc-weight-bold);
  border-bottom: var(--lc-border-width) solid var(--lc-grey-300);
  white-space: nowrap;
}

.lc-table__td {
  padding: var(--lc-space-3) var(--lc-space-4);
  color: var(--lc-grey-900);
  border-bottom: var(--lc-border-width) solid var(--lc-grey-100);
  vertical-align: top;
}

/* A TABLE CELL IS NOT PROSE (ADR 0178). The content roots break an unbreakable
 * token so no single URL can widen the page - but `overflow-wrap: anywhere`
 * INHERITS, and unlike `break-word` it lowers the min-content width, which under
 * auto table layout is the column's own floor. Left inherited it made a wide
 * worklist stop scrolling and start squashing: measured on a six-column Cyrillic
 * row, intrinsic width 691px -> 600px, first column 125px -> 62px, and a name
 * breaking mid-word as "Алексан/дрина". That contradicts ADR 0108 (a wide table
 * SCROLLS inside its wrap) and the ADR-0135 n7 rule, which declares exactly this
 * for `th` and says why: word-wrap "between words only, never inside one".
 * Cells opt back out; the header rule keeps its own scoped declaration.
 * `:is(th, td)` rather than the two class names: the final sweep found hand
 * templates carrying an unstyled `lc-table__cell` spelling whose cells kept
 * the inherited anywhere grain and shredded words - ANY cell of a `.lc-table`
 * is a cell of the library table, whatever its class attribute says. */
.lc-table :is(th, td) { overflow-wrap: normal; }

/* THE FIGURE CLASS ON EVERY SURFACE (ADR 0191, DP1/A1): the portal's date
 * cells and contract-number titles joined `.lc-num` in the final sweep, and
 * the class was defined only in office.css - the token-integrity law is
 * surface-blind, so the library carries the one shared declaration (the
 * doctrine comment lives beside the office figure slots). */
.lc-num { white-space: nowrap; }

/* `lc-table__cell` is the same cell (DP1): several office registers spell the
 * body-cell class this way, and unstyled it carried NO padding - measured as
 * ink 2.5px from the bordered wrap's bottom edge and cells set in the browser
 * default 1px. One alias, same box as `.lc-table__td`. */
.lc-table__cell {
  padding: var(--lc-space-3) var(--lc-space-4);
  color: var(--lc-grey-900);
  border-bottom: var(--lc-border-width) solid var(--lc-grey-100);
  vertical-align: top;
}

/* Alignment carried from the column descriptor onto both head and body cells. */
.lc-table__cell--center {
  text-align: center;
}

.lc-table__cell--right {
  text-align: right;
}

.lc-table__cell--left {
  text-align: left;
}

/* Zebra striping + hover via neutral grey tints — ink text stays AA on both. */
.lc-table__body .lc-table__row:nth-child(even) .lc-table__td {
  background: var(--lc-cream);
}

.lc-table__body .lc-table__row:hover .lc-table__td {
  background: var(--lc-grey-100);
}

.lc-table__row:last-child .lc-table__td {
  border-bottom: none;
}

/* Sort affordance — look only this slice (no real sorting). A real <button> so it
 * is keyboard-focusable; the glyph is decorative (aria-hidden in the partial). */
.lc-table__sort {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: var(--lc-space-2);
  min-height: var(--lc-target-floor);
  margin: 0;
  padding: var(--lc-space-1) var(--lc-space-2);
  background: transparent;
  color: var(--lc-grey-900);
  border: none;
  border-radius: var(--lc-radius-xs);
  font: inherit;
  font-weight: var(--lc-weight-bold);
  cursor: pointer;
  transition: background-color var(--lc-motion-fast) var(--lc-ease);
}

.lc-table__sort:hover {
  background: var(--lc-grey-100);
}

.lc-table__sort:focus-visible {
  outline: var(--lc-focus-ring-width) solid var(--lc-focus-ring-color);
  outline-offset: var(--lc-focus-ring-offset);
}

.lc-table__sort-glyph {
  color: var(--lc-grey-700);
  font-size: var(--lc-text-xs);
}

/* Empty state — a single full-width cell, quiet ink, centred. */
.lc-table__td--empty {
  text-align: center;
  padding: var(--lc-space-6) var(--lc-space-4);
  color: var(--lc-grey-700);
}

/* Dense — regulated / tabular data steps the type down and tightens padding. */
.lc-table--dense {
  font-size: var(--lc-text-sm);
}

.lc-table--dense .lc-table__th,
.lc-table--dense .lc-table__td {
  padding: var(--lc-space-2) var(--lc-space-3);
}

.lc-table--dense .lc-table__th {
  font-size: var(--lc-text-xs);
}

/* ====================================================================== *
 *  Motion (AMD-003 §5) — honour prefers-reduced-motion: no transitions.
 * ====================================================================== */
@media (prefers-reduced-motion: reduce) {
  .lc-tabs__tab,
  .lc-table__sort {
    transition: none;
  }
}

/* ====================================================================== *
 *  THE HIT-TARGET LAW — the shared library (ADR 0186, owner item 3)
 *
 *  The floor itself lives in tokens.css and carried every control already
 *  sitting on --lc-hit-target. What lands here is the pair the floor could not
 *  reach on its own: a CHECKBOX and a RADIO are ~24px boxes by design, and
 *  making them 44px squares would be a regression bought by measuring the
 *  wrong thing. A control's target is the union of its box and the LABEL that
 *  names it - clicking the label toggles the control - so the LABEL carries
 *  the floor and the box keeps its size. The ADR-0186 detector measures that
 *  same union, which is why the two agree.
 * ====================================================================== */
.lc-checkbox__label,
.lc-radio__option-label {
  display: inline-flex;
  align-items: center;
  min-height: var(--lc-target-floor);
}

/* A BUTTON HAS TWO DIMENSIONS AND THE LAW BINDS ON BOTH. `.lc-btn` had a
 * min-height and no min-width, so a short label - the header's „Вход" chip at
 * 42px, a `←` year step - cleared the floor vertically and missed it across.
 * THE ORDERING, STATED CORRECTLY: the used width is
 * `max(min-width, min(max-width, width))`, so `min-width` WINS over
 * `max-width: 100%` - a container narrower than 44px WOULD be overflowed by
 * the floor. What makes that safe is a MEASUREMENT, not this rule: the
 * ADR-0186 census reports zero page-level horizontal scroll across 105 pages
 * down to 390px. The ADR-0178 declarations below handle the far commoner
 * case - a LONG label - and are untouched. */
.lc-btn { min-width: var(--lc-target-floor); }

/* Stacked fields keep the law's clear space between their controls. */
.lc-field + .lc-field,
.lc-checkbox + .lc-checkbox { margin-top: var(--lc-target-gap); }

/* A CHECKBOX OR RADIO'S TARGET IS ITS LABEL, wherever the label comes from.
 * `.lc-checkbox__label` above covers the library component; a raw Django
 * widget (the product editor's flags, the wizard's contact-consent formset,
 * the ID-card "indefinite" tick) renders its own <label> instead, and those
 * unions measured 39.4px. Both association shapes are covered - the label
 * WRAPPING the control, and the label beside it in the same field block -
 * because the design system does not get to choose which one a Django form
 * emits. (ADR 0186) */
label:has(> input[type="checkbox"]),
label:has(> input[type="radio"]),
p:has(> input[type="checkbox"]) > label,
p:has(> input[type="radio"]) > label,
div:has(> input[type="checkbox"]) > label,
div:has(> input[type="radio"]) > label {
  display: inline-flex;
  align-items: center;
  min-height: var(--lc-target-floor);
}

/* A hand-built form (the portal profile stacks label/control pairs straight
 * into its <form>) has no field wrapper to carry the rhythm, so its controls
 * butted at zero. Whatever FOLLOWS a control starts something new and takes
 * the law's clear space. (ADR 0186) */
:is(.lc-input, .lc-select, .lc-textarea) + .lc-field__label {
  /* A <label> is INLINE by default and a vertical margin on an inline box does
   * NOTHING - which is why the portal address form still measured 1px after the
   * margin was added. The display change is what makes the margin real. */
  display: block;
  margin-top: var(--lc-target-gap);
}
:is(.lc-input, .lc-select, .lc-textarea)
  + :is(.lc-btn, .lc-input, .lc-select, .lc-textarea) {
  margin-top: var(--lc-target-gap);
}
