/* ============================================================
   Supplier portal, Keuringsinbox — world: the inspection sticker.
   Touches layer-2 and layer-3 tokens from brand/tokens.css only.
   ZERO hex values: every colour comes from config/theme.tokens.json.

   Mobile first, and that is not a slogan here. This screen is read on a phone
   in a workshop: one column, large touch targets (--target-min), nothing
   floating that disappears under a thumb. The wide variants sit at the bottom
   as scaling up, not as the starting point.

   NO @font-face HERE. Those already live in brand/tokens.css, which is
   generated from config/theme.tokens.json and served at /assets/tokens.css;
   the paths in it are relative (./fonts/…) and therefore resolve to
   /assets/fonts/… — exactly where src/routes/assets.ts puts them.

   Declaring them again here looked harmless and was not: two @font-face blocks
   for the same family with different paths, one of which 404s. The page then
   falls back to Arial with no error anywhere — only in the network console of a
   browser you happen to open. One source, and it is the generated one.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  /* A full-height column so the footer stays at the bottom instead of ending
     halfway down the screen with a grey band under it. On an empty offer list
     that is the difference between "there is nothing" and "something is broken". */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--surface-canvas);
  color: var(--text-body);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  /* Tabular figures: the balance must not shift when it contains a 1. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.005em;
  color: var(--text-strong);
}
h1 { font-size: var(--fs-2xl); line-height: var(--lh-snug); }
h2 { font-size: var(--fs-lg); line-height: var(--lh-snug); }
h3 { font-size: var(--fs-base); line-height: var(--lh-snug); }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }
main:focus { outline: none; }

:focus-visible {
  outline: var(--focus-ring-width) solid var(--ring);
  outline-offset: var(--focus-ring-offset);
}
.bar :focus-visible { outline-color: var(--ring-on-inverse); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 10;
  display: inline-flex; align-items: center; min-height: var(--target-min);
  padding: 0 var(--space-6);
  background: var(--color-action-on-inverse); color: var(--text-on-action-inverse);
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  text-decoration: none;
}
.skip:focus { left: var(--space-6); top: var(--space-6); }

.wrap {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-7) var(--space-6) var(--space-9);
}
main { flex: 1 0 auto; }

/* ------------------------------------------------------------- buttons */
.button {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--target-min); padding: 0 var(--space-7);
  border: var(--rule-strong) solid var(--color-action);
  border-radius: var(--btn-radius);
  background: var(--color-action); color: var(--text-on-action);
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-base);
  text-transform: uppercase; letter-spacing: 0.06em; text-decoration: none;
  cursor: pointer;
  transition: background var(--motion-state) var(--motion-ease),
              color var(--motion-state) var(--motion-ease);
}
.button:hover { background: transparent; color: var(--color-action); }
.button--wide { width: 100%; }
.button--bare {
  background: transparent; color: var(--text-on-inverse);
  border-color: var(--border-strong-inverse);
  font-size: var(--fs-2xs); padding: 0 var(--space-5);
  min-height: var(--target-min);
}
.button--bare:hover {
  background: var(--color-action-on-inverse); color: var(--text-on-action-inverse);
  border-color: var(--color-action-on-inverse);
}

/* ------------------------------------------------------------- the bar */
.bar {
  background: var(--surface-inverse-deep);
  color: var(--text-on-inverse);
  border-bottom: var(--die-width) solid var(--color-brand-accent);
}
.bar__row {
  max-width: var(--container-max); margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-4) var(--space-6);
  padding: var(--space-4) var(--space-6);
}
.bar__right { display: flex; align-items: center; gap: var(--space-5); }

.brand {
  display: inline-flex; align-items: center; gap: var(--space-5);
  text-decoration: none; min-height: var(--target-min);
}
.brand svg { display: block; width: 2rem; height: 2rem; }
.brand__word {
  display: grid;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-lg);
  text-transform: uppercase; letter-spacing: 0.04em; line-height: var(--lh-tight);
}
.brand__word small {
  font-size: var(--fs-2xs); letter-spacing: 0.12em;
  color: var(--text-muted-on-inverse); font-weight: 700;
}

