/* 05-forms.css: Form sections and banners, form blocks, document and check rows, generic form controls,
   inline POST forms.
   Loaded by base.html, one <link> per file in number order; a later file wins on source order. */

/* Grouped form sections with a header and an optional info banner, per the
   BOLT mockups (e.g. HEA-232's candidate intake). */
.form-section {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  margin-top: 1.25rem;
}

.form-section h2 {
  font-size: 1rem;
  margin: 0 0 1rem;
}

/* Neutral by default (HEA-461): most plain banners state a fact, not a
   problem, so the fill is sand, not the salmon that used to read as
   "something is wrong". A banner that shows a real error or a validation
   warning carries .info-banner-error / .info-banner-warning on top. */
.info-banner {
  display: flex;
  gap: 0.6rem;
  background: var(--color-bg-accent);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text);
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  font-size: 0.875rem;
  margin-bottom: 1rem;
}

/* A banner whose padding is its edge (the intake's and the supplement page's
   notices): the last block inside it adds no margin below, and a banner that
   is one paragraph adds none above either. Opt-in, so no other banner moves. */
.info-banner--flush > p,
.info-banner--flush > div > :last-child {
  margin-bottom: 0;
}

.info-banner--flush > p {
  margin-top: 0;
}

/* Its bold title and the sentence under it read as one notice, as
   HEA-236_aanvullingspagina.png sets them: a hair apart, not a paragraph. */
.info-banner--flush strong + p {
  margin-top: 0.25rem;
}

/* One that closes a card (the intake's "provided later" warning under the
   upload form) keeps a row's distance from what precedes it. */
.form-section > .info-banner--flush:last-child {
  margin: 1rem 0 0;
}

/* One after a card's read-only rows, or after another such banner, keeps a row's distance from
   the rule above it, as fields after .info-rows do. */
.info-rows + .info-banner--flush,
.info-banner--flush + .info-banner--flush {
  margin-top: 1rem;
}

/* A banner headed like a card, e.g. the outstanding-invitations signal on a
   company page. Same reasoning as .form-section h2: the banner sets its own
   compact scale, so its heading drops the browser's h2 size and margins
   rather than pushing the banner open around one line of content. */
.info-banner h2 {
  font-size: 1rem;
  margin: 0;
}

/* Actions parked at the right end of a banner, per HEA-192's alert. */
.info-banner__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  flex-shrink: 0;
}

/* A form's submit row when its actions are not in the page header. */
.form-section__actions {
  margin-top: 1rem;
}

.form-section__actions--end {
  display: flex;
  justify-content: flex-end;
}

/* A labelled group of fields inside one card -- HEA-185's contact role
   blocks: a small heading with its pill, then a field row. */
.form-block + .form-block {
  margin-top: 1.75rem;
}

/* A .form-block set off as a panel of its own inside its card: hairline
   border, the card radius and its own padding. For a card that stacks
   several peer blocks a reader must tell apart at a glance -- HEA-451 puts
   one per klant-brokerrelatie inside a single "Afspraken via de broker"
   card, so the two brokers' ruled rows cannot run together. */
.form-block--boxed {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  /* HEA-451: the fill is deliberately this one declaration, so the choice
     between a filled and an outlined panel is a one-line change. */
  background: var(--color-bg);
}

.form-block__head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.form-block__head h3 {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 700;
}

/* Secondary text sitting inline in a row, e.g. a document's version. */
.muted-inline {
  color: var(--color-muted);
  font-size: 0.8125rem;
}

/* components/_error_inline.html: its lines sit tight, whether the box is inside a form (where
   `.page form p` already zeroes the top) or on a bare page (where a paragraph's default top margin
   would push the text down). */
.info-banner-error.info-banner--flush > div > p {
  margin: 0 0 0.35rem;
}

.info-banner-error.info-banner--flush > div > p:last-child {
  margin-bottom: 0;
}

.info-banner-error {
  background: var(--color-error-bg);
  border-color: var(--color-error);
  color: var(--color-error);
}

/* The "+ Add contact person" button under a contact list
   (companies/_contact_list.html): a row's distance below the last row, and the
   same again above the pickers (.contact-pickers) that follow it. */
.contact-editor__add {
  margin-top: 1.25rem;
}

.contact-pickers {
  margin-top: 1.25rem;
}

/* The list under an error summary's title (components/_error_summary.html): one
   plain row per problem, the link itself being the message. The banner is
   focused on load, so its outline is the focus ring, not the field it names. */
.error-summary__list {
  margin: 0.4rem 0 0;
  padding-left: 1.1rem;
}

/* A link inside an error or warning banner's sentence (the scheduled-jobs notice, HEA-495;
   the send confirmation, HEA-198) takes the banner's colour: the underline and the weight
   mark it as the link. */
