/* ============================================================================
   KitCheck Suite — Design System Foundation
   ----------------------------------------------------------------------------
   Extracted from the 2014 Kitcheck app + the Blazor spike and condensed into a
   single token sheet (see docs/Visual-Guidelines.md). This file is intended to
   become the app's REAL stylesheet — it replaces the throwaway inline styles in
   src/Kitcheck.Server/Components/Pages/History.razor once approved.

   Contents:
     1. Design tokens (CSS custom properties)
     2. Base / typography
     3. Hero band (.kc-hero)
     4. History section (.kc-section)
     5. Calendar grid + week tile (collapsed + expanded)
     6. Category card
     7. Check card (leaf)
     8. Status pills, icons, accessibility helpers
     9. Responsive rules
   ========================================================================== */

/* ============================================================================
   1. DESIGN TOKENS  —  single source of truth for colour, type, shape, motion
   ========================================================================== */
:root {
  /* --- Brand ------------------------------------------------------------- */
  --kc-blue:          #7AC0DA;   /* ThemeBlue — the Kitcheck blue */
  --kc-blue-light:    #A4D4E6;   /* hero gradient end */
  --kc-navy:          #324158;   /* banner / headings emphasis */
  --kc-hero-ink:      #3E5667;   /* body text inside hero band */
  --kc-ink:           #333333;   /* default body text */
  --kc-heading:       #000000;
  --kc-wordmark:      #C8C8C8;   /* "Kitcheck" wordmark grey */

  /* --- Page greys -------------------------------------------------------- */
  --kc-frame:         #E2E2E2;   /* page frame */
  --kc-surface:       #FFFFFF;   /* content card */
  --kc-surface-alt:   #EFEEEF;   /* content zone / section band */
  --kc-section-band:  #EFEFEF;   /* .history-section background in the spike */
  --kc-border-soft:   rgba(0,0,0,0.10);
  --kc-muted:         #666666;   /* empty-week text */
  --kc-subtle:        #444444;   /* tile subtitle */

  /* --- Status (pastel bg + dark text + REQUIRED icon/text) --------------- */
  --kc-status-ok:       #BBF7D0;   /* Godkänd     — Tailwind green-200 */
  --kc-status-missed:   #FEF9C3;   /* Ej utförd   — Tailwind yellow-100 */
  --kc-status-failed:   #FECACA;   /* Ej godkänd  — Tailwind red-200 */
  --kc-status-empty:    #E5E7EB;   /* no checks that week */
  --kc-status-unknown:  #E5E5E5;   /* replaces the spike's black .unknown bug */

  /* Pågående — a record that has been raised and not yet finished. Blue on purpose: it sits OUTSIDE the
     green/amber/red verdict scale because it is not a verdict, and a reader must not have to decide
     whether unfinished work is a little bad or quite bad. It is also the one hue nothing else on the
     calendar uses, so an open record is separable from the other three without reading the icon. */
  --kc-status-open:     #DBEAFE;   /* Pågående    — Tailwind blue-100 */

  /* Slightly darker sibling tones for borders/accents (same hue family) */
  --kc-status-ok-edge:      #86D3A3;
  --kc-status-missed-edge:  #E8DB8A;
  --kc-status-failed-edge:  #F0A0A0;
  --kc-status-open-edge:    #93C5FD;

  --kc-error-text:    #E80C4D;   /* validation text only — never a fill */

  /* --- Check-type pastels (legacy assignments; carried as recognition) --- */
  --kc-type-storage:      #DAC8C8;
  --kc-type-cleaning:     #B8E1D3;
  --kc-type-heating:      #D79C9D;
  --kc-type-heating-fish: #FFB398;
  --kc-type-reheat:       #B26859;
  --kc-type-cooling:      #C0DCE6;
  --kc-type-hothold:      #EFECD3;
  --kc-type-coldhold:     #B0C4DE;
  --kc-type-arrival:      #DFC7A8;
  --kc-type-pest:         #DFB36F;
  --kc-type-other:        #E5E5E5;

  /* --- Typography -------------------------------------------------------- */
  --kc-font-body: "Segoe UI", system-ui, Verdana, Helvetica, sans-serif;
  /* Wordmark uses the brand body font until a logo typeface is chosen with the logo work.
     (The legacy .site-title declared Rockwell but fell back to Consolas/monospace; not carried over.) */
  --kc-font-wordmark: var(--kc-font-body);

  /* --- Shape & motion ---------------------------------------------------- */
  --kc-radius-panel: 10px;      /* legacy house radius */
  --kc-radius-card:  0.5rem;    /* spike tile/card radius */
  --kc-radius-pill:  999px;
  --kc-shadow-card:  0 1px 3px rgba(0,0,0,0.10);
  --kc-shadow-lift:  0 4px 12px rgba(0,0,0,0.12);
  --kc-transition:   0.3s ease;
  --kc-touch-min:    44px;      /* WCAG touch target — raised from legacy 30px */

  /* --- Accent + status text pairs (promoted from ad-hoc literals) --------- */
  --kc-blue-deep:    #2E93BC;   /* active nav / selected borders — was only a var() fallback */
  --kc-ok-text:      #12693A;   /* on --kc-status-ok */
  --kc-warn-text:    #7A5B12;   /* on --kc-status-missed */
  --kc-fail-text:    #8F2020;   /* on --kc-status-failed */
  --kc-info-bg:      #DBEAFE;
  --kc-info-text:    #1E5A82;
  --kc-neutral-bg:   #E5E7EB;
  --kc-neutral-text: #444444;

  /* --- Product explorer -------------------------------------------------- */
  --kc-img-bg:       #FFFFFF;   /* packshot area — pure white like the photos */
  --kc-skeleton:     #ECECEC;   /* loading shimmer base */

  /* --- Blue frame (opt-in page frame, see "PAGE FRAME" below) ------------ */
  /* The gradient the Kitcheck blue fades through down the centre column, and the two inks that read on
     it. Text on the blue is never the body grey: it is either white (the title) or this deep teal. */
  --kc-blueframe-2:       #92CBE0;
  --kc-blueframe-3:       #BFE0EC;
  --kc-blueframe-4:       #D7ECF3;
  --kc-blueframe-ink:     #0F2F3F;
  --kc-blueframe-eyebrow: #1E4A5F;
  --kc-heading-ink:       #1C2A3A;   /* headings and names on the white cards set on the blue */
  --kc-gauge-full:        #57B47E;   /* the liquid gauge's "all done" green (KcLiquidGauge.razor.js) */

  /* --- Severity in dense rows (Produktkvalitet) -------------------------- */
  /* A row is tinted and left-edged by its WORST open problem; its problems are small square tags in the
     same two families. Deeper than the calendar's pastels on purpose: these sit in 13px rows, a hundred to
     a page, and the calendar tones washed out to near-white at that size. */
  --kc-stop-row:      #FDEEEE;
  --kc-stop-edge:     #D64545;
  --kc-stop-tag:      #F9C9C9;
  --kc-stop-tag-ink:  #6E1111;
  --kc-stop-tag-edge: #E59A9A;
  --kc-stop-num:      #9B1C1C;
  --kc-warn-row:      #FFFBEA;
  --kc-warn-edge:     #D9A400;
  --kc-warn-tag:      #FBEFB8;
  --kc-warn-tag-ink:  #5C4600;
  --kc-warn-tag-edge: #E5D27A;
  --kc-warn-num:      #6B5300;
  --kc-go-ink:        #1F7A45;   /* "Godkänn" and an all-clear on white */
}

/* ============================================================================
   2. BASE / TYPOGRAPHY
   ========================================================================== */
.kc-root {
  font-family: var(--kc-font-body);
  color: var(--kc-ink);
  background: var(--kc-surface);
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
}

.kc-root *,
.kc-root *::before,
.kc-root *::after { box-sizing: border-box; }

.kc-root h1, .kc-root h2, .kc-root h3, .kc-root h4 {
  color: var(--kc-heading);
  margin: 0;
  padding: 0;
  line-height: 1.2;
}

/* Content frame — fluid, mobile-first replacement for the 960px fixed float layout */
.kc-wrapper {
  width: 100%;
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 1rem;
}

/* Density follows the viewport, never the component (visual guidelines §12): a data surface declares
   itself wide and fills the screen; the touch-first check pages keep the narrow frame. Declared by the
   page rather than sniffed from its contents, so adding a surface is one class, not a selector edit. */
main.kc-wrapper:has(> .kc-page--wide) {
  max-width: 1400px;
}

/* ============================================================================
   3. HERO BAND  (.kc-hero)  — "Historik." + subtitle + intro paragraph
   Faithful to .featured: sky-blue gradient, white title + inline subtitle.
   ========================================================================== */
.kc-hero {
  background: var(--kc-blue);
  background-image: linear-gradient(90deg, var(--kc-blue) 0%, var(--kc-blue-light) 100%);
  color: var(--kc-hero-ink);
  padding: 20px 40px 30px;
}

.kc-hero__title { margin-bottom: 10px; }

/* Title + one-line explainer sit inline, the distinctive Kitcheck page pattern */
.kc-hero__title h1 {
  display: inline;
  font-size: 2rem;
  color: #fff;
}
.kc-hero__title h2 {
  display: inline;
  font-size: 1.2rem;
  font-weight: normal;
  margin-left: 0.5rem;
  color: #fff;
}
.kc-hero p {
  margin: 10px 0 0;
  font-size: 1.1rem;
  color: #fff;
}

/* ============================================================================
   4. HISTORY SECTION  (.kc-section)
   ========================================================================== */
.kc-main { padding: 30px 0 40px; }

.kc-section {
  margin-top: 40px;
  background: var(--kc-section-band);
  padding: 16px;
  border-radius: var(--kc-radius-panel);
  border-bottom: 1px solid #ccc;
}
.kc-section:first-child { margin-top: 0; }

.kc-section > h3 {
  font-size: 1.2rem;
  margin: 0 0 12px;
  color: var(--kc-navy);
}

.kc-section__hint {
  font-size: 0.9rem;
  color: var(--kc-muted);
  margin: 0 0 12px;
}

/* Placeholder for not-yet-built sections (Rapporterade klagomål) */
.kc-placeholder {
  padding: 24px;
  border: 1px dashed #c9c9c9;
  border-radius: var(--kc-radius-card);
  color: var(--kc-muted);
  font-style: italic;
  text-align: center;
  background: rgba(255,255,255,0.5);
}

/* ============================================================================
   5. CALENDAR GRID + WEEK TILE
   ========================================================================== */
.kc-calendar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 0.5rem;
}

/* --- Empty week: distinct grey, italic, non-interactive -------------------*/
.kc-week--empty {
  background: var(--kc-status-empty);
  aspect-ratio: 1 / 1;
  min-width: 104px;
  border-radius: var(--kc-radius-card);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-size: 0.85rem;
  text-align: center;
  color: var(--kc-muted);
  font-style: italic;
  pointer-events: none;
  user-select: none;
  padding: 0.5rem;
  border: 1px solid var(--kc-border-soft);
}
.kc-week--empty .kc-week__dash { font-size: 1.1rem; font-style: normal; line-height: 1; }

/* --- Week tile (button element for accessibility) -------------------------*/
.kc-week {
  border-radius: var(--kc-radius-card);
  border: 1px solid var(--kc-border-soft);
  transition: transform var(--kc-transition), box-shadow var(--kc-transition),
              background-color var(--kc-transition);
  box-sizing: border-box;
  font-family: inherit;
  color: var(--kc-ink);
  padding: 0;
}

/* Collapsed tile mode */
.kc-week--tile {
  aspect-ratio: 1 / 1;
  min-width: 104px;
  min-height: var(--kc-touch-min);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  cursor: pointer;
  overflow: hidden;
  padding: 0.5rem;
  text-align: center;
  width: 100%;
}
.kc-week--tile:hover { transform: translateY(-2px); box-shadow: var(--kc-shadow-lift); }
.kc-week--tile:focus-visible { outline: 3px solid var(--kc-navy); outline-offset: 2px; }

/* Expanded mode — spans the whole grid row, drill-down happens in place */
.kc-week--expanded {
  grid-column: 1 / -1;
  aspect-ratio: auto;
  display: block;
  padding: 1rem;
  cursor: default;
  box-shadow: var(--kc-shadow-lift);
}

/* Status fills (worst-status-wins is computed by the app/JS) */
.kc-week.is-ok      { background: var(--kc-status-ok); }
.kc-week.is-open    { background: var(--kc-status-open); }
.kc-week.is-missed  { background: var(--kc-status-missed); }
.kc-week.is-failed  { background: var(--kc-status-failed); }

.kc-week__num  { font-size: 1.2rem; font-weight: 700; line-height: 1.1; }
.kc-week__frac { font-size: 1rem; color: var(--kc-subtle); font-weight: 600; }

/* Expanded week header: clickable row that collapses the week */
.kc-week__header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: var(--kc-touch-min);
  background: transparent;
  border: 0;
  border-radius: var(--kc-radius-card);
  cursor: pointer;
  font-family: inherit;
  color: var(--kc-ink);
  text-align: left;
  padding: 0.25rem 0.25rem 0.75rem;
}
.kc-week__header:focus-visible { outline: 3px solid var(--kc-navy); outline-offset: 2px; }
.kc-week__header .kc-week__num  { font-size: 1.3rem; }
.kc-week__header .kc-caret { margin-left: auto; font-size: 1rem; }

/* Grid of category cards inside an expanded week */
.kc-catgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1rem;
}

/* ============================================================================
   6. CATEGORY CARD  — one check-type (or equipment group) within a week
   ========================================================================== */
.kc-cat {
  min-width: 190px;
  border-radius: var(--kc-radius-card);
  border: 1px solid var(--kc-border-soft);
  padding: 1rem;
  box-sizing: border-box;
  cursor: pointer;
  transition: box-shadow var(--kc-transition), transform var(--kc-transition);
  font-family: inherit;
  color: var(--kc-ink);
  text-align: left;
  width: 100%;
  display: block;
}
.kc-cat:hover { box-shadow: var(--kc-shadow-card); }
.kc-cat:focus-visible { outline: 3px solid var(--kc-navy); outline-offset: 2px; }

.kc-cat.is-ok      { background: var(--kc-status-ok); }
.kc-cat.is-open    { background: var(--kc-status-open); }
.kc-cat.is-missed  { background: var(--kc-status-missed); }
.kc-cat.is-failed  { background: var(--kc-status-failed); }

/* Collapsed: square summary */
.kc-cat--tile {
  aspect-ratio: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.4rem;
  min-height: var(--kc-touch-min);
}
.kc-cat__name   { font-weight: 700; font-size: 1.05rem; }
.kc-cat__frac   { font-size: 1.4rem; font-weight: 600; }

/* Expanded category: header row + list of check cards */
.kc-cat--open { aspect-ratio: auto; cursor: default; }
.kc-cat__header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1.05rem;
  min-height: var(--kc-touch-min);
  margin-bottom: 0.5rem;
}
.kc-cat__header .kc-caret { margin-left: auto; }