.balance-chip {
  display: inline-flex; align-items: baseline; gap: var(--space-3);
  min-height: var(--target-min); padding: 0 var(--space-5);
  border: var(--rule-strong) solid var(--color-brand-accent);
  border-radius: var(--badge-radius);
  color: var(--color-action-on-inverse); text-decoration: none;
  align-self: center;
}
.balance-chip__number { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-lg); }
.balance-chip__label { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: 0.12em; }
.logout { margin: 0; }

/* Navigation scrolls sideways rather than folding out: a disclosure menu opens
   differently on every screen, and scrolling works with one thumb AND with a
   keyboard. */
.mainnav {
  max-width: var(--container-max); margin-inline: auto;
  display: flex; gap: var(--space-6);
  padding: 0 var(--space-6);
  overflow-x: auto; scrollbar-width: none;
}
.mainnav::-webkit-scrollbar { display: none; }
.mainnav a {
  display: inline-flex; align-items: center; min-height: var(--target-min);
  white-space: nowrap; text-decoration: none;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-sm);
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted-on-inverse);
  border-bottom: var(--die-width) solid transparent;
  transition: color var(--motion-state) var(--motion-ease);
}
.mainnav a:hover { color: var(--text-on-inverse); }
.mainnav a[aria-current="page"] {
  color: var(--text-on-inverse);
  border-bottom-color: var(--color-brand-accent);
}

/* ------------------------------------------------------------ notices */
.notice {
  border: var(--rule-strong) solid var(--border-die);
  border-left-width: var(--die-width);
  border-radius: var(--card-radius);
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-7);
  background: var(--surface-card);
}
.notice__text { font-weight: 500; color: var(--text-strong); }
.notice__link { font-weight: 700; }
.notice__details {
  margin-top: var(--space-4); display: grid; gap: var(--space-2);
  font-size: var(--fs-sm); color: var(--text-body);
}
/* Green, yellow, red — and yellow is the default tone, not red. A request that
   turned out to be sold out is news, not a failure; see flash.ts. */
.notice--success { background: var(--status-ok-wash); border-color: var(--status-ok-ink); }
.notice--notice  { background: var(--status-warn-wash); border-color: var(--status-warn-line); }
.notice--failure { background: var(--status-alert-wash); border-color: var(--status-alert-ink); }
.notice--failure .notice__text { color: var(--status-alert-ink); }

/* -------------------------------------------------------------- cards */
.intro { margin: var(--space-5) 0 var(--space-7); max-width: 62ch; color: var(--text-body); }
.crumb { margin-bottom: var(--space-6); font-size: var(--fs-sm); font-weight: 600; }

.cards { display: grid; gap: var(--space-6); }
.cards--single { max-width: var(--container-narrow); }

.card {
  background: var(--surface-card);
  border: var(--rule-width) solid var(--border-hairline);
  border-top: var(--die-width) solid var(--card-color, var(--border-die));
  border-radius: var(--card-radius);
  box-shadow: var(--elevation-applied);
  padding: var(--space-6);
  display: grid; gap: var(--space-5);
}
.card__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-3) var(--space-5); }
.card__head h2 a { text-decoration: none; }
.card__region {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--text-strong);
  background: var(--surface-tint); border: var(--rule-width) solid var(--border-strong);
  border-radius: var(--badge-radius); padding: 2px var(--space-4);
}
.card__time {
  display: flex; flex-wrap: wrap; gap: var(--space-3);
  font-size: var(--fs-sm); color: var(--text-muted);
}
.card__slots { font-size: var(--fs-sm); font-weight: 600; color: var(--text-body); }
.card__price { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--text-strong); }
.card__buy { margin: 0; }