.info-banner-error a,
.info-banner-warning a {
  color: inherit;
  font-weight: 600;
}

/* A banner stating a settled, good fact: the G-rekening split (HEA-213 inkoop),
   the kickback grondslag, a signed contract with nothing open (HEA-460). */
.info-banner-success {
  background: var(--color-success-bg);
  border-color: rgba(22, 101, 52, 0.25);
  color: var(--color-success-fg);
}

/* Status banner with a heading line, body lines and a muted note, e.g.
   HEA-189's "Dossier incompleet - uitbetaling geblokkeerd". Unlike
   .info-banner-error only the heading takes the status colour: the body is
   read, not alarmed at. Border sampled #e6aa9b off the mockup, i.e. the
   error colour at 35% over the banner's own fill. */
.info-banner--danger {
  align-items: center;
  background: var(--color-error-bg);
  border-color: rgba(180, 35, 24, 0.35);
  padding: 1rem 1.25rem;
}

/* The same banner when Management has lifted the block: an incomplete
   dossier that does not block payout. */
.info-banner--warning {
  align-items: center;
  background: var(--color-warning-bg);
  border-color: rgba(138, 90, 18, 0.3);
  padding: 1rem 1.25rem;
}

.info-banner--danger p,
.info-banner--warning p {
  margin: 0.15rem 0 0;
}

/* `.page form p` (1rem below every paragraph) outranks the rule above, so a banner inside a form
   would grow a gap under its title and a tall bottom edge. */
.page form .info-banner--danger p,
.page form .info-banner--warning p {
  margin: 0.15rem 0 0;
}

.info-banner__title {
  font-size: 1rem;
  font-weight: 700;
}

.info-banner--danger .info-banner__title {
  color: var(--color-error);
}

.info-banner--warning .info-banner__title {
  color: var(--color-warning-fg);
}

.info-banner__note {
  color: var(--color-muted);
  font-size: 0.8125rem;
}

/* "Leveranciers /" above a detail title (HEA-189), in place of a Terug
   button: it names where the page sits, not just that there is a way out. */
.breadcrumb {
  margin: 0 0 0.25rem;
  font-size: 0.8125rem;
  color: var(--color-muted);
}

.breadcrumb a {
  color: var(--color-muted);
  text-decoration: none;
}

.breadcrumb a:hover {
  color: var(--color-primary);
}

/* A detail title with its pills beside it on one line (HEA-189: name + type). */
.page-header__title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
}

/* A document/check list whose status pills line up in a column of their own,
   as HEA-189 draws them (pills start half way across the card), rather than
   .check-row's pill pushed to the far right. One grid for the whole list, each
   row's cells laid straight into it (display: contents), so the columns align
   across rows whatever each row carries; a row's history spans the width.
   The row actions share the pill's cell, pushed right, so they never move
   the pill column off the card's midline. */
.dossier-grid {
  display: grid;
  /* The name column holds the longest document label ("Polis
     beroepsaansprakelijkheid (BAV)") on one line, so every row is the name
     over its "download · vN" / a check's outcome with its date -- two lines --
     and no row grows to a third (HEA-462). Without the floor the name column
     kept only what the status column left and the longest label wrapped. */
  /* The status column takes what its widest cell needs: one pill, and
     Opnieuw beside a check's (HEA-507). */
  grid-template-columns: minmax(16rem, 1fr) auto;
  align-items: center;
  column-gap: 1rem;
  row-gap: 0.1rem;
}

/* The status column takes the width its longest pill needs rather than the
   mockup's half of the card. The pills still start in one column, which is
   what HEA-189 draws; they start further right than the mockup's midline. */
.dossier-grid__status {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  white-space: nowrap;
}

.dossier-grid__row {
  display: contents;
}

/* Every row reserves the height the tallest one needs -- a two-line document
   name with its "download · v2" -- so the rows read as one set instead of
   stepping with their content. */
.dossier-grid__row > * {
  /* 3.3rem plus the padding is 64px: the tallest row carries three lines
     (the name, its line under it, the earlier versions' summary). */
  min-height: 3.3rem;
  padding: 0.35rem 0;
}


/* Name on its own line, "download · v2" / a check's outcome on the next -- always, for
   every row, one layout across the card (HEA-462, against
   HEA-189_leverancierdetail). In the 6/6 card the name column is half the
   mockup's width, so an inline hint sits beside a short name but wraps below a
   long one; stacking places it below in both. The 2.8rem row floor holds the
   two lines. */
.dossier-grid__name {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 0.1rem 0;
  font-size: 0.875rem;
  font-weight: 600;
  /* Tight lines: a row with earlier versions holds a third line, their
     summary, inside the same row height. */
  line-height: 1.25;
}

.dossier-grid__name a {
  color: var(--color-primary-hover);
}