/* ============================================================================
   7. CHECK CARD (leaf)  — one individual check, coloured by its own result
   ========================================================================== */
.kc-check {
  border-radius: var(--kc-radius-card);
  box-shadow: var(--kc-shadow-card);
  margin-bottom: 0.5rem;
  padding: 0.5rem 1rem;
  background: #fff;
  transition: background-color var(--kc-transition);
}
.kc-check.is-ok      { background: var(--kc-status-ok); }
.kc-check.is-open    { background: var(--kc-status-open); }
.kc-check.is-missed  { background: var(--kc-status-missed); }
.kc-check.is-failed  { background: var(--kc-status-failed); }
.kc-check.is-unknown { background: var(--kc-status-unknown); }

.kc-check__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  font-size: 0.875rem;
  padding: 0.25rem 0;
}
.kc-check__grid > div {
  flex: 1 1 130px;
  min-width: 110px;
  max-width: 220px;
}
.kc-check__grid strong { color: var(--kc-navy); font-weight: 600; }

/* ---------------------------------------------------------------------------
   DENSE GRID — the programme as a spreadsheet, not a page of headings.
   The unit is a COLUMN, so two kitchens can be compared by reading down. Every
   row carries its control type's colour (--tc, the same one that type wears on
   the day board) as a left edge plus a tint, so the programme is scannable by
   shape rather than by reading each line.
   --------------------------------------------------------------------------- */