.hint {
  display: inline-block;
  background: var(--surface-sticker); color: var(--text-on-sticker);
  border: var(--rule-width) solid var(--status-warn-line); border-radius: var(--badge-radius);
  padding: 1px var(--space-4);
  font-size: var(--fs-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
}

/* ------------------------------------------------- answers and contact */
.answers, .contact {
  display: grid; gap: var(--space-4);
  border-top: var(--rule-width) solid var(--border-hairline);
  padding-top: var(--space-5);
}
.contact {
  background: var(--surface-tint);
  border: var(--rule-width) solid var(--border-strong); border-radius: var(--input-radius);
  padding: var(--space-5);
}
.answer { display: grid; grid-template-columns: minmax(8rem, 40%) minmax(0, 1fr); gap: var(--space-5); }
.answer dt {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted);
}
.answer dd { margin: 0; font-size: var(--fs-sm); color: var(--text-strong); overflow-wrap: anywhere; }
.contact .answer dd { font-size: var(--fs-base); font-weight: 600; }

/* ------------------------------------------------------------ outcome */
.outcome {
  border-top: var(--rule-width) solid var(--border-hairline);
  padding-top: var(--space-5); display: grid; gap: var(--space-4);
}
.outcome__buttons { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.outcome__buttons form { margin: 0; }
/* Five buttons, each big enough for a thumb wearing a work glove. */
.outcome-button {
  min-height: var(--target-min); padding: 0 var(--space-5);
  background: var(--surface-card); color: var(--text-strong);
  border: var(--rule-strong) solid var(--border-strong); border-radius: var(--btn-radius);
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.06em; cursor: pointer;
  transition: background var(--motion-state) var(--motion-ease),
              border-color var(--motion-state) var(--motion-ease);
}
.outcome-button:hover { border-color: var(--color-action); background: var(--color-action-wash); }
.outcome-button--active {
  background: var(--surface-sticker); color: var(--text-on-sticker);
  border-color: var(--status-warn-line);
}

/* ------------------------------------------------------------ credit terug */
/* A filed claim, in whichever of its three states it is. ONE block for all
   three: a supplier who reported something has to find it in the same place
   whether it is still being read, granted or refused. The badge carries the
   state and the sentence under it carries the consequence, because "Afgewezen"
   on its own does not say that the credits stay debited. */
.claim {
  border-top: var(--rule-width) solid var(--border-hairline);
  padding-top: var(--space-5); display: grid; gap: var(--space-4); justify-items: start;
}
.claim__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-3) var(--space-5); }
.claim p { max-width: 62ch; }

/* -------------------------------------------------- balance and bundles */
.balance-card { gap: var(--space-4); }
.balance__big {
  font-family: var(--font-display); line-height: var(--lh-tight); color: var(--text-strong);
}
.balance__big strong { font-size: var(--fs-2xl); }
.balance__big span { font-size: var(--fs-lg); text-transform: uppercase; letter-spacing: 0.08em; }
.cards--bundles { margin-top: var(--space-6); }
.bundle__price { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--text-strong); }
.discount {
  display: inline-block; margin-left: var(--space-3);
  background: var(--status-ok-wash); color: var(--status-ok-ink);
  border-radius: var(--badge-radius); padding: 1px var(--space-4);
  font-size: var(--fs-2xs); font-weight: 700; text-transform: uppercase;
}

/* The table scrolls inside its own box. Without this it pushes the whole page
   wider than the screen on a phone, navigation included. */
.table-box {
  overflow-x: auto;
  border: var(--rule-width) solid var(--border-hairline); border-radius: var(--card-radius);
  background: var(--surface-card); margin-top: var(--space-6);
}
.ledger { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.ledger caption { caption-side: bottom; padding: var(--space-4) var(--space-5); text-align: left; }
.ledger th, .ledger td {
  padding: var(--space-4) var(--space-5); text-align: left;
  border-bottom: var(--rule-width) solid var(--border-hairline);
  min-height: var(--row-min-height); white-space: nowrap;
}
.ledger th {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted);
  border-bottom-color: var(--border-strong);
}
.ledger tbody tr:last-child td { border-bottom: none; }
.number { text-align: right; font-weight: 700; }
.credit { color: var(--status-ok-ink); }
.debit { color: var(--text-strong); }

/* --------------------------------------------------------------- status
   The WORD carries the meaning and the colour is the second layer
   (DESIGN.md §2). Every modifier below therefore only tints a badge that
   already says what it means; none of them is the only signal. Green and red
   appear here and only here, as approved and expired — never as a category. */