.dossier-grid__name .muted-inline {
  white-space: nowrap;
}

.dossier-grid__actions {
  display: flex;
  flex-shrink: 0;
  gap: 0.4rem;
  margin-left: auto;
  white-space: nowrap;
}

.dossier-grid__history {
  grid-column: 1 / -1;
  /* The row-height floor is for the rows themselves; the fold-out under one
     takes exactly the height its list needs. */
  min-height: 0;
  padding: 0;
  font-size: 0.8125rem;
  line-height: 1.3rem;
}

/* Closed, a row's earlier versions are one summary line under its name, inside
   the row's own height: the name gives up that line and the status cell spans
   both, so the row stands as tall as the others and its pill stays on their
   centre line. Open, the list takes the card's width under the row. */
.dossier-grid__history:not([open]) {
  grid-column: 1;
  height: 1.3rem;
}

.dossier-grid__row:has(> .dossier-grid__history:not([open])) > .dossier-grid__name {
  min-height: 2.25rem;
  padding: 0.2rem 0 0;
}

.dossier-grid__row:has(> .dossier-grid__history:not([open])) > .dossier-grid__status {
  grid-row: span 2;
}

.dossier-grid__history summary {
  color: var(--color-muted);
  cursor: pointer;
}

.dossier-grid__history ul {
  margin: 0.3rem 0 0.4rem;
  padding: 0 0 0 1rem;
  list-style: none;
}

.dossier-grid__history li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.15rem 0;
}

.dossier-grid__note {
  margin-top: 0.85rem;
}

/* One row per configured document type (HEA-185 step 1's "Documenten &
   checks" card). Every row shares this same grid-template-columns
   -- name, pill, description, actions -- rather than
   each row's own flex layout deciding its own column widths
   from its own content: that would let the pill and description start at a
   different x per row (a long name, or no actions at all on the check
   row, pushes everything after it over). They are not a subgrid of one
   another; five rows with an identical explicit template line up exactly
   the same without one. The pill and badge live in their own columns, not
   nested inside .doc-checklist__name/__actions, so their content's own
   width never feeds back into where the *next* column starts. */
.doc-checklist__row {
  display: grid;
  /* The name column fits the longest configured label on one line ("Bewijs
     ondernemerschap inkomstenbelasting", ZZP scope); at 16rem it wraps and
     that row stands 10px taller than its neighbours. */
  grid-template-columns: 19rem 6rem 16rem minmax(14rem, 1fr);
  align-items: center;
  column-gap: 0.75rem;
  row-gap: 0.35rem;
  /* Every row reserves the height the tallest needs: a row whose slots hold a
     date input stands 3px taller than one that only carries the choice group,
     and a set of rows that steps by 3px reads as a mistake. */
  min-height: 2.2rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--color-border);
}

/* The last row keeps the border's 1px in its box, transparent, so it stands
   exactly as tall as the rows above it. */
.doc-checklist__row:last-child {
  border-bottom-color: transparent;
}

/* A document card whose types carry no verplicht/optioneel pill (HEA-447),
   because
   which documents are demanded is not modelled for them (HEA-225). Same row
   grid without the pill column, and a name column sized for its own longest
   label rather than the supplier catalog's. Every row still shares one
   explicit template, which keeps the columns in line down the card. */
.doc-checklist--plain .doc-checklist__row {
  grid-template-columns: 12rem 11rem minmax(14rem, 1fr);
}

.doc-checklist__name {
  font-size: 0.875rem;
  font-weight: 600;
}

.doc-checklist__badge {
  display: flex;
}

.doc-checklist__description {
  color: var(--color-muted);
  font-size: 0.8125rem;
}

.doc-checklist__actions {
  display: flex;
  justify-content: flex-end;
}

/* Four slots in every row, documents and checks alike, so each control sits
   at the same x down the card (HEA-189): the choice (the later-or-file
   group / a check's result), the date the row needs, the file name, and the
   end slot (Intrekken / "automatisch"). A slot a row does not use stays empty
   rather than letting the next control slide left -- which is what keeps the
   "automatisch" pills in one column with the Intrekken buttons (HEA-444).
   Anchored right, as the mockup's "+" column is. */
.doc-checklist__upload {
  display: grid;
  /* The end slot fits "Opnieuw controleren" on one line (HEA-444): at the
     5.75rem "Intrekken" needs, that button breaks over two lines and makes the
     check rows taller than the document rows. */
  grid-template-columns: 8.5rem 9rem 8rem 9.5rem;
  justify-content: end;
  align-items: center;
  column-gap: 0.5rem;
}

/* No end-slot control ever wraps: a button broken over two lines stops
   reading as one, and it would set the height of its row alone. */
.doc-checklist__slot--end .btn-quiet {
  white-space: nowrap;
}