.kc-grid {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.8125rem;
  line-height: 1.3;
  background: #fff;
  border: 1px solid var(--kc-line, #e5e7eb);
  border-radius: 0.5rem;
  overflow: hidden;
}
.kc-grid thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--kc-navy, #1f3a5f);
  color: #fff;
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  text-align: left;
  padding: 0.375rem 0.5rem;
  white-space: nowrap;
}
.kc-grid td {
  padding: 0.25rem 0.5rem;
  border-top: 1px solid var(--kc-line, #e5e7eb);
  vertical-align: middle;
}
/* The type colour: a solid edge (survives greyscale and colour blindness as a
   position cue) plus a wash strong enough to read as a colour rather than a
   smudge. The palette is pastel, so it takes a high mix to register — text
   stays near-black against all of them. */
.kc-grid__row td:first-child { box-shadow: inset 5px 0 0 0 var(--tc, #1f3a5f); }
.kc-grid__row td { background: color-mix(in srgb, var(--tc, #fff) 42%, #fff); }
.kc-grid__row:hover td { background: color-mix(in srgb, var(--tc, #fff) 62%, #fff); }
.kc-grid__row.is-off td { background: #f4f4f5; color: var(--kc-ink-muted, #6b7280); }
.kc-grid__row.is-off .kc-grid__name { text-decoration: line-through; }

/* Structure the reader can see without reading: a heavy double rule where the UNIT changes, a single
   rule where the control type changes within it. Grouping without headings, so the grid stays a grid. */
.kc-grid__row.is-unitbreak td { border-top: 4px double var(--kc-navy, #1f3a5f); }
.kc-grid__row.is-typebreak td { border-top: 1px solid var(--kc-navy, #1f3a5f); }

.kc-grid__unit { font-weight: 600; white-space: nowrap; }
.kc-grid__name { font-weight: 600; }
.kc-grid__num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.kc-grid__mid { text-align: center; width: 1%; }
.kc-grid__acts { width: 1%; white-space: nowrap; text-align: right; }
.kc-grid__acts .kc-btn { margin-left: 0.25rem; }

.kc-gridbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
}

/* ---- Unit setup dialog -------------------------------------------------------------------------
   Editing a kitchen opens a dialog, because its uppgifter, its equipment and its opening hours are
   three facts about ONE kitchen. Laid down the page they read as unrelated lists; inside a dialog
   titled with the kitchen's name, ownership is unmistakable. Wide, because it hosts a grid.
   Selectors carry .kc-modal too: the base pattern lives in kc-controls.css, which loads AFTER this
   sheet, so a single class would lose its 420px max-width at equal specificity. */
.kc-modal.kc-unitmodal {
  max-width: min(940px, 100%);
  max-height: 92vh;
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.kc-unitmodal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  /* The node's own kind colour, so the dialog is visibly about THIS kitchen. */
  background: color-mix(in srgb, var(--tc, #fff) 30%, #fff);
  border-bottom: 1px solid var(--kc-line, #e5e7eb);
}

.kc-unitmodal__eyebrow {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--kc-muted, #64748b);
}

.kc-unitmodal__title { margin: 0.1rem 0 0; font-size: 1.25rem; line-height: 1.2; }
.kc-unitmodal__sub { margin: 0.15rem 0 0; font-size: 0.8125rem; color: var(--kc-muted, #64748b); }

/* Header actions: the entry-wide toggle beside the close button. */
.kc-unitmodal__acts { display: flex; align-items: center; gap: 0.5rem; flex: none; }

.kc-unitmodal__acts .kc-editcard__toggle { background: #fff; }

.kc-unitmodal__close {
  flex: none;
  border: 1px solid var(--kc-line, #e5e7eb);
  background: #fff;
  border-radius: 0.5rem;
  width: 2rem;
  height: 2rem;
  font: inherit;
  line-height: 1;
  cursor: pointer;
  color: var(--kc-muted, #64748b);
}

.kc-unitmodal__close:hover { color: var(--kc-ink); border-color: var(--kc-navy); }

.kc-unitmodal__body {
  overflow-y: auto;
  padding: 0.25rem 1.1rem 1rem;
  background: var(--kc-surface-alt, #f6f8fa);
}

.kc-unitmodal__foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.7rem 1.1rem;
  border-top: 1px solid var(--kc-line, #e5e7eb);
  background: #fff;
}

/* A titled block inside the dialog: Enhetens uppgifter, Utrustning, Verksamhetsschema. */
.kc-setupsect {
  border: 1px solid var(--kc-line, #e5e7eb);
  border-radius: 0.75rem;
  background: #fff;
  padding: 0.6rem 0.85rem 0.85rem;
  margin: 0.75rem 0 0;
  /* The register is a wide grid; it scrolls inside its own section rather than widening the dialog. */
  overflow-x: auto;
}

.kc-setupsect__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 0 0.5rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--kc-line, #e5e7eb);
}

.kc-setupsect__title {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--kc-muted, #64748b);
}

/* A table cell that is also the way in. Looks like the text it replaced until you approach it — a grid
   sprouting blue links reads as a page of navigation rather than as data. */
.kc-linkcell {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: inherit;
  cursor: pointer;
  text-align: left;
  border-bottom: 1px dashed color-mix(in srgb, currentColor 35%, transparent);
}

.kc-linkcell:hover { color: var(--kc-blue-deep); border-bottom-color: var(--kc-blue-deep); }

/* ---- One kitchen at a glance -------------------------------------------------------------------- */
.kc-uov { display: flex; flex-direction: column; gap: 0.75rem; }

.kc-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.5rem;
}

.kc-kpi {
  border: 1px solid var(--kc-line, #e5e7eb);
  border-radius: 0.6rem;
  background: #fff;
  padding: 0.55rem 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.kc-kpi__value { font-size: 1.5rem; font-weight: 800; line-height: 1.1; color: var(--kc-navy); font-variant-numeric: tabular-nums; }
.kc-kpi__label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--kc-muted); font-weight: 700; }
.kc-kpi__hint { font-size: 0.72rem; color: var(--kc-muted); }

/* A figure that should not exist and one that should be zero must not look the same. */
.kc-kpi.is-alarm { border-color: var(--kc-status-failed-edge); background: color-mix(in srgb, var(--kc-status-failed) 30%, #fff); }
.kc-kpi.is-alarm .kc-kpi__value { color: var(--kc-fail-text); }

.kc-uov__cal { background: #fff; border: 1px solid var(--kc-line, #e5e7eb); border-radius: 0.6rem; padding: 0.6rem; }

/* ---- Stepped form (the equipment editor) --------------------------------------------------------
   Three decisions — what it is, how often, and what that adds up to — each in its own numbered panel.
   Flat, they read as one long list of fields and the schedule gets skipped. */
.kc-step {
  border: 1px solid var(--kc-line, #e5e7eb);
  border-radius: 0.6rem;
  background: #fff;
  padding: 0.6rem 0.8rem 0.8rem;
  margin: 0.6rem 0 0;
}

.kc-step__head { display: flex; align-items: flex-start; gap: 0.6rem; margin-bottom: 0.5rem; }

.kc-step__n {
  flex: none;
  width: 1.5rem; height: 1.5rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--kc-blue);
  color: #08313f;
  font-size: 0.8125rem; font-weight: 800;
}

.kc-step__title { display: block; font-size: 0.95rem; color: var(--kc-navy); }
.kc-step__hint { display: block; font-size: 0.78rem; color: var(--kc-muted); }

/* The figure the chosen type brings with it — the answer to "what is okay here?", stated before the
   override fields rather than hidden behind them. */
.kc-step__band {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.5rem;
  margin-top: 0.5rem; padding: 0.4rem 0.6rem;
  border-radius: 0.4rem;
  background: color-mix(in srgb, var(--kc-blue) 16%, #fff);
  border: 1px solid color-mix(in srgb, var(--kc-blue) 45%, #fff);
}

.kc-step__bandval { font-weight: 700; color: var(--kc-navy); font-variant-numeric: tabular-nums; }

/* The editor's own header: title left, the entry-wide Aktiv switch right. It belongs to the whole entry,
   not to any one step, which is why it is not inside one. */
.kc-editcard__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

/* Tight: a switch, not a card. The house .kc-check is a full-width row on the check board, which is far
   too much furniture for a two-word toggle in a header. */
.kc-editcard__toggle {
  margin: 0;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.5rem;
  border-radius: 0.4rem;
  box-shadow: none;
  border: 1px solid var(--kc-line, #e5e7eb);
  font-size: 0.85rem;
}

/* The band and the instruction, side by side — the two things that decide what the card says and how it
   is judged. Stacked, they pushed the schedule below the fold. */
.kc-step__split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  align-items: start;
  margin-top: 0.5rem;
}

.kc-step__col { min-width: 0; }
.kc-step__col > .kc-step__band { margin-top: 0; }

@media (max-width: 820px) {
  .kc-step__split { grid-template-columns: 1fr; }
}

/* The instruction the card will carry — the standard text until someone replaces it. */
.kc-tplinstr__text {
  margin: 0.2rem 0 0.4rem;
  padding: 0.5rem 0.7rem;
  border-left: 3px solid var(--kc-border-soft);
  background: var(--kc-surface-alt, #f6f8fa);
  border-radius: 0 0.4rem 0.4rem 0;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--kc-ink);
}

.kc-tplinstr__edit { margin: 0.2rem 0 0.4rem; font-size: 0.85rem; line-height: 1.45; }

.kc-tplinstr__own {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.5rem;
  border-radius: 0.4rem;
  box-shadow: none;
  border: 1px solid var(--kc-line, #e5e7eb);
  font-size: 0.8125rem;
}

/* Why the proposed interval is what it is. Deliberately not styled as a warning: no rule states a
   frequency, so this is a reason to weigh, not an instruction to obey. */
.kc-basis {
  margin: 0 0 0.6rem;
  padding: 0.5rem 0.7rem;
  border-radius: 0.4rem;
  background: color-mix(in srgb, var(--kc-info-bg, #DBEAFE) 55%, #fff);
  border: 1px solid color-mix(in srgb, var(--kc-info-text, #1E5A82) 22%, #fff);
}

.kc-basis__tag {
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--kc-info-text, #1E5A82);
}

.kc-basis__why { margin: 0.25rem 0 0.3rem; font-size: 0.85rem; line-height: 1.45; color: var(--kc-ink); }

.kc-step__more { margin-top: 0.5rem; }
.kc-step__more > summary { cursor: pointer; font-size: 0.8125rem; color: var(--kc-muted); }
.kc-step__more > summary:hover { color: var(--kc-navy); }
.kc-step__more[open] > summary { margin-bottom: 0.4rem; }

.kc-cal__legend {
  display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap;
  margin: 0 0 0.4rem; font-size: 0.78rem; color: var(--kc-muted);
}

.kc-cal__legend .kc-cal__dot { margin-left: 0.5rem; }
.kc-cal__legend .kc-cal__dot:first-child { margin-left: 0; }

.kc-setupsect__aside {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.8125rem;
  color: var(--kc-muted, #64748b);
  white-space: nowrap;
}

@media (max-width: 640px) {
  .kc-modal.kc-unitmodal { max-height: 100dvh; border-radius: 0; }
  .kc-overlay:has(.kc-unitmodal) { padding: 0; }
}
.kc-gridbar__count { font-size: 0.8125rem; color: var(--kc-ink-muted, #6b7280); }

/* Destructive, admin-only, and it should look it — never adjacent to a save. */
.kc-danger-zone {
  border: 1px solid #f0c8c2;
  background: #fdf5f4;
  border-radius: 0.5rem;
  padding: 0.625rem 0.875rem;
  margin: 1rem 0 0;
}
.kc-danger-zone p { margin: 0.25rem 0 0.5rem; font-size: 0.8125rem; max-width: 52rem; }

/* The entry point to the guided setup, on the programme page. */
.kc-guidecard {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  border: 1px solid var(--kc-line, #e5e7eb);
  border-radius: 0.75rem;
  padding: 0.875rem 1rem;
  margin: 0 0 1rem;
}
.kc-guidecard p { margin: 0.25rem 0 0; max-width: 46rem; }
.kc-guidecard__acts { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* Where a recorded limit's authority came from — "lagkrav" reads differently from "vår kritiska gräns",
   and a historical record has to say which it was judged under. Secondary to the figure, never louder. */
.kc-hist__basis {
  color: var(--kc-ink-muted, #6b7280);
  font-size: 0.8125rem;
  white-space: nowrap;
}

/* Art. 19: unsafe food reached a guest and the control authority was informed. The most consequential
   single line the register can hold, so it does not read as one field among nine. */
.kc-hist__art19 {
  border-left: 3px solid var(--kc-status-failed-edge);
  padding-left: 0.5rem;
  font-weight: 600;
}

/* ============================================================================
   8. STATUS PILLS, ICONS, ACCESSIBILITY HELPERS
   Colour is NEVER the only signal — every status pairs an icon + text label.
   ========================================================================== */
.kc-status {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0.6rem;
  border-radius: var(--kc-radius-pill);
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
  border: 1px solid transparent;
}
.kc-status.is-ok     { background: var(--kc-status-ok);     border-color: var(--kc-status-ok-edge); }
.kc-status.is-open   { background: var(--kc-status-open);   border-color: var(--kc-status-open-edge); }
.kc-status.is-missed { background: var(--kc-status-missed); border-color: var(--kc-status-missed-edge); }
.kc-status.is-failed { background: var(--kc-status-failed); border-color: var(--kc-status-failed-edge); }

/* Status icon — a shape/glyph channel independent of hue (color-blind safe).
   ✓ = Godkänd, ✗ = Ej godkänd, ! = Ej utförd, → = Pågående (the only glyph that points somewhere,
   because it is the only state still moving). */
.kc-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15em;
  height: 1.15em;
  border-radius: 50%;
  font-weight: 700;
  font-size: 0.85em;
  line-height: 1;
  flex: 0 0 auto;
}
.kc-icon.is-ok     { background: var(--kc-status-ok-edge);     color: #14532d; }
.kc-icon.is-open   { background: var(--kc-status-open-edge);   color: #1E3A8A; }
.kc-icon.is-missed { background: var(--kc-status-missed-edge); color: #713f12; }
.kc-icon.is-failed { background: var(--kc-status-failed-edge); color: #7f1d1d; }

/* Legend + colour-blind toggle bar (history-mockup.html) */
.kc-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  margin: 0 0 4px;
  padding: 0.5rem 0;
  font-size: 0.9rem;
}
.kc-cbtoggle { display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer; }
/* The journal's kitchen filter (CN-074). Sits in the toolbar beside the colour-blind toggle and wears the
   same weight: it narrows a view, it does not navigate anywhere. */
.kc-unitfilter {
  font: inherit;
  padding: 0.2rem 0.4rem;
  border: 1px solid #cbd0d6;
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
}
.kc-legend { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-left: auto; }
.kc-status--empty { background: var(--kc-status-empty); border-color: #cbd0d6; }

/* Colour-blind assist — a SECOND, hue-independent channel on top of the icons, so the pastels are
   separable without relying on hue at all: ok = solid edge, open = dotted, missed = dashed,
   failed = double. Four distinguishable outline styles is very nearly the whole vocabulary CSS has
   here, so "pågående" took the one that reads as provisional next to the solid edge of a settled
   record — which is exactly what an unfinished record is. */
.kc-cb .kc-week.is-ok, .kc-cb .kc-cat.is-ok, .kc-cb .kc-check.is-ok, .kc-cb .kc-status.is-ok {
  outline: 3px solid #1f7a3d;
  outline-offset: -3px;
}
.kc-cb .kc-week.is-open, .kc-cb .kc-cat.is-open, .kc-cb .kc-check.is-open, .kc-cb .kc-status.is-open {
  outline: 3px dotted #1D4ED8;
  outline-offset: -3px;
}
.kc-cb .kc-week.is-missed, .kc-cb .kc-cat.is-missed, .kc-cb .kc-check.is-missed, .kc-cb .kc-status.is-missed {
  outline: 3px dashed #9a7d10;
  outline-offset: -3px;
}
.kc-cb .kc-week.is-failed, .kc-cb .kc-cat.is-failed, .kc-cb .kc-check.is-failed, .kc-cb .kc-status.is-failed {
  outline: 3px double #a11;
  outline-offset: -3px;
}

/* Screen-reader-only utility */
.kc-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;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .kc-root *, .kc-root *::before, .kc-root *::after {
    transition: none !important;
    animation: none !important;
  }
  .kc-week--tile:hover { transform: none; }
  /* The reconnect dialog's VISIBILITY rides on its entrance animation (base opacity 0 + fill-mode
     both) — with animations killed it must still appear, or a dropped circuit dims and blocks the
     whole app behind an invisible modal. The spinner is pure keyframe geometry, so hide it instead
     of leaving collapsed dots. */
  #components-reconnect-modal[open] { opacity: 1 !important; }
  .components-rejoining-animation { display: none !important; }
}

/* ============================================================================
   9. RESPONSIVE
   ========================================================================== */
@media (max-width: 640px) {
  .kc-hero { padding: 14px 16px 20px; }
  .kc-hero__title h1 { font-size: 1.6rem; }
  .kc-hero__title h2 { display: block; margin-left: 0; font-size: 1rem; margin-top: 4px; }
  .kc-hero p { font-size: 1rem; }

  .kc-calendar { grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 0.4rem; }
  .kc-week--tile, .kc-week--empty { min-width: 84px; }
  .kc-week__num { font-size: 1rem; }
  .kc-week__frac { font-size: 0.85rem; }

  .kc-catgrid { grid-template-columns: 1fr; }
  .kc-cat--tile { aspect-ratio: auto; padding: 1rem; }

  .kc-check__grid > div { flex: 1 1 100%; max-width: none; }
}

/* ============================================================================
   10. APP SHELL ADDITIONS  (KitCheck Suite runtime — not part of the design
   draft in design/kitcheck-design.css). Component classes for the app chrome
   the Historik mockup did not cover: the top app bar, buttons, form fields,
   the Dagens-kontroller equipment cards, deviation cards and the journal/history
   table. Everything below is built from the section-1 tokens — no new colours.
   ========================================================================== */

/* Page frame — light-grey frame, brand 10px black top border (legacy detail). */
body.kc-root {
  margin: 0;
  min-height: 100vh;
  background: var(--kc-frame);
  border-top: 10px solid #000;
}

/* Centred content column below the app bar. */
.kc-content {
  padding: 1.5rem 1rem 3rem;
}

/* --- Top app bar ----------------------------------------------------------- */
/* Thin black line, then the Kitcheck-blue app bar with a circular badge, then a white nav row. */
.kc-topline { height: 5px; background: #0c0d10; }
.kc-appbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem clamp(0.7rem, 2.5vw, 1.4rem);
  padding-left: 152px;
  min-height: 70px;
  background: var(--kc-blue);
  color: var(--kc-navy);
  position: relative;
  overflow: visible;
  box-shadow: 0 2px 10px rgba(29, 52, 66, 0.16);
}
.kc-logo {
  position: absolute; left: 28px; top: 4px;
  width: 94px; height: 94px; border-radius: 50%;
  background: #fff; box-shadow: 0 5px 16px rgba(29, 52, 66, 0.30);
  display: grid; place-items: center; z-index: 30;
}
.kc-logo b {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 3.05rem; line-height: 1; font-weight: 800;
  color: var(--kc-navy); letter-spacing: -0.02em;
}
.kc-appbar__scope { font-weight: 750; font-size: 1.7rem; line-height: 1.1; color: var(--kc-navy); white-space: nowrap; }

/* The unit switcher (CN-074). Wears the scope name's own type so moving between kitchens reads as a
   change of place rather than as a form control parked in the header. Only rendered when somebody
   genuinely holds more than one node. */
.kc-appbar__scopesel {
  font: inherit;
  font-weight: 750;
  font-size: 1.7rem;
  line-height: 1.1;
  color: var(--kc-navy);
  background: rgba(255,255,255,0.42);
  border: 1px solid rgba(255,255,255,0.5);
  border-radius: 10px;
  padding: 0.1rem 2rem 0.1rem 0.5rem;
  max-width: 22ch;
  min-height: 44px;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%232f4658' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  background-size: 12px 8px;
}
.kc-appbar__scopesel:hover { background-color: rgba(255,255,255,0.62); }
.kc-appbar__scopesel:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: 2px; }
/* The indentation carries the tree, so the option text must not be collapsed. */
.kc-appbar__scopesel option { white-space: pre; font-size: 1rem; font-weight: 600; }
.kc-grow { flex: 1 1 auto; }
.kc-modesw { display: inline-flex; background: rgba(255,255,255,0.42); border: 1px solid rgba(255,255,255,0.5); border-radius: 999px; padding: 3px; gap: 2px; }
.kc-modesw button { border: 0; background: transparent; color: #2f4658; padding: 0.4rem 0.9rem; border-radius: 999px; font: inherit; font-weight: 650; min-height: 36px; cursor: pointer; }
.kc-modesw button.active { background: #fff; color: #22303f; box-shadow: 0 1px 4px rgba(29,52,66,0.2); }
.kc-appbar__user { display: flex; align-items: center; gap: 0.75rem; }
.kc-appbar__name { font-weight: 650; color: var(--kc-navy); white-space: nowrap; }

/* The bar never widens the page — the shell's rule, as for the menu below: never a sideways scroll. Its parts
   are as wide as the names in them: a select as its LONGEST option unless told otherwise, and the account tile
   as the person's name. Only the mode switch could give way, by stacking its labels, so on a tablet held up in
   portrait a slightly longer kitchen anywhere in the list pushed the tile past the screen and every page
   scrolled sideways (761px with a second kitchen called "Nytt E2E-kök": 10px). So:
     0. the switcher is as wide as the place it SHOWS (field-sizing), not the longest one in its list — a
        kitchen nobody is standing in neither widens the bar nor leaves blank space beside the one you are, and
        the person's name is never cut while the switcher has room to spare. Its box now ends just after the
        chevron, at every width;
   and when the bar still runs short, room is taken in order:
     1. the mode switch stacks its labels, as it always has — so wherever the bar fitted inside its padding
        before, it looks as it did (where the tile used to hang into the bar's right padding, 761-770px for
        "Kitcheck Admin", the name now loses its last letters to the ellipsis instead);
     2. then the person's name truncates, as it always could (.kc-acct__name), down to the avatar, which still
        says whose account it is — on a phone the name is hidden altogether;
     3. last of all the place's name is clipped at its end: where you stand is what the bar is for.
   Strictly one at a time, because a stacked label or an ellipsis shows for the smallest shortfall. Flex hands
   every shrinking item a share of the shortfall in proportion to its flex-shrink times its width, so the
   weights are far apart: while the switch is still giving, the name's share stays below what the layout can
   even represent (well under 1/64 px), and the place's share is a hair the clip never shows. A browser without
   field-sizing keeps the select at its longest option and skips step 0; steps 1-3 still hold the page.
   Held by NavRestructureTests with a kitchen name longer than the switcher's 22ch, from 1024px down to a phone
   — for the switcher, and for the plain name somebody who holds one kitchen sees. */
.kc-appbar__scopesel { field-sizing: content; }
/* The bar's own switch only: /avvikelse wears the same pill as its Ny/Pågående toggle, and must not inherit
   the bar's order of giving way. */
.kc-appbar .kc-modesw { flex-shrink: 10000; }
.kc-appbar__scope, .kc-appbar__scopesel { min-width: 0; flex-shrink: 0.001; }
.kc-appbar__scope { overflow-x: clip; }

.kc-navrow {
  display: flex; align-items: center; gap: 0.15rem;
  padding: 0 clamp(0.5rem, 2vw, 1.2rem) 0 152px;
  background: var(--kc-surface);
  border-bottom: 1px solid var(--kc-border-soft);
  /* The menu WRAPS to a second row when it doesn't fit (owner decision) — never a sideways scroll.
     Lives here in the shell (MainLayout), so every page gets it. */
  flex-wrap: wrap;
}

/* Impersonation banner — persistent, high-contrast warning while acting as someone else. */
.kc-impbar {
  display: flex; align-items: center; justify-content: space-between; gap: 0.8rem;
  padding: 0.55rem clamp(0.6rem, 2vw, 1.2rem);
  background: #7a2e00; color: #fff;
  font-weight: 600; font-size: 0.95rem;
}
.kc-impbar .kc-btn { background: rgba(255,255,255,0.14); color: #fff; border-color: rgba(255,255,255,0.6); }
.kc-impbar .kc-btn:hover { background: rgba(255,255,255,0.26); }
/* "Avsluta" is a form post (it must work before the circuit attaches); the form itself takes no room of its own. */
.kc-impbar__form { margin: 0; }
/* Sized so the Hantera menu of a Kitcheck administrator — ten entries, the longest set anybody has — fits
   ONE line at 1440px (owner, 2026-10-09; the agreed mockup sets it at 16px). Moving Gästkoder and
   Åtkomstlogg into Administration took two entries out; at the old 1.08rem with 0.85rem sides, and the active
   entry growing to 1.2rem, the remaining ten still broke onto a second row. Laptops down to 1280 get the
   two tighter steps below; narrower screens still wrap, which stays the rule — never a sideways scroll. */
.kc-nav__link {
  display: inline-flex; align-items: center;
  padding: 0.5rem 0.6rem;
  min-height: 46px;
  color: var(--kc-hero-ink);
  text-decoration: none;
  font-weight: 600; font-size: 1rem;
  border-bottom: 3px solid transparent;
  white-space: nowrap; line-height: 1.2;
}
.kc-nav__link:hover { color: var(--kc-navy); }
/* Words and bar in the brand's deep blue. On the white bar the words are 3.5:1, under WCAG's 4.5:1; the axe work
   (2026-10-11) gave them a darker blue, and the owner put the brand blue back (2026-10-12). A darker blue belongs to
   the high-contrast theme (docs/Accessibility-Inventory-2026-10-11.md); axe spares this element (Axe.RevertedByOwner). */
.kc-nav__link.active {
  color: var(--kc-blue-deep, #2E93BC);
  border-bottom-color: var(--kc-blue-deep, #2E93BC);
  font-size: 1.08rem; font-weight: 750;
}
.kc-nav__link:focus-visible { outline: 3px solid var(--kc-navy); outline-offset: 2px; }

/* Something waiting behind an entry — "Utbildning 2" (TR-71). Navy, not red: an assigned course is work to
   do, not a fault, and red already means "Ej godkänd" everywhere else. The number is the signal; the colour
   only makes it findable. */
.kc-nav__count {
  display: inline-grid; place-items: center;
  min-width: 1.25rem; height: 1.25rem; margin-left: 0.35rem; padding: 0 0.35rem;
  border-radius: 999px; background: var(--kc-navy); color: #fff;
  font-size: 0.72rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
}

/* The same ONE line on the laptops the product is actually used on, not only at the 1440 of the mockup: at
   1366 and 1280 the administrator's ten entries otherwise broke onto a second row, which is exactly what the
   owner asked to be rid of. Two steps, each a little tighter, and the row starts closer to the logo (it
   still clears it: the logo ends at 120px). Below 1280 the rule above still holds — the menu wraps, it never
   scrolls sideways — because squeezing the text further stops being readable before it stops wrapping. */
@media (max-width: 1439px) {
  .kc-navrow { padding-left: 136px; }
  .kc-nav__link { padding: 0.5rem 0.45rem; font-size: 0.95rem; }
  .kc-nav__link.active { font-size: 1rem; }
}

@media (max-width: 1365px) {
  .kc-nav__link { padding: 0.5rem 0.4rem; font-size: 0.9rem; }
  .kc-nav__link.active { font-size: 0.95rem; }
}

@media (max-width: 760px) {
  .kc-appbar { padding-left: 90px; min-height: 60px; }
  .kc-logo { width: 60px; height: 60px; left: 14px; top: 3px; }
  .kc-logo b { font-size: 2rem; }
  .kc-navrow { padding-left: 90px; }
  .kc-appbar__scope, .kc-appbar__scopesel { font-size: 1.3rem; }
  .kc-nav__link { font-size: 1rem; }
  .kc-nav__link.active { font-size: 1.1rem; }
}

.kc-appbar__break { display: none; }

/* Phones (owner layout): row 1 = scope … [user name over Logga ut] top-right; row 2 = the Utför/Hantera
   toggle right-aligned UNDER the user stack. Never widens the document. */
@media (max-width: 560px) {
  .kc-appbar { flex-wrap: wrap; row-gap: 0.3rem; padding-right: 0.6rem; padding-top: 0.35rem; padding-bottom: 0.45rem; }
  .kc-appbar__scope, .kc-appbar__scopesel { font-size: 1.1rem; order: 0; }
  .kc-grow { order: 1; }
  .kc-appbar__user { order: 2; flex-direction: column; align-items: flex-end; gap: 0.15rem; }
  .kc-appbar__name { display: inline; font-size: 0.78rem; max-width: 55vw; overflow: hidden; text-overflow: ellipsis; }
  .kc-appbar__user .kc-btn { padding: 0.3rem 0.7rem; min-height: 34px; font-size: 0.85rem; white-space: nowrap; }
  .kc-appbar__break { display: block; order: 3; flex-basis: 100%; height: 0; }
  .kc-modesw { order: 4; margin-left: auto; }
  .kc-modesw button { padding: 0.3rem 0.6rem; min-height: 32px; font-size: 0.85rem; }
  .kc-navrow { padding-left: 84px; }
}

/* --- Buttons --------------------------------------------------------------- */
.kc-btn {
  min-height: var(--kc-touch-min);
  padding: 0.7rem 1.2rem;
  font-size: 1rem;
  font-weight: 700;
  font-family: inherit;
  border: none;
  border-radius: var(--kc-radius-panel);
  background: var(--kc-blue);
  color: var(--kc-navy);
  cursor: pointer;
  transition: background-color var(--kc-transition);
}
.kc-btn:hover:not(:disabled) { background: var(--kc-blue-light); }
.kc-btn:focus-visible { outline: 3px solid var(--kc-navy); outline-offset: 2px; }
.kc-btn--block { width: 100%; }

/* A link wearing the button's clothes. There are two dozen of these and every one was wrong: an <a> is
   inline, so it ignored width and min-height, and it arrived underlined - a stray underlined word in a
   blue box rather than the page's one action. Fixed on the class, not on each page, because the next
   <a class="kc-btn"> somebody writes should be right without their having to know this. */
a.kc-btn {
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; box-sizing: border-box;
}
a.kc-btn--block { display: flex; }

/* A button that cannot be pressed must not look pressable. There was no rule for this at all, so every
   disabled button in the product rendered identical to a live one and simply did nothing when clicked —
   the worst of both worlds, since neither greying out nor hiding was actually happening. Kept as one rule
   on the base class so every variant inherits it. */
.kc-btn:disabled,
.kc-btn[aria-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
  filter: grayscale(1);
}

/* Ghost button — the distinctive Kitcheck transparent-with-fade-hover control. */
.kc-btn--ghost {
  background: transparent;
  border: 2px solid var(--kc-navy);
  color: var(--kc-navy);
  padding: 0.5rem 1rem;
}
.kc-btn--ghost:hover:not(:disabled) { background: rgba(255, 255, 255, 0.4); }

/* --- Form fields ----------------------------------------------------------- */
.kc-field { margin-bottom: 0.75rem; }
.kc-label { display: block; font-weight: 600; color: var(--kc-navy); margin-bottom: 0.25rem; }
.kc-input, .kc-select {
  width: 100%;
  min-height: var(--kc-touch-min);
  padding: 0.75rem;
  font-size: 1rem;
  font-family: inherit;
  color: var(--kc-ink);
  background: var(--kc-surface);
  border: 1px solid var(--kc-border-soft);
  border-radius: var(--kc-radius-panel);
  box-sizing: border-box;
}
.kc-input:focus-visible, .kc-select:focus-visible {
  outline: none;
  border-color: var(--kc-blue);
  box-shadow: 0 0 0 3px rgba(122, 192, 218, 0.4);
}
.kc-error { margin: 0.5rem 0 0; color: var(--kc-error-text); font-weight: 600; }

/* A result worth stating that is not a failure. Separate from .kc-error because "sparad som utkast"
   printed in the validation colour teaches people to stop believing the colour. */
.kc-notice { margin: 0.5rem 0 0; color: var(--kc-ok-text); font-weight: 600; }

/* What a pending programme change would cost, stated before the save rather than reported after it.
   The two variants differ in one thing only: whether the change is running yet. */
.kc-verdict {
  display: grid;
  gap: 0.15rem;
  margin: 0.75rem 0 0;
  padding: 0.6rem 0.75rem;
  border-left: 4px solid var(--kc-status-ok-edge);
  border-radius: 0 6px 6px 0;
  background: color-mix(in srgb, var(--kc-status-ok) 35%, white);
  color: var(--kc-ok-text);
  font-size: 0.95rem;
}

.kc-verdict--wait {
  border-left-color: var(--kc-status-missed-edge);
  background: color-mix(in srgb, var(--kc-status-missed) 35%, white);
  color: var(--kc-warn-text);
}

/* The sentence that keeps somebody from believing a parked change is in force. Never quiet. */
.kc-verdict__now { font-weight: 700; }

/* --- Login card ------------------------------------------------------------ */
/* --- Login screen ---------------------------------------------------------- */
.kc-loginpage {
  min-height: 100vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1rem; padding: 2rem 1rem;
  background: linear-gradient(160deg, var(--kc-blue) 0%, var(--kc-blue-light) 55%, var(--kc-frame) 55%);
}

/* The same card, inside the running application. No ground of its own and no filling of the viewport:
   the page it is on already has both, and a second full-height front door under the navigation bar reads
   as having been thrown out of the product. */
.kc-loginpage--inapp {
  min-height: 0;
  background: none;
  padding: 1.5rem 1rem;
  align-items: flex-start;
}
.kc-loginpage--inapp .kc-logincard {
  padding-top: 1.6rem;
  border: 1px solid var(--kc-border-soft);
  box-shadow: var(--kc-shadow-card);
}
.kc-logincard {
  width: 100%; max-width: 24rem;
  background: var(--kc-surface);
  border-radius: 18px;
  box-shadow: 0 12px 40px rgba(29, 52, 66, 0.22);
  padding: 2.4rem 1.8rem 1.9rem;
  text-align: center;
}
.kc-loginlogo {
  width: 82px; height: 82px; border-radius: 50%;
  background: #fff; border: 1px solid var(--kc-border-soft);
  box-shadow: 0 5px 16px rgba(29, 52, 66, 0.20);
  display: grid; place-items: center; margin: -3.6rem auto 0.8rem;
}
.kc-loginlogo b {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 2.6rem; line-height: 1; font-weight: 800;
  color: var(--kc-navy); letter-spacing: -0.02em;
}
.kc-login__title { color: var(--kc-navy); margin: 0 0 0.2rem; font-size: 1.6rem; }
.kc-login__lede { margin: 0 0 1.4rem; color: var(--kc-hero-ink); font-size: 0.95rem; }
.kc-loginform { text-align: left; }
.kc-loginform .kc-field { margin-bottom: 0.9rem; }
.kc-loginbtn { margin-top: 0.4rem; font-size: 1.05rem; }
.kc-loginhelp { margin: 0.9rem 0 0; font-size: 0.88rem; }
.kc-loginhelp a { color: var(--kc-blue-deep, #2E93BC); text-decoration: none; font-weight: 600; }
.kc-loginhelp a:hover { text-decoration: underline; }
.kc-loginfoot {
  font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--kc-navy); opacity: 0.7; margin: 0;
}

/* --- Incident forms (Avvikelse / Klagomål) --------------------------------- */
.kc-iform { max-width: 720px; }
.kc-fcard { background: var(--kc-surface); border: 1px solid var(--kc-border-soft); border-radius: var(--kc-radius-panel); box-shadow: var(--kc-shadow-card); padding: 1.1rem 1.2rem; margin-top: 1rem; }
.kc-fcard--later { background: var(--kc-surface-alt); border-style: dashed; }
.kc-sec-h { display: flex; align-items: center; gap: 0.55rem; margin: 0 0 0.15rem; }
.kc-sec-h h2 { font-size: 1.02rem; margin: 0; color: var(--kc-navy); }
.kc-sec-n { font-size: 0.72rem; font-weight: 800; color: #fff; background: var(--kc-blue-deep, #2E93BC); border-radius: 999px; min-width: 22px; height: 22px; display: inline-grid; place-items: center; padding: 0 0.3rem; }
.kc-fcard--later .kc-sec-n { background: var(--kc-muted); }
.kc-sec-hint { margin: 0.1rem 0 0.8rem; font-size: 0.84rem; color: var(--kc-muted); }
.kc-laterbadge { font-size: 0.66rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--kc-subtle); background: var(--kc-frame); border: 1px solid var(--kc-border-soft); border-radius: 999px; padding: 0.15rem 0.5rem; margin-left: auto; }

.kc-stepper { display: flex; flex-wrap: wrap; gap: 0.25rem; align-items: center; margin: 0.1rem 0 1rem; }
.kc-stepper .st { display: flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; font-weight: 650; color: var(--kc-muted); }
.kc-stepper .st .dot { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--kc-border-soft); display: grid; place-items: center; font-size: 0.7rem; font-weight: 800; background: var(--kc-surface); }
.kc-stepper .st.active { color: var(--kc-blue-deep, #2E93BC); }
.kc-stepper .st.active .dot { border-color: var(--kc-blue-deep, #2E93BC); background: var(--kc-blue); color: #08313f; }
.kc-stepper .sep { width: 16px; height: 2px; background: var(--kc-border-soft); flex: none; }

.kc-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.kc-chip { display: inline-flex; align-items: center; gap: 0.35rem; border: 1.5px solid var(--kc-border-soft); background: var(--kc-surface); color: var(--kc-subtle); border-radius: 999px; padding: 0.55rem 1.05rem; min-height: 46px; font-weight: 650; font-size: 0.95rem; cursor: pointer; }
.kc-chip:hover { border-color: var(--kc-blue-deep, #2E93BC); color: var(--kc-navy); }
.kc-chip[aria-pressed="true"] { background: var(--kc-blue); border-color: var(--kc-blue-deep, #2E93BC); color: #08313f; }
.kc-chip[aria-pressed="true"]::before { content: "✓"; font-weight: 900; font-size: 0.85em; }
.kc-chip--sev[aria-pressed="true"] { background: var(--kc-status-failed); border-color: var(--kc-status-failed-edge); color: #8F2020; }

/* Flat (passive, non-interactive) display chip — distinct from the interactive .kc-chip filter button.
   Used for allergen/diet/nature/certification readouts across the product surfaces. Tone classes pair a
   pastel fill with its dark text; an icon or wording must accompany the colour (never colour alone). */
.kc-fchips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.kc-fchip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.18rem 0.6rem; border-radius: var(--kc-radius-pill);
  font-size: 0.85rem; font-weight: 600; line-height: 1.35;
  background: var(--kc-neutral-bg); color: var(--kc-neutral-text);
  white-space: nowrap;
}
.kc-fchip--ok      { background: var(--kc-status-ok);     color: var(--kc-ok-text); }
.kc-fchip--warn    { background: var(--kc-status-missed); color: var(--kc-warn-text); }
.kc-fchip--fail    { background: var(--kc-status-failed); color: var(--kc-fail-text); }
.kc-fchip--info    { background: var(--kc-info-bg);       color: var(--kc-info-text); }
.kc-fchip--outline { background: var(--kc-surface); border: 1.5px dashed var(--kc-status-missed-edge); color: var(--kc-warn-text); }
.kc-fchip__sub { opacity: 0.75; font-weight: 500; font-size: 0.92em; }

.kc-escal { display: none; gap: 0.7rem; align-items: flex-start; background: var(--kc-status-failed); border: 1px solid var(--kc-status-failed-edge); color: #8F2020; border-radius: 12px; padding: 0.8rem 0.95rem; margin-top: 0.85rem; }
.kc-escal.is-on { display: flex; }
.kc-escal .ic { font-size: 1.15rem; flex: none; }
.kc-acts-lbl { font-size: 0.72rem; letter-spacing: 0.05em; text-transform: uppercase; font-weight: 700; opacity: 0.85; margin: 0.75rem 0 0.35rem; }
.kc-acts { display: flex; flex-direction: column; gap: 0.4rem; }
.kc-act { display: flex; align-items: center; gap: 0.65rem; width: 100%; text-align: left; background: var(--kc-surface); border: 1.5px solid var(--kc-status-failed-edge); border-radius: 10px; padding: 0.6rem 0.75rem; min-height: 48px; color: #8F2020; font-weight: 600; font-size: 0.92rem; cursor: pointer; }
.kc-act .cb { width: 22px; height: 22px; border-radius: 6px; border: 2px solid currentColor; display: grid; place-items: center; font-size: 0.82rem; color: transparent; flex: none; }
.kc-act[aria-pressed="true"] { background: var(--kc-status-ok); border-color: var(--kc-status-ok-edge); color: #12693A; }
.kc-act[aria-pressed="true"] .cb { background: var(--kc-status-ok-edge); border-color: var(--kc-status-ok-edge); color: #fff; }

.kc-allergyblock { display: none; gap: 0.7rem; align-items: flex-start; background: var(--kc-status-missed); border: 1px solid var(--kc-status-missed-edge); color: #7A5B12; border-radius: 12px; padding: 0.8rem 0.95rem; margin-top: 0.85rem; }
.kc-allergyblock.is-on { display: flex; }

.kc-fld2 { margin-bottom: 0.85rem; }
.kc-fld2 label, .kc-flabel { display: block; text-transform: uppercase; font-size: 0.7rem; letter-spacing: 0.05em; font-weight: 700; color: var(--kc-subtle); margin-bottom: 0.32rem; }
.kc-req { color: var(--kc-error-text); }
.kc-two { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; }
.kc-gdpr { display: flex; gap: 0.55rem; align-items: flex-start; background: var(--kc-surface-alt); border: 1px dashed var(--kc-border-soft); border-radius: 10px; padding: 0.65rem 0.8rem; margin-top: 0.5rem; font-size: 0.8rem; color: var(--kc-hero-ink); }
.kc-stamp { display: flex; align-items: center; gap: 0.5rem; color: var(--kc-muted); font-size: 0.84rem; margin-top: 1rem; padding-top: 0.75rem; border-top: 1px dashed var(--kc-border-soft); }
.kc-checks { display: flex; flex-direction: column; gap: 0.45rem; margin-top: 0.2rem; }
.kc-checks label { display: flex; align-items: center; gap: 0.6rem; font-size: 0.95rem; min-height: 42px; cursor: pointer; }
.kc-iactions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 1.1rem; }
.kc-fhint { display: block; margin-top: 0.35rem; font-size: 0.78rem; color: var(--kc-muted); }
@media (max-width: 520px) { .kc-two { grid-template-columns: 1fr; } }

/* --- Dagens kontroller — summary + equipment cards ------------------------- */
.kc-summary { color: var(--kc-hero-ink); font-size: 1.1rem; }
.kc-equipgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 1rem;
}
.kc-equip {
  padding: 1rem;
  background: var(--kc-surface);
  border: 1px solid var(--kc-border-soft);
  border-radius: var(--kc-radius-panel);
  box-shadow: var(--kc-shadow-card);
}
.kc-equip__head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.kc-equip__name { font-size: 1.1rem; color: var(--kc-navy); }
.kc-equip__limit { color: var(--kc-muted); }
.kc-equip__status { margin: 0.5rem 0; }
.kc-equip__muted { margin: 0.5rem 0; color: var(--kc-muted); }
.kc-today { margin: 0.4rem 0 1.2rem; }

/* Modules / entitlements upsell */
.kc-modgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); gap: 1rem; }
.kc-modcard { background: var(--kc-surface); border: 1px solid var(--kc-border-soft); border-radius: 14px; padding: 1rem 1.1rem; box-shadow: 0 1px 3px rgba(30,50,66,.06); }
.kc-modcard--off { background: var(--kc-surface-alt); border-style: dashed; }
.kc-modcard__head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.35rem; }
.kc-modcard__name { font-weight: 800; color: var(--kc-navy); font-size: 1.05rem; }
.kc-modcard__badge { font-size: 0.72rem; font-weight: 700; padding: 0.15rem 0.5rem; border-radius: 999px; background: var(--kc-status-empty); color: var(--kc-subtle); white-space: nowrap; }
.kc-modcard__badge--on { background: var(--kc-status-ok); color: #12693A; }
.kc-modcard__tag { margin: 0 0 0.8rem; font-size: 0.88rem; color: var(--kc-muted); }
.kc-lockcard { display: flex; align-items: center; gap: 0.7rem; background: var(--kc-surface-alt); border: 1px dashed var(--kc-border-soft); border-radius: 12px; padding: 0.9rem 1rem; }
.kc-lockcard__lock { font-size: 1.3rem; }
.kc-lockcard__name { font-weight: 700; color: var(--kc-navy); }
.kc-lockcard__msg { margin: 0.1rem 0 0; font-size: 0.85rem; color: var(--kc-muted); }
.kc-ent-loading { height: 3rem; }
.kc-quota { margin: 0 0 1rem; font-size: 0.9rem; color: var(--kc-subtle); background: var(--kc-surface-alt); border: 1px solid var(--kc-border-soft); border-radius: 10px; padding: 0.5rem 0.8rem; display: inline-block; }
.kc-quota strong { color: var(--kc-navy); }
.kc-audit__kind { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 999px; font-size: 0.78rem; font-weight: 700; white-space: nowrap; }
.kc-audit__kind.is-grant { background: var(--kc-status-ok); color: #12693A; }
.kc-audit__kind.is-revoke { background: var(--kc-status-failed); color: #8F2020; }
.kc-audit__kind.is-imp { background: #E3EEF3; color: #2E7A9B; }
/* The lockout override reads as a warning, not as another act-as line: it is the one row in this log
   that says a decision of the customer's was overruled. */
.kc-audit__kind.is-override { background: var(--kc-status-warn, #FBE8C8); color: #8A4B00; }
/* A vendor trainer was shown a kitchen's staff names (TR-41): somebody from outside READ, nothing changed —
   neutral, and distinct from the act-as blue so the two kinds of reach are told apart at a glance. */
.kc-audit__kind.is-read { background: #EFE8F6; color: #5B3E86; }
/* The object of the event, beside its badge — the role, on the one row type that has one (CN-084). It
   replaces a Roll COLUMN, which was blank for every act-as and support-access row; plain text rather than
   a second pill, so the badge stays the thing the eye scans down. */
.kc-audit__what { margin-left: 0.4rem; font-size: 0.86rem; color: var(--kc-subtle); }
.kc-equip__saved { margin: 0; font-size: 0.82rem; color: #12693A; font-weight: 600; }
.kc-equip__saved--idle { color: var(--kc-muted); font-weight: 500; }
.kc-equip__entry { display: flex; gap: 0.5rem; margin-top: 0.5rem; }
.kc-equip__entry .kc-input { flex: 1; min-width: 0; padding: 0.9rem; font-size: 1.2rem; }
.kc-equip__entry .kc-btn { white-space: nowrap; }

/* --- Deviation cards ------------------------------------------------------- */
.kc-devgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 1rem;
}
.kc-deviation {
  padding: 1rem;
  background: #fff7f7;
  border: 1px solid var(--kc-status-failed-edge);
  border-radius: var(--kc-radius-panel);
}
.kc-deviation__title { color: var(--kc-navy); }
.kc-deviation__meta { margin: 0.25rem 0; color: var(--kc-hero-ink); }
.kc-deviation .kc-label { margin-top: 0.25rem; }
.kc-deviation .kc-input, .kc-deviation .kc-select { margin-top: 0.25rem; }

/* --- Journal / history table ----------------------------------------------- */
.kc-table { width: 100%; border-collapse: collapse; }
.kc-table th {
  padding: 0.5rem 0.4rem;
  text-align: left;
  color: var(--kc-navy);
  border-bottom: 2px solid var(--kc-border-soft);
}
.kc-table td { padding: 0.5rem 0.4rem; border-top: 1px solid var(--kc-border-soft); }
/* An empty table's one row, there for a screen reader only ("Inget registrerat idag."): a cell with no padding and
   no border, its words visually hidden by .kc-sr-only, so the table looks exactly as it does with no rows — checked
   pixel by pixel (2026-10-12). Hiding the whole row instead (.kc-sr-only on the <tr>) takes it out of layout, but
   Chromium then paints the header's translucent bottom border twice, a shade darker. */
.kc-table td.kc-table__empty { padding: 0; border: 0; }

/* --- Misc utilities -------------------------------------------------------- */
.kc-h2 { margin-top: 2rem; color: var(--kc-navy); }
.kc-h3 { margin-top: 1.25rem; margin-bottom: 0.5rem; color: var(--kc-navy); font-size: 1.05rem; }
.kc-note { color: var(--kc-hero-ink); }

/* Week tile selected state for the Historik drill-down accordion. */
.kc-week.is-selected { outline: 3px solid var(--kc-navy); outline-offset: 2px; }

/* --- Program tree (read-only) ---------------------------------------------- */
.kc-prog-unit { margin-top: 1.5rem; }
.kc-prog-kind {
  margin: 1.4rem 0 0.4rem;
  color: var(--kc-navy);
  font-size: 1rem;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.kc-prog-count { color: var(--kc-hero-ink); font-size: 0.85rem; font-weight: 400; }
.kc-prog-unithead { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.kc-actcol { text-align: right; white-space: nowrap; }
.kc-actcol .kc-btn { margin-left: 0.4rem; }
.kc-confirm { color: var(--kc-navy); font-weight: 600; margin-right: 0.4rem; }
.kc-btn--sm { min-height: 2.2rem; padding: 0.3rem 0.7rem; font-size: 0.85rem; }

/* Grid-tight button. Defined AFTER .kc-btn deliberately: same specificity, so whichever comes last wins,
   and the base rule's touch-min height would otherwise make these BIGGER than the ones they replace.
   The touch target is knowingly traded away — this is a dense desktop grid, not the day board a worker
   uses with wet hands, and the equivalent actions stay full size everywhere a phone is the surface. */
.kc-btn--xs {
  min-height: 1.65rem;
  padding: 0.1rem 0.45rem;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.35;
  border-radius: 0.3rem;
}
.kc-btn--danger { background: var(--kc-status-fail, #FECACA); color: #8F2020; }
.kc-btn--danger:hover:not(:disabled) { background: #FBB4B4; }

/* Equipment edit card (program setup). */
.kc-editcard {
  background: var(--kc-surface, #fff);
  border: 2px solid var(--kc-navy);
  border-radius: var(--kc-radius-panel);
  padding: 1rem 1.2rem;
  margin: 1rem 0 1.5rem;
}
.kc-editgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.75rem 1rem;
}
.kc-editactions { margin-top: 1rem; display: flex; gap: 0.6rem; }
.kc-sched-heading { margin-top: 1rem; }

/* Schedule picklist editor (master-detail). */
.kc-sched { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-top: 0.4rem; }
@media (min-width: 720px) { .kc-sched { grid-template-columns: 14rem 1fr; align-items: start; } }
.kc-sched__list { border: 1px solid var(--kc-border-soft); border-radius: var(--kc-radius-panel); overflow: hidden; }
/* Section label, NOT an option. It previously sat on the same background with the same alignment as the
   rows beneath it, so it read as a selectable item that refused to respond. Now a tinted band with muted,
   smaller text: unmistakably a heading, at a glance and before anyone clicks it. */
.kc-sched__group {
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--kc-ink-muted, #6b7280);
  font-weight: 700;
  padding: 0.375rem 0.7rem;
  background: #eceff3;
  border-top: 1px solid var(--kc-border-soft);
  cursor: default;
}
.kc-sched__group:first-child { border-top: none; }
.kc-sched__item { display: block; width: 100%; text-align: left; border: none; border-top: 1px solid var(--kc-border-soft); background: transparent; color: var(--kc-navy); font: inherit; font-weight: 600; padding: 0.6rem 0.7rem; min-height: var(--kc-touch-min); cursor: pointer; }
.kc-sched__item:hover { background: rgba(255, 255, 255, 0.4); }
.kc-sched__item[aria-selected="true"] { background: var(--kc-blue); box-shadow: inset 3px 0 0 var(--kc-navy); }
.kc-sched__detail { border: 1px solid var(--kc-border-soft); border-radius: var(--kc-radius-panel); padding: 1rem; }
.kc-sched__desc { font-weight: 700; color: var(--kc-navy); margin: 0 0 0.8rem; }
.kc-days { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.6rem; }
.kc-day { min-width: 44px; min-height: 44px; border-radius: 0.6rem; border: 2px solid var(--kc-border-soft); background: transparent; color: var(--kc-navy); font: inherit; font-weight: 700; cursor: pointer; }
.kc-day--wide { min-width: 62px; }
.kc-day[aria-pressed="true"] { background: var(--kc-blue); border-color: var(--kc-navy); }
.kc-check { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--kc-navy); font-weight: 600; margin: 0.3rem 0; cursor: pointer; }
.kc-input--time { max-width: 8rem; }

/* Preview calendar (CN-032 §5) — the generator's dry-run. Month grid + click-a-day detail. */
.kc-cal { border: 1px solid var(--kc-border-soft); border-radius: var(--kc-radius-panel); overflow: hidden; margin-top: 0.6rem; background: var(--kc-surface); }
.kc-cal__bar { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.5rem 0.7rem; background: var(--kc-surface-alt); border-bottom: 1px solid var(--kc-border-soft); }
.kc-cal__month { font-weight: 700; color: var(--kc-navy); }
.kc-cal__nav { min-width: 40px; min-height: 40px; border-radius: 0.6rem; border: 1px solid var(--kc-border-soft); background: var(--kc-surface); color: var(--kc-navy); font-size: 1.2rem; font-weight: 700; cursor: pointer; }
.kc-cal__nav:hover { background: var(--kc-blue); }
.kc-cal__banner { margin: 0; padding: 0.5rem 0.7rem; background: var(--kc-status-missed); color: var(--kc-navy); font-weight: 600; font-size: 0.85rem; border-bottom: 1px solid var(--kc-border-soft); }
.kc-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; background: var(--kc-border-soft); padding: 1px; }
.kc-cal__head { text-align: center; font-size: 0.68rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--kc-hero-ink); font-weight: 700; padding: 0.35rem 0; background: var(--kc-surface); }
.kc-cal__cell { position: relative; min-height: 3rem; display: flex; flex-direction: column; align-items: flex-start; gap: 0.15rem; border: none; background: var(--kc-surface); color: var(--kc-navy); font: inherit; padding: 0.3rem 0.35rem; cursor: pointer; }
.kc-cal__cell:hover { background: var(--kc-surface-alt); }
.kc-cal__cell.is-out { color: var(--kc-subtle); background: color-mix(in srgb, var(--kc-surface) 60%, var(--kc-surface-alt)); }
.kc-cal__cell.is-closed { background: repeating-linear-gradient(135deg, transparent, transparent 5px, var(--kc-surface-alt) 5px, var(--kc-surface-alt) 6px); }
.kc-cal__cell.is-sel { box-shadow: inset 0 0 0 2px var(--kc-navy); }
.kc-cal__num { font-size: 0.8rem; font-weight: 600; }
.kc-cal__dots { display: flex; flex-wrap: wrap; gap: 2px; }
.kc-cal__dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
/* Green is what THIS configuration produces — the thing being decided. Everything the kitchen already does
   that day is the pale blue behind it, so a schedule is read against its neighbours instead of alone. */
.kc-cal__dot--due { background: #34A853; }
.kc-cal__dot--win { background: var(--kc-status-ok); }
.kc-cal__dot--duewin { background: #E8A33D; }
.kc-cal__dot--min { background: #8B7BD8; }
.kc-cal__dot--other { background: var(--kc-blue); }
.kc-cal__othern { font-size: 0.65rem; font-weight: 700; color: var(--kc-muted); line-height: 1; font-variant-numeric: tabular-nums; }
.kc-cal__item.is-other { color: var(--kc-muted); }
.kc-cal__detail { padding: 0.7rem; border-top: 1px solid var(--kc-border-soft); }
.kc-cal__detailhead { font-weight: 700; color: var(--kc-navy); text-transform: capitalize; margin-bottom: 0.4rem; }
.kc-cal__note { margin: 0; color: var(--kc-muted); }
.kc-cal__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.kc-cal__item { display: flex; align-items: center; gap: 0.5rem; color: var(--kc-navy); }
.kc-cal__dl { margin-left: auto; font-size: 0.8rem; color: var(--kc-muted); }
/* Facets as a JOINED button grid: the group is one bordered surface (the 1px gaps reveal the container
   background as shared hairlines), so the buttons read as a single tidy control, not scattered pills. */
.kc-explorer__facets {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 1px;
    padding: 1px;
    background: var(--kc-border-soft);
    border: 1px solid var(--kc-border-soft);
    border-radius: 8px;
    overflow: hidden;
    align-self: flex-start;
}

.kc-explorer__facetlabel {
    display: inline-flex;
    align-items: center;
    padding: 0 0.8rem;
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--kc-hero-ink);
    background: var(--kc-surface-alt);
    min-width: 5.4rem;
}

.kc-facet {
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0.35rem 0.8rem;
    min-height: 38px;
    border: none;
    border-radius: 0;
    background: var(--kc-surface);
    color: var(--kc-subtle);
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease;
}

.kc-facet:hover {
    background: #EAF4F9;
    color: var(--kc-navy);
}

.kc-facet:focus-visible {
    outline: 3px solid var(--kc-navy);
    outline-offset: -3px;
}

.kc-facet--on {
    background: var(--kc-blue);
    color: #08313f;
}

.kc-facet--on::before {
    content: "✓ ";
    font-weight: 800;
}

.kc-facet__count {
    opacity: 0.6;
    font-weight: 500;
    font-size: 0.9em;
}

/* ---------- Rich text editor (Quill snow theme integration) ----------
   The Quill stylesheet is vendored and loaded lazily by KcRichText; these rules snap the editor into
   the Kitcheck design language. Global because the Quill DOM is created at runtime (scoped css would
   not attribute it). */
.kc-richtext .ql-toolbar.ql-snow {
    border: 1px solid var(--kc-border-soft);
    border-radius: 8px 8px 0 0;
    background: var(--kc-surface-alt);
}

.kc-richtext .ql-container.ql-snow {
    border: 1px solid var(--kc-border-soft);
    border-top: none;
    border-radius: 0 0 8px 8px;
    background: var(--kc-surface);
    font-family: inherit;
    font-size: 0.95rem;
}

.kc-richtext .ql-editor {
    min-height: 6.5rem;
    line-height: 1.55;
}

.kc-richtext .ql-editor.ql-blank::before {
    color: var(--kc-muted);
    font-style: normal;
}
/* --- Production & purchasing ------------------------------------------------
   Shared by /produktion and /inkopslista: two readings of one plan, so they use one bar, one summary and
   one numeric column style. These live here rather than in a component's scoped sheet BECAUSE they are
   shared — Blazor confines scoped CSS to its own component, so a second page reusing the class names
   silently renders unstyled. */

.kc-prod__bar {
  display: flex;
  align-items: flex-end;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.kc-prod__pick {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--kc-muted);
}
.kc-prod__pick .kc-select { width: auto; min-width: 16rem; }
.kc-prod__daynav { display: flex; align-items: center; gap: 0.4rem; }
.kc-prod__date { min-width: 13rem; text-align: center; font-weight: 700; }

.kc-prod__summary {
  display: flex;
  align-items: baseline;
  gap: 2rem;
  flex-wrap: wrap;
  padding: 0.9rem 1.2rem;
  margin-bottom: 1rem;
  border-radius: var(--kc-radius-panel);
  background: var(--kc-surface-alt);
}
.kc-prod__stat { display: flex; align-items: baseline; gap: 0.4rem; }
.kc-prod__stat strong { font-size: 1.6rem; font-variant-numeric: tabular-nums; }
.kc-prod__stat span { font-size: 0.8rem; color: var(--kc-muted); }
.kc-prod__unit { margin-left: auto; font-size: 0.85rem; font-weight: 600; color: var(--kc-muted); }

/* Numbers are compared down the column, so they line up and share a width. */
.kc-prod__num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* "ca" against a pack size the supplier only approximated: a human looks before ordering against it. */
.kc-prod__approx {
  margin-left: 0.3rem;
  padding: 0 0.3rem;
  border-radius: 4px;
  background: var(--kc-status-missed);
  color: var(--kc-warn-text);
  font-size: 0.7rem;
  font-weight: 700;
}

/* --- Account tile ------------------------------------------------------------
   Who is signed in, by NAME, with logging out and personal settings inside it rather than as loose chrome
   on the bar. An email address is a login credential; it never belonged in the corner of every screen. */

.kc-acct { position: relative; }

.kc-acct__tile {
  display: flex;
  align-items: center;
  position: relative;
  gap: 0.55rem;
  padding: 0.25rem 0.5rem 0.25rem 0.25rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  font: inherit;
  color: inherit;
  max-width: 15rem;
}
.kc-acct__tile:hover { background: rgba(255, 255, 255, 0.55); border-color: var(--kc-border-soft); }
.kc-acct--open .kc-acct__tile { background: var(--kc-surface); border-color: var(--kc-border-soft); }

.kc-acct__avatar {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  border-radius: 50%;
  display: grid; place-items: center;
  overflow: hidden;
  background: var(--kc-navy);
  color: #fff;
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.02em;
}
.kc-acct__avatar img { width: 100%; height: 100%; object-fit: cover; }

/* The name is the point, so it gets the room; the subtitle is secondary and truncates first. A one-column grid
   whose column may close to nothing (minmax(0, max-content)), so the tile can narrow to the avatar when the bar
   runs short and the name truncates with its ellipsis — as a column of nowrap text it could not go below the
   name's full width, and the bar pushed past the screen instead. Each line fills the column, which is what lets
   its ellipsis engage; text-align keeps both lines starting at the left, as they did, rather than taking the
   button's centring now that the shorter line is as wide as the longer. */
.kc-acct__who { display: grid; grid-template-columns: minmax(0, max-content); min-width: 0; line-height: 1.15; text-align: start; }
.kc-acct__name {
  font-weight: 650; color: var(--kc-navy);
  max-width: 10rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The job title and the chevron sit on the bar's blue, where the body grey --kc-muted is 2.8:1 — under the 4.5:1
   small text needs and the 3:1 a symbol needs (axe, 2026-10-11, on a learner with a job title). They take the
   bar's own ink, as the name does: navy is 5.1:1 on the blue. Smaller and lighter in weight than the name, so
   they still read as second. */
.kc-acct__sub {
  font-size: 0.7rem; color: var(--kc-navy);
  max-width: 10rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kc-acct__chev { color: var(--kc-navy); font-size: 0.7rem; }

/* Full-viewport scrim: a menu you can only dismiss by choosing something is a trap. */
.kc-acct__scrim { position: fixed; inset: 0; z-index: 60; background: transparent; }

.kc-acct__menu {
  position: absolute; right: 0; top: calc(100% + 0.4rem); z-index: 61;
  min-width: 15rem;
  padding: 0.35rem;
  border: 1px solid var(--kc-border-soft);
  border-radius: var(--kc-radius-panel);
  background: var(--kc-surface);
  box-shadow: var(--kc-shadow-lift);
}
.kc-acct__head {
  display: flex; flex-direction: column; gap: 0.1rem;
  padding: 0.5rem 0.6rem 0.6rem;
  border-bottom: 1px solid var(--kc-border-soft);
  margin-bottom: 0.35rem;
}
.kc-acct__head span { font-size: 0.75rem; color: var(--kc-muted); word-break: break-all; }

.kc-acct__form { margin: 0; }
.kc-acct__item {
  display: block; width: 100%;
  padding: 0.55rem 0.6rem;
  border: none; border-radius: 8px;
  background: transparent;
  text-align: left; text-decoration: none;
  font: inherit; color: var(--kc-ink);
  cursor: pointer;
}
.kc-acct__item:hover { background: var(--kc-surface-alt); }
.kc-acct__item--danger { color: var(--kc-fail-text); font-weight: 600; }

/* Unread mail, on the CLOSED tile. The inbox link inside the menu is the route; this is the reason to
   open it — a count nobody sees until they already looked is not a notification. Survives the phone
   breakpoint below, where the name goes and the avatar stays. */
.kc-acct__unread {
  position: absolute; top: 0; left: 26px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 9px;
  display: grid; place-items: center;
  background: var(--kc-fail-text); color: #fff;
  font-size: 0.62rem; font-weight: 700; line-height: 1;
}

@media (max-width: 700px) {
  /* On a phone the name is the casualty, not the avatar: the picture still identifies the account. */
  .kc-acct__who { display: none; }
  .kc-acct__chev { display: none; }
}

/* --- Nav groups --------------------------------------------------------------
   One top-level entry standing for several pages that belong together. The bar had grown to fifteen flat
   links across two wrapped rows, which is the point at which a menu stops being navigable. */

.kc-navgroup { position: relative; display: inline-flex; }

/* Only what a <button> needs on top of .kc-nav__link, which it also wears. This rule comes later in the sheet
   at the same specificity, so whatever it sets wins: it used to set `font: inherit` and `border: none`, which
   undid the link's weight, size and line height (the entry rendered lighter and smaller than its neighbours)
   and its underline (an active group had no bar under it). A button does not inherit the font FAMILY by
   itself, so that one is said; the rest comes from .kc-nav__link. */
.kc-navgroup__button {
  gap: 0.35rem;
  border-width: 0 0 3px; border-style: solid; border-color: transparent;
  background: none; font-family: inherit; cursor: pointer;
}

/* A drawn chevron rather than "▾": at the size a menu arrow wants, the glyph rendered as a dot in Segoe UI. */
.kc-navgroup__chev {
  flex: 0 0 auto;
  width: 0.7em; height: 0.7em;
  opacity: 0.75;
  transition: transform 0.15s ease;
}
.kc-navgroup--open .kc-navgroup__chev { transform: rotate(180deg); }

.kc-navgroup__scrim { position: fixed; inset: 0; z-index: 60; background: transparent; }

.kc-navgroup__menu {
  position: absolute; left: 0; top: calc(100% + 0.15rem); z-index: 61;
  min-width: 13rem;
  padding: 0.35rem;
  border: 1px solid var(--kc-border-soft);
  border-radius: var(--kc-radius-panel);
  background: var(--kc-surface);
  box-shadow: var(--kc-shadow-lift);
  display: flex; flex-direction: column;
}

.kc-navgroup__item {
  padding: 0.5rem 0.6rem;
  border-radius: 8px;
  text-decoration: none;
  color: var(--kc-ink);
  white-space: nowrap;
}
.kc-navgroup__item:hover { background: var(--kc-surface-alt); }
.kc-navgroup__item.active { background: var(--kc-surface-alt); font-weight: 650; }

/* --- Programme references (KcProgramText) ------------------------------------
   The cross-references authors write inline in programme prose: to another section, to a control, to a
   regelverk paragraph. Global rather than scoped BECAUSE the same markup has to look the same where a
   component's scoped sheet cannot reach it — the printed programme and any preview built at runtime
   (the same reason as the Quill rules above).

   This is body prose, not a nav bar. The kinds differ by underline style and hue, never by a fill: a
   section where every third word lights up is a section nobody reads. Colour is never the only signal
   either — solid / dashed / dotted plus the § still separate them for a reader who cannot tell the
   hues apart.

   Markup:
     <span class="kc-ref-host">
       <a|span class="kc-ref kc-ref--section|--control|--regulation [--broken] [--external]">…</a>
       <span class="kc-refcard" role="tooltip">__title  __body  __out</span>
     </span>
   Inline elements throughout: this renders inside authored <p>, where a <div> would be re-parented out
   of the paragraph by the browser's own parser before Blazor ever saw it. */

.kc-ref-host {
  /* The card's containing block. Inline rather than inline-block, so a two-word label still breaks at
     the end of a line instead of shoving itself whole onto the next one. */
  position: relative;
}

/* Italic and a little heavier. A cross-reference is a citation, and italic is how a document has always
   marked one — it separates "avsnitt 3.2 Kylförvaring" from the sentence carrying it without the colour
   doing all the work, which matters on paper and to a reader who cannot see the colour at all. Weight
   stops at 600: full bold beside italic turns body prose into a page of shouting. */
.kc-ref {
  font-style: italic;
  font-weight: 600;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a.kc-ref { cursor: pointer; }

/* Not a link — nowhere to go, only something to explain. */
span.kc-ref { cursor: help; }

.kc-ref--section {
  color: var(--kc-blue-deep);
  text-decoration-style: solid;
  text-decoration-color: var(--kc-blue-deep);
}

.kc-ref--control {
  color: var(--kc-navy);
  text-decoration-style: dashed;
  text-decoration-color: var(--kc-navy);
}

.kc-ref--regulation {
  color: var(--kc-subtle);
  text-decoration-style: dotted;
  text-decoration-color: var(--kc-muted);
}

/* § is what a Swedish reader already scans a page for. The empty alt text keeps it out of the spoken
   announcement — the link's own words say which provision it is. */
.kc-ref--regulation::before {
  content: "§" / "";
  margin-right: 0.15em;
  color: var(--kc-muted);
}

/* Leaving the page is worth one glyph. Text decoration does not propagate into an atomic inline-level
   box, which is how the arrow keeps clear of the link's underline. */
.kc-ref--external::after {
  content: "↗" / "";
  display: inline-block;
  margin-left: 0.15em;
  font-size: 0.8em;
  color: var(--kc-muted);
}

.kc-ref:hover,
.kc-ref:focus-visible {
  color: var(--kc-navy);
  text-decoration-style: solid;
  text-decoration-thickness: 2px;
}

.kc-ref:focus-visible {
  outline: 3px solid var(--kc-navy);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Editor mode only. A key that resolves to nothing reaches a reader as ordinary words; it reaches the
   author who has to fix it as this. */
.kc-ref--broken,
.kc-ref--broken:hover {
  color: var(--kc-error-text);
  text-decoration-style: wavy;
  text-decoration-color: var(--kc-error-text);
  text-decoration-thickness: 1px;
}

.kc-refcard {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  transform: translateX(var(--kc-refcard-shift, 0px));   /* the module's nudge off a viewport edge */
  z-index: 40;
  width: max-content;
  max-width: min(24rem, calc(100vw - 2rem));
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--kc-line, var(--kc-border-soft));
  border-radius: var(--kc-radius-card);
  background: var(--kc-surface);
  box-shadow: var(--kc-shadow-lift);
  font-size: 0.85rem;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  color: var(--kc-ink);
  /* Hidden, not removed: it stays laid out, so the edge nudge can measure it before anything is
     painted, and aria-describedby still reads it to a screen reader that has no hover to give. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s ease;
}

/* Separate rules, not one selector list: an engine that does not know :has() would throw away the
   whole list and take hover down with it. */
@media (hover: hover) {
  .kc-ref-host:hover > .kc-refcard { opacity: 1; visibility: visible; pointer-events: auto; }
}

.kc-ref-host:has(> .kc-ref:focus-visible) > .kc-refcard { opacity: 1; visibility: visible; }

/* Held open by tap (KcProgramText.razor.js). */
.kc-ref-host.is-open > .kc-refcard { opacity: 1; visibility: visible; pointer-events: auto; }

.kc-refcard__title { display: block; font-weight: 650; color: var(--kc-navy); }
/* A control's card is three labelled lines the resolver joins with \n — frequency, limit, corrective
   action. Without pre-line they set as one paragraph and the reader has to find where the limit ends and
   the action begins. Its own declaration, so the card's white-space: normal cannot be inherited over it. */
.kc-refcard__body { display: block; margin-top: 0.2rem; color: var(--kc-subtle); white-space: pre-line; }
.kc-refcard__out  { display: block; margin-top: 0.35rem; font-size: 0.78rem; color: var(--kc-muted); }

@media (hover: none) {
  /* On a phone the first tap opens the card instead of following the link. Saying so is the difference
     between a deliberate gesture and a broken one, and only the stylesheet knows the device has no
     hover to offer. */
  .kc-ref-host:has(a.kc-ref) .kc-refcard::after {
    content: "Tryck igen för att öppna" / "";
    display: block;
    margin-top: 0.35rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--kc-blue-deep);
  }
}

@media (prefers-reduced-motion: reduce) {
  .kc-refcard { transition: none; }
}

@media print {
  /* An inspector reads words on paper. The cards go, and the references print as ink rather than as a
     colour that photocopies to grey mush. */
  .kc-ref-host .kc-refcard { display: none; }
  .kc-ref { color: var(--kc-ink); text-decoration-color: var(--kc-muted); }
}

/* ============================================================================
   OPS PAGES  (.kc-opssheet, .kc-info)
   The shared idioms of the internal ops views — /ops/jobs, /ops/product-mirror.
   Global rather than colocated because there are now two of them and a third
   would copy whichever it happened to be opened next to.
   ========================================================================== */

/* One white sheet under the whole page. The rest of the app puts small white cards on the grey frame,
   which suits a page of separate things; an ops page is ONE thing — a grid and the controls that act on
   it — and reading a wide table across bands of grey and white makes the columns look unrelated. */
.kc-opssheet {
  background: var(--kc-surface);
  border: 1px solid var(--kc-border-soft);
  border-radius: var(--kc-radius-card);
  box-shadow: var(--kc-shadow-card);
  padding: 1rem 1.1rem 1.25rem;
  margin-top: 1rem;
}

/* A grid on the sheet draws its own frame, which doubles up as a box inside a box. Let the navy header
   row and the tinted rows do the containing instead. */
.kc-opssheet .kc-grid { border: 0; border-radius: 0; }

/* What DABAS's own tree says about a brick, under the sample name in the to-map queue. Indented and quiet:
   it is the strongest hint a curator gets, but it is still the supplier's filing rather than our decision,
   and styling it as an answer would invite it to be clicked through unread. */
.kc-mirror__hint {
  margin-top: .35rem;
  padding-left: .6rem;
  border-left: 3px solid var(--kc-border-soft);
  font-size: .85rem;
}

.kc-mirror__hintlabel {
  display: block;
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--kc-ink-muted, #6b7280);
}

/* The supplier's preparation instruction on the product card. The method chip leads and the prose sits
   under it, because "Ätfärdig" changes what the programme asks of a cook and the instruction only matters
   once you know which method it belongs to. */
.kc-pdetail__prep { margin: .4rem 0 .6rem; }

.kc-pdetail__prepinstr {
  margin: .3rem 0 0;
  font-size: .88rem;
  line-height: 1.45;
  white-space: pre-line;   /* suppliers write real line breaks into these */
}

/* --- The "what this does and why" card ---------------------------------------------------------------
   Hover OR keyboard focus. A mouse-only tooltip carrying the only explanation of what a control will do
   is an explanation half the operators cannot reach — and the person deciding whether to start something
   irreversible at 02:00 needs it most. */
.kc-info { position: relative; display: inline-flex; }

.kc-info__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05rem;
  height: 1.05rem;
  border: 1px solid var(--kc-navy);
  border-radius: 50%;
  font-family: var(--kc-font-body);
  font-size: 0.7rem;
  font-weight: 700;
  font-style: italic;
  line-height: 1;
  color: var(--kc-navy);
  background: #fff;
  cursor: help;
}

.kc-info:hover .kc-info__mark,
.kc-info:focus-visible .kc-info__mark { background: var(--kc-blue); }
.kc-info:focus-visible { outline: none; }
.kc-info:focus-visible .kc-info__mark { outline: 2px solid var(--kc-navy); outline-offset: 2px; }

.kc-info__card {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  z-index: 40;
  display: none;
  flex-direction: column;
  gap: 0.35rem;
  width: min(30rem, 70vw);
  padding: 0.6rem 0.75rem;
  background: var(--kc-surface);
  border: 1px solid var(--kc-navy);
  border-radius: var(--kc-radius-card);
  box-shadow: var(--kc-shadow-lift);
  font-family: var(--kc-font-body);
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.45;
  color: var(--kc-ink);
  white-space: normal;
  text-align: left;
  cursor: default;
}

.kc-info:hover .kc-info__card,
.kc-info:focus-visible .kc-info__card,
.kc-info:focus-within .kc-info__card { display: flex; }

.kc-info__title { font-weight: 700; color: var(--kc-navy); }
.kc-info__row em { font-style: normal; font-weight: 600; color: var(--kc-navy); }

/* Opened from a control near the right edge, the card would hang off the page. */
.kc-info--right .kc-info__card { left: auto; right: 0; }

/* --- Ops dialog chrome (.kc-opsmodal) ---------------------------------------------------------------
   The header/body/footer an ops dialog wears: a bar naming what is being edited or shown, a scrolling
   body, and actions pinned where they stay reachable however long the content gets. Global because the
   job editor and the product card both use it — they were the same markup with one page's scoped styles,
   which is why the second one rendered with its close button dropped onto its own line. */

.kc-opsmodal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  border-bottom: 1px solid var(--kc-border-soft);
  background: var(--kc-surface-alt);
}

.kc-opsmodal__eyebrow {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--kc-muted);
}

.kc-opsmodal__title { margin: 0.15rem 0 0.1rem; font-size: 1.15rem; color: var(--kc-navy); }

/* The identifier in monospace, so the dialog and the row it was opened from are visibly the same record. */
.kc-opsmodal__sub {
  margin: 0;
  font-family: var(--kc-font-mono, ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace);
  font-size: 0.78rem;
  color: var(--kc-muted);
}

.kc-opsmodal__close {
  border: 0;
  background: none;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.3rem 0.4rem;
  color: var(--kc-muted);
  cursor: pointer;
  border-radius: 0.35rem;
}

.kc-opsmodal__close:hover { background: var(--kc-surface); color: var(--kc-ink); }

.kc-opsmodal__body {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: 1rem 1.1rem;
  overflow-y: auto;
}

.kc-opsmodal__body .kc-field { display: flex; flex-direction: column; gap: 0.25rem; }

.kc-opsmodal__check {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.85rem;
  line-height: 1.4;
}

.kc-opsmodal__foot {
  display: flex;
  gap: 0.6rem;
  padding: 0.8rem 1.1rem;
  border-top: 1px solid var(--kc-border-soft);
  background: var(--kc-surface-alt);
}

/* --- Rengöringsområden (the cleaning register) ------------------------------
   Proposed from the equipment register and the guide's answers, confirmed one line at a time. Reads as a
   list of decisions rather than a form: most lines need one click, and the only typed value is a frequency
   the kitchen has to be able to justify. */
.kc-arealist {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
  border-top: 1px solid var(--kc-line);
}

.kc-area {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.45rem 0.2rem;
  border-bottom: 1px solid var(--kc-line);
}

.kc-area__id { flex: 1 1 16rem; display: flex; flex-direction: column; }

.kc-area__name { font-size: 0.9rem; }

/* A proposal is a question, so it does not carry the weight of a decision already made. */
.kc-area--suggested { background: var(--kc-zebra, #fafafa); }

/* Refused, and kept refused — visible so it can be taken back, quiet so it is not in the way. */
.kc-area--rejected { opacity: 0.55; }

.kc-area__tag {
  padding: 0 0.4rem;
  border-radius: 1rem;
  background: var(--kc-line);
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.kc-area__rhythm { max-width: 11rem; }

.kc-area__add { margin-top: 0.8rem; font-size: 0.85rem; }
.kc-area__add > summary { cursor: pointer; }

/* ============================================================================
   PAGE FRAME — the Kitcheck-blue centre column  (.kc-blueframe, opt-in)
   ----------------------------------------------------------------------------
   The page's own column wears the Kitcheck blue, top to bottom, fading as it goes down; the title sits on
   the blue and the content sits on it as white cards. The grey frame shows only at the sides. Opt-in by
   ONE class on the page's root element — the shell never guesses — so a page adopts it without touching
   the layout, and every other page is left exactly as it was until the owner has seen it on a mockup.

   WIDTH-NEUTRAL: the frame colours the column a page already has and does not widen it. It was born on
   Produktkvalitet at 1300px, and that width was the page's — a dense data surface — not the frame's: the
   day board, a touch page used on phones in kitchens, wears it at the ordinary 1040px (owner, 2026-10-09).
   A page that wants the wide column says so with .kc-blueframe--wide; Produktkvalitet and Platform
   Administration (hub, installation, settings) do, and so keep exactly the width they had.

   Spanning the page height is the point, so the body becomes a column and the main grows into whatever
   the viewport leaves below the app bar. Scoped by :has() to the pages that carry the class, so no other
   page's body changes display at all.
   ========================================================================== */
body.kc-root:has(> main > .kc-blueframe) {
  display: flex;
  flex-direction: column;
}

main.kc-wrapper:has(> .kc-blueframe) {
  flex: 1 0 auto;
  padding: 28px 24px 56px;
  background: linear-gradient(180deg,
    var(--kc-blue) 0, var(--kc-blueframe-2) 220px, var(--kc-blueframe-3) 560px, var(--kc-blueframe-4) 100%);
}

/* The wide column, for the data surfaces that had it before the frame went width-neutral. Before the
   phone rule below on purpose, so a phone still gets the frame's own narrow padding. */
main.kc-wrapper:has(> .kc-blueframe--wide) {
  max-width: 1300px;
  padding: 28px 30px 56px;
}

.kc-blueframe {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

/* The title block, set straight on the blue: where you are, what the page is, the one question it answers —
   and on the right, how fresh the numbers are and the pages next door. */
.kc-blueframe__head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 2px 6px;
}

.kc-blueframe__titles { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 560px; }
.kc-blueframe__eyebrow { font-size: 0.8125rem; color: var(--kc-blueframe-eyebrow); }

.kc-root .kc-blueframe__title {
  margin: 0;
  font-size: 1.875rem;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}

.kc-blueframe__lede { margin: 0; font-size: 0.9375rem; color: var(--kc-blueframe-ink); }

.kc-blueframe__aside {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-end;
  font-size: 0.8125rem;
  color: var(--kc-blueframe-ink);
}

.kc-blueframe__pills { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }

.kc-blueframe__pill {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 12px;
  border-radius: var(--kc-radius-pill);
  background: rgba(255, 255, 255, 0.85);
  color: var(--kc-heading-ink);
  text-decoration: none;
  font-weight: 600;
}
.kc-blueframe__pill:hover { background: #fff; }
.kc-blueframe__pill:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: 2px; }

/* A white card on the blue: the unit everything on a framed page is built from. */
.kc-blueframe__sheet {
  background: var(--kc-surface);
  border-radius: var(--kc-radius-panel);
  box-shadow: var(--kc-shadow-card);
  min-width: 0;
}

/* Status lines that belong to the whole page, as small cards rather than loose text on the gradient. */
.kc-blueframe__notice {
  margin: 0;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--kc-surface);
  box-shadow: var(--kc-shadow-card);
  font-size: 0.875rem;
  color: var(--kc-ink);
}
.kc-blueframe__notice--bad { box-shadow: inset 3px 0 0 var(--kc-stop-edge), var(--kc-shadow-card); color: var(--kc-stop-num); font-weight: 600; }
.kc-blueframe__notice--ok { box-shadow: inset 3px 0 0 var(--kc-go-ink), var(--kc-shadow-card); }

@media (max-width: 760px) {
  main.kc-wrapper:has(> .kc-blueframe) { padding: 20px 16px 40px; }
  .kc-blueframe__aside { align-items: flex-start; }
  .kc-blueframe__pills { justify-content: flex-start; }
}

/* ============================================================================
   PRODUCT QUALITY  (.kc-pq…)  — /ops/produktkvalitet
   ----------------------------------------------------------------------------
   Global rather than scoped, deliberately: the page and the queues component (ProductQualityQueues) draw
   the same rows, tags and pager, and a component's scoped sheet stops at its own markup. The old queues
   leant on rules scoped to Product sync, the page they had been born on — and so rendered unstyled on the
   page they had moved to.
   ========================================================================== */

/* --- "Behöver åtgärdas": one card per problem that is not zero ------------------------------------- */
.kc-pq-attention { display: flex; flex-direction: column; gap: 8px; }
.kc-root .kc-pq-attention__head { margin: 0; font-size: 1rem; color: var(--kc-blueframe-ink); }
.kc-pq-attention__clear { margin: 0; font-size: 0.875rem; color: var(--kc-blueframe-ink); }

.kc-pq-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 10px;
}

.kc-pq-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border-radius: 8px;
  background: var(--kc-surface);
  box-shadow: var(--kc-shadow-card);
  border-top: 3px solid var(--kc-stop-tag-edge);
}
.kc-pq-card--warn { border-top-color: var(--kc-warn-tag-edge); }

.kc-pq-card__line { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.kc-pq-card__num { font-size: 1.375rem; font-weight: 700; color: var(--kc-stop-num); font-variant-numeric: tabular-nums; }
.kc-pq-card--warn .kc-pq-card__num { color: var(--kc-warn-num); }
.kc-pq-card__title { font-size: 0.875rem; font-weight: 600; color: var(--kc-heading-ink); }
.kc-pq-card__why { margin: 0; font-size: 0.8125rem; line-height: 1.4; color: var(--kc-ink); flex-grow: 1; overflow-wrap: anywhere; }

.kc-pq-card__go {
  align-self: flex-start;
  min-height: 30px;
  padding: 0 12px;
  border: 0;
  border-radius: 6px;
  background: var(--kc-navy);
  color: #fff;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}
.kc-pq-card__go:hover { background: var(--kc-heading-ink); }
.kc-pq-card__go:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: 2px; }

/* --- Where every listed article is: the import bar -------------------------------------------------- */
.kc-pq-flow { padding: 14px 20px; display: flex; flex-direction: column; gap: 10px; }
.kc-pq-flow__top { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; justify-content: space-between; }
.kc-root .kc-pq-flow__head { margin: 0; font-size: 1rem; color: var(--kc-heading-ink); }
.kc-pq-flow__totals { font-size: 0.8125rem; color: #555; }
.kc-pq-flow__totals strong { color: var(--kc-heading-ink); }

.kc-pq-bar { display: flex; height: 16px; border-radius: 4px; overflow: hidden; background: var(--kc-status-empty); }
.kc-pq-bar__seg { height: 100%; }

/* One colour per state, and the same colour for its dot in the legend. Green done, the open-blue for work
   waiting, a deeper blue for work in hand, red for what did not get in, and a neutral grey for what DABAS
   says no longer exists — not imported, but not a failure of ours either, so not red. */
.kc-pq-state--done     { background: var(--kc-status-ok-edge); }
.kc-pq-state--waiting  { background: var(--kc-status-open-edge); }
.kc-pq-state--fetching { background: #3B82C4; }
.kc-pq-state--missing  { background: #E05252; }
.kc-pq-state--gone     { background: #8C939D; }

.kc-pq-legend { display: flex; flex-wrap: wrap; gap: 6px 22px; align-items: center; font-size: 0.8125rem; color: var(--kc-subtle); }

.kc-pq-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 0;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--kc-subtle);
}
.kc-pq-legend__item strong { color: var(--kc-heading-ink); }
button.kc-pq-legend__item { cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
button.kc-pq-legend__item:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: 2px; }
.kc-pq-legend__dot { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }
.kc-pq-legend__note { margin-left: auto; color: var(--kc-muted); }

/* --- The work queues: equal tabs, each with its count ----------------------------------------------- */
.kc-pq-work { display: flex; flex-direction: column; }

.kc-pq-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 4px 12px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}

.kc-pq-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 38px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 0.875rem;
  color: #555;
  cursor: pointer;
}
.kc-pq-tab:hover { color: var(--kc-heading-ink); }
.kc-pq-tab:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: -2px; }
.kc-pq-tab[aria-selected="true"] { color: var(--kc-heading-ink); font-weight: 600; box-shadow: inset 0 -3px 0 var(--kc-navy); }

.kc-pq-badge {
  display: inline-block;
  padding: 0 6px;
  line-height: 18px;
  border-radius: 3px;
  font-size: 0.75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: var(--kc-neutral-bg);
  color: var(--kc-ink);
}
.kc-pq-badge--bad  { background: var(--kc-stop-tag); color: var(--kc-stop-tag-ink); }
.kc-pq-badge--warn { background: var(--kc-warn-tag); color: var(--kc-warn-tag-ink); }
.kc-pq-badge--ok   { background: var(--kc-status-ok); color: #14532D; }

.kc-pq-panel { padding: 12px 16px 16px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }

/* "Vad det är och vad du gör" — one line until somebody asks. */
.kc-pq-guide { font-size: 0.8125rem; color: var(--kc-subtle); }
.kc-pq-guide > summary { cursor: pointer; color: #2F5F86; }
.kc-pq-guide p { margin: 6px 0 0; line-height: 1.45; max-width: 110ch; }

/* --- The compact segmented strip (Feltyp, Nivå) ------------------------------------------------------
   One grey frame, 1px gaps, white segments, the chosen one in Kitcheck blue — the original page's strip,
   not a row of pills. A type that belongs to the OTHER tab is greyed but live: picking it moves you there. */
.kc-pq-seg {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  padding: 1px;
  background: rgba(0, 0, 0, 0.10);
  border: 1px solid rgba(0, 0, 0, 0.10);
  border-radius: 8px;
  overflow: hidden;
}

.kc-pq-seg__label {
  display: inline-flex;
  align-items: center;
  padding: 0 10px;
  background: #F4F5F7;
  color: #555;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.kc-pq-seg__item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 30px;
  padding: 0 10px;
  border: 0;
  background: var(--kc-surface);
  color: var(--kc-ink);
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
}
.kc-pq-seg__item:hover { background: #F4F9FB; }
.kc-pq-seg__item:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: -2px; }
.kc-pq-seg__item--dim { color: #6B6B6B; }
.kc-pq-seg__item--on,
.kc-pq-seg__item--on:hover { background: var(--kc-blue); color: #08313F; font-weight: 600; }
.kc-pq-seg__kind,
.kc-pq-seg__count { color: var(--kc-muted); }
.kc-pq-seg__count { font-size: 0.75rem; font-variant-numeric: tabular-nums; }
.kc-pq-seg__item--on .kc-pq-seg__kind,
.kc-pq-seg__item--on .kc-pq-seg__count { color: #08313F; }
/* What the strip's numbers count, under it: problems, where the tab beside it counts articles. */
.kc-pq-seg__caption { margin: -4px 0 0; font-size: 0.75rem; color: var(--kc-muted); }

/* --- Bulk decisions ----------------------------------------------------------------------------------- */
.kc-pq-bulk { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-size: 0.8125rem; }
.kc-pq-bulk__all { display: inline-flex; align-items: center; gap: 6px; }
.kc-pq-bulk__count { color: var(--kc-muted); }

.kc-pq-input {
  flex: 1 1 260px;
  min-height: 28px;
  padding: 0 8px;
  border: 1px solid #C9CDD2;
  border-radius: 4px;
  font: inherit;
  font-size: 0.8125rem;
  background: var(--kc-surface);
}
.kc-pq-input:focus-visible { outline: none; border-color: var(--kc-blue); box-shadow: 0 0 0 3px rgba(122, 192, 218, 0.4); }
select.kc-pq-input { flex: 0 1 auto; padding-right: 4px; }

/* Small outlined buttons for dense surfaces: a page of a hundred rows is no place for 44px blocks. */
.kc-pq-btn {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 10px;
  border: 1px solid #C9CDD2;
  border-radius: 4px;
  background: var(--kc-surface);
  color: var(--kc-ink);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
}
.kc-pq-btn:hover:not(:disabled) { background: #F4F5F7; }
.kc-pq-btn:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: 2px; }
.kc-pq-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.kc-pq-btn--go   { border-color: var(--kc-go-ink); color: var(--kc-go-ink); }
.kc-pq-btn--stop { border-color: var(--kc-stop-num); color: var(--kc-stop-num); }
.kc-pq-btn--navy { border-color: var(--kc-navy); color: var(--kc-navy); }
.kc-pq-btn--sm   { min-height: 24px; padding: 0 8px; font-size: 0.75rem; }
.kc-pq-btn--plain { font-weight: 400; }

/* --- Dense rows: one line per article ----------------------------------------------------------------- */
/* Positioned so it can clip what it holds: a scroller only contains the absolutely positioned descendants
   it is the containing block for, and the visually hidden header labels (.kc-sr-only) are exactly that —
   without this they escaped to the page and pushed a phone 140px wide. */
.kc-pq-scroll { position: relative; overflow-x: auto; }

.kc-pq-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }
.kc-pq-table thead tr { text-align: left; color: #555; font-size: 0.75rem; border-bottom: 1px solid rgba(0, 0, 0, 0.15); }
.kc-pq-table th { padding: 4px 6px; font-weight: 600; }
.kc-pq-table td { padding: 3px 6px; vertical-align: middle; }
.kc-pq-table tbody tr { border-bottom: 1px solid rgba(0, 0, 0, 0.06); }

/* Tinted and left-edged by the worst open problem on the row. */
.kc-pq-row--stop { background: var(--kc-stop-row); box-shadow: inset 3px 0 0 var(--kc-stop-edge); }
.kc-pq-row--warn { background: var(--kc-warn-row); box-shadow: inset 3px 0 0 var(--kc-warn-edge); }

.kc-pq-name { white-space: nowrap; max-width: 380px; overflow: hidden; text-overflow: ellipsis; }
.kc-pq-name strong { color: var(--kc-heading-ink); }
.kc-pq-meta { color: var(--kc-muted); font-size: 0.75rem; font-weight: 400; }
.kc-pq-muted { color: #555; }
.kc-pq-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.kc-pq-num--stop { font-weight: 700; color: var(--kc-stop-num); }
.kc-pq-acts { text-align: right; white-space: nowrap; }
.kc-pq-acts > * + * { margin-left: 6px; }
.kc-pq-wrap { white-space: normal; overflow-wrap: anywhere; }

.kc-pq-tags { display: flex; flex-wrap: wrap; gap: 3px; }

.kc-pq-tag {
  display: inline-block;
  padding: 0 5px;
  line-height: 18px;
  border-radius: 3px;
  font-size: 0.75rem;
  white-space: nowrap;
  border: 1px solid var(--kc-border-soft);
  background: var(--kc-neutral-bg);
  color: var(--kc-ink);
}
.kc-pq-tag--stop { background: var(--kc-stop-tag); color: var(--kc-stop-tag-ink); border-color: var(--kc-stop-tag-edge); }
.kc-pq-tag--warn { background: var(--kc-warn-tag); color: var(--kc-warn-tag-ink); border-color: var(--kc-warn-tag-edge); }
.kc-pq-tag--ok   { background: var(--kc-status-ok); color: #14532D; border-color: var(--kc-status-ok-edge); }
/* The warning levels on Varningar (owner, 2026-10-10): "hög" — only the supplier can fix it — reads as more
   than a plain warning; "verifiera" reads as less. Text carries the level too (▲, the strip's "· hög"). */
.kc-pq-tag--high   { background: #FBD9B0; color: #6B2E00; border-color: #E8A866; font-weight: 600; }
.kc-pq-tag--verify { background: var(--kc-neutral-bg); color: var(--kc-ink); border-color: var(--kc-border-soft); border-style: dashed; }
.kc-pq-seg__item--high .kc-pq-seg__kind { color: #8A3B00; font-weight: 600; }

/* "Granska": a link to the review page, compact enough to sit in a 24px row. */
.kc-pq-review {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  border-radius: 4px;
  border: 1px solid var(--kc-navy);
  color: var(--kc-navy);
  text-decoration: none;
  font-size: 0.75rem;
  font-weight: 600;
}
.kc-pq-review:hover { background: var(--kc-navy); color: #fff; }

/* A GTIN that opens the product card: a link in looks, a button in kind, monospace so it pastes. */
.kc-pq-gtin {
  border: 0;
  padding: 0;
  background: none;
  font-family: var(--kc-font-mono, ui-monospace, "Cascadia Mono", Consolas, monospace);
  font-size: 0.75rem;
  color: var(--kc-navy);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.kc-pq-pager {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  font-size: 0.8125rem;
  color: #555;
}
.kc-pq-pager__btns { display: flex; gap: 6px; }

.kc-pq-link { color: #2F5F86; font-size: 0.75rem; }
.kc-pq-link:hover { color: #1E3F5A; }
.kc-pq-guide > summary,
.kc-pq-link { text-underline-offset: 2px; }
/* The same link, for an action that opens something in place ("Visa artiklarna") and so is a button. */
.kc-pq-linkbtn {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  font-size: 0.75rem;
  color: #2F5F86;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.kc-pq-linkbtn:hover { color: #1E3F5A; }
.kc-pq-linkbtn:focus-visible { outline: 2px solid var(--kc-navy); outline-offset: 2px; }
.kc-pq-empty { margin: 0; font-size: 0.875rem; color: var(--kc-subtle); }
.kc-pq-note { margin: 0; font-size: 0.8125rem; line-height: 1.45; color: var(--kc-subtle); max-width: 110ch; }
.kc-pq-note--ok { color: var(--kc-go-ink); }
.kc-pq-status { margin: 0; font-size: 0.8125rem; color: var(--kc-heading-ink); font-weight: 600; }
.kc-root .kc-pq-subhead { margin: 8px 0 0; font-size: 0.875rem; color: var(--kc-heading-ink); }
.kc-pq-confirm { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: flex-end; white-space: normal; }

/* --- Ej importerade: the article count, in one line ------------------------------------------------- */
.kc-pq-total {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--kc-stop-row);
  box-shadow: inset 3px 0 0 var(--kc-stop-edge);
}
.kc-pq-total--ok { background: #ECFDF3; box-shadow: inset 3px 0 0 var(--kc-go-ink); }
.kc-pq-total__num { font-size: 1.625rem; font-weight: 700; color: var(--kc-stop-num); font-variant-numeric: tabular-nums; }
.kc-pq-total--ok .kc-pq-total__num { color: var(--kc-go-ink); }
.kc-pq-total__text { font-size: 0.875rem; color: var(--kc-heading-ink); }

/* The articles of one cause, opened under its row. */
.kc-pq-sublist > td { padding: 6px 6px 10px 18px; background: var(--kc-surface); }

/* One cause the import gave up for: its Swedish lead, the cause's own text — monospace, because it is what gets
   searched for in the code — and an example GTIN or two, stacked in the one cell. */
.kc-pq-cause { display: flex; flex-direction: column; gap: 2px; padding: 2px 0; }
.kc-pq-cause__lead { color: var(--kc-heading-ink); }
.kc-pq-cause__text {
  font-family: var(--kc-font-mono, ui-monospace, "Cascadia Mono", Consolas, monospace);
  font-size: 0.75rem;
  color: var(--kc-subtle);
}
.kc-pq-cause__text--title { color: var(--kc-ink); }
/* Beside a long error the GTIN and the time would otherwise wrap; they are the columns read at a glance. */
.kc-pq-causeitems .kc-pq-gtin,
.kc-pq-causeitems .kc-pq-muted { white-space: nowrap; }
/* One article's own full error, under its cause: where what the cause leaves out is read. */
.kc-pq-err {
  min-width: 18rem;
  font-family: var(--kc-font-mono, ui-monospace, "Cascadia Mono", Consolas, monospace);
  font-size: 0.6875rem;
  color: var(--kc-subtle);
}

/* --- Att mappa: what kinds of decision are owed ------------------------------------------------------ */
.kc-pq-mapcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px; }

.kc-pq-mapcard {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, 0.12);
}
.kc-pq-mapcard--fyi { border-style: dashed; border-color: rgba(0, 0, 0, 0.25); background: #F4F5F7; }
.kc-pq-mapcard__label { font-size: 0.8125rem; font-weight: 600; color: var(--kc-heading-ink); }
.kc-pq-mapcard__label strong { font-weight: 700; }
.kc-pq-mapcard__what { font-size: 0.75rem; color: #555; }

.kc-pq-mapgroup { display: flex; flex-direction: column; gap: 6px; }
.kc-root .kc-pq-mapgroup__title { margin: 6px 0 0; font-size: 0.9375rem; color: var(--kc-heading-ink); display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.kc-pq-mapgroup__count { font-size: 0.8125rem; font-weight: 400; color: var(--kc-muted); }
.kc-pq-mapgroup--fyi .kc-pq-table { opacity: 0.8; }
.kc-pq-mapper { display: flex; gap: 6px; align-items: center; }
.kc-pq-mapper--wrap { flex-wrap: wrap; margin-bottom: 4px; }
.kc-pq-mapper--wrap .kc-pq-input { flex: 1 1 18rem; }
.kc-pq-mapper .kc-pq-input { flex: 1 1 auto; min-width: 10rem; }
.kc-pq-hint { margin-top: 3px; padding-left: 8px; border-left: 3px solid var(--kc-border-soft); font-size: 0.75rem; color: var(--kc-subtle); white-space: normal; }

/* The product card, opened from a GTIN in a queue: the same card the recipe builder opens, wider than a
   confirm dialog and scrolling inside its own frame. */
.kc-modal.kc-pq-cardmodal {
  max-width: min(900px, 100%);
  max-height: 92vh;
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.kc-pq-cardmodal__body { overflow-y: auto; padding: 1rem 1.1rem; }

@media (max-width: 760px) {
  .kc-pq-flow { padding: 12px 14px; }
  .kc-pq-panel { padding: 10px 12px 14px; }
  .kc-pq-tabs { padding: 4px 6px 0; }
  .kc-pq-legend__note { margin-left: 0; }
  .kc-pq-name { max-width: 220px; }
}