.status {
  display: inline-flex; align-items: center; white-space: nowrap;
  padding: 2px var(--space-4);
  border: var(--rule-width) solid var(--border-strong);
  border-radius: var(--badge-radius);
  background: var(--surface-tint); color: var(--text-strong);
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.08em;
}
/* `--approved`, `--filed` and `--rejected` are the three states of a "credit
   terug" claim and share their tint with the agenda states they rhyme with: a
   granted claim is settled the way a valid inspection is, a refused one is a
   dead end the way an expired one is, and a claim still being read is the
   sticker yellow of something that needs attention. Same tint, own name — a
   view reading `.status--valid` for a refund would be a rename away from
   meaning nothing. */
.status--valid,
.status--approved { background: var(--status-ok-wash); border-color: var(--status-ok-ink); color: var(--status-ok-ink); }
.status--due,
.status--filed   { background: var(--surface-sticker); border-color: var(--status-warn-line); color: var(--text-on-sticker); }
.status--expired,
.status--rejected { background: var(--status-alert-wash); border-color: var(--status-alert-ink); color: var(--status-alert-ink); }
.status--current { background: var(--surface-sticker); border-color: var(--status-warn-line); color: var(--text-on-sticker); }
.status--locked  { background: var(--surface-tint); border-color: var(--border-strong); color: var(--text-muted); }

/* --------------------------------------------------------- expiry agenda */
/* The date is the product, so it is set in the display face at reading size
   rather than tucked into the meta line the way a purchase timestamp is. */
.agenda__limit { margin-bottom: var(--space-7); }
.agenda__when { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-3) var(--space-5); }
.agenda__date {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-lg);
  color: var(--text-strong);
}
.agenda__converted {
  display: grid; gap: var(--space-3); justify-items: start;
  background: var(--status-warn-wash);
  border: var(--rule-width) solid var(--status-warn-line);
  border-radius: var(--input-radius);
  padding: var(--space-5);
  font-size: var(--fs-sm); color: var(--text-strong);
}
.agenda__converted a { font-weight: 700; }

/* A native disclosure, no script. The marker stays: it is the only thing that
   says this opens, and a summary styled into a heading without one is a heading
   people do not click. */
.reveal { border-top: var(--rule-width) solid var(--border-hairline); }
.reveal > summary {
  min-height: var(--target-min); padding: var(--space-4) 0;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-strong);
  cursor: pointer;
}
.reveal__archive {
  margin-top: var(--space-7); padding-top: var(--space-6);
  border-top: var(--rule-width) solid var(--border-hairline);
}
/* The add form is a section of its own rather than a row in a card. */
.reveal--add {
  margin-top: var(--space-9); padding: 0 var(--space-6) var(--space-7);
  background: var(--surface-card);
  border: var(--rule-width) solid var(--border-hairline);
  border-top: var(--die-width) solid var(--color-brand-accent);
  border-radius: var(--card-radius);
  box-shadow: var(--elevation-applied);
}
.reveal--add > summary { font-size: var(--fs-base); }
/* Closed, the block is a summary and nothing else. Without this it keeps the
   padding of its contents and reads as a card that failed to load. */
.reveal--add:not([open]) { padding-bottom: 0; }
/* One column, and no wider than a form is comfortable to read. A field stretched
   over twelve hundred pixels makes the eye travel from label to caret and back. */
.reveal .form { max-width: 34rem; }

/* ------------------------------------------------- features, locked or not */
/* A locked feature is the same block with a badge and one sentence. Hiding it
   means the supplier never learns it exists; a dead button means they learn it
   is broken. Neither is what "not in your plan" should look like. */
.features { display: grid; gap: var(--space-6); margin-top: var(--space-9); }
.feature {
  display: grid; gap: var(--space-4); justify-items: start;
  background: var(--surface-card);
  border: var(--rule-width) solid var(--border-hairline);
  border-top: var(--die-width) solid var(--color-brand-accent);
  border-radius: var(--card-radius);
  box-shadow: var(--elevation-applied);
  padding: var(--space-6);
}
.feature--locked {
  background: var(--surface-tint);
  border-top-color: var(--border-die);
  box-shadow: var(--elevation-resting);
}
.feature__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-3) var(--space-5); }
.feature p { max-width: 62ch; }
.feature .field__label { margin-top: var(--space-3); }