/* The two ways a document row can go forward, in one outlined control
   (HEA-444): promise it for later, or attach the file now. Same shape as
   .segmented -- both inputs stay in the DOM, clipped and focusable, so the
   group is operable by keyboard as the native controls it is made of -- but
   sized for a card row rather than a filter bar, and its second option is a
   label for the row's own .sr-only file input rather than a radio. They
   exclude each other; doc_upload.js clears the one when the other is picked. */
.doc-choice {
  display: inline-flex;
  width: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
}

.doc-choice__option {
  display: inline-flex;
  position: relative;
  flex: 1;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0.3rem 0.5rem;
  background: var(--color-bg-accent);
  color: var(--color-muted);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
}

/* The "+" is the narrow half: the word carries the meaning, the plus is an
   affordance beside it. */
.doc-choice__option--file {
  flex: 0 0 2.75rem;
  border-left: 1px solid var(--color-border);
  font-size: 1rem;
}

.doc-choice__option input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
}

.doc-choice__option:has(input:checked),
.doc-choice__option--file.is-chosen {
  background: var(--color-primary);
  color: #ffffff;
}

.doc-choice__option:has(input:focus-visible) {
  outline: 3px solid rgba(230, 83, 46, 0.35);
  outline-offset: -3px;
}

.doc-checklist__slot {
  display: flex;
  align-items: center;
  min-width: 0;
}

.doc-checklist__slot--end {
  justify-content: flex-end;
}

/* A check's outcome in words (HEA-444). It takes the three slots a document
   row uses for its controls and sits against the button, so the full
   "geregistreerd · gecontroleerd op <datum>" reads rather than being cut off
   in a single slot. Muted like a document's file name: both say what the row
   has on file, not what to do next. */
.doc-checklist__status {
  grid-column: span 3;
  justify-content: flex-end;
  font-size: 0.8125rem;
  color: var(--color-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Row-form errors sit under the whole row, not squeezed into the actions
   column they came from -- same full-width-under-the-grid pattern as
   .dossier-grid__history. */
.doc-checklist__errors {
  grid-column: 1 / -1;
}


.doc-checklist__upload input[type="date"],
.doc-checklist__upload select {
  width: 100%;
  padding: 0.3rem 0.5rem;
}

.doc-checklist__file {
  gap: 0.4rem;
}

/* The file input itself is .sr-only (its native "Choose File / No file
   chosen" chrome is English and not in the mockup); this is the chosen
   name, in its own slot beside the group whose "+" opens the picker.
   Reused as-is (not doc-checklist-specific despite
   the name) by HEA-180's raamovereenkomst upload, inside .field__control-row
   rather than .doc-checklist__file -- both are flex containers, so the
   flex:1 here still does the same job. */
.doc-checklist__filename {
  flex: 1;
  min-width: 0;
  font-size: 0.8125rem;
  color: var(--color-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Generic form controls for the (still flat, .as_p-rendered) Company/Candidate forms. */
.page form p {
  margin: 0 0 1rem;
}

/* An error under a field's hint sits as close to it as under a control: no 1rem between the two
   lines that annotate one field. */
.page form .field p.field__help:has(+ .field__errors) {
  margin-bottom: 0;
}

input[type="text"],
input[type="email"],
input[type="number"],
input[type="date"],
input[type="time"],
input[type="password"],
select,
textarea {
  width: 100%;
  max-width: 28rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: 0.9rem;
  font-family: inherit;
  background: var(--color-field);
  color: var(--color-text);
  box-sizing: border-box;
}

/* A control with a validation error (Django sets aria-invalid="true") takes the error border and
   a soft ring of the same colour, in every form. No fill: a form that was never submitted
   should not shout. */
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"],
.segmented[aria-invalid="true"] {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 15%, transparent);
}

label {
  display: block;
  margin-bottom: 0.375rem;
  font-weight: 600;
}

/* A label in a table cell (a row per upload, HEA-470 step 1) sits on the row's middle like the
   control beside it, so it drops the gap a label above its control keeps. */
.data-table td > label {
  margin-bottom: 0;
}

/* A table of one upload per part (HEA-470 step 1): the part column keeps one width, so the file
   column starts at the same x whether the table has one row or three. */
.data-table--parts th:first-child,
.data-table--parts td:first-child {
  width: 18rem;
}

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--color-text);
  -webkit-box-shadow: 0 0 0 1000px var(--color-field) inset;
  box-shadow: 0 0 0 1000px var(--color-field) inset;
  transition: background-color 9999s ease-in-out 0s;
}

.error {
  color: var(--color-error);
}

:focus-visible {
  outline: 3px solid rgba(230, 83, 46, 0.35);
  outline-offset: 3px;
}

/* Single-action POST forms sitting inline in a table cell (resend / revoke). */
.inline-form {
  display: inline;
}

button.action-link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
}