/* The calendar feed address: readable, selectable, and not a link. Clicking an
   .ics feed downloads one snapshot instead of subscribing, and the address is
   itself the secret. */
.feed-url {
  width: 100%; max-width: 44rem;
  min-height: var(--target-min); padding: 0 var(--space-5);
  font-family: var(--font-body); font-size: var(--fs-sm); color: var(--text-strong);
  background: var(--surface-tint);
  border: var(--rule-strong) solid var(--border-strong); border-radius: var(--input-radius);
}

/* --------------------------------------------- levels and the payment step */
.cards--plans { margin: var(--space-6) 0; }
.card--plan, .card--confirm { border-top-color: var(--color-brand-accent); }
/* The name of a level carries as much as its price: it is what the supplier will
   say on the phone. Same size, different voice. */
.card--plan h3 { font-size: var(--fs-lg); }
.plan__price {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-lg);
  color: var(--text-strong);
}
.plan__buys { display: grid; gap: var(--space-4); }
.plan__buys form { margin: 0; }
.card--confirm h1 { font-size: var(--fs-lg); }

/* A register list: separated by a rule, not by a bullet or a tick glyph. */
.rows { display: grid; max-width: 62ch; }
.rows li {
  padding: var(--space-4) 0;
  border-bottom: var(--rule-width) solid var(--border-hairline);
  font-size: var(--fs-sm); color: var(--text-strong);
}
.rows li:last-child { border-bottom: none; }
.rows--off li { color: var(--text-muted); }
.rows--plain li { font-size: var(--fs-base); color: var(--text-body); }

/* ---------------------------------------------------------------- forms */
.form { display: grid; gap: var(--space-6); margin-top: var(--space-7); }
.field { display: grid; gap: var(--space-3); }
.field__label {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted);
}
.field__optional { text-transform: none; letter-spacing: 0.02em; font-weight: 500; }
.field__hint { font-size: var(--fs-sm); color: var(--text-muted); max-width: 56ch; }
.field input, .field select {
  min-height: var(--target-min); padding: 0 var(--space-5);
  font-family: var(--font-body); font-size: var(--fs-base); color: var(--text-strong);
  background: var(--surface-card);
  border: var(--rule-strong) solid var(--border-strong); border-radius: var(--input-radius);
}
.field input:focus-visible, .field select:focus-visible { border-color: var(--color-action); }
/* The only multi-line input in this portal: the note on a "credit terug" claim.
   It opens at three lines and grows by hand — an auto-growing box needs script,
   and a box that scrolls internally hides what was already typed. */
.field textarea {
  min-height: calc(var(--target-min) * 2); padding: var(--space-4) var(--space-5);
  font-family: var(--font-body); font-size: var(--fs-base); color: var(--text-strong);
  background: var(--surface-card);
  border: var(--rule-strong) solid var(--border-strong); border-radius: var(--input-radius);
  resize: vertical;
}
.field textarea:focus-visible { border-color: var(--color-action); }

/* Field groups are separated by a rule carrying the group name, not by white
   space alone (DESIGN.md §5). */
.form fieldset { border: 0; margin: 0; padding: 0; display: grid; gap: var(--space-6); }
.form legend {
  width: 100%; padding: 0 0 var(--space-3);
  border-bottom: var(--rule-strong) solid var(--border-strong);
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-strong);
}

/* A rejected field. The word comes first and the colour second (DESIGN.md §2):
   the message sits under the input and is announced, the border only repeats
   what it already says. A red border on its own is a signal half the readers of
   this portal cannot use. */
.field__error {
  font-size: var(--fs-sm); font-weight: 600; color: var(--status-alert-ink);
}
.field--error > input, .field--error > select { border-color: var(--status-alert-ink); }

/* Checkbox groups: the two lists that decide which requests a supplier sees.
   A row per choice, each row at least a thumb high — this is filled in on a
   phone, in a workshop, and a 16px box between two others is a mis-tick that
   costs a whole niche. */
.choices { list-style: none; display: grid; gap: var(--space-2); }
.choice {
  display: flex; align-items: center; gap: var(--space-4);
  min-height: var(--target-min); padding: 0 var(--space-4);
  border: var(--rule-width) solid var(--border-hairline); border-radius: var(--input-radius);
  background: var(--surface-card);
}
.choice:focus-within { border-color: var(--color-action); }
.choice label { flex: 1; font-size: var(--fs-base); color: var(--text-strong); }
/* Overrides the text-input sizing above: a checkbox is not a field to type in,
   and the shared rule would give it 44px of height and 20px of padding. The
   radio is in the same selector rather than a copy of it — the two are the same
   control with different arity, and a second block is a second thing to forget
   when the sizing changes. */
.field .choice input[type="checkbox"],
.field .choice input[type="radio"] {
  flex: none; width: var(--space-6); height: var(--space-6);
  min-height: 0; padding: 0; accent-color: var(--color-action);
}
/* A reason to choose, not a box to tick: each option carries a line explaining
   what it covers, so the row grows past one thumb instead of truncating. The
   hint sits INSIDE the label, so tapping the explanation selects the option —
   on a phone that is where the thumb lands. */
.choice--reason { align-items: flex-start; padding: var(--space-4); }
.choice--reason label { display: grid; gap: var(--space-2); }
.choices__group { display: grid; gap: var(--space-2); }
.choices__groupname {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-2xs);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted);
}

/* The closed state: visibly off, still readable. A form that goes nowhere is
   switched off with the reason above it, never left live to answer with a 403. */
.field input:disabled, .field select:disabled {
  background: var(--surface-tint); color: var(--text-muted);
  border-color: var(--border-hairline);
}
.button:disabled { background: var(--surface-tint); color: var(--text-muted); border-color: var(--border-hairline); cursor: default; }
.button:disabled:hover { background: var(--surface-tint); color: var(--text-muted); }

.button--quiet {
  background: transparent; color: var(--text-body);
  border-color: var(--border-strong);
  font-size: var(--fs-2xs); padding: 0 var(--space-6);
}
.button--quiet:hover { background: var(--surface-tint); color: var(--text-strong); border-color: var(--color-action); }

/* ----------------------------------------------------- the bare shell */
.bare { background: var(--surface-inverse-deep); }
.bare__centre {
  min-height: 100dvh; display: grid; align-content: center; justify-items: center;
  gap: var(--space-6); padding: var(--space-7) var(--space-6);
}
.card--bare {
  width: 100%; max-width: var(--container-narrow);
  border-top-color: var(--color-brand-accent);
}
.card--bare .brand { color: var(--text-strong); }
.card--bare .brand__word small { color: var(--text-muted); }
.bare__foot {
  max-width: 44ch; text-align: center;
  font-size: var(--fs-sm); color: var(--text-muted-on-inverse);
}

/* ----------------------------------------------------------- empty state */
.empty {
  display: grid; gap: var(--space-6); justify-items: start;
  background: var(--surface-card);
  border: var(--rule-width) solid var(--border-hairline);
  border-top: var(--die-width) solid var(--border-die);
  border-radius: var(--card-radius);
  padding: var(--space-8) var(--space-6);
}
.empty p { max-width: 56ch; }

.fine { font-size: var(--fs-sm); color: var(--text-muted); }
.fine a { font-weight: 600; }

/* -------------------------------------------------------------- footer */
.foot {
  background: var(--surface-inverse); color: var(--text-muted-on-inverse);
  border-top: var(--rule-strong) solid var(--border-inverse);
  font-size: var(--fs-sm);
}
.foot .wrap { display: grid; gap: var(--space-3); padding-block: var(--space-7); }

/* --------------------------------------------------------- wider screens */
@media (min-width: 48rem) {
  .cards { grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr)); align-items: start; }
  .cards--single { grid-template-columns: minmax(0, 1fr); }
  .card { padding: var(--space-7); }
  .wrap { padding-inline: var(--space-7); }
  .bar__row, .mainnav { padding-inline: var(--space-7); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 1ms !important; }
}
